《说文解字》与程序设计

说文解字

《说文解字》,简称《说文》,是由东汉经学家、文字学家许慎编著的语文工具书著作。《说文解字》是中国最早的系统分析汉字字形和考究字源的语文辞书,也是世界上很早的字典之一。

以上是“说文解字”在百度百科的解释,前段时间刷知乎时,看到了W雨辰一篇介绍汉字造字法(指事,象形,形声,会意,转注,假借)的文章,其介绍简单有趣,深入浅出,读完了之后感觉汉字的造字与程序设计、尤其是面向对象的设计有许多共同之处,写一篇文章记录一下思路,感兴趣的朋友可以一起来探讨下。

说文解字的格式

说文解字是有固定一种格式的,网上有许多网站支持搜索《说文解字》,打开一个词典网,在上面搜索“老”字,弹出来的结果是这样的:

这个格式分三部分:

1. 元数据:某字,配一张图。

2. 职责:X也。

3. 实现:从XX

比如:

:教行也。从匕从人,匕亦声。

:铸器之法也。从土刑声。

:更也。从攴己。

它的模型猜想图如下:

解字

庖丁解牛,解一个汉字,看看说文解字是如何诠释的:

更也。从攴己

这个【改】字的解释有点意思:从,就是继承的意思;从攴,继承于攴,攴从图画上看是一根小树枝的意思。那么这个“攴己”,就像是挥舞着小树枝抽打自己

……Why?为毛要抽自己?难道是因为自己欠抽吗??

——因为[更也]。更,指更新,鞭策自己是为了改过自新。

 

将上述描述换成面向对象语言:

class 更;
class 攴
{
    public 更 Do(object o);
}
class 改 : 攴;

var o = new 改();
var result = o.Do(new 己())

从攴,从有继承的意思。从支己,就是继承(攴)并调用函数传参(己)的意思。

 

这里有歧义的地方是“更也”,这个“更”不能仅仅做返回值处理,其更多的是表达了一种差量元数据(diff merge's metadata),这个差量元数据体现出了目的性

——鞭策自己是为了更新,这是“改”的本义。

 

用程序设计的思路描述:

class B;
class C;
class A :B
{
     public C do()      
}

翻译成说文解字:

A,C也,从B。

 

又如:

class B;
class C;
class D;
class A :B
{
     public C do() 
    {
         this.RaiseEvent(new D());
    }         
}

翻译成说文解字:

A,C也,从B,D声。

 

顺着这个解释,说文解字有着一系列精彩的发挥:

比如前面提到的“老”字:从人毛匕,它有三个元素:从人、毛、匕hua=化)。

按照知乎上w雨辰的解释:“人、毛、化”就是人的毛的化的意思——将人的毛看做头发,头发变化了……大概率是变白了……变白了就是老了。

这样就通过人——毛——匕的链条将“老”的意思解释清楚,这个令读者使用“意会”的方式get到字的方法,按照许老的说法:叫做《说文解字》。

 

这个人—毛—匕的解释,在面向对象的语言中非常常见,就是对象的属性赋值:

 class 人
 {
      public object 毛 { get; set; }  
 }

 var ren = new 人();
 ren.毛 = 匕;

以程序的角度来看,毛是人的一个属性,匕是毛的当前状态值。相当于

 {人,毛,匕} => 老

汉字造字的原理有点意思,它将【动态】的属性赋值(或者叫方法调用),连带着参数压缩成了一个【静态】的字,化动为静,在读者阅读时再通过意会的方式在读者脑子中解释执行。这种模式有点类似于反射,但类型信息又非常灵活。

这种把多级的信息集压缩到一个平面上,使其变成一个字,是汉字的一个造字原理。其展开方式来自于读者的意会:造字时将立体压缩成平面,理解时在读者脑子中将平面还原成立体

象形,指事,形声,会意,转注,假借

谈到了设计少不了模式,类似于程序设计的原则(开闭原则、单一职责原则等),说文解字也总结了其六大模式(设计原则),分别是:象形,指事,形声,会意,转注,假借,统称为六书:

六书

一曰指事。指事者,视而可识,察而见意。上下是也。

二曰象形。象形者,画成其物,随体诘诎,日月是也。

三日形声。形声者,以事为名,取譬相成,江河是也。

四日会意。会意者,比类合谊,以见指撝,武信是也。

