更新的命名方法,请参见第二篇
"好多人都故意在文章开头引用诗句来表达自己的情怀,我从来不干这种事" —— nimomeng
口、 引子
“你的函数名字太难读懂了!”
“代码不仅仅要实现需求,还应该能让别人看懂。”
“你这个代码命名很不合理!”
很多新码农在工作中总会被老鸟批评程序命名的陋习,我也被批评过很多次。痛定思过,我决定要研究应该怎么命名,为什么要给函数一个好的命名很难,应该怎么样给函数命名。
一、 大牛们怎么看函数命名
Stephen Wolfram[1][2]对于函数命名进行了表述,总结了什么样的命名是好的命名,什么样的命名会给人造成困扰;同时他说,函数命名的过程就像一首短诗,值得仔细推敲,细细品味。
Xah Lee[3]指出,好的命名应该可以让领域外的人一目了然,批评了Lisp语言的命名,如cdr,car,cons,认为这些命名让不懂Lisp的人看得不知所云,也批评了pop、push、shift这些命名,认为这些命名都与数据结构有过于深刻的关联。他认为这些过分含有领域背景的命名都是风格不好的命名。
Marcus M. Edvall[4]认为,命名应该尽量从简,而且推荐用三个字母的前缀来区分各个函数的命名,如ibm公司定义的函数用ibm_xxx来标识,或者文件模块的函数用fil_xxx来标识。
大牛们的观点总结如下:
好的命名 | 坏的命名 |
---|---|
简单,可以望文生句 | 用词太过宽泛 |
跨领域,外行一看便知 | 用词太过技术化 |
优美的像一首极简的诗 | 用容易产生歧义的词 |
在充分理解函数功能的基础上进行 | 函数本身功能实现有问题 |
可是,在现实世界中,起名字并不是特别困难的事,为什么在程序语言里给函数命名是一件看起来非常困难的事呢?
二、 人类世界语言VS程序语言
这种困难,归根结底是人类世界的语言和程序语言存在差异,主要在以下三个方面:
人类语言 | 程序语言 |
---|---|
定义不清晰,逐渐细化 | 完全、清晰、明确的定义 |
含义不唯一,需要上下文 | 有名函数具有严格、唯一的含义及使用场景 |
更容易来造词 | 只能在已有语言基础上来拼接 |
- 人类语言中,词的产生大多是由个人慢慢扩散至群体,并在过程中不断细化其含义。这些词一开始只在一个人或者一小群人里流行,慢慢的口口相传,在传播的过程中不断的细化,最终成为通用、流行的词汇,比如晒工资、房奴等词。人类世界语言的词的含义允许用时间来修正。而程序语言中,一个函数命名一旦被确定,马上会被相关所有函数确定并知晓,这个函数的重命名、修改、删除都会被其它相关函数所察觉。这一过程是瞬时性的,不允许用时间来修正的,且影响力始终不变的。例如Mathematica 1.0(1987)年的很多函数命名至今都没变,其影响力始终如一。
- 人类语言中词的含义往往不唯一,需要借鉴上下文里其它词来确定其含义。而程序语言中,每个函数都在一个特殊、唯一的场景里被命名,其含义也是唯一、不变的。
- 人类语言中的字、词允许再造。而在程序语言中,只能基于已有的语言基础去造词,比如大部分基于英语的程序语言,和基于中文的易语言。
那了解了什么样的函数命名是好的命名,也了解了为什么程序语言命名难,那该怎么对函数进行命名呢?
三、 如何给一个函数命名
我认为,可以通过以下六种方法进行函数命名:
- 基于已有认知。如果在领域里已经有一些约定俗成的函数命名,最好直接拿来用,比如I18N、L10N等。新词最好由约定俗成的命名所构成,例如PointX。
- 尽量反映函数的通用性。命名应当能够反映函数的各种用途,如果函数本身是通用的,但是其命名带有某种领域的误导性,那么这种无形中缩小了函数使用范围的命名就是不好的命名。
- 能望文生义。好的命名应该一目了然,而且针对不同的情况应该做不同的命名。如果针对复杂函数,应当用复杂命名,如EventHandler;针对简单、直接、常见功能用尽量简单的名称,如表示尺寸的Size;针对生僻的函数功能用不很常见的名称,如Through。
- 由句到词。遇到不知道改怎么命名的函数,先用一句话将函数描述出来,再逐渐提炼、精简句子结构,最终提炼出函数名称。
- 类比、联想。如果找不到合适的词语,可以采用类比、联想等方式,形象的表述一个函数的含义,比如throw、catch。
- 易于理解。尽量不用一些容易造成误解的词语,比如live、active等词。
解决了用什么词给函数命名的问题,但是怎么解决一些复杂情况下,词语组合的顺序问题?来看下Mathematica7的命名分析。
四、 Mathematica 7 命名统计分析
Mathematica是一款科学计算软件,很好地结合了数值和符号计算引擎、图形系统、编程语言、文本系统、和与其他应用程序的高级连接。而且作为一款跨领域软件,Mathematica的函数名能做到让不同领域的人一目了然,其命名很具有参考意义。
分析数据来源:Mathematica线上API的所有函数名
分析方法:通过提取API相关函数名并处理(如把复合词进行切词)并调用金山词霸线上API对所有函数名进行翻译,取第一个释义的词性进行统计,统计结果如下:

统计结果分析:
通过上述分析结果可以看出,名词和动词占了命名的最大比例。在对其中的名词和动词进行进一步分析之后,结论如下:
- 表述实体或者属性时,用名词或者名词词组。如Array、CMYKColor。
- 表述一个动作时,用动词或者动词词组。其中,若动作针对特殊实体,往往将实体名带上,如DeleteCases、FindRoot等;若动作属于通用性动作,则不带实体名,如Insert、Scan。
- 如果在描述一个实体时,需要突出被描述的实体,则将实体放在前,描述属性或者动作放在后面,如RootReduce、MapIndexed。
五、 总结
文章通过对命名进行研究,总结出一种函数命名方法,并通过对Mathematic的API函数名进行分析,得出各种情况下的词组组合情况。
希望小文能对各位朋友的工作起到帮助!
网友评论