Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Objects, finally (try 1)

29 views
Skip to first unread message

Dan Sugalski

unread,
Jan 9, 2003, 4:40:20 PM1/9/03
to perl6-i...@perl.org
Okay, as promised, here's the object proposal for parrot. (And yes,
it was finished by 5PM EST--if you got it later, it just means I
lingered over coffee in a blissfully wireless-free coffee shop down
the street from my apartment)

Objects, as far as I see it, have the following properties:

1) They have runtime-assignable properties
2) They have reference semantics
3) They belong to a class
4) The class they belong to may be the child of one or more parent
classes
5) You can call methods on them
6) They have a set of attributes
7) They may inherit attributes from their parent class(es)
8) Attributes are mostly private to the declaring class
9) They don't have a value outside their attributes
10) Parent classes can only be in the inheritance hierarchy once.
11) They are all orange

There are probably other core object properties that I've
missed. This would be the time to mention them.

Now, as far as the above go, here's what we're going to need to add,
and what I'm proposing.

#1 is provided by core services already. We do need to work out
whether properties get propagated to the object or stay with the
reference part, but as property assignment's delegated to the PMC
itself we can do this with no core changes.

#2 can be done with a reference PMC type that delegates most of its
operations to its referent. This isn't much (if any) different from
regular references, and just needs a PMC class for it. No biggie.

#3 Since each class has a PMC type, we just need to associate the PMC
type with the data a class needs. Also pretty much no big deal, and
something we already have facilities for.

#4 is a matter either for method dispatch, which is handled by the
PMC's vtable method entry, or for attribute construction, which
we'll deal with in a little bit.

#5 We can already do this, via the method entry in the PMC's
vtable. We need to better define how it works, since I've been
unreasonably fuzzy about it. I'll do that in a little, hopefully
with a JIT-friendly spin.

#6 Attributes. These are just a set of slots with names associated
with them. Objects are essentially an attribute chunk wrapper with
some metadata. I'll describe them after the end of the list

#7 This means that we have to deal with a parent class looking for
attributes insinde an object of a child class

#8 means we may potentially deal with multiple attributes of the same
name in an object, in separate parent classes

#9 Yes, this is different from perl 5's object model. That's fine, as
it won't impact perl 5 object code running on us. (Think about it
for a second, given what we already have in place... :)

#10 We do MI, but we don't instantiate a class' attributes multiple
times if its in the hierarchy for a class more than once. If it is,
the leftmost instance is real, the rest are virtual

#11 This goes without saying, of course

So, with these things in place, what do we need? I see the current
scheme needing extension in three places

1) We need callmeth and jmpmeth opcodes

2) The method call vtable entry needs to be better defined.

3) We need to define what the heck attributes are and how the work
for an object

4) We need to define how attributes work for classes

The call/jmpmeth opcodes either make a returnable or non-returnable
method call. They fetch the function pointer from the object PMC and
either dispatch to it or save the current state and jsr to it. Note
that you can't jmpmeth into a C-implemented method, so no tail
calling into those without some wrapper opcodes. The registers still
need to be set up appropriately, just like with a regular sub call.

The find_method vtable entry should die, and be replaced with a plain
method entry. This should return either the address of the start of
the method's bytecode, or NULL. The NULL return is for those cases
where the method actually executed via native code, and thus doesn't
have to go anywhere. If an address is returned it's expected that the
engine will immediately dispatch to that spot, obeying parrot's
calling conventions.

For object attributes, we're going to use an Attr PMC. Its data
pointer points to an attribute bufffer, which is just an array. Each
attribute takes up a single slot in the array. By default attributes
must be GC-able entities, but if someone objects and is willing to
pay the speed penalty they can have an Attr subclass that has a
custom GC routine. (I'm not convinced that the speed loss outweighs
the memory win, hence the default restrictions)

Classes are a type of object, and the attributes in classes keep
track of the important meta-information for objects. For example, one
of the class attributes is a hash that has a name->slot mapping table
so we don't have to duplicate it for each object.

We have the option of either building in attribute lookup code to the
interpreter, or adding in a few vtable methods. I'm more inclined to
gp with interpreter support, as we've got more than enough vtable
entries as it is, but I can be convinced otherwise. If we *do* add in
vtable support I think we can safely skip the keyed versions, since
the only things that should be getting attribute info are the methods
for a class, and by the time you're in there you have to have a real
object, not an index into an array or something.

The structures:

*) Attr PMCs have an array off their data pointer.

*) Classes are variants of Attr PMCs. They have the following
guaranteed attributes in slots:

0) Hash with class name to attribute offset
1) Hash with attribute name to attribute offset (relative to the
offset found from the hash in slot 0, generally known at
compile time, but introspection is nice)
2) Integer number of attributes this class has
3) Notification array

Finally, for perl 5 compatibility, we don't have to add anything
special to the interpreter engine. Having an appropriate method
vtable entry for perl 5 classes is all it takes, and that's no big
deal. (As perl 5 classes are just hashes/arrays/scalars with a special
method call entry)

I'm not 100% sure how to handle delegation, so for right now we're
just punting. No automatic delegation. This *will* be fixed, but we
can hash it out after this proposal has been ravaged appropriately.

So.... have at it. What have I forgotten, what's wrong, and who's got
questions on how this works? (I can put together examples, but this
is pretty long as it is, and I think it's reasonably
self-explanatory. Besides, assembly language isn't generally the best
way to demonstrate anything... :)

--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Peter Haworth

unread,
Jan 10, 2003, 8:37:34 AM1/10/03
to perl6-i...@perl.org
On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
> #10 We do MI, but we don't instantiate a class' attributes multiple
> times if its in the hierarchy for a class more than once. If it is, the
> leftmost instance is real, the rest are virtual

This will mean we can't support Eiffel, which allows repeated real
inheritance of the same class. It does this by allowing renaming at the
feature level (thats attributes and methods in perl) when inheritance is
declared. Repeated inherited features are shared if they keep the same name
(and they really are the same feature), or split if they don't.

--
Peter Haworth p...@edison.ioppublishing.com
Warning! Your Operating System is out of date!
It can be replaced by a more memory abusive Operating System.
Please contact your System Vendor for details.

Attriel

unread,
Jan 10, 2003, 10:37:44 AM1/10/03
to perl6-i...@perl.org
> On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
>> #10 We do MI, but we don't instantiate a class' attributes multiple
>> times if its in the hierarchy for a class more than once. If it is,
>> the leftmost instance is real, the rest are virtual

My only question here is: What is leftmost? Is that the same as "closest
to the actual class we're looking at" or is it "first time it appears in
the inheritance structure, and thus the furthest from the relevant class"
? (or something else entirely?)

> This will mean we can't support Eiffel, which allows repeated real
> inheritance of the same class. It does this by allowing renaming at the
> feature level (thats attributes and methods in perl) when inheritance is
> declared. Repeated inherited features are shared if they keep the same
> name (and they really are the same feature), or split if they don't.

I'll admit to never having gotten to looking at eiffel, just hearing about
it from some other folks ...

But what is the point of explicitly inheriting from the same class
multiple times? I mean, sure, if it's in the inheritance tree multiple
times, fine, but then you ignore most of them generally; what benefit/use
comes from having it actually be in the tree multiple times as distinct
entities?

I'm just wondering there ...

But if it's renaming the structure anyway, wouldn't it still be possible
with the single-MI structure that dan proposed? as in, if B inherits from
A and then C inherits from A and B directly (and assuming there's a need
to separately retain the individual inheritance directions), wouldn't the
compiler then say that B inherits from A and C inherits from A2 and B, to
retain them both in the parrot?

--attriel

(I could, of course, be horribly wrong, had I stated a firm opinion rather
than requests for more information :)


Dan Sugalski

unread,
Jan 10, 2003, 11:49:14 AM1/10/03
to Peter Haworth, perl6-i...@perl.org
At 1:37 PM +0000 1/10/03, Peter Haworth wrote:
>On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
>> #10 We do MI, but we don't instantiate a class' attributes multiple
>> times if its in the hierarchy for a class more than once. If it is, the
>> leftmost instance is real, the rest are virtual
>
>This will mean we can't support Eiffel

Nope. :)

What it means is that the proposed base object system won't work for
eiffel. There are very few proposed core changes to support this
object system, and if you think about it the expressed program-level
semantics are sufficient for eiffel (I think), it's just the
behind-the-curtain bits that aren't. And there's nothing to say that
a theoretical eiffel implementation couldn't just have a different
Attr-style object. (Eiffel's classes, IIRC, are compile-time fixed so
it can do the necessary code cloning and renaming magic to make it
all work. I suppose we could too, but it's a lot more work to do it
since things can change at runtime in perl/python/ruby classes)

Dan Sugalski

unread,
Jan 10, 2003, 11:53:36 AM1/10/03
to att...@d20boards.net, perl6-i...@perl.org
At 10:37 AM -0500 1/10/03, attriel wrote:
> > On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
>>> #10 We do MI, but we don't instantiate a class' attributes multiple
>>> times if its in the hierarchy for a class more than once. If it is,
>>> the leftmost instance is real, the rest are virtual
>
>My only question here is: What is leftmost? Is that the same as "closest
>to the actual class we're looking at" or is it "first time it appears in
>the inheritance structure, and thus the furthest from the relevant class"
>? (or something else entirely?)

For attributes it doesn't matter. For methods, well, I'm not sure
whether a leftmost depth-first insertion is right or inserting it
somewhere else is better. I expect Damian Has The Answer. (Or, if I
remember from the last time I asked, several answers of which there
wasn't a clear Best Answer)

> > This will mean we can't support Eiffel, which allows repeated real
>> inheritance of the same class. It does this by allowing renaming at the
>> feature level (thats attributes and methods in perl) when inheritance is
>> declared. Repeated inherited features are shared if they keep the same
>> name (and they really are the same feature), or split if they don't.
>
>I'll admit to never having gotten to looking at eiffel, just hearing about
>it from some other folks ...
>
>But what is the point of explicitly inheriting from the same class
>multiple times? I mean, sure, if it's in the inheritance tree multiple
>times, fine, but then you ignore most of them generally; what benefit/use
>comes from having it actually be in the tree multiple times as distinct
>entities?

If you do redispatching of method calls it makes sense, since if
there are enough redispatches you may end up redispatching to one
class' method more than once because it's in the tree more than once,
in which case you'd want to get the correct set of attributes, as
each instance of the class in the tree should have a separate set of
attributes in that case.

>(I could, of course, be horribly wrong, had I stated a firm opinion rather
>than requests for more information :)

Ah, go for the bold statement. People are more likely to refute an
error that way. :)

Also, as I pointed out a little while ago, this is the proposal for
the base perl6/ruby/python object scheme, but there's nothing that
forbids transparent interoperability with a different object scheme.

Jerome Quelin

unread,
Jan 10, 2003, 12:12:41 PM1/10/03
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski wrote:
> and who's got
> questions on how this works? (I can put together examples, but this
> is pretty long as it is, and I think it's reasonably
> self-explanatory. Besides, assembly language isn't generally the best
> way to demonstrate anything... :)

Well, as far as I'm concerned, an assembly snippet would be nice.
But I can as well wait for implementation and study what will be
relevant to objects in the t/ directory.

Indeed, once you wrote some Parrot assembly code to support a^Htwo
stupid^Wesoteric languages, Parrot assembly is quite a nice and easy
way to see how theory behaves in real life... :o)

Jerome
--
jqu...@mongueurs.net

Chris Dutton

unread,
Jan 10, 2003, 2:57:13 PM1/10/03
to perl6-i...@perl.org
On Friday, January 10, 2003, at 11:49 AM, Dan Sugalski wrote:

> At 1:37 PM +0000 1/10/03, Peter Haworth wrote:
>> This will mean we can't support Eiffel
>
> Nope. :)
>
> What it means is that the proposed base object system won't work for
> eiffel.

Actually, if you really want Eiffel to compile to Parrot, it might be
interesting to work on getting ANSI C to compile to Parrot first, since
most Eiffel compilers use compilation to C as an intermediate step.

You might lose the ability to reuse an Eiffel-created object with other
languages, but if you're using Eiffel, you're probably not going to be
happy with object-orientation in any language that doesn't strictly
enforce DBC anyway. ;-)

gre...@focusresearch.com

unread,
Jan 10, 2003, 11:18:19 AM1/10/03
to att...@d20boards.net, perl6-i...@perl.org
Here are some examples from Object Oriented Software Construction (Second
Edtion), Chapter 15 (Multiple Inheritance):

* Simple multiple inheritance:

class PLANE ...
class ASSET ...
class COMPANY_PLANE inherit PLANE ASSET ...

or

class TREE [G] ... -- Parametric Polymorphism
class RECTANGLE ...
class WINDOW inherit TREE[WINDOW] RECTANGLE ...

* Renaming:

class WINDOW inherit
TREE [WINDOW]
rename
child as subwindow,
is_leaf as is_terminal,
root as screen,
arity as child_count, ...
end
RECTANGLE
...

* Page 548, "Unobtrusive repeated inheritance":

Cases of repeated inheritance [...], with duplicated features as
well as shared
ones, do occur in practice, but not frequently. THey are not for
beginners;
only after you have reached a good level of sophistication and
practice in
object technology should you encounter any need for them.

If you are writing a straightforward application and end up using
repeated
inheritance, you are probably making things more complicated than
you need to.

* Redundant inheritance:

class A ...
class B inherit A ...
class D inherit B A ... -- Forgetting that B inherits from A

