使用 Cusp Eclipse 插件开发 Lisp 应用程序

使用 Cusp Eclipse 插件开发 Lisp 应用程序

Lisp 不再只适用于人工智能 —— 试试它,您可能会用不同的方式思考 Java 和 C 编程

Tyler Anderson ([email protected] ), Freelance writer, *撰稿人

简介:  Lisp 是一种极好的编程语言,由于它具有很强的无类型特性,因此使您可以扩展编程语言知识。它还可以帮助那些拥有丰富的 Java™、PHP 或 C/C++ 等编程语言经验的人士在开发应用程序时用新的方式思考。此外,您可以用 Lisp 来实现一些很棒的操作。了解如何使用 Cusp Eclipse 插件来开发 Lisp 应用程序。

本文的标签:   eclipse插件

发布日期:  2007 年 11 月 26 日
级别:  中级
访问情况  1307 次浏览
建议:  0 (添加评论 )

使用 Cusp Eclipse 插件开发 Lisp 应用程序 使用 Cusp Eclipse 插件开发 Lisp 应用程序 使用 Cusp Eclipse 插件开发 Lisp 应用程序 使用 Cusp Eclipse 插件开发 Lisp 应用程序 使用 Cusp Eclipse 插件开发 Lisp 应用程序 平均分 (共 3 个评分 )

Cusp,Lisp 的 Eclipse 开发环境

Cusp 是 Common Lisp 编程语言的开发环境。使用 Lisp 可以开发所有类型的应用程序,包括 Web 应用程序。Lisp 是目前仍在使用的第二种最古老的编程语言(在 Fortran 之后)并被称为第一种函数语言。Lisp 的创建开始于二十世纪五十年代后期,并且于 1958 年由 MIT 人工智能 (AI) 项目首次实现。它的强大之处在于处理列表:AI 和符号数学。实际上,Lisp 是 “list processor” 的简写,正是出于对列表处理器的需求创建了这种编程语言,您将在稍后的段落中看到相关说明(有关 Lisp 的历史信息,请参阅 参考资料 )。

您将会发现 Lisp 与其他普通的编程语言根本不同。例如,在大多数普通编程语言中,执行乘法就像您在纸上作运算一样:int times = 5 * 5 ;。

使用 Lisp,将通过代码 (* 5 5 3) 得到 75。要获得此列表中的最大值,使用 (MAX 9 8 7 6 20) 将返回 20。

注意,这里所说的 “第一种函数语言” 十分贴切,因为一切都基于函数。每个函数都可以有若干数目不定的参数。使用递归和诸如 carcdr 之类的 Lisp 函数处理这些列表是使用 Lisp 处理列表的强大之处。

由于 Lisp 历史较久,因此您可以找到许多适用于 Lisp 的开发环境,但是,也存在旧编程语言固有的问题,工具支持大部分都是基于文本的,并且对于新手来说不够直观。因此,尝试使用 Cusp 的一个原因是它提供了供新手了解和开发 Lisp 的直观 GUI,而不使用基于文本的 “尝试记住所有这些命令” 类型的界面。它还比 Eclipse GUI 框架固有的 superb 项目管理功能更具优势。

继续之前,您需要从 Eclipse.org 下载最新的 Eclipse 标准包。然后了解如何安装和设置 Cusp。

回页首

安装 Cusp

现在应当有一个经过压缩的 Eclipse 标准包归档。请将其解压缩并运行 eclipse.exe。

要获得最新版本的 Cusp,请单击 Help > Software Updates > Find and Install 。单击 Search for new features to install 选项。现在单击 New Remote Site 按钮。键入名称 Cusp update site 和 URL http://www.sergeykolos.com/cusp/update ,然后单击 OK (参见图 1)。


图 1. 为 Cusp 输入远程站点信息
使用 Cusp Eclipse 插件开发 Lisp 应用程序

单击已添加的新远程站点旁边的复选框并单击 Finish (参见图 2)。


图 2. 选择 Cusp Eclipse Update Site
使用 Cusp Eclipse 插件开发 Lisp 应用程序

系统将显示另一个窗口,在该窗口中需要展开 Cusp Eclipse Update Site 并选择 Cusp,如下所示:


图 3. 选择要安装的功能
使用 Cusp Eclipse 插件开发 Lisp 应用程序

单击 Next 。然后阅读许可证协议并单击 I accept the terms in the license agreement 接受许可证协议,然后单击 Next 。确保选中所有库,如下所示,然后再次单击 Next


图 4. 选择可选功能
使用 Cusp Eclipse 插件开发 Lisp 应用程序

最后一个页面将显示要安装功能的安装汇总。单击 Finish 。插件及其组件将下载并安装。下载后,您将收到一则警告,表明将要安装一个未签名的功能。单击 Install all 。在安装结束时,系统将询问您是否要重新启动 Eclipse;请单击 Yes

您已经安装了 Eclipse Cusp 插件。接下来,将创建一个 Lisp 项目。

回页首

