clojure与FP

16 Apr 2013

1 Clojure 初体验

1.1 说明与动机

  1. 自己也是初学,介绍不深入,很简单。
  2. 没有大局观,不系统,小例子。
  3. 内容分散。
  4. 引用为主。
  5. 内容与Clojure相关性不大。
  6. Progamming Language课程的学习。

1.2 可能具有的一些特点

1.2.1 不变数据与副作用

无变量,数据是不变的。性能上的问题, 应该是 通过写时复制与重用之前的数据。副作用本身与不变数据没有必然的联系,但是不变数据是促进了无副作用的编程,因为没有变量,减少了全局变量的因素,也就限制了副作用可能产生的范围,副作用往往都是受限在一定范围内的。

1.2.2 惰性求值

最近的王垠对于这一问题的批评:

集中于性能上的讨论,惰性求值可能带来堆积和连锁效应,在某些时刻触发之前所有的堆积的操作。

1.3 可能的优点?

1.3.1 单元测试

主要是无副作用,保证了函数映射的固定,固定输入固定输出,方便了测试。与外界的变量隔离后,内部状态相对容易控制和观察,调试方便。

1.3.2 并行

无外部变量的影响,所以竞争条件不多,没有必要增加锁。Map Reduce与hadoop 的应用。

1.5 语法

1.5.1 Lambda算子

之前已经有过介绍,不再多言。 http://www.slideshare.net/qinjian623/lambda-15570486

1.5.2 S-expression介绍

  1. 什么是?

    树结构的数据格式表示形式。有形式化的文档描述,一个没有通过的RFC,地址: http://people.csail.mit.edu/rivest/Sexp.txt 用于通讯数据。 John McCarthy最先提到。

    第一代计算机科学家的年代。

    1. Dennis Ritchie found dead 2011.10.12
    2. John McCarthy 2011.10.24
    3. Steve Jobs 2011.10.05

1.5.3 XML、JSON 与S-exp的相似性

reinvent, 显然,三者的表达能力等价,语法相异但相近。相关的讨论.

XML相对更加接近数据,JSON和S-exp则与语言更紧密。技术哲学话题,见仁见智。

1.5.4 高阶函数,Map Reduce

  1. Map and Reduce

    http://www.cs.cornell.edu/courses/cs3110/2009sp/lectures/lec05.html 良好的数据操作的抽象,可以作为一个通用的大规模数据处理框架,因为可以并行。80年代末就存在了使用这一抽象的并行系统The Connection Machine。但是时机对于技术的影响极大,有其自己的进化路径,Google将其发扬光大,Hadoop作为Google 的Map reduce的开源实现,目前已经被被广泛应用。

    "Our abstraction is inspired by the map and reduce primitives present in Lisp and many other functional languages. We realized that most of our computations involved applying a map operation to each logical record in our input in order to compute a set of intermediate key/value pairs, and then applying a reduce operation to all the values that shared the same key in order to combine the derived data appropriately."

    "inspired by",视界和思维定式往往限制了一个人,虽然这一说法过于“形而上”,但是保持学习的态度,广泛的开拓视野的作用自不言说。

    1. 大数据 互联网大规模数据挖掘与分布式处理

      第二章利用map-reduce来实现选择、投影、并交差运算的方法,这些方法基本都可以自然的应用于具有map reduce操作语言上。

    2. Map func list

      将list中的每个元素都经过func进行操作,形成新的一个list。其实也可以同时操作多个list,相对的func就需要同时传入多个参数。

    3. Reduce func init list

      func接受两个参数,以此遍历list,刚开始传入的是list的第一和第二项,然后通过func计算返回值,作为下次迭代传入的第一个参数。如有init,第一次传入的为init和list第一个项。

    4. 小径

      Map自然也可以通过reduce来实现,包括filter也可以。

1.6 语法与编程范型的无关性

1.6.1 Java的实现

Java也可以写出具有FP特征的代码,但是性能和理解上不舒适。

1.6.2 LISP != FP

最初的LISP并非满足FP. Fortran与LISP的对比对应于图灵机与Lambda的对比。一个更加靠经硬件,一个更加靠近数学抽象。

  1. History of Lisp by John McCarthy
  2. History of Lisp by Paul Graham and also On Lisp
  3. Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp by Peter Norvig
  4. Concepts, Techniques, and Models of Computer Programming

1.6.3 其他的语言

  1. ML-> F# OCaml

    'Programming Language' on coursera.org

  2. LISP -> ELISP /Common Lisp/Clojure …
    1. By GNU
    2. By Xah
    3. ELISP的“原始”

      dynamic scope

  3. Scala in twitter
    1. A Conversation with 3 people in twitter
  4. Haskell

    纯函数式编程语言

    1. 副作用

1.7 小陶示例与运行时的性能比较

1.7.1 直接版本

(defn extend-list [char-set]
  "扩展列表方法,可将(1 2 3),扩展为((1) (1 2))"
  (map #(take (inc (.indexOf char-set %)) char-set) (drop-last char-set)))

(defn flatten-sub-index
  "原始无优化版本"
  [char-set]
  (if (= 1 (count char-set))
    (list char-set) 
    (map #(concat % (list (last char-set)))
         (reduce #(concat %1 %2) []
                 (map flatten-sub-index (extend-list char-set))))))

1.7.2 memoize版本

函数式无副作用带来的优势,本身的基本实现也极为简单。

(declare fm)
(defn flatten-sub-index-two
  [char-set]
  (if (= 1 (count char-set))
    (list char-set) 
    (map #(concat % (list (last char-set)))
         (reduce #(concat %1 %2) []
                 (map fm (extend-list char-set))))))
(def fm (memoize flatten-sub-index-two))
  1. memoize 的极端简单的实现示例 in racket

1.7.3 laziness版本

1.7.4 python的函数式快速排序、以及堆排序的可能性?

python函数式编程风格的快速排序,没有变量的引入。

q=lambda s:s if len(s)<2 else q([x for x in s[1:]if x<s[0]])+[s[0]]+q([x for x in s[1:]if x>=s[0]])

1.7.5 Purely Functional Data Structures until 1998

1.8 嵌入式语言实现、解释器

1.8.1 嵌入式的eval

  1. Racket <- Scheme

    Lisp,语法不多言

  2. 来自Programming Language[纸质材料]

1.8.2 bootstrap scheme的eval,其中的尾递归转化为迭代的优化实现。

1700 lines c,

  1. 尾递归上次提过

1.8.3 构建系统语言的实现

  1. makefile or ant

    仅仅在计划上,预计不会继续。

  2. csv的dsl语言

    实现一个很简单的对csv进行操作的类SQL。

1.8.4 Java的尾递归的上层构建过程

《The Role of the Study of Programming Languages in the Education of a Programmer》

1.9 杂交化的趋势

两个方向,与分久必合。

1.9.1 C++ lambda引入

1.9.2 jvm class file dynamic 的类型引入,支持上层动态语言

2 没有银弹