最近看了一本叫做《黑客与画家》的书,其中对于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的更多相关文章

  1. C,C++,Lisp,Java,Perl,Python

    (译注:圣经记载:在远古的时候,人类都使用一种语言,全世界的人决定一起造一座通天的塔,就是巴别塔,后来被上帝知道了,上帝就让人们使用不同的语言,这个塔就没能造起来. 巴别塔不建自毁,与其说上帝的分化将 ...

  2. lisp学习总结(二)-----lisp应该探索发展的方向

    现在流行一种语言叫做Clojure,他是lisp直接嫁接到java的结果,但是我就感觉这却成为lisp的失败. 因为lisp最强大最有优势的能力是构造抽象,构造设计思想,而不是运行期以确定的方式运行, ...

  3. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

  4. 【转】人工智能(AI)资料大全

    这里收集的是关于人工智能(AI)的教程.书籍.视频演讲和论文. 欢迎提供更多的信息. 在线教程 麻省理工学院人工智能视频教程 – 麻省理工人工智能课程 人工智能入门 – 人工智能基础学习.Peter ...

  5. python 面向对象设计思想发展史

    这篇主要说的是程序设计思想发展历史,分为概述和详细发展历史 一,概述 1940年以前:面向机器 最早的程序设计都是采用机器语言来编写的,直接使用二进制码来表示机器能够识别和执行的 指令和数 据.简单来 ...

  6. history program(language)

    1950与1960年代 有三个现代编程语言于1950年代被设计出来,这三者所衍生的语言直到今日仍旧广泛地被采用: Fortran (1955),名称取自"FORmula TRANslator ...

  7. (转)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 ...

  8. Python 入门基础1 --语言介绍

    本节目录: 一.编程语言介绍 二.python解释器介绍 三.安装python解释器 四.运行python程序的两种方式 五.变量 六.后期补充内容 一.编程语言介绍 1.机器语言: 直接用二进制编程 ...

  9. 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 ...

随机推荐

  1. DS18B20 for STM32 源代码 【worldsing笔记】

    DS18B20是DALLAS公司生产的一线式数字温度传感器,具有3引脚TO-92小体积封装形式:温度测量范围为-55℃-+125℃,可编程为9位-12位A/D转换精度,测温分辨率可达0.0625℃.主 ...

  2. C#模仿360安全卫士玻璃按钮,不闪烁,背景切换效率快

    首先先上效果图: 1.准备两张透明的png图片(尺寸74 x 82),一张用于鼠标进入控件时显示,一张用于鼠标单击控件时显示 2.拖一个GlassButton按钮 3.设置按钮属性 this.btnE ...

  3. sublime Text 3的默认快捷键大全

    Ctrl+M 光标跳至对应的括号 Alt+. 闭合当前标签 Ctrl+Shift+A 选择光标位置父标签对儿 Ctrl+Shift+[ 折叠代码 Ctrl+Shift+] 展开代码 Ctrl+KT 折 ...

  4. virtualbox 创建com对象失败

    其实这个错误是因为VirtualBox不兼容Win7引起的,只要把VirtualBox的兼容模式改为出Win7以外的就行了.. 右键VirtualBox的桌面快捷方式,选择属性,选到兼容性选项卡,勾选 ...

  5. mysql select 报错

    代码片段: sql_url = "select * from webpage where url = '%s'" % b try: cursor.execute(sql_url) ...

  6. 3、VS2010+ASP.NET MVC4+EF4+JqueryEasyUI+Oracle项目开发之——用户登录

    近期因为项目赶着上线,一直没时间接着写博客,今天最终空出了时间.声名:我不是专业美工,所以界面问题,希望大家不要拍砖.登录界面例如以下: 在ASP.NET MVC中,要新增一个功能,我们首先要加入一个 ...

  7. (DP6.1.2.1)UVA 147 Dollars(子集和问题)

    /* * UVA_147.cpp * * Created on: 2013年10月12日 * Author: Administrator */ #include <iostream> #i ...

  8. careercup-C和C++ 13.7

    13.7 写一个函数,其中一个参数是指向Node结构的指针,返回传入数据结构的一份完全拷贝. Node结构包含两个指针,指向另外两个Node. C++实现代码: typedef map<Node ...

  9. 关于Android模拟器键盘不能使用的解决方法

    很多朋友遇到一个问题,自己搭建完了Android环境后,启动模拟器体验Android系统,但是发现不能使用键盘方便的输入内容,如下图: 同时,使用笔记本的键盘也无法输入内容,只能通过模拟器内置的输入法 ...

  10. cxf

    一,cxf webService入门案例 1,jar包 注意版本 使用jdk6和apache-cxf-3.1.2,但cxf-3.1.2已经不支持jdk6,需要jdk7以上 版本用错会报java.lan ...