In Eiffel, the default sharing semantics for multiple inheritance
means this misstep
doesn't cause weird things to happen.

* Other weirdness

class DRIVER ... -- violation count, address, etc.
class US_DRIVER inherit DRIVER ...
class FR_DRIVER inherit DRIVER ... -- Ah, France!
class US_FR_DRIVER inherit US_DRIVER rename violations as
us_violations, ...
FR_DRIVER rename violations as fr_violations.

PLEASE NOTE: I'm not a fan of this example. But, it comes from the
book. I'd be more
likely to model this as DRIVER has-a SET of LICENSEs keyed-by
AUTHORITY,
where the LICENSE has stuff like licensed address and violation
count, etc. But,
then, my thinking and modeling habits tend toward the dynamic, and
Eiffel tends
toward the static. The implications of continuing the pattern of this
example in
the face of a larger set of authorities (countries) is, well,
explosive (speaking
combinatorically). In the face of a dynamic set of authorities, its
unworkable.

Anyway, I know that the Eiffel libraries make plenty of use of Eiffel's
inheritance
and assertion mechanisms. I don't know how often these more complicated
situations arise in practice. The point is, Eiffel does have these
mechanisms
defined and they are expected to be available, and possibly required just
to
build mundane applications that use the standard library.


Regards,

-- Gregor

"attriel" <att...@d20boards.net>
01/10/2003 10:37 AM
Please respond to attriel


To: <perl6-i...@perl.org>
cc:
Subject: Re: Objects, finally (try 1)


> On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
>> #10 We do MI, but we don't instantiate a class' attributes multiple
>> times if its in the hierarchy for a class more than once. If it is,
>> the leftmost instance is real, the rest are virtual

My only question here is: What is leftmost? Is that the same as "closest
to the actual class we're looking at" or is it "first time it appears in
the inheritance structure, and thus the furthest from the relevant class"
? (or something else entirely?)

> This will mean we can't support Eiffel, which allows repeated real


> inheritance of the same class. It does this by allowing renaming at the
> feature level (thats attributes and methods in perl) when inheritance is
> declared. Repeated inherited features are shared if they keep the same
> name (and they really are the same feature), or split if they don't.

I'll admit to never having gotten to looking at eiffel, just hearing about
it from some other folks ...

But what is the point of explicitly inheriting from the same class
multiple times? I mean, sure, if it's in the inheritance tree multiple
times, fine, but then you ignore most of them generally; what benefit/use
comes from having it actually be in the tree multiple times as distinct
entities?

I'm just wondering there ...

But if it's renaming the structure anyway, wouldn't it still be possible
with the single-MI structure that dan proposed? as in, if B inherits from
A and then C inherits from A and B directly (and assuming there's a need
to separately retain the individual inheritance directions), wouldn't the
compiler then say that B inherits from A and C inherits from A2 and B, to
retain them both in the parrot?

--attriel

(I could, of course, be horribly wrong, had I stated a firm opinion rather

Gopal V

unread,
Jan 10, 2003, 11:42:42 PM1/10/03
to Chris Dutton, perl6-i...@perl.org
If memory serves me right, Chris Dutton wrote:
> Actually, if you really want Eiffel to compile to Parrot, it might be
> interesting to work on getting ANSI C to compile to Parrot first, since
> most Eiffel compilers use compilation to C as an intermediate step.

This won't be too much of stretch .... We already have an ANSI C compiler
working well with DotGNU pnet.. (with a IL output plugin)...

<log of="#dotgnu" on="22-10-2002">

[11:31] <rhysw> Dan: to go off on a different tangent now - C support
[11:31] <rhysw> Dan: compiling C to Parrot, that is
[11:31] <Dan> Ah, that. Yeah, definitely doable. It'll be rather slow, though
[11:31] <Dan> Our function call overhead's rather large compared to what C needs
[11:32] <Dan> Still, I find the thought of C with native continuations rather interesting. Scary, but interesting
[11:32] <rhysw> Dan: I was more thinking of the memory layout issues. C code is very particular about struct layout, array representation, etc. I didn't see any opcodes that would allow one to do "pull an int32 out of offset N from this pointer".
[11:33] <Dan> C's not at all particular about struct layout, unless they changed the standard.
[11:33] <Dan> Still, you can do them either with struct PMCs, whcih'd be slowish, or with the pack/unpack opcodes, which I bet are insufficiently documetned
[11:34] Action: Dan apparently can't type this evening
[11:35] <Dan> Still, the packed structures need more thoght. Hrm.
[11:35] <rhysw> Dan: I suppose a better question would be "is supporting C a goal, or would it just be a cool hack but otherwise uninteresting?"
[11:36] <rhysw> because, as you say, it wouldn't be terribly efficient ...
[11:36] <Dan> Neither, really. It's interesting in the sense that it'd let people use code that they otherwise couldn't, if they don't have a C compiler for.
[11:36] <Dan> But it's definitely not a primary goal
[11:36] <Dan> Consider it both mildly interesting and mildly bemusing :)
[11:37] <fitzix> Dan: It could make it very useful as a power tool
[11:37] <Kyeran> Could someone toss up the Parrot URL so I can find out what it is? :)
[11:37] <fitzix> Dan: sort of a "swiss army knife" kind of thing
[11:37] <Dan> True, but I'm not willing to lose sight of the primary goal for it.

</log>

Was our last conversation about Parrot & C compilers ..

We'll be adding a Parrot codegen for the compiler backend , as soon as the
Objects are set in stone.... So possibly there exists a possibility for doing
up the C compiler (with codegen tweaking) to develop a C compiler targetting
Parrot.


Gopal
--
The difference between insanity and genius is measured by success

Leopold Toetsch

unread,
Jan 11, 2003, 3:38:32 AM1/11/03
to Jerome Quelin, Dan Sugalski, perl6-i...@perl.org
Jerome Quelin wrote:

> Dan Sugalski wrote:
>
>>... Besides, assembly language isn't generally the best


>>way to demonstrate anything... :)

> Indeed, once you wrote some Parrot assembly code to support a^Htwo

> stupid^Wesoteric languages, Parrot assembly is quite a nice and easy
> way to see how theory behaves in real life... :o)


Good point. The implmentation of $thing does show, how's the real
usability. These totally unneeded^Wsuperfluous^Wfine languages brought
parrot & imcc a lot further.


> Jerome


leo

Nicholas Clark

unread,
Jan 11, 2003, 5:50:03 AM1/11/03
to Gopal V, Chris Dutton, perl6-i...@perl.org
On Sat, Jan 11, 2003 at 10:12:42AM +0530, Gopal V wrote:
> If memory serves me right, Chris Dutton wrote:
> > Actually, if you really want Eiffel to compile to Parrot, it might be
> > interesting to work on getting ANSI C to compile to Parrot first, since
> > most Eiffel compilers use compilation to C as an intermediate step.

> [11:32] <rhysw> Dan: I was more thinking of the memory layout issues. C code is very particular about struct layout, array representation, etc. I didn't see any opcodes that would allow one to do "pull an int32 out of offset N from this pointer".


> [11:33] <Dan> C's not at all particular about struct layout, unless they changed the standard.
> [11:33] <Dan> Still, you can do them either with struct PMCs, whcih'd be slowish, or with the pack/unpack opcodes, which I bet are insufficiently documetned

Probably this has all been worked out by now, but Rhys and Dan are coming at
it from different angles. C isn't fussy, but the ABI for a platform is very
fussy. I presume Rhys is thinking about compiling C code to parrot, and then
linking through to native C code (such as the native standard C library) via
parrot. Dan's assuming that C code we compile never wants to call out to the
platform. If I remember the terms correctly, Dan's thinking about
free standing C implementations. Effectively that would give Inline::C
without needing a C compiler, but you'd not be able to call out from your
C code.

What Rhys is thinking about is potentially far more interesting, as it would
allow the perl6 version of Inline::C to wrap external libraries supplied
only as objects and headers, without needing a C compiler on the machine.
It's also harder, partly because such a system would need to know the ABI for
each platform you wanted to do this on.

But if anyone has tuits, could we have a z-code interpreter first please?
Or better still, a unified, fast, assembler?
(with a pony?)

Nicholas Clark

Gopal V

unread,
Jan 11, 2003, 8:04:56 AM1/11/03
to perl6-i...@perl.org
If memory serves me right, Nicholas Clark wrote:
> fussy. I presume Rhys is thinking about compiling C code to parrot, and then
> linking through to native C code (such as the native standard C library) via
> parrot.

Nope ... At least for our .NET platorm stuff ,we are planning to compile
glibc into IL so that the "native ABI" is accessed only via the engine.
Most peices of glibc, depend on a few platform functions to run (most
notably some in unistd.h) ... Most of the other peices of glibc can be
directly used like the printf formatting code or file functions , once
these underlying posix calls are in place... this is consistent with design
philosophy of glibc which has been source portability rather than binary.

So get your own glibc-managed.dll according to long,int, and char sizes :)

> without needing a C compiler, but you'd not be able to call out from your
> C code.

We are facing a similar situation, but only that we have PInvoke (like your
NCI) which allows you to define PInvoke methods from Managed C (I'd prefer
the term Micro-Managed :)

But the following does work for some functions :)

extern int puts(const char *s) __attribute__((__pinvoke__("libc.so.6")));

mm... ugly !

Rhys has also been really cool about the data stored via C ... So legacy
code which used fixed size files (otherwise called "records") will be useful.
This allows us to declare 8bit characters and strings of those and all the
stuff we're used to with C like unions ... (C# has 16bit chars, and strings
are UTF8 encoded , IIRC) ...

In short, we will keep similar layouts in memory for structs and unions as
far as possible ... (unions without offset based access to memory boggles
my mind....)

So even with all the type-safety of IL we can run the following code ...

float a=3.14;
int b=*((int*)(&(a)));

> What Rhys is thinking about is potentially far more interesting, as it would

What Rhys is using right now is a custom stdlib which is called pnetC and
was just released ... People *really* curious about what Rhys is doing
(and what those half-a-million lines are doing in DotGNU) should try the
Portable.net C compiler (http://dotgnu.org/downloads/pnet/) .. We have
mirrors on each gnu mirror as /projects/dotgnu ... (since we're likely to
be slashdotted to death soon....)

Very, Very curiously ... I can call C# methods from Managed C, but not the
otherway around :) .. and I can call native methods from Managed C , but
that's dreadfully unportable like you said ...

I'm really working only to get C# compiled to Parrot .... other language
frontends in development like Java or C or JScript can wait a looong time.

Nicholas Clark

unread,
Jan 11, 2003, 11:08:50 AM1/11/03
to Dan Sugalski, perl6-i...@perl.org

On Thu, Jan 09, 2003 at 04:40:20PM -0500, Dan Sugalski wrote:
> The find_method vtable entry should die, and be replaced with a plain
> method entry. This should return either the address of the start of
> the method's bytecode, or NULL. The NULL return is for those cases
> where the method actually executed via native code, and thus doesn't
> have to go anywhere. If an address is returned it's expected that the
> engine will immediately dispatch to that spot, obeying parrot's
> calling conventions.


What about the case where the object doesn't have the method you're asking
for? You seem to be using NULL to mean something other than "not found",
so does that mean not found is an exception?

And if NULL is returned it is expected that the method has already been
called? If so, there doesn't seem to be any way to find out if a PMC
possesses (modulo AUTOLOAD) a method, without the danger of it being called.

Will there be anything built in at parrot level like Perl's AUTOLOAD system?
Or will that have to be done explicitly by the perl6 code generator wrapping
methods in a routine that catches the "not found" exception, and attempts to
use AUTOLOAD? [and whatever multimatch despatch system perl6 will be using to
find the "best" method]

Nicholas Clark

Nicholas Clark

unread,
Jan 11, 2003, 11:01:59 AM1/11/03
to Gopal V, perl6-i...@perl.org
On Sat, Jan 11, 2003 at 06:34:56PM +0530, Gopal V wrote:
> If memory serves me right, Nicholas Clark wrote:
> > fussy. I presume Rhys is thinking about compiling C code to parrot, and then
> > linking through to native C code (such as the native standard C library) via
> > parrot.
>
> Nope ... At least for our .NET platorm stuff ,we are planning to compile
> glibc into IL so that the "native ABI" is accessed only via the engine.

Oh right. As you commented on IRC, I am very wrong.

> Rhys has also been really cool about the data stored via C ... So legacy
> code which used fixed size files (otherwise called "records") will be useful.
> This allows us to declare 8bit characters and strings of those and all the
> stuff we're used to with C like unions ... (C# has 16bit chars, and strings
> are UTF8 encoded , IIRC) ...

That doesn't sound right. But if it is right, then it sounds very wrong.

(Translation: Are you sure about your terms, because what you describe sounds
wonky. Hence if they are using UTF8 but with 16 bit chars, that feels like a
silly design decision to me. Perl 5 performance is not enjoying a variable
length encoding, but using an 8 bit encoding in 8 bit chars at least makes
it small in memory.)

> So even with all the type-safety of IL we can run the following code ...
>
> float a=3.14;
> int b=*((int*)(&(a)));

Ooh. So what happens if I try to run:

char *a = 0;
*a++;

:-)

Does the VM just "segfault" the failing thread, rather than all threads in
a process?

