写点什么

ClojureScript 通过 Javascript 将 Clojure 引入到浏览器端

  • 2011-08-01
  • 本文字数:3109 字

    阅读完需:约 10 分钟

你可以通过 ClojureScript 使用 Clojure 语言编写代码,然后将其编译为 Javascript。ClojureScript 是由 Clojure 的创建者 Rich Hickey 发布的(这里是 Rich 的 ClojureScript 声明 ClojureScript 声明的视频)。

ClojureScript 是 Clojure 的一个子集,目前缺失的特性与库要么是尚未实现,要么是由于对 Javascript VM 毫无意义而不会添加进来,比如线程支持、Java 集成等等。ClojureScript Wiki 上详细列出了Clojure 与ClojureScript 之间的差异列表

设计ClojureScript 的缘由

ClojureScript 的基本原理(摘录自文档)就是“做 Javascript 所能做到的事情”。Javascript VM 正变得越来越快,应用的领域也越来越广。借助于 ClojureScript,我们可以将 Clojure 用于 GUI 客户端编程、包括移动平台(带有强大的 HTML 组件与 Javascript VM)。运行 Clojure 需要客户端安装有 Java VM;虽然桌面操作系统可能都有 Java VM,但浏览器的应用却更加普遍,并且每个客户端操作系统都会有浏览器。这种局面在移动平台上就更清晰了——目前还没有哪个主流的移动平台带有可以直接运行 Clojure 的 Java VM。Android 并不带 Java VM;它需要将所有字节码转换为 Dalvik VM 字节码;现在人们还在为能让Clojure 顺利运行在Android 上而不断努力

ClojureScript 还有另一个使用场景:命令行程序。Java 的命令行程序使用的并不多,特别是需要频繁加载的程序,原因在于 JVM 的启动时间(诸如Nailgun 之类的解决方案就是为了解决这个问题而出现的)。正如Rich Hickey 所述,如果将命令行程序编译为Javascript,然后使用Node.js 运行会大大降低启动时间。

关于在服务器端使用Javascript 的一个普遍观点是可以在服务器端和客户端重用相同的代码;特别是像输入验证这样的逻辑。借助于ClojureScript 依然可以做到这一点:使用ClojureScript 编写的算法可以编译为Javascript 并运行在浏览器中,同时还可以用在服务器端的Clojure 代码基中,这时算法会被编译为Java 字节码。它还为在服务器端完全抛弃Java 提供了一种可能——使用ClojureScript 编写应用,然后在Javascript 栈如Node.js 上运行服务器端。

ClojureScript 的实现方式

ClojureScript 编译器并没有任何 Javascript 代码,它使用 Clojure 编写,这意味着编译器需要运行在 Java VM 上。因此,ClojureScript 缺少 eval 和其他类型的运行时代码加载能力。ClojureScript 的目的在于编写程序并将其编译为 Javascript 而非作为浏览器中的 REPL。

然而,确实有 ClojureScript REPL,它位于 ClojureScript 仓库中,使用 Clojure 实现,它用于启动 Rhino——使用 Java 编写的 Javascript 运行时。要想运行 ClojureScript 代码,需要将其发送给基于 Clojure 的 ClojureScript 编译器,后者会返回 Javascript 代码,然后由 Rhino 运行。在浏览器中不通过 Clojure 实例来这么做显然是不可行的——至少需要将 Clojure 编译器工具链编译成 Javascript 才行。

ClojureScript 代码可以使用 Clojure 宏。宏是个编译期的特性;如果 ClojureScript 代码引用了宏调用,那么宏扩展就会被 ClojureScript 编译器所执行,在 Clojure 中执行。

虽然目前 ClojureScript 编译器只能运行在 Clojure 上,但 ClojureScript 却带有 Clojure Reader。说明一下,Reader 基本上是个 Clojure 解析器;它会将文本形式的 Clojure 程序转换为 Clojure 数据结构,然后再对该数据结构求值。ClojureScript 自带的 Reader 可以解析 Clojure(Script)符号中的数据,然后以数据的形式将其传递给 ClojureScript 代码。ClojureScript 的 Reader 只会解析,由于运行期并没有 ClojureScript 编译器,因此它并不会求值。

