Функция не определена.(Рекурсия) - PullRequest
0 голосов
/ 25 марта 2012

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

Вот моя функция:

(defun mem (prop L)
  (cond
    ((eq (caar L) prop) (print cadar L)))
    (t (mem (prop (cdr L))))))                   // error is on this line!

Итак, если я введу

(mem `i `((i 1) (j 2)))

, он вернёт 1. Однако, если я введу

(mem `j `((i 1) (j 2)))

он возвращает ошибку, что «функция prop не определена».

Как я могу сообщить программе, что prop - это не функция, а просто входной параметр?

Это моя первая программа lisp, поэтому я предполагаю, что ответ невероятныйпросто, но я много чего перепробовал и пока не добился успеха.

1 Ответ

4 голосов
/ 25 марта 2012

В частности, проблема в фрагменте: (prop (cdr L)).Это пытается вызвать prop, передавая (cdr L).Чтобы передать его в качестве аргумента mem, просто пропустите лишние скобки: (mem prop (cdr L)).

Если у вас возникла проблема с определением места, где ставить скобки, обратите внимание, что синтаксис Lisp оченьаналогично математическому синтаксису для функций, за исключением того, что функция идет внутри скобок (и вы используете пробелы вместо запятых, но здесь это не проблема).Например, в математической записи у вас есть: mem(prop(cdr(L))) вместо mem(prop, cdr(L)).

Другие проблемы

Похоже, у вас есть дополнительные скобки после первой ветви cond, что заканчивается рано.Используйте редактор / IDE с соответствующими круглыми скобками, чтобы поймать такого рода ошибки.Emacs делает это, как DrRacket .Первый может использоваться с Common LISP через SLIME (поиск в Интернете инструкций по настройке для вашей платформы), в то время как последний легко поддерживает Scheme.

Точка с запятой (";")это символ комментария, используемый в большинстве LISP.

print не требуется для этой функции и (в зависимости от его поведения) может быть неправильным.В некоторых LISP (например, Common LISP) он возвращает свой аргумент, но в других он может вернуть nil или экземпляр некоторого типа void.

Квазицитат (он же обратная цитата * 1029)*, backtick) также не требуется.Quasiquote позволяет вам заключить в кавычки некоторые символы, в то время как другие (с префиксом запятой) заменяются их значениями.Поскольку вам не требуется подстановка в выражениях в кавычках, будет работать простая кавычка: (mem 'j '((i 1) (j 2))).

Для удобства чтения вставьте больше пробелов между закрывающими и открывающими скобками.

...