all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: "Pascal J. Bourguignon" <pjb@informatimago.com>
To: help-gnu-emacs@gnu.org
Subject: Re: EIEIO built in methods -- question
Date: Sun, 09 Jun 2013 22:47:10 +0200	[thread overview]
Message-ID: <874nd7j9kh.fsf@kuiper.lan.informatimago.com> (raw)
In-Reply-To: mailman.1279.1370791373.22516.help-gnu-emacs@gnu.org

Eric Abrahamsen <eric@ericabrahamsen.net> writes:

> Specifically: Override the initialization method for a class that
> inherits from eieio-persistent, to make sure that it's impossible to
> create two instances of the class that have the same :file slot. I've
> already realized constructor is the wrong method, so probably
> initialize-instance.

Ok, initialize-instance won't do it, because make-instance doesn't
return the result of initialize-instance, and it doesn't because the
default constructor method doesn't.

In CL, make-instance is a generic function so it would be a simple
matter of overriding make-instance.

In eieio, they've made make-instance a normal function and defered to
the generic function constructor, so indeed I think you will have to
define a method on your class for contructor.

Now, the default method for constructor takes an instance of the class
eieio-default-superclass.

It would be easy if eieio was made correct, but it seems that have some
deficiencies in the meta class domain:


(class-of (make-instance 'c)) --> c                   ; in eieio
(class-of (make-instance 'c)) --> #<standard-class c> ; in CLOS

; in eieio:
(class-of (class-of (make-instance 'c))) 
Lisp error: (wrong-type-argument eieio-object-p c)

; in clos:
(class-of (class-of (make-instance 'c))) 
#<standard-class standard-class>  ; moral equivalent to eieio-default-superclass


and foremost, it lacks EQL specializers!

in CLOS, you could write:

(defmethod constructor ((class (eql (find-class 'persistent-thing))))
   …)


but not so in eieio.  For a start, eieio classes are not instances:

(class-of (find-class 'c))
Lisp error: (wrong-type-argument eieio-object-p [defclass c nil nil [0
value 0] (value) (#2=#:unbound) (nil) [t] (nil) (nil) ((default)) (nil)
(nil) ((:value . value)) nil nil #1=[] nil nil nil nil nil #1# [object c
default-cache-object #2#] (:custom-groups (default))])


And finally, eieio defclass documentation says:

    Options in CLOS not supported in EIEIO:

      :metaclass - Class to use in place of `standard-class'

so we cannot even define persistent-thing as having a different
metaclass onto which we could define a specific constructor method.



This indeed leaves us in a bad situation.

You could either patch eieio, or wrap around it. 
I would advise you the later.  If I started patching eieio, I would
rewrite it entirely to make it a correct CLOS implementation…


So instead of using make-instance to get your persistent-things, use
your own function that will test for singletons:


(defvar *file-things-map* (make-hash-table :test (function equal)))

(defun make-persistent-thing (&rest arguments)
  (let ((file (getf :file slots)))
    (assert file)
    (or (gethash file *file-things-map*)
        (setf (gethash file *file-things-map*) 
              (apply (function make-instance) 'persistent-thing arguments)))))




> Generally: If OO programming in (e)lisp is anything like OO programming
> in other languages, overloading initialization, deletion, and
> representation methods is *not* something to throw up our hands and wail
> about, it's a perfectly normal part of programming. See my specific
> example above.

Obviously, eieio failed to do that on the class level.

(class-of instance) not being objects is a big FAIL.


> Unless I'm wrong about that, I'm offering to add a section to the manual
> detailing the right way to overload the basic methods on
> eieio-default-superclass, as a learning exercise for myself, if someone
> will agree to look at what I write, help me understand the issues
> correctly, and make sure what I write is accurate. That's all.


But let's not critisize eieio authors.  AFAIK, they've just applied
usual Agile directives, implementing an object system only to fulfill a
very definite and limited goal, that of implementing cedet.  Their
product manager never had a budget to schedule a sprint about
implementing CLOS in emacs lisp.  The customer only wanted cedet, not
CLOS (and if he wanted CLOS, he would know where to find it).


Too bad your needs don't match exactly those of cedet.  Time to scratch
your itch yourself ;-)
-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.
You can take the lisper out of the lisp job, but you can't take the lisp out
of the lisper (; -- antifuchs


  parent reply	other threads:[~2013-06-09 20:47 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-09 10:22 EIEIO built in methods -- question Eric Abrahamsen
2013-06-09 10:49 ` Eric Abrahamsen
2013-06-09 11:54 ` Pascal J. Bourguignon
2013-06-09 15:22   ` Eric Abrahamsen
     [not found]   ` <mailman.1279.1370791373.22516.help-gnu-emacs@gnu.org>
2013-06-09 20:47     ` Pascal J. Bourguignon [this message]
2013-06-10 15:48       ` David Engster
2013-06-11  2:16         ` Eric Abrahamsen
2013-06-12 15:44           ` David Engster
2013-06-13  5:11             ` Eric Abrahamsen
2013-06-13  9:06               ` Eric Abrahamsen
2013-06-13 15:49               ` David Engster
2013-06-14  1:37                 ` Eric Abrahamsen
2013-06-14 15:14                   ` David Engster
2013-06-14 16:15                     ` Eric Abrahamsen
     [not found]                     ` <mailman.1680.1371226519.22516.help-gnu-emacs@gnu.org>
2013-06-14 18:29                       ` Pascal J. Bourguignon
     [not found]       ` <mailman.1356.1370879310.22516.help-gnu-emacs@gnu.org>
2013-06-10 19:18         ` Pascal J. Bourguignon
2013-06-11 15:43           ` David Engster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874nd7j9kh.fsf@kuiper.lan.informatimago.com \
    --to=pjb@informatimago.com \
    --cc=help-gnu-emacs@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.