Вопрос Picolisp, segfault при манипулировании списками чисел (из списка рассылки) - PullRequest
3 голосов
/ 11 ноября 2009

Я новичок в Picolisp.

Я попробовал это, и получил segfault:

: ('(1 2) 6)
Segmentation fault

Но, если я попробую:

: ('(a b c) 6)
-> NIL

Я в основном понимаю, почему, но было удивительно, что PicoLisp ответил с ошибкой в ​​виде сегфоута вместо ошибки. Означает ли это, что Picolisp не проверяет, является ли число функцией, а делает, когда это символ?

1 Ответ

3 голосов
/ 11 ноября 2009

(снято с список рассылки picolisp .)

Да, это ожидаемое поведение.

PicoLisp оценивает CAR списка, возможно, несколько раз, пока не достигнет на функции. Функция - это либо список (тогда это уровень Lisp функция) или короткий номер (тогда это встроенная функция, написанная в либо АСМ или С). Если это число не указывает на исполняемый код (что трудно проверить во время выполнения), происходит сбой.

Я бы посчитал такой сбой "расширенным сообщением об ошибке": почему бы не аппаратное обеспечение (MMU) проверять во время выполнения?

Как правило, переводчик не может поймать возможная ошибка (например, бесконечные циклы), поэтому PicoLisp принимает Стенд возложить некоторую ответственность на программиста.

На практике ошибка, подобная вышеописанной, будет обнаружена при первом тестовый прогон вашей программы.

Кстати, исключением из вышеприведенного правила является только список, который имеет номер в своей машине. Такой список автоматически оценивает:

   : (1 2 3)
   -> (1 2 3)

Это просто удобная функция, не требующая цитирования таких константных списков.

: ('(a b c) 6)
-> NIL

Я в основном понимаю, почему, но это было удивительно, что Picolisp ответил Segfault вместо ошибки. Есть ли это означает, что Picolisp не проверяет если число является функцией, но оно делает когда это символ?

В этом случае (a b c) фактически является юридическим определением функции: функция с единственным символическим параметром «а» (так что функция не оцените его аргументы) и тело из двух символов. Это эквивалентно до

   : (de foo a
      b
      c )
   -> foo

Когда эта функция выполняется, она связывает список аргументов (3) с этим символ «а», затем выполняет «б» и «с». Эта функция возвращает значение «с», который был NIL в вашем примере.

Когда вы делаете:

: (de foo H H) 

: (foo 1 2 3)
-> (1 2 3) 

: foo
-> (H H)

так что вы также можете сделать:

: ('(H H) 1 2 3)
-> (1 2 3)

Правильно.

Бьюсь об заклад, вы знаете, что здесь происходит; вы пытаются использовать номер в качестве переменная, которая недопустима -> падение (к тому же это не имеет смысла в любом случае)

Это правильно, что вы сказали. Переводчик нажимает на «1» на месте ожидаемого параметра функции.

   : (setq 7 5)  
   !? (setq 7 5)
   7 -- Variable expected
   ?
...