[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

*To*: srfi-26@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*Subject*: is that useful?*From*: "Walter C. Pelissero" <walter@xxxxxxxxxxxxx>*Date*: Fri, 22 Feb 2002 13:29:44 +0000*Delivered-to*: srfi-26@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*Reply-to*: walter@xxxxxxxxxxxxx

Maybe somebody can explain me what is the use of this SRFI. The original curry, as explained by some book, (define (curry f x) (lambda (y) (f x y))) is a suggestive trick to produce a specialization of f without an explicit lambda expression. A special case of partial application, one might argue. While having an educational value the curry higher-order function is not very useful as its specialization is only on the first parameter and therefore its applicability is marginal as it doesn't address common cases like: (lambda (y) (/ y 2)) ; where x=2 (lambda (z) (< 0 z 1)) ; where x=0, y=1 (lambda (y) (hash-store table y y)) ; where x=table (lambda (y z) (list 1 z 2 y 3)) I see that this SRFI aims at solving the first and second cases, with the introduction of a place-holder notation, but still doesn't address the swapping of two arguments and the repetition of one argument. Indeed, pretty common cases. The original curry is elegant, because the declaration of the missing argument is implicit. This SRFI, to cope with the positional arguments, departs from that idea. Making explicit the position of the parameters, it goes toward the vanilla lambda expression with the only benefit that you don't have to invent and declare names for the place-holders. In short, it looks to me like a lambda form with the limitations of curry. If all you want is a shortcut for the lambda expression, there are a couple of things that come to mind. In Scheme 48, with the macro: (define-syntax f (lambda (form rename compare) `(lambda (_) ,(cdr form)))) you can write closures like: (define halve (f / _ 2)) (define in-range? (f < 0 _ 1)) (define store (f hash-store table _ _)) but, of course, this goes far beyond curry, because you are free to write subforms: (define quadratic (f + (* _ _ 2) (* _ 3) 4)) It's, indeed, a replacement notation for lambda with the imaginable impact on readability (not so easy sometime). The underscore notation is not by chance. It's taken from the Paul Graham's wish list for his brainchild, Arc. Actually, he proposes the use of a square bracket shortcut: (define halve [/ _ 2]) (define in-range? [< 0 _ 1]) (define store [hash-store table _ _]) (define quadratic [+ (* _ _ 2) (* _ 3) 4]) Which is trivial to implement in Common Lisp and Scheme 48, but not necessarily in other Lisp dialects lacking read macros. This macro, while flexible, still doesn't address the multiple (and swapped) arguments issue. This is a bit more work: (define-syntax fn (lambda (form rename compare) (letrec ((arg-number (lambda (x) (if (symbol? x) (let ((s (symbol->string x))) (if (char=? #\$ (string-ref s 0)) (or (string->number (substring s 1 (string-length s))) 0) 0)) 0))) (number-of-arguments (lambda (l) (let loop ((l l)) (if (null? l) 0 (let ((x (car l))) (max (if (pair? x) (loop x) (arg-number x)) (loop (cdr l)))))))) (make-argument-list (lambda (n) (do ((n n (- n 1)) (l '() (cons (string->symbol (string-append "$" (number->string n))) l))) ((zero? n) l))))) (list 'lambda (make-argument-list (number-of-arguments form)) (cdr form))))) With that you can write things like: (define foo (fn list "(" $2 "." $1 ")")) ; swap 1st and 2nd arg (define bar (fn list $2)) ; ignore 1st arg (define acf (fn an $2 (arbitrary $3 'complex) $1 (form $2))) Once again, this has nothing to do with curry as it lets you write horrible syntactic closures resembling more Perl than Scheme in anything with more than two or three parameters. -- walter pelissero http://www.pelissero.org

- Prev by Date:
**Re: Changing the name** - Next by Date:
**Re: is that useful?** - Previous by thread:
**Re: A short name.** - Next by thread:
**Re: is that useful?** - Index(es):