是否存在一个list的car是另一个list并且它本身可以求值(evaluate)

即是否存在 ((a)) 可以求值

Elisp:

Elisp 的调用表达式中第一项必须是 lambda 表达式或者函数名符号

(defun a () (lambda () 1))
;;=> a
(funcall (a))
;;=> 1

Racket

(define (a) (λ () 1))
((a))
;;=> 1
1 个赞

也就是说emacs的解释器无法做到。感谢指导 :pray:

可以看看 Elisp Manual 中的函数相关章节

草,很早之前碰到过这个问题: 由 (λ(x)(x x)) 看 elisp 与 scheme 之区别

说起来,C语言不使用循环和跳转,也不定义递归函数,制造循环或许也是可行的。C里面的循环和跳转是严格对应跳转指令的,函数也严格对应调用指令,这两类指令以外是不存在第三类本地跳转的。然而,如果允许操作系统层面的操作,可以直接控制mmu,那么,程序结束时,把它的代码段所在的页的首地址映射成此时进程的指令地址,然后刷新icache,此时icache抓到的指令就是从原来的代码段首地址开始抓,这样不停地滑动地址,就可以达到循环的效果了。代码看起来应该是这样:

__attribute__((noreturn)) void f(void) 
{
    /* do something here */
    // slide page address back
    map_page(to_phys_addr(f), END);
    // flush icache
    __builtin___clear_cache(f, f + PAGE_SIZE);
    barrier();
END:
}


1 个赞

有点 6,我研究一下去。

当时写的时候没考虑这么多,也许拿个更高级的语言举例更好,比如 Python :joy:

Tcl 也可以 :joy:

proc a {} {lindex 1}
# => {}
[list [list a]]
# => 1

然而它的机制和 Lisp 是不一样的。继续实验会发现:

[list [list [list [list a]]]]
# => 1
[list [list [list [list [list [list a]]]]]]
# => 1

这是因为在 evaluate 的时候, 会强制取 list 的第一个元素的字符串表示,并将其作为命令名。这时它已经不再是(准确来说,是不再表示为)一个 list 了。

如果要用「更像」Lisp 的匿名函数写法,那就是:

set a [list {} {lindex 1}]
# => {{} {lindex 1}}
apply $a
# => 1

不对,好像已经歪楼了(逃

2 个赞