emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: EIEIO with lexical scoping


From: Stefan Monnier
Subject: Re: EIEIO with lexical scoping
Date: Mon, 13 May 2013 22:13:57 -0400
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3.50 (gnu/linux)

> The code around here looks like this:

>       (let ((eieio-skip-typecheck t))
>       ;; All type-checking has been done to our satisfaction
>       ;; before this call.  Don't waste our time in this call..
>       (eieio-set-defaults cache t))

> I'm not that familiar with lexical-binding, but I suspect this won't
> work... right?

I don't see anything problematic here (since eieio-skip-typecheck
was declared with defvar to be dynamically scoped).

> A quick search shows that the method invocation has a similar pattern with
> eieiomt-optimizing-obarray' in 'eieio-generic-form' as well as use of
> scoped-class' in 'shared-initialize'.  I would look at these first.

eieiomt-optimizing-obarray is defvarred as well, so it looks fine.
But `scoped-class' indeed looks like it might be a potential source of
problems, I'll take a closer look, thank you.

> You are using a version of eieio that still uses eval-and-compile.

Yes.

> I flushed the remaining uses of eval-and-compile from EIEIO in March in the
> CEDET repository due to a previous thread.

Yes, I remember.

> I thought I had shared this change or it was merged upstream, but
> maybe I forgot?  I apologize if you didn't get the update.
> The changes were extensive as half of EIEIO moved into a second file
> to help with compilation.

Those changes haven't yet been merged into trunk.  I was hoping someone
else could do it.

> It would be better of we both worked from there.  Papers are all up to
> date if you want to pull that change from the CEDET repository.

Right, I'm not particularly worried.  For now, I'm just trying to make
it work and don't plan on installing the change into trunk yet.
And porting/merging the patch won't be a problem, at least for now.

>> -(defmacro class-p (class)
>> +(defsubst class-p (class)
> Is this generic cleanup, or important for a lexical binding?

It's not indispensable, but enables the subsequent

-              (if (fboundp namep)
-                  (funcall `(lambda () (,namep val)))
-                (funcall `(lambda ()
-                            (,(intern (concat name "-p")) val)))))))
+              (funcall (if (fboundp namep) namep (intern (concat name "-p")))
+                        val))))

simplification, which otherwise would need to be turned into:

               (funcall `(lambda (val)
                           (,(if (fboundp namep) namep
                               (intern (concat name "-p")))
                            val))
                        val))))

Note how `val' needs to be passed to the newly built lambda, because the
`val' inside the lambda is just a symbol in some data structure (as far
as the compiler is concerned) rather than being a reference to the
external `val' variable.  With dynamic scoping, this worked, but not
with lexical scoping.

`defsubst' tends to be a bit more costly than an "equivalent" defmacro,
but that's less so when compiling with lexical scoping, which is why
I think it's OK to make things like class-p into defsubsts.

>> -              (mapc (lambda (g) (add-to-list 'groups g))
>> +              (mapc (lambda (g) (pushnew g groups :test #'equal))
> Similar question.  Is add-to-list bad for lexical binding?

Very much so, yes, because here again "'groups" just returns a symbol
and the compiler has no idea it's related to the "groups" variable.


        Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]