问题标签 [clos]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
5 回答
145 浏览

java - Java 是否支持像 Lisp 那样基于多个对象的类型分派到特定的实现?

将自己读入 Lisp,目前在此页面 ( http://landoflisp.com ) 上,我在单击链接CLOS GUILD时显示的页面的倒数第二段中找到了以下语句:

关于该示例需要注意的重要一点是,为了确定在给定情况下调用哪个 mix 方法,CLOS 需要考虑传入该方法的两个对象。它根据多个对象的类型分派到方法的特定实现。这是传统面向对象语言(如 Java 或 C++)中不具备的功能。

这是示例 Lisp 代码:

不,我认为最后一句话是错误的。实际上,我可以使用以下 Java 代码做到这一点:

当我运行它时,它给了我相同的输出:

所以我的问题是:该页面上的这句话实际上是错误的吗?在 Java / C++ 中可能吗?如果是这样,也许在旧版本的 Java 中是不可能的?(虽然我非常怀疑,因为这本书只有 5 年的历史)如果不是这样,我在我的例子中忘记考虑什么?

0 投票
1 回答
225 浏览

common-lisp - 获取类优先级列表时未绑定插槽?

为什么我不能在 sbcl 中获得一个简单的类优先级列表?

0 投票
1 回答
472 浏览

lisp - CLOS:使用一个槽值来初始化另一个槽

我对使用 CLOS 很陌生。在这里,我编写了一种使用 CLOS 定义队列的可能方法:

如您所见,我使用 slot 的值queue-size来制作 slot 中的数组elements。但是,不幸的是,这给了我以下错误:

正如我所说,我对 CLOS 很陌生。有什么办法我仍然可以做到这一点?是否可以覆盖某种初始化方法?如果是,我该怎么做?

0 投票
2 回答
587 浏览

common-lisp - Changing method dispatch in Common Lisp

I'm trying to simulate something akin to Haskell's typeclasses with Common Lisp's CLOS. That is, I'd like to be able to dispatch a method on an object's "typeclasses" instead of its superclasses.

I have a metaclass defined for classes which have and implement typeclasses(which are just other classes). Those classes(those that implement typeclasses) have a slot containing the list of the typeclasses they implement.
I'd like to be able to define methods for a typeclass, and then be able to dispatch that method on objects whose class implement that typeclass. And I'd like to be able to add and remove typeclasses dynamically.

I figure I could probably do this by changing the method dispatch algorithm, though that doesn't seem too simple.

Anybody is comfortable enough with CLOS and the MOP to give me some suggestions?

Thanks.

Edit: My question might be specified as, how do I implement compute-applicable-methods-using-classes and compute-applicable-methods for a "custom" generic-function class such that if some of the specializers of a generic function method are typeclasses(classes whose metaclass is the 'typeclass' class), then the corresponding argument's class must implement the typeclass(which simply means having the typeclass stored in a slot of the argument's class) for the method to be applicable?
From what I understand from documentation, when a generic function is called, compute-discriminating-functionis first called, which will first attempt to obtain applicable methods through compute-applicable-methods-using-classes, and if unsuccessful, will try the same with compute-applicable-methods.
While my definition of compute-applicable-methods-using-classes seems to work, the generic function fails to dispatch an applicable function. So the problem must be in compute-discriminating-function or compute-effective-method.

See code.

0 投票
3 回答
412 浏览

common-lisp - 使用 CLOS 类实例作为哈希表键?

我有以下课程:

现在,我想使用这个类作为哈希表的键。实例的地址可以很容易地与 进行比较eq。然而问题是,这个category类可能有多个相同的实例,我希望哈希表也能将其识别为键。

所以,我试图像这样覆盖函数的:test参数make-hash-table

不幸的是,这是不允许的。:test需要是函数 eq、eql、equal 或 equalp 之一的指示符。

解决这个问题的一种方法是将类category变成一个结构,但我需要它成为一个类。有什么办法可以解决这个问题吗?

0 投票
2 回答
4003 浏览

class - Common Lisp中结构和类的区别

我对结构的理解是它有存储数据的槽,有一个类型,有make-X和槽访问器函数,并且可以通过一个方法专门化(因为它有一个类型)。

我对一个类的理解是它具有所有相同和多重继承。这个问题的最佳答案表明结构可以具有单一继承,并且 CLOS 的初始实现比结构“慢得多”。

根据人们如何谈论 CLOS 和结构,我认为肯定还有其他一些差异,但是我的琐碎谷歌搜索没有结果。所以我问:CLOS和结构之间有什么实际区别?

