君子不器(君子不做工具人)
形而上者谓之道,形而下者谓之器。”形而上是无形的道体,形而下是万物各自的相。被万物各自的形象与用途束缚,就不能领悟、回归到无形的道体之中。
君子心怀天下,不像器具那样,作用仅仅限于某一方面。器者,形也。有形即有度,有度必满盈。故君子之思不器,君子之行不器,君子之量不器。
所以面向对象语言,如Java等,都是在“器”里钻研。道,是否就是流程、函数、lambda。
强类型语言,都有一套自己的类型规则。函数式语言有类型推导检查,推导不过就不让你写代码。
是解决类型推导这个问题,还是计算本身。如果有编译还好,编译期检查类型,编译后无类型检查,运行效率会很高。
函数式的类型,会像正则表达式一样复杂化。蕴含多态,而且是递归式的,可能需要对节点命名,而一旦得到命名的节点,就“器”化地存在,成为质碍,项目无限地庞杂,需要高智力的统畴,无法局部化,还有对同声明不同命名的类型是否相同的推导。
为什么类型会复杂化?因为需求本来是复杂的,需求不按类型来,类型只有去有去适应需求。需求方的模型里面,本来就没有类型,而是松散的字典、列表与流程,js已经很相似,而自作聪明定义模型,要么能否定需求,要么只得乖乖大范围打开类型或推倒重构,都不是愉快的事。
从机器语言到高级语言,都是降低性能去适合人类的使用习惯,而编码本身,也是为了实现乱七八糟的需求。强类型语言,你得曲折求全去实现那些需求,因为必须低头遵循强类型的规则。可是这曲折得一多,出现的问题也会多,更不易理解,是否会比一两句简单的动态语言更有优势?动态语言不受约束。但项目规模大之后,动态语言都无法解决,静态语言能做到更好吗?项目终归是人的脑子在管理,人管理语言,语言管理项目。如果人脑子统摄不了,能用静态语言去统摄?
总有人拿没有例证证明自己便是最好的,所以什么应试教育好,当下就是最好。其实封建社会不知道资本主义的好。
需求稳定,倒是可以用静态语言去固定模型,进一步优化。这时候业务逻辑已经成为大家脑子里固定的模型。
需要用类型验证空吗?我认为验证空是业务逻辑,但类型把统一的问题掰开成两处。
需要类型吗?在red语言里,对字符串进行了细分,比如邮箱类型,如果这种细化在Java等面向对象语言里去实现,细节就多了。这是类型验证与业务逻辑的抢夺。给人看的api文档是不可替代的。但传统强类型语言重构能力强,这倒是不可替代的优点,每次调整api,能在IDE提示到所有调整api的地方,但验证到什么样的程度?只是手动对比回忆?或者特别与规则地命名再遍历文件?(目前是这样做的)
数据库字段有允许空、长度、无重,是搜索优化,业务代码中如果不预检查,则会从数据库报出客户看不懂的内部错误。关系数据库有长度等,只是对现实的一种建模方式,总在根据现实而调整(随认识增加,努力与真实模型一致),关系数据库像面向对象语言,更准确说是结构体的C。我认为数据库应该是文档链表,每次提交都是一个文件,文件内部依填写者去关联别的文件,文件要遍历搜索,那种全部反序列化是不可少的,只是本机与多线程使个人的效率提高。
命名是增加概念,概念越多越复杂,越难以理解,是器的范畴。
哪种语言命名少?Java支持匿名类,比其它面向对象语言如(C#)减少很多名字。即显然带Lambda的语言命名少。反观面向对象语言,类型命名完全是凭空捏造的,业务逻辑不需要的。面向对象语言是建模与性能的妥协。
一门语言需要哪些核心呢?1.表达式,树状表达式嵌套,从叶子结点递归执行,返回结果。既然要递归执行,表达式本身就不应该是表达式的数据结构(否定宏)。2.表达式需要取定义,因此要有定义表达式(S-Lisp中的Let表达式)。3.表达式执行依函数,自定义函数为了复用代码,所以要能定义函数。函数也是一种对表达式的延迟执行(唯一一种)。基本上就可以了,其它如if、while语句,都可以用函数组合来实现。
从数据结构的角度来说,对一个数据结构进行解释,列表就够了,可以根据提示值将其解释为某种特定数据结构,比如字典。但要扩充解释,目标解释器并不一定有足够的内置解释,于是需要客户去自定义解释方法,这就相当于将列表的第一个声明为函数,去解释这个列表的后续部分。
语法越多,增加语言的复杂度,并无好处,未来发展方向不定,还存在分叉与兼容问题。S表达式就够了,一切用库组合。
自然语言表达需求,需求会向什么方向发展?代码的复杂度与需求的复杂度之差越小越好,但业务逻辑复杂到一定程度,如果带Lambda的语言都无法解决,其它的只有更甚,不能归咎于语言。想要修改,总归得了解全局逻辑(项目最好能依高聚低耦拆分成一个个小项目)。需求的表述,也是逻辑的有先后顺序,定义函数的场合,必然知道定义前的东西,这便是Lambda的闭包。
类型就像自行车的辅助轮,新手可能需要,但带着累赘,只能在潜水区扑腾,或者本可以潜得更深。需要主动管理类型,类型的存在感太强,如果有某种新技术能让IDE在不声明类型时安全检查到隐患。如果语言是可以类型推导的,是不是也意味着存在大量冗余而将无类型的隐患变成庞杂代码的隐患?
人们希望编程能做更好(Java+Spring…),结果变成一堆凑合复杂业务的烂摊子,其实也只能找到解决问题的语言(js到S-Lisp)。
面向对象不是完全没有,比如各S-Lisp都是用面向对象来实现的,只有目前过于流行泛滥了。js应该流行,因为lambda像自然语言一样轻松表达。那什么情况需要用面向对象呢?目标足够明确,需求基本不会发生变化,或者说是对现实业务需求已经充分认识,则可以用面向对象固化下来,甚至可以进行性能优化,反哺验证现实中的需求异常和操作异常。