> What Rhys is using right now is a custom stdlib which is called pnetC and
> was just released ... People *really* curious about what Rhys is doing
> (and what those half-a-million lines are doing in DotGNU) should try the
> Portable.net C compiler (http://dotgnu.org/downloads/pnet/) .. We have
> mirrors on each gnu mirror as /projects/dotgnu ... (since we're likely to
> be slashdotted to death soon....)

> I'm really working only to get C# compiled to Parrot .... other language
> frontends in development like Java or C or JScript can wait a looong time.

Hmm. So if DotGNU has a C to Parrot compiler, then we just compile the perl5
source code down to Parrot bytecode, et voilá, we have a perl implementation.
I do hope no-one wanted it to go fast. :-)
[then again, I wonder how the parrot JIT would cope]

So Rhys is mad:

> The difference between insanity and genius is measured by success

I hope he falls on the right side of the divide.

Nicholas Clark

Gopal V

unread,
Jan 11, 2003, 12:03:58 PM1/11/03
to Nicholas Clark, perl6-i...@perl.org
If memory serves me right, Nicholas Clark wrote:
> That doesn't sound right. But if it is right, then it sounds very wrong.
>
> (Translation: Are you sure about your terms, because what you describe sounds
> wonky. Hence if they are using UTF8 but with 16 bit chars, that feels like a
> silly design decision to me. Perl 5 performance is not enjoying a variable
> length encoding, but using an 8 bit encoding in 8 bit chars at least makes
> it small in memory.)

I mean they're using UTF8 encoded strings ... and chars are 16 bit ...
which means that reading chars from strings is wonky (from all I remember,
ILString* uses int16[] for storing stuff... but the files do use UTF8)..
Actually I think the ILImage functions in Portable.net abstract out the
UTF8 reading and return int16* arrays ...

Hope that makes more sense :)

> Ooh. So what happens if I try to run:
>
> char *a = 0;
> *a++;

Assuming you meant (*a)++; ... coz *a++; is optimsed away into just a++;
by GCC ..

> Does the VM just "segfault" the failing thread, rather than all threads in
> a process?

How does this do for an answer ?

Uncaught exception: System.NullReferenceException: The value 'null' was found where an instance of an object was required
at <Module>.main() in segfault.c:3
at <Module>..start(String[])

Bye Bye segfaults, hello exceptions ...

> Hmm. So if DotGNU has a C to Parrot compiler, then we just compile the perl5
> source code down to Parrot bytecode, et voilá, we have a perl implementation.

This is assuming we can get all the perl5 dependencies compiled to Parrot
without any issues ... (in fact this might be very,very hard... considering
the fact that parrot codegen is still commented out for most of portable.net).

> I do hope no-one wanted it to go fast. :-)
> [then again, I wonder how the parrot JIT would cope]

Which is why nobody is really interested in doing this :-) ... we're
building the C compiler for fun ...

> So Rhys is mad:
>
> > The difference between insanity and genius is measured by success
>
> I hope he falls on the right side of the divide.

That's *my* sig ... and I'm attempting a cross-over :)

Gopal
--

Dan Sugalski

unread,
Jan 11, 2003, 1:25:37 PM1/11/03
to Nicholas Clark, perl6-i...@perl.org
At 4:08 PM +0000 1/11/03, Nicholas Clark wrote:
>On Thu, Jan 09, 2003 at 04:40:20PM -0500, Dan Sugalski wrote:
>> The find_method vtable entry should die, and be replaced with a plain
>> method entry. This should return either the address of the start of
>> the method's bytecode, or NULL. The NULL return is for those cases
>> where the method actually executed via native code, and thus doesn't
>> have to go anywhere. If an address is returned it's expected that the
>> engine will immediately dispatch to that spot, obeying parrot's
>> calling conventions.
>
>
>What about the case where the object doesn't have the method you're asking
>for? You seem to be using NULL to mean something other than "not found",
>so does that mean not found is an exception?

Sorry. The assumption is one of three things happen:

1) A value is returned, which is the address of the parrot code to dispatch to
2) A NULL is returned, which indicates the method call has been made
and the interpreter can proceed to the next instruction in the stream
3) An exception is thrown, indicating that the method couldn't be called.

>And if NULL is returned it is expected that the method has already been
>called? If so, there doesn't seem to be any way to find out if a PMC
>possesses (modulo AUTOLOAD) a method, without the danger of it being called.

If we don't have a can in the vtable, then we need to fix that. :)

>Will there be anything built in at parrot level like Perl's AUTOLOAD system?
>Or will that have to be done explicitly by the perl6 code generator wrapping
>methods in a routine that catches the "not found" exception, and attempts to
>use AUTOLOAD? [and whatever multimatch despatch system perl6 will be using to
>find the "best" method]

Parrot will have an AUTOLOAD-style fallback mechanism available to
it. I'll add that to the design todo list for the edited version of
objects.

Dan Sugalski

unread,
Jan 11, 2003, 1:28:20 PM1/11/03
to Jerome Quelin, perl6-i...@perl.org
At 6:12 PM +0100 1/10/03, Jerome Quelin wrote:
>Dan Sugalski wrote:
>> and who's got
>> questions on how this works? (I can put together examples, but this
>> is pretty long as it is, and I think it's reasonably
>> self-explanatory. Besides, assembly language isn't generally the best
>> way to demonstrate anything... :)
>
>Well, as far as I'm concerned, an assembly snippet would be nice.
>But I can as well wait for implementation and study what will be
>relevant to objects in the t/ directory.

I'll put together some of what I'm thinking of next week with the
first rev of the object spec.

Paolo Molaro

unread,
Jan 12, 2003, 7:43:33 AM1/12/03
to perl6-i...@perl.org
On 01/11/03 Nicholas Clark wrote:
> > This allows us to declare 8bit characters and strings of those and all the
> > stuff we're used to with C like unions ... (C# has 16bit chars, and strings
> > are UTF8 encoded , IIRC) ...
>
> That doesn't sound right. But if it is right, then it sounds very wrong.
>
> (Translation: Are you sure about your terms, because what you describe sounds
> wonky. Hence if they are using UTF8 but with 16 bit chars, that feels like a
> silly design decision to me. Perl 5 performance is not enjoying a variable
> length encoding, but using an 8 bit encoding in 8 bit chars at least makes
> it small in memory.)

The CLR runtimes use 16 bit chars and UTF16-encoded strings (at least as
far as it's visible to the 'user' programs).

lupus

--
-----------------------------------------------------------------
lu...@debian.org debian/rules
lu...@ximian.com Monkeys do it better

Gopal V

unread,
Jan 12, 2003, 8:57:50 AM1/12/03
to perl6-i...@perl.org
If memory serves me right, Paolo Molaro wrote:
> The CLR runtimes use 16 bit chars and UTF16-encoded strings (at least as
> far as it's visible to the 'user' programs).

10 23.2.3 #Strings heap
11 The stream of bytes pointed to by a "#Strings" header is the physical representation of the logical string heap.
13 but parts that are reachable from a table shall contain a valid null terminated UTF8 string. When the #String

So I think the runtime does a UTF16 conversion , I suppose ...So you're right
... all C# programs get UTF16 strings to work with... but that's not the way
they're in meta-data... (JVM also has UTF8 strings and 16 bit chars, it's not
really a big issue :)

But coming back to parrot ... I don't think parrot uses UTF8 (from what
I could gather it seems to be all ASCII ?) ... Or is UTF8 hiding in
somewhere ?...

Gopal
--

Paolo Molaro

unread,
Jan 12, 2003, 10:29:15 AM1/12/03
to perl6-i...@perl.org, Gopal V
On 01/12/03 Gopal V wrote:
> If memory serves me right, Paolo Molaro wrote:
> > The CLR runtimes use 16 bit chars and UTF16-encoded strings (at least as
> > far as it's visible to the 'user' programs).
>
> 10 23.2.3 #Strings heap
> 11 The stream of bytes pointed to by a "#Strings" header is the physical representation of the logical string heap.
> 13 but parts that are reachable from a table shall contain a valid null terminated UTF8 string. When the #String

The #Strings heap doesn't contain strings for programs that run in the
CLR (unlike the #US -user sring- heap that contains the strings in
UTF-16) encoding. What matters, though, is the encoding of the String
class at runtime and that is defined to be UTF-16, it has absolutely no
importance what encoding it has on disk (even though that encoding is
still UTF-16).

Brent Dax

unread,
Jan 12, 2003, 1:07:59 PM1/12/03
to Gopal V, perl6-i...@perl.org
Gopal V:
# But coming back to parrot ... I don't think parrot uses UTF8
# (from what I could gather it seems to be all ASCII ?) ... Or
# is UTF8 hiding in
# somewhere ?...

Parrot will have a "default string type" that's build-specific, so that
e.g. Asian nations can have whatever the most popular encoding is in
their country. The "default default string type" will be utf8, but it's
currently ASCII because Unicode Is Hard.

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

"If you want to propagate an outrageously evil idea, your conclusion
must be brazenly clear, but your proof unintelligible."
--Ayn Rand, explaining how today's philosophies came to be

Dan Sugalski

unread,
Jan 12, 2003, 9:13:48 PM1/12/03
to perl6-i...@perl.org
At 7:27 PM +0530 1/12/03, Gopal V wrote:
>But coming back to parrot ... I don't think parrot uses UTF8 (from what
>I could gather it seems to be all ASCII ?) ... Or is UTF8 hiding in
>somewhere ?...

Unicode is hiding in the ICU directory, which we need to get
integrated. We'll probably be mostly UTF16, only because that's what
ICU uses and there's no good reason to reinvent the wheel again. All
three encodings and their endian variants will be supported, as will
a variety of other encodings and character sets.

Dan Sugalski

unread,
Jan 12, 2003, 9:41:19 PM1/12/03
to Brent Dax, Gopal V, perl6-i...@perl.org
At 10:07 AM -0800 1/12/03, Brent Dax wrote:
>Gopal V:
># But coming back to parrot ... I don't think parrot uses UTF8
># (from what I could gather it seems to be all ASCII ?) ... Or
># is UTF8 hiding in
># somewhere ?...
>
>Parrot will have a "default string type" that's build-specific, so that
>e.g. Asian nations can have whatever the most popular encoding is in
>their country. The "default default string type" will be utf8, but it's
>currently ASCII because Unicode Is Hard.

Well... default may well be latin-1 or plain ASCII, because Unicode
Is Unneccesary. :) Well, most of the time at least. Unicode, of
course, will be available, but if the data coming in is ASCII or
Latin-1, re-encoding's a bit of a waste of time.

Peter Haworth

unread,
Jan 13, 2003, 10:00:58 AM1/13/03
to Dan Sugalski, perl6-i...@perl.org
On Fri, 10 Jan 2003 11:49:14 -0500, Dan Sugalski wrote:
> At 1:37 PM +0000 1/10/03, Peter Haworth wrote:
> >On Thu, 9 Jan 2003 16:40:20 -0500, Dan Sugalski wrote:
> >> #10 We do MI, but we don't instantiate a class' attributes multiple
> >> times if its in the hierarchy for a class more than once. If it is,
> >> the leftmost instance is real, the rest are virtual
> >
> >This will mean we can't support Eiffel
>
> Nope. :)

I realised this soon after leaving for the weekend, thus leaving myself
looking stupid for an extended period of time :-)

> Eiffel's classes, IIRC, are compile-time fixed so it can do the necessary
> code cloning and renaming magic to make it all work.

Exactly. At the implementation level you end up directly inheriting once
from the offending class, and reimplementing some/all of the features for
the repeated inheritance, either directly in the derived class, or in a
specially constructed modified copy of the base class which is only used for
inheritance by the derived class.

I'm not an Eiffel programmer either, but I have read OOSC, so I know enough
to make me dangerous.

--
Peter Haworth p...@edison.ioppublishing.com
"An IRC channel, in ERROR?! On Undernet no less?! THE DEUCE YOU SAY!!
Next thing you're going to tell me the commentary on Slashdot isn't
totally impartial!"
-- Michael G Schwern

Jonathan Sillito

unread,
Jan 14, 2003, 12:51:22 PM1/14/03
to perl6-i...@perl.org
Dan,

Below are some questions about this ...

> -----Original Message-----
> From: Dan Sugalski [mailto:d...@sidhe.org]

[snip]

> Objects, as far as I see it, have the following properties:
>
> 1) They have runtime-assignable properties

Terminology question: what is the difference between a property and an
attribute? Perhaps the answer could go in the glossary.

[snip]

> #3 Since each class has a PMC type, we just need to associate the PMC
> type with the data a class needs. Also pretty much no big deal, and
> something we already have facilities for.

So, while there may be exceptions, generally all classes will be instances
of the Class PMC, true?

[snip]

> The call/jmpmeth opcodes either make a returnable or non-returnable
> method call. They fetch the function pointer from the object PMC and
> either dispatch to it or save the current state and jsr to it. Note
> that you can't jmpmeth into a C-implemented method, so no tail
> calling into those without some wrapper opcodes. The registers still
> need to be set up appropriately, just like with a regular sub call.

So the call opcode takes a method name or offset and calls a vtable method
to find the method and then invokes it?

> The find_method vtable entry should die, and be replaced with a plain
> method entry. This should return either the address of the start of
> the method's bytecode, or NULL. The NULL return is for those cases
> where the method actually executed via native code, and thus doesn't
> have to go anywhere. If an address is returned it's expected that the
> engine will immediately dispatch to that spot, obeying parrot's
> calling conventions.

Not sure what this means, does it mean that there is a method named
"find_method" accessed something like

call Px, Py, "find_method"

which I can then call to find the method or am I off?

