FrankHB
2019-02-07 14:12:24 +08:00
本着“请尽量让自己的回复能够对别人有帮助”,还有另外几点没预热过的先给过一遍,预防以后跑题:
1.在实现语言时,indentation 的 error condition 不管算成 syntax error 还是 semantic error 都很别扭。这种逼迫实现无法区分 syntactic grammar 的语言设计姿势当然远不止是引入 semantic-sensitive indentation 一种,更著名拉仇恨的比如 C++的 vexing parse。据我所知,职业搞 PL 的基本不会在这上面跟自己和用户一起过不去,非要搞就是一个 preprocessing phase ( C processor、Lisp reader、……),和余下的语言规则的耦合通常是较为松散的;而这里 indentation 甚至能影响控制结构的特典就显得非常突兀了。某些语言的设计者如何忍受这些问题并坚持在一个实用且不拒绝未来扩展的语言中保留这类奇怪的 feature,就是一个耐人寻味的话题了。
2.有人提到,缩进多或少也跟代码质量普遍地有关。然而从操作上来看,这原则上只能在已知整个翻译单元的自顶向下的视点下才看起来有那么点意义。讨论重构之类的“工程级别”的变换(区分于语言实现的 code transformation ),通常默认更强调代码的局域性和松耦合:如果不影响外部的代码,能局部定位修改满足目的才是好的。这里和缩进层次多少并没有直接关系,差别只是编辑嵌套比较深的代码时需要对付的前缀缩进的数量确实比较多而已,然而调整这种缩进在大部分( py 以外的)用户的严重,本来就该是编辑器的机械劳动。缩进多影响代码质量的观点这个看法看起来也不是 py 用户的发明,那么它到底是哪来的?我能记得的好像就是某些 C 用户对嵌套控制语句的“滥用”非常不满而鼓吹嵌套超过若干层是不好的代码,逐渐演化成了缩进过多是不对的。但是这很大程度本来就是 C 的无能,不知道为何推广到不少其它语言上好像也被莫名其妙地接受了。
技术细节:C 没有函数嵌套(倒是省了 funarg problems ),因此除了控制语句外很多重复构造的变换其实经常没有能耐嵌套(严格来说,struct+模仿 C++的 lambda operator()的 free function 可以做到,但实在太麻烦了,没见到有人日常这样写),所以很多东西干脆直接重复用代码(或者宏)实现了。Python 哲学里所谓 flat 优于 nested 这样的说法似乎也是这样来的?
反观 Lisp-like 的,大部分有意无意随便嵌套(倒也间接增加了)))))))))))的概率),用户就完全没这样的意识。