分享会 2011-01-06 Introduction of Clojure

18 views
Skip to first unread message

Neo

unread,
Jan 4, 2011, 9:50:44 PM1/4/11
to is...@googlegroups.com
我将在明天下午4点到6点,在创新院4楼做关于 Clojure 的分享会,介绍 Clojure 的历史、目标,并结合实例介绍基本和有特点的语言特性,欢迎各位到场拍砖。




-- 
No, I will not fix your computer.

Neo Lee

LI Daobing

unread,
Jan 4, 2011, 9:54:21 PM1/4/11
to is...@googlegroups.com
OK

2011/1/5 Neo <neo...@gmail.com>:

--
Best Regards
LI Daobing

孔祥波

unread,
Jan 4, 2011, 10:02:03 PM1/4/11
to is...@googlegroups.com
学习

2011/1/5 Neo <neo...@gmail.com>
360.gif

Neo Lee

unread,
Jan 6, 2011, 6:51:44 AM1/6/11
to is...@googlegroups.com
附件是今天的讲义,请享用。

今天有几个当时无法确定的问题,我记得的回头试过会把结论发上来,其它欢迎大家展开讨论——不到三个小时要讲清楚一门复杂的编程语言其实是不可能的,所以只能是点到即止,抛砖引玉。其实 Clojure 还有不少有趣的东西可以研究。

--
No, I will not fix your computer!

neo...@gmail.com
Clojure Intro.pdf

Neo

unread,
Jan 6, 2011, 9:34:07 AM1/6/11
to is...@googlegroups.com
问题1:ref 和 atom 等定义可以嵌套么?(老庄)
答:可以,示例代码如下:

(def a (atom 0))

-> #'user/a

(def b (ref a))

-> #'user/b

@b

-> #<Atom@3cecfaea: 0>

@@b

-> 0

(swap! a inc)

-> 1

@@b

-> 1

(swap! @b inc)

-> 2


问题2:Clojure 是否支持 closure(闭包) 和 coroutine(协程)?(方块 & 道哥)
答:支持 closure,样例如下:

(println (reduce + 

  (filter even? 

    (take-while (fn [n] (< n 4000000)) (lazy-seq-fibo)))))

 

(println (reduce + 

  (filter even? 

    (take-while #(< % 4000000) (lazy-seq-fibo)))))


这两段代码完全等价,fn 宏和 #() 效果都是生成一个闭包。

Clojure 本身并没有对协程的直接的支持(还是 JVM 的限制),但是有人贡献了一个代码(在 clojure.contrib.monads 里)实现了一个 continuation monad,后面的引文有介绍。友情提示:这篇文章很长很纠结,慎入[1]。

问题3:用于 Java 互操作的「.」是语言特性还是库函数?(道哥)
答:「.」在下面这些形式里全是 Special Form:

(. instance-expr member-symbol)

(. Classname-symbol member-symbol)

(. instance-expr (method-symbol args*)) ;or (. instance-expr method-symbol args*)

(. Classname-symbol (method-symbol args*)) ;or (. Classname-symbol method-symbol args*)


而其它几种访问 Java 代码的 form 都是基于 Macro 展开的语法糖:

(.instanceMember instance args*)

(.instanceMember Classname args*)

(Classname/staticMethod args*)

Classname/staticField


(.. instance-expr member+)

(.. Classname-symbol member+)


问题4:关于 partition 函数的特性
答:讲解有误,如果不够数,多余的会被舍弃,确保返回的每个小 list 的元素数字都一致(仔细想确实这样合理):

(partition 3 [1 2 3 4 5 6 7 8 9 10])

-> ((1 2 3) (4 5 6) (7 8 9))


问题5:关于 join 函数的特性
答:join 函数其实类似于 RDBMS 里的 join,将相同键值匹配之后合并每条记录,其原型是:

(join relation-1 relation-2 keymap?)


其中最后的键值映射表是可选的,没有的话自动在两个参数里找相同键值匹配,有的话根据映射表匹配(类似 SQL 的 where 子句),看回今天讲到的例子:

(join #{{:a 1 :b 2 :c 3} {:a 1 :b 21 :c 42}}

      #{{:a 1 :b 2 :e 5} {:a 1 :b 21 :d 4}})

-> #{{:d 4, :a 1, :b 21, :c 42} {:e 5, :a 1, :b 2, :c 3}}


把第一个集合看作一个两行记录的数据表,第二个集合也是,然后进行键值相当匹配,遵循最大匹配原则,第一个配第一个,第二个配第二个。其实这种写法不太好,手工指定一个键值映射表比较易读。


LI Daobing

unread,
Jan 6, 2011, 9:38:12 AM1/6/11
to is...@googlegroups.com
我这边还记了几个问题

1. let [v (+ v 1)] 是否合法?

2. dosync 能否嵌套?

2011/1/6 Neo <neo...@gmail.com>:

--
Best Regards
LI Daobing

Neo Lee

unread,
Jan 6, 2011, 10:10:59 AM1/6/11
to is...@googlegroups.com
问题6:(let [v (+ v 1)] ...) 是否合法?(道哥)
答:合法,结果合乎逻辑,例如:

(def v 1)

-> #'user/v

(let [v (inc v)]

     v)

-> 2


问题7:dosync (STM)是否可以嵌套?(道哥)
答:可以,但是在多线程情况下的具体表现还没试。范例:

(def a (ref 1))

-> #'user/a

(def b (ref 100))

-> #'user/b

(dosync 

  (alter a inc)

  (dosync

    (alter b dec)))

-> 99

@a

-> 2

@b

-> 99





-- 
No, I will not fix your computer.

Neo Lee

Jeffrey Zhao

unread,
Jan 7, 2011, 4:32:47 AM1/7/11
to is...@googlegroups.com
赞。我打算在20号讲一下F#,大家到时候要来听啊。
 

高博

unread,
Jan 7, 2011, 4:35:46 AM1/7/11
to is...@googlegroups.com
那必须的。
Reply all
Reply to author
Forward
0 new messages