diff --git a/Ch1-2-ProgrammingLanguage.tex b/Ch1-2-ProgrammingLanguage.tex index 1d41fd5..5ab1cdd 100644 --- a/Ch1-2-ProgrammingLanguage.tex +++ b/Ch1-2-ProgrammingLanguage.tex @@ -1,64 +1,83 @@ % !TEX root = main.tex \section{概述} %概念的界定,怎么展开 -软件工程师在开发软件系统时,不可避免地要用到某种程序设计语言。顾名思义,程序设计语言\index{程序设计语言}是程序员用来描述程序行为的语言。一般来说,每种程序设计语言往往具有某种应用背景、所属的语言范型以及鲜明的特征。程序理论作为程序设计语言的基础,不仅可以用于描述程序设计语言的语法、语义,还可以支撑程序的正确性构造。在计算机科学领域,曾出现过数百种程序设计语言。近几年,TIOBE、IEEE 等给出了目前常用的程序设计语言,排名居于前列的包括:Java、C、Python、C++、C\#、JavaScript、PHP等。Sebesta~\cite{sebesta2012concepts}从高级语言机制的设计角度对程序设计语言进行了深入细致的介绍和比较。大多数新程序设计语言的创建都受以前语言概念的启发,而新出现的程序设计语言往往通过规则的简化,使程序员的工作变得更加简单。 +软件工程师在开发软件系统时,不可避免地要用到某种程序设计语言。顾名思义,程序设计语言\index{程序设计语言}是程序员用来描述程序行为的语言,为程序员表达基于计算的解决方案提供了(通用)抽象设施。一般来说,每种程序设计语言往往具有某种应用背景、所属的语言范式以及鲜明的特征。程序理论作为程序设计语言的基础,提供程序抽象及其之间的推理和构造原理,不仅可以用于描述程序设计语言的语法、语义,还可以支撑程序的正确性构造、指导程序的高效正确的实现。在计算机科学领域,曾出现过数百种程序设计语言。近几年,TIOBE、IEEE 等给出了目前常用的程序设计语言,排名居于前列的包括:Java、C、Python、C++、C\#、JavaScript、PHP等。Sebesta~\cite{sebesta2012concepts}从高级语言机制的设计角度对程序设计语言进行了深入细致的介绍和比较。大多数程序设计语言的创建都受其之前语言概念的启发,而新出现的程序设计语言提供更强更为自然的抽象设施,使程序员的工作变得更加简单、有效。 %程序设计语言的定义可分为语法、语义等方面。语义表示程序的含义,由静态语义和动态语义组成。静态语义指程序编译时可以确定的语法成分的含义;建立在转换/迁移系统上的动态语义则描述程序如何执行。 % \section{程序设计语言} -在计算机发展的早期,人们往往是用二进制(0/1序列)给计算机发指令。这显然很不方便。后来,逐渐出现了汇编语言\index{汇编语言}以及各种高级语言。一般来说,提高软件开发本身的效率与质量需要更抽象更高级的程序设计语言;而提高现实计算机硬件系统的利用率和执行效率,则需要使用较低级的程序设计语言,这样程序可以更直接地控制硬件资源。较通用的程序设计语言适用于广泛的应用领域和应用场景,可吸引大量的语言使用者,积累充足的遗产代码,便于培训与推广共享资源;但高度通用的语言设计上难以兼顾开发效率与执行效率。很多针对特定应用领域的程序设计语言更容易通过合适的语言机制同时改善软件开发与执行的效率。多样化的编程接口具有程序设计语言功能,但缺乏相应的编程框架甚至程序库等。这类接口反映了相应的编程模型的特点,实质上起到了程序设计语言的作用。 +在计算机发展的早期,人们往往是用二进制(0/1序列)给计算机发指令。这显然很不方便。后来,逐渐出现了汇编语言\index{汇编语言}以及各种高级语言。一般来说,提高软件开发本身的效率与质量需要更符合人类思维的程序设计语言;而提高现实计算机硬件系统的利用率和执行效率,则需要使用较低级的程序设计语言,这样程序可以更直接地控制硬件资源。较通用的程序设计语言适用于广泛的应用领域和应用场景,可吸引大量的语言使用者,积累充足的遗产代码,便于培训与推广共享资源;但高度通用的语言设计上难以兼顾开发效率与执行效率。很多针对特定应用领域的程序设计语言更容易通过合适的语言机制同时改善软件开发与执行的效率。此外,多样化的编程接口常具有部分的程序设计语言功能,反映了相应的编程模型的特点,也可以起到程序设计语言的作用。 -程序设计语言的发展因计算机系统发展的驱动和行业应用需求发展的推动,不同语言不同程度地受这些因素推动。新出现的程序设计语言通常是应对新兴应用或者新兴计算机体系结构的需要。但从程序设计语言发展历史角度看,应用需求的影响明显处于主导地位。 +程序设计语言的发展往往在不同程度上得到了计算机系统和行业应用需求发展的推动。 +新出现的程序设计语言通常是应对新兴应用或者新兴计算机体系结构的需要。从程序设计语言发展历史角度看,应用需求的影响明显处于主导地位。 \subsection{语言的设计、实现及生命期} +为了便于使用与推广,程序设计语言的设计与实现通常要遵守一定的规则。同时,不同应用的涌现也推动了多种程序设计语言的提出与发展。 + \subsubsection{设计} 一般说来,程序语言的设计应该遵守以下原则\footnote{http://people.cs.aau.dk/$\sim$bt/DAT5E07/PrgLDesign.pdf}: \begin{itemize} -\item 可读性:能够很容易的理解; -\item 可写性:能够清晰、准确地表达计算意图; -\item 可靠性:确保程序不会导致意外; -\item 正交性(Orthogonality):每种语言构造的组合都是合法的; -\item 一致性:相似的特点有相似的表示和行为; -\item 可维护性:能够很容易发现错误并纠正; -\item 通用性:若干结构可以组合成更通用的结构; -\item 可扩展性:能够给用户提供加入新结构的机制; -\item 标准化性(Standardability):允许程序在不同机器和系统间的移植; -\item 可实现性:能够编写对应的转换器\index{转换器}或解释器\index{解释器}。 +\item 程序语言的构造方面: + \begin{itemize} + \item 可读性:能够很容易的理解; + \item 可写性:能够清晰、准确地表达计算意图; + \item 通用性:若干结构可以组合成更通用的结构; + \item 正交性(Orthogonality):每种语言构造的组合都是合法的; + \item 一致性:相似的特点有相似的表示和行为; + \end{itemize} +\item 程序语言的实现方面: + \begin{itemize} + \item 可实现性:能够编写对应的转换器\index{转换器}或解释器\index{解释器}; + \item 可靠性:确保程序不会导致意外; + \item 可维护性:能够很容易发现错误并纠正; + \item 可扩展性:能够给用户提供加入新结构的机制; + \item 可标准化性(Standardability):允许程序在不同机器和系统间的移植。 + \end{itemize} \end{itemize} -语言设计在实践中有三个角度:从程序设计语言理论角度出发设计的语言如Pascal、Ocaml、X10等十分关注语言语义的清晰性、灵活性、简洁性,往往直接反映了理论领域的创新成果;从系统软件与体系结构角度出发设计的语言如图形处理器支持的CUDA,关注如何充分利用系统结构的特点来优化性能;从应用角度出发设计的语言如XML、PHP、Julia等关注与目标应用的契合度以及编程的便易性。 +语言设计是上述几方面原则的综合权衡,在实践中有不同角度,体现不同的侧重点:从程序设计语言理论角度出发设计的语言如Pascal、Ocaml、X10等十分关注语言语义的清晰性、灵活性、简洁性,往往直接反映了理论领域的创新成果;从系统软件与体系结构角度出发设计的语言如图形处理器支持的CUDA,关注如何充分利用系统结构的特点来优化性能;从应用角度出发设计的语言如XML、PHP、Julia等关注与目标应用的契合度以及编程的便易性。 -某些语言如数据库查询语言SQL简洁地表示数据表格间的代数关系\index{代数关系},大幅简化了对数据库\index{数据库}的查询;深度学习编程框架\index{编程框架}TensorFlow~\cite{abadi2016tensorflow}、PyTorch等辅助编程者方便地生成神经网络结构\index{神经网络结构}并根据学习算法自动生成反向网络。这些语言或框架追求编程简单性,虽然简化了循环和递归这样的图灵可计算性的关键语句,但仍然反映了一定的程序设计模型\index{程序设计模型}。 +某些语言如数据库查询语言SQL简洁地表示数据表格间的代数关系\index{代数关系},大幅简化了对数据库\index{数据库}的查询;深度学习编程框架\index{编程框架}TensorFlow~\cite{abadi2016tensorflow}、PyTorch等辅助编程者方便地生成神经网络结构\index{神经网络结构}并根据学习算法自动生成反向神经网络。这些语言或框架追求编程简单性,虽然简化了循环和递归这样的图灵可计算性的关键语句,但仍然反映了一定的程序设计模型\index{程序设计模型}。 \subsubsection{实现} -语言的传统实现方式分为从高级语言\index{高级语言}到机器代码\index{机器代码}的静态编译与直接对高级语言程序解释执行\index{解释执行}两种方式。如果存在中间语言,在不同层次可能分别采用不同方式混合实现,如避免在运行时的编译性能消耗和内存消耗的运行前编译(Ahead of Time,简称为AOT)与根据当前硬件情况实时编译生成机器指令的运行时编译\index{运行时编译}(Just-in-time,简称为JIT)。编译技术仍然是语言实现的关键技术。一方面,类型检查等静态程序分析\index{静态程序分析}均在编译阶段实施;另一方面,代码生成过程中的优化技术是对程序员屏蔽硬件复杂性的主要手段。 +语言的传统实现方式分为从高级语言\index{高级语言}到机器代码\index{机器代码}的静态编译与直接对高级语言程序解释执行\index{解释执行}两种方式。如果存在中间语言,在不同层次可能分别采用不同方式混合实现,如避免在运行时的编译性能消耗和内存消耗的运行前编译(Ahead of Time,简称为AOT),以及根据当前硬件情况实时编译生成机器指令的运行时编译\index{运行时编译}(Just-in-time,简称为JIT)。编译技术仍然是语言实现的关键技术。一方面,类型检查等静态程序分析\index{静态程序分析}均在编译阶段实施;另一方面,代码生成过程中的优化技术是对程序员屏蔽硬件复杂性的主要手段。 -近年来,随着计算机系统结构\index{计算机系统结构}的多样化和复杂化,程序设计语言出现了许多新的形式。例如,并行编程模型\index{并行编程模型}OpenMP使用预编译制导语句插在C或Fortran的代码中,描述了多线程并行。尽管OpenMP本身不具有完整的独立语法,但因为反映了与串行C语言不同的共享变量式并行编程模型,我们也可以称之为新的“语言”或者至少是新的“语言机制”。 -通用语言的程序可以像OpenMP那样插入新的语言机制的语句,也可以反过来在新风格的程序中插入通用语言的子程序。这一方式在大数据处理编程框架MapReduce、Hadoop、Spark中得以应用,不仅简化了分布式并行数据处理编程,而且允许程序员设计灵活高效的程序用于数据处理。一些编程模型的实现甚至不引入任何新的语法扩展,仅仅以子程序库的形式出现。比如,科学计算中广泛使用的MPI由C和Fortran程序库实现,支持多种形式的消息传递通讯。 +通用语言的程序可以像OpenMP那样插入新的语言机制的语句;也可以反过来在大数据处 +理编程框架MapReduce、Hadoop、Spark新风格的程序中插入通用语言的子程序,不仅简 +化了分布式并行数据处理编程,而且允许程序员设计灵活高效的程序用于数据处理;一 +些编程模型的实现甚至不引入任何新的语法扩展,仅仅以子程序库的形式出现,比如科 +学计算中广泛使用的MPI由C和Fortran程序库实现,支持多种形式的消息传递通讯。 +%近年来,随着计算机系统结构\index{计算机系统结构}的多样化和复杂化,程序设计语言的实现出现了许多新的形式。一种方式是在已有的程序设计语言中加入实现不同功能的语句,构建新的语言机制。例如,并行编程模型\index{并行编程模型}OpenMP使用预编译制导语句插在C或Fortran的代码中,描述了多线程并行。尽管OpenMP本身不具有完整的独立语法,但因为反映了与串行C语言不同的共享变量式并行编程模型,我们也可以称之为新的“语言”或者至少是新的“语言机制”。 +%\note{本段是不是主要指一些语言采取库的实现方式?建议与实现方式能一致系统的描述} +%第二种实现方式是在新风格的程序中插入通用语言的子程序。 +%%通用语言的程序可以像OpenMP那样插入新的语言机制的语句,也可以反过来在新风格的程序中插入通用语言的子程序。 +%这一方式在大数据处理编程框架MapReduce、Hadoop、Spark中得以应用,不仅简化了分布式并行数据处理编程,而且允许程序员设计灵活高效的程序用于数据处理。 +%第三种方式是编程模型的实现不引入任何新的语法扩展,仅仅以子程序库的形式出现。比如,科学计算中广泛使用的MPI由C和Fortran程序库实现,支持多种形式的消息传递通讯。 \subsubsection{发展} -\begin{figure}[htbp] - \centering - \includegraphics[width=0.95\textwidth]{fig1-2/2-1.png} - \caption{常见程序设计语言的发展脉络 - \label{fig:2-1}} -\end{figure} +%\begin{figure}[htbp] +% \centering +% \includegraphics[width=0.95\textwidth]{fig1-2/2-1.png} +% \caption{常见高级程序设计语言的发展脉络 +% \label{fig:2-1}} +%\end{figure} 自20世纪60年代以来的发展历程看,程序设计语言的抽象级别显著提高。历史上曾出现过将程序设计语言分为四代的提法: \begin{enumerate}[1)] \item 机器语言\index{机器语言}:由二进制0、1代码指令构成,不同的处理器具有不同的指令系统。由于机器语言难编写和维护,人们已很少直接使用这种语言。 \item 汇编语言\index{汇编语言}:汇编语言指令可以直接访问系统接口。由汇编程序翻译成的机器语言程序效率高。但同样难以使用与维护。 - \item 高级语言:它是面向用户的,独立于计算机种类与结构。因此易学易用,通用性强,应用广泛。图\ref{fig:2-1}给出了常见高级程序设计语言的发展脉络\footnote{https://exploring-data.com/vis/programming-languages-influence-network/},其中箭头指向的程序设计语言借鉴了前驱的设计思想。 + \item 高级语言:它是面向用户的,独立于计算机种类与结构。因此易学易用,通用性强,应用广泛。%图\ref{fig:2-1}给出了常见高级程序设计语言的发展脉络\footnote{https://exploring-data.com/vis/programming-languages-influence-network/},其中箭头指向的程序设计语言借鉴了前驱的设计思想。 \item 声明式语言\index{非过程化语言}:使用这种语言编码时只需说明“做什么”,不需描述算法细节。数据库查询语言是其中的一种,用户可以对数据库中的信息进行复杂的操作。 \end{enumerate} -在程序设计语言发展最初阶段,程序设计语言按照主要编程范型\index{编程范型},可以被归类为过程式、面向对象、函数式~\cite{hu2015functional}等。随着C++、C\#等语言的出现,传统分类之间的界限逐渐变得模糊。现代的编程语言往往具有若干种类编程语言的元素,这就是所谓的多范型编程语言。而多范型程序设计语言\index{多范型程序设计语言}也是一个越来越明显的趋势。 +在程序设计语言发展最初阶段,程序设计语言按照主要编程范式\index{编程范式},可以被归类为过程式、面向对象、函数式~\cite{hu2015functional}、逻辑式等。随着C++、C\#等语言的出现,传统分类之间的界限逐渐变得模糊。现代的编程语言往往具有若干种类编程语言的元素,这就是所谓的多范式编程语言。而多范式程序设计语言\index{多范式程序设计语言}也是一个越来越明显的趋势。 + +%一个成功的程序设计语言从探索到推广、接受和最终成为行业标准往往经历以下四个阶段:第一阶段,在应用与系统的软件开发过程中不断完善;第二阶段,为提高软件生产率,提供方便灵活的开发工具;第三阶段,行业的积累有助于产生相应的遗产代码资源,并推广资源;第四阶段,随着大量遗产代码开始积累,行业标准成型,行业倾向于使用成熟的程序设计语言。分析程序设计语言所处的发展阶段有助于我们了解甚至预测其发展趋势。 -一个成功的程序设计语言从探索到推广、接受和最终成为行业标准往往经历以下四个阶段:第一阶段,新兴应用与系统的软件开发在早期开发过程只能采用已有的程序设计语言配以一定的软件工程方法;第二阶段,为提高软件生产率,多种语言工具开始出现;第三阶段,行业标准的形成有助于积累遗产代码资源和培训与推广资源;第四阶段,随着大量遗产代码开始积累,行业商业模式成型,倾向于使用成熟的程序设计语言。分析程序设计语言所处的发展阶段有助于我们了解甚至预测其发展规律。 \subsection{应用驱动的程序设计语言发展} @@ -70,15 +89,17 @@ \end{figure} %这里以多个有代表性的语言为例,分析其应用背景、设计特点与发展规律,从而展现程序设计语言发展的历史与现状。 -按照程序设计语言的类型与应用,图\ref{fig:2-2}给出了以时间为主线的不同类别语言的发展过程与分类关系。从不同角度来看,一种程序设计语言既可能属于系统编程语言,又是面向对象语言。从发展过程来看,一种语言在发展过程中会不断进行扩充,融入不同的范型,进而趋近于多范型语言。计算机产业的发展往往是新的产业应用从已有的应用模式中成长出来而不是取而代之。新语言的出现往往标志着信息技术在新的应用领域的扩张。本节主要以应用驱动来组织。 - +按照程序设计语言的类型与应用,图\ref{fig:2-2}给出了以时间为主线的不同类别语言的发展过程与分类关系。从不同角度来看,一种程序设计语言既可能属于系统编程语言,又是面向对象语言。从发展过程来看,一种语言在发展过程中会不断进行扩充,融入不同的范式,进而趋近于多范式语言。计算机产业的发展往往是新的产业应用从已有的应用模式中成长出来而不是取而代之。新语言的出现往往标志着信息技术在新的应用领域的扩张。本节主要以应用驱动来组织。 + + \begin{itemize} \item 科学与工程计算(1954$\sim$) -\end{itemize} +\end{itemize} + -早期计算机系统硬件结构简单,软件专用性强,主要用于核反应计算、密码破译这样专业性强的科学与工程计算领域,直接服务对象往往是政府与军工。由John Backus主导实现的Fortran语言标志着具有完整工具链的程序设计语言出现。Fortran语言符合典型的过程式语言的特征,由从事系统结构和系统软件的研究人员设计,采取编译的方式实现,反映了程序设计与计算机系统之间的紧密联系。尽管串行的科学计算软件开发方法已成熟,积累的大量遗产代码保证了Fortran这样的语言在其适用领域仍然具有生命力。 +早期计算机系统硬件结构简单,软件专用性强,主要用于核反应计算、密码破译这样专业性强的科学与工程计算领域,解决数值计算问题,直接服务对象往往是政府与军工。由John Backus主导实现的Fortran语言标志着具有完整工具链的程序设计语言出现。Fortran语言符合典型的过程式语言的特征,由从事系统结构和系统软件的研究人员设计,采取编译的方式实现,反映了程序设计与计算机系统之间的紧密联系。串行的科学计算软件开发方法已成熟,积累的大量遗产代码保证了Fortran这样的语言在其适用领域仍然具有生命力。 -早期语言的准确语义往往依赖于编译器的实现,针对特定体系结构由编译器的开发者设计。上世纪五十年代末期出现了一些由计算机逻辑理论与程序语义研究者设计和实现的程序设计语言,如ALGOL和LISP语言。上世纪七十年代后出现的大量函数式语言如ML、Haskell往往具有清楚而简洁的数学表示,设计出发点上更多地考虑如何优美地表示计算,但由于缺乏工业级应用的针对性以及性能上对常见体系结构的适配性,其接受范围受到限制。 +早期语言的准确语义往往通过编译器的实现来体现,针对特定体系结构由编译器的开发者设计。上世纪五十年代末期出现了一些由计算机逻辑理论与程序语义研究者设计和实现的程序设计语言,如ALGOL和LISP语言。上世纪七十年代后出现的大量函数式语言如ML、Haskell往往具有清楚而简洁的数学表示,设计出发点上更多地考虑如何优美地表示计算,但由于缺乏工业级应用的针对性以及性能上对常见体系结构的适配性,其应用范围受到限制。 科学与工程性质的计算,尤其是高性能计算往往与计算机体系结构密切相关,发展了多种形式的编程接口。OpenMP是共享内存的并行计算所常用的编程接口。其特点是在C或Fortran中插入指导语句,希望不改变原有串行程序语义的条件下利用共享存储器的多线程并行加速计算。MPI是跨平台的消息传递通讯程序库,完全不增加额外的语法机制。图形处理器语言CUDA在C基础上扩展了一些语法机制,用以区分在CPU、GPU上运行的程序片段,作出不同的编译。并行程序设计模型一直是程序设计理论研究的一个重点 。 @@ -86,15 +107,15 @@ \item 商用计算(1960$\sim$) \end{itemize} -信息技术的应用逐渐从专业领域扩展到广阔的商业领域信息化。COBOL语言的出现标志着商业化的事务处理如金融、财会有了强有力的语言技术支持。该时期计算系统往往是大型机或小型机服务器。COBOL拥有庞大的用户群,据称积累了超过2000亿行遗产代码\footnote{http://cobolcowboys.com/cobol-today/}。由于商业计算的多样性,一台大型机往往需要运行多种类型的软件,甚至同时并发地运行不同软件。这一时期开始,管理不同类型软件的操作系统得以发展。C语言可以直接处理系统资源,尤其适合系统软件开发。相比之下,同样是过程式语言\index{过程式语言}的PASCAL语言则是由程序设计语言理论研究者设计的更加安全和规范的语言。数据库查询语言\index{数据库查询语言}SQL是较早出现的领域专用语言。它不具有完整的程序设计语言功能,但可看成是针对关系数据库\index{关系数据库}应用的编程模型。 +信息技术的应用逐渐从专业领域扩展到广阔的商业领域信息化,相应的程序设计语言需大规模复杂事务的处理能力。COBOL语言的出现标志着商业化的事务处理如金融、财会有了强有力的语言技术支持。该时期计算系统往往是大型机或小型机服务器。COBOL拥有庞大的用户群,据称积累了超过2000亿行遗产代码\footnote{http://cobolcowboys.com/cobol-today/}。由于商业计算的多样性,一台大型机往往需要运行多种类型的软件,甚至同时并发地运行不同软件。这一时期开始,操作系统开始发展,C语言可以直接处理系统资源,尤其适合系统软件开发。相比之下,同样是过程式语言\index{过程式语言}的PASCAL语言则是由程序设计语言理论研究者设计的更加安全和规范的语言。数据库查询语言\index{数据库查询语言}SQL是较早出现的领域专用语言。它不具有完整的程序设计语言功能,但可看成是针对关系数据库\index{关系数据库}应用的编程模型。 -随着商用计算而来的是软件大规模化。1960年代末出现了一系列旨在有效控制大规模软件开发过程复杂性的程序设计思想。面向对象的思想及其第一个语言Simula 67试图对不同程序模块访问共享变量的方式进行限制,使得程序更加具有模块组装特性。Edsger W. Dijkstra提出避免使用GOTO语句的结构化程序设计\index{结构化程序设计}思想~\cite{dijkstra1968go},对程序的控制流进行限制。 +随着商用计算而来的是软件大规模化。1960年代末出现了一系列旨在有效控制大规模软件开发过程复杂性的程序设计思想。面向对象的思想及其第一个语言Simula 67试图通过数据封装对不同程序模块访问共享变量的方式进行限制,使得程序更加具有模块组装特性。Edsger W. Dijkstra提出避免使用GOTO语句的结构化程序设计\index{结构化程序设计}思想~\cite{dijkstra1968go},对程序的控制流进行限制。 \begin{itemize} \item 人工智能(1960$\sim$) \end{itemize} -人工智能\index{人工智能}自诞生以来,广受关注。在该领域也出现了若干专用语言。例如,基于λ演算的函数式编程语言LISP,具有对符号表达式的支持、交互式环境和可扩展性等特性,曾大量用于人工智能系统的开发。人工智能有符号主义、连接主义等流派。 +人工智能\index{人工智能}自诞生以来,广受关注。在该领域也出现了若干专用语言,用于编写程序求解非数值计算、知识处理、推理、规划、决策等具有智能的各种复杂问题。例如,基于$\lambda$演算的函数式编程语言LISP,具有对符号表达式的支持、交互式环境和可扩展性等特性,曾大量用于人工智能系统的开发。人工智能有符号主义、连接主义等流派。 符号主义就是以符号逻辑系统\index{符号逻辑系统}为基础来表示知识。二十世纪七十年代,Robert Kowalski 等人提出了逻辑可以作为程序设计语言的基本思想,把逻辑和计算这两个截然不同的概念统一在一起。这就是逻辑程序设计(Logic Programming),而Prolog语言就是典型的逻辑程序设计语言。对经典的逻辑程序设计语言,可以进行各种扩充。例如,将状态转移的控制机制引入到时序逻辑系统的XYZ/E是世界上第一个可执行的时序逻辑程序设计语言~\cite{Tang2002}。 @@ -104,17 +125,24 @@ \item 个人计算与系统编程(1981$\sim$) \end{itemize} -在摩尔定律背景下,计算机硬件系统的价格不断下降,个人使用计算机的情形越来越普遍。随个人计算而来的是软件的多样化,应用形式从事务处理和业务处理扩展到教育与娱乐。软件的开发与销售形式从硬件捆绑式发展到专业软件企业发行软件拷贝的销售形式。软件开发团队与人员的数目大量增加。C 语言是一种通用的、面向过程式的计算机程序设计语言。计算机系统设计以及应用程序编写是C语言应用的主要领域。 C++是C语言的面向对象扩展,又增加了泛型编程机制,更适合大中型程序的开发。 -作为一种新的多范型语言,Rust不仅能够提供友好的编译器和清晰的错误提示信息,而且速度快、内存利用率高,同时具有丰富的类型系统保证内存安全和线程安全。目前从初创公司到大型企业,已有很多公司都在使用 Rust,应用非常广泛。 +在摩尔定律背景下,计算机硬件系统的价格不断下降,个人使用计算机的情形越来越普遍。随个人计算而来的是软件的多样化,应用形式从事务处理和业务处理扩展到教育与娱乐。 +%软件的开发与销售形式从硬件捆绑式发展到专业软件企业发行软件拷贝的销售形式。 +软件开发团队与人员的数目大量增加。为了便于使用与推广,相应的程序设计语言不仅构成简单,而且功能较全,适应面广。 +BASIC是在计算机发展史早期应用最为广泛的程序设计语言之一,它结构简单、易于学习、执行方式灵活,很快就普遍流行起来。 +%C 语言是一种通用的、面向过程式的计算机程序设计语言。计算机系统设计以及应用程序编写是C语言应用的主要领域。 +C++是C语言的面向对象扩展,又增加了泛型编程机制,更适合大中型程序的开发。 + +作为一种新的多范式语言,Rust不仅能够提供友好的编译器和清晰的错误提示信息,而且速度快、内存利用率高,同时具有丰富的类型系统保证内存安全和线程安全。目前从初创公司到大型企业,已有很多公司都在使用 Rust,应用非常广泛。 \begin{itemize} \item Web服务与移动计算(1990$\sim$) \end{itemize} -伴随互联网的出现,Web服务软件一改拷贝销售形式,直接通过互联网向终端用户提供服务。其服务形式多样,方式多变。服务的反应速度往往受限于互联网的带宽与延迟,而不是计算的速度。因此,客户端与服务器端交互程序设计语言重点关注软件的开发效率,而不是程序的性能。典型的支持此类应用的脚本语言有JavaScript、PHP等。 +伴随互联网的出现,Web服务软件一改拷贝销售形式,直接通过互联网向终端用户提供服务。其服务形式多样,方式多变。服务的反应速度往往受限于互联网的带宽与延迟,而不是计算的速度。客户端与服务器端交互程序设计语言重点关注软件的开发效率,而不是程序的性能。典型的支持此类应用的脚本语言有JavaScript、PHP等。 1990年代后智能手机的出现与普及将计算拓展到个人随身携带的新模式。一些为Web服务设计的语言仍然适用,但新的应用形式也带来了新的挑战。许多项目需要同时以网页、平板以及智能手机形式提供服务。由于应用需求与服务逻辑的易变性,软件的任何更新希望在不同平台上一致地更新。它们不仅需要支持复杂的功能,还需要解决跨平台、跨设备、跨操作系统兼容可移植的难题。 +Java语言具有平台独立及可移植性等特点,被广泛用于Web应用程序、桌面应用程序和嵌入式系统应用程序的开发。 \begin{itemize} \item 大数据分析与处理(2004$\sim$) @@ -129,51 +157,57 @@ %基本的Map与Reduce命令还不能涵盖一般的并行计算步骤的数据依赖关系。 \begin{itemize} - \item 互联网金融(2009$\sim$) + \item 区块链计算(2009$\sim$) \end{itemize} -以软件为核心的互联网金融指的是以互联网为载体的金融服务形式,而并非仅仅将互联网作为连接客户的信息系统。开源软件技术主导的金融服务形式始于2009年出现的第一个数字货币--比特币。数字货币以去中心化共识的区块链记账技术为基础,提供类似法定货币的金融功能,具有特殊的金融服务属性。以太坊数字货币扩展了记账技术,支持区块链中记录完整的程序并以可验证的方式执行这样的程序:合同即是程序,程序即是合同。这就是所谓的智能合约(Smart Contract)。Solidity是目前最流行的合约编程语言。Solidity语法类似于JavaScript,支持继承、类和复杂的用户定义类型,通过编译的方式生成以太坊虚拟机中的代码。 +以软件为核心的互联网金融指的是以互联网为载体的金融服务形式,而并非仅仅将互联网作为连接客户的信息系统。开源软件技术主导的金融服务形式始于2009年出现的第一个数字货币--比特币。区块链是比特币的底层技术,是一个去中心化的数据库,具有分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。数字货币以区块链记账技术为基础,提供类似法定货币的金融功能,具有特殊的金融服务属性。以太坊数字货币扩展了记账技术,支持区块链中记录完整的程序并以可验证的方式执行这样的程序:合同即是程序,程序即是合同。这就是所谓的智能合约(Smart Contract)。Solidity是目前最流行的合约编程语言。Solidity语法类似于JavaScript,支持继承、类和复杂的用户定义类型,通过编译的方式生成以太坊虚拟机中的代码。 \section{程序理论} -程序设计语言都具有语法和语义。语义表示程序的含义。程序理论涵盖程序设计语言的设计、实现,以及程序正确性的分析方法等。本节将介绍程序设计语言的语法与语义基础,并给出描述程序设计规范的形式化方法,如图\ref{fig:1-2-4}所示。其中,形式语言是用数学方法研究程序设计语言的语法,研究语言的组成规则。类型理论\index{类型理论}可以帮助完善程序设计本身,帮助运行系统检查程序中的语义错误。形式语义\index{形式语义}是程序设计理论\index{程序设计理论}的组成部分,以数学为工具,利用符号和公式,精确地定义和解释计算机程序设计语言的语义。而形式规约\index{形式规约}将事物的状态和行为用数学符号形式化描述,为编写计算机程序和验证程序的正确性提供依据。 +程序设计语言都具有语法和语义。语义表示程序的含义。程序理论涵盖程序设计语言的设计、实现,以及程序正确性的分析方法等。本节将介绍程序设计语言的语法与语义基础,并给出描述程序设计规范的形式化方法,如图\ref{fig:1-2-4}所示。其中,形式语言是用数学方法研究程序设计语言的语法,研究语言的组成规则。类型理论\index{类型理论}可以帮助完善程序设计本身,帮助编译或运行系统检查程序中的语义错误。形式语义\index{形式语义}是程序设计理论\index{程序设计理论}的组成部分,以数学为工具,利用符号和公式,精确地定义和解释计算机程序设计语言的语义。而形式规约\index{形式规约}将事物的状态和行为用数学符号形式化描述,为编写计算机程序和验证程序的正确性提供依据。 \begin{figure}[htbp] \centering \includegraphics[width=0.99\textwidth]{fig1-2/2-4.png} - \caption{程序设计语言的发展及分类} + \caption{程序理论的发展时间线} \label{fig:1-2-4} \end{figure} -\subsection{程序设计语言的词法与语法} -程序设计语言都有自己的词法和语法,而词法和语法的定义是一系列规则的集合,这些规则的基础就是形式语言。文法\index{文法}是形式语言中十分重要的基本概念,是描述语言的语法结构的一组形式规则。文法有四种分类,其中最常用的为正则语言\index{正则语言}和上下文无关语言\index{上下文无关语言}。正则语言可以用正规式定义,上下文无关语言可以用上下文无关文法(元素和规则的集合)定义。程序设计语言中的大多数算术表达式可用上下文无关文法\index{上下文无关文法}生成。正则语言是最简单的语言类,是上下文无关语言类的一个真子类。对程序设计语言编写的程序进行分析和处理(编译)时,需要判断对应的句子是否合法,可以通过对应语言的自动机进行判断。自动机是语言的另一种表示方法。其中,正则语言可以转换成有限状态自动机\index{有限状态自动机}、上下文无关语言可转换成下推自动机\index{下推自动机}表示,反之亦然。针对某种特定输入的一系列有限的规则,对不同的输入元素,自动机依据自身的状态会做出不同的响应,最后达到某种特定的状态。 + +\subsection{程序设计语言的语法} + +程序设计语言都有自己的语法,而语法的定义是一系列规则的集合,这些规则的基础就是形式语言,从而保证规则是无二义性的。文法\index{文法}是形式语言中十分重要的基本概念,是描述语言的语法结构的一组形式规则。文法有四种分类,其中最常用的为正则语言\index{正则语言}和上下文无关语言\index{上下文无关语言}。正则语言可以用正规式定义,上下文无关语言可以用上下文无关文法(元素和规则的集合)定义。程序设计语言中的大多数算术表达式可用上下文无关文法\index{上下文无关文法}生成。正则语言是最简单的语言类,是上下文无关语言类的一个真子类。对程序设计语言编写的程序进行分析和处理(编译)时,需要判断对应的句子是否合法,可以通过对应语言的自动机进行判断。自动机是语言的另一种表示方法。其中,正则语言可以转换成有限状态自动机\index{有限状态自动机}、上下文无关语言可转换成下推自动机\index{下推自动机}表示,反之亦然。针对某种特定输入的一系列有限的规则,对不同的输入元素,自动机依据自身的状态会做出不同的响应,最后达到某种特定的状态。 \subsection{程序设计语言的类型系统} -在很多程序设计语言中,变量与数据是带类型的;而类型之间有一定的关联。人们在研究程序设计语言理论时,可以借鉴类型论\index{类型论}(Type theory, 也称“类型理论”)来研究程序设计语言的类型系统\index{类型系统}。类型论是数理逻辑中的一个分支,其中的马丁洛夫类型理论用规则来刻画类型及行为,是程序构造的形式理论。类型理论\index{类型理论}研究的是程序设计语言的类型系统,用于定义如何将编程语言中的数值和表达式等短语归类为许多不同的类型,如何操作这些类型,这些类型如何互相作用。类型通过预测程序部件的某些执行行为来协调这些部件间的交互。在类型化的程序设计语言中,语言构造分为引入和消去两种形式。类型的引入形式确定该类型的值或范型,而消去形式则确定如何操作该类型的值以形成另一种(可能是相同的)类型的计算。例如,可以使用类型系统中的归纳类型定义如自然数、表、树等数据结构\index{数据结构};使用多态类型处理程序的特定型与参数型这些不同的输入类型;使用记录类型定义一组记录的命名类型等;自然数类型的引入形式是自然数,消去形式是加法和乘法等。 + +在很多程序设计语言中,变量与数据是带类型的;而类型之间有一定的关联。人们在研究程序设计语言理论时,可以借鉴类型论\index{类型论}(Type theory, 也称“类型理论”)来研究程序设计语言的类型系统\index{类型系统}。类型论是数理逻辑中的一个分支,其中的马丁洛夫类型理论用规则来刻画类型及行为,是程序构造的形式理论。类型理论\index{类型理论}用于定义如何将编程语言中的数值和表达式等短语归类为许多不同的类型,如何操作这些类型,这些类型如何互相作用。类型通过预测程序部件的某些执行行为来协调这些部件间的交互。在类型化的程序设计语言中,语言构造分为引入和消去两种形式。类型的引入形式确定该类型的值或范式,而消去形式则确定如何操作该类型的值以形成另一种(可能是相同的)类型的计算。例如, +%可以使用类型系统中的归纳类型定义如自然数、表、树等数据结构\index{数据结构};使用多态类型处理程序的特定型与参数型这些不同的输入类型;使用记录类型定义一组记录的命名类型等; +自然数类型的引入形式是自然数,消去形式是加法和乘法等。 \subsection{程序的语义} -给定一个程序,如何判断它是否正确?这是很早以前人们就关注的问题。简单来说,如果一个程序恰当地实现了设计者与用户的意图,它就是正确的。严格意义上,程序的正确性~\cite{turing1989checking}需要数学证明,不仅需要形式描述设计者与用户的意图,而且要形式描述程序的含义,并推导程序的行为满足设计者与用户的意图。程序含义的形式化描述就是形式语义学。基于形式语义,不仅可以构建描述程序含义的基础,还可以用于验证程序的正确性。 +给定一个程序,如何判断它是否正确?这是很早以前人们就关注的问题。简单来说,如果一个程序恰当地实现了设计者与用户的意图,它就是正确的。严格意义上,程序的正确性~\cite{turing1989checking}需要数学证明,不仅需要形式描述设计者与用户的意图,而且要形式描述程序的含义,并推导程序的行为满足设计者与用户的意图。程序含义的形式化描述就是形式语义。基于形式语义,不仅可以构建描述程序含义的基础,还可以用于验证程序的正确性。 -程序设计语言的语法是符号化的,语义是该语言程序所描述的计算或过程。根据语义,程序设计语言的解释器或编译器可以将该语言程序编译成计算机可处理的机器语言程序。在程序设计语言的早期,人们使用自然语言解释语义。这种自然语言解释的语义不精确、有歧义,无法分析和证明程序的正确性。为了提高程序设计语言的可理解性、支持语言标准化、指导语言设计、辅助编译器开发、证明程序的性质和程序之间的等价性,需要对程序设计语言的语义进行抽象,给出严格的定义。为此,人们开始研究使用数学结构定义程序设计语言的语义,并扩展出各类形式规约(Specification)语言~\cite{Wang2019},形成了形式语义学\index{形式语义学}~\cite{Zhou2018}。 +程序设计语言的语法是符号化的,语义是该语言程序所描述的计算或过程。根据语义,程序设计语言的解释器或编译器可以将该语言程序编译成计算机可处理的机器语言程序。在程序设计语言的早期,人们使用自然语言解释语义。这种自然语言解释的语义不精确、有歧义,无法分析和证明程序的正确性。为了提高程序设计语言的可理解性、支持语言标准化、指导语言设计、辅助编译器开发、证明程序的性质和程序之间的特定关系,需要对程序设计语言的语义进行建模,给出严格的定义。为此,人们开始研究使用数学结构定义程序设计语言的语义,并扩展出各类形式规约(Specification)语言~\cite{Wang2019},形成了形式语义学\index{形式语义学}~\cite{Zhou2018}。 它的基本方法是用一种元语言将程序加工数据的过程及其结果形式化,从而定义程序的语义。根据所用数学工具和研究重点,形式语义学可分为操作语义、公理语义、代数语义和指称语义四大类。 \begin{itemize} \item 操作语义 \end{itemize} -操作语义(Operational Semantics)\index{操作语义}使用结构化的归约规则,着重描述程序运行中变量赋值的变化、行为的变迁。它将语言中各个成分翻译成计算机系统中相应的一组操作。目前最为常见的操作语义是标号迁移系统\index{标号迁移系统}(Labeled Transition System,LTS),将程序执行描述成标号迁移系统,其中的状态是程序执行期间任意时刻观察到的变量取值。迁移规则规定如何从一个状态转换到下一个状态,每条迁移规则对应一个语句,称为标号。一条语句的语义由一组以其为标号的规则定义;标号规则具有组合性,即一个复合语句的规则可以由其成分语句的规则组合而成。例如,针对一个C程序中的循环语句while(x=y) goto out; - if (x=y) goto out; +% if (x