我是 Picolisp 的新手。
我尝试了这个,并获得了一个段错误:
: ('(1 2) 6)
Segmentation fault
但是,如果我尝试:
: ('(a b c) 6)
-> NIL
我基本明白为什么,但令人惊讶的是 PicoLisp 以段错误而不是错误响应。这是否意味着 Picolisp 不检查数字是否为函数,但当它是符号时它会检查?
(从picolisp 邮件列表中提取。)
是的,这是预期的行为。
PicoLisp 可能会重复评估列表的 CAR,直到遇到一个函数。函数要么是一个列表(那么它是一个 Lisp 级别的函数),要么是一个短数字(那么它是一个内置函数,用 asm 或 C 编写)。如果该数字不指向可执行代码(在运行时很难检查),则会发生崩溃。
我会认为这样的崩溃是“扩展错误消息”:为什么不让硬件(MMU)进行运行时检查?
一般来说,解释器不可能捕捉到任何可能的错误(例如,想想无限循环),所以 PicoLisp 采取了让程序员承担一些责任的立场。
实际上,在程序的第一次测试运行时会检测到类似上述错误。
顺便说一句,上述规则的一个例外只是一个在其 CAR 中直接包含数字的列表。这样的列表会自动评估:
: (1 2 3)
-> (1 2 3)
只是一个方便的功能,不必引用这样的常量列表。
: ('(a b c) 6)
-> NIL
我基本明白为什么,但令人惊讶的是,Picolisp 以段错误而不是错误响应。这是否意味着 Picolisp 不检查数字是否为函数,但当它是符号时它会检查?
在这种情况下,(abc) 实际上是一个合法的函数定义:它是一个具有单个符号参数“a”的函数(因此该函数不会评估其参数)和两个符号的主体。这相当于
: (de foo a
b
c )
-> foo
执行此函数时,它将参数列表 (3) 绑定到该符号“a”,然后执行“b”和“c”。此函数返回“c”的值,在您的示例中为 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
?