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...

Reply via email to