gpt4 book ai didi

clojure - 在 Common Lisp 中模拟 Clojure 风格的可调用对象

转载 作者:行者123 更新时间:2023-12-02 18:23:15 24 4
gpt4 key购买 nike

在 Clojure 中, HashMap 和向量实现 invoke,因此它们可以用作函数,例如

(let [dict {:species "Ursus horribilis"
:ornery :true
:diet "You"}]
(dict :diet))

lein> "You"

或者,对于向量,

(let [v [42 613 28]]
(v 1))

lein> 613

可以通过让 Clojure 实现 IFn 来在 Clojure 中创建可调用对象。我对 Common Lisp 还很陌生——可调用对象是可能的吗?如果是的话,实现它会涉及什么?我真的很希望能够做这样的事情

(let ((A (make-array (list n n) ...)))
(loop for i from 0 to n
for j from 0 to m
do (setf (A i j) (something i j)))
A)

而不是让代码中充斥着aref。同样,如果您可以访问其他数据结构的条目,例如字典,同样的方式。

我查看了 wiki entry在 Lisp/Scheme 中的函数对象上,似乎拥有一个单独的函数命名空间会使 CL 的问题变得复杂,而在 Scheme 中你可以使用闭包来做到这一点。

最佳答案

Common Lisp 先驱中的可调用对象示例

之前已经提供了可调用对象。例如在 Lisp Machine Lisp 中:

Command: ("abc" 1)            ; doesn't work in Common Lisp
#\b

Common Lisp 中的绑定(bind)

Common Lisp 具有独立的函数名称和值 namespace 。因此,只有当 array 是表示函数命名空间中的函数的符号时,(array 10 1 20) 才有意义。因此函数值将是一个可调用数组。

将值绑定(bind)到变量充当函数,很大程度上违背了函数和值的不同命名空间的目的。

(let ((v #(1 2 3)))          
(v 10)) ; doesn't work in Common Lisp

对于具有不同函数和值命名空间的语言,上述内容没有任何意义。

FLET 用于函数而不是 LET

(flet ((v #(1 2 3 4 5 6 7))) ; doesn't work in Common Lisp
(v 4))

这意味着我们会将数据放入函数命名空间中。我们想要那个吗?事实并非如此。

在函数调用中将文字数据作为函数。

人们还可以考虑至少允许文字数据充当直接函数调用中的函数:

(#(1 2 3 4 5 6 7) 4)         ; doesn't work in Common Lisp

而不是

(aref #(1 2 3 4 5 6 7) 4)

Common Lisp 不允许以任何微不足道或相对简单的方式做到这一点。

旁注:

人们可以在将函数和值与 CLOS 集成的方向上实现一些东西,因为 CLOS 通用函数也是类 STANDARD-GENERIC-FUNCTION 的 CLOS 实例,并且可以拥有和使用用户-定义的子类。但这通常不会被利用。

推荐

因此,最好适应不同的语言风格并按原样使用 CL。在这种情况下,Common Lisp 不够灵活,无法轻松整合这样的功能。不省略符号以进行次要代码优化是一般的 CL 风格。危险在于混淆和只写代码,因为很多信息并不直接在源代码中。

关于clojure - 在 Common Lisp 中模拟 Clojure 风格的可调用对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27995801/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com