[snip]

> The structures:
>
> *) Attr PMCs have an array off their data pointer.
>
> *) Classes are variants of Attr PMCs. They have the following
> guaranteed attributes in slots:
>
> 0) Hash with class name to attribute offset

I am not sure what this means, Don't we already have the class and it's
attributes if we are accessing these slots?

> 1) Hash with attribute name to attribute offset (relative to the
> offset found from the hash in slot 0, generally known at
> compile time, but introspection is nice)
> 2) Integer number of attributes this class has
> 3) Notification array

Do we store ptrs to parent classes in one of these slots? Also Can I access
slots like:

set Px, Py[1] # store the name to offset hash in Px

[snip]

So to sum up we need the following pmc's:

pmclass Ref {
data is a pointer to an object
}

pmclass Attr {
data is an array of attributes
}

pmclass Class extends Attr {
}

pmclass Object {
this was not explained, but I guess it at least
has a reference to a Class and field data ???
}

Does that cover it?
--
Jonathan Sillito

Dan Sugalski

unread,
Jan 14, 2003, 2:01:14 PM1/14/03
to Jonathan Sillito, perl6-i...@perl.org
At 9:51 AM -0800 1/14/03, Jonathan Sillito wrote:
>Dan,
>
>Below are some questions about this ...

And now some answers. :)

> > -----Original Message-----
>> From: Dan Sugalski [mailto:d...@sidhe.org]
>
>[snip]
>
>> Objects, as far as I see it, have the following properties:
>>
>> 1) They have runtime-assignable properties
>
>Terminology question: what is the difference between a property and an
>attribute? Perhaps the answer could go in the glossary.

A property is a runtime assignable name/value pair that you stick on
a variable or value. An attribute is a named variable that all
objects of a particular class have.

Properties can come and go at runtime, but attributes are fixed. (I
think you could also consider attributes "instance variables", but
I'm a bit OO fuzzy so I'm not sure that's entirely right)

> > #3 Since each class has a PMC type, we just need to associate the PMC
>> type with the data a class needs. Also pretty much no big deal, and
>> something we already have facilities for.
>
>So, while there may be exceptions, generally all classes will be instances
>of the Class PMC, true?

Generally, yes.

> > The call/jmpmeth opcodes either make a returnable or non-returnable
>> method call. They fetch the function pointer from the object PMC and
>> either dispatch to it or save the current state and jsr to it. Note
>> that you can't jmpmeth into a C-implemented method, so no tail
>> calling into those without some wrapper opcodes. The registers still
>> need to be set up appropriately, just like with a regular sub call.
>
>So the call opcode takes a method name or offset and calls a vtable method
>to find the method and then invokes it?

Yep.

> > The find_method vtable entry should die, and be replaced with a plain
>> method entry. This should return either the address of the start of
>> the method's bytecode, or NULL. The NULL return is for those cases
>> where the method actually executed via native code, and thus doesn't
>> have to go anywhere. If an address is returned it's expected that the
>> engine will immediately dispatch to that spot, obeying parrot's
>> calling conventions.
>
>Not sure what this means, does it mean that there is a method named
>"find_method" accessed something like
>
> call Px, Py, "find_method"
>
>which I can then call to find the method or am I off?

You're off. It'll be something like:

callmethod Px, "method_name"

or

jmpmethod Px, "method_name"

> > The structures:
>>
>> *) Attr PMCs have an array off their data pointer.
>>
>> *) Classes are variants of Attr PMCs. They have the following
>> guaranteed attributes in slots:
>>
>> 0) Hash with class name to attribute offset
>
>I am not sure what this means, Don't we already have the class and it's
>attributes if we are accessing these slots?

Well...

The problem is finding which slot to access, a problem that's
compounded by multiple inheritance.

Let's say, for example, that you have a class A, which inherits from
B and C. Let's also say that each class has 10 attributes, and you
have a fixed-width mail reading font. The inheritance diagram then
looks like:


C B
\ /
|
A

Since the attributes are an array, it looks like:

CCCCCCCCCCBBBBBBBBBBAAAAAAAAAA
012345678901234567890123456789

We make a method call and it gets resolved to be one we inherited
from B. Now, how does B know which slots in the object holds its
attributes? In a single-inheritance case, it could assume that since
it has no parents it can start at slot 0, but that doesn't work
here--C is first. So what B needs to do is query the object to find
out where the attributes for class B start in the attribute array,
and to do that it looks in the hash stored in the object's class
attributes that maps class names to starting offsets. From there B
can figure out what slot to look in, since class attributes are
contiguous, and thus there only needs to be a single lookup.

Single inheritance makes all this resolvable at compile time, which
would be so much nicer. Alas, no joy for us there.

> > 1) Hash with attribute name to attribute offset (relative to the
>> offset found from the hash in slot 0, generally known at
>> compile time, but introspection is nice)
>> 2) Integer number of attributes this class has
>> 3) Notification array
>
>Do we store ptrs to parent classes in one of these slots? Also Can I access
>slots like:
>
> set Px, Py[1] # store the name to offset hash in Px

No the parent's gotten to via the vtable, and yes you can.

>So to sum up we need the following pmc's:
>
> pmclass Ref {
> data is a pointer to an object
> }
>
> pmclass Attr {
> data is an array of attributes
> }
>
> pmclass Class extends Attr {
> }
>
> pmclass Object {
> this was not explained, but I guess it at least
> has a reference to a Class and field data ???
> }
>
>Does that cover it?

I'd say so, yep.

Mr. Nobody

unread,
Jan 14, 2003, 2:44:02 PM1/14/03
to perl6-i...@perl.org

Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass,
PerlObject?


__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com

Dan Sugalski

unread,
Jan 14, 2003, 3:00:17 PM1/14/03
to Mr. Nobody, perl6-i...@perl.org
At 11:44 AM -0800 1/14/03, Mr. Nobody wrote:
>Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass,
>PerlObject?

Nope. There's nothing particularly perlish about them, and if we're
going to have a common base set of object functionality, they'll
probably be named ParrotRef/Attr/Class/Object. They should suffice
for perl, python, and ruby (at the very least) unless I've missed
something.

Jonathan Sillito

unread,
Jan 14, 2003, 3:38:35 PM1/14/03
to perl6-i...@perl.org
> -----Original Message-----
> From: Dan Sugalski [mailto:d...@sidhe.org]

> A property is a runtime assignable name/value pair that you stick on
> a variable or value. An attribute is a named variable that all
> objects of a particular class have.
>
> Properties can come and go at runtime, but attributes are fixed. (I
> think you could also consider attributes "instance variables", but
> I'm a bit OO fuzzy so I'm not sure that's entirely right)

Ok, in the case of python or ruby, instance variables are not fixed and they
are not declared as part of the class. I suppose this can be handled by
giving such classes one hash attribute for storing these instance variables.

> You're off. It'll be something like:
>
> callmethod Px, "method_name"
>
> or
>
> jmpmethod Px, "method_name"
>

Is there going to be any way to (in PASM) find a method with out invoking
it? I am not sure, but it may be useful for currying and some efficiency
stuff (like moving dispatch outside of a loop that repeatedly invokes a
method).

> >Do we store ptrs to parent classes in one of these slots? Also
> Can I access
> >slots like:
> >
> > set Px, Py[1] # store the name to offset hash in Px
>
> No the parent's gotten to via the vtable, and yes you can.

Sorry if this is obvious, but which vtable method is used to get the
parents?

Thanks!
--
Jonathan Sillito

Garrett Goebel

unread,
Jan 14, 2003, 4:05:33 PM1/14/03
to Dan Sugalski, Jonathan Sillito, perl6-i...@perl.org
From: Dan Sugalski [mailto:d...@sidhe.org]
> At 9:51 AM -0800 1/14/03, Jonathan Sillito wrote:
> >
> >Below are some questions about this ...
>
> And now some answers. :)
>
> >> From: Dan Sugalski [mailto:d...@sidhe.org]
> >
> >[snip]
> >
> >> Objects, as far as I see it, have the following properties:
> >>
> >> 1) They have runtime-assignable properties
> >
> >Terminology question: what is the difference between a
> >property and an attribute? Perhaps the answer could go in
> >the glossary.
>
> A property is a runtime assignable name/value pair that you stick on
> a variable or value. An attribute is a named variable that all
> objects of a particular class have.

For a while perl6-language was using both terms for the runtime
variable/value name/value tag. This stems from Perl 5.6's attributes and
Attribute::Handlers modules. But in Perl6 s/attributes/properties/ because
properties have nothing to do with OO, whereas 'attribute' has the
"object/class data-member" meaning in OO.


