(defMacro defMultiple [varName funcName] `{ (var ,varName 5) (function ,funcName [] 6)}) (defMultiple myVar myFunc) (defMacro variadicPlus [&rest l] `(+ ,@l)) (defMacro listPlus [l] `(+ ,@l)) // Both forms of passing expression lists to macros should work: (function sum1 [] (variadicPlus 1 2 3)) (function sum2 [] (listPlus [1 2 3])) // You should be able to run list comprehensions on expressions // and put the pieces back together in a modular way (defMacro altDefun [name args &body body] (let [argPairs (groups (expList args) 2) untypedArgs [] letBindings []] (doFor [name type] argPairs (untypedArgs.push name) (letBindings.push name) // (print type) // (print name) (letBindings.push `(the ,type ,name))) (print letBindings) `(function ,name ,untypedArgs (let ,letBindings ,@body)))) (altDefun nameAndNumber [name String number Int] "$name $number") (defMacro listOfExp [exp times] (let [times (eval times)] (_listOfExp exp times))) (defMacroFunction _listOfExp [exp times] (case times (1 `[,exp]) (otherwise `(.concat ,(_listOfExp exp 1) ,(_listOfExp exp (- times 1)))))) (function _testRecursiveMacroFunction [] (Assert.equals (Std.string [10 10 10 10 10 10 10 10 10 10]) (Std.string (listOfExp 10 10)))) (defMacroFunction printAtMacroTime [] ~"Print at macro time should work just fine" `null) (defMacro _testPrintAtMacroTimeMacro [] (printAtMacroTime)) (function _testPrintAtMacroTime [] (_testPrintAtMacroTimeMacro) (Assert.pass)) // Calling (set) on a macroVar is a faux-pas, because (setMacroVar) is the right way (defMacroVar count 0) (defMacro _testSetMacroVarMacro [] (assertThrows (set count (+ count 1))) (ReaderExp.StrExp (Std.string count))) (function _testSetMacroVar [] (_testSetMacroVarMacro) (Assert.pass)) (defMacro _testRedefineMacroVarMacro [] (setMacroVar count (+ count 1)) (symbol (Std.string count))) (function _testRedefineMacroVar [] (Assert.equals 1 (_testRedefineMacroVarMacro)) (Assert.equals 2 (_testRedefineMacroVarMacro))) // ifLet and its derivatives should be disabled in defMacro bodies: (defMacro _testIfLetDisabledMacro [] (assertThrows (ifLet [a "b"] a)) (assertThrows (whenLet [a "b"] a)) (assertThrows (unlessLet [a "b"] a)) `null) (function _testIfLetDisabled [] (_testIfLetDisabledMacro)) (defMacro _testTryCatchWithoutDynamicMacro [] (try (throw "intended") (catch [e] (ReaderExp.StrExp e)))) (function _testTryCatchWithoutDynamic [] (Assert.equals "intended" (_testTryCatchWithoutDynamicMacro))) (function _testAssertReturnsValue [] (Assert.equals true (assert true))) // DANGEROUS tests: // (don't add new tests below here, because these tests redefine important forms) // If for whatever reason, you wanted to make a variable with the name of a built-in identifier alias: (undefAlias &ident chooseRandom) (var chooseRandom 9) // Also if you want a function called print: (undefAlias &call print) (function print [thing] (+ 1 thing)) (defAlias &ident alias 5) (undefAlias &ident alias) (var alias 9) (function aliasValue [] alias) // If for whatever reason, you wanted to make a function called and (undefMacro and) (function and [a b] (+ a b)) (function andValue [] (and 5 6))