用于funcall的语法糖?

cor*_*ump 1 lisp functional-programming common-lisp

为什么funcall没有语法糖?我们需要它很多.写一些像是为什么不添加类似Ruby的&:方法表示法的东西(&#do-something arg0 arg1 arg2)不是很好(funcall do-something arg0 arg1 arg2)吗?语言中是否有某些内容?

Jos*_*lor 7

语言中没有任何内容; 您可以轻松地将该功能分配给其他名称,并使用它.例如,如果您想使用&,您可以:

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是一个函数,而不是一个特殊的形式或宏,因此容易用另一个名称对它进行别名,如上所示.大多数人这样做的事实应该说明它是多么令人满意.


ace*_*ent 6

没有语法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.