I wrote:
The macro:
(define-syntax &&
(syntax-rules ()
( (&& (f ...) (x ...))
(lambda (x ...)
(and (f x ...)
...)) )
( (&& (f ...))
(&& (f ...) (x)) )))
Just curious, what do y'all use for this sort of thing?
Derick Eddington wrote:
lambda or my `and?' higher-order procedure.
Looking for 'and?' in xitomatl ... found it. Yep, it's similar.
I find syntax like this
confusing, because I have to learn the syntax for no syntactic benefit
(IMO) over lambda (but the same could be said of my `and?', which I've
barely used, I mostly made it for fun).
I use things like '&&' or your 'and?' with procedures like 'every',
'any', 'find', etc. For example:
(every (&& (number? odd?)) '(1 3 5))
as opposed to:
(every (lambda (x) (and (number? x) (odd? x))) '(1 3 5))
of course, there's something to be said for factoring out 'odd-number?'
:-) But this is just an example.
Alot of stuff that comes from my corner is experimental. Lately I've
been doing alot of "FP" style stuff and so '&&' is right at home there.
Your 'and?' is (sensibly) single-arity which is the common case. I made
'&&' useful with other arities. E.g.:
(&& (f g h) (x y))
The trouble is, this mucks up the common case with those extra
parenthesis! It would be nice to just say:
(&& number? odd?)
Just yesterday, you cited a note from Clinger [1] where he listed a few
principles of language design. Seems like '&&' goes against #1:
Thou shalt not hair up the common case just to
simplify unusual cases.
There are a few ways out of this. One is, leave '&&' for the common case
of single arity and have a separate macro that does the general thing.
The other is to design '&&' so that it supports both elegantly. But, I'm
not sure such a design exists. For example, here's a naive version which
works in some cases:
(define-syntax &&
(syntax-rules ()
( (&& (f ...) (x ...))
(lambda (x ...)
(and (f x ...)
...)) )
( (&& f ...)
(&& (f ...) (x)) )))
But breaks down sometimes:
( (&& (lambda (x) (number? x))
(lambda (x) (odd? x)))
5 )
That matches the macro's first pattern but the user meant the unary case.
Here's one which uses additional syntax '=>' to help disambiguate:
(define-syntax &&
(syntax-rules (=>)
( (&& (f ...) => (x ...))
(lambda (x ...)
(and (f x ...)
...)) )
( (&& f ...)
(&& (f ...) => (x)) )))
But this version still isn't "correct" for all cases; what if you have a
procedure named '=>'? I.e. here the user intends the unary case, but it
matches the first rule:
(define (=> x y) #t)
(&& (lambda (x) (number? x)) => (lambda (x) (odd? x)))
Ed
[1] http://groups.google.com/group/comp.lang.scheme/msg/e10cd3ab3f90c5be
PS: Going back to your comment about confusing syntax, I wonder how
you'd feel about the J programming language! ;-) Or K, Q, etc...