2010-06-28 11 views
6

Decidí aprender LISP hoy, y he estado jugando un poco con eso. Escribí una función simple de bebé solo para poner a prueba mi comprensión, y ahora entiendo que mi comprensión no comprende tanto como yo lo había entendido. : DLa función LISP simple no funciona

De todos modos, aquí está la función. La idea es que cuando se llame, p. (esexp base x) debe devolver el valor base^x. Por lo tanto (3 esexp 4) = 3^4 = 81.

(estoy usando la aplicación CMU de Common Lisp, si lo que importa.)

(defun esexp (base x) 
    (if (= x 0) 
     1 
     (if (< x 0) 
      (/ esexp (base (+ x 1)) base) 
      (* esexp (base (+ x 1)) base)))) 

Esto no funciona. Obtengo errores que parecen (Advertencia: Esta variable no está definida: SLBEXP) y (Error en KERNEL :: UNBOUND-SYMBOL-ERROR-HANDLER: la variable SLBEXP está desatada.) Entonces. ¿Qué estoy haciendo mal? ¿Y habría una mejor (o más forma LISP-ish) para escribir esta función?

ETA

código corregido:

(defun esexp (base x) 
    (if (= x 0) 
     1 
     (if (< x 0) 
      (/ (esexp base (+ x 1)) base) 
      (* (esexp base (- x 1)) base)))) 

Respuesta

11

esexp(base (+ x 1))

debe ser

(esexp base (+ x 1))

esexp es una función igual +. La sintaxis para invocar una función es

(function-name arg1 arg2 ...) 
+0

Ah duh. Gracias. – Asker

0

Solo una nota sobre el código. Creo que debería ser

(defun esexp (base x) 
     (if (= x 0) 
       1 
       (if (< x 0) 
         (/ (esexp(base (+ x 1)) base)) 
         (* (esexp(base (- x 1)) base)))) 

De lo contrario, la función nunca terminará. (Había (* (esexp(base (+ x 1)) base)))))

+0

Además, gracias. Eso fue un error en la transcripción. – Asker

5

La explicación técnica del error: el compilador analizaba el código:

(/ esexp(base (+ x 1)) base) 

como esto:

(/ esexp (base (+ x 1)) base) 

que dice:

  • primera , agregue 1 al parámetro x
  • luego, invoque una función llamada base con el resultado anterior.
  • divide el valor de variable llamado esexp por el resultado anterior.
  • luego, divida ese resultado por el parámetro base. (El operador de división en Common Lisp puede tomar más de dos argumentos.)

¿Ves el truco? Cuando una palabra aparece como el primer elemento en una expresión s (y esa expresión s no se cita), generalmente se trata como el nombre de una función que desea invocar. De lo contrario, se trata como el nombre de una variable cuyo valor desea recuperar.Además, en Common Lisp, un símbolo como esexp puede vincularse a un valor de función y un valor de variable al mismo tiempo; el contexto o expresiones especiales como #'esexp (que significa la función) se utilizan para determinar a cuál te refieres.

El compilador le estaba diciendo que, aunque esexp estaba destinado a una funcióncon su estado de defun, que todavía no se había unido a un valor variable de , y por lo tanto no podía ser utilizado como tal. Por lo tanto, el error.