创建 Lisp 项目

在开始进行 Lisp 开发之前,必须先创建一个新的 Lisp 项目。您可以通过转到 File > New > Project 来完成此操作。展开 Lisp 文件夹,单击 Lisp Project ,然后单击 Next 。为新项目选择一个名称 my_new_lisp_project,如下所示,然后单击 Finish


图 5. 命名新 Lisp 项目
使用 Cusp Eclipse 插件开发 Lisp 应用程序

单击 Finish 后,将创建新项目并打开 Lisp 透视图,如下所示:


图 6. Lisp 透视图
使用 Cusp Eclipse 插件开发 Lisp 应用程序

查看 Lisp 透视图。Lisp Navigator 窗口显示打开的项目及其相关文件。Outline 窗口显示当前打开文件的概要。位于右上侧显示 main.lisp 的窗口是 Lisp 开发窗口。位于右下侧的窗口 REPL 是 Lisp 的命令行 Lisp 解析程序,您可以在这里运行 Lisp 命令。

如果关闭并重新打开 Eclipse,则需要装入项目的 .asd 文件,如下所示:


图 7. 装入 ASD 文件
使用 Cusp Eclipse 插件开发 Lisp 应用程序

注意,需要在 my_new_lisp_project 文件夹下的 my_new_lisp_project.asd 文件上右键单击,然后选择 Load asd 。这实际上就是在 REPL 窗口中编译 Lisp 项目,允许您输入可以使用新代码的 Lisp 命令。

接下来,将尝试使用 Cusp 进行一些 Lisp 开发。

回页首

使用 Cusp 进行 Lisp 开发

首先,还是定义并测试一个简单的自定义函数。打开 main.lisp 文件,并使用 defun (定义函数)命令,然后添加以下内容:

...
(defun first_howdy_function ()
  "howdy ho")

 

保存该文件。要从包中导出函数,请在 defpackage.lisp 中键入以下代码:

...
   ;; Exported symbols go here
  first_howdy_function
   ))
   

 

可以从包的外部使用该函数。要测试新函数,请在 REPL 中位置靠下的窗口中键入以下代码:(my_new_lisp_project:first_howdy_function)

注意,在您所处的范围内,这样做与输入 (my_new_lisp_project::first_howdy_function) 等效。如果未在 defpackage.lisp 中导出函数,则这是您必须键入的代码。

单击 Send ,然后查看输出。输入上面任意一条命令所得到的输出都是:

COMMON-LISP-USER>
(my_new_lisp_project:first_howdy_function)

"howdy ho"

 

您已经得到它了:第一个 Lisp Howdy 函数。

尝试为 echo 函数提供一个输入:

...
(defun first_echo_function (echoval)
  echoval)
  

 

