前言

在之前几篇我们讨论的语法、语义、命名、类型和抽象适用于所有语言。然而我们的注意力都主要集中在命令式语言上,现在这篇来看看其它范式的语言。函数式和逻辑式语言是最主要的非命令式语言。

函数式语言

命名和作用域问题出现在各种模型中,还有类型、表达式和选择与递归等控制流概念等等。所有语言都必须经过扫描、语法分析和语义分析,

函数式程序设计的概念

函数式程序设计将一个程序的输出定义为其输入的一个数学函数,在其中没有内部状态的概念,因此也没有副作用。函数式提供了一下特征,其中许多都是命令式语言中没有的:

  • 第一级的值和高阶函数
  • 广泛的多态性
  • 表类型和表操作
  • 结构性的函数返回
  • 结构性的对象的构造函数
  • 废料收集

Scheme

我们以Scheme为例子,来看一下概念

约束

(let ((a 3)
(b 4)
(square (lambda (x) (* x x)))
(plus +))
(sqrt (plus (square a) (square b))))

特殊型let有两个或者多个参数,其中第一个参数是一些二元组的表,每个二元组的表,每个二元组中的第一个元素是名字,第二元素就是这个名字在let的第二个参数中代表的值。其余参数将按顺序求值,对于整个结构的求值将是最终参数的值

控制流和赋值

(cond
((< 3 2) 1)
((< 4 3) 2)
(else 3))

cond的参数是一些二元组,它们将被从头到尾按顺序考虑。如果第一个二元组的第一个元素求值得到#t,那么整个表达式的值就是这个二元组的第二个元素的值

求值顺序

在之前的几篇已经提到了两种求职方式:应用序求值和正则序求值。和大多数命令式语言一样,Scheme在大多数情况下都是用应用序求值。

严格求值和惰性求值

如果一个无副作用的函数在其任何一个参数是未定义的情况下也是未定义的,我们就称它为严格。这种函数可以安全的对所有参数求值,所以其结果也将不依赖于求值顺序。

惰性求值使我们可以得到正则序求值的优势,回忆一下我们之前说的,惰性求值对实现无穷数据结构非常有用

高阶函数

如果一个函数以函数作为实际参数,或者返回函数作为值,那么它就是一个高阶函数。

比如Scheme的map函数

(map * '(2 4 6) '(3 5 7)) => (6 20 42)

map将对这些表中的一组元素调用相应的函数

高阶函数主要的作用就是从现有的函数出发构造新函数

(define total (lambda (l) (fold + 0 1)))
(total '(1 2 3 4 5)) (define total-all (lambda (l)
(map tatal l)))
(total-all '((1 2 3 4 5)
(2 4 6 8 10)
(3 6 9 12 15)))

Curry化

柯里化是一个常见的操作,是用一个单参数函数取代一个多参数的函数,这个单参数函数返回一个函数

(define curried-plus (lambda (a) (lambda (b) (+ a b))))
((curried-plus 3) 4)
(define plus-3 (curried-plus 3))
(plus-3 4)

除了其它用途之外,这种curry操作还使我们能够给高阶函数传递一个部分求值函数

