链接“let”语句时最好使用“and”或“in”?
Posted
技术标签:
【中文标题】链接“let”语句时最好使用“and”或“in”?【英文标题】:Better to use "and" or "in" when chaining "let" statements? 【发布时间】:2011-09-15 02:21:44 【问题描述】:我知道这可能是一个愚蠢的问题,但是......
如果我要链接一堆let
语句,而这些语句不需要 需要知道彼此的值,那么使用and
或in
更好吗?
例如,如果有的话,哪一个更可取:
let a = "foo"
and b = "bar"
and c = "baz"
in
(* etc. *)
或
let a = "foo" in
let b = "bar" in
let c = "baz"
in
(* etc. *)
我的直觉告诉我,前者应该是“更好的”(通过对“更好”的一个非常狭隘的定义),因为它创建了必要的最小范围数量,而后者是一个范围内的范围内-a-scope 编译器/解释器注意但最终并不重要且不必要的深度。
【问题讨论】:
【参考方案1】:“哪个更好?”问题的答案只有当解释没有不同时才真正有意义。 ML 系列语言(至少是 SML 和 OCaml)既有并行初始化形式 (and
) 又有顺序的、本质上是嵌套范围的形式 (in
),因为它们在某些情况下都很有用。
在您的情况下,语义是相同的,因此您需要回答“什么对您来说最好读?”这个问题。也许(如果这不是为时过早的话)“可能会更有效地执行?”在您的情况下,替代方案是:
对于and
的情况:计算一堆字符串并并行绑定到三个标识符。
对于in
情况:将foo
绑定到a
,然后 将bar
绑定到b
,然后 绑定@987654329 @到c
。
哪个更好读?在这种情况下这是一个折腾,因为结果并不重要。你可以对一些说英语的人进行投票,但我怀疑会有很多偏好。也许大多数人会喜欢and
,因为它将绑定分开,在表达式之前留下唯一的in
。
至于什么执行效率更高,我认为一个好的编译器可能会产生相同的代码,因为它可以检测绑定的顺序无关紧要。但也许您有一个编译器可以为多核处理器生成代码,使用and
会更好。或者可能是一个天真的编译器,它将所有 RHS 写入临时存储然后绑定它们,从而使 and
的情况变慢。
这些可能是非必要的优化问题,特别是因为它们涉及绑定并且可能不在紧密循环中。
底线:在这种情况下,这是一个 true 折腾;当结果很重要时,请确保正确使用并行与顺序。
【讨论】:
【参考方案2】:我的意见是in
更好。 and
的使用意味着定义相互依赖。我认为最好清楚事实并非如此。另一方面,一些 OCaml 程序员确实更喜欢 and
用于非常短的定义,其中稍微更紧凑的符号看起来更清晰。当您可以将定义放在一行时尤其如此:
let a = "foo" and b = "bar" in
【讨论】:
即使不使用let rec
,它们能否相互依赖?
正如 nimrodm 所说,以下内容不起作用(意味着and
可能并不总是暗示依赖):let a = 3 and b = a + 7 in (* ... *)
【参考方案3】:
我相信这与 Lisp 中 let
和 let*
之间的区别相同。
let*
(功能类似于 in..in..
结构 - 您问题中的第二个结构)有时用于隐藏 命令式 编程,因为它保证了表达式的顺序执行(请参阅 Paul Graham 所说的话关于 let* in On Lisp)。
所以,我会说前一种构造更好。但事实是,我认为后者在我见过的 Ocaml 程序中更常见。可能只是更容易使用,让一个在以前命名的表达式上构建。
【讨论】:
我完全忘记了保证顺序执行;谢谢你提醒我。【参考方案4】:我会说 in 更好,因为它缩小了范围并更好地表达了意图。如果我看到所有这些定义以共享范围的方式链接在一起,我会觉得这样做是有原因的,并且会寻找它们如何相互影响。
【讨论】:
以上是关于链接“let”语句时最好使用“and”或“in”?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 for..of / for..in 循环可以使用 const 而普通的 for 循环在 JS 中只能使用 let 或 var 作为其变量? [复制]
MySQL 2 SQL数据使用(检索排序过滤:SELECT/FROM/LIMIT/ORDER BY/DESC/WHERE/AND/OR/IN/NOT)