从中缀转换为前缀表示法

Ale*_*xey 9 oop clojure infix-notation prefix

我最近开始学习Clojure.通常它看起来很有趣,但我不能习惯一些语法上的不便(与之前的Ruby/C#体验相比).

嵌套表达式的前缀表示法.在Ruby中,我习惯于编写复杂的表达式,并将它们从左到右连接起来:some_object.map { some_expression }.select { another_expression }.当您逐步从输入值移动到结果时,它非常方便,您可以专注于单个转换,而无需在键入时移动光标.与在Clojure中编写嵌套表达式时的情况相反,我将内部表达式的代码编写到外部,我必须不断地移动光标.它会减慢并分散注意力.我知道->->>宏,但我注意到它不是惯用语.当你开始在Clojure/Haskell等编码时,你有同样的问题吗?你是怎么解决的?

mik*_*era 9

我最初对Lisps有同感,所以我觉得你的痛苦:-)

然而,好消息是你会发现,经过一段时间和常规使用,你可能会开始喜欢前缀表示法.事实上,除了数学表达式,我现在更喜欢它的中缀风格.

喜欢前缀表示法的原因:

  • 与函数的一致性 - 大多数语言使用混合的中缀(数学运算符)和前缀(函数调用)表示法.在Lisps中,如果你认为数学运算符是函数,它就是一致的,它具有一定的优雅
  • - 如果函数调用始终处于第一位置,则会变得更加理智.
  • Varargs - 很高兴能够为几乎所有的运营商提供可变数量的参数.(+ 1 2 3 4 5)比哇哇更好1 + 2 + 3 + 4 + 5

然后一个技巧就是使用->->>librerally,这在逻辑意义上以这种方式构造代码.这在处理对象或集合的后续操作时通常很有用,例如

(->>
  "Hello World" 
  distinct 
  sort 
  (take 3))

==> (\space \H \W)
Run Code Online (Sandbox Code Playgroud)

我在前缀样式中工作时发现的最后一个技巧是在构建更复杂的表达式时充分利用缩进.如果你正确缩进,那么你会发现前缀表示法实际上很清楚:

(defn add-foobars [x y]
  (+
    (bar x y)
    (foo y)
    (foo x)))
Run Code Online (Sandbox Code Playgroud)

  • @Alexey:有一个原因是` - >`和` - >>`和不同的参数顺序.这是由于seq抽象和集合之间的区别.我认为这会让人感到困惑,因为集合通常被视为seq.我经常回顾Rich Hickey的解释 - http://groups.google.com/group/clojure/msg/a8866d34b601ff43 (3认同)
  • 此外,如果你真的想要它,瑞士箭头库提供钻石棒宏:http://stackoverflow.com/q/10068398/148578 (2认同)

Art*_*ldt 3

当我第一次开始使用 lisp 时,我确实遇到了同样的障碍,这真的很烦人,直到我看到它使代码更简单、更清晰的方法,一旦我理解了它的好处,烦恼就消失了

initial + scale + offset
Run Code Online (Sandbox Code Playgroud)

成为

(+ initial scale offset)
Run Code Online (Sandbox Code Playgroud)

然后尝试(+)前缀表示法允许函数指定自己的标识值

user> (*)
1
user> (+)
0
Run Code Online (Sandbox Code Playgroud)

还有更多的例子,我的观点不是捍卫前缀表示法。我只是希望传达这样的信息:随着积极的一面变得明显,学习曲线(情感上)会趋于平坦。

当然,当您开始编写宏时,前缀表示法就成为必备的而不是方便的。


为了解决你的问题的第二部分,线程第一个和线程最后一个宏在任何时候都是惯用的,它们使代码更清晰:)它们比纯算术更常用于函数调用,尽管没有人会因为在它们使代码更清晰时使用它们而责怪你方程更容易接受。


附言:(.. object object2 object3)-> object().object2().object3()

(doto my-object
   (setX 4)
   (sety 5)`
Run Code Online (Sandbox Code Playgroud)