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:
- a proper list of variables, (var1 ... varn), such as we have already seen,
- a single variable, var n , or
- 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.