我试图通过添加《 Practical Common Lisp》一书中描述的选择函数来修改这个defstruct示例。我正在使用 Common Lisp 包在 Emacs 中运行代码。select -by-first不返回任何内容。在Lisp书中,作者没有使用defstruct,所以我必须需要做一些稍微不同的事情?
(defun按名字选择(名字)
(如果没有则删除
#'(lambda(员工)
(等于(getf员工:名字)名字))
*emp-db*))
(首先选择“史蒂夫”)
完整的程序:
(require 'cl)
;; http://mypage.iu.edu/~colallen/lp/node56.html
;; http://www.gigamonkeys.com/book/practical-a-simple-database.html
;;
(defvar *emp-db* nil)
(defun add-record (emp) (push emp *emp-db*))
(defstruct employee
age
first-name
last-name
sex
children)
(add-record (make-employee))
(add-record (make-employee
:age 34
:last-name 'farquharson
:first-name 'alice
:sex 'female))
(add-record (make-employee
:age 43
:last-name 'jobs
:first-name 'steve
:sex 'male))
(add-record (make-employee
:age 53
:last-name 'ballmer
:first-name 'steve
:sex 'male))
(defun select-by-first (first-name)
(remove-if-not
#'(lambda (employee)
(equal (getf employee :first-name) first-name))
*emp-db*))
(select-by-first "steve")
有一些基本的错误/问题。但只需进行两个小更改,我们就可以让您的示例在 Common Lisp 中运行。
Emacs Lisp 的 Common Lisp 兼容包并不是真正的 Common Lisp。通常最好使用真正的 Common Lisp 实现。Emacs Lisp 缺乏一些难以模拟以使其与 Common Lisp 兼容的基本功能 - 例如词法闭包(更新 2014,最新版本的 GNU Emacs 现在也支持词法闭包)。
小改动:我更改了您的示例,以便数据库不再包含史蒂夫·乔布斯两次,而是包含史蒂夫·乔布斯和史蒂夫·鲍尔默。
现在,我们需要更改什么才能使其在 Common Lisp 中运行?
(getf employee:first-name) 实际上应该是 (employee-first-name employee) 。DEFSTRUCT 宏自动生成这些访问器函数。在 Common Lisp 中,您无法使用 GETF 访问实际结构的字段。
您的数据库有两个名为 STEVE(符号)的对象,但您正在搜索名称“steve”(字符串)。(等于'steve“steve”)是错误的。一般来说,符号不等于字符串。因此,您应该使用 (select-by-first 'steve) 进行搜索。
在 LispWorks 中:
CL-USER 11 > (select-by-first "steve")
NIL
CL-USER 12 > (select-by-first 'steve)
(#S(EMPLOYEE :AGE 53 :FIRST-NAME STEVE :LAST-NAME BALLMER :SEX MALE
:CHILDREN NIL)
#S(EMPLOYEE :AGE 43 :FIRST-NAME STEVE :LAST-NAME JOBS :SEX MALE
:CHILDREN NIL))
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
923 次 |
| 最近记录: |