在编程的世界里,Lisp就像一位神秘的武术大师,教我们如何在代码与数据之间游刃有余。正如电影《功夫熊猫》中阿宝所学到的那样:「蜡在右手,蜡在左手,蜡在上,蜡在下」,每一个动作都是为了掌握更深的技巧。今天,我们就跟随Lisp的脚步,深入探讨全局变量和列表的奥秘。
🧙♂️ Lisp的神奇:代码即数据
Lisp的名字来源于「List Processing」,其核心思想就是通过列表来处理数据。你可以把Lisp视作一个魔法师,它允许你将代码视为数据,反之亦然。这种特性被称为「同构性」(homoiconicity),是其他编程语言所无法企及的。通过这种强大的能力,你将能够以独特的方式操控程序。
⚔️ 恶魔般的全局变量
在这个充满力量的世界中,全局变量就像是双刃剑,既能为你带来便利,也可能让你陷入危险的境地。全局变量的定义如下:
(defvar *symbol-for-global-variable* "optional initial value" "I LOVE DOC strings")
这里的*my-var*
是我们定义全局变量的惯例,耳罩样式的星号告诉我们:「小心!我有可能是个危险分子!」为什么说全局变量有「恶魔潜力」呢?因为你可以在任何函数中读取和修改它的值,甚至在REPL中也可以随意操作。这种特性让我们在某些情况下可以轻松实现功能,但在其他情况下却可能导致难以追踪的错误。
🔮 动态作用域
全局变量的另一个特性是「动态作用域」(Dynamic Scope),它就像是历史的奇妙扭曲,让「恶」变成了「善」。动态作用域允许你在函数中访问全局变量,这种设计理念虽然古怪,却为我们提供了强大的灵活性。
📜 列表的力量
在Lisp中,列表是数据的基本形式。你可以通过list
操作符来创建列表:
(list 1 2 3 4)
这将返回一个包含四个元素的列表 (1 2 3 4)
。但Lisp的魅力不仅于此,它的列表可以包含任何类型的对象:
(list 1 #\a "2" 'symbol-name #'print)
这将返回一个包含数字、字符、字符串、符号和函数的列表 (1 #\a "2" SYMBOL-NAME #<FUNCTION PRINT>)
。Lisp的列表就像是一个百宝箱,里面装满了各种各样的宝藏。
🚀 列表操作的多样性
Lisp提供了丰富的操作符,让我们可以对列表进行各种操作。例如,我们可以使用car
和cdr
来获取列表的第一个元素和剩余部分:
(car *mylist*) ; => 1
(cdr *mylist*) ; => (2 3 4 5)
这就像是打开一扇窗,透过它我们可以一览无余。更有趣的是,Lisp的列表操作是无副作用的,意味着我们在操作列表时不会改变原始数据。
🎩 赋值与修改
在Lisp中,setf
是一个强大的赋值操作符,它可以让你随意修改列表中的元素。比如,想把第二个元素改为99:
(setf (second *mylist*) 99)
这时,*mylist*
将变为 (1 99 3 4 5)
。就像魔法师挥动魔杖,瞬间改变了世界。
✨ 便捷的列表创建
如果你觉得使用list
创建列表太繁琐,可以通过单引号简化操作:
'(1 2 symbol-1 symbol-2 "a string")
这将返回相同的列表,而不需要额外的函数调用。这样一来,编写代码就像是在书写诗篇,优雅而简洁。
🌈 结论:Lisp的无限可能
Lisp以其独特的全局变量和强大的列表操作,为我们提供了无尽的编程可能。无论是定义全局变量,还是操作列表,Lisp都展现出其独特的魅力和灵活性。正如武术的每一个动作都蕴含着深刻的哲理,Lisp的每一行代码也都在诉说着编程的美妙。
在这个充满挑战与机遇的编程世界中,掌握Lisp的技巧就像是获得了无与伦比的力量。让我们继续探索,发现更多编程的乐趣吧!
面向记忆的学习材料
任务目标
快速学习并记住 Common Lisp 中关于全局变量和列表的相关知识
知识点: Lisp 的命名由来 知识点: Lisp 的同像性 知识点: 全局变量的命名约定 知识点: defvar 的特性 知识点: defparameter 的特性 知识点: defconstant 的用途 知识点: 列表的创建 知识点: car 和 first 函数 知识点: cdr 和 rest 函数 知识点: nth 函数 知识点: append 函数 知识点: reverse 函数 知识点: push 函数 知识点: pop 函数 知识点: 引用语法 知识点: setf 的通用性 知识点: 列表元素的修改 知识点: 列表的替换 本学习材料涵盖了 Common Lisp 中关于全局变量和列表操作的重要概念: 这些知识点构成了 Common Lisp 中处理全局变量和列表的基础。掌握这些概念将有助于理解和编写 Lisp 程序,特别是在处理数据结构和进行元编程时。建议读者多加练习这些操作,以熟练掌握 Lisp 的列表处理能力。 http://l1sp.org Common Lisp – The Tutorial Part 6.pdf https://github.com/rabbibotton/clog/blob/main/LEARN.md
题目: Lisp 的名称源自于哪个短语?
选项:
A. List Processing✅
B. Logic In Simple Programming✅
C. Language for Intelligent System Programming✅
D. Logical Instruction Set Programming✅
题目: Lisp 语言的哪个特性使得它可以将代码作为数据处理,反之亦然?
选项:
A. 动态作用域✅
B. 垃圾回收✅
C. 同像性✅
D. 函数式编程✅
题目: 在 Common Lisp 中,全局变量和参数通常使用什么命名约定?
选项:
A. 全部大写✅
B. 驼峰命名法✅
C. 下划线分隔✅
D. 星号包围(earmuffs)✅
题目: 使用 defvar 定义全局变量时,如果变量已存在,重新编译 defvar 语句会发生什么?
选项:
A. 变量值会被更新✅
B. 变量值保持不变✅
C. 会抛出错误✅
D. 变量会被重新创建✅
题目: defparameter 与 defvar 在重新编译时的主要区别是什么?
选项:
A. defparameter 不允许重新编译✅
B. defparameter 每次重新编译都会重新绑定值✅
C. defparameter 只能用于定义常量✅
D. defparameter 不支持文档字符串✅
题目: 在 Common Lisp 中,defconstant 的主要用途是什么?
选项:
A. 定义可变的全局变量✅
B. 定义不可变的常量✅
C. 定义局部变量✅
D. 定义函数✅
题目: 在 Common Lisp 中,下列哪个表达式不能创建列表 (1 2 3 4)?
选项:
A. (list 1 2 3 4)✅
B. ‘(1 2 3 4)✅
C. (quote (1 2 3 4))✅
D. (cons 1 2 3 4)✅
题目: 在 Common Lisp 中,car 和 first 函数的区别是什么?
选项:
A. car 用于获取列表的第一个元素,first 用于获取第二个元素✅
B. car 只能用于点对,first 只能用于列表✅
C. car 和 first 完全等价,没有区别✅
D. car 是低级操作,first 是高级抽象✅
题目: 对于列表 (1 2 3 4),调用 (cdr list) 会返回什么?
选项:
A. 1✅
B. (2 3 4)✅
C. (1 2 3)✅
D. 4✅
题目: 对于列表 (a b c d e),表达式 (nth 2 list) 会返回什么?
选项:
A. b✅
B. c✅
C. d✅
E. e✅
题目: 表达式 (append ‘(1 2) ‘(3 4)) 的结果是什么?
选项:
A. (1 2 3 4)✅
B. ((1 2) (3 4))✅
C. (1 2 (3 4))✅
D. (3 4 1 2)✅
题目: 对列表 (1 2 3 4) 调用 reverse 函数后,原列表会发生什么变化?
选项:
A. 列表变为 (4 3 2 1)✅
B. 列表保持不变✅
C. 列表变为 ((1 2 3 4))✅
D. 列表变为 (1)✅
题目: 如果 mylist 的值为 (2 3 4),执行 (push 1 mylist) 后,mylist 的新值是什么?
选项:
A. (2 3 4 1)✅
B. (1 2 3 4)✅
C. ((1) 2 3 4)✅
D. (1 (2 3 4))✅
题目: 如果 mylist 的值为 (1 2 3 4),执行 (pop mylist) 会返回什么,mylist 的新值又是什么?
选项:
A. 返回 1,✅mylist 变为 (2 3 4)
B. 返回 (1),✅mylist 变为 (2 3 4)
C. 返回 4,✅mylist 变为 (1 2 3)
D. 返回 (1 2 3 4),✅mylist 变为 nil
题目: 在 Common Lisp 中,'(1 2 symbol) 等价于以下哪个表达式?
选项:
A. (list 1 2 ‘symbol)✅
B. (quote (1 2 symbol))✅
C. (cons 1 (cons 2 (cons ‘symbol nil)))✅
D. (1 2 symbol)✅
题目: 以下哪个不是 setf 的有效用法?
选项:
A. (setf (car list) 10)✅
B. (setf (aref array 0) 20)✅
C. (setf (length list) 5)✅
D. (setf (gethash key hash-table) value)✅
题目: 如果 mylist 的值为 (1 2 3 4 5),执行 (setf (second mylist) 99) 后,mylist 的新值是什么?
选项:
A. (1 99 3 4 5)✅
B. (99 2 3 4 5)✅
C. (1 2 99 4 5)✅
D. (1 2 3 4 99)✅
题目: 执行 (setf mylist ‘(1 2 3)) 后,mylist 的值会是什么?
选项:
A. (1 2 3)✅
B. ((1 2 3))✅
C. (list 1 2 3)✅
D. ‘(1 2 3)✅总结
参考文献
https://github.com/rabbibotton/clog/blob/main/LEARN.md