【问题标题】:clojure unqoute problemclojure unqoute 问题
【发布时间】:2011-03-16 23:49:00
【问题描述】:

我有一个简单的 clojure 语法问题(因为我是该语言的新手)。对于这两个示例,我都有一个列表 lst (1 2 3 4):

在 Lisp 中我可以写:

=>`(列表中的第一个是 ,(first lst))
(列表中的第一个是 1)

在 Clojure 中,如果我写相同的东西(用语言翻译 , 到 ~ 就像我在某处读到的那样),我会得到:

=>'(列表的第一个是 ~(first lst))
(列表中的第一个是 (clojure.core/unquote (first lst)))

我希望我也可以在 Clojure 中做我想做的事,但我只是语法错误。我发现的所有示例都首先具有功能并使用`(反引号)。我不想调用这样的函数:

`(my-function ~(first lst))

我只想返回 '(其中替换为 ,(first lst) 的一些列表)

我可以在 Clojure 中做这样的事情吗?

编辑:我举了一个糟糕的例子,因为我的实际问题是处理字符串。让我再举一个例子……

=>(def color-lst '(红绿蓝))

我想返回的是:

=>`(我想要的颜色是~(first color-lst))

这产生了我看到的所有奇怪的回报。另一种方法是

=>(format "我想要的颜色是%s" (first color-lst))

这就是我解决问题的方法。

【问题讨论】:

  • 虽然其他人已经帮助您解决了您的问题,但请注意这不是 Clojure 的方式。例如。 clojure 使用关键字而不是引用符号。如果您想要字符串(如您的示例中所示),请使用它们。所有'〜'的东西都很丑陋。而且你迟早会遇到一个难以发现的错误。
  • 所有这些 ' ` 和 ~ 通常与宏一起使用。除非必要,否则尽可能避免它们。

标签: syntax clojure


【解决方案1】:

即使你的问题解决了,CL 和 Clojure 之间也有一些根本区别值得一提:

CL 和 Clojure 之间关于反引号中的符号的主要区别在于,Clojure 解析准引号符号;产生一个命名空间限定符号(查看 Clojure 文档的 reader section):

user> `foo
user/foo

所以,在 CL 中:

CL-USER> (let ((list '(foo bar baz)))
            `(first is ,(first list)))
(FIRST IS FOO)

但在 Clojure 中:

user> (let [lst '(foo bar baz)]
        `(first is ~(first lst)))
(clojure.core/first user/is foo)

为了在 Clojure 中获得非限定符号(在反引号内),您必须使用如下内容:

user> `~'foo
foo

因此,要获得与 CL 版本相同的结果(忽略 readtable-case),您必须使用:

user> (let [lst '(foo bar baz)]
        `(~'first ~'is ~(first lst)))
(first is foo)

【讨论】:

  • 嘿,就是这样!从那时起,我又转向了另一个问题,但我想我现在会回去并用这个代替。这正是我一直在寻找的,我只是无法推断出正确的引号/反引号/波浪号组合。谢谢。
  • 不客气。由于符号在当今学习/使用的大多数编程语言中都不是一等公民,因此它们是一个人们必须逐渐习惯的概念。
【解决方案2】:

我有点不清楚你的代码中“列表中的第一个是”是什么意思:

'(first of list is ,(first lst))

但是,如果您的意思只是列表开头的占位符,那么以下应该可以正常工作(确保使用反引号!):

`(1 2 3 ~(first [1 2]))
=> (1 2 3 1)

或者,使用引号会导致以下结果(这似乎是您的问题):

'(1 2 3 ~(first [1 2]))
=> (1 2 3 (clojure.core/unquote (first [1 2]))) 

【讨论】:

  • 好的,现在我到了某个地方。确实有效(刚刚尝试过)。 “列表中的第一个是”只是我上面代码中的一个句子。所以也许我正在以错误的方式解决这个问题?当反引号列表包含数字时它可以工作,但当它包含单词时则不行。我认为问题可能是 '(这是一个列表) 和 `(这是一个列表) 在 Lisp 中评估为相同的东西......但在 Clojure 中没有。会是这样吗?
  • 看来您遇到的问题是使用引号 (') 而不是反引号 (`)。反引号应该以相同的方式处理字符串列表。
  • 评估 '(这是一个列表)会产生(这是一个列表)如 id 期望的那样。评估`(这是一个列表) yields (user/this user/is user/a clojure.core/list) 这不是我所期望的,但这就是我没有正确使用语言:(
  • 好的,在'(这是一个列表)中,clojure 将该列表的元素视为变量,而不是字符串。引号和反引号之间的区别在于,反引号将所有内容命名为当前命名空间,而引号则没有。这就是为什么你在一个中看到“clojure.core/list”,而在另一个中看到“list”。尝试更改当前命名空间(例如(ns my-namespace)),您将看到反引号返回的“my-namespace/list”。
  • 感谢 unignorant,您的原始陈述是我找到解决方案的原因
【解决方案3】:

找到了另一种方式。也许我一直没有按照“Clojure”的方式做事?

(formate "first of list is %d" (first lst)) 得到我正在寻找的东西。

我认为问题描述部分是我的错,我举了一个不好的例子。似乎问题出现在我在列表中使用字符串(可能不正确?)之前。那和'first'也是一个可接受的函数调用。我认为所有这些都混淆了这个问题。

【讨论】:

  • 我认为混淆实际上是您没有在原始示例列表中使用字符串 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-22
  • 2011-02-22
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
  • 2018-04-03
相关资源
最近更新 更多