简体   繁体   中英

What does this Scheme code mean? (Definition of 'list' operator using lambda)

As the definition to the list operator that compiles and returns a list of arguments , i found this scheme code at this tutorial

(define list
(lambda args args))

But, This doesn't match with the usual lambda syntax that i know. I mean, the lambda should have the parameters in brackets etc. Please explain how this works.

Although the general form of arguments in a lambda seems to always include parentheses, it's not necessarily required. If take a look at this section in the The Scheme Programming Language 4e , it says that:

The general form of lambda is a bit more complicated than the form we saw earlier, in that the formal parameter specification, (var ...), need not be a proper list, or indeed even a list at all . The formal parameter specification can be in any of the following three forms:

  1. a proper list of variables, (var1 ... varn), such as we have already seen,
  2. a single variable, var n , or
  3. an improper list of variables, (var1 ... varn . varr).

In the first case, exactly n actual parameters must be supplied, and each variable is bound to the corresponding actual parameter. In the second, any number of actual parameters is valid; all of the actual parameters are put into a single list and the single variable is bound to this list.

The part in bold face (bold-face set by me), is the part that is very relevant to your question. And as your tutorial says, it is a varargs argument that is converted into a list.

This defines a variadic procedure (a procedure that can take different numbers of arguments) of at least zero arguments. All the arguments are bundled up into a list called args , in this case.

Here's another example of a variadic procedure (this one requires at least one argument), which returns the minimum value of all the arguments passed in:

(define (min arg1 . rest)
  (let loop ((val arg1)
             (rest rest))
    (if (null? rest)
        val
        (let ((next (car rest)))
          (loop (if (< next val) next val)
                (cdr rest))))))

A Scheme interpretation pairs up a formal parameter specification with the actual arguments supplied in a function call, thus doing a sort of restricted pattern matching, with the formal parameter specification serving as kind of a pattern.

When it is a proper list of length n , this is like saying, will bind each of the n supplied argument values to each of the variables in the spec . Scheme demands exactly n arguments be supplied in such situation, although some dialects could be imagined to allow more, or less, than n arguments in such function call, without causing an error:

(define mylist (lambda (x y)      ; (define (mylist x y)    ; exactly two 
  (list x y)))                    ;   (list x y))           ;  arguments required

When it's an improper list with n variables and one tail variable, this is like saying if given more than n arguments, will bind the rest of them, as a list, to that tail variable . If there were no more arguments, naturally an empty list will be bound to the tail variable:

(define mylist (lambda (x . y)    ; (define (mylist x . y)  ; at least one
  (cons x y)))                    ;   (cons x y))           ;  argument required

The sole variable as a formal parameter specifiction is identified as a tail variable of an improper list, serving as a particular variant of the previous case. It will be thus bound to all the argument values supplied in a function call, as a list:

(define mylist (lambda x          ; (define (mylist . x)    ; any number of
  x))                             ;   x)                    ;  arguments can be used

x is already a list holding all the supplied arguments.

As is readily seen, all three cases can be handled by the same code transformation,

(define (translate-define-to-lambda code)
  (list (car code)                 ; "define"
        (caadr code)               ; name
        (cons 'lambda
              (cons (cdadr code)   ; parameters
                    (cddr code)))))

(because (cdr '(<a> . <b>)) == <b> ).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM