从指令的角度理解表达式和语句
在理解计算机语言时,把注意力放在“表达式”和“语句”的概念上是不合适的。事实上这两个词含义模糊、界限不清,而且是基于人类的理解习惯设置的概念,无益于理解计算机的行为。
对计算机语言的基础分类应该是对指令的分类。因为对计算机而言有意义的输入有且仅有一种,那就是指令。万物皆指令。
一条"语句"就是指一条完整的指令
计算机语言的基本概念单元是存储指令和运算指令。这是计算机之所以被发明出来的最原始的目的,也是至今为止仍然是最主要的功能。
对它而言,人类对它输入的任何语言,要么是向它发出的存储指令,要么是运算指令。理解了这个原理,再去理解表达式和语句就清晰了。
“表达式”是运算指令的一部分
表达式,包括数学运算表达式、逻辑运算表达式、函数运算表达式等,是用符号记录和表达运算方法的公式或通用形式。
也就是记录、描述和表达运算指令所使用的一种方法和形式。所以,它是运算指令的一部分,但不是一条完整的运算指令。
只有当表达式按照规定的格式补充为一条完整的语句时,它才成为一条运算指令。这个补完形式可以是使用“=”号进行赋值,也可以是简单地加一个“;”号或放入函数的参数括号内。
需要指出的是,一条赋值语句,如果存在运算过程,那么它同时包含了运算指令和存储指令。
函数的声明与执行
函数也是表达式,它符合前述的关于表达式的所有定义规范。
它可以返回运算值,也可以返回某种不能以“值”的方式体现的操作结果。
它也是运算指令中记录和表达运算方法的通用形式,和“数学运算“与“逻辑运算“一样,我们可以称之为“函数运算”,它的运算方式记录在函数体内,往往就是一组较为复杂的数学运算和逻辑运算的组合。
于是我们便能理解计算机对待输入函数名称的行为为什么会出现不同态度。
当我们声明一个函数时,计算机认为这是一条存储指令,目的是将一种函数运算方法存储到内存中,并将这种方法映射到一个新注册的函数名称上。
此时的函数虽然具备带括号的参数形态,但计算机知道这是对参数类型和名称的预设行为,而不是一条输入参数并要求运算结果的指令。
出于更加明确地区分声明与运算的目的,有些语言会将函数名与参数括号拆分开,中间用冒号、function等保留词进行标记,明确这是一个声明。
那么什么时候输入函数名才是一条运算指令而不是存储指令呢?
当它不是以声明的形式出现在语句开头部分,并且形式上提供了运算参数时(比如在函数名后面象征性地添加了一个空括号"()",意思是“你就当我给了一个空参数”),计算机都认为这是一句运算指令。
一般情况下,这已经足以区分函数的声明与函数的执行了。
但是,当出现“立即执行函数”这种东西时,理解产生了歧义。
立即执行函数同时具备了“函数名出现在语句开头”的声明特征,也出现了以圆括号"()"结尾的执行特征。计算机产生了困扰:这到底是一条存储指令还是一条运算指令?
它会认为这是一条有语法毛病的函数声明,因而报错。
这就是我们需要在句首用“(”、";"、“+”号等无意义符号来标记立即执行函数的原因:告诉计算机这不是一条普通的函数声明,这既是一条存储指令,也是一条运算指令。