先说一个悖论吧。
程序员的任务是让机器帮助人类做工作。
程序员的唯一工作就是开发代码。
程序员喜欢手动hack开发代码。
这就是我今天想要讨论的。
今天读到了阮一峰翻译的为什么Lisp语言如此先进?感触很深。原文Revenge of the Nerds
正如我开头说明的一样,之所以软件工程这个领域这么奇怪,有什么人月神话;有各种其他工程都完全不可能遇见的奇怪问题;即使开发得非常熟悉的类型的项目,再去开发仍然无法准确估计工期和成本;最讨厌的代码就是别人的代码,要知道别的工程领域流水线都是最重要的提高效率的方案,也就是在其他人做了某个步骤的产品基础之上在做一个步骤;即使软件工程理论已经存在和发展了几十年,软件项目的可测性和可控性都完全没有提高;被业界高呼了二十年的面向对象被骂为骗局;等等等等。。。
之所以这一切问题存在,是因为软件工程根本就是一个悖论。当别的工程领域早就摆脱了手工作坊生产,早就工业化自动化了的时候,软件工程还在手动hack代码。就像摆着高大的吊车和推土机不用,软件工程师们想要徒手建造长城,一次又一次的非要从地基开始重新建起。
这里再附上之前在代码交叉拷贝悖论中同ownwaterloo的讨论吧,在读到上述那篇文章之前,其实我们已经走到某一个角落了,其实已经离这个真理只差一步之遥了。(好吧。。虽然我说的也不见得就是啥“真理”啦。。)
OwnWaterloo at 10/11/2010 18:12
不知道是不是想要这样的效果? 伪代码大致是这样:
for image in [ thumb, caption, buttom /* 这里还可以更多 */ ] :
image.offset(height)
image.rotation(270)
hawk at 10/11/2010 23:58
呜!这段代码很漂亮!
可惜c++效仿起来有难度。。
OwnWaterloo at 10/12/2010 10:36
其实那代码是一个暗示……
做GUI这种效率不吃紧的东西, 能不用C++, 就别用C++……
如果我早点学python, 并且发现OpenCV其实有python的绑定……
不知道可以节省多少时间…… 陪gf玩玩什么的……
hawk at 10/12/2010 16:25
那时候因为是在winCE上做widget,没有.NET,所以只能用C++了。。
现在做界面都尽可能用网页或者.NET了。。。
OwnWaterloo at 10/13/2010 12:37
.net也行, 它至少有元数据, 可以”按名字调用”。
C++在运行前完成”名字到地址的转换”, 运行时就没函数名了。
其实按今天的内存和磁盘容量来说, 元数据并不大。
但需要它的时候, 真离不开它……
貌似C++0x也不打算加入……
hawk at 10/14/2010 23:27
是的,javascript那种字符串直接当代码调用的功能强大得一塌糊涂!!
是的,.net的按名字调用,甚至javascript的自解释。为什么他们就那么强大呢?到lisp这里就找到祖宗了。可能就像文章中说的“格林斯潘第十定律”一样,在你追求代码自动化的过程中,你最终就会找到祖宗那里去了。
当然了,我相信lisp肯定也不是最终的完美。但是它是一个指引,指导我们什么是我们想要的。那就是自动化的编程。以前见过貌似是《程序员修炼之道》里面提到过的unix哲学理念,其中有一条是被人大为忽视的,就是让程序自动生成代码。刚在网上翻了一下,维基上的说法是“六:尽可能地榨取软件的全部价值”[引用]。这点是关键吧。软件工程应该像其他的工程一样,尽可能工业化、自动化,早日脱离3、5人小团队的作坊式生产(当然这样说很可能导致一批人失业,不过那是十年或者二十年后的事情了)。当然手工生产会留下来,做那些最精细,最高难,计算机无法自动完成的事情。另外就是确定需求分析设计这部分,这部分是机器无法自动化的。
当然,软件行业变成当今的现状是很自然的。程序员都是聪明而高傲的。他们喜欢证明自己更优秀。他们喜欢hack。他们瞧不起催进度的老板和搞需求的公关。并且程序究竟该怎么开发这点烂事是企业里的管理人员无法操心的。他们看不见那些无形的重型机械被程序员抛开,也看不见程序员其实是在手工修建长城。但是程序员应该自己反省。是的,一次两次骗过肥头胖脑的老板可能蛮有趣的,但是总是手动hack程序员就偏离了自己职业的宗旨-让机器帮助人。
我一直以来都是c\c++的忠实拥趸,藐视高级语言,喜欢重度hack,喜欢重头发明轮子。但是最近的反思,加上这次看到的文章,让我大大醒悟了。高级语言的真正高级之处,就是他强大的自动生成代码的能力啊!
作为一个高傲的程序员,低头使用别人的代码生成器总有“食嗟来之食”的感觉(当然这是不对的。。当真正要解决问题的时候我还是会用合适的工具的!lisp当然也在学,python和perl也在学,也知道用网页和.net来做一些事情了,也体会到.net和js的强大了)。那就自己去发掘,自己去创造。这话说得貌似又变成重新发明轮子了。当然工程实践中不会这么去做的。但是作为理论学习的方向,这方面应该是重点。我研究生专业学的是嵌入式方向,学的是最底层最hack的东西。学的是怎么把c当成汇编来用,怎么把编程看成是操作实际硬件。假如沉迷于此的话,我的软件观就彻底歪掉了。这些东西都算不上是软件。只不过是硬件接口罢了。软件的宗旨是正好相反的。软件的任务就是形而上学,就是纯粹的逻辑和理学的完美。只有结合了天堂的圣洁和地域的邪恶,才能创造出人类世界。
另外一点就是借着AIIDE的契机,学习了机器学习和人工智能的东西。这是软件工程未来的一个新的方向。就是用人工智能来开发代码。是的,不仅仅是用人工智能来解决问题,还要让人工智能来开发程序,让人工智能来开发人工智能。那其实是人工智能提出的时候最早的目标。可惜大多数学习这个领域的人都专注于用它做其他的事情了。遗传编程,一开始就是为了让程序自动创造程序而研究出来的,可惜现在都在做其他的解决方案。
可能说到人工智能产生人工智能,有些人就要想到黑客帝国了。一方面作为理论研究不应该考虑太多伦理问题,伦理是随着理论进步的。另一方面人工智能不等于生命,再高级也不等于生命。关于他的纯哲学讨论我放到下一篇博客去讲吧。估计这里的人多数不会有兴趣看的。
总之今天就像醍醐灌顶了一样一下子有了很多新想法。可惜我的问题在于想法太多动手太少。。。要努力实践!