Принципы биомедицинской информатики в SBCL: что не так с этим пусть? - PullRequest
0 голосов
/ 06 июня 2018

Lisp noob здесь, склонен полагать, что я, безусловно, что-то неправильно понимаю, так как это проблема со страницы 35 довольно длинной книги о ее втором издании.Я читал о let привязке, поэтому позвольте мне удостовериться в том, что автор * намерения ясен, цитируя его:

В следующем коде символ pos служит временным хранилищемили переменная, которая имеет в качестве значения результат выражения функции position.Наконец, как мы будем накапливать результаты?Рекурсивный вызов должен дать нам список оставшихся позиций, поэтому первую найденную позицию нужно просто поставить на передний план.У нас уже есть функция для этого, cons функция

Это код:

(defun all-pos (item seq start)
  (let ((pos (position item seq :start start))
    (if pos
        (cons pos
          (all-pos item seq (+ 1 pos)))
    nil))))

и это ошибка:

Ch1_Notes.lisp:27:5:
  error: 
    The LET binding spec (IF POS
                             (CONS POS (ALL-POS ITEM SEQ (+ 1 POS)))
                             NIL) is malformed.

Compilation failed.

Это, очевидно, неправильно?Есть ли какой-то предыдущий код, который я тоже должен включить?

* Автор, Ира Дж. Калет, мертв, поэтому я не могу его спросить.

Ответы [ 3 ]

0 голосов
/ 06 июня 2018

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

Но Lisp также поставляется со встроенным форматированием кода, которое называется pretty printing :

CL-USER > (let ((*print-right-margin* 60))
 (pprint '

; your code follows:

(defun all-pos (item seq start)
  (let ((pos (position item seq :start start))
    (if pos
        (cons pos
          (all-pos item seq (+ 1 pos)))
    nil))))

))

Выходные данные выглядят так:

(DEFUN ALL-POS (ITEM SEQ START)
  (LET ((POS (POSITION ITEM SEQ :START START))
        (IF POS (CONS POS (ALL-POS ITEM SEQ (+ 1 POS)))
         NIL))))

Это облегчает понимание того, что if находится на том же уровне отступа, что и привязка переменной pos. Это не может быть правильно!

Чтобы отформатировать код с помощью Lisp, вам просто нужно:

(let ((*print-right-margin* 60))
  (pprint '

; here goes your code

))

и Lisp отформатирует его для вас ...

0 голосов
/ 07 июня 2018

Как отмечали ответчики до меня, проблема с простыми скобками:

;; correct version:

(defun all-pos (item seq start)
  (let ((pos (position item seq :start start)))
     (if pos
         (cons pos
               (all-pos item seq (+ 1 pos)))
  nil)))

;; e.g.
(all-pos '3 '(1 2 3 4 3 5 4) 0)
;; returns (2 4) - correctly
0 голосов
/ 06 июня 2018

Похоже, у вас проблема с неуравновешенными паразитами.Чтобы увидеть это, посмотрите закрывающую скобку после NIL.Это закрывает заявление IF.После этого есть еще два закрывающих, которые закрывают LET и DEFUN.Тем не менее, у вас еще есть еще один после этого.Вот что является причиной проблемы.

...