Unix缺陷读后

10 Sep 2012

写了很长时间,一直放在gmail里面存着,今晚整理收件夹,拿出来了

最近读了王垠的《Unix的缺陷》http://blog.sina.com.cn/s/blog_5d90e82f01014k5j.html 文章似乎主要集中在Unix的设计哲学中的使用文本流的方法。

举例的是命令行用户接口不友好,特别是文本流和命令的选项之间的混淆,造成的误删除等等的操作,和find中查找文件时文件名称存在空格的问题。 这些问题主要的原因还是使用文本流造成的类型丢失,被统一转换成了字符串类型,而不具备其他的属性方便程序区分造成。

其实文本流的手段不过操作系统IPC的途径之一。文本流通过管道的方式,实现IPC。 王垠提出的方法是如下的三点:

  1. 保留数据类型结构。
  2. 统一标准表示数据结构
  3. 程序间的数据传递和存储,像程序内部的数据结构一样。

三个方法,似乎从可行上来看没有任何可能,不过不考虑执行的可行性,其思想还是十分美好的,为了实现这些方法,已经有了很多方面的努力,不过貌似,还是文本流最受欢迎。 程序间的数据传递和存储,在某些情况下,也都是利用内部数据结构来描述的,文本流的IPC只不过是一部分,其他的更加直接的IPC方法,譬如Socket和共享内存,有很多也是通过内部数据直接传递的,但是其实这个和文本流也没有什么本质的区别,在目前通用计算机的体系下,任何数据结构都有一个前提,就是能够在内存中表示,而内存不过是一个一维的存储部件,和文本流一样,如果真的需要以内部数据结构来传递和存储IPC的消息,其实文本流也一样,不过是二进制和文本流的区别而已。不过这一说法其实就很流氓了,因为最通用的当然是二进制流了,越简单越通用,但是二进制流的可读性真的确实不如文本流了。

回头来看,只能是这样的一个结论,All structs suck, text just sucks less。王垠提出的方法似乎也与他的研究方向有一定的关系,希望利用程序语言设计的思想来设计一个更加优美的系统。 而文本流的问题其实是一个进程间通讯的手段问题,在实现进程间通讯上似乎Plan9,MS的com等等都有做过尝试,虽然有得有失,但是似乎现在文本流还是一个不错的解法。

统一所有接口的理想有很大的吸引力和美感,但是这个想法在实践上似乎有很大的问题,本身接口能否满足统一的条件不算,在完成统一后,其实还是需要进行接口描述以方便用户使用的,不论这个用户是人类还是机器,也接口如何必须让使用这些接口的用户能够理解,对人类来说图片、表格、文本流都是少不了的。不过文中将shell程序抽象成为函数的方法确实让自己换了一个角度来看待问题。

有关文本流带来的问题上,

  1. 在配置文件上,似乎即使统一了格式,管理好还是需要大量的人力物力的,会不会变成MS的注册表的管理(这个也是结构化的统一的格式的配置文件管理),那还真不如文本流来的实在。不过萝卜青菜各有所爱,如果可以在配置文件上统一好格式,肯定会更好。
  2. 程序使用结构化,这个倒是真可以有。不过不知道编译器在词法语法分析上耗费的时间有多少比例,不过常识上看,文本处理确实是耗时的一件事情。
  3. 数据库接口,SQL语句有更多类型支持方便调试倒是很不错,不过程序还是人写出来的,SQL语句也肯定存在一个文本流到语法树的过程,这个是不是与文本流有太大的关系?似乎更多的还是语言设计上的类型安全性上?
  4. XML,XML的设计目的似乎就是试图完成结构化数据和可读性的结合,不过现在来看结果是两边都不讨好,两边都弄个将就,尴尬。而各种复杂的XML标准其实也是为了统一数据结构的理想,不过,都是挺讨人厌的。
  5. JS的安全性,这个即使加上类型,安全性肯定也不能解决,但是肯定会好一点的。字符串可以随意拼接,这个当然,结构化的代码照样也可以任意组合,只要是通过CPU的二进制流,那都是安全隐患,安全性与文本流没有必然的联系。换成不用文本流只不过是代码入侵的手段有点变化而已。
  6. IDE接口,这个倒是真可以有,不过这个其实想想实践上的问题,也就要泄气了。不过Apple Scipt是通过结构化的数据实现了进程间通讯,这个确实很不过,可以加强普通应用的自动化水平。不过其实很多应用也并不支持Apple Scipt的外部接口。
  7. log分析,结构化的log还是要依靠人来提取有用的信息,不过结构化的log的优势是工具具有通用性,减少不少无用功。
  8. 测试上,如果强行要求不得使用toString进行对比也就可以避免这个问题了,貌似这个更是一个规范的问题。结构化数据在自动化对比上方便,但是结构化数据也有序列化的需求,即使不序列化成为文本流,也得序列化成为其他的格式

在文中提出的解决方法中

  1. 保留数据结构,不涉及人机交互可以,但是一旦存在人机交互,总能有个人能读的东西,文本流算是 sucks less的东西了。
  2. 还是执行的问题,说的很美好,但是执行上没辙。就像说“大家讲道德,要高尚”。谁都知道将道德好,结果照样有不讲道德的。
  3. 这个当然好,但是程序的数据怎么实现自描述,才能提供给别的程序(这是动态导入和解析上的观点)。静态上,没有问题。

后面提出的带来的好处

  1. 智能补全上,用文本流也可以补全,不过需要加个描述文件,当然,这个就是结构化数据了,在外面来个描述文件确实有点丑陋,要真的内部集成那敢情好。
  2. 真心没看懂,哪怕从自己的角度理解也没看懂,果断不乱说了。
  3. 这个其实也是进程间通讯的协议涉及问题,有了这个协议和文本流完全可以共存,所以和文本流没什么关系。
  4. 代码以Parse tree存储,怎样来实现展示呢,再解析成代码?程序写个文本,存成Parse tree,然后再解析回来,怎么保证还是原来的样子呢?以Parse tree存储的形式应该应用在和开发没有关系的情况下。这个和IDE的扩展又有什么联系呢?解析程序代码应该是编译器的事情,不过每次都能解析成Parse tree后,编译器、程序语言语法、编辑器相互之间的联系肯定可以更自然紧密一点。
  5. 这个貌似还是上面4的结构化存储后带来的编辑器和程序语法的联系紧密,不过直接结构化的代码,难道让程序员直接接触这种形式?貌似LISP确实很接近结构化的,因为它是语言及数据,数据也可以作为语言的。毕竟还有其他形式的语言,不能语言上都统一成一样的吧。
  6. 这个敢情好,不过,程序语言是有语义这个因素在里面的,完美的结构化版本控制应该还有很大距离。
  7. 三位一体这个东西,很有宗教宣传的感觉。不过貌似也还是三者的接口三位一体而已,和下面的实现其实也没什么关系,即使在目前情况下,在这三个东西上层加一个抽象层,一样就是三位一体了。不过确实很符合自己的未来价值观,程序最终是用户所写,开发者提供的是编程的基础设施。