4 ms·
One possible alternative is to combine PROGN with LET, which you might then call BLOCK, with the macro definition of BLOCK looking for `VAR`s. The VAR syntax wo
by ogogmad 3y ago
One possible alternative is to combine PROGN with LET, which you might then call BLOCK, with the macro definition of BLOCK looking for `VAR`s. The VAR syntax wouldn't make sense anywhere else. More exactly:
(block
(var first-thing 'EXAMPLE)
(do-something)
(var foo 'EXAMPLE)
(do-something-else))
Expand this into:
(let ((first-thing 'EXAMPLE))
(do-something)
(let ((foo 'EXAMPLE'))
(do-something-else)))
This would reduce indentation. But it would also involve big changes to Common Lisp.
- Jtsummers 3y agoIt wouldn't require any changes to the language. It would probably require a tree-walking macro, which are not too uncommon. You'd want a different name though since `block` is already a thing in CL. http://clhs.lisp.se/Body/s_block.htm http://clhs.lisp.se/Body/s_block.htm I'd recommend On Lisp by Paul Graham and Let Over Lambda by Doug Hoyt if you're interested in trying it.
- reikonomusha 3y agoIf BLOCK weren't already the name of something in Common Lisp, this sort of syntax is very easy to add, easy enough to write in an HN comment. Let's call it OGOGMAD instead. (defmacro ogogmad (&body b) (cond ((endp b) '(progn)) ((endp (rest b)) b) (t (let ((f (first b)) (r (rest b))) (if (eq 'var (first f)) `(let (,(rest f)) (ogogmad ,@r)) `(progn ,f (ogogmad ,@r)))))) Exactly as you specify, this only lets you put VAR syntax immediately inside of OGOGMAD forms. (Untested, typed on mobile.)
- lispm 3y agoReducing indentation is mostly a non-goal in Lisp. Can't work with nested lists? Don't use Lisp. Lisp processes nested lists. Lisp means List Processor. You may want to do it in a text oriented language, but not so much in an expression oriented language, where programmers edit an expression tree, by tree manipulation commands. In Lisp the "tree" is "nested lists". Btw., what does (block (when (foo) (var first-thing 'EXAMPLE)) (do-something) (var foo 'EXAMPLE) (do-something-else)) mean? Is it legal? Your macro would need to traverse the expression tree, knowing the whole Lisp syntax, including expanding macros, possibly in a source interpreter. WHEN is a macro. BLOCK would need to find the VAR expression inside the WHEN macro, which is not easy for the general case. This would be very very strange. Macros are usually expanded outside to inside. Your BLOCK macro would need to expand macros in enclosed code, to find VAR expressions. In JavaScript something like above is legal in a function.
- kazinator 3y agoWe would specifically not want this macro to be looking inside forms like when, and just analyze the forms that are its direct arguments. (Which is pretty easy.)
- kazinator 3y agoTXR Lisp: (defmacro ogogmad (:match) (() ()) (((var @var @init)) ^(progn ,init nil)) ((@single) single) (((var @var @init) . @rest) ^(let ((,var ,init)) (ogogmad ,*rest))) ((@first . @rest) ^(progn ,first (ogogmad ,*rest)))) 1> (expand '(ogogmad (var a 4) (var b 5) (+ a b))) (let ((a 4)) (let ((b 5)) (+ a b))) 2> (expand '(ogogmad)) nil 3> (expand '(ogogmad 42)) 42 4> (expand '(ogogmad (var a 42))) nil 5> (expand '(ogogmad (var a (print 42)))) (progn (print 42) ()) 6> (ogogmad (var a 4) (var b 5) (+ a b)) 9 :match is a new kind of macro, called a parameter list macro, that I invented. defmacro doesn't know anything about pattern matching. Parameter list macros are expanded in any function/lambda or macro parameter list situation. The :match macro assumes that the function's body consists of pattern matching clauses. It infers the parameters from it, which get substituted.