@
aloxaf len 这种东西说不上多巧妙,但是现实中几个值得一提展开的点(还是普遍到跟 Python 不需要直接关系)。
我确信 GvR 始终没摸到这方面的坑的主要边界,以至于解释中很大程度都是 ABC 的历史包袱。
1.关于混合所谓自由函数和方法的问题。
其实大多数语言都还没有复杂到要你纠结坑的地步,但也存在进退失据的例子。搜索 C++ UFCS 有真相。
因为,认为 len(x)和 x.len()不是一种含义会造成明显的不一致,以至于有不少人认为这两种语法的含义干脆合并得了,定义一个就能两用。但这样就有个灵魂拷问:既然允许 len(x),为啥还要发明 x.len(),浪费一个不同的语法?然后什么 customization point 之类的妖魔鬼怪上来凑一脚,不忍直视……
所谓“前缀符号更可读,简单胜过复杂”其实倒并非没有道理。
仔细还原这类语言的语义规则,*this 被作为隐藏的参数,但这其实还有个更一般的形式——静态环境(在静态语言中通常被处理成不可见的符号表)。
隐藏显式名称查找的语法,都写成前缀,比如 Lisp 语法:(len x)——就能发现完全是一回事。是不是要依赖 this/self ,只不过 len 到底是从哪里来的罢了,这完全可以作为实现细节,而实现这里的简单。
2.这玩意儿是个普遍的问题,和 OOP 本没多大关系。
扯上 OOP 的关系,大约是某 PL 大手子的功劳。
这样的理解原则上就是歪的,应当予以纠正:
https://stackoverflow.com/a/74375048 。
无论是误会的形成还是传播,去除脏话以后,拍案叫绝的成分都是够多的。
顺便,至于 0 索引,那倒是有点洞察世界的味道,但是只字不提 EWD831 (
https://www.cs.utexas.edu/~EWD/transcriptions/EWD08xx/EWD831.html )这种常识性文献,多少有点过分。
原文评论区有人指出了这点。GvR 只是提供了关于 slice 的新发明,然而除了提了一点避免 off-by-one 错误问题外并没有涵盖 EWD831 的内容。
EWD831 距离所谓的世界的洞察也是有一段距离的,因为它只是很隐晦地顺带提到了根本原因:基数(cardinals)和序数(ordinals)的区别。
这种洞察,对有点数学(哲学)系统训练的用户来说,实在过于基础了,也许不值一提。不过放在这种文献中解释,从一般情形(而非举例)证明为什么索引应该从 0 开始,本应当是有必要的。不过作者并没那么做。