位置传参 vs 命名参数:自然语言里的“格”与代码架构
在许多编程语言中,我们可以通过位置(Positional Arguments)或键名(Named Arguments)来为函数传参——前者依赖严格的出现顺序,后者则通过显式的类型与变量标记解耦了物理位置。
自然语言的演化亦遵循着同样的系统设计哲学:没有“格”(Case)的语言(如现代英语或汉语)就像只支持位置传参的函数,必须依靠极其严格的词序(SVO)来让编译器(大脑)推断主宾关系;而拥有丰富“格”标记的语言(如拉丁语、古冰岛语或德语)则相当于为每一个名词贴上了显式的“键名/类型标签”,只要标记存在,词汇便能在句子中自由飘移而绝无语义混淆。这种在“运行时记忆开销”与“词序表达自由度”之间的博弈,恰是自然语言在数千年迭代中所展现的最优雅的架构设计之一。
- 没有“格”的语言(如汉语、英语): 类似于“按位置传参”(Positional Arguments)。
- 表达式:
func(Subject, Object) - 在英语或汉语中,词序(Word Order)决定了语法功能。例如:
John bit the dog(John 是主语,dog 是宾语)- 如果把顺序颠倒变成
The dog bit John,语义就彻底变了。
- 因为没有显式的标记,编译器(大脑)只能严格依赖参数在序列中的相对位置(位置索引)来推断谁是动作的发起者,谁是接受者。
- 表达式:
- 有“格”(Case)的语言(如拉丁语、德语、俄语、古冰岛语): 类似于“按命名参数传参”(Named / Keyed Arguments)。
- 表达式:
func(agent: John_NOM, patient: dog_ACC) - 在这些语言中,名词后附加了“格标记”(Case Suffix/Marker)。例如主格标记(Nominative)代表主语(Agent),宾格标记(Accusative)代表宾语(Patient)。
- 只要名词身上贴着这个“变量名标签/类型标签”,它在句子里的位置就可以极度自由:
- 拉丁语:Johannes canem mordet(John-主格 dog-宾格 bites)
- 颠倒顺序:Canem Johannes mordet(dog-宾格 John-主格 bites)
- 无论位置怎么换,编译器(大脑)通过读取名词上的“格标签”(Name/Key),就能精准匹配到正确的形参位置,语义完全不变(只影响修辞或强调焦点)。
- 表达式:
语言学中的“语法权衡”
既然这个类比这么贴切,我们甚至可以用编程语言的设计思想,来解释为什么世界上有的语言保留了复杂的“格”,而有的语言却丢弃了“格”:
内存/传输开销 vs. 语法灵活性(Overhead vs. Flexibility)
-
按名字传参(有“格”的语言):
- 优点: 词序极度自由(Flexible Order)。这在诗歌、修辞或需要强调特定信息(Focus/Topic)时极其方便,你可以把任何想强调的词放在句首,而不用担心语法崩溃。
- 缺点(运行时开销高): 每一个名词都需要根据性(Gender)、数(Number)、格(Case)进行极其繁琐的屈折变格(Inflection)。
- 语言学事实: 说话者和听话者的大脑必须实时维护一张庞大的“变格表”(类似于复杂的类型转换和运行时标签解析),记忆和调用开销巨大。
-
按顺序传参(无/弱“格”的语言):
- 优点: 名词本身形式非常纯粹(比如汉语/英语里的
dog,无论做主语还是宾语,拼写都不变),极大地降低了词汇形态的记忆开销。 - 缺点: 必须牺牲词序灵活性(Rigid Word Order)。你不能随便乱摆词汇的位置,必须严格遵守 SVO(主-谓-宾)或 SOV 结构,否则代码(句子)就会产生编译错误(语法错误)或语义篡改。
- 优点: 名词本身形式非常纯粹(比如汉语/英语里的
语言演化中的“类型系统重构”
历史上许多语言从“有格”向“无格”演化(例如古英语演化为现代英语,拉丁语演化为法语/意大利语),这个过程非常像编程语言的重构:
- 早期(如拉丁语/古英语):依靠名词后缀(格)来按名字传参。
- 演化期:随着口语发音的磨损,名词末尾的“格标签”渐渐被读模糊了(类型标签丢失,产生了类型不安全)。
- 应对方案:为了避免语义混淆,语言系统引入了更严格的词序以及介词(Prepositions)。
- 介词(如 to, from, with)其实就像是 引入了显式的包装函数或映射接口,用来弥补丢失的“格标签”。