论坛首页 综合技术论坛

理想的编程语言

浏览 14051 次
该帖已经被评为隐藏帖
作者 正文
   发表时间:2009-08-07   最后修改:2010-03-11
理想的编程语言  鞠文广

以下纯粹是个人观点, 不代表任何组织或社团.
关键词: 并发编程 函数编程 逻辑编程
摘要: 由于现有语言不能很好的为现实世界建模, 我提出一种编程方法论和编程语言Processlog. 它的编程思想是"面向进程 + 函数编程+ 逻辑编程等", 用它写的程序的软件体系结构很清晰, 程序简洁优美, 程序的正确性容易用数学推理证明, 适用于各种领域.

现在流行的编程语言如Java和C#, 大多是面向对象的, 程序的各部分是通过方法调用连在一起, 其编程范式是命令编程, 即使支持其他范式也包装得很难理解和使用.

面向对象实际上只适合实现抽象数据类型, 让它去完成除此之外的任务确实是勉为其难, 即便能完成也给人不伦不类的感觉, 既不像面向对象编程, 也不像它的前任(过程编程). 这些语言中的对象与物质世界的物质(或对象)很不一致, 它使用方法调用的方式与其他对象进行相互作用, 而这与物质之间的(通过通信或媒介)相互作用是截然不同的, 因此用面向对象无法很确切地模拟现实世界(面向对象思想的初衷), 更不用说准确地为现实世界建立模型.

这几年流行的web服务和SOA虽使程序间交互更方便, 但它从本质上说还是使用”面向对象+命令编程+方法调用”的思路, 在编程方法论上并没有实质的进步.

用现在流行的语言实现的完成复杂功能的程序逻辑不清晰, 原因在于”命令编程+方法调用”的设计机制. 这使程序很难模块化, 副作用无所不在, 因此很难正确实现复杂功能.

现实世界的发展变化是通过事物间的相互作用实现的, 而这种相互作用用计算机科学的语言来说就是进程间的并发(concurrency). 软件的本质是什么? 我觉得:软件总是完成某种功能的,归根到底是对现实世界的事物间相互作用进行建模. 因此软件的组成部分间自然就是并发的关系, 而不是过程调用的关系. 用相互通信的进程来对现实世界的事物间相互作用进行建模是比较合理的. 所以进程应该作为语言的基础成分, 是软件的基本组成部分, 而不是只为了提高效率才采用的.

为了使程序能准确地为现实世界建立模型, 从而正确性更高, 结构更合理, 模块化程度更高, 因此在几种编程思想或语言的基础上(见references), 我提出一种新的编程思想: 面向进程+函数编程+逻辑编程+约束编程(constraint programming)+其他合理的范式(命令编程除外)和以此为方法论的一门编程语言Processlog (全称process logic).

由于现有的并发机制要么不够理想, 存在不能接受的缺陷(如Java中的monitor机制); 要么很难应用于实际(如CSP的通道(channel)通信), Processlog中采用的并发机制是: 程序中同时运行的进程相互间通过端口来通信. 这种并发机制是我根据Abstract Behavior Types[1]的思想提出来的. 要完成两个进程间通信, 需把一个进程的输出端口和另一进程的输入端口相连, 然后在输出端口发送消息, 在输入端口接收消息就可以了. 这种机制很自然, 和现实世界的事物间相互作用是类似的.

Processlog的语法概要如下:

1 运算符
(1)  ?  输入;  c ? x 从输入端口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)
)
}

进程由事件组成, 如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 谓词"就是其中一部分代码.

我的想法是: 应先在纸面上规定它的语法与语义, 再通过使用它完成一些复杂的项目代码来发现它的不足, 再进而改进它, 再实践, 再改进, 直到它基本完善再在机器上实现.

现在需解决的问题是: 软件分析设计方法(不同于面向对象编程和面向过程编程)?

希望有识之士和我一起共同发展这种编程方法论和这门语言.

联系方式: 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
5. JCSP
注: 转载时请注明作者.
  • 大小: 11.9 KB
   发表时间:2009-08-07  
