天道酬勤,学无止境

Common Lisp:专门研究数组长度的泛型函数(Common Lisp: Generic Function Specializing on Array Length)

问题
vector2:normalize - for normalizing *vector2s* vector3:normalize - for normalizing *vector3s* etc. (make-array 3 :element-type `single-float). (defmethod v+1 ((vec-a #.(class-of (make-array 3 :element-type `single-float))) (vec-b #.(class-of (make-array 3 :element-type `single-float)))) (v3:v+1 vec-a vec-b)) (defmethod v+1 ((vec-a #.(class-of (make-array 4 :element-type `single-float))) (vec-b #.(class-of (make-array 4 :element-type `single-float)))) (v4:v+1 vec-a vec-b)) V> (class-of (make-array 4 :element-type `single-float)) #<BUILT-IN-CLASS SB-KERNEL::SIMPLE-ARRAY-SINGLE-FLOAT>
回答1
(defmethod v+1 ((size (eql 3)) vec-a vec-b) (v3:v+1 vec-a vec-b)) (defmethod v+1 ((size (eql 4)) vec-a vec-b) (v4:v+1 vec-a vec-b)) (defmethod v+1 ((size (eql 3)) vec-a vec-b) (assert (= 3 (length vec-a) (length vec-b)) "Vector size mismtach") (v3:v+1 vec-a vec-b)) (defmacro v+1* (vec-a vec-b) (once-only (vec-a vec-b) `(if (= (length ,vec-a) (length ,vec-b)) (v+1 (length ,vec-a) ,vec-a ,vec-b) (error "Vector size mismatch"))))
回答2

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 在普通的 lisp 中,如何以可移植的方式检查对象的类型(In common lisp, how can I check the type of an object in a portable way)
    问题 我想定义一个方法,该方法将专门用于具有无符号字节 8 元素的数组类型对象。 在 sbcl 中,当您(make-array x :element-type '(unsigned-byte 8)) ,对象类由 SB-KERNEL::SIMPLE-ARRAY-UNSIGNED-BYTE-8 实现。 是否有专门针对无符号字节数组类型的实现独立方式? 回答1 使用尖点在读取时插入依赖于实现的对象类: (defmethod foo ((v #.(class-of (make-array 0 :element-type '(unsigned-byte 8))))) :unsigned-byte-8-array) 锐符点读取器宏在读取时评估表单,确定数组的类。 该方法将专门用于特定 Common Lisp 实现用于数组的类。 回答2 请注意, MAKE-ARRAY的:ELEMENT-TYPE参数做了一些特别的事情,它的确切行为可能有点令人惊讶。 通过使用它,您告诉 Common Lisp ARRAY 应该能够存储该元素类型或其某些子类型的项目。 Common Lisp 系统然后将返回一个可以存储这些元素的数组。 它可能是一个专门的数组,也可能是一个也可以存储更通用元素的数组。 注意:它不是类型声明,也不一定会在编译或运行时检查。 UPGRADED-ARRAY-ELEMENT
  • Common Lisp 宏 let-curry - 不工作(Common Lisp macro let-curry - not working)
    问题 我发现自己调用了许多方法,它们的第一个参数是来自给定类的复杂对象。 虽然 with-slots 和 with-accessors 很有用,但不能以这种方式绑定泛型方法。 所以我想:如果我们可以在本地柯里化任何函数,槽 + 访问器 + 泛型函数 + 函数都可以用相同的结构来处理。 我要清理的代码示例: (defun clox-string (scanner) "Parse string into a token and add it to tokens" (loop while (and (char/= #\" (peek scanner)) (not (at-end-p scanner))) do (if (char= #\Newline (peek scanner)) (incf (line scanner)) (advance scanner))) (when (at-end-p scanner) (clox.error::clox-error (line scanner) "Unterminated string.") (return-from clox-string nil)) (advance scanner) ;; consume closing " (add-token scanner 'STRING (subseq (source scanner) (1+
  • 通用编程与元编程(Generic programming vs. Metaprogramming)
    问题 究竟有什么区别? 似乎这些术语可以互换使用,但是在阅读 Objective-c 的维基百科条目时,我遇到了: 除了 C 的过程式编程风格之外,C++ 还直接支持某些形式的面向对象编程、泛型编程和元编程。 参考 C++。 那么显然他们是不同的? 回答1 编程:编写一个程序来创建、转换、过滤、聚合和以其他方式操作数据。 元编程:编写创建,转换,过滤器,聚集和否则操纵程序的程序。 通用编程:编写一个程序来创建、转换、过滤、聚合和以其他方式操作数据,但只对数据结构做出最少的假设,从而最大限度地跨广泛的数据类型重用。 正如在其他几个答案中已经提到的那样,C++ 中的区别可能会令人困惑,因为通用编程和(静态/编译时)元编程都是使用模板完成的。 更让你困惑的是,C++ 中的泛型编程实际上使用元编程来提高效率,即模板特化从泛型生成专门的(快速)程序。 还要注意的是,正如每个 Lisp 程序员都知道的那样,代码和数据是一回事,所以真的没有“元编程”这样的东西,它只是编程。 同样,这在 C++ 中有点难以看到,因为您实际上使用两种完全不同的编程语言进行编程(C++,一种 C 系列中的命令式、过程式、面向对象的语言)和元编程(模板,一种纯函数式的“偶然” “一种介于纯 lambda 演算和 Haskell 之间的语言,语法很丑,因为它实际上从未打算成为一种编程语言。)
  • Lisp 中 C 结构的惯用等价物是什么?(What's the idiomatic equivalent of C structs in Lisp?)
    问题 在 C 类型语言中,从一开始和每本介绍性书籍都非常强调结构/记录和对象。 然后,他们的完整系统是围绕管理这些结构、它们的相互关系和继承而设计的。 在 Lisp 文档中,你通常可以找到 1-2 页关于 Lisp 如何“也”有一个 defstruct,一个简单的例子,通常就是这样。 此外,根本没有提到结构的嵌套。 对于来自 C 背景的人来说,首先似乎分层组织不同的数据类型不是 Lisp 中的首选方法,但除了 CLOS,它是一个成熟的对象系统,如果你只想要结构,那么它太复杂了,除了填充所有内容进入列表,没有明显的方法来转移您的 C 结构知识。 最类似于 C 结构的分层组织数据的惯用 Lisp 方式是什么? —— 我认为我的问题的总结答案是:对于初学者学习目的,defstruct 和/或 plists,虽然“遗留功能”,可以使用,因为它们最接近 C 结构,但它们已被更多的灵活的 defclass/CLOS,这是当今大多数 Lisp 程序所使用的。 这是我关于 SO 的第一个问题,所以感谢大家抽出时间来回答。 回答1 使用 CLOS。 这并不复杂。 否则使用结构。 如果你有一个具体的问题如何使用它们,那就问吧。 (defclass point () ((x :type number) (y :type number))) (defclass rectangle () ((p1
  • Lisp 作为 C++ 应用程序中的脚本语言 [关闭](Lisp as a Scripting Language in a C++ app [closed])
    问题 就目前而言,这个问题不适合我们的问答形式。 我们希望答案得到事实、参考或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。 如果您认为此问题可以改进并可能重新打开,请访问帮助中心以获取指导。 7年前关闭。 嘿,我一直在研究将脚本语言添加到我的框架中的可能性,我听说了 Lisp 并认为我会试一试。 是否有像 Lua 和 Python 这样的 Lisp 虚拟机,还是我的心态错误。 我在这里找到了 CLISP,http://clisp.cons.org/,但我不确定这是否是我要找的。 任何人都可以指出我正确的方向吗? 回答1 CLISP 只是 Common Lisp 的一种实现。 这是一个非常好的实现,它确实支持嵌入其他(基于 C 的)程序,但这不是它的重点,它是 GPL,这对您来说可能是也可能不是交易破坏者。 您可能有兴趣查看 ECL。 这个实现是专门为嵌入而设计的(实际上,“E”代表“Embeddable”!),并且具有许多可能对您有用的功能,包括将 Common Lisp 程序编译为 C 的能力(以及提供字节-代码编译和解释器)。 回答2 除非您需要整个 Lisp,否则您可能更愿意选择像 Guile 这样的 Scheme 实现,它旨在合并到另一个程序中。 回答3 尝试可嵌入的 Common Lisp (ECL)。 http://ecls.sourceforge
  • Lisp如何让您重新定义语言本身?(How does Lisp let you redefine the language itself?)
    问题 我听说Lisp可以让您重新定义语言本身,并且我已经尝试对其进行研究,但是在任何地方都没有明确的解释。 有没有人有一个简单的例子? 回答1 Lisp用户将Lisp称为可编程编程语言。 它用于符号计算-使用符号进行计算。 宏只是利用符号计算范式的一种方法。 更广阔的视野是Lisp提供了简单的方式来描述符号表达式:数学术语,逻辑表达式,迭代语句,规则,约束描述等等。 宏(Lisp源格式的转换)只是符号计算的一种应用。 这有某些方面:如果您询问“重新定义”语言,那么严格地重新定义将意味着重新定义一些现有的语言机制(语法,语义,语用学)。 但是也有语言功能的扩展,嵌入,删除。 在Lisp传统中,已经进行了许多尝试来提供这些功能。 Lisp方言和某种实现可能仅提供其中的一个子集。 主要Common Lisp实现提供的几种重新定义/更改/扩展功能的方法: s-expression语法。 s-expressions的语法不固定。 读取器(功能READ)使用所谓的读取表来指定读取字符时将要执行的功能。 可以修改和创建读取表。 例如,这允许您更改列表,符号或其他数据对象的语法。 还可以为新的或现有的数据类型(例如哈希表)引入新的语法。 也有可能完全替换s-ex​​pression语法并使用其他解析机制。 如果新的解析器返回Lisp格式,则解释器或编译器不需要更改。
  • 在 Common Lisp 中替换列表中的项目?(Replace an item in a list in Common Lisp?)
    问题 我有一个清单(我将其称为 L)、一个索引(N)和一个新事物(NEW)。 如果我想用 NEW 替换 L at N 中的东西,最好的方法是什么? 我是否应该将子列表从 N 到 N 到列表的末尾,然后使用列表将第一部分 NEW 和最后一部分的新列表粘合在一起? 或者有没有更好的方法来做到这一点? 回答1 (setf (nth N L) NEW) 应该做的伎俩。 回答2 你打算多久做一次; 如果你真的想要一个数组,你应该使用一个数组。 否则,是的,一个由前 N 个元素、新元素和尾部的副本组成的新列表的函数将没问题。 我不知道我头顶上有什么内置函数,但我有一段时间没有用 Lisp 编程了。 这是 Scheme 中的一个解决方案(因为我比 Common Lisp 更了解它,并且有一个解释器来检查我的工作): (define (replace-nth list n elem) (cond ((null? list) ()) ((eq? n 0) (cons elem (cdr list))) (#t (cons (car list) (replace-nth (cdr list) (- n 1) elem))))) 回答3 (setf (nth N L) T) 是最清晰、最简洁、最快捷的方式,如果您想做的是“破坏性”修改,即实际更改现有列表。 它不分配任何新内存。 回答4 我只是尝试修复
  • 在 SBCL 内部使用 deftransform/defknown 使编译器转换用户编写的函数(Using deftransform/defknown in SBCL internals to get the compiler to transform user authored functions)
    问题 在当前 SBCL 手册第 6.5 节的末尾,我们引用了以下内容: 如果您的系统性能由于某些原则上可以有效编译但 SBCL 编译器在实践中无法有效编译而受到影响,请考虑为编译器编写补丁并将其提交以包含在主要来源中。 这样的代码通常编写起来相当简单; 搜索字符串“deftransform”的来源以找到许多示例(有些简单,有些不那么简单)。 我一直在玩,发现了 sb-c::defknown 和 sb-c::deftransform 之类的东西,但到目前为止,在成功添加任何可以做任何事情的新转换方面运气不佳。 让我们假设我有以下 3 个玩具功能: (defun new-+ (x y) (+ x y)) (defun fixnum-+ (x y) (declare (optimize (speed 3) (safety 0)) (fixnum x y)) (+ x y)) (defun string-+ (x y) (declare (optimize (speed 3) (safety 0)) (string x y)) (concatenate 'string x y)) 作为一个纯粹的玩具示例,假设我们想告诉编译器它可以将对我的用户定义函数new-+调用转换为对 fixnum-+ 或 string-+ 的调用。 编译器将(new-+ xy)转换为(fixnum-+ xy
  • 如何在 lisp 中全局更改函数内的变量值(How do I globally change a variable value within function in lisp)
    问题 我想知道是否有任何方法可以用 LISP 中的指针来模拟 C 行为。 在 C 中,如果更改指针所指向的变量的值,则它具有全局效果(即该值也将在函数外部更改)。 所以如果我有 (defun mutate ( a ) (some-magic-function a 5) ) 调用 mutate 后,无论之前是什么,a 都会变为 5。 我知道带有列表的元素是可能的(大部分是副作用) 在 common-lisp 中,如何在不更改原始列表的情况下从函数中修改列表参数的一部分? 但我想知道如何为整个列表做到这一点。 回答1 C 代码的讨论 sds 的回答解决了问题的要点,但对于您正在模拟的 C 代码中发生的事情,看起来确实有些混乱: 我想知道是否有任何方法可以用 LISP 中的指针来模拟 C 行为。 在 C 中,如果更改指针所指向的变量的值,则它具有全局效果(即该值也将在函数外部更改)。 考虑以下内容,我认为它与您提供的 Lisp 代码最相似: #include<stdio.h> int a = 3; int mutate( int a ) { return a = 5; } int main() { mutate( a ); /* or mutate( 8 ) or anything other argument */ printf( "%d\n", a ); /* prints 3 */
  • 为什么在Common Lisp中的lambda之前使用#'?(Why #' is used before lambda in Common Lisp?)
    问题 我想知道为什么我看到的大多数Common Lisp代码都具有类似以下内容 (mapcar #'(lambda (x) (* x x)) '(1 2 3)) 而不只是 (mapcar (lambda (x) (* xx)) '(1 2 3)) , 这似乎也可以。 我开始学习Common Lisp,并且在Scheme中有一定背景,这引起了我的兴趣。 编辑:我知道您需要带功能名称的#',因为它们与变量位于不同的命名空间中。 我的问题只是在lambda之前##,因为lambda已经返回了一个函数对象(我认为)。 少#'的lambda由于宏扩展而起作用的事实使其变得更加吸引人... 回答1 #'foo是读者的(function foo)的缩写。 在CL,有几种不同的命名空间, #'foo或(function foo)将返回的foo 。 您可能想要搜索“ Lisp-1 vs. Lisp-2”,检查其他Stackoverflow问题或阅读Pitman和Gabriel的旧文章,以了解有关多个名称空间(也称为符号的或。 )。 在lambda的情况下,CL中可能省略#'的原因是它是一个宏,因此会扩展(取自Hyperspec): (lambda lambda-list [[declaration* | documentation]] form*) == (function (lambda
  • 如何在 Common Lisp 中进行模式匹配(How to do Pattern Matching in Common Lisp)
    问题 我不知道是否存在 Common Lisp 的模式匹配函数,但我必须创建自己的函数。 我对 Lisp 一无所知。 有人可以提出学习 Lisp 的建议,最重要的是,如何在 Lisp 中进行模式匹配。 我将不得不传递一个模式和一个事实,然后说它们是否匹配。 一个例子是 (heroes (hitpoints=hp) (mana=m)) 应该匹配 (Morphling (hitpoints 435) (mana 260)) 它还应该能够对一个数字是更大还是更小进行数字比较。 就像另一个英雄的法力比变体精灵少。 回答1 各种 Lisp 书籍中都解释了简单的模式匹配功能。 Lisp,第 3 版,温斯顿/霍恩人工智能编程范式,Common Lisp 案例研究,Peter Norvig 和别的。 以上书籍很好地解释了在 Lisp 中实现模式匹配。 存在库,例如 trivia、cl-match 和其他各种库。 回答2 我想你可能想要 CL-Unification 库:http://common-lisp.net/project/cl-unification/ 回答3 我不想让你需要为学校做的任何学习短路(如果这是需要这个项目的背景),但你可以研究 cl-ppcre 库,http://weitz.de/cl- ppcre/,看看有经验的 Lisper 是如何做到的。 您可以下载源代码并研究以了解。
  • Common Lisp 中的类型类(Typeclasses in Common Lisp)
    问题 我想知道是否有办法在 Common Lisp 中模拟 Haskell 的typeclasses 。 泛型函数允许overloading ,并且可以使用deftype定义类型(例如,可以通过某些实例列表的成员资格来定义)。 但我不能dispatch一个类型。 有没有办法让一个类在定义后成为其他类的子类(和子类型)(例如,使cons类成为sequence类的子类,而不重新定义cons )? 谢谢。 回答1 Haskell 中的类型类是一种以字典的形式静态查找“接口”实现的方法(类似于如何使用例如 C++ 中的 vtable,但(几乎)完全是静态的,不像 C++ 在运行时进行动态调度)。 然而,Common Lisp 是一种动态类型语言,因此这样的查找毫无意义。 但是,您可以在运行时实现自己对“类型类”实现(实例)的查找——在像 Common Lisp 这样富有表现力的语言中,这种设计并不难想象。 如果您想参考动态设置中的现有解决方案,PS Python 的 Zope 具有非常相似的特性的适应机制。 回答2 您无法以您设想的方式修改类层次结构,但您可以获得几乎相同的效果。 假设您对sequence的定义是它具有函数sequence-length 。 (defclass sequence ...) (defmethod sequence-length ((s sequence))
  • 学习一个 Lisp 有助于学习另一个吗?(Does learning one Lisp help in learning the other?)
    问题 学习不同的 Lisp 语言之间有什么协同作用吗? 我目前正在学习 Emacs Lisp,因为它在我的日常 Emacs 使用中立即有用,但是我对所有 Lisp 都很着迷,所以也许有一天我会学习和使用其他的。 当我开始研究 Common Lisp、Scheme 或 Clojure 时,学习 Emacs Lisp 对我有帮助吗? 换句话说,对我来说是像学习一门全新的语言,还是一些观念和范式是通用的? 我也对比较 Lisp 之间的独特差异很感兴趣,当我从一个 Lisp 转到另一个 Lisp 时,这将是一个问题。 在如何开始学习 Common Lisp 和 Emacs Lisp? 提到会有“浪费”,但没有详细说明到什么程度。 回答1 是的- 如果你已经知道一个新的 Lisp,那么拿起一个新的 Lisp 会容易得多。 原因: 您将理解“代码即数据”的概念和同形语言中的元编程(这可以说是使 Lisps 与众不同/区别于其他语言的最大的单一因素) 您将能够更轻松地阅读 Lisp 语法。 到达“看到”Lisp 代码结构的地步需要几周的时间,但在那之后就容易多了。 一段时间后,您开始忽略括号。 开发风格类似,使用 REPL 与运行环境交互它们共享共同的习语,例如使用列表和各种函数式编程技术 回答2 如果您想学习一些较旧的 Lisp 基础知识,那么 Emacs Lisp 很好。 Emacs
  • 为什么Lisp用于AI? [关闭](Why is Lisp used for AI? [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 我一直在学习Lisp,以扩大我的视野,因为我听说它已用于AI编程中。 在进行了一些探索之后,我还没有找到AI实例或任何其他使它更倾向于AI的语言。 Lisp过去是因为可用而使用过,还是我只是想缺少一些东西? 回答1 Lisp WAS在AI中一直使用到1980年代末。 然而,在80年代,Common Lisp被推销为商业界的“ AI语言”。 强烈的反对迫使大多数AI程序员使用C ++几年了。 如今,原型通常是用一种较年轻的动态语言(Perl,Python,Ruby等)编写的,成功研究的实现通常是用C或C ++(有时是Java)实现的。 如果您对70年代感到好奇...那么,我不在那儿。 但是我认为Lisp在AI研究中取得了成功,原因有三点(按重要性排序): Lisp是出色的原型制作工具。 这是很长一段时间以来最好的。 Lisp仍然擅长解决您尚不知道如何解决的问题。 该描述完美地描述了AI。 Lisp很好地支持符号编程。 旧的AI也是象征性的。 长期以来,它在这方面也是独一无二的。 Lisp非常强大。 代码/数据的区别较弱
  • 在Common Lisp中查找函数的Arity(Find function's arity in Common Lisp)
    问题 我一直在做一些遗传编程,并且根据他们的特性将函数分为不同的函数集。 这一切都相当复杂。 我想知道是否有更简单的方法可以做到这一点。 例如,如果有一个函数返回给定函数的arity。 提前加油。 回答1 对于解释函数,您应该可以使用function-lambda-expression。 遗憾的是,对于已编译的函数,该函数通常返回nil ,因此您将不得不使用依赖于实现的函数(clocc / port / sys.lisp): (defun arglist (fn) "Return the signature of the function." #+allegro (excl:arglist fn) #+clisp (sys::arglist fn) #+(or cmu scl) (let ((f (coerce fn 'function))) (typecase f (STANDARD-GENERIC-FUNCTION (pcl:generic-function-lambda-list f)) (EVAL:INTERPRETED-FUNCTION (eval:interpreted-function-arglist f)) (FUNCTION (values (read-from-string (kernel:%function-arglist f)))))) #
  • 面向对象程序员的方案(scheme for object-oriented programmers)
    问题 我对 Scheme 非常感兴趣,并从一些玩具编程示例开始,并且正在阅读 Paul Graham 的 On Lisp。 我找不到一本书或网站,旨在向“面向对象的人”教授 Scheme,即像我这样的人已经用 c++/Java/Python 完成了 99% 的编码。 我看到闭包有点像 object-y,因为它们具有本地状态,并提供一个或多个可以访问该状态的函数。 但我不想学习 Scheme 只是为了将我现有的习惯移植到它上面。 这就是我现在学习 Scheme 而不是 Common Lisp 的原因; 我担心 CLOS 可能只是我现有的面向对象习惯的拐杖。 理想的是一本书或网站,它提供了用面向对象语言和 Scheme 以 Schemey 方式解决的问题的案例研究。 我想我最喜欢科学计算和/或计算机图形问题,但任何事情都可以。 任何教学指导将不胜感激。 回答1 我怀疑 CLOS 会成为旧习惯的拐杖,我发现它与 C++/Java/Python 中的 OO 风格非常不同,而且非常有趣。 我不明白所有的细节,但我会推荐 Peter Seibel 的 Practical Common Lisp。 如果您在阅读On Lisp 时没有遇到太多麻烦,您应该能够深入了解在 PCL 中介绍 CLOS 的章节。 另外,我推荐他的 Google Tech Talk 比较 Java 和 Common Lisp
  • Common Lisp 中有函数原型吗?(Are there function prototypes in Common Lisp?)
    问题 我已经用通用 lisp 编程一段时间了,在我使用 lisp 的经验中,我还没有看到任何函数/宏的行为类似于 C 或 C++ 中的函数原型。 目前我必须非常小心我的函数的顺序,否则,当我尝试从另一个函数调用一个函数时,Lisp 会说该函数“不存在”,因为它是在文件后面定义的。 有没有办法解决这个问题? 我可以在文件顶部声明我所有的函数原型,以及下面的完整定义吗? 回答1 声明和声明 您可以使用 declaim 来全局声明某个事物具有某个函数类型。 例如,如果您定义了调用 undefined baz 的foo1 (在 SBCL 中),首先看看会发生什么: CL-USER> (defun foo1 () (baz)) ; in: DEFUN FOO1 ; (BAZ) ; ; caught STYLE-WARNING: ; undefined function: BAZ ; ; compilation unit finished ; Undefined function: ; BAZ ; caught 1 STYLE-WARNING condition FOO1 现在,让我们添加一个声明,说明baz是一个没有参数的函数,并返回一些东西。 如果您愿意,您显然可以添加更多类型信息,但这至少将提供baz是一个函数的数量和知识。 CL-USER> (declaim (ftype
  • Common Lisp 一个 Lisp-n?(Common Lisp a Lisp-n?)
    问题 我知道 Common Lisp 对函数和变量有不同的绑定环境,但我相信它还有另一个用于标签体标签的绑定环境。 还有比这更多的绑定环境吗? 如果是这样,那么将 Common Lisp 归类为 Lisp-2 是否公平? 这些问题并不意味着迂腐或自行车脱落,我只是想更好地了解 Common Lisp 并希望能获得一些指示,了解在哪里更深入地研究它的规范。 回答1 我知道 Common Lisp 对函数和变量有不同的绑定环境, 根据 HyperSpec,这将是namespaces : 命名空间 n. 1. 外延仅限于特定种类的绑定。 The bindings of names to tags is the tag namespace.'' 2. any mapping whose domain is a set of names. 一个包定义了一个命名空间。'' (第 1 点。) 但我相信它还有另一个标签体标签的绑定环境。 还有比这更多的绑定环境吗? 是的,还有更多的命名空间。 我什至记得有一个小片段暴露了它们中的大部分,但不幸的是,我再也找不到它了¹。 它至少暴露了变量、函数、标签和块命名空间,但也可能包括类型和声明。 还有另一个列出这些名称空间的 SO 答案。 如果是这样,那么将 Common Lisp 归类为 Lisp-2 是否公平? 在对上述链接答案的评论中,Rainer
  • Common Lisp是否具有类似于Java的Set Interface / implementing类的东西?(Does Common Lisp have a something like java's Set Interface/implementing classes?)
    问题 我需要这样的东西,一个元素集合,其中不包含任何元素的重复项。 Common Lisp,特别是SBCL,是否有这样的东西? 回答1 对于快速解决方案,只需使用哈希表(如前所述)即可。 但是,如果您喜欢更原则的方法,则可以看一下FSet,它是“功能性集合理论集合库”。 除其他外,它包含套件和袋子的类和操作。 (编辑:)最干净的方法可能是将面向集合的操作定义为泛型函数。 毕竟,一组通用函数基本上等效于Java接口。 您可以简单地在标准HASH-TABLE类上实现方法作为第一个原型,并允许其他实现。 回答2 看cl容器。 有一个集合容器类。 回答3 您可以使用列表,尽管它们可能无法有效地表示大型集合。 使用ADJOIN或PUSHNEW将新元素添加到列表中,然后使用DELETE或REMOVE完成相反的操作。 (let ((set (list))) (pushnew 11 set) (pushnew 42 set) (pushnew 11 set) (print set) ; set={42,11} (setq set (delete 42 set)) (print set)) ; set={11} 需要注意的一件事是,这些运算符默认情况下都使用EQL来测试集合中可能存在的重复项(就像Java使用equals方法一样)。 这对于包含数字或字符的集合是可以的,但是对于其他对象的集合
  • 在 Common Lisp 中,如何定义通用数据类型说明符(如整数列表)?(In Common Lisp, how to define a generic data type specifier (like list of integers)?)
    问题 我想定义一个描述相同类型事物列表的类型说明符。 所以我想要(list-of integer)类似于(array integer) (内置)。 我能够为特定类型创建它,如下所示: (defun elements-are-integer (seq) (every #'(lambda (x) (typep x 'integer)) seq)) (deftype list-of-integer () '(and list (satisfies elements-are-integer))) 但是,这意味着我必须为每种可能的类型执行此操作。 如何更改此代码,以便该类型将另一种类型作为参数,并动态构造satisfies谓词? 问题是, satisfies需要一个全局符号,我不知道如何在适当的上下文中定义谓词函数(我想我需要以某种方式对其进行gensym ,但是如何?)。 此外,该解决方案应该有效,以便可以在另一个包中创建该类型。 回答1 试试这个: (defun elements-are-of-type (seq type) (every #'(lambda (x) (typep x type)) seq)) (deftype list-of-type (type) (let ((predicate (gensym))) (setf (symbol-function predicate)