pierce@lanai.cs.ucla.edu (10/19/88)
- Some good person replied to my example in Re: Limitation with Lambda. This person pointed out that the "case-lambda" syntax is not standard Scheme. My apologies, case-lambda is from Chez Scheme Version 2.0, and I have found it so useful (I use it a *lot*) that I just forgot that users of other Scheme systems might not know what it meant. An excerpt from the Chez Scheme Version 2.0 release notes follows. It's a simple idea that not only makes code easier to write and to understand, but it also runs faster than the old way. Maybe Kent Dybvig could be encouraged to post a little more info about case-lambda? -- Brad Pierce ------------------------------------------------------------------------ (below Copyright Kent Dybvig) Optional Arguments Procedures with a variable number of arguments could only be defined in earlier versions using the "lambda dot" interface, which requires allocation of a list to hold all but the required parameters. Version 2.0 supports a variant of "lambda", called "case-lambda", that allows procedures with variable numbers of arguments to be defined efficiently. "case-lambda" has the form: (case-lambda [idspec-a exp1-a exp2-a ...] [idspec-b exp1-b exp2-b ...] ...) where the idspecs are normal "lambda" parameter lists. In essence, each bracketted item (parens may be used in place of the brackets) represents a different "lambda" expression; which one is evaluated depends upon the number of arguments. If the number of arguments is a correct number for the first idspec, evaluation proceeds with the first body within the bindings implied by the first idspec. If not, then if the number of arguments is a correct number for the second idspec, evaluation proceeds with the second body, etc.
Krulwich-Bruce@cs.yale.edu (Bruce Krulwich) (10/19/88)
In article <16934@shemp.CS.UCLA.EDU>, pierce@lanai writes: >Some good person replied to my example in Re: Limitation with Lambda. >This person pointed out that the "case-lambda" syntax is not standard >Scheme. My apologies, case-lambda is from Chez Scheme Version 2.0, >and I have found it so useful (I use it a *lot*) that I just forgot >that users of other Scheme systems might not know what it meant. ... > Procedures with a variable number of arguments could only be defined > in earlier versions using the "lambda dot" interface, which requires > allocation of a list to hold all but the required parameters. > Version 2.0 supports a variant of "lambda", called "case-lambda", > that allows procedures with variable numbers of arguments to be > defined efficiently. "case-lambda" has the form: > > (case-lambda [idspec-a exp1-a exp2-a ...] > [idspec-b exp1-b exp2-b ...] ...) > > where the idspecs are normal "lambda" parameter lists. The following is an implementation of CASE-LAMBDA in T. The only things that it uses that may not be standard are the use of a () argument as an ignored argument and the function INTS-TO-N which must return a list of any N items. (define-syntax (case-lambda . lambda-specs) (let* ((min-len (apply min (map (lambda (spec) (length (car spec))) lambda-specs))) (const-args (map (lambda (()) (generate-symbol 'arg)) (ints-to-n min-len))) (rest-arg (generate-symbol 'rest)) (len-var (generate-symbol 'length)) ) `(lambda (,@const-args . ,rest-arg) (let ((,len-var (length ,rest-arg))) (cond ,@(map (lambda (spec) `((eq? ,len-var ,(fx- (length (car spec)) min-len)) (apply (lambda ,(car spec) ,@(cdr spec)) ,@const-args ,rest-arg))) lambda-specs) (else (error "Wrong number of args to a CASE-LAMBDA")) ))) )) This implementation is efficient in the sense that it will cause the smallest possible rest-arg to be CONSed for every procedure, but it would obviously more efficient to do this as a low-level construct (as I think is done in Chez-Scheme) so that no rest-arg would be CONSed. My question, though, is just how useful this construct is. It seems to me that most of the uses of procedures with variable arguments is for the first few of them (the constant ones) to have the same use regardless of the optional (rest) arg's, and for the main block of code of the procedure to be the same once the optional values are decoded and defaults are set if necessary. The CASE-LAMBDA construct specifies completely disjoint blocks of code for each of the argument configurations. It seems awkward. Can someone who has used CASE-LAMBDA and likes it post or send to me examples of its use (presumably examples that show it being used beneficially)?? Bruce Krulwich