【问题标题】:What should we call an object declared in a clojure prog?我们应该怎样称呼在 clojure prog 中声明的对象?
【发布时间】:2023-03-14 15:14:01
【问题描述】:

当我们谈论 clojure (或其他 lisp) prog 时,当引用其中声明的对象时我们应该说什么?例如:

(let [a ...

当然,如果a是一个函数,我们说function a,但是当它不是一个函数的时候我们应该说什么呢? 表格数据符号文字

一般来说,我们用其他编程语言variablesobjects说这些东西。

【问题讨论】:

    标签: clojure scheme lisp


    【解决方案1】:

    let 特殊形式在符号之间创建绑定

    let 的官方文档实际上使用了您正在寻找和应该使用的词汇和措辞,特别是 Binding Forms 部分更加阐明了该主题:

    基本思想是绑定形式可以是包含符号[或只是单个符号]的数据结构文字,这些符号被绑定到 init-expr 的各个部分。

    【讨论】:

    • 我的问题不限于let表单。
    • @xando 答案不仅限于let 形式,它推广到Clojure 中需要绑定形式的每个特殊形式和表达式(即letloop、@ 中的参数向量987654329@等)。您还想到了哪些其他案例? def 有点不同,但 binding 的概念仍然存在。
    【解决方案2】:

    我认为这个问题混淆了两件事,或者至少没有明确说明它们是不同的。

    正如到目前为止的其他答案所示,“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 互操作技巧也不遵循相同的规则。

    【讨论】:

    • 所以,在一般情况下,将 clojure prog 中声明的任何内容说成 symbol 是否合适?
    • 鉴于您可能的意思,这是正确的。也许这取决于你所说的“任何声明的......”是什么意思。您可能不仅仅指“出现在declare 语句中的任何内容”,即像(declare ...) 这样的表达式中的任何内容,而且我不确定Clojure 对于“声明”有任何其他含义。 “符号”一词在 Clojure 中具有精确的含义,herehere
    • 另请注意,即使声明的任何东西都是符号,但并非所有符号都被声明。如果你只是在 repl 提示符下输入 foo,它就是一个符号,即使它没有被定义或声明或绑定或任何东西。
    【解决方案3】:

    a 始终是一个符号,与绑定到它的值无关(无论是函数还是数字或其他任何东西)

    之前有一个关于 Clojure 符号的答案,可能会在这里更清楚地说明问题:Symbols in Clojure

    记住symbols are not the same thing as vars

    【讨论】:

      猜你喜欢
      • 2012-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-03
      相关资源
      最近更新 更多