写点什么

LispyScript:让 JavaScript 支持宏!

  • 2015-06-11
  • 本文字数:1215 字

    阅读完需:约 4 分钟

与其它类 Lisp 语言不同,不支持宏是 JavaScript 与生俱来的一个问题,这是因为宏会在编译时操作语法树,而这在像 JavaScript 这样的语言中几乎是不可能的。 LispyScript 是一种采用 Lispy 语法、支持宏的 JavaScript 实现。

在 LispyScript 中,开发者以树形结构编写 JavaScript 代码。只要了解 JavaScript 和类 Lisp 语言,就可以轻松使用 LispyScript。即使不了解类 Lisp 语言,也只需要学习如何以树形结构编写代码。

下面是 LispyScript 中 Hello World 的示例代码:

复制代码
(console.log "Hello LispyScript!")

如上所示,LispyScript 由括号中的表达式组成。表达式的第一个元素是一个函数或者 LispyScript 关键字。由空格分割的其它元素为函数的参数。可以看出,LispyScript 可以直接使用 JavaScript 函数。所有的 JavaScript 函数、对象和常量都可以用在 LispyScript 中。

Lispy 宏语法如下:

复制代码
(macro name (arguments expression) (template expression))

开发者可以通过往代码中增加宏来扩展 LispyScript。比如,下面的代码可以为 LispyScript 增加类似 JavaScript console.log 函数的 print 表达式:

复制代码
(macro print (str rest...) (console.log ~str ~rest...))

下面是该宏的其中两种调用方式:

复制代码
(print "Hello print macro!")
(print "2 + 2 = %d" (+ 2 2))

这就是宏的强大之处。开发者可以对语言本身进行扩展,或者创建自己的领域专属语言。

除了支持宏外,LispyScript 还支持如下特性:

  • 尾调用优化;
  • 回调序列:避免嵌套回调;
  • Monads:允许开发者分步处理数据;
  • 服务器端和浏览器端 REPL;
  • 内置测试特性:允许开发者在开发过程中测试代码。

LispyScript 0.3.0 及更高版本仅支持 IE9 及更高版本。但编译生成的 JavaScript 代码兼容所有的现代浏览器。LispyScript 可以直接在浏览器中运行。不过,其运行速度要逊于加载服务器预编译生成的 JavaScript。

有关 LispyScript 的更多信息,请查看项目文档 GitHub 页面

下面是 Hacker News 上的一些观点

网友 grayrest 指出,JavaScript 不是没有宏支持,而只是没有原生宏支持, sweet.js 就是证明。但 sweet.js 出现的时间要晚一些。aidenn0 提到了 Parenscript 。该项目通过 Common Lisp 为 JavaScript 提供宏功能。breuleux 提到了 Earl Grey 项目。他指出,该项目的宏系统是模块化的,宏库的编写和发布非常方便。同时,他认为,类 Lisp 语法并不是宏系统必须的。evmar 则自己维护着一个非常相似的项目。讨论还提到了其它项目,如 spock Sibilant 等。

另外,lispm 认为,LispyScript 的函数、宏和语法都不像 Lisp,而更像 Clojure 。gjm11 也有类似观点,认为 LispyScript 与 Lisp 的关系正如 JavaScript 与 Java 的关系,它们是完全不同的语言。


感谢魏星对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-06-11 04:332776
用户头像

发布了 1008 篇内容, 共 388.1 次阅读, 收获喜欢 344 次。

关注

评论

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

电商平台微服务架构

Jack

架构实战训练营9期

架构模块六-作业

许四多

MobPush for Flutter

MobTech袤博科技

「Go实战」记一次降低30%的CPU使用率的优化

Go学堂

golang redis 程序员 个人成长 11月月更

【Node.js 】开发中遇到的多进程‘keylog‘ 事件以及TLS/SSL的解决学习方案实战

恒山其若陋兮

前端 11月月更

一文熟悉 Go 的循环结构 —— for 循环

陈明勇

Go golang for 11月月更 for-range

2022-11-27:超过经理收入的员工。编写一个SQL查询来查找收入比经理高的员工。以下数据的结果输出是Joe,因为Joe是唯一挣得比经理多的雇员。 DROP TABLE IF EXISTS `em

福大大架构师每日一题

MySQL 数据库 福大大

ubuntu部署ELK-三节点

忙着长大#

ELK

企业级项目开发中的交互式解释器以及global全局定义、Stream流的合理运用和实战【Note.js】

恒山其若陋兮

前端 11月月更

云原生下日志采集的3种方式

穿过生命散发芬芳

11月月更 云原生日志采集

【web 开发基础】PHP自定义回调函数之call_user_func_array() (36)

迷彩

回调函数 web开发基础 11月月更 call_user_func_array 自定义回调函数

「Go实战」基于Prometheus+Grafana搭建完整的监控系统

Go学堂

golang 程序员 个人成长 监控 11月月更

在使用Note.js的过程中对于tty对于终端的运用、加密模块以及Assert的事件驱动程序的深入运用理解

恒山其若陋兮

前端 11月月更

项目经理和Scrum Master之间的不同(译)

Bruce Talk

Scrum 敏捷开发 Agile

C++学习---类型萃取---is_function

桑榆

C++ STL 11月月更

CDH5部署三部曲之二:部署和设置

程序员欣宸

大数据 hadoop 11月月更

运维进阶训练营 -W05H

赤色闪电

运维

分布式锁:不同实现方式实践测评

闫同学

Go 分布式 后端 分布式锁 11月月更

架构实战营模块6作业-拆分电商系统为微服务

冷夫冲

架构 「架构实战营」

Maven 如何配置推送的仓库

HoneyMoose

跳板机逐渐被堡垒机替代的最主要原因是这个!

wljslmz

运维 堡垒机 跳板机 11月月更

【web 开发基础】PHP类静态函数和对象方法的回调 (37)

迷彩

对象 回调函数 11月月更 静态方法 成员方法

ELK 各组件功能及Elasticsearch 的节点角色类型介绍

忙着长大#

ELK

发布MagicOS 7.0, 荣耀如何打造“松弛感”的操作系统?

脑极体

防火墙是网络安全的第一道防线,你认同吗?

wljslmz

网络安全 防火墙 11月月更

【web 开发基础】PHP回调函数之变量函数 (35)

迷彩

php 回调函数 11月月更

浅谈MySQL Binlog日志

闫同学

MySQL 数据库 Binlog 11月月更

电商微服务架构图

Johnny

架构实战训练营9期

关于登录框的渗透测试

网络安全学海

网络安全 安全 信息安全 渗透测试 漏洞挖掘

极客时间运维进阶训练营第五周作业

Starry

Mobtech短信验证 for Flutter

MobTech袤博科技

LispyScript:让JavaScript支持宏!_JavaScript_谢丽_InfoQ精选文章