[theory] 理想的编程语言
forrestju
2009-08-07
理想的编程语言 鞠文广
以下纯粹是个人观点, 不代表任何组织或社团. 关键词: 进程代数 函数编程 逻辑编程 摘要: 由于现有语言不能很好的为现实世界建模, 我提出一种编程方法论和编程语言ProcessLog. 它的编程思想是"面向进程 + 函数编程+ 逻辑编程等", 用它写的程序的软件体系结构很清晰, 程序简洁优美, 程序的正确性容易用数学推理证明, 适用于各种领域. 现在流行的编程语言如Java和C#, 大多是面向对象的, 程序的各部分是通过方法调用连在一起, 其编程范式是命令编程, 即使支持其他范式也包装得很难理解和使用. 面向对象实际上只适合实现抽象数据类型, 让它去完成除此之外的任务确实是勉为其难, 即便能完成也给人不伦不类的感觉, 既不像面向对象编程, 也不像它的前任(过程编程). 这些语言中的对象与物质世界的物质(或对象)很不一致, 它使用方法调用的方式与其他对象进行相互作用, 而这与物质之间的(通过通信或媒介)相互作用是截然不同的, 因此用面向对象无法很确切地模拟现实世界(面向对象思想的初衷), 更不用说准确地为现实世界建立模型. 这几年流行的web服务和SOA虽使程序间交互更方便, 但它从本质上说还是使用”面向对象+命令编程+方法调用”的思路, 在编程方法论上并没有实质的进步. 用现在流行的语言实现的完成复杂功能的程序逻辑不清晰, 原因在于”命令编程+方法调用”的设计机制. 这使程序很难模块化, 副作用无所不在, 因此很难正确实现复杂功能. 现实世界的发展变化是通过事物间的相互作用实现的, 而这种相互作用用计算机科学的语言来说就是进程间的并发(concurrency). 软件的本质是什么? 我觉得:软件总是完成某种功能的,归根到底是对现实世界的事物间相互作用进行建模. 因此软件的组成部分间自然就是并发的关系, 而不是过程调用的关系. 用相互通信的进程来对现实世界的事物间相互作用进行建模是比较合理的. 所以进程应该作为语言的基础成分, 是软件的基本组成部分, 而不是只为了提高效率才采用的. 为了使程序能准确地为现实世界建立模型, 从而正确性更高, 结构更合理, 模块化程度更高, 因此在几种编程思想或语言的基础上(见references), 我提出一种新的编程思想: 面向进程+函数编程+逻辑编程+约束编程(constraint programming)+其他合理的范式(命令编程除外)和以此为方法论的一门编程语言ProcessLog (全称process logic). ProcessLog只支持一种并发:通信进程. 因其他并发机制要么不够理想, 存在不能接受的缺陷(如Java中的monitor机制, Erlang中的Actor); 要么很难应用于实际(如CSP的通道(channel)通信). 这种并发机制是我根据Abstract Behavior Types[1]的思想提出来的. 要完成两个进程间通信, 需把一个进程的输出端口和另一进程的输入端口相连, 然后在输出端口发送消息, 在输入端口接收消息就可以了. 这种机制很自然, 和现实世界的事物间相互作用是类似的. ProcessLog的语法概要如下: 1 运算符 (1) ? 输入; c ? x 从输入端口c或通道c上接收输入值放到变量x中 (2) ! 输出; c ! v 把v的值从输出端口或通道c上输出 (3) -> 顺序进行的事件的先后关系 (4) | b : s 分支 (5) a >> p.b 输出端口a连接到进程p的输入端口b (6) a << p.b 输入端口a连接到进程p的输出端口b (7) and, or, not 逻辑运算符 (8) 算术运算符和关系运算符 与Java中相同 2 程序的组成成分 (1) Unit 程序单元 (2) Process 进程 (3) Function 函数 (4) Predicate 谓词 (5) DataInPort 数据输入端口类型 (6) OutPort 输出端口类型 (7) InPort 输入端口类型 (8) ResultPort 结果输出端口类型 3 原子数据结构 (1) List (函数编程中的List类型, 对List的操作函数与函数编程中相同); (2) Tuple 元组, 同Clean. (3) Set 集合 没有数组 4 进程的定义 Process ChangeRel ( DataInPort dataIn(List, Em, Em); ResultPort resultOut(Em); InPort fromGetRel; OutPort toGetRel, toDetach, toAttach, toChangeRel ) % 生成(或使用已有的)与当前进程相连接的进程, 并配置端口间的连接 ( GetRel getRel; Detach detach; Attach attach; toGetRel >> getRel.dataIn, fromGetRel << getRel.resultOut; toDetach >> detach.dataIn; toAttach >> attach.dataIn ) { dataIn?(list, rlEm, em) -> ( | list=[cem:cems]: ( ChangeRel changeRel; toChangeRel >> changeRel.dataIn % 递归进程 ) toGetRel!(rlEm.id) -> fromGetRel?rel -> toDetach!(cem, rlEm.id) -> toAttach!(cem, em.id, rel.level, rel.weight, rel.relation) -> toChangeRel!(cems, rlEm, em) ) -> self % 进程是一直运行的, 直到整个系统终止 } 进程由事件组成, 如fromGetRel?rel是输入事件, toGetRel!(rlEm.id)是输出事件. 该段程序的动态视图见论坛中相应主题的附件. 用ProcessLog写的程序都可以用这种动态视图来表示, 其中的方形表示进程, 箭头表示数据流向. 进程间是并行运行的, 相互通信. 5 函数 [Function] compute(double x)= | x<=0: x*x+3 | x>0: compute(x-5)* compute(x-3) 函数只能以事件的方式在进程中使用或在其他函数中使用, 不能独立使用. 6 谓词 /* 建图 */ Predicate createGraph(t, graph):- addNode(t, null, ({},{}), graph1), getDS(t, graph1.ns, tlist), addList(tlist, t, graph1, graph). /* 加节点 */ Predicate addNode(t, null, (ns, es), (ns1, es):- merge(ns, {t}, ns1). Predicate addNode(t, upper, (ns, es), (ns1, es1)):- merge(ns, {t}, ns1), merge(es, {(upper, t)}, es1). 7 把谓词转换为函数 create(t)= graph where createGraph(t, graph) 谓词不能独立使用也不能在进程中直接使用, 先转换为函数后再在进程中使用. 8 程序单元: 包含进程和数据类型 Unit PMDAO; interface Tuple M; Process GetReleasedVersion(DataInPort dtIn, OutPort pt1 , InPort pt2); … implementation M=(String id, String name, String version, …); Process GetReleasedVersion(DataInPort dtIn, OutPort pt1 , InPort pt2) (…) { … } 指导原则: 程序是由通过端口相连接的进程组成的. 数据处理和算法用函数编程实现, 如果函数编程不适用于要处理的问题, 就使用逻辑编程或约束编程. ProcessLog语言限制了编程的随意性, 要求只能用进程+函数编程+逻辑编程的方式编程, 不允许用Java或c#的命令方式编程. ProcessLog 现在还没有在机器上实现. 我用该语言重写了实际项目中的一些复杂代码(原是Java代码), 证实用它写的程序确实简单清晰, 有类似数学的简洁美. "7 谓词"就是其中一部分代码. 我的想法是: 应先在纸面上规定它的语法与语义, 再通过使用它完成一些复杂的项目代码来发现它的不足, 再进而改进它, 再实践, 再改进, 直到它基本完善再在机器上实现. 另外, 大家不要把语言分为中国人提出的还是外国人提出的, 科学无国界. 现在需解决的问题是: 在这种并发机制下, 1怎么实现事务控制? 2 怎么实现异常机制? 希望有识之士和我一起共同发展这种编程方法论和这门语言. 联系方式: juwenguang2000@yahoo.com.cn 博客: http://www.cnblogs.com/forrestju/ References 1. Farhad Arbab, Abstract Behavior Types: a foundation model for components and their composition 2. Clean http://clean.cs.ru.nl/ 3. Prolog 4. Delphi 注: 转载时请注明作者. |
|
pascal4123
2009-08-19
尽管不是科班出身,语言层面的东西无法判别.但还是佩服作者的想法,有一部分想法还是很一致的.
感觉现在OO搞过了,变得有点形而上学的味道, 编程语言领域应该往数学方向发展,而不是往建筑学. |
|
forrestju
2009-08-21
"编程语言领域应该往数学方向发展,而不是往建筑学." 说得很对啊.
|
|
forrestju
2009-09-02
很遗憾在fp论坛上我的这篇帖子被一些人投了隐藏票, 我很纳闷我这篇文章违反了javaeye的什么规定导致被隐藏? 请明白人指点.
|
|
night_stalker
2009-09-02
没什么规定,民主投票的结果而已,换言之就是被机器潜规则了。
不要太偏执走上民科的道路啊 …… |
|
forrestju
2009-09-03
night_stalker 写道 没什么规定,民主投票的结果而已,换言之就是被机器潜规则了。
不要太偏执走上民科的道路啊 …… 谢谢答复. 原来是元老们对我的文章不满啊. 业余做科学研究出成果的人恐怕不少,而且有些人对科学的贡献还很大, 大家知不知道爱因斯坦提出狭义相对论时是不是职业科学家(或研究者)? 还有费马大定理听说过吗? 提出者是专业数学家吗? 听说过陆家曦吗? 不要看不起自己, 认为自己提不出有创新意义的理论, 完全拜倒在那些大师脚下; 更不要对自己不了解的人和理论妄加评论. |
|
forrestju
2009-09-03
night_stalker 写道 还有老爱可是科班出身,就不要拿出来和民科相比了。 那个陆家曦不认识,望赐教。 "老爱可是科班出身",大学本科就是科班出身吗? 那在这个论坛上的大部分人都是科班出身了. 陆家羲,http://baike.baidu.com/view/310329.html 我不想与你争论, 没多大必要. |
|
huanlong78
2009-09-14
很多人可能看到这文章第一个念头就是,现在能用它测试下么?
哪怕是个Hello world .. 最现实的问题... |
|
IamSungod
2010-01-01
楼主说的这种多范式编程语言20年前就已经产生了,例如http://www.mozart-oz.org/。
麻省理工学院有门课程,叫CTMCP,是它的作者写的,与著名的SICP齐名。 在计算机基础编程领域,例如编译理论、程序设计方法学、编程语言和虚拟机等,中国甚至落后某些欧洲小国几十年... |