没有合适的资源?快使用搜索试试~ 我知道了~
理论计算机科学电子笔记253(2010)37-50www.elsevier.com/locate/entcs接口概念为什么声明风格Anya HeleneBagge Magne Haveraaen2挪威卑尔根大学信息学系摘要概念(或签名)通过列出这些类型应该支持的操作来描述一组抽象类型的接口。当实现一个泛型操作(比如排序)时,我们可以通过要求元素类型对Comparable概念建模来指定诸如“元素必须是可比较的”这样的要求。我们也可以使用公理来描述所有模型都应该通用的行为一个概念。然而,概念所指定的操作并不总是最适合实现的操作。例如,数字和矩阵可能都是可加的,但是将两个数字相加可以通过使用返回值来方便地完成,而将稀疏矩阵和稠密矩阵相加可能最好通过修改稠密矩阵来实现。不过,在这两种情况下,我们可能都想假装我们正在使用一个带有返回值的简单函数,因为这与我们从数学中知道的符号最接近。本文提出了两个简单的概念,以打破实现和使用之间的符号联系,一个操作:函数化,从过程中派生一组规范的纯函数;和多功能化,将使用函数化声明的调用转换为对实现过程的调用。关键词:概念,函数,过程,多变量,公理,命令式与函数式,基于概念的编程1引言概念是泛型编程的一个有用特性,允许程序员指定抽象数据类型的接口和行为。概念特性被引入到C++0x(即将到来的C++标准修订版)中,以便在模板代码中给出更清晰的错误消息,并提供一种更容易将泛型代码粘合在一起的方法类似的功能在其他编程语言中也有。在本文中,我们将在Magnolia编程语言(一种松散基于C++的实验性语言)的上下文中研究概念。概念是Magnolia的组成部分,鼓励程序员指定代码1 http://www.ii.uib.no/2http://www.ii.uib.no/1571-0661 © 2010 Elsevier B.V. 在CC BY-NC-ND许可下开放访问。doi:10.1016/j.entcs.2010.08.03038A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37依赖关系,并使用概念来指定实现模块的接口。概念用于隐藏实现细节,以便一个模块可以被另一个建模相同概念的模块替换。甚至如果我们要在一个公共接口后面隐藏不同的实现我们必须考虑到不同的情况需要不同的编程风格。例如,对原始数据类型的操作可以使用返回值方便地处理,而对大数据结构的相应操作可以通过更新它来更好地处理。此外,库实现的需求可能与使用它的代码的需求不同。例如,数学问题可以很容易地用函数和操作符调用来表示,而通信协议可以更好地用过程调用序列来表示。但是,作为库用户3C++是一种语言的例子,在这种语言中,符号变体的扩散特别糟糕(或好,取决于你的观点)-成员和非成员函数,运算符重载,以及大量的参数传递模式(值,引用,常量引用,指针)。像ML和Haskell这样的函数式语言问题较少,因为这些语言已经限制在函数式声明形式。泛型和生成式技术受到同一抽象概念实现的声明形式(C++术语中的原型)激增的阻碍例如,当元素操作的声明形式不同一个是数字数组,一个是矩阵数组对于C++0x来说,对于本质上相同的操作有许多不同的声明形式的问题通过允许实现者在概念图中添加显式粘合代码(一些给定类型模型给定概念的声明)来解决在受约束的模板代码中,用户将使用概念中的声明,而不需要知道实现是如何声明的。但是请注意,这种便利仅在受约束的模板代码中可用在本文中,我们将展示如何在Magnolia中解决这个问题,方法是将实现签名与使用签名分离,允许独立于实现样式使用不同的调用样式。通过让编译器在不同的调用风格之间进行转换,我们为程序处理器增加了灵活性我们称这些翻译为功能化和多重化。我们将首先给出关于我们的方法的直觉,然后再定义3用户指的是使用库的程序员,实现者指的是实现了库的程序员。运行最终软件产品的最终用户不在我们讨论的范围之内。A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)3739更正式地在后面的文章中。我们用Magnolia中的例子来说明我们的观点,Magnolia将功能化和多功能化作为基本的内置功能。Magnolia支持命令式过程(允许更新其参数)和纯函数(不允许)。示例Magnolia过程dec看起来像这样:int n(int n);过程fib接受一个参数,一个updatableinteger,它既用于输入,也用于返回结果。函数化接受一个过程声明,并将其转换为函数声明。fib的功能化是:int n(int n);– 一个带有整数参数的函数,返回一个整数。这是一个概念中通常使用的声明。fib过程的不同声明fib(int n,intr);– 其观测参数n并输出参数r,产生相同的函数化。函数化过程声明给了我们一个可以从Magnolia表达式调用的函数,但没有该函数的实现。这就是多功能进入画面的地方。Mutification使用函数化过程获取表达式,并将其转换为直接调用该过程的语句。在这里,我们展示了对上面每个声明的调用,函数形式(中间)可以转换为所示的任何一个过程调用x=0;return fib();←y =fib(x); →调用fib(x,y);为什么我们要用一种声明形式实现一个算法,而用另一种声明形式使用它呢?如上所述,实现方面通常取决于什么适合问题或算法有几个原因可以解释为什么代数风格在用户端很有用:灵活性:具有不同特性的多个实现可以隐藏在同一个接口后面。这在泛型代码和构建可互换组件的基础时特别有用。易于推理:不仅对人类,而且对编译器和工具。例如,基于公理的重写规则[2,8,12]允许程序员通过在程序中嵌入简化规则来帮助编译器这样的规则很难用语句和更新过程来表达。符号清晰度:某些问题以代数或函数的形式表达得最清楚,这与数学的符号风格很接近,这是几个世纪以来为表达清晰而许多正式的规范语言,例如,落叶松共享语言[6]和CASL [9]使用函数式风格,因为它很清晰。用代数风格写的程序很容易联系起来40A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37×一个正式的规格。使用单个声明形式可以声明诸如“+”和对于代数交换环是交换的”,并且将其应用于满足交换环的性质的所有类型(即,对概念CommutativeRing建模的所有类型)-原则上,我们可以选择任何声明形式作为通用的规范样式--我们选择代数样式是出于上述原因,不太受实现考虑因素的影响(例如选择哪些参数应该输出结果)。正如我们将看到的,这种选择并不意味着我们必须强制使用代数编程风格。我们现在将对此事进行更深入的讨论。本文的其余部分组织如下:首先,我们介绍了Magnolia语言的必要特征(第2节)。然后,我们定义多功能化和功能化,并解释它们如何应用于Magnolia程序(第3节)。 我们继续讨论一些局限性和务实的考虑,以及这种方法的好处和可能性(第二节)。4)。2Magnolia语言本节简要介绍Magnolia编程语言。Magnolia基于C++,删除了一些功能,添加了一些功能,并对语法进行了一些更改。我们将其设计为比C++更容易处理和编写工具(这实际上是我们使用新语言而不是使用C++的主要原因),同时足够相似,我们可以轻松编译为C++代码并使用高性能C++编译器。以下是与本文相关的特征:过程对它们的输入和输出有显式的控制:允许它们根据过程声明中给出的参数模式修改它们的参数可用的模式是只输入参数的observe模式、既可以读又可以写的参数的upd模式和只输出参数的output模式。这些模式描述了过程- 结果可能取决于哪些值,以及哪些变量可能被过程改变。参数传递模式(例如,通过值,通过引用,通过复制输入/输出)是未定义的,因此编译器可以自由地为给定的数据类型使用最有效的传递模式。过程没有返回值,结果通过写入一个或多个参数来给出。过程调用使用call关键字,因此它们很容易与函数调用区分开来。函数有一个单一的返回值,它只依赖于参数。不允许修改参数。运算符可以被重载,并且只是函数调用的花哨语法函数和过程统称为操作。数据类型类似于C++结构和类,但没有成员A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)3741操作-目前还没有动态分派或继承,我们概念通过列出一些所需的操作、操作的ax-iom和可能的其他需求来描述类型的接口。一组类型被认为是对一个概念进行建模,如果操作是为这些类型定义的,并且需求是满足的。例如,以下定义了一个简单的concept Indexable ( A ,I , E ) {E getElt ( A ,I);AsetElt(A,I,E);public int findDuplicate(A){setElt(a,i,e) == e;}Indexable有三种类型,类似数组的类型A,索引类型I和元素类型E。这个概念定义了两个函数,getElt和setElt,以及一个与函数相关的简单公理。泛型:泛型编程是通过类似于C++的模板工具完成的。类型参数可以使用概念来约束,使得只有对给定概念建模的类型才可被接受为参数。无别名:别名使代码推理变得困难,因为它破坏了一个基本假设,即分配或更新一个变量不会改变另一个变量的值函数式语言通过简单地禁止修改变量的整个想法来避免这个问题我们觉得不允许修改的代价太高了,特别是在使用数值软件和大型数据结构时,所以Magnolia有一套规则,旨在防止别名,同时仍然拥有命令式代码的大部分自由• 没有指针或引用。任何需要这些特性的数据结构都必须隐藏在一个程序员必须负责确保实现是安全的。• 没有办法引用数据结构的一部分。例如,因此,改变对象字段或数组元素是对对象或数组本身的操作(不像在C++中,字段和元素通常是l值,可以直接赋值这就是为什么上面Indexable概念中的setElt操作被声明为返回数组的函数,而不是像C++中典型的那样返回对元素的引用。• 如果变量作为upd或out参数传递给过程,则该变量不能用于同一调用中的任何其他参数位置4我们避免在示例中使用运算符,以保持语法简单42A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)373相关功能和程序我们现在将建立Magnolia函数和过程之间的关系,这样每个过程声明都有一组由函数化给出的相应函数声明(定义3.1),每个表达式都有一个由多函数化给出的相应过程调用序列(定义3.1)。3.2)。3.1声明的功能化定义3.1函数化,F,将过程声明映射到一个或多个函数声明。这使得过程可以从表达式中访问,在签名级别。由于一个过程可以有多个输出参数,而一个函数只能有一个返回值,因此我们为过程的每个输出参数(编号为1到i)获得一个函数:Fi(Proc(n,q))=Fun(ni,Out(q)i,In(q))(1)为了清晰起见,我们在定义中使用抽象语法,Proc(name,proc- parameter-list)是过程声明,Fun(name,return-type,fun- parameter-list)是函数声明。In和Out给出了一个过程的输入和输出参数,分别为5:In(q)=[t |m,t<$<$← q,m ∈{obs,upd}] Out(q)=[t |m,t<$←q,m ∈ {out,upd}]其中m是参数模式,t是参数类型。然后,我们可以获得对应于过程的函数列表:F(Proc(n,q))=[Fi(Proc(n,q))] |i = 1. (2)求函数的表达式:注意函数化和标准技术之间的相似性,这些技术用于描述具有多个返回值的过程的语义。这是过程的语义和功能化版本之间的联系,也是保持两种编程符号之间语义正确性的关键。例如,以下过程:procedure plus(upd densex, obs sparsey);procedure plus(obsint x, obsint y, outintz); procedure copy(obs Tx, out Ty);功能化为以下功能:函数dense plus(densex, sparsey);函数intplus(intx,int y);函数T copy(Tx);5使用列表解析符号(类似于集合符号),如Haskell或Python。A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)3743⎡⎢↓⎤⎥⎦这就是在概念声明中使用的内容。我们保持函数和过程的命名空间,以及它们的使用标记(表达式与调用),不同的,从而避免重载冲突。对于多输出过程,函数将获得编号名称请注意,逆操作-然而,我们可以定义一个规范的过程化P,其中每个函数都映射到一个过程,其中一个out参数用于返回值,一个obs参数用于函数的每个参数P(Fun(n,tJ,[t1,..., t n])= Proc(n,[t b b,t1b,.,(3)(3)3.2多用途定义3.2[赋值的多重化]多重化将一系列函数调用和赋值转换为一个过程调用。给定一个过程p=Proc(n,q):M(Assign(y,Apply(f,x)=i;Call(Proc(n,q),xS),其中F(Proc(n,q))=f,如果x∈/y,则S_b→S_x,N_p其中x=↓x. 如果x∈y,则TmpVar(t,x)和xS,i=unzip其中x=↓xout,s⎢ ⎥upd,s其中y=↓y并且dyjj=k,对于所有yj,yk∈y(4)模式Assign(y,Apply(f,x))识别一个赋值序列,每个赋值对应于p的每个upd或out参数。被调用的函数列表f必须按顺序与p的函数化相匹配。如果没有合适的指令可以从其他地方移动,则可以插入虚拟分配以完成此操作。所有变量(y)分配给的必须是不同的。然后,我们通过检查p的形式参数列表来构造新的参数列表xS和设置语句列表i,在obs的情况下从x中选择参数,在out的情况下从y中选择参数,在upd的情况下从y中选择并生成赋值Assign(y,xNop表示空指令,TmpVar创建临时变量,Assign表示赋值。为了避免别名问题,需要一个临时变量来存储obs参数的值,该参数也用于输出。为upd参数生成赋值是必要的,因为变量y可能与原始参数列表中的相应变量具有不同的值这可能在y已经处于预定义中时生成冗余的Assign(y,y)指令⎣44A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37更新位置例如,如果我们有一个过程p(outt1, updt2, obst3)和f1,f2=F(p):a = f_1(3,2);b= f_2(3,2);→3.3过程调用b =3;(a,b,3);给定函数声明到过程声明的规范映射(即,程序化,如3.1节所述),我们可以将过程调用功能化这意味着我们失去了对程序某些方面的控制,比如中间变量的创建和删除。然而,由于我们认为基于表达式的程序更容易通过工具进行分析和处理,因此获得尽可能接近纯基于表达式的程序的东西将是有用的因此,选择语言形式进行工作成为一种方便。我们的经验主要是利用代数定律进行高级优化-同样的情况也可以在现代优化编译器中看到,它通常会根据执行的优化将低级代码转换为静态单分配(SSA)形式。定义3.3[过程调用的函数化]对于过程p=Proc(n,q):F(Call(p,x))=[Fi(Call(p,x))|i = 1. len(Out(q))](5)Fi(Call(p,x))=Assign(yi,Apply(Fi(p),xS))(6)其中y=Outq(x)且xS=Inq(x)。赋值的顺序是无关紧要的,因为对过程调用参数的要求确保变量y与xS不同。为了函数化一个过程调用Call(n,q),我们构建一个新的参数列表xS,包含所有输入参数,然后为每个输出参数生成一个赋值。Inq和Outq相对于形式参数列表q选择实际参数列表的输入和输出参数:In q(x)=[x|如果m ∈ {obs,upd}],则输出q(x)=[x|如果m ∈ {out,upd},则为{x,m,t,t,t,t}例如,给定一个函数int f(int),我们可以使用规范过程(3)来获得并使用过程p(obs int,out int)。 由于(3)只给我们一个输出过程,所以我们每次调用p只得到一个赋值。使用上面的(5),我们可以使以下语句函数化:(5,x);return(x,y);→f(5);returnf(x);数据流分析将允许我们将代码转换为y =f(f(5)),如果不需要,可能会删除xA.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37453.4整个程序的多重化多任务对它所操作的指令有严格的假设,所以我们可能需要执行指令重新排序和操作,以使程序适合多任务:嵌套表达式必须拆分。这是通过将子表达式移出其包含表达式并将其分配给临时变量来完成的。当函数化程序时,可以应用反向操作(表达式内联)来尽可能深地嵌套表达式,从而使高级转换规则的应用变得容易。在control-callow语句中的调用必须移到外部。Mutification多值程序应专门化。如果我们指令应该重新排序以利用多值过程调用的多值化.一般来说,如果指令i2不依赖于i1的结果,并且不改变i1中的变量,则可以将其移动到i1之前。如果重新排序失败,切片也是不可能的-指令可以通过引入临时指令而彼此独立。例如,如果我们想将第二条指令移到第一条指令之前,我们可以将y的值存储在一个临时变量中:f(i);(3)int n =nums;t=y;x =f(t);(3)int n=intt=y;y =g(3);f(t);把你的旧编译器书翻出来!指令的重新排序和调度在编译器的构造中是众所周知的,这里也可以应用类似的技术.例如,重新排序赋值以利用多值pro-cycle调用与重新排序指令以利用处理器中的并行执行路径没有什么不同。许多熟悉的优化技术,如常数传播,值编号,公共子表达式消除,死变量/代码消除等,可以很容易地应用于Magnolia程序,要么首先转换为SSA(静态单赋值)形式,要么使用简单的数据流分析[10]。纯函数和关于过程的输入和输出的显式信息使得应用优化变得容易得多图图1显示了一个在多重化之前和之后的示例程序,使用了编译器多重化阶段的实际中间输出→46A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37fib(out intf, obs int n){if(n2)f=n;其他f = fib(n-1)+fib(n-2);}public int findDuplicate(intf,intn){call __(a_0,n,2);if(a_0)f=n;int c_0;c_0 = n;public intfindDuplicate(1); intfindDuplicate(2);调用fibonacci::fib(b_0,c_0); int d_0;n = 0;return_-_(1);调用fibonacci::fib(f,d_0);调用_+_(f,b_0);方法102(upd int n){if(n 2);其他n= 102(n-1)(n =2);}}int n(int n){int n;call __(e_0,n,2);if(e_0);其他int f_0;f_0 = n;return_-_(f_0,2);调用fibonacci::f_0();调用_-_(n,1);调用fibonacci::f2(n);调用_+_(n,f_0);}Fig. 1.左:递归斐波那契过程的两个不同变体。右:两个过程的混合结果(编译器的实际中间输出请注意,使用upd参数的fib 2 符号_+_(a,b)只是操作符调用a + b的去糖函数调用变体,而call _+_(a,b)是更新过程调用,类似于C++中的a += b。4讨论4.1使用概念和公理到目前为止,我们所看到的主要好处(除了定义模糊的符号清晰度之外)是代码和规范之间的关系,特别是概念特征。• 在概念中定义的大多数操作都有一个代数风格的声明(除了像I/O这样的某些东西不需要决定是定义函数式接口,还是OO式接口或命令式接口。• 在概念中定义的公理直接映射到代数规范。 在C++中,祈使风格概念的ax-ioms通常使用逗号运算符(表达式的顺序组合)编写:公 理 getset ( Aa , Ii ,Ee ){ setElt(a,i,e),getElt(a,i) ==e;}• 在大多数情况下,概念中使用的过程声明和函数声明之间存在内置的定义良好的映射只要程序代码是针对概念接口编写的,公理就很容易与程序代码联系在C++中,通常需要小型包装器来在概念中的声明风格和实现中的声明风格之间进行转换这种间接性A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)3747这使得将公理与实际的程序代码联系起来更加困难,例如用作重写规则[12]。基于公理的重写[2]是一种通过使用等式公理作为重写规则来进行高级优化的方便方法通过基于纯的、行为良好的函数和无别名的代码,这是非常容易实现的,并且可以应用规则,而无需任何复杂的别名分析,这些分析是现代编译器的一部分请注意,虽然这项工作补充了概念功能,但它绝不依赖于它,并且在没有它的情况下也同样有效4.2多重化的限制多功能化和功能化有一定的局限性。我们基本上是将命令式代码隐藏在纯函数的接口后面,如果我们想在不增加开销的情况下做到这一点,我们隐藏的内容必须是相当纯的。这意味着:• 过程结果只能由输入参数控制。• 一个过程除了对它的输出参数有影响外,对程序状态不能有其他影响• 用作函数参数的对象必须是可克隆的必须能够保存和恢复对象的完整状态前两个限制排除了对全局变量进行操作的过程。后者排除了诸如流I/O和用户交互之类的事情全局变量是有问题的,因为它们干扰推理-引入意外的依赖关系或导致意外的副作用。这打破了简单的代数推理模型,该模型允许我们移动代码并对其进行修改,而无需进行复杂的分析。在某些情况下,全局变量可以通过显式或隐式地将它们作为参数传递来处理(让编译器将全局变量添加到声明和调用中)。在某个时候,我们将到达调用树中最外层的过程,该过程必须从运行时系统获取所有全局变量作为参数,或者被允许直接访问全局变量如果全局状态很大,传递它可能是不切实际的,特别是因为多任务需要在必要时克隆状态。然而,全局变量通常是不受欢迎的,并且会产生可重入性和多线程的问题,所以这在实践中可能不是问题可克隆性要求来自于在应用多功能时有时需要引入临时程序,这对于防止别名是必要的,并且对于避免不必要的重新计算也是有用的然而,一些对象是不可克隆的,例如,因为它们代表了与现实世界的某种交互(例如,读取和写入文件或终端)。这样的物体被认为是不纯洁的。它们只能用作upd参数,并且涉及不纯对象的代码的转换必须保留访问对象的顺序和条件。这类似于C编译器处理volatile的方式48A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37底层代码中的变量,如设备驱动程序。不纯对象最好使用过程来处理,尽管原则上我们可以禁止涉及不纯对象的函数调用,只要不需要复制。4.3性能我们还没有关于Magnolia的性能数据,但我们已经尝试了一种简单的多任务形式,以减少Sophus数值软件库中的开销[3,7]。Sophus在C++中以代数编码风格实现-即,更喜欢纯函数调用而不是参数更新。通过修改Seismod地震模拟应用程序的代码,我们发现与原始的非多重代数式代码相比,加速因子为1.8(大数据集)到2.0(小数据集)。内存使用率降低到60%。4.4相关工作流利的语言[4]通过将语言分成子语言来结合函数式和命令式风格,PROCEDURE是完全命令式的,OB-SERVERs不会导致副作用,FUNCTIONs不会导致副作用,PURE是引用透明的(没有副作用,并且在每次评估时返回相同的值)。不变量通过禁止调用限制更宽松的子程序来维护。另一方面,我们的多功能负责防止有害的副作用,允许从函数调用过程Euclid语言[11]的设计考虑到了验证,并且与Magnolia一样在过程和无副作用函数之间有相同的区别,并且还禁止别名。别名规则类似于Magnolia,但也处理指针和传递数组组件以及作为参数的解引用指针,这在Magnolia中是禁止的。多址转换与编译器中存在的三地址代码的翻译有一些相似之处[1]。我们的方法是更高层次和一般性的,处理任意的过程,而不是一组预先确定的汇编/中间语言指令。复制消除[5]是一种在编译函数式语言中使用的方法,以避免不必要的临时变量。通过为每个表达式找到一个合适的目标,评估可以将结果直接存储在需要的地方,从而消除(至少一些)中间副本。表达式模板[13]避免了中间过程,并通过使用C++中的模板元编程将表达式(特别是大型数值表达式)直接编译为赋值函数来提供进一步的这允许用户编写代数风格的表达式,但实现者必须手动将所有运算符编码到表达式模板系统中,这增加了额外的负担。A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37495结论我们提出了一种程序设计方法和形式化工具,它使操作的使用和实现更加方便。通过函数化和多功能化,我们使命令式过程可作为代数风格的函数调用,并提供使用函数调用的代码和使用过程调用的代码之间的转换。这种脱钩为我们带来了以下好处:• 重用-具有统一的调用风格简化了通用代码与各种实现的接口签名操作还可以帮助集成来自不同源的代码。这绝不是对重用问题的完整解决方案,而是拼图中的一小块,可能会使事情变得更容易。• 可扩展性-具有不同性能特征的多个实现可以通过同一个接口访问• 函数式的符号清晰度-• 链接到公理和代数规范。代数表示法可以直接与规范中使用的表示法相关,从而弥合了实际编程和正式规范之间的差距。这使得公理可以用于高级优化和自动化测试[2]。• 带有变量原位更新的过程命令式风格提供了更好的空间和时间效率,特别是对于大型数据结构。符号和推理的好处类似于函数式编程语言,不需要不可变的变量。我们最初的多功能实验是在C++上完成的,因为C++出色的高性能编译器使其成为性能关键代码的良好选择。然而,像C++这样的语言很难通过工具进行分析和处理。Magnolia背后的想法是删除C++中难以处理或干扰我们推理代码的部分,然后添加必要的功能来支持我们的方法。Magno-lia编译器将产生C++代码,允许我们利用好的编译器和好的编程方法。本文通过以下方式扩展了关于多变量的早期工作[3]:(1)允许操作形式更新任意数量的参数(以前限于一个),(2)允许过程调用的函数化,(3)提供函数化和多变量的形式化处理,以及(4)独立于数值应用领域(这是[3]的核心)来函数化和多功能化最初是出于代码清晰性和效率的考虑,后来对泛型编程的好处变得明显。在确定使用命令式与代数风格,以及使用代数风格与命令式风格时可以预期的生产力这两个方面都是软件工程的考虑因素。还需要进一步正式证明多重化的有效性和正确性50A.H. Bagge,M.Haveraaen/Electronic Notes in Theoretical Computer Science 253(2010)37支持功能化和多功能化的Magnolia原型实现可在以下网址获得:http://magnolia-lang.org引用[1] Aho,A.五、R. Sethi和J.D.Ullman,[2] Bagge , A.H. 和 M.Haveraaen , 基 于 公 理 的 转 换 : 优 化 和 测 试 , 在 : J 。 Vinju 和A.Johnstone , editors , Eighth Workshop on Language Descriptions , Tools and Applications(LDTA 2008),ENTCS(2008).[3] Dinesh , T. , M. Haveraaen 和 J.Heering , 数 值 软 件 及 其 优 化 , Scienti fic Programming8(2000),pp. 247-259.[4] Gi Baud,D.K. 和j.M. Lucassen,Integrating functional and imperative programming,LFP28比38[5] Gopinath,K.和j.L. Hennessy,函数式语言中的副本消除,在:POPL303-314.[6] Guttag,J. 和j. Horning,关于落叶松共享语言的报告,计算机编程科学6(1986),pp. 103-134[7] Haveraaen , M. , H. A. Friis 和 T. A. Johansen , Formal Software Engineering for ComputationalModeling,Nordic Journal of Computing6(1999),pp.241-270[8] 琼斯,S。P.,A. Tolmach和T. Hoare,Playing by the rules:Rewriting as a practical optimizationtechnique in GHC,in:R.Hinze,editor,2001 Haskell Workshop,Firenze,Italy.[9] 莫斯警局编辑,[10] 奥 尔 莫 斯 湾 和 E. Visser , Composing source-to-source data-- Bodik , editor , 14th InternationalConference on Classifier Construction(CC204-220[11] Popek,G. J.,J. J. Horning,B. W. Lampson,J. G. Mitchell和R. L. London,Notes on thedesign of Euclid , in : Proceedings of an ACM conference on Language design for reliablesoftware,1977,pp. 11-18.[12] 唐 , X. 和 j.Järvi , Concept-based optimization , in : Proceedings of the ACM SIGPLANSymposium on Library-Centric Software Design(LCSD[13] Veldhuizen,T. L.,表达式模板,C++Report7(1995),pp. 26
下载后可阅读完整内容,剩余1页未读,立即下载
cpongm
- 粉丝: 4
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 收起
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
会员权益专享
最新资源
- zigbee-cluster-library-specification
- JSBSim Reference Manual
- c++校园超市商品信息管理系统课程设计说明书(含源代码) (2).pdf
- 建筑供配电系统相关课件.pptx
- 企业管理规章制度及管理模式.doc
- vb打开摄像头.doc
- 云计算-可信计算中认证协议改进方案.pdf
- [详细完整版]单片机编程4.ppt
- c语言常用算法.pdf
- c++经典程序代码大全.pdf
- 单片机数字时钟资料.doc
- 11项目管理前沿1.0.pptx
- 基于ssm的“魅力”繁峙宣传网站的设计与实现论文.doc
- 智慧交通综合解决方案.pptx
- 建筑防潮设计-PowerPointPresentati.pptx
- SPC统计过程控制程序.pptx
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功