> Properties can come and go at runtime, but attributes are fixed. (I
> think you could also consider attributes "instance variables", but
> I'm a bit OO fuzzy so I'm not sure that's entirely right)

Both classes and objects can have attributes.

No runtime modification of class and/or object attributes... :(

--
Garrett Goebel
IS Development Specialist
ScriptPro Direct: 913.403.5261
5828 Reeds Road Main: 913.384.1008
Mission, KS 66202 Fax: 913.384.2180
www.scriptpro.com gar...@scriptpro.com

Mr. Nobody

unread,
Jan 14, 2003, 4:24:42 PM1/14/03
to perl6-i...@perl.org

So a property is just an element in a hash attribute?

Dan Sugalski

unread,
Jan 14, 2003, 5:18:22 PM1/14/03
to Jonathan Sillito, perl6-i...@perl.org
At 12:38 PM -0800 1/14/03, Jonathan Sillito wrote:
> > -----Original Message-----
>> From: Dan Sugalski [mailto:d...@sidhe.org]
>
>> A property is a runtime assignable name/value pair that you stick on
>> a variable or value. An attribute is a named variable that all
>> objects of a particular class have.
>>
>> Properties can come and go at runtime, but attributes are fixed. (I
>> think you could also consider attributes "instance variables", but
>> I'm a bit OO fuzzy so I'm not sure that's entirely right)
>
>Ok, in the case of python or ruby, instance variables are not fixed and they
>are not declared as part of the class. I suppose this can be handled by
>giving such classes one hash attribute for storing these instance variables.

Less work than that even. While the attributes aren't declared
formally, the compiler definitely knows what they are, and can
allocate space as needed. The only place you'll run into issues is
either runtime introduction of attributes (after the class has been
compiled) or writing to attributes by name.

Though the need to add attributes after the fact is an important
one--we don't want to have to go rejigging every object that derives
from some wacky parent class every time that class adds or removes an
attribute.

> > You're off. It'll be something like:
>>
>> callmethod Px, "method_name"
>>
>> or
>>
>> jmpmethod Px, "method_name"
>>
>
>Is there going to be any way to (in PASM) find a method with out invoking
>it? I am not sure, but it may be useful for currying and some efficiency
>stuff (like moving dispatch outside of a loop that repeatedly invokes a
>method).

Yep. There should be a can operator, though I'm not sure how often
one wants to check for the existence of a method in an object without
calling it. But no reason not to. More for rev 2.

> > >Do we store ptrs to parent classes in one of these slots? Also
>> Can I access
>> >slots like:
>> >
>> > set Px, Py[1] # store the name to offset hash in Px
>>
>> No the parent's gotten to via the vtable, and yes you can.
>
>Sorry if this is obvious, but which vtable method is used to get the
>parents?

It should be hanging off the vtable as one of the fixed slots. I
think it isn't, though, so that needs fixing too.

Dan Sugalski

unread,
Jan 14, 2003, 5:19:32 PM1/14/03
to perl6-i...@perl.org
At 1:24 PM -0800 1/14/03, Mr. Nobody wrote:
>So a property is just an element in a hash attribute?

No. Properties are separate from anything OO.

Dan Sugalski

unread,
Jan 14, 2003, 5:19:05 PM1/14/03
to Garrett Goebel, Jonathan Sillito, perl6-i...@perl.org
At 3:05 PM -0600 1/14/03, Garrett Goebel wrote:
>From: Dan Sugalski [mailto:d...@sidhe.org]
>
>> Properties can come and go at runtime, but attributes are fixed. (I
>> think you could also consider attributes "instance variables", but
>> I'm a bit OO fuzzy so I'm not sure that's entirely right)
>
>Both classes and objects can have attributes.
>
>No runtime modification of class and/or object attributes... :(

Larry's decision, and a common one with OO languages. Not universal,
though, so time to go fix... :)

Adriano

unread,
Jan 14, 2003, 11:53:40 PM1/14/03
to perl6-i...@perl.org
On Tue, 14 Jan 2003 17:18:22 -0500, Dan Sugalski <d...@sidhe.org> wrote:

Dan:


> You're off. It'll be something like:
>
> callmethod Px, "method_name"
>
> or
>
> jmpmethod Px, "method_name"

Jonathan:


> Is there going to be any way to (in PASM) find a method with out invoking
> it? I am not sure, but it may be useful for currying and some efficiency
> stuff (like moving dispatch outside of a loop that repeatedly invokes a
> method).

Dan:


> Yep. There should be a can operator, though I'm not sure how often one
> wants to check for the existence of a method in an object without calling
> it. But no reason not to. More for rev 2.

I think what Jonathan asked for was an operator for returning a method (as
an object)
which can be invoked later with some arguments (or even applied with a
partial list
of arguments for currying).
This would be a lot more useful than a yes-or-no answer about the existence
of a method.


--
Adriano

Attriel

unread,
Jan 14, 2003, 6:16:06 PM1/14/03
to perl6-i...@perl.org
> Dan:
>> Yep. There should be a can operator, though I'm not sure how often one
>> wants to check for the existence of a method in an object without
>> calling it. But no reason not to. More for rev 2.

Adriano:


> I think what Jonathan asked for was an operator for returning a method
> (as an object)
> which can be invoked later with some arguments (or even applied with a
> partial list
> of arguments for currying).
> This would be a lot more useful than a yes-or-no answer about the
> existence of a method.

I think just knowing it exists would be useful (ala java's "reflection")
since you might want to know if it exists in order to do some set of
calculations before calling it, since if it doesn't exist there's a
better/different set of calcs you need to do that have no use for the
first set. I also like currying functions, which I can see kindof wanting
the funcall pointer (although ... would it also need some way of garnering
what the parameterlist (quantity or types) is?) ...

Luckily the former (yes/no) can be easily inferred from the latter
(funcall ptr) simply by "if the pointer is null, that'd be a no" :)
although, with the parameter info that may be encapsulated and returned in
some way with the fptr (if any is returned, that is), it might also be
beneficial to have a seperate opcode for "just tell me if it exists",
depending on how much overhead the fptr & param-info incurs ...

Short version: I think both are good. Yes/No is inferrable from a
pointer, but if the pointer has to include other information (and thus be
a full PMC or however, precisely) seperate might be good.

--attriel


Christopher Armstrong

unread,
Jan 14, 2003, 9:18:21 PM1/14/03
to perl6-i...@perl.org
On Tue, Jan 14, 2003 at 12:38:35PM -0800, Jonathan Sillito wrote:
> > -----Original Message-----
> > From: Dan Sugalski [mailto:d...@sidhe.org]
>
> > A property is a runtime assignable name/value pair that you stick on
> > a variable or value. An attribute is a named variable that all
> > objects of a particular class have.
> >
> > Properties can come and go at runtime, but attributes are fixed. (I
> > think you could also consider attributes "instance variables", but
> > I'm a bit OO fuzzy so I'm not sure that's entirely right)
>
> Ok, in the case of python or ruby, instance variables are not fixed and they
> are not declared as part of the class. I suppose this can be handled by
> giving such classes one hash attribute for storing these instance variables.

Yeah, that would be similar to how Python works now anyway; all
instance attributes are stored in a dict which is itself accessible as
an attribute on an instance: '__dict__'. Oh, except for the new
__slots__ feature, which might actually find a use with the
fixed-attribute-system that Dan has proposed.

--
Twisted | Christopher Armstrong: International Man of Twistery
Radix | Release Manager, Twisted Project
---------+ http://twistedmatrix.com/users/radix.twistd/

Christopher Armstrong

unread,
Jan 14, 2003, 9:37:51 PM1/14/03
to perl6-i...@perl.org, Dan Sugalski
On Tue, Jan 14, 2003 at 03:00:17PM -0500, Dan Sugalski wrote:
> At 11:44 AM -0800 1/14/03, Mr. Nobody wrote:
> >Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass,
> >PerlObject?
>
> Nope. There's nothing particularly perlish about them, and if we're
> going to have a common base set of object functionality, they'll
> probably be named ParrotRef/Attr/Class/Object. They should suffice
> for perl, python, and ruby (at the very least) unless I've missed
> something.

Hmm, well. Are you really trying to make it so Python won't have to
make a specialized subclass (err, subPMC?) of this system? If so, then
it'll probably need drastic changes.. I'm a Python hacker who's pretty
familiar with its object system. If you want, I can offer up some
explanations/advice for making this system usable directly by Python.

As it stands, an implementation of the Python object system could
definitely be implemented _in terms of_ what you have now, but, for
example, the method system that you have worked out now would be
totally unusable (afaics), as instance methods have some pretty
whacky, dynamic semantics. It'd probably have to be implemented in
terms of properties.

The problem, of course, is that either you go more static and make the
very dynamic, reflective languages like Python harder to implement (or
prevent them from making use of your existing abstractions like
methods, as explained above), or you go more dynamic and make the more
static languages (like Haskell?) slower because they'd have to
implement their features in terms of dynamic ones, when a lot of the
information could be available at compile-time.

But who knows, maybe it could be made modular enough (i.e., more
interface-oriented?) to allow the best of both worlds -- I'm far too
novice wrt Parrot to figure out what it'd look like, unfortunately.

I've been lurking this thread for a while, very interested, and unsure
if I should offer my suggestions for making the object system more
compatible with Python, and this looks like a great chance for me to
jump in. :-)

Dan Sugalski

unread,
Jan 15, 2003, 1:27:17 AM1/15/03
to perl6-i...@perl.org
At 6:16 PM -0500 1/14/03, attriel wrote:
>
>Short version: I think both are good. Yes/No is inferrable from a
>pointer, but if the pointer has to include other information (and thus be
>a full PMC or however, precisely) seperate might be good.

I think we're going to have to go with can and method calls leave it
at that. Much as I'd like to have automatically fetchable method
PMCs, I don't think it's feasable at this point.

I may well change my mind later--certainly wouldn't be the first time. :)

Dan Sugalski

unread,
Jan 15, 2003, 1:00:59 AM1/15/03
to Adriano, perl6-i...@perl.org

I thought about this--it's what the find_method vtable method was for
in the first place. Unfortunately, as was pointed out to me, there's
no good way to cache the result, since it could potentially be wrong
by the time the method is actually called.

We could potentially get around this if we put in place a
notification framework to invalidate these method handles, but that
means we have to have a fair amount of infrastructure in place to do
that. (Though, honestly, I do really like the idea, as it means we
can be faster by default and just pay the price when things change,
but there's that pesky code that needs writing and systems that need
designing to support it...)

Dan Sugalski

unread,
Jan 15, 2003, 1:29:42 AM1/15/03
to Christopher Armstrong, perl6-i...@perl.org
At 9:18 PM -0500 1/14/03, Christopher Armstrong wrote:
>On Tue, Jan 14, 2003 at 12:38:35PM -0800, Jonathan Sillito wrote:
>> > -----Original Message-----
>> > From: Dan Sugalski [mailto:d...@sidhe.org]
>>
>> > A property is a runtime assignable name/value pair that you stick on
>> > a variable or value. An attribute is a named variable that all
>> > objects of a particular class have.
>> >
>> > Properties can come and go at runtime, but attributes are fixed. (I
>> > think you could also consider attributes "instance variables", but
>> > I'm a bit OO fuzzy so I'm not sure that's entirely right)
>>
>> Ok, in the case of python or ruby, instance variables are not fixed and they
>> are not declared as part of the class. I suppose this can be handled by
>> giving such classes one hash attribute for storing these instance variables.
>
>Yeah, that would be similar to how Python works now anyway; all
>instance attributes are stored in a dict which is itself accessible as
>an attribute on an instance: '__dict__'. Oh, except for the new
>__slots__ feature, which might actually find a use with the
>fixed-attribute-system that Dan has proposed.

I'm pretty sure (though not 100% sure) that the non-slot attribute
stuff in python would actually correspond to variable properties,
rather than attributes, but I may be incorrect here. Are the current
python instance attributes both:

*) defined per object rather than per class
*) Essentially global, that is not hidden from parent classes or
anything. (Basically one big pool 'o things attached to the object)

Dan Sugalski

unread,
Jan 15, 2003, 1:57:28 AM1/15/03
to Christopher Armstrong, perl6-i...@perl.org
At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote:
>On Tue, Jan 14, 2003 at 03:00:17PM -0500, Dan Sugalski wrote:
>> At 11:44 AM -0800 1/14/03, Mr. Nobody wrote:
>> >Seems pretty reasonable, but don't you mean PerlRef, PerlAttr, PerlClass,
>> >PerlObject?
>>
>> Nope. There's nothing particularly perlish about them, and if we're
>> going to have a common base set of object functionality, they'll
>> probably be named ParrotRef/Attr/Class/Object. They should suffice
>> for perl, python, and ruby (at the very least) unless I've missed
>> something.
>
>Hmm, well. Are you really trying to make it so Python won't have to
>make a specialized subclass (err, subPMC?) of this system? If so, then
>it'll probably need drastic changes.. I'm a Python hacker who's pretty
>familiar with its object system. If you want, I can offer up some
>explanations/advice for making this system usable directly by Python.

Thanks--I *really* appreciate that.

>As it stands, an implementation of the Python object system could
>definitely be implemented _in terms of_ what you have now, but, for
>example, the method system that you have worked out now would be
>totally unusable (afaics), as instance methods have some pretty
>whacky, dynamic semantics. It'd probably have to be implemented in
>terms of properties.

Methods I'm not actually worried about, though we've not much
discussed them. (I think you'll find that Python's got nothing on
Ruby or Perl for method wackiness... :) Though you've definitely
pointed out an area that I need to get more detailed.

Method dispatch is the one place I know that we may have custom
behaviour, but I don't think it'll actually be necessary. Python
method dispatch, from the references I have, isn't unusual, which is
a good thing. (Plus I'll be layering multimethod dispatch on top, but
that'll be transparent)

>The problem, of course, is that either you go more static and make the
>very dynamic, reflective languages like Python harder to implement (or
>prevent them from making use of your existing abstractions like
>methods, as explained above), or you go more dynamic and make the more
>static languages (like Haskell?) slower because they'd have to
>implement their features in terms of dynamic ones, when a lot of the
>information could be available at compile-time.

At the moment the only really proposed static stuff is the attribute
list, and only because I'm trying hard to stick with the more
efficient array structure. (We could just bite the bullet and drop to
using a tree, but I think we can avoid that in the common case if we
have a fallback--I just need to define the fallback now)

>But who knows, maybe it could be made modular enough (i.e., more
>interface-oriented?) to allow the best of both worlds -- I'm far too
>novice wrt Parrot to figure out what it'd look like, unfortunately.

It'll actually look like what we have now. If you can come up with
something more abstract than:

callmethod P1, "foo"

that delegates the calling of the foo method to the method dispatch
vtable entry for the object in P1, well... gimme, I want it. :)

I'll add "define method dispatch more" to the list o' stuff for the
next edit of the proposal.

Gopal V

unread,
Jan 15, 2003, 8:41:15 AM1/15/03
to perl6-i...@perl.org
If memory serves me right, Dan Sugalski wrote:
> rather than attributes, but I may be incorrect here. Are the current
> python instance attributes both:
>
> *) defined per object rather than per class
> *) Essentially global, that is not hidden from parent classes or
> anything. (Basically one big pool 'o things attached to the object)

Speaking out of turn .... Python instance stuff is per Object ...
And from the looks of it's just a dictionary lookup in the
obj.__dict__ dictionary ... So the stuff looks essentially global.

eg.

class Foo:
def __init__(self):
pass
def toString(self):
return self.Name

class FooBar(Foo):
def __init__(self,name):
self.Name=name

a=FooBar("hello")
print a.toString()
------
hello

Gopal
PS: considering the fact that non-virtual functions are the only portion
holding out the TreeCC Python plugin , I have had quite some heart burn
with this. (or I need a switch statement :)

Peter Haworth

unread,
Jan 15, 2003, 10:10:27 AM1/15/03
to Dan Sugalski, Adriano, perl6-i...@perl.org
On Wed, 15 Jan 2003 01:00:59 -0500, Dan Sugalski wrote:
> At 8:53 PM -0800 1/14/03, Adriano wrote:
> >I think what Jonathan asked for was an operator for returning a method
> >(as an object) which can be invoked later with some arguments (or even
> >applied with a partial list of arguments for currying). This would be a
> >lot more useful than a yes-or-no answer about the existence of a method.
>
> I thought about this--it's what the find_method vtable method was for in
> the first place. Unfortunately, as was pointed out to me, there's no good
> way to cache the result, since it could potentially be wrong by the time
> the method is actually called.

Is that such a big deal? The same problem exists in perl 5 with the
following code:

if(my $meth=$obj->can($action)){
# Stuff could happen here which redefines the method in $obj's class
# However, I know it won't get redefined because I wrote the whole system
$obj->$meth();
}else{
die "Some custom error message or appropriate action";
}

Surely it's up to the person/compiler writing the code to decide whether it
matters that the method has been redefined in the meantime. We shouldn't
prevent something useful just because it's not universally applicable.

--
Peter Haworth p...@edison.ioppublishing.com
"I can talk on this stuff for hours when given insufficient discouragement."
-- Dan Sugalski

Garrett Goebel

unread,
Jan 15, 2003, 11:28:18 AM1/15/03
to Peter Haworth, Dan Sugalski, Adriano, perl6-i...@perl.org
Peter Haworth wrote:

> Dan Sugalski wrote:
> > Adriano wrote:
> > >
> > >I think what Jonathan asked for was an operator for
> > >returning a method (as an object) which can be invoked
> > >later with some arguments (or even applied with a
> > >partial list of arguments for currying).
> > >
> > >This would be a lot more useful than a yes-or-no
> > >answer about the existence of a method.

Exactly. 'Yes' might be valid one moment, and invalid the next. Not a very
useful operation... Returning a coderef on the other hand is useful.


> > I thought about this--it's what the find_method vtable
> > method was for in the first place. Unfortunately, as
> > was pointed out to me, there's no good way to cache
> > the result, since it could potentially be wrong by the
> > time the method is actually called.
>
> Is that such a big deal? The same problem exists in perl 5 with the
> following code:
>
> if(my $meth=$obj->can($action)){
> # Stuff could happen here which redefines the method in

> # $obj's class However, I know it won't get redefined
> # because I wrote the whole system


> $obj->$meth();
> }else{
> die "Some custom error message or appropriate action";
> }

I don't see it as a problem. In Perl5, you get back a coderef. And despite
whether the method is modified or removed from the class in the meantime,
that code reference is still valid. Sure, if you want to garrauntee you'll
get the "appropriate" method implementation at a given instance in time,
you'll have to code a bit more carefully, but at least you know the method
implementation you've got isn't going to be changed out from under you.

I'm not sure I follow the talk of invalidating method handles. I'm sure
there's some use for method handles. But I hope a reference to method's
implementation isn't going to run the chance of being invalidated before its
called.

I realize with Perl6 we'll have the possiblity of multi-method dispatch. But
my assumption based on Damian's posts to perl6-language is that Perl6's
->can will support passing some form of parameter list specification so that
it'd be possible for ->can to resolve the dispatch and return a coderef to
the implementation before you actually invoke it.

Attriel

unread,
Jan 15, 2003, 11:44:31 AM1/15/03
to perl6-i...@perl.org
>> > >I think what Jonathan asked for was an operator for
>> > >returning a method (as an object) which can be invoked
>> > >later with some arguments (or even applied with a
>> > >partial list of arguments for currying).
>> > >
>> > >This would be a lot more useful than a yes-or-no
>> > >answer about the existence of a method.
>
> Exactly. 'Yes' might be valid one moment, and invalid the next. Not a
> very useful operation... Returning a coderef on the other hand is
> useful.

Er. How could "Is it possible to call this method" become invalid, but
the fptr remains valid? I'm not sure that I follow that ...

> I don't see it as a problem. In Perl5, you get back a coderef. And
> despite whether the method is modified or removed from the class in the
> meantime, that code reference is still valid.

I think the issue is that Perl is interpreting things, whereas the parrot
would be quoting back actual memory locations saying "ok, this is RIGHT
HERE. when you want to do it, go RIGHT HERE" and then we up and moved
"here" to "there" and all hell breaks loose when I try to "callmethod" on
a pure number :o

Although, I guess Parrot could still be doing memory management at the VM
level and the PASM would still be getting lookup refs instead of actual
physical pointers, at which case I'm not sure I see the problem ...

I guess if "who's 'foo()' am I calling" is determined by some property of
the object, then it's possible to get a fptr P to function F from object O
at time T, do stuff with O (some of which might cause P' to be the proper
F fptr instead of P), and then calling P is no longer "legitimate" ... But
I'm not entirely convinced that's not the coder's problem, since that
would, imo, be a side-effect of whatever calls were made between "can" and
"call", which means either (a) they're documented properly and the coder
missed that step and forgot to get a new P for F (making P <- P') or (b)
it's NOT documented, at which point it's still the coder's error, just a
different coder :) since the side-effect is important and (possibly)
break-a-licious ...

--attriel

(so, at the level we're talking about right now, are we getting fptr P as
a memory location that has the function and we want to jump there (or has
the function ref, etc); or is P a ref that parrot will then look up in the
object and dig up the right answer (but has already done some level of
lookup to make this lookup easy; we've already found where it is in the
object the first time; now I have to find out where that is in memory/load
that into memory and call it)

Jonathan Sillito

unread,
Jan 15, 2003, 12:38:25 PM1/15/03
to Dan Sugalski, perl6-i...@perl.org
I realize this will vary from language to language, but generally we will
need a PMC that encapsulates a method (and responds to the invoke vtable
method like Sub, or maybe the Sub PMC could do?). This python code is
interesting:

class A:
def f (self):
print "A.f()"

def g (self):
print "g()"

a = A()
a.f() # output: A.f()

x = a.f # get the method, a limited form of currying
# since the first arg (a==self) is stored
x() # output: A.f()

setattr(A, "f", g) # replace A's f with g

a.f() # output: g()
x() # output (still): A.f() !!!!!!!

Which shows that the dispatch (i.e. selecting which method to call) can
happen before the invocation.
--
Jonathan Sillito

> -----Original Message-----
> From: Dan Sugalski [mailto:d...@sidhe.org]
>

Christopher Armstrong

unread,
Jan 15, 2003, 3:06:21 PM1/15/03
to perl6-i...@perl.org, Dan Sugalski

I'll help you along by offering this explanation of how instance
methods work in Python. (sorry if you're already familiar with this
stuff, but it's in my best interest to make sure you are ;-))

When you say something like `o.foo()', it translates into these steps:

1) LOAD_NAME 'o'
2) LOAD_ATTR 'bar'
3) CALL_FUNCTION

#2 has extra magic. What I mean is, when you LOAD_ATTR a function from
a *class*, you just get back a plain old `unbound method'. When you
LOAD_ATTR from an *instance*, and (after failing to find an instance
attribute) the attribute is found on its class, you get a `bound
method', which basically means that Python has "curried" that method
so the first argument is automatically passed -- that first argument
is the instance which you LOAD_ATTRd from. This is why you see all
those python methods with the first argument being `self', and rarely
see code which explicitly passes that first argument.

Now, like I said, this magic is done in LOAD_ATTR, not CALL_FUNCTION,
so you can take that bound method object and do whatever you want with
it before calling it.

Here's an interesting code snippet which also demonstrates the fact
that methods are just attributes.

>>> def toot(): print "hello"
...
>>> class Foo: pass
...
>>> # binding a method *to the instance* -- this prevents magic
>>> o = Foo(); o.toot = toot
>>> o.toot()
hello
>>> # binding method *to the class* -- just the same as if we defined
>>> # `toot' in the class definition
>>> Foo.toot = toot
>>> o2 = Foo()
>>> o2.toot()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: toot() takes no arguments (1 given)

That traceback happened because, as I explained above, when the `toot'
attribute was LOAD_ATTR'd from the instance and found on the class, it
was turned into a bound method that would have the instance
automatically passed to it.

HTH,

Dan Sugalski

unread,
Jan 15, 2003, 11:19:41 AM1/15/03
to Peter Haworth, Adriano, perl6-i...@perl.org
At 3:10 PM +0000 1/15/03, Peter Haworth wrote:
>On Wed, 15 Jan 2003 01:00:59 -0500, Dan Sugalski wrote:
>> At 8:53 PM -0800 1/14/03, Adriano wrote:
>> >I think what Jonathan asked for was an operator for returning a method
>> >(as an object) which can be invoked later with some arguments (or even
>> >applied with a partial list of arguments for currying). This would be a
>> >lot more useful than a yes-or-no answer about the existence of a method.
>>
>> I thought about this--it's what the find_method vtable method was for in
>> the first place. Unfortunately, as was pointed out to me, there's no good
>> way to cache the result, since it could potentially be wrong by the time
>> the method is actually called.
>
>Is that such a big deal? The same problem exists in perl 5 with the
>following code:

Right, but the example is showing a programmer's error. The folks
using parrot have to make their own subtle mistakes--we can't make
the mistakes on their behalf.

Dan Sugalski

unread,
Jan 15, 2003, 11:17:17 AM1/15/03
to Gopal V, perl6-i...@perl.org
At 7:11 PM +0530 1/15/03, Gopal V wrote:
>If memory serves me right, Dan Sugalski wrote:
>> rather than attributes, but I may be incorrect here. Are the current
>> python instance attributes both:
>>
>> *) defined per object rather than per class
>> *) Essentially global, that is not hidden from parent classes or
>> anything. (Basically one big pool 'o things attached to the object)
>
>Speaking out of turn .... Python instance stuff is per Object ...
>And from the looks of it's just a dictionary lookup in the
>obj.__dict__ dictionary ... So the stuff looks essentially global.

In that case they'd correspond to our properties, and I can already
feel a massive terminology disconnect looming. Maybe we should rename
properties and attributes to frobs and thingies, just so there's no
overlap. :(

At least getting to obj.__dict__ is simple enough, as we can map that
to the property hash fetch opcode.

Nicholas Clark

unread,
Jan 15, 2003, 3:40:30 PM1/15/03
to Dan Sugalski, Gopal V, perl6-i...@perl.org
On Wed, Jan 15, 2003 at 11:17:17AM -0500, Dan Sugalski wrote:
> In that case they'd correspond to our properties, and I can already
> feel a massive terminology disconnect looming. Maybe we should rename
> properties and attributes to frobs and thingies, just so there's no
> overlap. :(

We could call them houses and hotels - you'd only be allowed attributes
after you had 4 properties, and if you want to mortgage, er serialise the
object you'd have to hand them all back to the bank, er GC system.

Mmm. Maybe that's taking the analogy well beyond breaking point.

I've had a look in a thesaurus for words similar to property and attribute,
and I can't see much that's good. "idiosyncrasy" is a nice word, but it's 6
syllables, and hard to spell. "satellite" seems quite good for objects and
"stuff" that are hangers-on, as does "chattels". I quite liked the idea of
"virtue" for a quality, although I'm not sure if Larry would sanction PMCs
having vices as well :-)

The downside of finding completely new names for these two concepts is that
everyone would have to learn what they meant. The upside is that there would
be no confusion with every other language's contradictory definitions.

Nicholas Clark

Nicholas Clark

unread,
Jan 15, 2003, 3:54:30 PM1/15/03
to Dan Sugalski, Adriano, perl6-i...@perl.org

How much infrastructure do you need? I thought perl5 cached method lookup,
but had a global (per interpreter) generation count, which went up by one
every time you (re)defined a method. So for parrot you return a "thingy"
that is initially implemented as the direct pointer, a generation count,
plus enough other stuff to redo the search. If at the time of calling the
generation count is the same, wehay, go for it. Otherwise redo the search
there and then, and update.

Later on you can add in the notify system, if that's faster. (It may well be,
as at that point the pointer will always be valid, even if it's now pointing
to some placeholder bytecode that just throws an exception if called.)

Hmm. That's a cheat idea. You could keep track of all these "thingies", and
make sure the jump pointer was always valid. You just arrange that it is
replaced with a pointer into a relookup routine every time something
"relevant" gets redefined. (Initially a global counter, but it can get more
specialised later). That trades faster call speed each time (because the
pointer is now always valid, so you never need to check the generation count
at each call) for more maintenance time for each method redefine.

Although in turn you could then maintain you backpointers to all the
"thingies" in two sets - ones that are currently pointing to the "lookup"
code, and ones that point to real methods. Every time the "world" is updated
with code (re)definition you convert all the real methods to point to the
"lookup" code. Every time a "lookup" code routine is called it finds the
real method, and moves itself back to the the real set. This would actually
let you defer the method lookup - when you create one of these pointers it's
actually lazy, pointing to the "lookup" code, and the lookup is really only
done the first time you call it.

Am I rambling too much?

Nicholas Clark

Jonathan Sillito

unread,
Jan 15, 2003, 6:03:56 PM1/15/03
to Perl6-Internals
Sounds like we want objects *and* classes to support:

static_attribs - which are defined at compile time and
accessed by offset probably stored in an array.

dynamic_attribs - which come and go at run time and are
generally accessed by name and likely stored in a hash.

--
Jonathan Sillito

Uri Guttman

unread,
Jan 15, 2003, 6:17:28 PM1/15/03
to Jonathan Sillito, Perl6-Internals
>>>>> "JS" == Jonathan Sillito <sil...@cs.ubc.ca> writes:

JS> Sounds like we want objects *and* classes to support:
JS> static_attribs - which are defined at compile time and
JS> accessed by offset probably stored in an array.

JS> dynamic_attribs - which come and go at run time and are
JS> generally accessed by name and likely stored in a hash.

that isn't a bad idea. describe them in parrot by their lower level use
(or implementation) and map them to the high level lang and its own
OO/property terms.

i would use shorter names like dyn_attr and stat_attr.

but where they are stored is also an issue. are they instance specific
or class only? there are several combinations of those features too.

uri

--
Uri Guttman ------ u...@stemsystems.com -------- http://www.stemsystems.com
----- Stem and Perl Development, Systems Architecture, Design and Coding ----
Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
Damian Conway Perl Classes - January 2003 -- http://www.stemsystems.com/class

Gopal V

unread,
Jan 16, 2003, 2:09:26 AM1/16/03
to Jonathan Sillito, Dan Sugalski, perl6-i...@perl.org
If memory serves me right, Jonathan Sillito wrote:
> x = a.f # get the method, a limited form of currying
> # since the first arg (a==self) is stored
> x() # output: A.f()
>
> setattr(A, "f", g) # replace A's f with g
>
> a.f() # output: g()
> x() # output (still): A.f() !!!!!!!
>
> Which shows that the dispatch (i.e. selecting which method to call) can
> happen before the invocation.

This makes sense .... let me put it in this way

x_mthdptr=a.__dict__["f"]
a.__dict__["f"]=g_mthdptr
x_mthdptr()

The dispatch vs invocation looks childishly simple when written this way..
(and I hope I'm right about that ... :)

Underneath the high level language most things are really simple ... The
Python compiler should work around all these language quirks and generate
appropriate Parrot code ... In bytecode it should look direct, simple and
fast !.

Gopal

Dan Sugalski

unread,
Jan 17, 2003, 11:06:22 AM1/17/03
to Garrett Goebel, Peter Haworth, Adriano, perl6-i...@perl.org
At 10:28 AM -0600 1/15/03, Garrett Goebel wrote:
>Peter Haworth wrote:
>> Dan Sugalski wrote:
>> > Adriano wrote:
>> > >
>> > >I think what Jonathan asked for was an operator for
>> > >returning a method (as an object) which can be invoked
>> > >later with some arguments (or even applied with a
>> > >partial list of arguments for currying).
>> > >
>> > >This would be a lot more useful than a yes-or-no
>> > >answer about the existence of a method.
>
>Exactly. 'Yes' might be valid one moment, and invalid the next. Not a very
>useful operation... Returning a coderef on the other hand is useful.

Returning a valid coderef isn't often useful, very limiting, and
potentially inappropriate for our main targets. The only way they're
of any general use is if they just wrap the method invocation again,
in which case they're also slower than a plain method call. I have
this nasty feeling I'm going to be going over this explanation
several times, so I'm going to do it once here and hope for the best.

We are building an OO system for dynamic languages. This means the
list of methods that exist for an object may vary over time, it means
the list of methods that can be satisfied for an object vary over
time, and it means the two sets don't completely overlap. Plus we
also have multimethods to contend with, for the unwary

When you invoke a method, like:

foo->bar

One of several things could happen:

1) The bar method somewhere in foo's hierarchy is invoked
2) The bar method for no args is invoked in foo's hierarchy
3) AUTOLOAD, or its moral equivalent, is invoked somewhere in the
hierarchy because there is no bar method, so the fallback is used
4) Like #3, only it then creates a bar method
5) We invoke the bar method, which then changes before we can invoke it again

Getting a handle on the real method, then, is potentially wrong in
cases 2 and 5, and not possible or really wrong in 3 and 4 (depending
on how we do autoloadish things). It's only really correct for case 1.

For user-level code, that's perfectly fine--if you want to write code
that is potentially really wrong, there's no problem. (You won't be
the first nor, alas, the last) For that reason we should provide a
way to get the real handle for a particular invocation, so if you
only want it for user code, that's cool, read no further.

For the interpreter's purposes, though, we can't really use it. User
code can incorrectly function in the face of mutating back-ends, but
the interpreter must behave correctly in all cases. That's where
things get more interesting for us.

Yes, I fully want a caching method-invocation layer, so we can do our
best to go as fast as possible in the common case. There's a lot of
literature on this, and I'm well aware that we need it if we want to
have any hope of blazing speed. Doing that right, though, means
caching method lookups and trapping symbol table mutations, doing...
interesting potential dispatch courtesy of multimethods, and
generally getting funky. Static method handles, though, are just of
no use for the *interpreter*. User program, sure, interpreter, no
way. The languages are just too dynamic for it to be correct. For
that we need dynamic handles, and those are much more work.

That's one of the reasons I didn't really address method invocation
with objects, as I wasn't quite ready to get into methods yet. (And
I'm still not sure how to handle closed classes, or if we even
should--perl/ruby/python classes aren't ever closed, though .NET/JVM
classes, IIRC, are all entirely closed)

Dan Sugalski

unread,
Jan 17, 2003, 11:07:48 AM1/17/03
to att...@d20boards.net, perl6-i...@perl.org
At 11:44 AM -0500 1/15/03, attriel wrote:
> >> > >I think what Jonathan asked for was an operator for
>>> > >returning a method (as an object) which can be invoked
>>> > >later with some arguments (or even applied with a
>>> > >partial list of arguments for currying).
>>> > >
>>> > >This would be a lot more useful than a yes-or-no
>>> > >answer about the existence of a method.
>>
>> Exactly. 'Yes' might be valid one moment, and invalid the next. Not a
>> very useful operation... Returning a coderef on the other hand is
>> useful.
>
>Er. How could "Is it possible to call this method" become invalid, but
>the fptr remains valid? I'm not sure that I follow that ...

I get the function pointer. Points to a method. Someone comes and
redefines that method in the object's class, or deletes it outright.
I still have a handle, so the code doesn't go away, but it's no
longer the right code for that method name.

Dan Sugalski

unread,
Jan 17, 2003, 11:25:23 AM1/17/03
to Jonathan Sillito, perl6-i...@perl.org
At 9:38 AM -0800 1/15/03, Jonathan Sillito wrote:
>I realize this will vary from language to language, but generally we will
>need a PMC that encapsulates a method (and responds to the invoke vtable
>method like Sub, or maybe the Sub PMC could do?). This python code is
>interesting:
>
>a = A()
>a.f() # output: A.f()
>x = a.f # get the method, a limited form of currying
>x() # output: A.f()
>setattr(A, "f", g) # replace A's f with g
>a.f() # output: g()
>x() # output (still): A.f() !!!!!!!
>
>Which shows that the dispatch (i.e. selecting which method to call) can
>happen before the invocation.

Right, which argues for a method fetch. Which is cool, we need it,
I'll make sure it gets in the list.

I've been arguing for things that will be generally of use to the
compiler and interpreter though--things that will be useful for
emitted code inferred from what the user's written, hence the
confusion. The interpreter itself can't do that sort of explicit
caching without a lot of infrastructure to support it.

Though, as I dig through the mail, I'm realizing more and more that
we *must* do the explicit caching layer, and if we want to take full
advantage of it we need to expose it to the compilers rather than
keeping it secret, though it may be fairly inefficient to start with.
Damn.

Dan Sugalski

unread,
Jan 17, 2003, 11:44:41 AM1/17/03
to Christopher Armstrong, perl6-i...@perl.org

Hrm, interesting. Single symbol table for methods and attributes,
though that's not too surprising all things considered. That may make
interoperability interesting, but I was already expecting that to
some extent.

The bound method call thing we can do as a curried function, so I'm
not that concerned about it in general, but it does definitely imply
that we need to build in currying support to the core rather than
leaving it to the compilers to do, though there's no reason that the
functionality can't be left to the python opcode
backwards-compatibility set and more explicit logic built into the
python front end, but...

Hrm. I appreciate the heads up here.

Dan Sugalski

unread,
Jan 17, 2003, 12:05:26 PM1/17/03
to Nicholas Clark, Adriano, perl6-i...@perl.org

What I don't want is to check every time. I want method invalidation
to be done only on demand, so the common case (multiple use without
intervening redefinition) is as fast as possible. If we do implicit
handles we'll need a good infrastructure with defined semantics to
make sure those handles get either invalidated or rejigged when
changes are made, plus we need them to support the cases where there
is no real method and we're faking it all.

I think I know what needs to be designed, and what semantics we need,
and I'm pretty sure I know how to fake it until the structure's done,
too, so after I dig through the rest of the aftermath here it'll be
time to start writing. :)

Dan Sugalski

unread,
Jan 17, 2003, 12:07:05 PM1/17/03
to Jonathan Sillito, Perl6-Internals
At 3:03 PM -0800 1/15/03, Jonathan Sillito wrote:
>Sounds like we want objects *and* classes to support:
>
>static_attribs - which are defined at compile time and
>accessed by offset probably stored in an array.
>
>dynamic_attribs - which come and go at run time and are
>generally accessed by name and likely stored in a hash.

Yep. I've pretty much decided that classes are objects, so the one
falls out of the other there. We can deal with the dynamism fairly
simply, though there are issues of efficiency, as I have the feeling
that supporting the dynamic case well (which is reasonably rare,
relatively speaking) will make all cases, or at least all method
calls, slower. I think. Need to ponder this more.

Piers Cawley

unread,
Jan 21, 2003, 4:24:02 PM1/21/03
to Dan Sugalski, Christopher Armstrong, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> writes:

Isn't that, essentially what Perl 6 will have too? It's just that the
sigil will be taken to be part of the symbol. Thus a method's symbol
will be &method (method?). Presumably one would first check with the
object for a matching symbol and then search up the class tree until
something comes up (which could then be cached back on the object, though
that would require some smarts on the object's binding to the method
so that Parrot could distinguish between cached methods and 'custom'
methods (hopefully the binding would also contain information about
where a cached method was found so that SUPER:: type dispatch could be
done dynamically instead of using the current hack based on the
package in which the C<< $self->SUPER::method() >> call was compiled
(what me? On a hobby horse? Never!)))

Hmm... was that a paragraph or an S-expression?

--
Piers

Dan Sugalski

unread,
Jan 22, 2003, 2:54:51 AM1/22/03
to Piers Cawley, Christopher Armstrong, perl6-i...@perl.org
At 9:24 PM +0000 1/21/03, Piers Cawley wrote:

>Dan Sugalski <d...@sidhe.org> writes:
> > Hrm, interesting. Single symbol table for methods and attributes,
>> though that's not too surprising all things considered. That may make
>> interoperability interesting, but I was already expecting that to some
>> extent.
>
>Isn't that, essentially what Perl 6 will have too?

Nope. Attributes and methods will be very separate. Attributes are
class-private, more or less, so they won't be in the symbol table.
Methods, OTOH, will be, as they aren't really private at all.

I've been thinking about how to handle methods, as we need a
mechanism everyone can share--you need a method cache for good
performance, and the last thing I want to have to deal with is a
dozen method caches for a dozen different language implementations,
especially as everyone's guaranteed to get the first version wrong.
(Plus, of course, there's MM dispatch to deal with, which needs to be
global as well)

Matt Fowles

unread,
Jan 22, 2003, 1:34:58 PM1/22/03
to P6I
All~

Regarding MM dispatch, I implemented a version of this for a class of mine
once. The version I have is in C++, and heavily uses templating to provide
compile time type checks where appropriate. Despite these differences,
however, I think that the system of caching methods and the system of
finding the appropriate method could be easily adapted.

http://www.cs.swarthmore.edu/~bulnes/PL/lab1/index.html

If anyone finds that interesting or has corrections for me, please send
them.

Boots
-----
"Computer Science is merely the post-Turing decline of Formal Systems
Theory."
-???


> -----Original Message-----
> From: Dan Sugalski [mailto:d...@sidhe.org]

> Sent: Wednesday, January 22, 2003 2:55 AM
> To: Piers Cawley
> Cc: Christopher Armstrong; perl6-i...@perl.org
> Subject: Re: Objects, finally (try 1)
>
>

Christopher Armstrong

unread,
Jan 22, 2003, 1:46:54 PM1/22/03
to perl6-i...@perl.org, Dan Sugalski

Just curious. Exactly how overridable is that `callmethod'? I don't
really know anything about the vtable stuff in Parrot, but is it
possible to totally delegate the lookup/calling of "foo" to a function
that's bound somehow to P1? Or does the "foo" entry have to exist in
the vtable already? Sorry for the naive question :-) Oh, and if you
just want to point me at a source file, I guess I can try reading it
:-) Python basically requires that each step in the process be
overridable. (1. look up attribute 2. call attribute, at least in
`callmethod's case).

Thanks.

Erik Bågfors

unread,
Jan 23, 2003, 2:42:03 AM1/23/03
to Christopher Armstrong, perl6-i...@perl.org, Dan Sugalski
On Wed, 2003-01-22 at 19:46, Christopher Armstrong wrote:
> On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote:
> > At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote:
> > >But who knows, maybe it could be made modular enough (i.e., more
> > >interface-oriented?) to allow the best of both worlds -- I'm far too
> > >novice wrt Parrot to figure out what it'd look like, unfortunately.
> >
> > It'll actually look like what we have now. If you can come up with
> > something more abstract than:
> >
> > callmethod P1, "foo"
> >
> > that delegates the calling of the foo method to the method dispatch
> > vtable entry for the object in P1, well... gimme, I want it. :)
>
> Just curious. Exactly how overridable is that `callmethod'? I don't
> really know anything about the vtable stuff in Parrot, but is it
> possible to totally delegate the lookup/calling of "foo" to a function
> that's bound somehow to P1? Or does the "foo" entry have to exist in
> the vtable already? Sorry for the naive question :-) Oh, and if you
> just want to point me at a source file, I guess I can try reading it
> :-) Python basically requires that each step in the process be
> overridable. (1. look up attribute 2. call attribute, at least in
> `callmethod's case).


Ruby needs to call the missing_method method (if I remember correctly).
So if "foo" doesn't exist, it would be good to be able to override
callmethods behavior and make it call missing_method.

/Erik

--
Erik Bågfors | er...@bagfors.nu
Supporter of free software | GSM +46 733 279 273
fingerprint: 6666 A85B 95D3 D26B 296B 6C60 4F32 2C0B 693D 6E32

Brent Dax

unread,
Jan 23, 2003, 3:05:21 AM1/23/03
to Christopher Armstrong, perl6-i...@perl.org, Dan Sugalski
Christopher Armstrong:
# On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote:
# > At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote:
# > >But who knows, maybe it could be made modular enough (i.e., more
# > >interface-oriented?) to allow the best of both worlds --
# I'm far too
# > >novice wrt Parrot to figure out what it'd look like, unfortunately.
# >
# > It'll actually look like what we have now. If you can come up with
# > something more abstract than:
# >
# > callmethod P1, "foo"
# >
# > that delegates the calling of the foo method to the method dispatch
# > vtable entry for the object in P1, well... gimme, I want it. :)
#
# Just curious. Exactly how overridable is that `callmethod'?

Extremely. callmethod maps to a function with a signature something
like

opcode_t * MyPMCClass_callmethod(Parrot_Interp interpreter, PMC*
self, char* name)

Which returns a pointer to the method's entry point, so that we don't
have C-level recursion for every method call. (It's also allowed to
just perform the call itself and return NULL, so you can call into C
efficiently.) The trick is to override MyPMCClass's callmethod to
provide whatever semantics you want to have. We're currently bickering
over whether you can cache pmc->vtable->callmethod's return value or
not, but it looks like either way it should be easily updatable.

# Python basically requires that each step in the process be
# overridable. (1. look up attribute 2. call attribute, at least in
# `callmethod's case).

I'm not sure exactly how this would be implemented but...um...I'm sure
you *could* do it. ;^)

Dan: with the various AUTOLOAD-esque features, can we reasonably expect
to be able to have One True Object PMC?

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

>How do you "test" this 'God' to "prove" it is who it says it is?
"If you're God, you know exactly what it would take to convince me. Do
that."
--Marc Fleury on alt.atheism

Paul Moore

unread,
Jan 23, 2003, 4:48:58 AM1/23/03
to
d...@sidhe.org (Dan Sugalski) wrote in message news:<a05200f05ba4de202efa4@[63.120.19.221]>...

> Hrm, interesting. Single symbol table for methods and attributes,
> though that's not too surprising all things considered. That may make
> interoperability interesting, but I was already expecting that to
> some extent.
>
> The bound method call thing we can do as a curried function, so I'm
> not that concerned about it in general, but it does definitely imply
> that we need to build in currying support to the core rather than
> leaving it to the compilers to do, though there's no reason that the
> functionality can't be left to the python opcode
> backwards-compatibility set and more explicit logic built into the
> python front end, but...
>
> Hrm. I appreciate the heads up here.

I'm even more of a lurker that Christopher (I picked this thread up
from Piers' summary posting) but if you're looking for Python method
strangeness, has anyone yet mentioned Python 2.2 static and class
methods? I think that static methods will be simple, but class methods
are worth considering:

class Demo(object):
def cls_meth(cls, arg):
print "I am an object of type", `cls`
print "Called with arg", arg
cls_meth = classmethod(cls_meth)

d = Demo()
d.cls_meth(12)

What's happening here, is that cls_meth is defined as a function
within the class, taking 2 parameters. Then, cls_meth is *reassigned*,
within the class definition, to the result of calling the builtin
classmethod() function, passing this function.

The resulting cls_meth method, when called with an instance, gets
passed a hidden firs parameter. This is like the normal "self" of
instance methods, but instead of being the object, it is the *class*
of that object (classes are first class objects in Python). In the
presence of inheritance, the cls argument is the real runtime class of
the instance used, not necessarily the same as the class that cls_meth
was defined in.

I don't know if this is likely to be hard to handle in Parrot, but
(AFAIK) it's a fairly unusual feature (it came from Smalltalk, I
believe).

As I say, static methods are not anything like as hard - they are
constructed in a similar way (with a staticmethod() builtin) but they
get passed no hidden argument. So they have no access to the original
object, or its class. Often used for things like extra constructors.

Hope this is useful,
Paul.

PS You don't want to know about metaclasses... (Actually, you
may well do, but I don't know enough myself to describe them).

Gopal V

unread,
Jan 23, 2003, 9:46:21 AM1/23/03
to Erik Bågfors, Christopher Armstrong, perl6-i...@perl.org
If memory serves me right, Erik Bågfors wrote:
> > :-) Python basically requires that each step in the process be
> > overridable. (1. look up attribute 2. call attribute, at least in
> > `callmethod's case).

would this be more of what you need ?

obj.__dict__["foo"].__call__();

/me again shows up and says that the compiler designer can do this with
ease ... Or in this case the interpreter designer can implement an
``InvocationExpression'' in anyway they want ...

I think Jython would be a fine example of how this could be done (though
speed suffers on a hash lookup without engine support ?).

> Ruby needs to call the missing_method method (if I remember correctly).
> So if "foo" doesn't exist, it would be good to be able to override
> callmethods behavior and make it call missing_method.

like I said , the compiler designer can put that explicitly in the
generated code ... You don't actually need instructions to do that.
Also the explicit generation might prove to be better to handle all
the quirks future languages might encounter....

My interest here is to obtain a clear and fast way to call stuff for
static compiled languages. :)

Erik Bågfors

unread,
Jan 23, 2003, 10:35:37 AM1/23/03
to Gopal V, Christopher Armstrong, perl6-i...@perl.org
On Thu, 2003-01-23 at 15:46, Gopal V wrote:

> > Ruby needs to call the missing_method method (if I remember correctly).
> > So if "foo" doesn't exist, it would be good to be able to override
> > callmethods behavior and make it call missing_method.
>
> like I said , the compiler designer can put that explicitly in the
> generated code ... You don't actually need instructions to do that.
> Also the explicit generation might prove to be better to handle all
> the quirks future languages might encounter....

Sure, there is only one problem with that. I don't know if it's a real
problem or not.

But if I write a library in ruby that depends on the missing_method
method it will not be usable from other languages, since those languages
doesn't call missing_method if the method they try to call doesn't
exist.

Of course, in real life I don't think that's a problem because I haven't
seen much use of missing_method.

Also, having a instruction would be faster which of course is more fun
:)

> My interest here is to obtain a clear and fast way to call stuff for
> static compiled languages. :)

But the really interesting thing about parrot is that it is primarily
made for very dynamic languages. Personally I think it's quite ok if C#
is a little bit slower under parrot than under mono/dotgnu/MS.NET, as
long as the dynamic languages are as fast or faster than they are now.

Gopal V

unread,
Jan 23, 2003, 11:40:55 AM1/23/03
to Erik Bågfors, perl6-i...@perl.org
If memory serves me right, Erik Bågfors wrote:

> But if I write a library in ruby that depends on the missing_method
> method it will not be usable from other languages, since those languages
> doesn't call missing_method if the method they try to call doesn't
> exist.

Hmm... that's twisting language features with virtual machine instructions.
Actually that's a gray area as far as I can see ... we'll have to go on
with `n' number of methods for `n' languages for member resolution ...

> Of course, in real life I don't think that's a problem because I haven't
> seen much use of missing_method.

Unfortunately I use a lot of __getattr__ for my python code (especially
GUI) ...

> Also, having a instruction would be faster which of course is more fun
> :)

