【发布时间】:2023-03-14 15:14:01
【问题描述】:
当我们谈论 clojure (或其他 lisp) prog 时,当引用其中声明的对象时我们应该说什么?例如:
(let [a ...
当然,如果a是一个函数,我们说function a,但是当它不是一个函数的时候我们应该说什么呢? 表格? 数据? 符号? 文字?
一般来说,我们用其他编程语言variables或objects说这些东西。
【问题讨论】:
当我们谈论 clojure (或其他 lisp) prog 时,当引用其中声明的对象时我们应该说什么?例如:
(let [a ...
当然,如果a是一个函数,我们说function a,但是当它不是一个函数的时候我们应该说什么呢? 表格? 数据? 符号? 文字?
一般来说,我们用其他编程语言variables或objects说这些东西。
【问题讨论】:
let 特殊形式在符号和值之间创建绑定。
let 的官方文档实际上使用了您正在寻找和应该使用的词汇和措辞,特别是 Binding Forms 部分更加阐明了该主题:
基本思想是绑定形式可以是包含符号[或只是单个符号]的数据结构文字,这些符号被绑定到 init-expr 的各个部分。
【讨论】:
let表单。
let 形式,它推广到Clojure 中需要绑定形式的每个特殊形式和表达式(即let、loop、@ 中的参数向量987654329@等)。您还想到了哪些其他案例? def 有点不同,但 binding 的概念仍然存在。
我认为这个问题混淆了两件事,或者至少没有明确说明它们是不同的。
正如到目前为止的其他答案所示,“a”是一个符号,它的计算结果是别的东西。因此,当我们谈论a 时,我们可能指的是符号或其他东西。我们甚至可以指作为符号和其他东西之间的中介的 var。 (有关 var/symbol 关系的更多信息,请参阅 Guillermo Winkler 链接的页面,我将在后台保留它。)
符号永远不是函数,但它可以有一个函数作为它的值。当你调用一个函数时,你只是以一种特殊的方式使用它的值。您甚至可以将内置函数的值设置为其他值:
(def + -)
WARNING: + already refers to: #'clojure.core/+ in namespace: user, being replaced by: #'user/+
#'user/+
user=> (+ 5 2)
3
user=> (def - "This used to be the minus function")
WARNING: - already refers to: #'clojure.core/- in namespace: user, being replaced by: #'user/-
#'user/-
user=> -
"This used to be the minus function"
我给了+-的值,然后把-的值变成了一个字符串。 (是的,有警告,但它起作用了。)函数只是符号的值这一事实是 Clojure 与许多其他语言的不同之处。 (方案类似。Common Lisp 类似,但方式更复杂。)
所以符号就是符号。它通常有一个值,可能是一个函数,或者一个数字,或者一个字符串,或者一个关键字,或者任何在 Clojure 中可以是值的东西——向量、惰性序列、列表(可能是 Clojure 代码),甚至是另一个符号(甚至是同一个符号:(def a 'a)。)如果在特定上下文中有用,您可以将其中一些东西称为数据。有时将函数描述为 Clojure 中的数据是合理的。
(def add-fns [#(+ 1 %) #(+ 2 %) #(+ 3 %)]) ;=> #'user/add-fns
add-fns ;=> [#object[user$fn__1178 0x71784911 "user$fn__1178@71784911"] #object[user$fn__1180 0x45ed957d "user$fn__1180@45ed957d"] #object[user$fn__1182 0x7838c8c5 "user$fn__1182@7838c8c5"]]
add-fns 是一个函数向量。我们应该怎样称呼作为向量元素的函数?如果我们像数据一样使用它们,它们不是某种意义上的数据吗?我们可以在它们上映射一个函数,或者重新排序它们,例如:
(map #(% 10) add-fns) ;=> (11 12 13)
(map #(% 10) (reverse add-fns)) ;=> (13 12 11)
这些表达式中的每一个都接受add-fns 中的每个函数,并以 10 作为参数调用它,并按顺序返回结果。
例外:宏不遵循相同的规则:
user=> and
CompilerException java.lang.RuntimeException: Can't take value of a macro: ...
一些 Java 互操作技巧也不遵循相同的规则。
【讨论】:
foo,它就是一个符号,即使它没有被定义或声明或绑定或任何东西。
a 始终是一个符号,与绑定到它的值无关(无论是函数还是数字或其他任何东西)
之前有一个关于 Clojure 符号的答案,可能会在这里更清楚地说明问题:Symbols in Clojure
【讨论】: