2011-02-16 11 views
9

En el esquema se puede definir el siguiente procedimiento:sintaxis correcta para una expresión lambda que recibe cualquier número de argumentos en el Esquema

(define (proc . vars) 
     (display (length vars))) 

Esto le permitirá enviar cualquier cantidad de argumentos a proc. Pero cuando trato de hacerlo de esta manera:

(define proc (lambda (. vars) 
     (display (length vars)))) 

me sale el siguiente error:

read: illegal use of "."

Me parece que no puede encontrar la sintaxis correcta para una expresión lambda que recibe cualquier número de argumentos . Ideas?

(estoy usando DrScheme, la versión 209, con un lenguaje ajustado a PLT (gráfica))

Gracias!

+0

No relacionado con su pregunta, le recomiendo encarecidamente que actualice a la última versión de DrScheme, ahora llamada DrRacket. Puede descargarlo aquí: http://racket-lang.org/ –

+0

@SamTH La versión de DrScheme que utilicé fue dictada por mi universidad, pero gracias de todos modos, puedo terminar de leer SICP en mi tiempo libre y utilizar esta versión en su lugar ... – Hila

Respuesta

14

El primer argumento de lambda es la lista de argumentos:

(define proc (lambda vars 
    (display (length vars)))) 

(proc 1 2 4) ; 3 
(proc) ; 0 
+0

Lambda es una forma especial, y es un error llamar a la segunda cosa en una forma lambda el "primer argumento". Lo siento, capitán pedante aquí. –

+0

@John: ¿Cómo lo llamarías? – Tim

+0

Probablemente lo llamaría "el segundo elemento de la forma lambda". El problema con la palabra "argumento" es que está inextricablemente asociado con la función de llamada. –

1

deberá omitir los paréntesis en la lista de argumentos de lambda para denotar un número variable de argumentos:

(define proc (lambda vars 
    (display (length vars)))) 
6

La idea clave de entendiendo la sintaxis (lambda args ...) (que otros carteles ya se han publicado) es que un elemento solitario que no es una lista (en este caso, args) es una lista degenerada inadecuada. Ejemplo:

(define a '(arg1 arg2 . rest)) 
a     ; => (arg1 arg2 . rest) (improper list of length 2) 
(cdr a)    ; => (arg2 . rest)  (improper list of length 1) 
(cdr (cdr a))  ; => rest    (improper list of length 0) 
+2

Solo para aclarar: la lista degenerada '(a1 a2. Args)' sería, sin a1 y a2, simplemente 'args'. Una lista degenerada es aquella que carece del par final con un nil. – Tim

+3

@Tim: el término adecuado para una lista que carece de un extremo ''()' es una _improper list_. Una lista _degenerada_ inapropiada es aquella que deja de parecerse a una lista, ni siquiera una incorrecta. –

+0

No sabía de la distinción entre _improper_ y _degenerate_. Gracias. – Tim

Cuestiones relacionadas