用编程视角理解英语语法
一、数学里的函数:自变量决定了"求值"需要几个输入
在数学里,一个函数被定义出来的第一件事,就是规定它需要几个自变量:
f(x) = x² // 一元函数,需要 1 个输入
g(x, y) = x + y // 二元函数,需要 2 个输入
h(x, y, z) = x·y + z // 三元函数,需要 3 个输入
函数本身只是一个"规则",规则要落地成一个具体的值,必须把所有自变量都填满。少填一个,这个表达式就无法求值,只能停留在"未完成"的状态:
g(3) // 缺少 y,无法求值
g(3, 5) = 8 // 参数齐全,求值成功
这里的关键概念是:函数的定义本身自带一份"需要几个输入"的规格,这份规格是函数与生俱来的属性,不是使用者临时决定的。你不能任意决定给 g 传一个参数还是三个参数——函数签名早已锁死了这件事。
二、编程里的函数:签名(Signature)与实参(Argument)
编程语言把这套数学逻辑原封不动地继承了下来,还给它们起了更精确的名字。以 TypeScript 为例:
function add(x: number, y: number): number {
return x + y;
}
add这个函数的签名(signature)规定了它必须接收两个number类型的参数。- 调用函数时实际传入的值,比如
add(3, 5)里的3和5,叫实参(argument)。 - 如果调用时少传参数:
add(3); // TypeScript 编译报错:Expected 2 arguments, but got 1.
程序在编译阶段就会因为"参数数量不满足签名要求"而报错——这跟数学里 g(3) 无法求值,是同一件事的两种表达方式。
值得注意的是,"argument"这个英语单词,从数学到编程,含义几乎没有变化:都是指为了让某个规则/函数完整运作,而必须提供的输入。这个词后来被语言学直接借用,正是下一节的主角。
三、泰尼埃:动词也是一种函数
20 世纪 50 年代,法国语言学家吕西安·泰尼埃(Lucien Tesnière)观察到一个现象:动词跟数学函数极其相似——每个动词天生就规定了它需要几个"参与者"才能构成一个语义完整的事件。他借用化学"化合价"的说法,把这个属性命名为配价(valency)。
用编程语言的方式重新表述泰尼埃的洞察,几乎不需要做任何翻译工作:
function sleep(subject: Entity): Event // 一价函数
function read(subject: Entity, object: Entity): Event // 二价函数
function give(subject: Entity, recipient: Entity, // 三价函数
object: Entity): Event
give 这个"动词函数"的签名规定了它需要三个输入才能求值,也就是构成一个完整的"给予事件":
give("She", ???, ???) // 参数不足,事件未完成
give("She", "him", "a book") // 参数齐全,事件成立
对应到英语句子:
*She gave. // ✗ 参数不足,不合语法
She gave him a book. // ✓ 参数齐全
*She gave. 之所以不合语法,跟 add(3) 在 TypeScript 里编译报错,本质上是同一类"错误":调用者没有满足被调用者(函数/动词)预先声明的参数需求。
泰尼埃提出配价理论时,明确借用的就是数学函数这套框架——动词是运算符,名词短语是它的操作数,句子则是这次"函数调用"最终求出来的值。
四、把函数框架套进句子结构:论元、题元角色、补足语
有了"动词即函数"这个起点,句法学里一整套围绕它展开的术语,都可以在编程里找到对应物。
4.1 论元(Argument)= 实参
give("She", "him", "a book")
"She"、"him"、"a book" 就是传入 give 这个函数的实参——在语言学里,这些实际出现在句子中、满足动词配价要求的名词短语,就叫论元(argument)。
4.2 题元角色(θ-role)= 参数类型标注
编程语言允许我们给每个参数标注类型,规定它该是什么样的值:
function give(
agent: Agent, // 谁发出动作
recipient: Recipient, // 谁接收
theme: Theme // 被给予的东西
): GivingEvent
Agent(施事)、Recipient(接受者)、Theme(客体)这些类型标注,对应语言学里的题元角色(θ-role)——规定每个论元在事件里扮演什么语义角色。传入类型不匹配的论元,句子在语义上就会显得怪异,即便语法结构完全合法:
#The rock gave him a book. // "The rock"语义上很难承担 Agent 这个角色
4.3 配价(Valency)= 函数的参数个数
function sleep(subject: Agent): Event // 一价
function read(subject: Agent, object: Patient): Event // 二价
function give(subject: Agent, recipient: Recipient, // 三价
object: Theme): Event
function put(subject: Agent, object: Theme, // 三价
location: Location): Event
传统语法说的"不及物动词""及物动词""双及物动词",正是这份参数列表长度不同的粗略说法。配价理论只是把这份"函数签名"完整地写了出来,不再停留在"及物/不及物"这种二元标签上。
4.4 补足语(Complement)= 参数在调用语句里的具体写法
论元规定的是"语义上必须有什么参与者",补足语则是这个参与者在句子里实际的句法形式——是一个名词短语、一个介词短语、还是一个从句:
I know the answer. // 补足语是名词短语
I know that he is right. // 补足语是从句
I want to leave. // 补足语是不定式
三句话里动词的"语义配价"没有变,变的只是补足语在句法上呈现的形式——就像同一个参数在编程里可以传入不同类型的值(只要符合接口约束)。
4.5 附加语(Adjunct)= 可选参数
function eat(
agent: Agent,
object?: Patient, // 可选参数
location?: Location, // 可选参数
time?: Time // 可选参数
): Event
He eats. // 一价用法,合法
He eats an apple. // 二价用法,合法
He eats an apple in the kitchen. // 可选参数不传也合法
in the kitchen 不是 eat 语义上要求的参与者,去掉句子依然完整——这正是"可选参数"不传也能正常求值的编程行为。语言学把这类"可去掉"的成分叫附加语(adjunct),跟"论元"形成对照。
4.6 函数重载(Overloading)= 动词变价
同一个动词在不同上下文里"变价",等价于同一个函数名注册了多个签名不同的重载版本:
function eat(agent: Agent): Event // 重载 1:一价
function eat(agent: Agent, object: Patient): Event // 重载 2:二价
使役交替(causative alternation)则更进一步,是参数位置本身发生了重新绑定:
function break(agent: Agent, object: Patient): Event // He broke the window.
function break(object: Patient): Event // The window broke.
第二个 break 里,原来处于宾语位置的参数"升级"占据了主语位置——这在编译器实现里,类似于同一个函数名底层绑定了两套完全不同的调用逻辑。
4.7 系动词(Copula)= 恒等函数 / 透明中间层
be 这类系动词,语义上几乎是空的,它不像 give、break 那样自带一份实义配价要求,而更像一个只做参数转发、自己不处理业务逻辑的中间层函数:
function be(subject: Entity, predicate: Predicate): State {
return predicate(subject); // be 本身不添加语义,只负责转发调用
}
be("She", happy) // 等价于直接调用 happy("She")
真正携带语义配价的是表语——上面例子里的 happy 才是"形容词函数",它自己要求一个论元(经历者);be 只是把这次调用用合法的英语语序包装出来,顺带挂上时态和人称这些语法屈折信息,就像一层只做参数转发、不改变业务逻辑的中间件。
五、总览:句法术语与编程概念的对照表
| 语言学术语 | 编程/数学类比 | 回答的问题 |
|---|---|---|
| 函数(数学) | 动词(语言学最初的灵感来源) | 一个规则需要几个输入才能求值? |
| 配价(valency) | 函数签名 / 参数个数(arity) | 这个动词要求几个参数? |
| 论元(argument) | 实参(passed-in values) | 实际传入的是什么? |
| 题元角色(θ-role) | 参数类型标注 | 每个参数扮演什么语义角色? |
| 补足语(complement) | 参数在调用语句里的书写形式 | 句法上怎么实现这个参数? |
| 附加语(adjunct) | 可选参数 | 不传也能正常求值的部分 |
| 动词变价 | 函数重载(overloading) | 同一个函数名注册多套签名 |
| 系动词 | 恒等函数 / 透明中间层 | 自身不产生语义,只做参数转发 |
六、这套类比为什么成立,而不只是巧合的附会
"argument"这个词从数学、到编程、再到语言学,始终指向同一件事:一个中心算子(函数/动词)所要求的、用来使其"求值完整"的输入。泰尼埃在提出配价理论时,直接借用的就是这套数学函数的语言——动词是运算符,名词短语是操作数,句子则是这次"调用"最终求出的值。
这不是后人牵强附会的类比,而是配价理论从诞生之初就自带的血统:句法语义学关心"一个中心成分需要哪些参与者才能构成完整意义",函数式编程关心"一个函数需要哪些参数才能返回一个值"——二者共享的,正是同一套关于"规则与输入"的底层逻辑。

浙公网安备 33010602011771号