在编程的世界里,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