Diary: Transformations in STAK
Want to have convenience forms such as:
(for/range (i 0 NUM-BLDGS)
body...)
Essentially equivalent to:
(define i 0)
(define #max NUM-BLDGS)
(while (< i #max)
body...
(set! i (+1 i)))
In this case it seems like a good use-case for a simple pattern-based macro system.
This solution is not without issues:
#max
will conflict in case of nested loops… in absence of block scopes, it should be a gensym.i
will escape into the surrounding scope. Corollary: the same macro cannot be used again with the same variable in the same scope – it will be considered as redefinition, an error.
All that being said, what if I really don’t want to go into spec’ing/implementing a macro language? Is there a way to still enrich language without spilling this complexity into the compiler, reusing pre-existing primitives?
Yes, there is: implement a transformation ‘hook’ before parsing
statement/expression, and put all transformations into another Hy
module, so that the compiler remains deliciously hackable. This crude
design will impose some limitations, but should be workable. For
example, to expand a statement into multiple statements, they can be
wrapped in (when 1 ...)
. This will come at the cost of size + runtime
overhead (as have many previous decisions), but that’s okay for the
moment.
As for implementing the transformations themselves, we will take the
same approach as used in the compiler itself (hy.model-patterns).
Unfortunately we don’t have syntax-case
(or the more advanced
syntax-parse
) in Hy. Maybe this would be a good opportunity to take a
shot at implementing it.