动态模型编程是一种以模型为基本元素的编程方法,在动态模型编程中编程中的各种东西都是用模型表示的,如函数、对象和类等都是使用模型表示的;另外模型是像XML这样的树形结构的数据,模型可以简单的理解为XML。
动态模型编程的理论是在框架编程中逐渐发现的。早在2006年我想编写一个基于框架的快速开发工具,如同Java编程中流行的Spring和Hibernate等框架一样,用XML来编写框架配置,然后用Java来编写框架的解释引擎,最后在Java中调用框架。在编写框架的过程中,我发现由于每个框架的Java解释引擎是不一样的,所以调用接口也是不一样的,而由于各个框架的调用接口不统一,所以如果同时使用多个框架时用起来很不方便。在这种情况下想到配置是像XML这样的数据,而不管什么框架其配置在我的系统中所映射的类是一样的,因此如果在配置所映射的对象中调用解释引擎,那么对任何框架的调用接口就统一了,这样就解决不同框架的调用不统一的问题。随着这个编程工具的不断完善,我也发现了在配置对象中调用解释引擎逻辑上等价于把解释引擎嵌入到了配置中,这时配置不但可以表示信息,配置还是可以执行的程序,就这样它也成为了一种新的编程方法,动态模型编程的理论就是这样逐渐发展起来的。
现在动态模型编程的理论已经比较成熟了,实现了动态模型编程的系统具有动态性,可以在运行时为系统自己编程。和脚本编程语言的代码的动态执行不同,动态模型编程带来的动态性是基于数据结构的,使用它可以在运行时彻底改变系统的结构,系统可以实现从一种形态到另一种形态的转变。我们可以想象一下客观世界中的一些系统,比如一个生态系统,或一颗种子从发芽到长成大树,这些系统随时都在变化,尤其是当它们的结构发生变化时还能从一个事物变成另一个事物。动态模型编程的为系统自己编程的动态性有很多好处,比如可以作为一个不断增长的编程和应用平台,可以整合和积累各种功能,也可以在原有的基础上开发新的功能,还有如果系统集成了人工智能,那么还有可能实现系统的自动学习和成长等。
动态模型编程的理论是符合计算机编程理论的基本理论的。在编程中指令和数据是两个基本概念,如果以代码为主的编程是基于指令的,那么动态模型编程就是以数据(信息)为基础的,它是现有编程方法一个重要的补充,实际上也是对现有编程方法一个完善。作为一个新的编程方法,我们认为它非常值得去研究。
动态模型编程是一个解释性的编程方法,像脚本语言一样可以在运行时修改和执行。
动态模型编程认为指令也是数据,所以编程的基础应该是数据,一个数据可以被看成指令,也可以被看成信息。和计算机中数据是二进制的不同,动态模型编程的数据是结构化的,我们把它称为模型。在动态模型编程中一个模型是由属性和子节点构成的,它和XML的结构一致,可以简单的理解为XML。
动态模型编程中的模型可变体现在两点,一是模型本身是数据,它可以随时添加和修改,二是一个模型的类型也是可变的,即它表示的内容是可变的,这样一个模型是什么也是可变的。
使用实现了动态模型编程的系统编程,新的程序总是自动属于系统本身。这是因为在实现了动态模型编程的系统里程序是由模型构成的,而模型是系统内部的数据,所以建立新的模型就是在增加系统的功能,而修改已有的模型就是在修改系统的功能。
作为一种编程方法,动态模型编程的方法并不只是给人来使用的,它也可以给实现了动态模型编程的系统自身使用,并且它还是一个人机交互的共同的语言框架。
从拟人化的角度看待动态模型编程比较容易理解它的本质,我们可以把一个实现了动态模型编程的系统当作一个人,比如可以想象为一个小孩,系统中的模型可比喻为它的知识,它可以通过已有的知识来产生新的知识,随着知识的不断丰富它的功能也在增长,并且如果它有一个大脑(AI)的话,也许它还可以主动学习等。
之所可以拟人化是因为实现了动态模型编程的系统是一个可以在运行时编程的系统,并且编程通常在和系统交互的情况下完成的,这样的编程方法就不是我们先设计和编码,然后编译和执行的编程方式了,这时拟人化更容易理解一些。
虽然我们把实现了动态模型编程的系统拟人化的,但需要澄清的是它并不是一个人工智能的系统。如果以人来类比的话,我们认为人工智能是大脑,而动态模型编程是为了身体,这样理解更合适一些。
模型的构建、解释和执行是动态模型编程的基本内容,它也是编程中的概念的构建、解释和应用的问题。构建是指如果通过交互的方式为系统输入理论上可以输入的任意模型,解释是指系统可以通过自身说出任何一个模型是什么,执行是指用模型编写的程序是可以执行的,这三者是动态模型编程的基础。
在这里需要注意的是模型的构建、解释和执行是在系统运行时发生的,下面也是想要说明这一点的。
在这里我们要证明系统最初只存在有限个模型的情况下,就可以通过这些模型直接或者间接的构造出其它任何模型来。这段话也可以表示为假设所有的模型的集合是A,那么是否存在有限个元素的A的子集B,使得通过B可以通过一个方法构造出任意一个属于A的模型。
现在我们要证明其实系统只要存在一个模型就可以直接或者间接的构造出其它任意模型了,这个模型我们称为元模型。
在这里我们提出一个构建模型的方法,模型可以简单的理解为ML,所以我们使用XML的结构来编辑XML的方法。
现在我们要证明任意模型的结构的结构是唯一的,这样系统最初只要存在这个结构的结构,那么就可以通过它直接或者间接的构造出其它模型来了。
一个模型是有属性和子节点构成的,所以我们先定义属性和子节点的结构。在这里我们使用XML来表示。
属性的结构,在XML中属性一般用<attributeName>="<value>"的格式表示属性,比如name="Tom" age="10"等,在动态模型编程中我们定义它的结构为:<attribute name="<attributeNmae>"/>,即只描述属性的名称。
节点的结构,在XML中节点的格式一般是<<nodeName> ...../>的格式,比如<Person ...../>,在动态模型编程中我们定义它的结构为:<thing name="<ndoeName>"/>,即只描述节点的名称。
由于属性是嵌套在节点中的,而子节点也是嵌套到父节点中的,所以可以使用嵌套的方式定义完整的模型的结构。比如:
<Person name="Tom" age="40“> <Child name="Smith" age="10"/> </Person>
它的结构是:
<thing name="Person"> <attribute name="name"/> <attribute name="age"/> <thing name="Child"> <attribute name="name"/> <attribute name="age"/> </thing> </thing>
如果计算任意一个模型的结构的结构,等价于计算任意一个XML的结构的结构,那么就会发现结果是:
<thing name=”thing”> <attribute name=”name”/> <thing name=”attribute”> <attribute name=”name”/> </thing> <ting name=”thing”> <attribute name="name"/> <thing name="attribute"> <attribute name="name"/> </thing> <thing name="thing"> ... </thing> </thing> </thing>
这是一个每层节点都一样的且有无限层节点的一个XML,我们把它称为元模型。
模型的解释是指系统可以回答‘一个模型是什么’这样的问题。
大家可以看下上面这个图,你认为它是鸭子还是兔子呢?这是经典的鸭兔图,它在心理学和哲学上都有广泛的研究,在这里我们就不深入讨论心理学或哲学了,所以摘了一段鸭兔图在百度百科中的文字。
这段文字是:“从心理学上讲,“鸭兔图”是格式塔心理学上的典型例证。它在表明:整体决定部分的性质,部分只有依存于整体才有意义。而在哲学上,哲学家却以此来思考感觉与认知的关系。比如,维特根斯坦在《哲学研究》中就借助这个图形来说明:如果同一个对象可以被看成是两个不同的东西,那么,这就表明知觉并不是纯粹的感觉。我们必须在叙述知觉中注意若干方面。对知觉的报道承受着概念,是对经验与思想的结合。”。
在这段文字中提到同一个对象可以被看成两个不同的东西,同样道理一个模型是什么也是可以看作是不同的东西的。
一个模型是什么?系统理论上只能用系统内的模型来解释。这个也可以参看一个语言中词的解释,一个词是什么,在这个语言它只能用自己或其它词来解释,所以还是在这个语言所有词的空间范围内。
综上所述一个模型是什么可以用系统内的模型来解释,一个模型是什么是可以不依赖于系统外的事物来解释的。
如何执行一个模型是通过递归的方法实现的,这一点可以参看后面的章节,而递归也是计算机编程的一个基本原理。
我们觉得模型的可执行性应该可以用可计算性原理来解释,但是由于本文的作者不是专业人事,所以说不出太多内容来,希望专业人士可以补充下。
作为一个编程人员我们可以使用动态模型编程,我们可以创建模型,可以用一个模型解释一个模型,也可以用递归的方法解释执行一个模型。
一个实现了动态模型编程的系统也可以使用它来编程,因为可以通过程序创建和修改模型,程序也可以用一个模型来解释一个模型,也可以用递归的方式解释执行一个模型。
在运行时构建任意模型的可行性证明里,我们提出了一个构建模型的方法,实际上这个方法也是系统生成界面和外界交互的方法,所以动态模型编程也是一个基本的人机交互的语言框架。
在讲述动态模型编程的基本概念前需要澄清几个概念,这非常重要,因为下面的概念非常容易不小心就陷入到哲学中,从而可能会对我们的本意误解。
在编程中,我们用程序表示各种东西,而东西在英文翻译为thing,也对应中文的事物,所以事物是编程时所想要表达的内容。
在日常用语中,世界是各种事物的集合,因此当我们使用事物这个概念时,那么机会使用世界这个词,因为需要有管理事物的容器。所在动态模型编程中世界实际上是模型的集合或管理器。
简单的说,是为了避免让人误以为本文是玄学,因为世界和事物这两个词是非常敏感的。其实本文也不是要说明事物和世界到底是什么,而是对这两个词在日常生活中的一些用法的总结,我们是根据它们的日常用法而总结出了一种编程方法。
动态模型编程的基本元素是模型,模型是像XML这样的数据,因此一个模型是由属性和子模型(子节点)构成的。
事物是模型想要表达的内容。有时这两个概念我们也不加区分,即模型、事物或事物模型通常指的是同一个东西。
世界是事物的容器,在动态模型编程中世界就是管理事物的容器,可以通过它获取各种事物。
动作是可以执行的程序,在动态模型编程中动作是通过事物转化而来的,并且动态模型编程认为任何事物都可以转化成动作,因此动作是事物的另一种形态。
在冯·诺依曼机中指令也是用数据存储的,即我们可以把某些数据看作是可以执行的指令,同样的道理事物模型是数据,我们也可以把它看作是可以执行的程序,即动作。
由于在动态模型编程中任何事物都可以转化为可执行的动作,而事物模型又具有XML这样的结构,它可以包含属性和子事物,这样我们就可以定义一个事物的某些子事物是它的行为。
描述者用于解释一个事物是什么的,比如存在两个事物A和B,那么就可以用A来解释B,或用B来解释A。如果用A来解释B,那么A是B的描述者,那么我们可以说B是一个A。动态模型认为一个事物可以用任意事物和任意个事物来描述。
描述者其实相当于类的作用,由于现实中事物是可变化的,对一个事物的认知是可能会发生变化的,因为我们也认为一个事物的描述者是可变的,并且动态模型编程认为一个事物可以用任何事物来作为它的描述者。
动态模型编程还规定一个事物继承其描述者的行为,即如果A是B的描述者,此时A有一个名为run的行为,那么B也有run这个行为,其中B的run行为是从A继承而来的。
继承是快捷表示复杂事物模型的一种有效的方法,一般情况下在动态模型编程中继承只实现行为的继承,但不实现属性和子事物的继承。比如存在A和B两个事物,如果B继承A那么B拥有A的行为,但A有的属性和子事物B并不一定有。
在动态模型编程里,如果事物B继承事物A,此时A有一个名为run的行为,那么B也有run这个行为,其中B的run行为是从A继承而来的。
因为行为可以在事物本身上定义,可以继承于描述者或被继承的事物,因此如果一个同名的动作三者都有定义,那么该选取哪一个呢?动态模型认为查找的顺序是自身->描述者->被继承的事物,当动作找到后就使用当前这个动作。
动作是事物转化而来的,而转化的过程相当于把数据当作程序指令的方法,其方法如下:
从动作的执行方法上可以看到其实事物模型本身并不是可执行的程序,一个动作的执行最终是要用元系统来执行,即用实现了动态模型编程的系统上执行,所以动态模型编程是建立在其它系统之上的一种编程方法。比如我们已用Java实现了动态模型编程的引擎,在这里任何模型最终都是迭代到Java上用Java解释执行的。因此动态模型编程是一个更高层次的编程方法,它可以用各种已有的编程语言来实现。
在计算机编程里程序是算法的实现,而算法是依赖数据结构的,所以当数据结构发生了变化其它也要跟着发生变化,这样就不能实现动态性。
在以往的传统编程过程里往往是先有数据结构,然后再制定算法和实现代码,这样程序是因果链的结果,而如果程序可以作为因果链的起点,那么它的改变就可以不受数据结构的限制了。
如何让把程序放在因果链的起点而又不违背计算机编程的基本原理呢?方法就是使用数据的逻辑结构。在计算机编程的教材《数据结构》中提到数据的结构分为物理结构和逻辑结构,而通常我们所要表达的信息反映在数据的逻辑结构上,因此我们可以在保持数据的物理结构不变的情况下我们可以实现一个程序,然后用这个程序动态解释数据的逻辑结构,这样程序在因果链上就可以放在数据的结构之前了。
当我们把程序放在了数据结构之前,那么新的数据结构所表示的信息或程序等是否可以被正确解释执行呢?实际上这也是本文所解决的问题。
我们认为一个事物的类型决定了它的逻辑结构。鸭兔图可以说明这一点,当我们把鸭兔图看成鸭子时图中左上角两个长长的分叉就是鸭子的嘴巴,而如果把鸭兔图看成兔子那么左上角的就是兔子的耳朵了。因此我们把一个事物看成了什么,也就同时也给它赋予了对应类型的结构。
在动态模型编程里一个事物模型的描述者是可以随时改变的,而描述者可以用于说明一个事物是什么,描述者可以作为事物的类,因此当一个事物的描述者发生变化时,它的类型也就发生了变化,而当它的类型发生变化时它的逻辑结构也改变了。
在一个实现了动态模型编程的系统里,系统是由各种模型组成的,而由于模型的结构是可变的,所以系统的结构也是可变的。
动态模型编程的理论是抽象的,它的基本概念是事物,一个事物可能是任何东西,而当我们处理各种具体的对象时,通常不会把它称为事物。比如我们吃一个苹果时,不会说正在吃一个事物。因此动态模型编程是一个间接的编程方法,我们在编程时时时刻刻都在用,但可能不会觉察到。
动态模型编程的理论可以用其它编程语言来实现,比如我们已经用Java实现了一个版本。另外动态模型编程的理论足够简单,它可能还可以在操作系统层或硬件层实现。
可以在实现了动态模型编程的系统里编程,由于我们是在间接的使用动态模型编程,所以我们面对的是实现了动态模型编程的系统的具体功能,因此具体如何编程需要看这个系统的说明。
虽然在不同的系统实现里具体的编程方法可能会不同,但它们的基础方法是一样的,就是编写模型数据,可以简单的理解为编写和运行XML。
目前我们已经有了一个Java版本的实现。
X-Meta引擎是动态模型编程的Java实现,可以参看它的主页X-Meta。
XWorker是各种模型库以及动态模型编程的开发工具等,可以参看它的主页XWorker。
实现了动态模型编程的系统具有各种可能性。XWorker是一个实现了动态模型编程的系统,下面我们演示它在编程上的动态性。
XWorker集成了Eclipse的SWT库,可以用它编写窗口应用,下面的视频展示了如何使用SWT模型边运行、边修改和边生效。
交互式编程也是一种动态的编程方法,它是用动态模型编程实现的。交互式编程实际上是一种函数式编程方法,它认为要运行一个函数主要是要确定函数的参数所使用的函数的过程,并且函数运行时有些函数可以是UI函数,这样参数的选择和UI函数的执行就可以形成一个交互,我们可以在交互中最终完成函数的设计和执行。
下面是一个交互式编程的例子,它的目的是在一个Linux服务器上运行一段脚本,所以初始函数是ExecWithSession(执行脚本),它的参数是session(服务器)、command(脚本)和是否后台运行,在视频中可以看到不断的在选择和设置函数参数的函数,当函数的参数选择后就运行,其中一些函数是具有UI界面的,比如视频中的从数据库中选择服务器、选择预先定义好的脚本等UI函数。
XWorker中目前只是初步集成了LIBGDX,所以只有一个简单的演示,这个示例是通过选择不同的模型切换到不同的游戏,它可以说明在编程时修改模型而无需重启系统,所以也是动态的。
Copyright © 2007-2019 XWorker.org 版权所有 沪ICP备08000575号