同上一个函数一样,将其导出到 defpackage.lisp 中。在 REPL 窗口中位置靠下的部分中键入以下代码 (my_new_lisp_project:first_echo_function '("howd" "y h" "o")) 来测试这个 first_echo_function 。注意,'("howd" "y h" "o") 部分是用于定义列表的语法。首先,单引号必须放在括号之前,然后在括号内定义列表元素。输出如下所示:

COMMON-LISP-USER>
(my_new_lisp_project:first_echo_function '("howd" "y h" "o"))

("howd" "y h" "o")

 

您将创建一种分别处理每个列表元素的方法,这是 Lisp 的真正强大之处。定义如下:

(defmethod concat2 ((str1 string) (str2 string))
  (concatenate 'string str1 str2))

 

注意,以上方法实际上定义了一个类型字符串。到现在为止,您一直在使用 Lisp 作为一种大型的无类型语言。虽然双引号隐式地把数据类型定义为字符串,但是以上方法显式地把 concat2 函数的输入和输出类型定义为字符串。此方法还使用内置的 concatenate 函数把两个字符串组合在一起,并将其作为单个字符串返回。

要测试 concat2 ,请将其导出,然后键入 (my_new_lisp_project:concat2 "howd" "y ho") 。输出如下:


清单 7. 连接两个字符串的输出

                
COMMON-LISP-USER>
(my_new_lisp_project:concat2 "howd" "y ho")

"howdy ho"

 

完成。字符串 "howd""y ho" 变成 "howdy ho" 。现在您将使用两个著名的 Lisp carcdr 函数创建更通用化的 concatenation 函数。


清单 1. 连接列表中的三个元素

                
(defun concat3 (args_list)
  (concat2 (car args_list)
           (concat2 (car (cdr args_list))
                    (car (cdr (cdr args_list))))))

 

注,此函数仍使用 concat2 函数,但是使用参数列表作为输入。注意如何从 args_list 检索连接的各个部分。car 将从列表中获取第一个元素。cdr 将返回减去第一个元素的列表。只需对列表调用 car 函数就可以看到如何获得第一个元素。获得第二个元素要求对列表调用 cdr ,然后对新列表调用 car 。通过对列表两次调用 cdr 并对得到的列表调用 car 获取第三个元素。

导出后以上函数的输出为:

COMMON-LISP-USER>
(my_new_lisp_project:concat3 '("howd" "y h" "o"))

"howdy ho"

 

就是这样。已正确连接了三个字符串来生成 "howdy ho" 。接下来,创建递归函数。

回页首

使用 Lisp 递归

将要创建的最后一个函数要执行一些递归操作,这是使用 Lisp 进行列表处理的真正强大之处。迭代是可能实现的(逐个遍历所有条目),但是不同于诸如 Java 语言之类的普通语言,递归是到现在为止 Lisp 中处理列表的最简单方法。在本节的末尾,您将明确了解递归的含义。

首先创建递归的 concat 函数。


清单 2. 递归连接(无限制的参数)

                
1   (defun concat_recursive (args_list)
2     (if (equal (cdr args_list) nil)
3         (car args_list)
4         (concat2 (car args_list)
5                  (concat_recursive (cdr args_list)))))

 

递归是十分难于处理的概念,因此让我们一起来查看这个概念:

  • 假定将任意参数列表传递给上面的函数。
  • 如果列表中只有一个元素(第 2 行中的 (cdr args_list) 部分返回 nil),则返回单个元素(第 3 行中的 (car args_list) )。
  • 如果列表中有多个元素(意味着第 2 行中的 (cdr args_list) 部分未返回 nil),则返回使用 (cdr args_list) 的结果作为参数(参见第 5 行)连接(使用 concat2 )列表的第一个元素(参见第 4 行)与递归调用 concat_recursive 的结果的结果。

当传递列表 '("ho" "wd" "y" "h" "o") 作为参数时,下面是递归输出:

  • 第一次执行到第 2 行时,if 语句为 false,并用 "ho"(concat_recursive '("wd" "y" " h" "o")) 调用 concat2
  • 第二次执行到第 2 行时,if 语句又为 false,并用 "wd"(concat_recursive '("y" " h" "o")) 调用 concat2
  • 第三次执行到第 2 行时,if 语句又为 false,并用 "y"(concat_recursive '(" h" "o")) 调用 concat2
  • 第四次执行到第 2 行时,if 语句又为 false,并用 " h"(concat_recursive '("o")) 调用 concat2
  • 第五次递归结束。这是因为这一次,第 2 行中的 if 语句现在为 true,并且简单地返回了 "o" 。递归解开为:
    • 第四次:连接并返回 "h""o"
    • 第三次:连接并返回 "y""ho"
    • 第二次:连接并返回 "wd""y ho"
    • 第一次:连接并返回 "ho""wdy ho" 作为最终结果。

这时就完成了递归 —— "howdy ho" 最终被返回,如下所示:

COMMON-LISP-USER>
(my_new_lisp_project:concat_recursive '("ho" "wd" "y" " h" "o"))

"howdy ho"

 

已经将递归添加到了 Cusp 开发工具库中。接下来请尝试调试器。

回页首

使用 Cusp 进行调试

考虑输入条件可能会导致 concat_recursive 失败,因此调试器可能会派得上用场。一种情况是可以发送一个混有数字的字符串来查看会发生什么情况。记住,使用 concat2 进行连接要求使用两个字符串,因此数字将导致此函数在递归之间中断。

键入以下命令:(my_new_lisp_project:concat_recursive '("ho" "wd" "y" 55 " h" "o")) 。注意没有用双引号引起的数字 55 不是字符串并将导致显示调试器,如下所示:


图 8. 触发调试器
使用 Cusp Eclipse 插件开发 Lisp 应用程序

注意,触发调试器的主要错误是无法对列表 (55 " ho") 调用 concat2 。另请注意,在触发该错误之前已经连接了 "h""o"

在调试器窗口中,您还可以看到 ==Backtrace== ,如图 8 所示。调试器下部的每行(本例中为 0 至 19 行)给出了从单击 Send 到发生错误的详细跟踪。在这里,您还可以查看并跟踪在触发了错误的数字 55 之前的递归。

现在做什么?遇到上面的情况,您有三种选择退出调试器并修改和验证函数输入:可以中止命令并返回到正常的 REPL 窗口;可以关闭连接(通过测试发现,如果选择此选项,则需要重新引导 Eclipse 来重新启动 Lisp 处理器);可以简单地中止调试器并返回到正常的 REPL 窗口。退出调试器的最佳选项始终是中止命令并返回到正常的 REPL 窗口。

就是这样。您已经在 Lisp 中实现了递归函数。

回页首

结束语

您已经成功地使用 Cusp Eclipse 插件完成了 Lisp 开发。现在应当知道 Lisp 为什么如此强大。通过简单的递归语句,可以轻松地推动处理符号和数据列表。Cusp 为 Lisp 的功能补充了内置 Cusp 调试器、拥有项目管理功能的可靠 GUI、交互式 Lisp 编辑器以及可以输入命令和测试代码的 Lisp 处理器命令行接口。要获得更多信息,请一定要查看 参考资料