Yes... But this not only makes it ugly (as an instruction) , but slow as
well ? . Like you said only a small number of people use this feature ,
does it make sense to slow down the rest ? . And how does hacker ZZ add
a new language with a different member lookup without getting his patches
inside Parrot ?..

Anyway I'm not *against* implementing this , I'm just questioning the
*need* to implement this ... Just a question for the philosophers ...

Dan Sugalski

unread,
Jan 23, 2003, 1:27:04 PM1/23/03
to Gopal V, "Erik Bågfors", perl6-i...@perl.org
At 10:10 PM +0530 1/23/03, Gopal V wrote:
>If memory serves me right, Erik Bågfors wrote:
>
>> But if I write a library in ruby that depends on the missing_method
>> method it will not be usable from other languages, since those languages
>> doesn't call missing_method if the method they try to call doesn't
>> exist.
>
>Hmm... that's twisting language features with virtual machine instructions.
>Actually that's a gray area as far as I can see ... we'll have to go on
>with `n' number of methods for `n' languages for member resolution ...

Grey? Heck, take a step back, lots of parrot is done up in neon paisley. :-P

> > Of course, in real life I don't think that's a problem because I haven't
>> seen much use of missing_method.
>
>Unfortunately I use a lot of __getattr__ for my python code (especially
>GUI) ...

