【翻译-不推荐】学习 Clojure - 语法
原文来自于官网:https://www.clojure.org/guides/learn/syntax
字面含义
下面是一些Clojure中常见原始的的字面表示法的例子。所有这些字面符号都是有效的Clojure表达式。
;
创建一个注释到行尾。有时会使用多个分号来表示标题注释部分,但这只是一种惯例。
数值类型
42 ; integer
-1.5 ; 浮点型
22/7 ; 比值
当整数在范围内时,会作为固定精度的64位整数来读取,否则就是任意精度。后面的N可以用来强制使用任意精度。Clojure还支持八进制(前缀0)、十六进制(前缀0x)和任意弧度(前缀为base,然后为r)整数的Java语法。比值是作为他们自己的类型提供的,结合了分子和分母。
浮点值可作为双精度64位浮点,或任意精度的M
后缀来读取。指数符号也被支持。特殊符号值##Inf
、##-Inf
和##NaN
分别代表正无穷大、负无穷大和 "非数字 "值。
字符类型
"hello" ; 字符串
\e ; character
#"[0-9]+" ; 正则表达式
字符串包含在双引号中,可以跨越多行。单个字符用前面的反斜杠表示。有一些特殊的命名字符。\newline
(换行), \spec
, \tab
等。Unicode字符可以用 \uNNNN
表示,或者用八进制的 \oNNNN
表示。
字面正则表达式是带有#
号的字符串。这些被编译成java.util.regex.Pattern对象。
符号和标识
map ; symbol
+ ; symbol - most punctuation allowed
clojure.core/+ ; namespaced symbol
nil ; null value
true false ; booleans
:alpha ; keyword
:release/alpha ; 带命名空间的关键字
符号由字母、数字和其他标点符号组成,用来指代其他东西,如函数、值、命名空间等。符号可以选择有一个命名空间,用正斜杠与名称分开。
有三个特殊的符号被当 作不同的类型来读 - nil
是空值,true
和false
是布尔值。
关键词以前面的冒号开始,并且总是对自己进行评估。它们经常被用作Clojure中的枚举值或属性名称。
集合
Clojure 还包括四种集合类型的文字语法:
'(1 2 3) ; list
[1 2 3] ; vector
#{1 2 3} ; set
{:a 1, :b 2} ; map
稍后我们将更详细地讨论这些 - 现在知道这四种数据结构可用于创建复合数据就足够了 。
计算
接下来我们将考虑 Clojure 如何读取和评估表达式。
传统的计算(Java)
在Java中,源代码(.java文件)被编译器(javac)作为字符读取,产生字节码(.class文件),可由JVM加载。
Clojure计算
在Clojure中,源代码是由阅读器作为字符来读取的。读取器可以从.clj文件中读取源码,也可以以交互方式给出一系列表达式。读取器产生Clojure数据。然后,Clojure编译器为JVM产生字节码。
这里有两个重要的观点:
- 源代码的单位是 Clojure 表达式,而不是 Clojure 源文件。 源文件被读取为一系列表达式,就像您在 REPL 中以交互方式键入这些表达式一样。
- 宏是特殊的函数,它接受代码(作为数据),并发出代码(作为数据)。你能看出在评估模型中可以插入一个用于宏扩展的 循环吗?
结构与语义
考虑一个Clojure表达式。
这张图说明了绿色的语法(Reader产生的Clojure数据结构)和蓝色的语义(Clojure运行时如何理解这些数据)之间的区别。
除了符号和列表之外,大多数Clojure的字面形式都会对自己进行评估。符号是用来指代其他东西的,当被评估时,返回它们所指代的东西。列表(如图)是作为调用来评估的。
在图中,(+ 3 4)
被解读为一个包含符号(+)和两个数字(3和4)的列表。第一个元素(找到+的地方)可以被称为 "函数位置",也就是说,找到要调用的东西的地方。虽然函数是一个明显的可调用的东西,但也有一些运行时已知的特殊操作符、宏和其他一些可调用的东西。
考虑到上述表达式的计算:
- 3 and 4 evaluate to themselves (longs)
+
evaluates to a function that implements+
- 计算该列表将调用
+
函数,参数为3和4。
许多语言都有语句和表达式,其中语句有一些有状态的效果,但不返回一个值。在Clojure中,所有的东西都是一个表达式,它可以赋值为一个值。一些表达式(但不是大多数)也有副作用。
现在让我们考虑如何在Clojure中交互式地赋值表达式。