Lisp常见类型与类的区别 [英] Common Lisp type vs. class distinctions

查看:148
本文介绍了Lisp常见类型与类的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


In the post at Common Lisp class hierarchy, Rainer Joswig & Joshua Taylor carefully distinguish some of the differences between built-in Common Lisp types and classes, where classes form part of the CLOS extension to the baseline. The type/class (plus mop) distinctions are also reflected in Pfeil's comprehensive hierarchy diagram. Using the diagram, it seems possible to extract the two distinct hierarchies. In particular, I am currently most interested in the tops of the hierarchies; namely, the direct subtypes and subclasses of t (since t is both a type and a class). Here are some provisional subtypes/subclasses distilled from the diagram:

For the type hierarchy, the direct subtypes of t seem to be atom, character, random-state, hash-table, restart, readtable, package, pathname, stream, function, array, sequence, number, and condition. All other types like float or list are subtypes of one of these types. The type hierarchy is also not strictly hierarchical (since (subtype t t) => T, but this seems to be the only exception). (ps: the types symbol and structure-object are not included in the diagram, but also may be direct subtypes of t.)

For the class hierarchy, the direct subclasses of t include corresponding classes for all the types above (except atom, and perhaps structure-object which is now a subclass of standard-object(?)), plus standard-object.

The MOP extends CLOS by adding the class metaobject (plus some meta-subclasses), but does not seem to add to the direct subclasses of t.

Can someone verify if this understanding is correct, or provide additional clarifications?

Note: I've discovered at least one mistake in the type hierarchy description above. All of the listed subtypes (character, etc.) are apparently subtypes of atom, so they are not direct subtypes of t. The only other direct subtype of t seems to be sequence, since a sequence can be a cons (non-atom). Moreover, symbol is, in fact, included in the diagram, and is also a subtype of atom.

解决方案

Graphing CL Subtypes of T in LispWorks:

Finding the subtypes:

(defun find-synonym-types (type1 types)
  (remove-if-not (lambda (type2)
                   (and (not (eq type1 type2))
                        (subtypep type1 type2)
                        (subtypep type2 type1)))
                 types))

(defun find-all-types-in-packages (packages &key include-nil)
  (let ((types nil))
    (loop for package in packages
          when (find-package package)
          do (do-external-symbols (sym (find-package package))
               (when (ignore-errors (subtypep sym t))
                 (let ((synonyms (find-synonym-types sym types)))
                   (if synonyms
                       (pushnew sym (get (first synonyms) :type-synonyms))
                     (pushnew sym types))))))
    (if include-nil types (remove nil types))))

(defun direct-subtypes (supertype &key all-types)
  (loop with subtypes = (remove supertype (loop for type in all-types
                                                when (subtypep type supertype)
                                                collect type))

        for type in subtypes
        when (loop for type2 in (remove type subtypes)
                   never (subtypep type type2))
        collect type))

Graphing it:

#+capi
(defun class-color (class-name)
  (typecase (find-class class-name)
    (standard-class  :blue)
    (built-in-class  :violet)
    (structure-class :brown)
    (otherwise       :red)))

#+capi
(defun graph-subtypes-from-t ()
  (let ((all-types (find-all-types-in-packages '("CL" "CLOS"))))
    (capi:contain
     (make-instance
      'capi:graph-pane
      :roots '(t)
      :children-function (lambda (type)
                           (direct-subtypes type :all-types all-types))
      :node-pane-function #'(lambda (graph-pane node)
                              (declare (ignore graph-pane))
                              (make-instance
                               'capi:item-pinboard-object
                               :text (format
                                      nil "~{~a~^, ~}"
                                      (cons node
                                            (get node :type-synonyms)))
                               :graphics-args `(:foreground
                                                ,(if (find-class node
                                                                 nil)
                                                     (class-color node)
                                                   :black))))
      :edge-pane-function #'(lambda (self from to)
                              (declare (ignore self from to))
                              (make-instance
                               'capi:arrow-pinboard-object
                               :graphics-args '(:foreground
                                                :grey))))
     :title "Common Lisp Subtypes in LispWorks")))

Graph

The types with corresponding CLOS classes are written in blue and structure classes are brown. The type NIL is not drawn. Included are types/classes from the CLOS MOP. Some types have more than one name. Also note that this graph is specific to LispWorks, especially what types are actually also structures, CLOS classes, built-in class or something else.

这篇关于Lisp常见类型与类的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