为什么学习 Clojure/ClojureScript?
发布在Clojure 学习手记2014年1月9日view:5071
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

Clojure 的学习其实很早就在计划了,不过迟迟没有开始(行动力不足), 写这么个专栏也是希望激励自己一下,开始学习 Clojure/ClojureScript。 另一方面也打算和大家分享一下学习过程,一起学(zuo)习(si)(笑

本篇文章就当是这个专栏的引言吧,说说为什么想学习 Clojure/ClojureScript。

JavaScript 异步编程

在使用 JavaScript (Node.js) 的过程中,我们会经常用到各种各样的流控制库, 通过 async、q、EventProxy、EventEmitter、after 这些手段, 我们对异步程序的执行流程进行控制。

但是这样的控制显得比较繁琐,编码的过程实在是愉快不起来,于是出现了 Wind.js 这样在 JavaScript 内再实现一个 CPS 风格( Continuation-pass Style )的库。 但是对于 Wind.js 我更觉得它更适合做成一门单独的、CPS 风格的语言, 而不是像现在这样嵌入到 JavaScript 作为库(这样传递闭包的方法着实太丑陋)

Node.js 0.10 出现的 Harmony Generators (新加入标准的 yield 原语) 配合各种协程(Coroutine)库可以达到很好的可读性, 但是协程模式也限制了并发度(只使用 yield 原语的话……使用协程函数对象的 API 可以解决这个问题,那就略复杂了)

流控制的问题追寻到底就是 处理语句之间的数据依赖问题 , 在顺序处理的程序当中,存在隐性的时间依赖关系(语句执行的先后顺序), 举个例子:

var a = 1, b = 2;
var c, d;

c = do_sync(a);
d = do_sync(b);

变量 c 依赖 a,而变量 d 依赖 b,由于是一个同步过程,因此 d 也依赖 c,而这个关系在业务上是冗余的,从而降低了这份程序的执行效率(并发度)。

将同步方法改写成异步方法以后:

var a = 1, b = 2;
var c, d;

do_async(a, function (_c) { c = _c });
do_async(a, function (_d) { d = _d });

就达到了只保留 c->ad->b 这两个变量依赖关系,效率自然就提高了。

换句话说 只保留最简单最纯粹的依赖就能让程序获得最高的并行度

顺便再来看看使用 generator 的一般效果

var a = 1, b = 2;
var ga = make_generator(a), gb = make_generator(b)
var c, d;

c = ga();
d = gb();

这样还是没能解除 d->c 的依赖关系,两条语句之间还是顺序执行(进入 ga 函数的时候会停止当前上下文的执行)。

大概是有正确的使用方法使得协程能够达到第二例的并发度,不过写起来也就失去了 协程的简洁性。(Python 的 Generator 面对这个问题是有解的, JavaScript 不该没有……我不知道而已 ┐(´д`)┌

幻想国 Avalon

不管如何改变,过程式语言在处理异步逻辑的时候都需要开发者格外注意不要产生额外的数据依赖关系(特别是时间上的依赖), 于是肯定会想要一门能够自动处理数据依赖的语言,能够直接得到数据之间的依赖关系, 创建脱离时间依赖的最小依赖的异步程序。

这就是函数式语言,函数式语言的数据依赖是确定的,可计算的, 并不产生基于语句先后顺序的隱性时间依赖。这样的代码具有天然的异步能力, 再加上状态不可变,开发者完全不需要管理异步逻辑(其实是开发者始终在思考异步逻辑)。

异步编程是一种趋势,在量子机能够实现理论上无限的并行度的时候, 还会使用过程语言来开发程序么?

Clojure 和 f2e

好吧,上面所描述的只是我脑补的函数式语言,当然这个思考还很不完全。 Clojure 已经出了很多版本,业内也有了比较成熟的应用, 所以我想现在开始学习 Clojure 和 ClojureScript 也不算太迟。

前端这个行业发展到现在也应该从页面设计走向交互设计的领域了。 你看最近也很流行 MVVM 和 Reactive 之类的设计思路嘛,聪明的你一定也会发现, 这些方法和函数式有很大很大的关系(用户交互时产生的事件正是异步过程所处理的对象)。

Clojure 以及 ClojureScript 在前端应用前景上还是非常广阔的, 几乎能高效简洁地处理所有的异步场景。

最后,不得不吐槽,我不太喜欢 Java 虚拟机,启动起来那叫一个慢啊!(好在 Clojure 的 REPL 可以跑成 daemon……)

总结

为什么你要学习函数式语言?——函数式语言的逼格高呀! ( For Asynchronization

评论
发表评论
4年前

@lidashuang ClojureScript 和 Coffee 的编程思想不一样……大概就是这样的区别……

4年前

clojurescript 和coffee一样,都是语法糖吗?还是clojurescript有特别的功能

4年前

学习Clojure,下一步可以考虑进军Lisp了。。。

WRITTEN BY
羽音篠之
People die if they do
TA的新浪微博
PUBLISHED IN
Clojure 学习手记

用于交流 Clojure/ClojureScript 的学习手记

Clojure is a dialect of Lisp, and shares with Lisp the code-as-data philosophy and a powerful macro system. Clojure is predominantly a functional programming language, and features a rich set of immutable, persistent data structures. When mutable state is needed, Clojure offers a software transactional memory system and reactive Agent system that ensure clean, correct, multithreaded designs.

我的收藏