pal*_*ind 16 lisp common-lisp tacit-programming
是否可以在Lisp中使用/实现默认编程(也称为无点编程)?如果答案是肯定的,它已经完成了吗?
dan*_*lei 14
这种编程风格原则上可以在CL中实现,但是,作为一个Lisp-2,必须添加几个#'s和funcalls.此外,与Haskell相比,例如,CL中没有函数,并且没有隐式的部分应用程序.一般来说,我认为这样的风格不会是非常惯用的CL.
例如,您可以像这样定义部分应用程序和组合:
(defun partial (function &rest args)
(lambda (&rest args2) (apply function (append args args2))))
(defun comp (&rest functions)
(flet ((step (f g) (lambda (x) (funcall f (funcall g x)))))
(reduce #'step functions :initial-value #'identity)))
Run Code Online (Sandbox Code Playgroud)
(这些只是我掀起的简单例子 - 对于不同的用例,它们并没有真正经过测试或深思熟虑.)
有了这些,map ((*2) . (+1)) xsHaskell之类的东西变成了:
CL-USER> (mapcar (comp (partial #'* 2) #'1+) '(1 2 3))
(4 6 8)
Run Code Online (Sandbox Code Playgroud)
的sum例子:
CL-USER> (defparameter *sum* (partial #'reduce #'+))
*SUM*
CL-USER> (funcall *sum* '(1 2 3))
6
Run Code Online (Sandbox Code Playgroud)
(在此示例中,您还可以设置符号的函数单元格,而不是将函数存储在值单元格中,以绕过funcall.)
顺便说一下,在Emacs Lisp中,部分应用程序是内置的apply-partially.
在Qi/Shen中,函数是curry,并且支持隐式部分应用(当使用一个参数调用函数时):
(41-) (define comp F G -> (/. X (F (G X))))
comp
(42-) ((comp (* 2) (+ 1)) 1)
4
(43-) (map (comp (* 2) (+ 1)) [1 2 3])
[4 6 8]
Run Code Online (Sandbox Code Playgroud)
在Clojure中还有一个语法线程糖,给出了类似的"流水线"感觉:
user=> (-> 0 inc (* 2))
2
Run Code Online (Sandbox Code Playgroud)
你可以使用类似的东西(这比->Clojure 更多):
(defmacro -> (obj &rest forms)
"Similar to the -> macro from clojure, but with a tweak: if there is
a $ symbol somewhere in the form, the object is not added as the
first argument to the form, but instead replaces the $ symbol."
(if forms
(if (consp (car forms))
(let* ((first-form (first forms))
(other-forms (rest forms))
(pos (position '$ first-form)))
(if pos
`(-> ,(append (subseq first-form 0 pos)
(list obj)
(subseq first-form (1+ pos)))
,@other-forms)
`(-> ,(list* (first first-form) obj (rest first-form))
,@other-forms)))
`(-> ,(list (car forms) obj)
,@(cdr forms)))
obj))
Run Code Online (Sandbox Code Playgroud)
(你必须小心也$从你放置的包中导出符号->- 让我们调用那个包tacit- 然后放入
你打算使用的任何包tacit的use子句->,这样->并$继承)
用法示例:
(-> "TEST"
string-downcase
reverse)
(-> "TEST"
reverse
(elt $ 1))
Run Code Online (Sandbox Code Playgroud)
这更像是F#|>(和shell管道)而不是Haskell .,但它们几乎是一样的(我更喜欢|>,但这是个人品味的问题).
要查看->正在做什么,只需宏示宏三次最后一个示例(在SLIME中,这是通过将光标放在(示例中的第一个并键入C-c RET三次来完成的).