ClojureScript 之所以带有 Reader 的目的在于读取 Clojure 数据,就像 Javascript 无需求值就可以读取 JSON 数据一样。我们可以通过 Clojure 生成 Clojure 数据并将其发送给 ClojureScript,反之亦然。

事实上,ClojureScript 编译器工具链的另一部分是 Google Closure 工具集。没错,带有字母“s”的 Closure,他们的命名很像,但 Google 的 Javascript 工具 Closure 集合,特别是 Closure 编译器和 Advanced Compilation 都用到了。

Closure 可用于几个目的:其中一个目的就是库与依赖的管理,这需要库与导出符号。ClojureScript 命名空间定义与 Google Closure 的 provide 与 require 调用对应。这样,ClojureScript 就可以轻松使用 Google Closure 库了,该库拥有非常丰富的 GUI 组件和其他特性。

ClojureScript 与 Clojure 语言非常像,但其标准库是 Clojure 的一个子集。目前,ClojureScript 的标准库有 clojure.string、clojure.set、clojure.walk、clojure.zip 等,同时更多的库将会被添加进来。将 Clojure 库移植到 ClojureScript 的难度取决于代码本身;仅使用基本语言元素来转换数据的纯算法代码很容易移植。使用了 I/O 库、线程、特定 Java 库的库则需要更多的工作;我们还需要分解平台特定的代码,这都是必要的工作。

Google Closure 一个有趣的用法就是作为优化编译器的后端。ClojureScript 编译器所生成的代码会进行优化以便与 Closure 的 Advanced Compilation 协同工作,它会接收 Javascript 源代码并对其进行优化,包括内联的函数调用、删除死代码(dead code)与无用的函数。这种方式的一个优势在于 ClojureScript 编译器无需实现这些优化工作了;它只需将其委托给 Google Closure 即可。

未来,其他的工作也可以委托给 Google Closure,比如为调试器提供源代码图,也就是说数据结构可以匹配生成的 Javascript 代码和生成它的 ClojureScript 代码。 Google Closure 对 SourceMaps 提供了一定的支持,同时 Mozilla 与 WebKit 项目都在致力于扩展其浏览器、调试器和 Javascript 引擎来支持他们。

不久大家就会看到关于 ClojureScript 的更多信息;其中一个信息来源就是 Michael Fogus 的博客,他已经发布了关于编译器系列文章的第一部分。Michael 从事于ClojureScript 实现。对编译器内部机制感兴趣的开发者们还应该看看 ClojureScript 开发说明,上面列出了很多信息,比如 ClojureScript 语言结构及其转换而成的 Javascript 结构。

Clojure 社区已经开始尝试 ClojureScript 了。Brian McKenna已经开始尝试使用宏来与回调地狱(callback hell)展开斗争,这指的是异步I/O 的每个操作都需要提供一个回调来接收操作的结果——这么做一两次还行,但对于连续的算法来说实在过于冗长了。在JS 世界中有不少解决方案在尝试解决这个问题,从新的语言如 StratifiedJS 使用Javascript 编写的嵌入式DSL 库

Brian 混合使用了嵌入式 DSL 解决方案与 ClojureScript,就像是带有宏的 LISP 一样,效果不错。试验处理了一系列的表达式并将其编译为嵌套的回调,每个回调都在序列中执行一个表达式,然后通过 setTimeout 调度序列中其他回调的执行。这不禁让人想起了支持 Monads(Haskell 的 do 符号)的语言或是 F#的 Compuational Expressions( Async Workflows )的程序分号方式。接下来将会支持更多的结构化程序设计概念,如循环,使用宏将其转换为这种连续的传递形式。

Justin Grant 的一篇博文介绍了如何实现一个算法并使用Google Closure 的Canvas 支持来绘制图像

