lambda - cond - map racket
¿Cuál es el punto de lambda en el esquema? (6)
De hecho, es solo una abreviatura de una expresión Lambda. Las siguientes dos expresiones son equivalentes:
(let ((alpha 7)) (* 5 alpha))
((lambda (alpha) (* 5 alpha)) 7)
Lambda sigue la filosofía del lenguaje de que todo debe parecer una función matemática. Pero en la práctica, Let hace que sea más fácil averiguar qué está sucediendo si hay demasiadas variables. Imagine 10 variables que tengan sus valores definidos después del bloque Lambda, e intente hacer coincidir cada una de ellas con el nombre de la variable, con Permitir que los valores de las variables se coloquen justo al lado de sus nombres, convenientes para el programador pero que se ajusten menos a la Funcional Filosofía de la programación.
Lambda puede usarse para devolver una función desde una función de orden superior, sin embargo, no podemos hacer eso. P.ej:
(define (plus-list x)
(cond ((number? x)
(lambda (y) (+ (sum-n x) y)))
((list? x)
(lambda (y) (+ (sum-list x) y)))
(else (lambda (x) x))
))
> ((plus-list 3) 4)
10
> ((plus-list ''(1 3 5)) 5)
14
> ((plus-list ''a) 5)
5
Lambda también se puede utilizar para pasar una función a una función:
>(map (lambda (x) (+ 1 x)) ''(-1 2 -3))
(0 3 -2)
Estoy aprendiendo el esquema. Sé cómo usar tanto lambda como dejar expresiones.
Sin embargo, estoy luchando para averiguar cuál es el punto de usar lambda. ¿No puedes hacer todo con dejar que puedas con lambda?
Sería especialmente útil ver un ejemplo de una situación en la que una expresión lambda es una mejor opción que dejar.
Otra cosa: ¿también hay situaciones en las que dejar sea más útil que lambda? Si es así, tal ejemplo sería bueno también.
Edición: También me interesa contrastar define y lambda, ya que parecen realizar tareas similares.
Actualizar:
Gracias por la ayuda a todos. Hice un poco más de análisis de lambda / dejar / definir después de leer sus respuestas y ahora lo entiendo mucho mejor.
Me encontré con un excelente ejemplo de uso fresco de lambda: devolver funciones anónimas de procedimientos. Por ejemplo, el procedimiento de operateTwice
siguiente operateTwice
una función anónima que se basa en los parámetros que se pasan al procedimiento:
(define operateTwice
(lambda (op1 op2)
(lambda (x y)
(op2 (op1 x y) y))))
((operateTwice * +) 2 3) ;equivalent to: (+ (* 2 3) 3), or in standard notation 2*3+3
Salida:
9
En Esquema, un procedimiento (o función) es un objeto de primera clase como una lista, un número o una cadena. Para crear un literal de lista utiliza la list
llamada primitiva:
> (define marks (list 33 40 56))
> marks
> (33 40 56)
Así, para crear un procedimiento, utiliza la primitiva lambda
(o forma especial):
> (define add-marks (lambda (m) (apply + m)))
> (add-marks marks)
> 129
Como los procedimientos son la forma primaria de abstracción, Scheme proporciona un atajo para define
y facilitar el enlace de nuevos procedimientos:
> (define (add-marks m) (apply + m))
Aparte de esto, los procedimientos son como todos los demás objetos de primera clase. Se pueden pasar como argumentos a otros procedimientos y un procedimiento puede evaluar para producir (o devolver) otro procedimiento.
Puede pensarlo así ... crea una función que usa otra función pero desea hacer las cosas más modulares, entonces lo que hace es llamar a la segunda función como un argumento de la primera, y eso le deja la posibilidad de cambia el segundo cuando sientas que necesitas otra funcionalidad ... espero que tenga sentido
Una let
es una lambda
.
P.ej
(let ((x 1))
body)
puede ser traducido a
((lambda (x) body) 1)
Además, en el Esquema, todas las estructuras de control y entorno pueden representarse mediante expresiones lambda y aplicaciones de lambdas.
Entonces, lambda
es estrictamente más poderosa que la let
y forma la base de muchas de las construcciones interesantes que se encuentran en el Esquema.
En cuanto a define
y lambda
, una define
nivel superior agrega un enlace al entorno de nivel superior.
Cuando escribes
(define (f x)
body)
realmente estás diciendo
(define f (lambda (x) body))
Las definiciones anidadas se traducen a letrec
, que también se pueden reescribir usando lambdas.
Entonces, una vez más, muchas construcciones de Esquema pueden traducirse en algo usando lambda
, y por lo tanto, realmente vale la pena que entiendas bien lambda
.
Utilice lambda si desea crear una función para usarla como un argumento para otra función (como por ejemplo el map
), pero en realidad no desea map
nombre a la función. Ejemplo:
Si desea agregar 42 a cada número en una lista, puede hacer:
(define (add42 x) (+ x 42))
(map add42 (list 1 2 3 4))
Pero si no quieres darle un nombre a una función que solo usas una vez, simplemente puedes hacerlo:
(map (lambda (x) (+ x 42)) (list 1 2 3 4))
lambda crea nuevas funciones anónimas, que por supuesto se evalúan cada vez que las usa.
let crea nombres temporales para los valores y se configura una vez para su uso en el alcance definido por el formulario let.
Son realmente bestias muy diferentes.
algunos ejemplos :
(lambda (x) (* 5 x))
(deje ([x 2]) (* 5 x)) 10 (deje ([f (lambda (x) (* 5 x))]) (f 2)) 10
La primera forma crea una función para multiplicar por 5.
la segunda forma asigna 2 a x y la multiplica por 5 dando como resultado 10
tercero, usamos la función de 1 (que se multiplica por 5) y la llamamos con 2 como un parámetro que también da como resultado 10