Error común de ceceo: “debería ser una expresión lambda”

Acabo de empezar a aprender Common Lisp hace unos días, y estoy tratando de crear una función que inserte un número en un árbol. Me aparece un error,

*** – SYSTEM ::% EXPAND-FORM: (CONS NIL LST) debe ser una expresión lambda

De buscar en Google, parece que esto sucede cuando tienes demasiados conjuntos de paréntesis, pero después de mirar esto durante una hora más o menos y cambiar las cosas, no puedo entender dónde podría estar haciendo esto.

Este es el código donde está sucediendo:

(defun insert (lst probe) (cond ((null lst) (cons probe lst)) ((equal (length lst) 1) (if (<= probe (first lst)) (cons probe lst) (append lst (list probe)))) ((equal (length lst) 2) ((cons nil lst) (append lst nil) (insertat nil lst 3) (cond (( probe (fourth lst)) (insert (fifth lst) probe)) (t (insert (third lst) probe))))))) 

Estoy bastante seguro de que está ocurriendo después de ((igual (longitud lst) 2), donde la idea es insertar una lista vacía en la lista existente, luego agregar una lista vacía al final, luego insertar una lista vacía en el medio .

¡Correcto! El problema está en la línea justo después de eso, donde dice

 ((cons nil lst) (append lst nil) (insertat nil lst 3) ... 

El problema son los dos paréntesis de apertura. Los paréntesis pueden cambiar el significado en contextos especiales (como el formulario de cond que está usando), pero en este contexto, los paréntesis significan una aplicación de función normal, tal como probablemente esté acostumbrado. Eso significa que lo primero después de los paréntesis debe ser una función. Desde la perspectiva de los paréntesis externos , lo primero es (cons nil lst) , por lo que debe ser una función (que no lo es).

Tenga en cuenta que no puede simplemente eliminar los paréntesis, ya que la función cons devuelve una nueva lista como usted quiere pero no cambia la lista anterior. Probablemente quieras algo como esto:

 (setq lst (cons nil lst)) (setq lst (append lst nil)) (setq lst (insertat nil lst 3)) ... 

Si sangra la función correctamente, entonces puede ver que hay un paréntesis adicional frente a CONS NIL LST.

 (defun insert (lst probe) (cond ((null lst) (cons probe lst)) ((equal (length lst) 1) (if (<= probe (first lst)) (cons probe lst) (append lst (list probe)))) ((equal (length lst) 2) ((cons nil lst) (append lst nil) (insertat nil lst 3) (cond ((<= probe (second lst)) (insert (first lst) probe)) ((> probe (fourth lst)) (insert (fifth lst) probe)) (t (insert (third lst) probe))))))) 

En la mayoría de los IDE de Lisp puedes aplicar sangrías a las expresiones. En LispWorks, seleccione la expresión completa y haga mx Sangría región.

Para arreglar el error inmediato, simplemente puede agregar un PROGN allí antes (CONS NIL …). PROGN funciona evaluando cada formulario en él y devuelve el valor de la última forma en él como su valor.

Sin embargo, su progtwig aún no hará lo que usted cree que hará (supongo). Ya sabes, en Common Lisp utilizas el primer objeto cons para representar toda la lista no vacía, y no puedes simplemente reemplazar las contras principales. La mejor manera es devolver la nueva lista como el valor de la función.

 (defun insert (lst probe) (ecase (length lst) (0 (list probe)) (1 (let ((c (first lst))) (if (<= probe c) (list probe c) (list c probe)))) (2 (cond ((<= probe (first lst)) (list probe (first lst) nil (second lst) nil)) ((> probe (second lst)) (list nil (first lst) nil (second lst) probe)) (t (list nil (first lst) probe (second lst) nil)))))) 

Tal vez quieras (setf lst (insert lst [some-number])) cuando usas esta función.

Tienes razón; en la línea marcada con “error aquí”, hay un error de syntax:

 (defun insert (lst probe) (cond ((null lst) (cons probe lst)) ((equal (length lst) 1) (if (<= probe (first lst)) (cons probe lst) (append lst (list probe)))) ((equal (length lst) 2) (#|Error is here|# (cons nil lst) (append lst nil) (insertat nil lst 3) (cond ((<= probe (second lst)) (insert (first lst) probe)) ((> probe (fourth lst)) (insert (fifth lst) probe)) (t (insert (third lst) probe))))))) 

Para el comstackdor / intérprete, el formulario se lee como una llamada de función a la “función” (cons nil list) que no es una función en absoluto. El comstackdor se queja aquí sobre el uso de una forma compuesta en la posición “operador”, que no es una lambda (el único tipo de formulario compuesto aceptado en esa posición).

 ((cons nil lst) #| <-- Form in operator position |# (append lst nil) #| <-- First argument form |# (insertat nil lst 3) #| <-- Second argument form |# (cond ((<= probe (second lst)) (insert (first lst) probe)) #| Third argument |# ((> probe (fourth lst)) (insert (fifth lst) probe)) (t (insert (third lst) probe)))) 

Ayudaría con la reformulación de la expresión, pero no estoy seguro de lo que quiere lograr aquí.

    Intereting Posts