Ошибка языка Common LISP: “должно быть лямбда-выражение”

Я только что начал изучать язык Common LISP несколько дней назад, и я пытаюсь создать функцию, которая вставляет число в дерево. Я получаю ошибку,

*** - СИСТЕМА:: %EXPAND-ФОРМА: (CONS NIL LST), должно быть лямбда-выражение

От поиска с помощью Google вокруг, кажется, что это происходит, когда у Вас есть слишком много наборов круглой скобки, но после рассмотрения этого в течение приблизительно одного часа и менять вещи, я не могу выяснить, где я мог делать это.

Это - код, где это происходит:

(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)))))))

Я вполне уверен, это происходит после ((равный (длина LST) 2), где идея состоит в том, чтобы вставить пустой список в существующий список, затем добавить пустой список на конец, затем вставить пустой список в середину.

9
задан Rainer Joswig 25 February 2016 в 15:11
поделиться

3 ответа

Верно! Проблема в строке сразу после этого, где написано

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

Проблема в двух открывающих скобках. Круглые скобки могут изменять значение в определенных контекстах (например, в форме cond , которую вы используете), но в этом контексте круглые скобки обозначают обычное приложение функции, как вы, вероятно, привыкли. Это означает, что первым после круглых скобок должна быть функция. С точки зрения внешних круглых скобок, первое - это (cons nil lst) , так что это должна быть функция (а это не так).

Обратите внимание, что вы не можете просто удалить круглые скобки, потому что функция cons возвращает новый список, как вы хотите, но не изменяет старый список. Вы, вероятно, захотите что-то вроде этого:

(setq lst (cons nil lst))
(setq lst (append lst nil))
(setq lst (insertat nil lst 3))
...
5
ответ дан 4 December 2019 в 13:46
поделиться

Вы правы; в строке, помеченной как «error is here», имеется синтаксическая ошибка:

(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)))))))

Для компилятора / интерпретатора форма читается как вызов функции для «function» (cons nil list) , который это вообще не функция. Здесь компилятор жалуется на использование составной формы в позиции «оператор», которая не является лямбда (единственный вид составной формы, принятой в этой позиции).

((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))))

Я бы помог с этим. переформулирую выражение, но я не уверен, чего вы хотите здесь достичь.

1
ответ дан 4 December 2019 в 13:46
поделиться

Если вы правильно сделаете отступ для функции, то увидите, что перед 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)))))))

В большинстве IDE Lisp вы можете использовать отступ в выражениях. В LispWorks выберите все выражение и выполните m-x Indent Region.

7
ответ дан 4 December 2019 в 13:46
поделиться