cor*_*ump 1 lisp functional-programming common-lisp
为什么funcall没有语法糖?我们需要它很多.写一些像是为什么不添加类似Ruby的&:方法表示法的东西(&#do-something arg0 arg1 arg2)不是很好(funcall do-something arg0 arg1 arg2)吗?语言中是否有某些内容?
语言中没有任何内容; 您可以轻松地将该功能分配给其他名称,并使用它.例如,如果您想使用&,您可以:
CL-USER> (setf (symbol-function '&) (symbol-function 'funcall))
#<FUNCTION FUNCALL>
CL-USER> (&'list 1 2 3)
(1 2 3)
CL-USER> (&'cons 'x 'y)
(X . Y)
Run Code Online (Sandbox Code Playgroud)
(最近有一个关于Stack Overflow的问题,关于第一行的不同方法:如何在作为函数参数传递时停止评估lisp表单?)
写一些
(&#do-something arg0 arg1 arg2)代替的东西不是很好(funcall do-something arg0 arg1 arg2)吗?
可能不是.Common Lisp是一种更喜欢函数和宏的表达名称的语言.名称funcall被识别,它清楚地表明存在间接函数调用.我们为什么要模糊这一点?显然,大多数人发现funcall在"足够短的写入"和"足够长的描述性"之间有适当的平衡.
为什么funcall没有语法糖?
您可以在Common Lisp中调用宏"语法糖",但这里不需要它.Funcall是一个函数,而不是一个特殊的形式或宏,因此很容易用另一个名称对它进行别名,如上所示.大多数人不这样做的事实应该说明它是多么令人满意.
没有语法funcall,因为我们不需要它(或者,定义"我们").我的意思是,在Lisp-2中,比如Common Lisp,这是权衡,除非你做一些重的lambda演算,否则你会习惯它.
如果您真的想使用更多succint语法,可以定义一个调度宏字符:
(set-dispatch-macro-character
#\# #\&
#'(lambda (stream subchar arg)
(let ((args-var (gensym)))
`(lambda (&rest ,args-var)
(declare (dynamic-extent ,args-var))
(apply ,(read stream t nil t) ,args-var)))))
(let ((my-function #'max))
(#&my-function 1 3 2))
Run Code Online (Sandbox Code Playgroud)
检查您的编译器是否会优化传递给的lambda表单和参数.dynamic-extent &restapply
我建议不要定义单个字符&作为宏观性质,因为它是一个组成部分字符大多在符号中使用&optional,&rest,&key,&allow-other-keys,&aux,&whole,&body和&environment.