(map (curried-plus 3) '(1 2 3)) => (4 5 6)

函数式小结

无副作用的程序设计是一种非常诱人的想法,从前面的几篇可以看出,副作用可能使程序难以阅读和编译。

不过,存在着许多常用的程序设计惯用形式,最正宗的副作用在其中扮演着核心角色。

我们关注计算的函数式模型。命令式程序的计算主要是通过迭代和副作用,而函数式程序的计算主要是通过将参数代换到函数中。

函数式语言的相应模型是lambda演算,许多函数式语言倾向于在lambda演算的基础上扩充一些特征,包括赋值、I/O和迭代。

并发模型

如果一个程序包含了多余一个活动的执行上下文。即多余一个控制线程,则称该程序是并发的。并发的出现至少有三方面的重要原因:

  • 为了反映一些问题的逻辑结构。许多程序,必须同时维护一批在同一时间基本相互独立的作业的轨迹
  • 利用额外的处理器以提高速度
  • 为了应对相互独立的多台物理设备

并发程序设计基础

在一个并发程序中,我们将使用术语线程来指代那些程序员认为与其他线程并发的运行的活动实体。在大多数系统中,给定程序的线程是在操作系统所提供的一个或多个进程的顶部实现的。

/*

通信和同步

在任何并发的程序设计模型中,需要处理的两个最关键的问题就是通信的同步。通信指线程可用于获得其它线程产生的信息的各种机制。

同步

*/

写到一般发现很像之前操作系统写到的进程管理,就不再重复了。放个链接

进程管理

进程调度

总结

这一篇就稍微提了一下除了命令式语言之外的其它范式,还有像现在语言支持的并发模型。但是之前讨论的语法、语义、命名、类型和抽象适用于所有语言

PL真有意思(八):其它程序设计模型的更多相关文章

  1. PL真有意思(二):程序设计语言语法

    前言 虽然标题是程序语言的语法,但是讲的是对词法和语法的解析,其实关于这个前面那个写编译器系列的描述会更清楚,有关语言语法的部分应该是穿插在整个设计当中的,也看语言设计者的心情了 和英语汉语这些自然语 ...

  2. PL真有意思(四):控制流

    前言 对大多数计算模型而言,顺序都是基本的东西,它确定了为完成所期望的某种工作,什么事情应该最先做,什么事应该随后做,我们可以将语言规定顺序的机制分为几个类别: 顺序执行 选择 迭代 过程抽象 递归 ...

  3. PL真有意思(一):引言

    前言 断断续续学编译原理到之前发过写一个编译器和正则表达式引擎系列文章也有一段时间了,然后最近看完PLP这本书,这本书应该算是入门书,但是对我这种半吊子收获很大.所以为了弥补最近学操作系统和接外包摸的 ...

  4. PL真有意思(五):数据类型

    前言 现在大多数程序设计语言中都有表达式和/或对象的类型概念.类型起着两种主要作用: 为许多操作提供了隐含的上下文信息,使程序员可以在许多情况下不必显示的描述这种上下文.比如int类型的两个对象相加就 ...

  5. PL真有意思(六):子程序和控制抽象

    前言 在之前我们把抽象定义为一种过程,程序员可以通过它将一个名字与一段可能很复杂的程序片段关联起来.抽象最大的意义就在于,我们可以从功能和用途的角度来考虑它,而不是实现. 在大多数程序设计语言中,子程 ...

  6. PL真有意思(七):数据抽象和面向对象

    前言 在之前的名字.作用域那篇提到模块类型,它使程序员可以从一个给定抽象出发,通过实例化产生多个实例:再后面是类,它使程序员可以定义一族相关的抽象. 在这一篇里,我们会来看一下面向对象程序设计及其三个 ...

  7. PL真有意思(三):名字、作用域和约束

    前言 这两篇写了词法分析和语法分析,比较偏向实践.这一篇来看一下语言设计里一个比较重要的部分:名字.在大部分语言里,名字就是标识符,如果从抽象层面来看名字就是对更低一级的内存之类的概念的一层抽象.但是 ...

  8. C++对象模型笔记之程序设计模型

    C++程序设计模型支持三种程序设计模型 1.程序模型(procedural model) 可以理解为过程化模型,就像C一样 2.抽象数据类型模型(ADT) 数据结构教材里有说过,查了下资料也不是很明确 ...

  9. CUDA C++程序设计模型

    CUDA C++程序设计模型 本章介绍了CUDA编程模型背后的主要概念,概述了它们在C++中的暴露方式.在编程接口中给出了CUDA C++的广泛描述. 使用的矢量加法示例的完整代码可以在矢量加法CUD ...

随机推荐

  1. codeblocks 调试不停止的解决办法。

    CB的工程路径不能有中文,也不能有空格. 所以一定要全英文路径,而且空格要用下划线代替. 否则,调试的时候,codeblocks不会在断点处停止.

  2. django-URL实例命名空间(十一)

    每生成一个地址,都是一个实例.使用实例命名空间,针对于一个app而言. book/views.py from django.http import HttpResponse from django.s ...

  3. 完美解决移动端H5页面的滑动穿透问题

    同事的分享,记录下来. 代码如下: css: body.modal-open { position: fixed; width: 100%; } js: // 兼容低版本 document.scrol ...

  4. 第七章 文件与I/O(4)

    文件共享 打开文件内核数据结构 一个进程两次打开同一个文件 一个进程能打开1024个文件描述符,没打开一个文件,内核会生成一个文件表,文件表中的v节点指针指向v节点表,v节点部分信息就是stat函数返 ...

  5. C语言I博客作业07

    这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-1/homework/9931 我在这个课程的目标 ...

  6. C++学习笔记8_零碎的知识

    1. int main(void) { int arr[] = {1,2,3,4}; //数组的长度 int len = sizeof(arr)/sizeof(int); //由此可以看出,sizeo ...

  7. Mysql数据一般问题

    数据插入中文全部变为???问题: 1.停止Mysql服务: 2.修改C:\Program Files (x86)\MySQL\MySQL Server 5.5\My.ini default-chara ...

  8. AtCoder Grand Contest 036 A-C

    目录 \(\bf A - Triangle\) \(\bf B - Do\ Not\ Duplicate\) \(\bf C - GP 2\) \(\bf D - Negative \ Cycle\) ...

  9. NOIP模拟 24

    连续爆炸的开端. 从这一场开始我没状态了 T1 star way to heaven 受强降雨boboQQQ影响,我一直认为这是一道和凸包有关的计算几何题 很快就弃了,除了期望没做过带实数的题,所以吓 ...

  10. Spring Cloud Gateway使用简介

    Spring Cloud Gateway是类似Nginx的网关路由代理,有替代原来Spring cloud zuul之意: Spring 5 推出了自己的Spring Cloud Gateway,支持 ...