Perl also makes heavy use of this in some of the more interesting modules.

> > Also, having a instruction would be faster which of course is more fun
>> :)
>
>Yes... But this not only makes it ugly (as an instruction) , but slow as
>well ? . Like you said only a small number of people use this feature ,
>does it make sense to slow down the rest ? . And how does hacker ZZ add
>a new language with a different member lookup without getting his patches
>inside Parrot ?..

That's why the smarts isn't in the opcode function, but rather in the
vtable method lookup function. That way you only pay the cost if the
feature is used.

This can also work to the advantage of languages that need this
feature, as it means that classes that don't have to have a fallback
method lookup can use a faster lookup function that doesn't need to
do a second trace to look for missing functions.

>Anyway I'm not *against* implementing this , I'm just questioning the
>*need* to implement this ... Just a question for the philosophers ...

The philosophers, alas, got drunk and started fighting over the one
fork at the table. Very messy.

Dan Sugalski

unread,
Jan 23, 2003, 1:23:36 PM1/23/03
to Gopal V, "Erik Bågfors", Christopher Armstrong, perl6-i...@perl.org
At 8:16 PM +0530 1/23/03, Gopal V wrote:
>If memory serves me right, Erik Bågfors wrote:
> > Ruby needs to call the missing_method method (if I remember correctly).
>> So if "foo" doesn't exist, it would be good to be able to override
>> callmethods behavior and make it call missing_method.
>
>like I said , the compiler designer can put that explicitly in the
>generated code ... You don't actually need instructions to do that.
>Also the explicit generation might prove to be better to handle all
>the quirks future languages might encounter....