ClojureScript 位于 GitHub。要想了解更多信息,请查看clojure.com 上的ClojureScript 声明,或是 GitHub 上的 ClojureScript Wiki ,上面有大量的信息,包括 ClojureScript 的基本原理快速起步指南等内容。 Clojure 邮件列表也是个不错的信息来源,你可以从中了解到 ClojureScript 的使用方式,社区也在上面讨论开发工作流、工具等信息。

查看英文原文: ClojureScript Brings Clojure To The Browser via Javascript

2011-08-01 02:115020
用户头像

发布了 88 篇内容, 共 268.3 次阅读, 收获喜欢 8 次。

关注

评论

发布
暂无评论
发现更多内容

数据结构与算法之间有何关系?

不在线第一只蜗牛

数据结构 算法

AI赋能美好生活,OpenVINO™技术成果助力多领域发展

E科讯

谷歌发布新 RL 方法,性能提升巨大;苹果前设计总监正与 OpenAI 合作开发 AI 设备丨 RTE 开发者日报

声网

BOE(京东方)携故宫博物院举办2024“照亮成长路”公益项目落地仪式以创新科技赋能教育可持续发展

科技汇

Facebook养号与推广技巧

Ogcloud

facebook 云手机 海外云手机 FB推广 FB引流

参与滴滴开源项目,获得精美礼品

XIAOJUSURVEY

GitHub 开源 活动 PR Issue

软件项目全套资料、全方案、源码梳理清单

金陵老街

开发文档 软件文档 实施文档 运维文档

海外云手机解决IP、成本、稳定性问题

Ogcloud

云手机 海外云手机 云手机海外版 海外原生IP 海外IP

漆包线工厂生产管理MES系统功能介绍

万界星空科技

mes 万界星空科技 漆包线mes 铜线mes 漆包线

中国可观测日「成都站」圆满落幕

观测云

可观测性

大咖领衔,2天AI创业创收训练营即刻启程!不要错过,速来占位!

霍格沃兹测试开发学社

一位架构师的自述:在尚未踏入的世界成为你自己

京东科技开发者

“数据思维人才培养论坛” 于大湾区大学举行,和鲸科技受邀共话产教创新路径

ModelWhale

人工智能 大数据 人才培养 高等教育

中文区块链媒体自媒体哪些发起来最有性价比?(非权威勿喷)

区块链项目一站式包装孵化

总裁,这是一份覆盖50家媒体的区块链发文套餐,请您收下!

区块链项目一站式包装孵化

NetFlow Analyzer:精准流量洞察,引领网络安全新纪元

Geek_a83400

【XIAOJUSURVEY& 北大】实现数据导出的前后端全流程

XIAOJUSURVEY

数据分析 Vue Node 问卷 数据导出

如何确定性能测试指标

老张

软件测试 性能测试 技术指标 高性能高可用

Yihong,从多元职业到代码之路 | MarsCoders 开发者说

Trae

Python 人工智能 编程 程序员 AI

《中国移动算力网络数据库白皮书》正式发布,NineData叶正盛分享

NineData

数据库 中国移动 叶正盛 NineData 算力网络数据库白皮书

如何免费调用有道翻译API实现多语言翻译

幂简集成

翻译软件 API

【理论篇】关于聚合根,领域事件的那点事---深入浅出理解DDD

京东科技开发者

mac苹果电脑游戏推荐:暗黑2:毁灭之王 for Mac(含各职业存档)

你的猪会飞吗

Mac游戏下载 Mac游戏推荐

BPM(业务流程管理)的最佳开源工具

NocoBase

开源 项目管理 低代码 BPM 无代码

精彩回顾|博睿数据Bonree ONE 3.0产品发布会圆满落幕:三城联动 共襄盛举!

博睿数据

SaaS业务架构:业务能力分析

不在线第一只蜗牛

架构 SaaS

座无虚席!首期流程挖掘实践训练营火爆收官

望繁信科技

数字化转型 流程挖掘 流程资产 流程智能 望繁信科技

ClojureScript通过Javascript将Clojure引入到浏览器端_Java_Werner Schuster_InfoQ精选文章