前言

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

函数式语言

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

函数式程序设计的概念

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

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

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. 防抖与节流 & 若每个请求必须发送,如何平滑地获取最后一个接口返回的数据

    博客地址:https://ainyi.com/79 日常浏览网页中,在进行窗口的 resize.scroll 或者重复点击某按钮发送请求,此时事件处理函数或者接口调用的频率若无限制,则会加重浏览器的负 ...

  2. js中用面向对象的思想——淡入淡出轮播图

    首先看下效果图 明确功能 1.前后切换(边界判断) 2.按键切换  3.自动轮播 css代码 <style> * {margin:0; padding:0;} li{list-style: ...

  3. django-表单之新增字段和设置css属性(四)

    要注意是模板元素 和 表单元素的对应.

  4. 你不知道的Canvas(二)

    你不知道的Canvas(二) 一.色彩Colors 到目前为止,我们只看到过绘制内容的方法.如果我们想要给图形上色,有两个重要的属性可以做到:fillStyle 和 strokeStyle. fill ...

  5. 防抖(debounce)和 节流(throttling)

    防抖(debounce)和 节流(throttling) 1.防抖和节流出现的原因 防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案. 在给DOM绑定事件时,有些事件我们是无法控制触发频率的. ...

  6. 2019 年容器生态统计报告发布 | 云原生生态周报 Vol. 26

    作者 | 酒祝.天元.元毅.心水.衷源 业界要闻 1.2019 年容器生态统计报告发布  据报告显示,Kubernetes 占据 77% 的容器编排产品份额,Docker 占据 79% 的容器引擎产品 ...

  7. 编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现

    实验内容 将非确定性有限状态自动机通过子集法构造确定性有限状态自动机. 实验步骤 1,读入NFA状态.注意最后需要设置终止状态. 2,初始态取空,构造DFA的l0状态,将l0加入未标记状态队列que ...

  8. 学习笔记14Js使用技巧

    **页面加载完毕时执行一段代码$(fuction(){ initialMethod(); }); *将一个<form>序列化为json对象并传给服务器var postData = $(&q ...

  9. web中间件常见漏洞总结笔记

    之前看吐司别人发的个文档,简单记的笔记 ----- IIS     解析漏洞        IIS 6            *.asp;.jpg会被当作asp解析            *.asp/ ...

  10. [考试反思]1024csp-s模拟测试86:消耗

    %%%两个没素质的和一个萌两小时AK 最近貌似总是可以比较快速的拿下T1,然后T2打到考试结束... T1是套路题没什么好说的. T2是一个比较蠢的博弈题,我花了很长时间干各种乱七八糟的事 什么打表啊 ...