感觉作者说的没有任何新意……
其中部分问题的本质是有否合适的框架支持。
另一些部分的问题,不过是因为java不能简明的实现随意的语法糖而已。
1 请登录后投票
   发表时间:2009-08-07   最后修改:2009-08-07
一定要看看 FX 推荐的 Katahdin

这是最 nb 的语言,要什么,就有什么,不要什么,就没什么 …… 直接消灭框架。
0 请登录后投票
   发表时间:2009-08-07  
很有思想!楼主能否贴点你用这个语言重写的一些代码?
0 请登录后投票
   发表时间:2009-08-07   最后修改:2009-08-07
软件设计中的代码可重用性,与编程语言无关,而在于领域本身的内在禀性。确切地说,是在于领域问题的内在"熵"。
软件设计的根本任务,即不在于模拟世界,也不在于用各种模块搭建架构,而是在于如何"压缩"代码,以逼近本领域的内在"熵"极限。


2 请登录后投票
   发表时间:2009-08-10  
语言知识表达的方式而已,就好像你可以说“你好”,也可以说成是"how are you"。
实际上,都没有改变什么。所以,不应该追求什么完美的语言,而是,要加强对实际问题的分析理解能力。要增强内功,而不是花巧的招式。
0 请登录后投票
   发表时间:2009-08-10  
mock1234 写道

这是不是说你的“语言”还不是一个靠谱的一步一步成功的语言,而是一步登天(如果登不上去就干脆摔死)的语言?!


语言是需要逐步完善的, 不是一下子就提出一个完善的语言.现在的ProcessLog只是雏形,我需要不断用它来实践来逐步完善, 等觉得足够完善了,再在机器上实现它.
2 请登录后投票
   发表时间:2009-08-10  
mock1234 写道

我是技术高手,所以我可以用你鄙视的那些语言写出优美的并行和进程通讯程序,基于语义网络的逻辑搜索程序,而无需等到语言的进化就实际去开始真正称得上实践的研究。

我建议你把精力放在解决问题的机制的研究上,先不要纠缠于语言之争。语言确实可以清晰地表达算法和结构,以及通信方式,但是你如果能够用别人擅长的语言来说清楚一整套你自己认为很牛逼的面向应用的系统设计问题,你说的才是真正牛逼的事情。如果你先忽悠别人放弃别人的语言,那恐怕大多数人都会觉得闲的无聊的时候才会介入编程语言之争。

大概有超过7、8年的时间,我都想对我研究了十几年的全局逻辑解题系统开发个框架出来。什么prolog之类的纯粹是不值一提,根本不能反应任何人工智能。可是,我知道这根本不是忽悠编程语言的问题,不论是使用java还是c++甚至basic都照样可以来实现逻辑系统的解题过程,首先跟语言没有关系,如果框架的实际内涵不清晰那么妄想设计出个语言来证明你懂行,也就无法被人理喻。

“流行”编程语言为什么流行,不是因为它是表达晦涩难懂的框架的理想语言,而是因为它是通用地表达各种设计框架。你先用通用编程语言来进行一些稍微大型一点的测试项目,来证明你的理论能不能解决实际问题,有没有那么高的市场价值,然后再开发特别的编程语言来给你的框架做写锦上添花吸引一些非职业编程人员,这样比较好。


我不是鄙视什么语言, 前人创造的事物有的合理,有的不合理, 不能全盘接受. 你有没有思考过你现在用的语言有哪些重要方面不合理? 你真的觉得现在这种面向对象语言很合理吗?

我在文章中已经说了, 我正在用这门语言在实际的复杂项目中实践. 我参与的项目都是大项目.
0 请登录后投票
   发表时间:2009-08-10  
我觉得在讨论问题时,大家不要太过于情绪化了,否则只知道维护自己的已有观点,而不是要探寻真理.

我们实际上是在做研究, 研究合理的编程语言.
0 请登录后投票
   发表时间:2009-08-10  
秦汉唐宋明 写道
很有思想!楼主能否贴点你用这个语言重写的一些代码?


我是不能公开贴的, 我担心引起知识产权问题, 毕竟是公司的项目. 不过,有兴趣的话可以用邮件联系.

juwenguang2000@yahoo.com.cn
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics