抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

“一切皆表达式”

Everything is an expression.

是的,理解了上面这句话,就基本理解了Wolfram语言。至于其它的,那都是细枝末节。

当然,想要理解这句话,首先要明白Wolfram语言里的表达式是什么。典型地f[x,y] 就是一个表达式,它由一个头部 f,以及两个 xy 构成。通常,我们会用 f[x,y] 来表示一个函数 f(x,y)f(x,y),但同时,这种形式也代表了Wolfram语言里表达式的一般结构。
一般的,表达式由头部和项组成,而头部和项同样也是表达式。这种结构不仅可以用来表示函数,它也可以用来表示列表图形动态控件,甚至是笔记本。表达式的这种灵活性为Wolfram语言语法的高度一致性,在理解了这种一致性的基础上,再去看Wolfram语言的各种行为,就会变得好理解很多。

再举几个例子(通过FullForm可以获得一个表达式的完整形式):

  • 算术表达式

  • 列表

    Str

    Str

  • 图形

    x

  • 非符号头部的表达式

  • 按钮控件

    <

    Push

  • 笔记本对象(输出仅供参考)

    kyhfi_shm

对象是结构化的表达式

前面提到了Wolfram语言表达式的一般结构,即:一个表达式由头部和若干项构成,而头部和项同样也是表达式,直到某个不可再分的原子对象,比如数字字符串符号。在最初的例子里,f[x,y]中,头部f,项xy都是符号。而对于更复杂的表达式,往往有较深的层次和较多的子项,但如果掌握了一些方法(比如 善用 TreeForm),分析一个表达式的结构并不困难。

理解了表达式的结构,以及Wolfram语言的这种一致性,那么Wolfram语言的很多设计与行为就好理解了。

比如,列表的下标为何从1开始?因为本质上,运算符[[...]]提供的是按索引获取表达式各个项的一般方法,而作为语言一致性的表现,[[0]]获取的是表达式的头部。因此,对任何列表,获取“下标”为0的部分得到的结果都会是List。同样,像1[[0]]这种在别的语言的使用者眼里看起来莫名奇妙的表达式,在Wolfram语言中是完全正确的(当然,我们推荐使用语义更清晰的Head[1]进行表达)。事实上,不仅仅是[[...]],有相当一部分的列表操作可以以完全一致的行为用在任何表达式上,例如LengthCasesSortMap……掌握好这些函数,在面对很多问题的时候都会有所帮助。

而表达式的这种结构特性使得它可以承载并组织各种各样的信息。自然而然地,我们可以使用表达式来表示对象。

作为展示“对象是结构化的表达式”的例子,再来看一个有趣的小trick:

上面这个例子实际展示了Plot 函数在绘图时是如何进行抽样的。而方法也很简单,只是把图中的线段替换为。而这种操作之所以可行,也是表达式一致性的体现。在这里,函数Plot输出的图形实际是一个Graphics 对象,从构成上看,无非就是包含一些图形基元和图形指令的Graphics表达式,只要将连接点的Line替换为不连接的Point就可以显示出那些抽样点了。

小结

“一切皆表达式”是Wolfram语言语法的核心。Wolfram语言用表达式来表示算式、数据、图形、控件等等。而掌握了表达式的结构,对Wolfram语言里的各种对象、操作都会有更清晰准确地认识。在下篇里,将会讲到Wolfram语言中表达式的另一个重点——表达式的计算,以及我们如何控制计算。

评论