通过改变像Dylan,Julia和Seph这样的主要括号,Clojure会失去什么?

haw*_*eye 25 lisp language-design clojure dylan julia

三种lispy homoiconic语言,Dylan,JuliaSeph都离开了前导括号 - 所以在Common Lisp中的假设函数调用看起来像:

(print hello world)
Run Code Online (Sandbox Code Playgroud)

看起来像下面的假设函数调用

print(hello world)
Run Code Online (Sandbox Code Playgroud)

用上面提到的三种语言.

如果Clojure沿着这条道路走下去 - 为了实现这一目标会有什么牺牲?

推理:除了Clojure中令人惊讶的懒惰功能数据结构,以及地图和seqs的改进语法,对并发的语言支持,JVM平台,工具和令人敬畏的社区 - 它是'LISP'的独特之处在于给出同音性的前导括号,它给出了提供语法抽象的宏.

但如果你不需要括号 - 为什么要这些呢?我能想到保留它们的唯一论点是

(1)重用emacs中的工具支持

(2)促使人们"在LISP中思考"而不是试图将其视为另一种程序性语言)

Joo*_*aat 23

只是将括号移动一个原子进行函数调用就不足以满足任何人的需要; 人们会抱怨缺少中缀运算符,开始/结束块等等.另外,你可能不得不在各种各样的地方引入逗号/分隔符.

给他们这些,并且只需要正确编写宏就会更难(并且编写看起来和行为很好的宏可能会更难以使用你所引入的所有新语法).并且宏不是一个你可以忽略的一个很好的功能,或者更令人讨厌; 整个语言(就像任何其他Lisp一样)构建在它们之上.clojure.core中的大多数"用户可见"内容,包括let,def,defn等都是宏.


Tur*_*est 20

(感谢andrew cooke的回答,他提供了与Wheeler和Gloria的"可读Lisp S表达式项目"的链接)

上面的链接是一个项目,旨在为所有语言提供基于s表达式的可读语法,包括Scheme和Clojure.结论是可以做到:有一种方法可以使用没有括号的可读Lisp.

基本上David Wheeler的项目所做的是为类似Lisp的语言添加语法糖,以提供更现代的语法,这种方式不会破坏Lisp对特定于域的语言的支持.增强功能是可选的,并且向后兼容,因此您可以根据需要添加尽可能多的内容,并将它们与现有代码混合使用.

该项目定义了三种新的表达式:

  • 卷毛-中缀表达式. (+ 1 2 3)在你想要使用任何arity的中缀运算符的每个地方变为{1 + 2 + 3}.(如果内联表达式使用多个运算符,例如{1 + 2*3},则需要谨慎处理特殊情况 - 尽管{1 + {2*3}}按预期工作.
  • 近代表达式.(fxy)变为f(xy)(要求函数名及其参数之间没有空格)
  • 甜表达式.打开和关闭父级可以替换为(可选的)类似python的语义缩进.甜表达式可以与传统的括号s表达式自由混合.

结果是符合Lisp但更易读的代码.新语法糖如何增强可读性的一个例子:

(define (gcd_ a b)
    (let (r (% b a))
        (if (= r 0) a (gcd_ r a))))

(define-macro (my-gcd)
    (apply gcd_ (args) 2))
Run Code Online (Sandbox Code Playgroud)

变为:

define gcd_(a b)
    let r {b % a}
        if {r = 0} a gcd_(r a)

define-macro my-gcd()
    apply gcd_ (args) 2
Run Code Online (Sandbox Code Playgroud)

请注意语法如何与宏兼容,这是以前旨在改进Lisp语法的项目的问题(如Wheeler和Gloria所述).因为它只是糖,每个新表达式的最终形式是一个s表达式,在处理宏之前由语言阅读器进行转换 - 因此宏不需要任何特殊处理.因此,"可读的Lisp"项目保留了homoiconicity,这个属性允许Lisp将代码表示为语言中的数据,这使得它成为一个强大的元编程环境.

  • 如果你们都被激怒了,那总是让我觉得球拍(一种支持多种"语言"的计划)将是实现这一目标的好地方 - https://en.wikipedia.org/wiki/Racket_features#Language_Extensions (2认同)

Art*_*ldt 13

编写宏会变得更加困难,因为结构将不再简单你需要另一种方式来编码表达式开始和停止使用一些语法符号来标记表达式的开始和结束你可以编写生成表达式的代码也许你可以通过添加类似于(标记表达式开头的内容来解决此问题...

在一个完全不同的角度,非常值得观看这个关于熟悉和轻松制作lisps语法之间差异的视频更熟悉,不会让人们更容易学习,如果它看起来很像它不是什么,可能会误导它.

即使你完全不同意,那个视频非常值得一试.


and*_*oke 13

你不需要牺牲任何东西.david Wheeler有一个非常仔细考虑的方法,它完全透明且向后兼容,完全支持宏等.


Jim*_*ski 5

你会有 Mathematica。Mathematica 接受函数调用 as f[x, y, z],但是当您进一步研究它时,您会发现这f[x, y, z]实际上是一个列表的语法糖,其中Head(元素 0) 是f并且Rest(元素 1 到 N) 是{x, y, z}。您可以从看起来很像 S 表达式的列表构造函数调用,并且可以将未Hold求值的函数分解为列表(防止求值,很像quote在 Lisp 中)。

Mathematica 和 Lisp/Scheme/Clojure 之间可能存在语义差异,但 Mathematica 的语法是一种演示,您可以将左括号移动一个原子并仍然明智地解释它,使用宏构建代码等。

使用预处理器很容易转换语法(比语义容易得多)。您可能可以通过Clojure 的 LispReader 的一些巧妙的子类化来获得您想要的语法。甚至还有一个项目试图通过用方括号替换它们来解决 Clojure令人反感的括号。(令人难以置信的是,这被认为是一件大事。)