我理解LET和LET*之间的区别(并行与顺序绑定),作为理论问题,它非常有意义.但有没有你真的需要LET的情况?在我最近看过的所有Lisp代码中,您可以用LET*替换每个LET而不做任何更改.
编辑:好的,我理解为什么有些人发明了LET*,大概是作为一个宏,回归的时候.我的问题是,鉴于LET*存在,是否有理由让LET留在身边?您是否编写了任何实际的Lisp代码,其中LET*不能像普通的LET那样工作?
我不买效率论证.首先,认识到LET*可以编译成像LET一样高效的情况,这似乎并不难.其次,CL规范中有很多东西似乎根本就不是围绕效率而设计的.(当你最后一次看到带有类型声明的循环时?那些很难弄清楚我从未见过它们使用过.)在20世纪80年代后期的Dick Gabriel基准测试之前,CL 非常缓慢.
看起来这是另一种向后兼容的情况:明智的是,没有人愿意冒险破坏像LET那样基本的东西.这是我的预感,但是听到没有人有一个我丢失的愚蠢简单的案例令人欣慰,因为LET比LET*更容易让事情变得简单.
在样式,约定,效率等方面,在Clojure中定义常量的最佳实践是什么?
例如,这是对的吗?
(def *PI* 3.14)
问题:
常量应该在Clojure中大写吗?
在风格上,他们是否应该在一侧或两侧都有星号(*)?
我应该注意的任何计算效率考虑因素?
作为一个非暴力者,我应该如何最好地理解vars得名的命名约定*var-name*
?
这似乎是一个表示全局变量的lisp约定.但是在clojure中,据我所知,这些变量出现在命名空间中.
我真的很感谢作者在他们的代码中使用这些变量时我应该期待的一个简短的解释,理想的例子是如何以及为什么在clojure库中使用和更改这样的var.
考虑以下宏:
(defmacro somemacro []
(list 'let ['somevar "Value"] 'somevar))
Run Code Online (Sandbox Code Playgroud)
扩展它会产生以下结果:
(macroexpand '(somemacro))
Run Code Online (Sandbox Code Playgroud)
结果:
(let* [somevar "Value"] somevar)
Run Code Online (Sandbox Code Playgroud)
我有两个关于let*(带星号)的问题:
不幸的是,我找不到关于let*的任何"官方"文档,这就是我在这里问的原因.
我已经考虑过的来源:
(doc let*) ; --> nil
(source let*) ; --> source not found
Run Code Online (Sandbox Code Playgroud)
Nota Bene:让Clojure就像让我们在Scheme中一样 - 每个init-expr都可以访问前面的绑定表单.(还有一个let*,但它或多或少都没有解构,实际上是底层实现.)
在Clojure中,它基本上意味着"foo*就像foo,但有些不同,你可能想要foo".换句话说,这意味着该代码的作者无法为第二个函数提供更好的名称,因此他们只是在它上面打了一个星.
- >这是let和let*的情况吗?但如果是这样,问题仍然存在,究竟有什么区别?