0 投票
4 回答
307 浏览

common-lisp - 在 Common Lisp 中定义多个后端的惯用方式?

我想编写具有多个用户界面后端(例如文本和图形)的代码,因此它们很容易切换。我的方法是使用 CLOS:

这种方法乍一看似乎没问题,但它有一些缺点。为了简化调用,我定义了参数ui-type将在每个函数调用中使用,以简化切换后端,但是在使用高阶函数时会出现问题:

如果采用这种方法,我们可以将通用函数命名为 %draw-user-interface,而将包装函数命名为 draw-user-interface。

这是有效的方法还是有更直接的方法?问题是为相同的功能提供不同的后端,不一定是用户界面。

另一个用例可能是这样一种情况,当我有许多相同算法的实现(针对速度、内存消耗等进行了优化)并且我想以一种干净的方式切换它们,保留接口和参数类型。

0 投票
5 回答
1927 浏览

inheritance - CLOS:如何调用一个不太具体的方法?

有一个通用的方法,比如说incx。有两个版本incx。一种专门针对类型a,一种专门针对类型b。类型b是 的子类a。给您一个类型的对象b,即派生类型,但您想调用专门针对类型的方法a。如果还没有专门针对 type 的同名方法,您可以轻松地做到这一点b,但是唉,有这样的方法。

a那么在这种情况下如何调用专门针对类型的方法呢?

正如 CLOS 所承诺的,这调用了最专业的方法:

但在这种特殊情况下,(不是一般情况下)我想要的是访问不太专业的版本。像这样说:

我看到call-next-method可以在专门的方法中使用该函数来获得下一个不那么专门的方法,但这不是这里想要的。

在被剪掉的代码中,我确实需要类似于 的东西call-next-method,但用于调用补充方法。与其在下一个不太专业化的类中调用同名方法,不如调用它的互补方法,该方法具有不同的名称。补充方法也是专门的,但调用这个专门的版本不起作用 - 原因call-next-method可能与包含的原因大致相同。专用于超类的所需方法并不总是具有相同的名称。

这是另一个例子

有一个描述电子特性的基类和一个描述“奇怪电子”特性的派生类。专门研究奇怪电子的方法希望调用专门研究电子的方法。为什么?因为这些方法为程序完成了正常电子部分的工作。奇怪电子的非电子部分几乎是微不足道的,或者更确切地说,如果它没有复制电子代码:

这一切都归结为一个简单的问题:

如果定义了更专业的方法,如何调用不太专业的方法?

0 投票
2 回答
218 浏览

lisp - 如何将超类对象传递给子类构造函数?

假设我有A几个插槽的课程:

B继承自的类A

如果我想实例化B,会make-instance提供给我插槽:a-1和.:a-2:b-1

这是一个疯狂的想法:如果我想B使用现有的实例实例化A并且只填充 slotb-1怎么办?

PS。为什么有用:如果实现了一些直接继承的A通用方法,而不添加任何新内容。B在另一种方法中,将实例A作为一个插槽B,我需要编写简单的方法包装器来在该插槽上调用这些方法。

我能想到的唯一方法:在辅助构造函数中分解对象A并将相应的插槽传递给make-instancefor B,即:

有没有更好的方法来做到这一点?(或者也许,这种方法会导致非常糟糕的设计,我应该完全避免它?)

0 投票
3 回答
1052 浏览

methods - 如何使用标准函数调用方法对象

如何将方法对象称为函数?

Closer-mopclos包都提供了将方法对象转换为函数的方法函数。但是,有没有办法在不包含另一个包的情况下做到这一点?如果没有,哪个包?(使用 SBCL),但是如果需要一个包,那么鉴别功能是如何做到的呢?

这是使用 find-method 获取方法对象的示例。那么问题是如何调用method-to-be- call 。

作为第二个问题,文档说鉴别功能首先尝试按类计算适用方法以查找方法对象,如果失败,则使用计算适用方法。为什么要采用这种两层方法?假设find-method正在执行这种两层方法是否正确,所以最好使用find-method

-- 附录 -- 在下面的评论中,Rainer Joswig 指出这种查找方法形式是依赖于实现的:

他说说明符列表应该是类并建议:

所以我想把我的课放在那里:

显然(defclass a ... )没有将a设置为类。事实上,它并没有设置任何东西!

... 变量 A 未绑定。

但是,这有效:

所以类是 defclass 的返回值,而不是提供给 defclass 的符号的值。