|
From: | Panicz Maciej Godek |
Subject: | Re: (ice-9 nice-9) module update |
Date: | Wed, 2 Sep 2015 17:06:31 +0200 |
Maybe it would be good to make define and define-syntax more symmetric.
So if
(define (foo . rest) . body)
is equivalent to
(define foo (lambda rest . body)),
then
(define-syntax (foo . rest) . body)
should perhaps be equivalent to
(define-syntax (lambda rest . body)).
This is how Racket does it too, and one could say it's the most logical
and generalized choice.
Also, while it has that annoyance, it also has the advantage of allowing
you to do anything you want with that one syntax-object argument you
receive, e.g. passing it to syntax-case or (in the future) syntax-parse.
OTOH, making the argument list "special" will tie the form to a specific
macro system like syntax-rules or syntax-case, and also forbid using
multiple pattern/template pairs on it.
In my experience, using multiple
patterns is very common, and some code-bases also make heavy use of
syntax-case instead of syntax-rules, so I wouldn't allocate a primary
"syntax slot" like '(define-syntax (...) ...)' to something very
specific like "syntax-rules with one arm."
There are many possible extensions to 'let' (abbrev. for lambda, for
let-values, or for match-let), all of which make equally much sense to
me, so I think they're all bad, because no matter which one you
sanction, you will have discriminated against two others. :-)
Just keep
pure 'let' pure, and let people specify the exact variant they want...
However, for 'let-syntax' the situation is different. There is no
let-syntax-values, and there is no match-let-syntax. There is only one
way to use let-syntax, which is to bind the identifier to a syntax
transformer. So I agree it's a good idea to extend it in that
direction.
That leaves the question of what sort of syntax transformer should be
created, syntax-rules or syntax-case or lambda, and the obvious choice
to me is to make it consistent with define-syntax, so in line with my
other recommendation, I would make
(let-syntax (((foo stx) ...)) ...)
equivalent to
(let-syntax ((foo (lambda (stx) ...))) ...).
And so the widest possible use-cases are covered.
Admittedly that slightly discriminates against syntax-rules, which
doesn't go well with the implicit lambda. For that reason I would
propose a different syntax, similar to define-syntax-rule:
(let-syntax-rule
(((foo x y)
(do stuff))
((bar a b)
(do stuff)))
(body goes here))
This way everything is very consistent. Define-syntax and let-syntax
are maximally generic and assume no specific macro system so one can
dispatch to the system of choice, the exception being syntax-rules which
requires there *not* to be a lambda, so for syntax-rules we define the
*-syntax-rule variants, and hopefully everyone is happy.
---
I also pondered on the following two, but note that each save merely a
single trivial line of code per syntax-rules invocation, so I think they
have little merit:
(define-syntax-rules foo ()
((_ x y)
(do stuff))
((_ x y z)
(do other stuff)))
(let-syntax-rules
((foo ()
((_ x y)
(do stuff))
((_ x y z)
(do other stuff)))
(bar ()
((_ a b)
(do stuff))
((_ a b c)
(do other stuff))))
(body goes here))
They're highly consistent with the rest though, so it shouldn't hurt
adding them if others think it's worth it.
That amounts to 6 cents, I hope it wasn't excessive. :-P
[Prev in Thread] | Current Thread | [Next in Thread] |