`
iyuan
  • 浏览: 471808 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

lisp初体验-Practical Common Lisp笔记-5.迷你数据库-下

    博客分类:
  • lisp
阅读更多
注意:如果你是初学者,甚至都没有其他任何语言基础,那么此篇,即<迷你数据库下>,可以略过,作为前两篇(上、中)的总结、优化,固然很强大,但个人感觉极有可能把初学者带到沟里去,这里涉及到一些较深的东西,并且作者没有给出详解(一如既往的"后面篇章会有的")。so,阅读需谨慎,此篇可跳过~

好吧,如果上面的红字没有能够阻止你的话,就让我们开始。

让你的代码变得更简洁

虽然之前的数据库也算基本可用了,不过明眼人估计都看出来有很多代码冗余的存在,比如where中的这句:
(if title (equal (getf cd :title) title) t)

在功用上,为了能够匹配所有情况而不得不每一次都做多重判定(浪费了效能),在代码上,除了关键字的区别外,根本是一个模子啊,那么为什么不就用同一个模子来做呢。
咱的期望是,如果要如此查找:
(select (where :title "Give Us a Break" :ripped t))

那么实现的代码最终看起来便是这个样子:
(select
 #'(lambda (cd)
     (and (equal (getf cd :title) "Give Us a Break")
          (equal (getf cd :ripped) t))))

只判断提供的东西。
其实,用lisp是非常容易达到这个目标的,不过这里就得涉及到lisp中的大杀器"宏"了,之前曾经简单解释成"当成公用函数",事实当然并非如此。宏即是宏,函数即是函数(有点绕)。不过在lisp中使用方式倒是差不多。目前也只需要知其形,至于意么,就见仁见智了~
跳出数据库,在这里简单建个宏,用用看:
(defmacro backwards (expr) (reverse expr))

宏和函数的定义关键字是不同的。这里reverse是自带宏,作用是:
(reverse '(1 2 3)) ==> (3 2 1)

用下咱写的宏:
(backwards ("hello, world" t format))

结果:
hello, world
NIL

是不是理解这个宏的用法了,此宏将lisp语法逆向了,如果你尝试下定义同样功能的函数,按照宏的使用方法时会报错的(不信你试试)

跳回数据库,如果where语句中冗余的那段可以缩略成:
(equal (getf cd field) value)

貌似,就解决了之前的瑕疵,那么试试看:
(defun make-comparison-expr (field value) 
  (list equal (list getf cd field) value))

似乎有些问题,修缮下:
(defun make-comparison-expr (field value)
  (list 'equal (list 'getf 'cd field) value))

多了一些单引号('),意思是,仅随其后的东东不要执行,就当作字符串。试试:
*(make-comparison-expr :rating 10)
(EQUAL (GETF CD :RATING) 10)

结果似乎又是一个Lisp语句,这里就涉及到lisp的终极奥义了:自己生产代码并执行(一如既往的,这是后话了)。
如果你想要实现一段部分实现的代码,那么似乎有些麻烦,lisp也想到了:
'(1 2 (+ 1 2))        ==> (1 2 (+ 1 2))
`(1 2 (+ 1 2))        ==> (1 2 (+ 1 2))
`(1 2 ,(+ 1 2))       ==> (1 2 3)

注意:第一行的那个是单引号('),而下面两行是背引号(`),在键盘位置的左上角ESC按钮下面一个位置,它的右边就是感叹号、1,想要部分实现代码的时候,在实现部分前加上逗号就可以了。
下面把之前的函数变异一下:
(defun make-comparison-expr (field value)
  `(equal (getf cd ,field) ,value))

在外层包一层循环体:
(defun make-comparisons-list (fields)
  (loop while fields
     collecting (make-comparison-expr (pop fields) (pop fields))))

现在,可以将我们的where函数升级成宏:
(defmacro where (&rest clauses)
  `#'(lambda (cd) (and ,@(make-comparisons-list clauses))))

先来解释下",@"组合的用处:将后面的执行结果向上并入
`(and ,(list 1 2 3))   ==> (AND (1 2 3))
`(and ,@(list 1 2 3))  ==> (AND 1 2 3)
`(and ,@(list 1 2 3) 4) ==> (AND 1 2 3 4)

而这里的"&rest"与"&key"类似,&key是只接受定义好的":abc"这种东东,而&rest则是接受任意传入并且组成列表list,例如:
(where :title "Give Us a Break" :ripped t)

参数会被组织成这样:
(:title "Give Us a Break" :ripped t)

好不容易写好的东西,应该试下:
* (select (where :title "Give Us a Break" :ripped t))
((:TITLE "Give Us a Break" :ARTIST "Limpopo" :RATING 10 :RIPPED T))

看样子工作的不错,而且代码没有重复了,最重要的是,似乎,这不单单适用于cd/music数据库了,更高层次的抽象大大拓宽了它的适用范围。

这里有给出一些宏和函数的区别:宏的抽象层次要比函数高,使得宏更具有普适性,恰如这里的where。

迷你数据库算告一段落了,当然,作为迷你版,它还有很多欠缺,这自有后话。作者终于承认了他在hello完world后就搞出这么个章节的动机了:hello world实在太小儿科了,都不足以彰显lisp的牛X。这~

(未完待续)
0
0
分享到:
评论

相关推荐

    Practical Common Lisp-1st-2005

    《Practical Common Lisp-1st-2005》是一本专注于Common Lisp编程语言的实用书籍,作者Peter Seibel通过这本书向读者展示了如何使用Common Lisp来解决真实世界中的问题,强调程序员作为工程师和艺术家的双重身份,而...

    common-lisp-the-language-second-edition.PDF

    common-lisp-the-language-second-edition.PDF

    Practical Common Lisp笔记

    《Practical Common Lisp笔记》是一本深入探讨Common Lisp编程语言的实用教程。Common Lisp是一种功能强大的多范式编程语言,以其动态类型、宏系统和丰富的内置数据结构而闻名。这篇笔记详细记录了作者在学习过程中...

    cad-lisp-3-表操作.LSP.lsp

    cad-lisp-3-表操作.LSP.lsp

    Lisp - 1990 - Common Lisp the Language, 2nd Edition - Steele, Guy L..pdf

    《Common Lisp the Language, 2nd Edition》是Guy L. Steele所著的一本关于Common Lisp编程语言的权威指南,作为第二版,它不仅继承了前一版的经典,还对Lisp语言进行了深入的扩展和更新。这本书是Lisp爱好者的宝贵...

    emacs-lisp-intro-2.04.tar.gz

    标题中的"emacs-lisp-intro-2.04.tar.gz"是一个典型的压缩文件名,它表明这个文件是一个关于Emacs Lisp的介绍性资料,并且版本号是2.04,格式为tar.gz。tar.gz是一种在Linux和Unix系统中常用的文件压缩格式,它先用...

    实用Common.Lisp编程.pdf

    标题:“实用Common.Lisp编程.pdf” 描述:“实用Common.Lisp编程.pdf,2011.10出版” 从这些信息中,我们可以提炼出几个关键的知识点: ### Common Lisp语言简介 Common Lisp是一种高级的、通用的、多范式的编程...

    Practical Common Lisp pdf

    在压缩文件中,只有一个名为"practical_common_lisp.pdf"的文件,这是本书的PDF版本。由于原版PDF文件较大,经过7z压缩后,文件大小显著减小,便于下载和存储,但同时也能保持较好的图像和文字质量,满足读者的阅读...

    Successful Lisp How to Understand and Use Common Lisp - David B. Lamkins

    Provides practical advice for the construction of Common Lisp programs. Shows examples of how Common Lisp is best used. Illustrates and compares features of the most popular Common Lisp systems on ...

    AutoLisp源文件--标注高程.LSP

    AutoLisp源文件--标注高程.LSP

    ANSI Common Lisp 中文翻译版.pdf

    ANSI Common Lisp 中文翻译版.pdf 此资源是 ANSI Common Lisp 的中文翻译版,涵盖了 Common Lisp 语言的基础知识和高级主题。该资源包含了 17 章节,从基础的列表、特殊数据结构、控制流程、函数、输入与输出、符号...

    实用Common.Lisp编程

    这本《Practical Common Lisp》之所以号称Practical,正是因为这本书大量介绍Common Lisp在现实世界中的各种应用方式,算是第一本「入世传教」的Common Lisp著作。《Practical Common Lisp》是目前最畅销的Common ...

    practical common lisp.pdf

    1. **数据库开发**:Common Lisp可以通过多种方式与数据库交互,如使用SQL或特定的Lisp库来操作数据。 2. **单元测试框架**:书中介绍了一种用于编写测试用例的方法,并且展示了如何使用Common Lisp构建一个完整的...

    CommonLisp数据库

    CommonLisp 的简单而复杂的MP3 数据库,根据实用CommonLisp编程

    Practical Common Lisp

    Practical Common Lisp 学习lisp的入门书籍

    lisp小工具-fx.zip

    计算多个数字之和、计算多条线段长度之和、插入墙高标注、查询多段线顶点坐标并绘制、自动生成页码、绘制示坡线、插入排水箭头 https://blog.csdn.net/qq_24141055/article/details/121446354

    Lisp-music-player.rar_autolisp_autolisp程序_lisp_player

    标题中的“Lisp-music-player.rar”表明这是一个基于Lisp语言开发的音乐播放器软件,其源代码或可执行文件被压缩在RAR格式的文件中。RAR是一种流行的压缩格式,通常用于存储和分发多个文件,它允许用户将多个文件...

    Common-Lisp-Actors, 通用Lisp的actor系统.zip

    Common-Lisp-Actors, 通用Lisp的actor系统 这是一个简单且易于使用的Actor系统,在。设置需要波尔多螺纹。http://common-lisp.net/project/bordeaux-threads/ 2. 加载 actors.lisp 并开始使用它。 如果你有 Quick

    lisp解密程序-适用于早期的Lisp程序

    Lisp是一种古老而强大的编程语言,它以其独特的语法和哲学在计算机科学领域中占有一席之地。Lisp的全称是“List Processing”,意为列表处理,它的核心思想是使用S表达式(一种类似括号包围的数据结构)来表示代码和...

Global site tag (gtag.js) - Google Analytics