五日转注。转注者,建类一首,同意相受,考老是也。

六日假借。假借者,本无其字,依声托事,令长是也。

 

寻找下对应关系:

一、象形:顾名思义,就是抽象,通过形状上的相似抽象出对象。  

object o = new object(); 

二、指事:指事。这个事用来特指,好比电影里面的特写镜头,点出来说明些“特殊味道”。

比如说 本 = 木 + 一,下面的“一”代表了树木的根部,用一(横)指出来,提醒人不管长多大,都不要忘记最初的一横。

指事在面向对象语言里,多用事件或消息表述:

o.RaiseEvent();

三、形声:把两个或多个对象放在一起来衍生,

“形”:定义了边界,定义了轮廓——对象在环境中的外在。

“声”,类似波,指对象对外能发出的功能。

class A;
class B
{
    private A a;
    public void Do {  a.do(); }
}

按照汉字的解释,一个对象调用另一个对象的方法,就是借助此一对象让另一对象发出“声音”。

汉字在这里的解释有些意思,声音无孔不入,对一个对象的方法调用,表面上看,似乎只会对被修改的对象产生影响。而汉字用声音说明,这种改变对象状态会对系统内的所有对象产生影响,只是不容易从表面看出,因为光还没有照到其它对象。

好比,一个人听了一句话,虽然表面上不动声色,可内心早已mmp的……波澜汹涌。

 

四、会意:使用多重继承,将两个意象并列放在一起,令人意会。

比如“信”是会意,把“人”和“言”放在一起,令人意会(……人和言放在一起是什么意思……信的意思吗?),意会出的意思就比较接近了。

class A;
class B;
class C :A, B 

相比于程序设计极力避开多继承,避开菱形继承,汉字系统就是建立在多继承的基础之上,在程序设计中is-a是主体,has-a是优选;而汉字系统中has-a是主体,is-a是优选

 

五、转注:类似多态,又有点像函数调用链。

老,从人毛匕——“人”,调用“毛”,再调用“匕”,这种调用更像是一种连接,如何把“人”、“毛”、“匕”用合理性的方式连接起来,直接传达出使用者的意图。

令功能本义不变,边界旋转,寻找一种可以从一个字注入到下一个字的方法。

class A
{
     private B b;
     public void Do()
     [
          b.Do();    
     }    
}

class B
{
     private C c;
     public void Do()
     {
          c.Do();    
     }    
 }  

六、假借

按照wu雨辰的解释:

比如“美”是指味道鲜美,但是人长得漂亮怎么形容呢?比如把人和美放在一起,那就把美假借为了“美丽”的意思了,跟“美”的本义“美味”意思不同,但是有没有必要再为了这层意思再造一个字形呢?其实没必要的,把“美”的字形拿过来假借一下,大家自然就明白什么意思了,“美”每变一个情景,就多一种假借,而且这个假借还让你看起来不动声色,后来才有了一字多义。

 

假借有种类型推断(匿名类型)的味道,将字还原到本义(将class还原成data、甚至还原成元数据metadata),再将其适配到其他字(类型)。 

假借有一种系统间通过DTO传参的味道:

struct Data;

class A
{
     public Data ToDTO();  
}

class B
{
     public static B FromDTO(Data data);
}

A a = new A();
var data = a.ToDTO();
var b = B.FromDTO(data);  

模型

回到最初的字模型,猜想一下:字=元数据(形)+职责(音)+实现(义)

其模型图:

汉字是一种象形文字,它和拼音文字相比,最大程序保留了元数据(图)。

有了元数据,系统就有了回溯的可能——当汉字无法理解(无法沟通)之时,可以还原到图上来理解,相比于拼音文字,它提供了一种回溯(Recompile)的可能性。

使用者随时可以利用元数据瓦解一个字,来获得其原始“意图”。类似于对象设计中的object.GetType(),随时可获取对象的类型数据,这个元数据是以一种更高级别的抽象(粗略的图)来提供的。使用者可以与时俱进,将元数据的图根据当前环境重编译(重解释),以更好的适应时代的变化。

汉字的系统演进了几千年(或更久),现代的编程语言几年内就会有种面目全非、令创始人都感慨的变化,而汉字系统依旧保持着旺盛的生命力,其形音义的设计理念有着精髓之处,值得令人深挖。

 

