Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Anonymous classes should be supported #1001

Open
Util opened this issue Oct 3, 2013 · 1 comment
Open

Anonymous classes should be supported #1001

Util opened this issue Oct 3, 2013 · 1 comment

Comments

@Util
Copy link
Member

Util commented Oct 3, 2013

Reported by: zefram@fysh.org

The newclass op creates a class metaobject, which is returned in the pmc register that is its output parameter. However, it insists on also putting something into the global namespace. This gives the impression that it's impossible to create an anonymous class. It should be possible to create an operable class without touching the global namespace.

Strangely, what's placed in the global namespace isn't the class metaobject. It's a namespace, apparently intended to contain the class's methods:

$ cat t29.pir
.HLL "zz"
.sub main :main
        $P0 = newclass "Foo"
        $P1 = $P0."new"()
        $P2 = get_namespace
        $P3 = iter $P2
        next:
        unless $P3 goto done
        $P4 = shift $P3
        say $P4
        goto next
        done:
        say ":::"
        $P5 = get_global "Foo"
        $I0 = isa $P5, "NameSpace"
        say $I0
.end
$ ./parrot t29.pir
main
Foo
:::
1

This arrangement is inside-out: part of the class's internals (the method namespace) has been made visible to the world while the class as a whole is only known to the code that created it.

Furthermore, the subclass op apparently can create an anonymous _sub_class. If it's used without a third operand, it returns a class metaobject and does not put anything new into the global namespace. I'm mystified as to where its method namespace lives, though.

Some IRC discussion on the topic:

<Zefram> I'm finding it inconvenient that some ops insist on writing
    into the namespace in addition to returning their result in a
    register
<Util> Zefram: Do you have an example of the "writing into the
    namespace in addition..."? Or was that one of the 12 bug reports?
<Util> re: anonymous classes; I need to look at the code before I speak
    to that.
<Zefram> I can put together an example if you want.  it's behaviour of
    the newclass op, which returns a class metaobject and also writes
    into the namespace using the name that it was given
<Zefram> the documentation has some mention of using the subclass op
    to get an anonymous subclass, but doesn't mention any way to get
    an anonymous class without providing a parent class
<Zefram> the newclass behaviour looks more like a deliberate design
    decision than a mistake, which is why I've classed this issue as
    subjective and needing opinions before proceeding with a ticket.
    but the availability of anonymous subclasses (if that actually
    works) makes newclass look anomalous
<Zefram> unfortunately investigating just what gets written into the
    namespace is impeded by the typeof and isa anomalies that are
    somewhere in the twelve reports that I mailed to you
<rurban> but even anonymous classes need a parent
<rurban> in my case an empty parent uses the default Object as parent
    class. names should be just optional, yes. registering them into
    namespaces makes lexically scoped classes hard
<rurban> this needs a discussion on the mailing list
<rurban> but should be no problem to implement
<Zefram> guess I should open a ticket for it then
<Zefram> thanks
<rurban> p5-mop has exactly this very problem
<Zefram> yeah, it's really difficult to work around Perl 5's use of
    the name as a proxy for the class all over the place
<benabik> I occasionally wonder if Parrot's idea of a single global
    namespace is problematic in and of itself.
<Zefram> but Parrot does have class metaobjects
<Zefram> I think Parrot's built-in namespace is an abstraction
    inversion. but not really *wrong* in itself
<rurban> names are needed for the general usecase, but should be
    optional for the simple, fast and small lexical case
<Zefram> you've just got to watch out for things *relying* on the
    namespace, which is where Perl 5 has a problem
<benabik> Well, Parrot's class mechanism is tied to its namespaces.
<Zefram> there are some Parrot doc notes about using namespaces to
    manage named methods, which has me a bit worried
<Zefram> does that imply that a class must have an absolute name?
<benabik> Probably.
<rurban> hmm...
<Zefram> if a class must have an absolute name, then you can't GC
    classes, because the namespace keeps a reference to some aspects
    of the class
<benabik> Yup.
<Zefram> if it's all managed through class metaobjects, otoh, you can
    GC classes perfectly well, and there's nothing to stop you naming
    a class (by storing the class metaobject in the namespace)
<Zefram> hence abstraction inversion to have the namespace come first
<benabik> Having to store methods in a namespace would also be less
    of an issue if the namespaces weren't global.
<Zefram> oh yes, there's no problem having an internal namespace for
    methods that just hangs from the class metaobject
<Zefram> that's all gcable
<benabik> The "natural" result (IMHO) is that you remove the global
    namespace and just have lexical outer ones.  Loading a modules
    returns a namespace that you can install into your own namespaces
    however you want.  (merge, name, leave anonymous, whatever.)
<benabik> But anyway...

-zefram

@Util
Copy link
Member Author

Util commented Oct 5, 2013

I (zefram@fysh.org) wrote:

Furthermore, the subclass op apparently can create an anonymous _sub_class. If it's used without a third operand, it returns a class metaobject and does not put anything new into the global namespace.

Looking at the implementation, it appears that a class's method namespace is reachable by a direct reference from the class metaobject, which ought to make it possible for anonymous classes to work. The implementations of the newclass and subclass ops also make it pretty obvious that a class could be created with neither name nor superclass.

However, much of the logic around classes (especially in the "isa_pmc" implementations) uses class names as cache keys and as a proxy to compare classes. So anonymous classes probably won't work in these basic operations. These should be reimplemented based strictly on the class metaobjects.

Incidentally, lazy creation of the PMCProxy objects seems a false economy. Might as well create them up front, and use them freely in class logic.

-zefram

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant