Redesigning the resolver
General planning issue for the rewritten resolver/macro expander. The current system is not well suited to several planned language features.
unpack
/splice
/@
)
Macros returning multiple values (from We first need to think about how this is going to work. The obvious use case is returning multiple top top-level definitions:
(defmacro gen-things (name)
@(`(define name "foo")
`(define ,(string->symbol (.. (symbol->string) "/bar")))
(gen-things)
However, do we want to handle this in other cases places, such as function arguments or cond
expressions. Consider:
(defmacro print-branch (case msg)
@(,case `(print! ,msg)))
(cond
((print-branch x "Hello") ;; ...
should this expand to
(cond
(x (print! "Hello") ;; ...
Also, should splice
be allowed in the middle of argument lists, like variadic arguments on unquote-splice
? Could we remove unquote-splice
and just emulate it as a mixture of unquote
and splice
?
REPL
The current resolver heavily relies on yielding coroutines. Whilst this is fine as we constantly need to exit to recompile sections, it does make the implementation of the REPL more complex. If we could abstract the yielding out of the State
and Scope
objects (maybe as a callback argument) this would be great.
Top-level unquote
A feature 'borrowed' from Metalua, it would be really cool to have compile-only code: basically an implicit macro. This could be done through the use of ,
. Obviously this would have the same restrictions as other quotes (only being able to capture top-level variables). Example:
(define people-names ,(io/read-all "names.txt"))
expands to
(define people-names "Kevin\nBruce\n")
This would then require assigning a state for arbitrary expressions, rather than just top level definitions (as we have to trace requirements). Maybe each node could have a immutable list of dependencies (built from a union of its children's dependencies).
Improved symbol "exposure"
Currently, symbols store a tag to their variable in the lookup table. In order to mutable variable metadata, we'd have to pass the variable lookup table at macro compile time. So `foo
would look something like {tag = "symbol", contents = "foo", var = _vars["foo_hash"] }
.