Lisp之根

The Root of List

约翰麦卡锡于1960年发表了一篇非凡的论文,他在这篇论文中对编程的贡献有如 欧几里德对几何的贡献.1 他向我们展示了,在只给定几个简单的操作符和一个 表示函数的记号的基础上, 如何构造出一个完整的编程语言. 麦卡锡称这种语 言为Lisp, 意为List Processing, 因为他的主要思想之一是用一种简单的数据 结构表(list)来代表代码和数据.

值得注意的是,麦卡锡所作的发现,不仅是计算机史上划时代的大事, 而且是一种 在我们这个时代编程越来越趋向的模式.我认为目前为止只有两种真正干净利落, 始终如一的编程模式:C语言模式和Lisp语言模式.此二者就象两座高地, 在它们 中间是尤如沼泽的低地.随着计算机变得越来越强大,新开发的语言一直在坚定地 趋向于Lisp模式. 二十年来,开发新编程语言的一个流行的秘决是,取C语言的计 算模式,逐渐地往上加Lisp模式的特性,例如运行时类型和无用单元收集.

在这篇文章中我尽可能用最简单的术语来解释约翰麦卡锡所做的发现. 关键是我 们不仅要学习某个人四十年前得出的有趣理论结果, 而且展示编程语言的发展方 向. Lisp的不同寻常之处–也就是它优质的定义–是它能够自己来编写自己. 为了理解约翰麦卡锡所表述的这个特点,我们将追溯他的步伐,并将他的数学标记 转换成能够运行的Common Lisp代码.

分型与混沌

中文字体
abcdABCD

参考资料

CPS变换

为什么函数调用需要保存状态?

add(1,2) mul(3,4) 这种调用明显不需要保存状态
而add(1,mul(1,2)) 这种计算是需要保存1级函数add的变量,再计算2级函数mul返回值和保存相加最终返回

得出一个结论:函数处在参数位置上,调用后需要返回的函数调用才需要保存状态
而什么是尾调用?无需返回的函数调用
一个简单的判定原则 即函数不在参数位置上

函数式程序设计为什么至关重要
Why Functional Programming Matters
函数式程序设计为什么至关重要

作者: John Hughes
翻译: CloudiDust [http://blog.csdn.net/ddwn/]
[在网上也可以找到其他同学的翻译哦,我翻译完了才看到的,呵呵。]

原文地址:http://www.md.chalmers.se/~rjmh/Papers/whyfp.html

为什么函数式编程至关重要

函数式程序的特点

  1. 函数式编程不包含任何赋值语句(也就是没有变量),所有的值从一开始就确定了
  2. 函数式编程不包含副作用,除了计数它本身的值以外不产生任何副作用,这一特性消灭了bug的一个主要来源
  3. 函数式编程值是一定的,那么执行顺序就不在重要,所以它可以在任何时候被执行,这一过程将程序员从控制流中解放
  4. 由于在任意时候求值,程序员可以随性所欲的用变量值来代替变量表达式,反之也可以用变量表达式代替变量的值。程序是引用透明,可以更容易的数学化控制
  5. 函数是一等公民,函数式编程中努力用函数来表达所有的概念,完成所有的操作
  6. 变量的不变性,赋值操作低人一等。简单将在scala函数是编程中只用val,不用var

lambda演算python实现[三]之Bool值和分支

原文出处:Lambda演算中的布尔值和选择

python实现

用python定义Bool值和bool运算如下

lambda演算python实现[二]之数字

原文出处:lambda演算中的数字

python实现

数字和加法的函数表示

Python lambda实现Y组合子

也许你我都难以理解,为什么有人对她痴迷疯狂,铭记在心中不说,还要刻在身上:

她让人绞尽脑汁,也琢磨不定!她让人心力憔悴,又百般回味!

她,看似平淡,却深藏玄机!她,貌不惊人,却天下无敌!

她是谁?

IPC进程通信、消息队列

计算机进程通信原理、IPC、消息队列,

常见的方法

  • 共享内存模式
  • 消息传递模式
  • 共享文件模式

主要使用的是前两种方法

多处理器之间通信

处理器之间不能通过消息传递模式通信,只能共享内存
处理器本身是异步执行的,消息队列没办法实现(接受消息和消耗消息有可能会冲突)
而共享内存的方法也有可能会导致冲突,可以为不同处理器划分不同地址空间来避免冲突

01

单处理器进程通信

进程之间的通信最常见最安全的方法就是消息队列。
每个进程会维护一个消息队列(常见的是FIFO队列,也有带优先级的队列本文不做讨论)

02

进程A给进程B发消息,首先获取进程B消息队列(链表)的地址,将消息插入到链表后面。
当进程B执行是会去取消息队列最前面的消息然后执行。
由于进程A进程B是在同一处理器上占不同的时间片(跟操作系统进程的调度算法有关),
同一时刻消息队列不可能即recive 又 consume,所以不存在队列读写冲突的问题。

消息可以是简单的数据编码标志,也可以携带数据(数据起始地址以及长度),或者其他数据结构体格式

03

scala 的Actor的消息传递也是用此方式实现。