Closed Ruin0x11 closed 5 years ago
Is there a way of getting back more than one top-level form from defmacro? I think Clojure and Racket have this feature.
Clojure certainly cannot do this, at least without reader macros, if I am understanding this correctly. https://stackoverflow.com/questions/15796831/clojure-macro-to-return-two-or-more-s-expressions. Racket may, but Janet is unlikely to as we don't have multiple return values (nor do I plan on adding them). Multiple return values are a headache, and cause more problems than they solve, especially when you have proper destructuring of tuples.
Wrap it in a do
and use the functions defglobal
and varglobal
to define your functions. These will define things at the top scope.
(do
(defglobal 'thing "abcdefg")
(defglobal 'my-fn "docstring... " (fn 'my-fn [] ...))
(defglobal 'my-fn2 "docstring... " (fn 'my-fn2 [] ...)))
As for splicing, that won't work here. Splice only works as an argument to a function call or inside a quasiquote. Splice as a top level form, or not as an argument to a function will do nothing and act as the identity function. Future version may even raise a compilation error.
What's the difference between defn
and defglobal
? Seeing that defglobal
would be able to create top level binds whilst defn can't within do
block.
Hmm, it looks like defn
can be nested within defn
s, and the scope will limit what is accessible from outside.
Is there a way of getting back more than one top-level form from
defmacro
? I think Clojure and Racket have this feature. I want to make a macro that can output this:However, it seems
defmacro
only outputs the last form if more than one is given, so you can't do this:Wrapping it with
do
is problematic because I still wantmy-fn
to be scoped to the top-level. Also, trying to usesplice
still creates a tuple of values.As a background, I'm trying to learn the macro system by making a library that can be used as either a macro or a series of functions. The macro version will compile a series of sexps into a string literal at execution time, while there is an equivalent function for each that can be called to return a single string, like this: