Lisp与JAVA的酷毙结合——abcl
最近看了一本叫做《黑客与画家》的书,其中对于Lisp语言大加褒奖。自己试着用了一下,虽然确实有反人类之嫌,但是确实是一门不错的语言,New Architect杂志上有一篇介绍ITA软件公司的文章,里面说"一行Lisp代码相当于20行C代码"。Lisp的强大,从中就可见一斑了。另外,Lisp还有理论上最高的计算能力。还有一个笑话是这么讲的:“任何C或Fortran程序复杂到一定程度之后,都会包含一个临时开发的、不合规范的、充满程序错误的、运行速度很慢的、只有一半功能的Common Lisp实现。"
但是Lisp是一种解释性语言,不能直接执行。所以,将其嵌入一个稳定的框架是个不错的选择。Java与Lisp就可以这样整合,其接口有很多,但我认为abcl(Armed Bear Common Lisp)是最好的选择,这个接口的性能表现是我觉得最优的。与其说它是一个接口,不如说是一个JAVA上的Common Lisp实现。本文将分两部分讲述,其一是怎么在JAVA里调用Lisp,其二是怎么在Lisp里调用JAVA,这有助于提高Lisp的扩展性。
Part One 在JAVA里用Lisp:
首先要安装abcl。在abcl官网下载其binary版本。解压出abcl.jar后,把它移动到jdk\lib目录下。并在环境变量CLASSPATH后加上一段话:%JAVA_HOME%\lib\abcl.jar(假设JAVA_HOME已经设置,指向jdk目录)。这样,abcl就算是安装好了。(与那些需要编译的C++库,安装过程简直太简单了,--我不是在吐槽boost!)
安装完毕后,就可以使用此接口了。在JAVA里用Lisp时,通常不把Lisp源码硬编码在JAVA程序中,而是另外建一个.lisp文件,在其中写上一些函数。这样易于修改,也不会致使你的JAVA源代码又臭又长!(想象一下,把Lisp源码以行为分割,打在方法的参数里,程序实在是太美观了)要加载外部的Lisp程序,可以这么做:
Interpreter interpreter = Interpreter.createInstance();
interpreter.eval("(load \"my-lisp-code.lisp\")");
“my-lisp-code.lisp”是外部lisp文件的文件名。那么加载后,怎么调用这段Lisp代码中的程序呢?首先,我们要得到一个abcl的Package:
org.armedbear.lisp.Package defaultPackage = Packages.findPackage("CL-USER");
在这个package里,我们要寻找Lisp代码中的函数,假设该函数叫做lispfunction,那么,代码应该这样写:
Symbol myFunctionSym=defaultPackage.findAccessibleSymbol("LISPFUNCTION");
根据这个Symbol对象,我们可以创建一个Fucntion对象并且运行,这里假设目标函数没有输入参数:
Function myFunction=(Function)myFunctionSym.getSymbolFunction();
myFunction.execute();
如果有参数呢?只要在execute中类似正常函数传参的方式,按次序写入参数即可。但要注意的是,不能直接填写,而要new一个JavaObject后传入,且Lisp代码中要用(jobject-lisp-value x)来转换。
如果又返回值呢?execute本来返回一个LispObject,可以通过其各种成员方法转换成相应的类型。
下面给出一个官方提供的例子,实现两个数的加法运算:点此下载
Part Two 在Lisp里用JAVA:
第一步依然是安装。提前声明:而且本部分的内容基于Part One。
通常的实现模式是按上面的方法在JAVA里调用Lisp,并且传入一个类。在Lisp里,通过一系列的转换,然后就可以调用了。
这里主要讲Lisp里的代码实现,JAVA部分只要写好函数,然后还需要在调用过程里这么写:
myFunction.execute(New Class1());
这就是传入的参数了,是一个类的实例。例如这个类有一个成员函数:addTwoNumbers(a,b)——表示两个数相加的和,a与b均为int类型,返回值也是int类型。传入后,在Lisp部分应该这么写(传入的参数为param):
- (let* ((class (jclass "Main"))
- (intclass (jclass "int"))
- (method (jmethod class "addTwoNumbers" intclass intclass))
- (result (jcall method param 2 4)))
- (format t "in void-function, result of calling addTwoNumbers(2, 4): ~a~%" result)))
其实很简单,在使用时,可以遵循此模式,先转换JAVA中的类型,再计算。
给出官方提供的例子代码:点此下载
附录:
这里讲些题外话,像abcl的运行速度,其他的Lisp->JAVA接口及如何打开abcl并把其作为一个外部独立运行的实现以学习Lisp的方法.
速度:许多Lisp用户就是奔着它有着理论上最高的运行速度去的。根据实验测试发现,其运行时间分两部分,分别是预载和实际计算。获取解释器实例(预载)时比较慢,命令行下为5-6s,Eclipse下更长。实际计算时间倒是在可以接受的范围内。
独立外部实现:下载了abcl.jar并且安装后,可以这样来运行它,将其作为一个外部的解释器——学习Lisp:
java -jar abcl.jar
另外的Lisp->JAVA接口现在概括如下:
1.abcl不支持Android,但目前仍在持续开发中,不排除2.0版本会对Android进行支持。
2.ecl支持Android,看github上的进度很久没有commit了,所以不建议优先考虑,但是这个接口还支持C语言。
3.clojure的Android支持性比较好,有nightcode这个集成的IDE,而且比较流行。
4.mocl,一个收费的common lisp的Android接口,具体性能也无法评定。
后记:
因为要期中迎考与本人较懒的缘故,本文后两部分写的较为粗略。可能无法从中清晰地了解到我所想讲述的。如果有什么疑问,可以评论或短消息我,我会竭尽所能地帮助。
Lisp与JAVA的酷毙结合——abcl的更多相关文章
- C,C++,Lisp,Java,Perl,Python
(译注:圣经记载:在远古的时候,人类都使用一种语言,全世界的人决定一起造一座通天的塔,就是巴别塔,后来被上帝知道了,上帝就让人们使用不同的语言,这个塔就没能造起来. 巴别塔不建自毁,与其说上帝的分化将 ...
- lisp学习总结(二)-----lisp应该探索发展的方向
现在流行一种语言叫做Clojure,他是lisp直接嫁接到java的结果,但是我就感觉这却成为lisp的失败. 因为lisp最强大最有优势的能力是构造抽象,构造设计思想,而不是运行期以确定的方式运行, ...
- Automake
Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...
- 【转】人工智能(AI)资料大全
这里收集的是关于人工智能(AI)的教程.书籍.视频演讲和论文. 欢迎提供更多的信息. 在线教程 麻省理工学院人工智能视频教程 – 麻省理工人工智能课程 人工智能入门 – 人工智能基础学习.Peter ...
- python 面向对象设计思想发展史
这篇主要说的是程序设计思想发展历史,分为概述和详细发展历史 一,概述 1940年以前:面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的 指令和数 据.简单来 ...
- history program(language)
1950与1960年代 有三个现代编程语言于1950年代被设计出来,这三者所衍生的语言直到今日仍旧广泛地被采用: Fortran (1955),名称取自"FORmula TRANslator ...
- (转)A curated list of Artificial Intelligence (AI) courses, books, video lectures and papers
A curated list of Artificial Intelligence (AI) courses, books, video lectures and papers. Updated 20 ...
- Python 入门基础1 --语言介绍
本节目录: 一.编程语言介绍 二.python解释器介绍 三.安装python解释器 四.运行python程序的两种方式 五.变量 六.后期补充内容 一.编程语言介绍 1.机器语言: 直接用二进制编程 ...
- Can you share some Scala List class examples?
Scala List FAQ: Can you share some Scala List class examples? The Scala List class may be the most c ...
随机推荐
- Android开发中常用的Eclipse快捷键
关闭所有窗口Ctrl + Shift + W 关闭所有已打开的编辑窗口 重命名Alt + Shift + R 文件或变量重命名(先选中文件或变量再同时按下快捷键) 快速引包Ctrl + Shi ...
- 框架中web.xml中配置文件解析
1.XSS指跨站脚本攻击 xss表示Cross Site Scripting(跨站脚本攻击),它与SQL注入攻击类似,SQL注入攻击中以SQL语句作为用户输入,从而达到查询/修改/删除数据的目的,而在 ...
- IDF实验室-简单编程-特殊的日子 writeup
题目:http://ctf.idf.cn/index.php?g=game&m=article&a=index&id=50 题目提示要爆破,代表加密应该是不可逆的. 密文:4D ...
- SpringMVC学习 DispatcherServlet (转载)
3.1.DispatcherServlet作用 DispatcherServlet是前端控制器设计模式的实现,提供spring Web MVC的集中访问点,而且负责职责的分派,而且与Spring Io ...
- Sql Server问题集锦
Sql数据库默认实例和命名实例的区别: 1.服务中服务名称的区别: 默认实例:MSSQLSERVER; 命名实例:实列名为:benet,在服务中的名称是:MSSQL$BENET; 注:如果你有多个 ...
- Win8 安装Oracle 10g 提示“程序异常终止”的解决方案
这段时间在做DRP,需要安装Oracle 10g的数据库,我的系统是win8企业版,安装Oracle 10g的时候,选择“高级安装”,提示“程序异常终止”,下面是几个解决方案,跟大家分享一下. 错误提 ...
- Mac Pro更换SSD后,在Win7下启用ACHI的方法AHCI
在Mac Pro下更换SSD后,如果安装Win7,要将SSD改为AHCI模式是非常麻烦的.本文介绍如何将Mac的Win7下的SSD改为AHCI方式驱动,及几种常见问题的处理. 一.当Lion与Win7 ...
- [AngularJS - app] AngularJS Location-picker app
From: http://rangle.io/blog/two-ways-to-build-a-location-picker-for-a-mobile-angularjs-application/ ...
- 打开已存在 Android项目及常见的问题
Eclipse 打开已存在 Android项目及常见的问题 1. 点击菜单“File”-- "Import",会弹出 Import 对话框: 2, 选择“General ...
- uboot中gd的定义和使用
近期在做uboot中nand启动相关的工作,遇到一个问题一直纠结着.如今最终明确了这个问题,想想还有好多兄弟在某个黑暗的角落里或者某台电脑前纠结着呢,所以赶紧写下来以供查阅. uboot versio ...