这种在编码的时候附带元信息的方式,在程序中可是特性、或是注释,在沟通里被称为意图,在设计上又看成背景。通常情况下,它与主信息之间呈现一种分离态。

而在汉字系统中,形音义“三位一体”,一个字的形音义必须全部确定后,它才会长久地存在下去。

汉字演进

乘坐时光,回到汉字的早期年代,观察一下汉字的演进:

举个例子: 需求

需求由“需”和“求”两个字组成。

 

需字:

 

求字

 

这两个字的图片有点意思,一个是一位"湿身"的男子,一个是一只伸长了求索的手。

需:天在下雨,人被淋湿

求:一只伸长的手

 

当“需”和“求”两个字金风玉露一相逢,便交会了人间无数。

做软件的少不了“需求”,这是一个高频词语,带点文绉绉,又很压人……“这个需求能否解决?”“确认一下客户需求。”“这个需求不合理。”

 

从元数据(图)上来看,这个词会有哪些启示呢?

 

单从图上来看,需求出现了三个基本元素:雨、人、手。 

缺少这三个元素的其中之一,都不能称之为“需求”,比如:

1. 如果天不下雨,那就不叫需求。

2. 如果人没被淋湿,也不叫需求。

3. 如果没伸出手,更不叫需求。

 

换成客户(爸爸)的解释:

1. 如果市场环境没发生变化,不叫需求,提了白提,客户不理解——(雨)。

2. 如果客户没伤到切身利益,不叫需求,说了白说,客户不痛——(人)。

3. 如果客户没主动要求,不叫需求,皇帝不急太监急,没用——(手)。

 

将这个解释抽象出道理:

  1. 如果大环境、时间不对,不叫需求——天时。
  2. 如果区域不对,不叫需求——地利。
  3. 如果客户吃瓜看热闹,不叫需求——人和。

 

这是一种越过词语,直接从元数据(字义)看图说话的解释,相对于词义,汉字的字义往往携带了更精髓的最初的元信息。

 

再举个例子:封装(面向对象高频词)。

=+(圭,诸侯的玉圭,代表责任;寸,恭恭敬敬手持,代表守责任)

装+(衣,上身穿的叫衣,下身穿的叫裳;壮,大也)

 

从字面来说,封装:要有责任,守责任,上身穿的好,肩膀端得住。

 

这个字面分析给出了一个很有意思的观点:面向对象的封装只封“上半身”即可,要玩“下半身失踪”。也就是说,面向对象的封装要有一种“并蒂莲”,要保留通过地下(类似于指针、内存)等从下一层次访问修改的可能性。

另,“壮”说明,对象的聚合性永远呈放大趋势,其有像龙卷风一样将其它对象席卷其中的野心——每一个对象都有成为“聚合根”的冲动和向往。

汉字系统

汉字的系统设计非常灵活,一个字既可以充当另一个字的基类,又可以充当另一个的方法、甚至可以是另一个字的元数据,其合理性来自于群体认证:

一个字(对象)不是合理才能应用,而是因为应用才产生合理

 

汉字的意会方式是一种元数据交流方式,意会的过程是一个先编译后执行的过程。如果把两个人比做两台电脑,在它们的网络通信中,不使用RPC调用,不使用Restful方法,而是在传输中直接传送元数据,接收方得到元数据,在其本地进行(无厘头)编译,以一种本地热重载(创建类型、JIT编译、解释执行)的方式完成沟通。

 

意会是一种“大数据”编译。

这种元数据通信方式可以充分的解耦,其有很高的扩展性,其本地编译的效果取决于“常识”、“经验”、“情感”,像是一种“大数据”编译,其注重的是不要丧失“不确定性”,不确定性是确定性的背景,它为确定性提供了生命力以及演化的可能性,它使得概念向本义收敛与边界扩张两个维度变化。

总结

本文讨论了《说文解字》与程序设计的关系,但牵强附会的地方很多,很多地方都是(无厘头)编译——开局一张图,内容全靠编。 

 伟大系统总有共通之处。

作为流传了几千年、上万年的文字系统,其内部有很深的智慧存在。

学习先贤,吸取一些经历时间(实践)证明过的设计真谛,希望程序设计和汉字设计能够借鉴、融合。

希望有风来的地方,都有阳光闪耀。

 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

posted @ 2021-05-23 14:14  周永恒  阅读(1014)  评论(3编辑  收藏  举报