2012-06-25 9 views
7

estoy tratando de escribir algo de mi primer código en Emacs Lisp y no puedo entender el comportamiento siguienteOrden de Evaluación en Emacs Lisp

(defun sq (x) (* x x)) 

(member 9 '(1 2 3 4 (sq 3))) 

Esto se evalúa como nil pero el valor que estaba esperando era (9)

Ahora supongo que * emacs lisp usa la evaluación de solicitud de pedido, entonces, ¿por qué no se evaluó la lista antes de aplicar la función?

Ya que necesitaba sólo para probar una condición no nulo, por fin pude hacer que funcione de la siguiente manera,

(member 9 (cons (sq 3) '(1 2 3 4))) 

que evalúa a (9 1 2 3 4)

Mi pregunta es ¿Esto funciona porque (sq 3) es un argumento "directo" a una función (contras) a diferencia del ejemplo anterior donde era un elemento dentro de un argumento? ¿Está utilizando cons una solución aceptable aquí o existe una forma mejor/correcta de obtener el comportamiento deseado?

* Si bien no pude averiguar con certeza qué orden de evaluación usa emacs lisp, probé la misma expresión en el intérprete de esquemas y obtuve la misma respuesta y desde el SICP sé que el esquema usa evaluación de orden aplicativa. ¡Ahora estoy realmente confundido!

Cualquier ayuda apreciada.

Respuesta

16

El problema es que está citando la lista y, por lo tanto, ninguno de sus elementos se evaluará, sino que simplemente se pasará como símbolos literales. Si desea evaluar determinados elementos de la lista, mientras que pasa en otros como literales, la forma más conveniente es utilizar la comilla inversa, es decir:

(member 9 `(1 2 3 4 ,(sq 3))) 

backquote comporta de forma idéntica a la cotización normal, excepto que los elementos de la lista precedido mediante una coma se evalúan, y el resultado de la evaluación se vuelve a incluir en la lista.

Como alternativa, puede utilizar la función de list, que evalúa sus parámetros (a menos que explícitamente citado):

(member 9 (list 1 2 3 4 (sq 3))) 
+0

Muchas gracias. Eso fue útil :) – naiquevin

+1

@naiquevin, mi placer. –