Or hiding it in the objects themselves, so we can make sure the
expense of generality is only in place for those objects or classes
that need it, rather than for everyone.

>My interest here is to obtain a clear and fast way to call stuff for
>static compiled languages. :)

Fair enough, though that would argue for embedding the functionality
in the objects and not the generated code, as AUTOLOAD searching
should be done for a method call on a perl object regardless of
whether the language making the method call supports it. If your C#
code calls a method on a perl object it gets, that method resolution
should be done with perl semantics, not C# semantics.

Dan Sugalski

unread,
Jan 23, 2003, 1:17:03 PM1/23/03
to Christopher Armstrong, perl6-i...@perl.org
At 1:46 PM -0500 1/22/03, Christopher Armstrong wrote:
>On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote:
>> At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote:
>> >But who knows, maybe it could be made modular enough (i.e., more
>> >interface-oriented?) to allow the best of both worlds -- I'm far too
>> >novice wrt Parrot to figure out what it'd look like, unfortunately.
>>
>> It'll actually look like what we have now. If you can come up with
>> something more abstract than:
>>
>> callmethod P1, "foo"
>>
>> that delegates the calling of the foo method to the method dispatch
>> vtable entry for the object in P1, well... gimme, I want it. :)
>
>Just curious. Exactly how overridable is that `callmethod'?

Completely. It ultimately delegates finding the method to the PMC via
its vtable, so you can then do whatever you want. We're going to
provide some convenience functions and predefined functionality so
everyone doesn't have to reimplement the same stuff over and over.

Delegating to the PMC also means that perl objects or ruby objects
will behave the way they should regardless of what language's code is
using them. I'm not really expecting too much in the way of different
behaviour between the languages, but the differences that are there
should be respected.

Dan Sugalski

unread,
Jan 23, 2003, 1:19:56 PM1/23/03
to Erik Bågfors, Christopher Armstrong, perl6-i...@perl.org

This'll be core functionality if languages want to use it. Perl has a
similar function, AUTOLOAD, that gets called if you make a
nonexistent method call. It sounds like we need generic pre and post
method call handler functionality as well, which should be
interesting to design.

Piers Cawley

unread,
Jan 27, 2003, 6:52:45 AM1/27/03
to Dan Sugalski, Christopher Armstrong, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> writes:

> At 9:24 PM +0000 1/21/03, Piers Cawley wrote:
>>Dan Sugalski <d...@sidhe.org> writes:
>> > Hrm, interesting. Single symbol table for methods and attributes,
>>> though that's not too surprising all things considered. That may make
>>> interoperability interesting, but I was already expecting that to some
>>> extent.
>>
>>Isn't that, essentially what Perl 6 will have too?
>
> Nope. Attributes and methods will be very separate. Attributes are
> class-private, more or less, so they won't be in the symbol
> table.

How private? We are still going to be able to write some kind of
serializing tool that won't require tons of per class overloads aren't
we? (I'd like such a serializing tool to work at the Parrot level with
possible callbacks into object methods).

--
Piers

Dan Sugalski

unread,
Jan 27, 2003, 8:37:10 AM1/27/03
to Piers Cawley, Christopher Armstrong, perl6-i...@perl.org
At 11:52 AM +0000 1/27/03, Piers Cawley wrote:
>Dan Sugalski <d...@sidhe.org> writes:
>
>> At 9:24 PM +0000 1/21/03, Piers Cawley wrote:
>>>Dan Sugalski <d...@sidhe.org> writes:
>>> > Hrm, interesting. Single symbol table for methods and attributes,
>>>> though that's not too surprising all things considered. That may make
>>>> interoperability interesting, but I was already expecting that to some
>>>> extent.
>>>
>>>Isn't that, essentially what Perl 6 will have too?
>>
>> Nope. Attributes and methods will be very separate. Attributes are
>> class-private, more or less, so they won't be in the symbol
>> table.
>
>How private?

Well... not *that* private. From the bytecode level all this stuff'll
be available, though I hadn't given much thought to the introspection
end of things.

> We are still going to be able to write some kind of
>serializing tool that won't require tons of per class overloads aren't
>we? (I'd like such a serializing tool to work at the Parrot level with
>possible callbacks into object methods).

We probably won't need to do that, since all the knowledge necessary
to serialize should be built into individual PMC classes, but yeah,
it should be reasonably doable assuming that particular classes don't
have odd internal structures that aren't otherwise available.

Piers Cawley

unread,
Jan 27, 2003, 11:23:25 AM1/27/03
to Dan Sugalski, Christopher Armstrong, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> writes:

I'm actually quite keen on providing an C<< Object::printOn( $a_stream
) >> type method which can be overridden in weird cases (for instance
in Objects that are actually Proxies for something in an external
library would need to override the method). I've been working on
the 'serialization' problem while writing Pixie so I'm getting some
fairy definite ideas about how it should be done :)

--
Piers

0 new messages