Clojure字符串到符号计算结果错误 [英] Clojure string to symbol evaluates to wrong result

查看:131
本文介绍了Clojure字符串到符号计算结果错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

user=> ((symbol "or") true false)
false
user=> (or true false)
true

为什么第一个表单求值 false ?我想象两个输入表单是等效的。

Why does the first form evaluate to false? I'd imagine the two input forms being equivalent.

奇怪的是,颠倒参数的顺序工作原理:

Strangely, reversing the order of the arguments works:

user=> ((symbol "or") false true)
true
user => (or false true)
true


推荐答案

你评估列表(或真假),Clojure首先评估第一个项目。在这种情况下,第一个项目是一个命名宏的符号,因此Clojure扩展了宏并评估了结果数据结构(在这种情况下,它将是一个 let 形式) 。

When you evaluate the list (or true false), Clojure first evaluates the first item. In this case, the first item is a symbol that names a macro, so Clojure expands the macro and evaluates the resulting data structure (which would be a let form in this case).

另一方面,当你评估列表((符号或)true false) Clojure首先评估第一个项目,但在这种情况下,第一个项目是另一个列表! 列表的第一个元素是符号符号,它命名一个函数,因此Clojure使用参数,再次生成符号。换句话说,你基本上评估('或true false)

On the other hand, when you evaluate the list ((symbol "or") true false), Clojure again first evaluates the first item, but in this case, the first item is another list! The first element of that list is the symbol symbol, which names a function, so Clojure calls that function with the parameter "or", again producing the symbol or. In other words, you are basically evaluating ('or true false).

这里是catch:Clojure采取那个事情,它只是评价,然后去再评价它。相反,由于它不是一个符号的首位,Clojure评估它,然后假设它必须是一个函数。是一个函数?确实,答案是肯定的!

Here's the catch: Clojure does not take that thing that it just evaluated and then go and evaluate it again. Rather, since it wasn't a symbol in the first place, Clojure evaluates it and then assumes that it must be a function. Is it a function? Indeed, the answer is yes!

user> (ifn? 'do)
;=> true

这里是一个有点棘手的地方。在 Symbol 类上的 invoke 的实现与 invoke 关键字类:它假设第一个参数是一个地图,并试图看看自己在那个地图。如果你提供第二个参数,它将使用它作为默认值。

Here's where it gets a little tricky. The implementation of invoke on the Symbol class is the same as the implementation of invoke on the Keyword class: it assumes that the first argument is a map and tries to look itself up in that map. If you provide a second argument, it will use that as a default value.

现在,显然,如果你尝试处理 true 作为映射,并在该映射中查找符号,您将找不到任何内容。所以Clojure有助于返回你提供的默认值: false 。您可以在第二个参数点中设置任何值,只要您的符号在第一个参数中不作为键存在,您将始终返回默认值。

Now, obviously, if you try to treat true as a map and look up the symbol or in that map, you'll find nothing. So Clojure helpfully returns the default value that you provided: false. You could put any value you'd like in that second parameter spot, and as long as your symbol doesn't exist as a key in the first argument, you'll always get back your default value.

这篇关于Clojure字符串到符号计算结果错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