前言

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

函数式语言

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

函数式程序设计的概念

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

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

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. Java基础(十一)回调(callback)与对象克隆(Cloneable)

    一.回调 1.回调是一种常见的程序设计模式,可以指出某个特定时间发生时应该采取的动作. 在java.swing包中有一个类Timer类,可以使用它在到达指定的时间间隔作出什么动作.那么就有两个问题,即 ...

  2. Process类调用exe,返回值以及参数空格问题

    (方法一)返回值为int fileName为调用的exe路径,入口参数为para,其中多个参数用空格分开,当D:/DD.exe返回值为int类型时. Process p = new Process() ...

  3. django-模板之if语句(九)

  4. github实用的搜索小技巧

    查资源,学习优秀的框架,搜索是一种能力! 作为程序猿开发中最大的同性交友网站,github当之无愧,里面有很多优秀的开源框架,各种技术大佬混迹其中,有他们总结的学习教程,造好的轮子(开发的各种工具,技 ...

  5. java中Arrays.sort()对二位数组进行排序

    int [][]a = new int [5][2]; //定义一个二维数组,其中所包含的一维数组具有两个元素 对于一个已定义的二位数组a经行如下规则排序,首先按照每一个对应的一维数组第一个元素进行升 ...

  6. 明解C语言 入门篇 第二章答案

    练习2-1 #include <stdio.h> int main() { int x; int y; int percent; puts("请输入两个整数"); pr ...

  7. QA:无重复字符的最长子串

    无重复字符的最长字串 leetcode地址:https://leetcode-cn.com/problems/longest-substring-without-repeating-character ...

  8. mysql多种备份与恢复方式一

    基于mysql社区版5.7,严重声明:本文中图方便直接写入了-p数据库密码,在生产环境中如果指定了一定要使用history -C清空历史命令记录哦,所有博客作者原创纯手打,转载一定要注明本博客链接,感 ...

  9. 赤壁情:dp

    首先这道题用到的3个新关键字大概讲一下: (我刚学会仅仅会瞎搞做题,欢迎大神补充) static:声明一个变量并清空.(不知道用不用时间,求解答) 具体用法:static 变量类型 变量名.如:sta ...

  10. vim编辑器介绍

    所有的 Unix Like 系统都会内建 vi 文书编辑器,其他的文书编辑器则不一定会存在. 但是目前我们使用比较多的是 vim 编辑器. vim 具有程序编辑的能力,可以主动的以字体颜色辨别语法的正 ...