218 lines
37 KiB
TeX
218 lines
37 KiB
TeX
|
||
世界离不开计算,描述计算离不开程序设计语言\index{程序设计语言}。不同的程序设计语言描述不同的计算模式\index{计算模式}
|
||
,例如,命令式语言描述以状态变迁作为计算的模式,函数式语言描述以函数作为计算的模式,逻辑语言描述以证明作为计算的模式,而量子语言则描述遵循量子力学规律调控量子信息单元进行计算的模式。在第\ref{book1-PL}章,我们对众多的程序设计语言进行了比较并回顾了程序设计语言的发展历史,从中可以看到,新的程序设计语言的出现通常是为了应对新的计算模式、新兴应用、或者新兴硬件和计算平台的需要
|
||
|
||
“软件定义一切”本质上是可编程思想扩张到整个社会和物理世界,是一种以软件实现分层抽象的方式来驾驭复杂性的方法论。随着人机物融合的发展,计算的泛在化成为必然,程序设计语言向下需要对物理世界进行抽象并提供处理物理世界的接口,向上需要能够支撑不同场景的应用编程。{泛在计算}\index{泛在计算}中不断涌现出的新的计算模式、新的计算平台和新的应用问题给程序设计语言的定义和实现带来了新的机遇和挑战。
|
||
|
||
|
||
首先,新的计算模式需要新的程序设计语言。随着不断涌现的新的计算模式,如适合于抽象描述机器学习的概率计算、神经网络计算、大数据计算、保护隐私的计算\cite{DBLP:conf/sp/RastogiHH14}等,我们需要新的语言定义和实现技术,快速开发各种各样新的程序设计语言,支持各类新型计算模式。
|
||
|
||
|
||
第二,新的硬件和计算平台需要新的语言实现技术。新的硬件(如XPU(GPU、TPU等)、非易失性内存等)和新的计算平台(如云、网构等)不断涌现。除了设计新的程序设计语言,我们还需要研究新的编译技术以生成适合于新的硬件和体系结构的高效代码。
|
||
|
||
|
||
第三,新的应用问题需要新的程序设计语言来高效地解决。随着社会的发展,我们会遇到各种各样的、新的复杂应用问题,除了利用既有程序设计语言开发新的软件之外,我们还可以通过设计更好的程序设计语言来解决这些问题。新型语言不单单提供了描述解决该问题本身的一个方法,而且可以提供解决一类相似问题的方便而可信的一般途径。程序设计语言技术会提供解决类似问题的方便而可信的途径。
|
||
|
||
|
||
第四,程序设计语言的发展需要健全的语言生态。程序设计语言的生态,包括支撑环境、集成开发环境、扩展功能支持库、第三方功能模块、帮助文档和知识库、技术交流社区、资源下载网站、教程和培训等。程序设计语言生态的繁荣决定了程序设计语言的繁荣。
|
||
|
||
|
||
在这一章里,我们将从计算的泛在和多样性,计算平台,软件的复杂性和安全性,以及软件生产率等几个方面来讨论新时代软件设计语言与支撑环境方面的挑战,列出重要的研究内容,并阐述展示程序设计语言及支撑环境方面的研究趋势。
|
||
|
||
\section{重大挑战问题}
|
||
程序设计语言的挑战问题集中于如何建立、描述和实现抽象。具体来说,其挑战表现在两个方面。首先,在抽象建立和描述方面,主要表现在如何通过对领域和应用问题的抽象,开发有效的领域特定语言\index{领域特定语言}(§\ref{2_3_1_1})、支持多范式程序设计\index{多范式程序设计}(§\ref{2_3_1_2}),特别是加强大数据时代语言对数据处理的支持(§\ref{2_3_1_3})。其次,在抽象的实现方面,主要表现在如何开发人机物融合的泛在范式的编译技术(§\ref{2_3_1_4})和构建程序语言的安全性保障机制(§\ref{2_3_1_5})。
|
||
|
||
\subsection{面向泛在计算的语言的定制}\label{2_3_1_1}
|
||
随着泛在计算的普及,一方面,专用化的计算设备和运行平台需要软件具备面向不同专用硬件和平台的高效定制能力;另一方面,泛在服务软件需要提供各种特定的编程抽象,支持面向人机物融合的最终用户编程。在泛在计算的环境下,程序员的概念也不断泛化——未来越来越多的人,甚至那些缺乏足够计算机专业知识的领域专家,需要对专用化的设备或特定领域的问题进行程序设计。这就需要我们开发各式各样的领域特定语言。泛在计算对领域特定语言的定义和实现带来了新的挑战。
|
||
|
||
\begin{itemize}
|
||
\item 特定领域语言一般是轻量的,是通用语言的特例。在通用语言的实现已经存在的前提下,我们可以用通用语言的方式来定义和实现领域特定语言。然而,这种方式不仅增加了开发的难度,而且也不经济。我们需要一种高效的特定语言的定义和实现方法。一种思路是设计并实现一种通用元级语言作为特定语言定义和实现的基础,但是什么样的通用语言适合于定义和实现各类特定领域语言是一个必须解决的问题。
|
||
\item 对于通用语言,我们已经开发了不少很有用的程序分析、优化、调试、测试方法。对于特定领域语言,我们需要利用这些方法。尽管我们可以用通用语言来实现某种特定领域语言,但是如何能够将这些一般性的方法系统化地映射到特定语言的实现上是一个挑战。例如,假设我们在通用语言上实现了一个测试方法,但是通用语言上的测试结果对于特定领域语言的用户而言是不能理解的。我们需要将通用语言上的测试例子和结果映射到特定语言程序上,特定领域语言的用户才能理解。
|
||
\item 在设计特定领域语言时存在的一个选择是应该设计一个小而精的语言,还是设计一个大而全面的语言?Schema语言的设计者之一的Guy Steele认为,既不应该建立一种小语言,也不应该建立一种大语言,而需要设计一种可以成长的语言。语言设计应该是增长式的——语言必须从小开始,能够随着用户集的增长而增长。例如,我们可以比较APL语言和LISP语言:APL不允许用户以“流畅”的方式向该语言添加新的原语(Premitive),这使得用户难以扩展该语言;在LISP中,用户可以定义与语言基元保持一致的单词,它使语言用户可以轻松扩展语言并共享代码。为此,在设计语言时,我们面临的挑战是,如何保证其具有一定的柔性,支持新的语言构造和特性可以被无缝接入其中,同时,在语言演化过程中,也能保证遗留系统被无障碍地执行。
|
||
\end{itemize}
|
||
|
||
\subsection{多范式程序设计的语言支持}\label{2_3_1_2}
|
||
主流程序设计语言支持不同的程序设计范式\cite{ DBLP:journals/software/WamplerC10}。从程序设计语言的角度出发,一方面,需要设计与程序设计语言相适应的程序设
|
||
计范式或者程序设计模型,以获取程序可读性、模块性、抽象性和性能上的平衡。另一方面,需要提供技术手段,根据程序员能力或者开发任务自动选择或者推荐程序设计范式,
|
||
提升程序员程序设计效率。然而随着解决的问题越来越复杂,我们需要研究支持多范式的程序设计语言,以及对多范式语言的高效实现机制。特别是,我们面对下面一些挑战。
|
||
|
||
|
||
首先,如何将描述函数计算最直接的函数式程序设计\index{函数式程序设计}融合到其它语言中是多范式语言设计的一个挑战。函数式程序设计\cite{kar50323}用函数来抽象
|
||
计算,它的高阶函数和计算的透明性的两个重要特征,一方面使函数式语言适用于大数据处理、人工智能等领域,但是另一方面也使它不容易与其它语言共用。尽管已有不少关于研究和系统讨论如何融合逻辑语言与函数式语言\cite{DBLP:series/lncs/Torra16},融合面向对象语言和函数式语言,不少通用程序设计语言(C++和Java、Kotlin等)也
|
||
开始支持函数式程序设计,但是,现在还没有一个公认的计算模型来系统地支持这种融合的设计和实现。如何将函数式语言的高阶函数和计算透明性有效而便捷地扩展至函数式语言以外的其他通用程序设计语言,以支持函数式程序设计或混成程序设计,成为一个值得关注的挑战问题。
|
||
|
||
|
||
其次,无缝融合并发程序设计是多范式语言设计和实现的另一个挑战。目前已经存在很多并发程序设计模型,它们指定了系统中的线程/
|
||
进程如何通过协作来完成分配给它们的作业——不同的并发模型采用不同的方式拆分任务,线程/进程间的协作和交互方式也不相同。为此,需要建立与特定程序设计语言相适应的
|
||
一组并发模型,更好支持程序员设计与实现并发任务。此外,传统的并发思维,是在单个处理器上,使用分时方式或是时间片模型来执行多个任务。如今的并发场景则正好相反,
|
||
是将一个逻辑上的任务放在多个处理器或者多核上执行。因此,程序设计语言需要提供足够的机制来分解任务。然而,基于目前并发API,例如,线程、线程池、监视等,编写并发程
|
||
序依然很困难,还需要更多关于程序设计语言及实现方面的努力。例如,可以由编译器甚至执行引擎识别出程序中可并发的任务,以便多核计算机可以将其安全地并发执行。
|
||
|
||
\subsection{大数据处理的程序语言支持}\label{2_3_1_3}
|
||
当今时代是大数据的时代。全球的数据在不断地增多,依赖这些数据对各行各业进行优化是当今社会的发展趋势。大数据呈现出体量巨大、数据类型多样、数据增长速度快和数据价值密度低的4V特征,这就意味着要利用好数据中的价值,我们必须依赖于程序以自动化地管理和分析数据,从而给程序设计语言带来了一系列全新挑战。
|
||
|
||
|
||
首先,大数据\index{大数据}的一个特点是数据类型多样,但不同的人和不同的场合需要的数据是不一样的,这就意味着我们常常需要对数据按不同方式进行组织。数据自主性和数据互操作性给程序语言的设计带来挑战。一方面,当我们按照某一种特定格式获取到数据的时候,需要把数据转换成其他格式保存和展示。另一方面,当我们修改了其中一份数据的时候,需要保证其它保存的数据和展示的视图都能对应修改。如果用传统程序设计语言编写这样的数据同步程序有两方面的问题:(1) 重复的编码工作量大:对于两种数据的同步一般需要编写两份转换程序,但这两份转换程序很多部分是重复的。(2) 很容易出现错误:两份转换程序容易写得不一致。因此,需要新的程序设计语言来处理此类数据管理需求。
|
||
|
||
|
||
其次,大数据具有体量巨大、数据增长快的特点。这就意味着,要对海量的大数据进行分析,不但人工无法完成,小型计算机系统通常也无法完成。要完成海量的数据分析,往往需要包含多个CPU的大型机系统,或者由多个中小型计算机联网形成的集群系统。但是,用普通程序设计语言编写这类集群系统上的大数据处理程序非常复杂,因为程序员必须处理并行任务分解、多CPU/计算机调度、进程/线程同步等一系列问题。需要新的程序设计语言来降低大数据处理程序的编写难度。尽管MapReduce, Pregel等面向大数据处理的并行计算模型已经提出,但是基于这些模型的程序语言要么接近于模型、用户难以使用,要么用户容易写,但是缺少优化方法、运行效率低。需要新的程序设计语言来解决此类数据计算需求。
|
||
|
||
|
||
最后,大数据具有价值密度低的特点,这就意味着如果要发挥大数据的作用,需要采用合适的方式对数据进行统计。有效的统计方法往往需要我们针对数据的特点构建统计模型,然后根据统计模型对数据进行统计。例如,现在流行的神经网络需要用户首先给出网络结构,然后根据数据确定网络中参数数值。而基于统计学的概率图方法需要先确定随机变量的分布和随机变量之间的依赖关系,然后基于数据确定随机变量的后验分布。这些统计模型的编写较为复杂,同时给定模型之后的统计算法也比较复杂,因此,需要有新的程序设计语言来支持这类模型的描述(如概率编程等)、验证和测试。
|
||
|
||
\subsection{面向人机物融合的泛在范式的编译技术}\label{2_3_1_4}
|
||
编译器\index{编译器}是程序设计语言的重要支撑环境,其负责将一种语言(通常为高级语言)所书写的程序变换成另一种语言(通常为低级语言)程序。编译器的另一个主要功能是对程序进行优化,提升软件的性能。现代软件系统呈现人机物融合的泛在混成特性,对编译技术也带来新的挑战。
|
||
|
||
首先,编译器需要能够快速应对不断出现的专用处理器。摩尔定律的逐渐失效以及大数据处理深度学习等新应用需求的出现,正助推计算机行业从通用计算机系统,转向一个青睐专用微处理器和专用存储系统等专用硬件的时代。这种转变需要我们研究新的更有效的编译技术。当一个新的硬件出现之后,首先,应该对专用硬件进行抽象,定义一个底层使用该硬件的领域特定语言(DSL)\cite{ DBLP:books/daglib/0030751}\cite{Thereska:2013:ISS:2517349.2522723};然后,扩充现有的语言,为之提供一个高层次的界面,以便用户描述专用硬件上的计算;最后,定义如何将高层次的程序翻译到底层的DSL。为了支持这个过程,我们需要研究自动编译技术——我们预测未来的编译器能够在SMT等求解器的帮助下自动生成能在专用处理器上运行的目标程序,通过重写策略对目标程序自动优化,且保证编译过程的正确性和代码质量\cite{Rompf:2012:LMS:2184319.2184345}\cite{ Chen:2018:TAE:3291168.3291211}\cite{Monsanto:2012:CRS:2103656.2103685}。
|
||
|
||
|
||
其次,编译器需要能够高效地处理混成系统\index{混成系统}。现在的软件系统越来越复杂,形成了一个混成的系统,需要既能处理离散的又能处理连续的计算,既能处理确定性(逻辑式)的又能处理概率性的计算,既针对命令式的又针对函数式的程序设计语言,既可静态类型检查又可以动态确认程序满足的性质。为了开发这样的复杂的软件系统,混成语言以及相应编译技术变得非常重要。此外,复杂软件系统可能由不同程序设计语言书写的程序组成。对不同程序设计语言所书写的程序进行高效混成编译,也是一个值得关注的研究问题。
|
||
\subsection{程序设计语言的安全性保障}\label{2_3_1_5}
|
||
程序设计语言的安全性(Safety),体现在两个方面:程序设计语言自身的安全性设计与其支撑环境(如库、编译器、解释器、运行时等)的安全性保障。程序设计语言的设计者和实现者都在不遗余力的提升程序设计语言的安全性。当前,程序设计语言的安全性方面,还存在以下的重大挑战问题。
|
||
|
||
|
||
首先,需要建立语言安全性和灵活性、复杂性之间的平衡。程序设计语言的安全性主要体现为程序设计模型中一组机制,保障程序员写出安全的程序。例如,C++支持的RAII(资源获取即初始化)通过栈语义保证对象析构函数的自动调用,解决了内存泄漏问题;类型系统使代码仅能访问被授权可以访问的内存位置;脸书公司推出的智能合约语言Move语言不支持动态分配和循环递归依赖等\cite{ 2019Move}等。然而,语言安全性的提升意味着程序设计灵活性的下降、支撑环境复杂性的提升。为此,在设计一门程序设计语言的同时,需要定义一组通用的或领域/环境相关的安全机制,包括是否支持指针、自动垃圾回收、异常处理,是否支持强类型检查和中间码验证等,一方面允许程序设计人员编写出既功能强大又足够安全的程序,另一方面在静态编译或者动态执行时实现程序的安全性检查。
|
||
|
||
|
||
其次,需要提供充分保障支撑环境可靠性、安全性的分析、测试和验证等技术手段。编译器、虚拟机和执行引擎的代码复杂,其中潜伏着包含缺陷或者安全漏洞。如何提升编译器、虚拟机和执行引擎的安全性是一个重要的问题。当前已经出现了经过验证的编译器,例如,CompCert\cite{Leroy:2009:FVR:1538788.1538814}\cite{Wang:2019:ASB:3302515.3290375}。此外,已经出现了一批针对编译器和虚拟机的测试和安全分析工作,例如,CSmith\cite{Yang:2011:FUB:1993498.1993532}、EMI等。尽管如此,对编译器(包括优化算法)及虚拟机等安全性分析、测试、验证工作还面临很多问题,我们仍需要能够充分保障编译器、虚拟机和执行引擎的安全性的分析、测试和验证技术手段。例如,不可能枚举出一个语言的所有程序实例以对支撑环境进行穷尽测试,相反,需要提供一套策略,协助选择或者自动生成具有代表性的程序实例以高效测试支撑环境的健壮性。特别是,针对支撑环境进行广泛测试,针对各类编译技术和算法(如优化算法和垃圾回收算法)进行正确性验证,及验证应用程序接口的正确性,仍然是这个方向上的难点问题。此外,在程序设计语言动态演化过程中,需要提供足够的技术手段,保障语言新特性和支撑环境新功能可以被可靠地、安全地加入至既有语言和支撑环境中。
|
||
|
||
\tikzstyle{every node}=[draw=black,thick,anchor=west]
|
||
\tikzstyle{selected}=[draw=red,fill=red!30]
|
||
\tikzstyle{optional}=[dashed,fill=gray!50]
|
||
\begin{figure}
|
||
\footnotesize
|
||
\begin{tikzpicture}[%
|
||
grow via three points={one child at (0.5,-0.55) and
|
||
two children at (0.5,-0.55) and (0.5,-1.1)},
|
||
edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}]
|
||
\node{程序设计语言主要研究内容}
|
||
child {node{语言设计}
|
||
child {node {传统语言设计}
|
||
child {node {类型系统}}
|
||
child {node {语言定义}}
|
||
child {node {内存模型}}
|
||
}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child {node {新型语言设计}
|
||
child {node {泛在计算}
|
||
child {node {\bf 软件定义网络的程序设计语言}}
|
||
child {node {软件定义内存的程序设计语言}}
|
||
child {node {\bf 离散和连续混成系统的语言}}
|
||
child {node {\bf 支持共享内存模型的并发程序设计}}
|
||
}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child {node {大数据处理}
|
||
child {node {\bf 面向数据管理统计的程序设计语言}}
|
||
}
|
||
child [missing] {}
|
||
child {node {人机物融合}
|
||
child {node {\bf 支持最终用户编程的程序设计语言}}
|
||
}
|
||
child [missing] {}
|
||
child {node {多范式/新范式程序设计}
|
||
child {node {\bf 多范式和领域特定的程序设计语言}}
|
||
child {node {\bf 智能合约的设计语言}}
|
||
}
|
||
child [missing] {}
|
||
}
|
||
}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child {node {语言实现和支撑环境}
|
||
child {node {编译器设计与实现}}
|
||
child {node {程序分析与验证}}
|
||
child {node {程序综合与精化}}
|
||
child {node {\bf 程序设计开发环境}}
|
||
child {node {\bf 离散和连续混成系统的语言支撑工具}}
|
||
}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child [missing] {}
|
||
child {node {语言生态}
|
||
child {node {\bf 程序设计框架和库}}
|
||
child {node {\bf 特定领域语言的元编程和开发环境}}
|
||
child {node {\bf 程序设计语言的生态及其演化规律}}
|
||
}
|
||
;
|
||
% child {node {E}
|
||
% child {node {``value''}}
|
||
% };
|
||
\end{tikzpicture}
|
||
\caption{程序设计语言主要研究内容\label{fig:ProgrammingLanguages}}
|
||
\end{figure}
|
||
|
||
|
||
\section{主要研究内容}
|
||
程序设计语言的主要研究内容请参见图\ref{fig:ProgrammingLanguages}。为了应对上述重大挑战,需要在多方面开展研究。首先,为了支持泛在计算、大数据处理、和人机物融合等多种新型应用场景,需要研究面向不同领域的编程语言,包括面向数据管理统计的程序设计语言(§\ref{2_3_2_2})、面向软件定义网络的程序设计语言(§\ref{2_3_2_3})、描述智能合约的设计语言(§\ref{2_3_2_10})、支持最终用户编程的程序设计语言(§\ref{2_3_2_6})。其次,为了设计面向泛在计算的语言和实现多范式程序设计支持,需要研究多范式和领域特定的程序设计语言(§\ref{2_3_2_1})、离散和连续混成系统的语言和工具(§\ref{2_3_2_4})以及支持共享内存模型的并发程序设计(§\ref{2_3_2_5})。最后,为了支持新语言所带来的开发环境和生态的变化,我们需要研究程序设计框架和程序设计开发环境(§\ref{2_3_2_7})、特定领域语言的元编程和开发环境(§\ref{2_3_2_8})、程序设计语言的生态及其演化规律(§\ref{2_3_2_9})。在图中,我们用粗体表示本章讨论的研究内容。
|
||
|
||
\subsection{多范式和领域特定的程序设计语言}\label{2_3_2_1}
|
||
主流程序设计语言都支持多种程序设计范式。一方面需要研究如何设计程序设计语言所支持的范式乃至于库、编程框架等,以助于程序员更便捷地编写大型应用。另一方面,需要研究如何根据程序员能力或者开发任务自动选择或者推荐程序设计范式,以提升程序员程序设计效率。此外,也需要对多范式程序设计语言的支撑环境(含编译、编译时和运行时优化、内存管理、多线程处理、垃圾回收等)及其程序分析、验证技术进行研究——在一门程序设计语言中引入新的程序设计范式,往往需要很多工业界和学术界的努力,避免支撑环境的复杂性、分析及验证技术难度的急剧上升。
|
||
|
||
|
||
随着专用处理器(如GPU、TPU)等硬件的不断出现以及各种特定应用领域软件开发的需求,领域特定语言的开发变得非常重要。领域特定语言既向下提供特定平台的编程模型,也向上提供具体应用场景的需求描述方法。尽管我们可以使用一般的程序语言的设计方法和编译技术,但是这样开发效率低。我们应该开发在通用语言的基础上实现领域特定语言的技术。主要研究内容包括:(1)运行时和编译时的错误的直观表示;(2)DSL程序测试用例的自动生成;和(3)深度嵌入和浅度嵌入的领域特定语言的定义方法的有机结合。
|
||
|
||
\subsection{面向数据管理统计的程序设计语言}\label{2_3_2_2}
|
||
数据在我们的生活中无处不在。在一个医疗保健系统中,医院、药房、患者都有各自的数据,为了保护隐私,这些数据没有被集中统一管理,而是以一种非中心的方式分散在不同的系统中。如何安全地共享和交换信息从而实现非中心数据的互操作成为现代社会亟需解决的一个重要问题。为了解决这个问题,需要将非中心数据的互操作问题分解为(1)局部的隐私控制问题、(2)全局的数据同步问题、(3)联系局部和全局的软件体系结构问题。每个问题的解决都需要我们设计好的程序设计语言,从而实现一个高可信且可扩展的非中心数据的互操作系统。目前,研究人员提出的双向变换语言\cite{Foster:2007:CBT:1232420.1232424} 能够保证两种数据的一致性,为部分解决数据的互操作提供一个好的解决方案,值得进一步深入研究。
|
||
|
||
|
||
解决数据统计问题的途径是设计程序设计语言来编写统计模型。目前的统计模型语言主要包括两类。一类是支持神经网络\index{神经网络}编写的语言,代表语言包括TensorFlow、PyTorch等。神经网络要求构造出一个网络结构,同时网络上的所有运算都要是能求导的。神经网络的程序设计语言通过限定程序中的运算必须是由可求导的操作构成来保证网络是可以求导的,并利用微积分中的求导算法自动求导来完成网络的训练。此外,神经网络语言通常包括大数据分析语言的功能,可以将运算分配到多个CPU或者多台计算机上,应对大数据程序的运算量要求。另一类是概率程序设计语言,代表语言包括Stan\cite{ DBLP:journals/jss2/Carpenter17}、PyMC等。概率程序设计\index{概率程序设计}语言主要用于编写一个概率模型,包括随机变量、随机变量的分布和相互关系等,允许程序员指定一些模型上的观察值,通过贝叶斯统计来对模型其他部分的随机变量计算后验分布。概率程序设计语言通常提供一系列分析算法和采样算法用于求解和近似求解模型,同时部分语言也提供并行计算能力,以支持用于在大型机/集群系统上快速求解。
|
||
|
||
|
||
\subsection{面向软件定义网络的程序设计语言}\label{2_3_2_3}
|
||
传统网络设施的网络协议都固定在芯片中,一旦制造出来就不可能支持新的网络协议。为了解决这个问题,软件定义的网络设备把控制器制作成可以程序设计的开关电路,允许通过软件控制开关来实现不同的协议。最基础的软件定义网络程序设计语言是Openflow,该语言用于直接控制网络硬件中的开关。由于直接程序设计控制开关较为困难,研究人员又进一步提出了高层的程序设计语言,其代表语言为NetKat语言\cite{Anderson:2014:NSF:2535838.2535862}和P4语言\cite{ Bosshart:2014:PPP:2656877.2656890}:NetKat语言主要从控制角度看待网络协议,允许程序员采用类似普通函数语言的方式来声明函数和函数的组合,然后该语言的编译器负责将这种高层声明转换成Openflow上的开关控制;P4语言主要从数据角度看待网络协议,通过数据格式和对应数据项上的操作来描述网络协议。然而,程序设计人员在编写应用的时候仍需要使用一组与新型硬件相关的库函数,这极大程度地影响了既有系统在新型硬件上的运行或者迁移。这里,值得关注的研究内容包括:(1)定义高层次的、具有更强表达能力的网络定义语言;(2)通过修改底层支撑环境(包含操作系统、编译器、执行引擎、库等),支持既有系统在编译或者执行过程中,主动支持新型硬件的使用。
|
||
|
||
\subsection{离散和连续混成系统的语言和工具}\label{2_3_2_4}
|
||
混成系统是由离散和连续的多个子系统组合而成的混成模型。尽管近年来已有很多处理混成系统的语言和系统工具,每个语言和工具对环境做出不同的假设,导致混成系统难以在不同的语言和工具之间共享信息。因此,需要解决混成系统中各个子系统的一致性问题,从而最大限度地利用现有的语言和工具。主要研究内容包括:(1)审阅和比较现有混成系统语言和工具的语义、表达能力和数学机制,发掘它们的差异;(2)设计一种语义感知的交换格式,便于描述不同语言间的语义变换(交叉语义);(3)设计一个描述混成系统的统一的描述语言并开发相应的实现和验证技术。
|
||
|
||
\subsection{支持共享内存模型的并发程序设计}\label{2_3_2_5}
|
||
由于处理器和编译器对程序的优化,大多数处理器和程序设计语言(如C++或Java)无法提供理想化的顺序一致性(Sequential Consistency)内存模型\index{内存模型}。近年,来对内存一致性模型的形式化定义成为研究的热点,包括对处理器(如x86、Arm、Power等)和并发程序设计语言(如C++和Java等)的内存模型的设计与实现等。然而,现有程序设计语言的内存模型仍然存在较多问题。Java和C++的内存模型仍然过于复杂,且允许程序产生违背直观的行为,特别是跟程序逻辑完全无关的行为(即所谓的out-of-thin-air行为,简写为OOTA)。因此这些内存模型还有待改进。另一方面,经典的并发验证逻辑和既有分析、测试、验证工具无法直接应用于弱内存模型程序,我们需要新的理论和工具支持。针对以上不足,我们需要解决以下问题:(1)改良现有的程序设计语言中的内存模型,避免内存模型中的OOTA行为;(2)基于改良后的内存模型,给出新型的并发程序验证、分析、测试的技术,保证弱内存模型下的并发程序编译及执行的正确性。
|
||
|
||
|
||
\subsection{智能合约的设计语言和开发环境}\label{2_3_2_10}
|
||
|
||
智能合约是一种以信息化方式传播、验证或执行合同的计算机协议,允许在没有第三方的情况下进行可信合约的签订。智能合约实质上是一种代码合约和算法合同,将成为未来数字社会的基础技术。它的主要研究内容包括:(1) 设计易于开发智能合约的设计语言;(2)研究规模化智能合约的自动生成技术;(3)研究适合于智能合约生命周期的形式化验证框架和验证方法;(4)实现智能合约的开发环境。
|
||
|
||
|
||
\subsection{支持最终用户编程的程序设计语言}\label{2_3_2_6}
|
||
最终用户程序设计主要涉及两条研究路线。一条路线是从教育的角度出发,把现有程序设计语言中的概念用更简单直观的图形化方式表达出来,使得没有学过程序设计的人也能很快熟悉和掌握。研究内容包括:(1)设计一组被最终用户所能接受和使用的语言构造,并通过相关支撑环境实现将用户设计的程序“编译”为可以被具体执行的程序; (2)研究提升此类程序设计语言的表达及容错能力的方法。最终用户程序设计\index{最终用户程序设计}的另一条路线是针对特定领域让用户用最自然的方式表达需求,同时用程序综合的方式来完成程序的构造\cite{ DBLP:journals/ftpl/GulwaniPS17}。主要研究内容包括:(1)研究适用于不同应用场景和不同用户级别的需求表达方式;(2)研究将这些需求自动转换成程序的方法。
|
||
|
||
最终用户程序设计的一个重要应用领域是应对面向人机物融合的大趋势,为最终用户提供控制网络上设备的编程方式。目前,在这个方向上已经有一些典型的应用,包括为智能家居的物联网设备编程。例如,物联网编程语言IFTTT采用了IF语句作为基础编程单元,主要表达不同条件满足的时候设备应该采用的动作。很多主流的智能家居企业,例如,小米、华为都采用了这种编程模型。但目前编程模型的能力还有较大局限性,一些需求无法完全表达;同时在程序变得比较复杂的时候,基于IFTTT的编程方式也容易带来预期之外的交互,引起较难调试的问题。
|
||
|
||
|
||
\subsection{程序设计框架和程序设计开发环境}\label{2_3_2_7}
|
||
程序设计语言与编程环境、程序设计框架、程序设计工具需要协同发展。近几十年来程序设计的努力主要体现在框架及工具等方面。例如,.NET Framework里有超过一万个类及十万个方法,现有的编译器和解释器之间的界限越来越模糊。类似的,现在的IDE包含了无数强大的功能,例如,语法提示,重构,调试器等。上述程序设计框架、工具等支撑着高层语言的普及和使用。因此,需要设计与开发与程序设计语言相匹配的程序设计框架和程序设计环境,支撑多范式程序设计,并集成程序搜索、推荐、自动修复等功能,以支持程序员轻易地开发出更强大的应用\cite{ DBLP:journals/ftpl/VechevY16}。
|
||
|
||
\subsection{特定领域语言的元编程和开发环境}\label{2_3_2_8}
|
||
程序设计语言方面的一个研究内容是构建支持特定领域语言的定义和实现的开发环境。这个环境需支持高效而正确地设计和实现众多的领域特定语言,抓住不同领域的计算特征,便于领域专家使用。同时,为了高效组合不同领域的计算特征,需要构建“面向语言”的程序设计环境。面向语言的程序设计明确鼓励开发人员构建自己的领域特定语言,或者将具有特定领域概念的现有语言作为方法的一部分进行扩展。利用这个环境,程序员在软件开发时不是只使用一种语言,而是使用最适合每项任务的语言,然后把它们有机组合在一起。例如,MPS (Meta Programming System) 等语言工作台是面向语言方法的重要组成部分。使用MPS,可以为任何新语言定义编辑器,使得领域特定语言的使用更简便。即使是不熟悉传统程序设计的领域专家,也可以在MPS中使用领域特定语言。
|
||
|
||
\subsection{程序设计语言的生态及其演化规律}\label{2_3_2_9}
|
||
程序设计语言的流行与发展,离不开其生态的繁荣与发展。程序设计语言的生态是围绕各种程序设计语言,为了支持语言标准化、使用及扩展所形成的语言设施(包括语言标准、集成开发环境、编译器、虚拟机、标准库、扩展功能支持库等)、语言涉众(包含语言的学习者、使用者、维护者、标准委员会和用户社区等)和知识体系(帮助文档和知识库、资源下载网站、教程和培训等),及在此基础上形成的相互依赖和相互作用的网络。生态提供了对程序设计语言更广泛的支持。然而,针对程序设计语言生态的研究还不多。仍需要对程序设计语言生态进行大量研究,研究如何定义/描述一个程序设计语言及其生态系统,以及研究如何将一个既有项目从一个语言生态迁移至另一个语言生态等。此外,需要分析生态系统的利益相关者及生态中蕴含的海量知识/数据等,以更好发现程序设计语言与生态、利益相关者的伴生、共同演化与发展的规律。
|
||
|
||
|
||
由于工业界、研究者的努力,程序设计语言将处于持续演化中,主要演化方向是使语言变得更简单、更完善、更强大、更安全、更易学和使用。然而,仍需要进一步探索程序设计语言的演化规律,理解、分析并利用程序设计语言演化的驱动力,探索可能的演化方向,推动程序设计语言进一步发展。首先,需要归纳、总结程序设计语言中出现的、程序设计人员更主动采纳的新特性、新机制。例如,如何设计一系列“语法糖”,帮助程序设计人员更便捷地书写程序;如何从语言角度设计模板,使得模板的编写变得更简单和容易理解;如何使程序员更容易使用容器和算法,且更容易组合算法等;如何通过语言来简化异步程序的编写等。此外,程序设计语言的演化,也会导致支撑环境性能的提升。例如,利用模块以加快编译速度,提供更强大的编译期反射功能和元数据查询能力,利用即时编译(JIT)编译器以省下了解释器的开销等等。这里,语言的演化更需要得到编程支撑环境方面的支持。
|
||
|
||
|
||
\section{本章小结}
|
||
软件已经成为人类社会的基础设施。如果说软件是信息社会发展的基础,那么程序设计语言就是软件持续发展的基础。在泛在计算的背景下,程序设计语言的挑战问题主要集中于如何建立、描述和实现泛在计算的抽象。泛在计算促使我们,探究各式各样的适合某种框架或具有某种特性的领域特定程序设计语言,使得向下能对硬件计算单元进行抽象并提供接口,向上适合处理不同场景的应用编程;研究程序设计语言随着时间和环境的改变而变化的演化和生长机制;探讨基于“语言工程”的软件设计方法和支撑环境。本章详细地说明了新时代程序设计语言的几个挑战性问题,有些问题并不新,但是它们被赋予新的内涵。同时,本章也列出了一些本领域的研究热点,希望有更多的科研人员投入程序设计语言及其生态的研究,迎接未来的挑战。
|