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

overloading the variable declaration process

6 views
Skip to first unread message

Darren Duncan

unread,
Feb 5, 2006, 10:26:09 PM2/5/06
to perl6-l...@perl.org
All,

Speaking briefly, I would like it if Perl 6 provided a way for a
class (or role, or meta-class, etc) to declare that all variables
declared to be of that type are automatically/implicitly set to a
particular value at declaration time, so that they are not undefined
if the programmer using them doesn't explicitly set a value.

Here are usage examples:

my NumType $foo; # implicitly contains a defined NumType of value 0
my StrType $bar; # implicitly contains a defined StrType of value ''

Sure, the user could say ".= new()" or such, but I wanted a fallback
if they didn't do that.

Then when they come to just use that not explicitly set variable, it
contains some type-defined reasonable default value.

Presumably, the object meta-model would have an appropriate function
defined for use at that time, which returns undef by default, and
this function is what individual classes can override.

Part way through writing this, I had a brief chat on #perl6 with
stevan (and apparently the meta-model is still quite in flux) and he
said my question was related to Larry's "class but undef" idea, and
that Larry should talk more about the subject.

Thank you. -- Darren Duncan

Audrey Tang

unread,
Feb 6, 2006, 2:02:30 AM2/6/06
to Darren Duncan, perl6-l...@perl.org
On 2/6/06, Darren Duncan <dar...@darrenduncan.net> wrote:
> Speaking briefly, I would like it if Perl 6 provided a way for a
> class (or role, or meta-class, etc) to declare that all variables
> declared to be of that type are automatically/implicitly set to a
> particular value at declaration time, so that they are not undefined
> if the programmer using them doesn't explicitly set a value.

In a somewhat related note, Perl 6 allows this form:

my Dog $fido .= new;

which may be treated as a special form (as is currently the case with Pugs).
However if it's not, it would desugar to:

my Dog $fido;
$fido = $fido.new;

which seem to imply that $fido is set to ::Dog (the dog class) as its
initial value.
However, that would potentially make this a no-op:

my Dog $fido = Dog;

which may make sense except that defined($fido) may need to be regulated
as true even for the "my Dog $fido" case.

If so, your use case can be satisfied by declaring that ::NumType (the
class object)
numifies to 0, and ::StrType stringifies to "", via the coerce<as> form.

Audrey

Larry Wall

unread,
Feb 6, 2006, 2:22:42 PM2/6/06
to perl6-l...@perl.org
On Sun, Feb 05, 2006 at 07:26:09PM -0800, Darren Duncan wrote:
: Part way through writing this, I had a brief chat on #perl6 with
: stevan (and apparently the meta-model is still quite in flux) and he
: said my question was related to Larry's "class but undef" idea, and
: that Larry should talk more about the subject.

Aside from the fact that it's not a class, and not necessarily undef,
"class but undef" is a good name for it. :-)

I've been calling them prototype objects lately for lack of a
better word. To me, the Real Class is the object instance hiding
behind .meta. But when you say bare "Foo" you actually naming a
generic object of the type ^Foo, which I see currently as shorthand
for Foo.meta, and which any object that does Foo can get at if it
needs metadata, including the Foo object itself. In short,

Foo.does('Foo')

This is mostly motivated by linguistics rather than computer science,
insofar as types/classes/roles in natural language are normally
represented by generic objects rather than "meta" objects. When I
ask in English:

Can a dog bark?

that's equivalent to asking in Perl 6:

Dog.can('bark')

The "Dog" there is in the same type category as $dog, and specifically
is *not* in the same type category as the class that is managing
the logic behind the scenes. As a user, I'm thinking about "doggy"
objects, not "classy" objects. It's the very same kind of linguistic
reasoning that gives us "given" rather than "switch", and "when" rather
than "case". People want to think about their problem's objects,
not the language implementor's representations of those objects.

Now in the case of .can, we do eventually end up asking the metaobject
whether this objects supports the .bark method, but the point is that
the user doesn't have to keep track of how many metas there are.
Or looking at it the other way, any object can stand in for all its
meta objects. This is how we think (I think).

Psycholinguistially, every "dog" object in your brain is really a
kind of partially instantiated object that is slowly being filled in
with knowledge about the real world counterpart to your mental model.
Your mental model is never perfect.

The trend in the world today is away from monolithic computers that
either know everything or nothing, and toward programs that have
to work with imperfect knowledge that is generated or downloaded on
the fly. So I think the modeling view of reality is the sweet spot
for the future, and languages that have to know everything before
they think they know anything are doomed to fail. Well, not fail,
but have restricted ecological niches, such as rocket science.
(And maybe not even there, as machines get more autonomous.)

So the basic answer to you question is, I think, yes. If Dog chooses
to always return true for .defined, then (in Haskell terms) it's more
like a Just type than a Maybe type. Perl 6's objects like to be Maybe
types by default, but you can override it. (I'm using the Haskell
terms loosely here, of course.) But the very concept of definedness
is getting mushy in Perl 6. What we need is more concepts of the
form "Is this *sufficiently* defined for what I want to do with it?"
That's why I proposed "defined according to a particular role" as
one way to ask that sort of question.

Hope this helps.

Larry

Darren Duncan

unread,
Feb 6, 2006, 3:36:52 PM2/6/06
to perl6-l...@perl.org
At 3:02 PM +0800 2/6/06, Audrey Tang wrote:
>On 2/6/06, Darren Duncan <dar...@darrenduncan.net> wrote:
>> Speaking briefly, I would like it if Perl 6 provided a way for a
>> class (or role, or meta-class, etc) to declare that all variables
>> declared to be of that type are automatically/implicitly set to a
>> particular value at declaration time, so that they are not undefined
> > if the programmer using them doesn't explicitly set a value.
>
>If so, your use case can be satisfied by declaring that ::NumType (the
>class object)
>numifies to 0, and ::StrType stringifies to "", via the coerce<as> form.

That could be fine for some situations, but I was looking for a more
generic solution for:

my FooType $foo; # acts like we said .= new()
$foo.do_action();

Essentially, that $foo is like or is a fully instantiated object on
which you can call arbitrary FooType object methods as if someone set
it with new(), but where in fact the user never did this.

The coercing solution won't work if the types of use are not
coersions to simple data types like strings or numbers.

Luke Palmer

unread,
Feb 6, 2006, 7:05:37 PM2/6/06
to perl6-l...@perl.org
On 2/6/06, Larry Wall <la...@wall.org> wrote:
> This is mostly motivated by linguistics rather than computer science,
> insofar as types/classes/roles in natural language are normally
> represented by generic objects rather than "meta" objects. When I
> ask in English:
>
> Can a dog bark?
>
> that's equivalent to asking in Perl 6:
>
> Dog.can('bark')

That sentence is ambiguous. You can interpret it as:

Can some dog bark?

Or as:

Can every dog bark?

I think you meant the latter, however the sentence is leaning toward
the former. "Can dogs bark?" would be less ambiguous in that respect.

And while I'm starting to see the linguistic rationale behind this
decision, I still can't find anything concrete that this buys us.
Call me an American, but I like instant gratification.

Luke

Matt Fowles

unread,
Feb 6, 2006, 10:41:02 PM2/6/06
to perl6-l...@perl.org
Larry~

On 2/6/06, Larry Wall <la...@wall.org> wrote:

> This is mostly motivated by linguistics rather than computer science,
> insofar as types/classes/roles in natural language are normally
> represented by generic objects rather than "meta" objects. When I
> ask in English:
>
> Can a dog bark?
>
> that's equivalent to asking in Perl 6:
>
> Dog.can('bark')

Or you might think of it more as a question like "Can the ideal of a
dog bark?" the answer to which is of course "No, it doesn't exist.".

Perhaps, I am just too firmly rooted in old paradigms but I think it
is very important not to conflate the representation of a thing with
the thing.

http://en.wikipedia.org/wiki/Image:MagrittePipe.jpg

Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-Stan Kelly-Bootle, The Devil's DP Dictionary

Ashley Winters

unread,
Feb 7, 2006, 4:25:52 AM2/7/06
to perl6-l...@perl.org
On 2/6/06, Larry Wall <la...@wall.org> wrote:
> So the basic answer to you question is, I think, yes. If Dog chooses
> to always return true for .defined, then (in Haskell terms) it's more
> like a Just type than a Maybe type. Perl 6's objects like to be Maybe
> types by default, but you can override it. (I'm using the Haskell
> terms loosely here, of course.) But the very concept of definedness
> is getting mushy in Perl 6. What we need is more concepts of the
> form "Is this *sufficiently* defined for what I want to do with it?"
> That's why I proposed "defined according to a particular role" as
> one way to ask that sort of question.

So, if ^Dog describes a Dog which defines a $dog, do we need an
undescribed() function?

Just kidding... kinda.

Ashley Winters

Larry Wall

unread,
Feb 7, 2006, 11:51:38 AM2/7/06
to perl6-l...@perl.org
On Mon, Feb 06, 2006 at 10:41:02PM -0500, Matt Fowles wrote:
: Larry~

:
: On 2/6/06, Larry Wall <la...@wall.org> wrote:
: > This is mostly motivated by linguistics rather than computer science,
: > insofar as types/classes/roles in natural language are normally
: > represented by generic objects rather than "meta" objects. When I
: > ask in English:
: >
: > Can a dog bark?
: >
: > that's equivalent to asking in Perl 6:
: >
: > Dog.can('bark')
:
: Or you might think of it more as a question like "Can the ideal of a
: dog bark?" the answer to which is of course "No, it doesn't exist.".

As soon as you say "the ideal" you've chosen Platonism over
Aristotelianism. :-)

: Perhaps, I am just too firmly rooted in old paradigms but I think it


: is very important not to conflate the representation of a thing with
: the thing.
:
: http://en.wikipedia.org/wiki/Image:MagrittePipe.jpg

Indeed, and the modeling point of view is that $pipe is *also* just
a representation of the Pipe. Neither Pipe nor $pipe is the thing
itself. Most computer programs are about Something Else, so computer
languages should be optimized for talking about other things rather
than talking about themselves. The answer to

Pipe.can("Smoke")
$pipe.can("Smoke")

should be the same, not different. On the other hand,

^Pipe.can("Smoke")

is a different matter, insofar as you're asking a question about a Class
object rather than a Pipe object. And now you get your Platonism back.
You just have to be explicit about it.

Larry

Matt Fowles

unread,
Feb 7, 2006, 12:32:59 PM2/7/06
to perl6-l...@perl.org
Larry~

On 2/7/06, Larry Wall <la...@wall.org> wrote:
>
> Indeed, and the modeling point of view is that $pipe is *also* just
> a representation of the Pipe. Neither Pipe nor $pipe is the thing
> itself. Most computer programs are about Something Else, so computer
> languages should be optimized for talking about other things rather
> than talking about themselves. The answer to
>
> Pipe.can("Smoke")
> $pipe.can("Smoke")
>
> should be the same, not different. On the other hand,
>
> ^Pipe.can("Smoke")
>
> is a different matter, insofar as you're asking a question about a Class
> object rather than a Pipe object. And now you get your Platonism back.
> You just have to be explicit about it.

I see the value of ^Pipe and $pipe as seperate objects which can be
manipulated programmatically. What I don't really understand is what
exactly Pipe is and where it would be useful.

They way you have described Pipe feels a little muddy to me and I am
unsure about its purpose and semantics. Is it just an object I ask
`.can()` or does it have some deeper usefulness?

Matt Fowles

unread,
Feb 7, 2006, 6:56:45 PM2/7/06
to Stevan Little, perl6-l...@perl.org
Stevan~

I am going to assume that you intended to reply to perl 6 language,
and thus will include your post in its entirety in my response.

On 2/7/06, Stevan Little <stevan...@gmail.com> wrote:


> On 2/7/06, Matt Fowles <uber...@gmail.com> wrote:
> > Larry~
> >
> > On 2/7/06, Larry Wall <la...@wall.org> wrote:
> > >
> > > Indeed, and the modeling point of view is that $pipe is *also* just
> > > a representation of the Pipe. Neither Pipe nor $pipe is the thing
> > > itself. Most computer programs are about Something Else, so computer
> > > languages should be optimized for talking about other things rather
> > > than talking about themselves. The answer to
> > >
> > > Pipe.can("Smoke")
> > > $pipe.can("Smoke")
> > >
> > > should be the same, not different. On the other hand,
> > >
> > > ^Pipe.can("Smoke")
> > >
> > > is a different matter, insofar as you're asking a question about a Class
> > > object rather than a Pipe object. And now you get your Platonism back.
> > > You just have to be explicit about it.
> >
> > I see the value of ^Pipe and $pipe as seperate objects which can be
> > manipulated programmatically. What I don't really understand is what
> > exactly Pipe is and where it would be useful.
> >
> > They way you have described Pipe feels a little muddy to me and I am
> > unsure about its purpose and semantics. Is it just an object I ask
> > `.can()` or does it have some deeper usefulness?
>

> Well since ^Pipe will really just be the same value as Pipe.meta, then
> you can do many things with it (if I get my metamodel wishes that is).
> Now, in keeping with the "examples of useful things for people other
> than programmers and computers" spirit of this discussion, here is one
> possible approach to using metaclasses in a constructive way.
>
> Okay, so lets assume you own a tobacco shop, and you have modeled a
> Pipe hierarchy to represent all the pipes you sell. Your base classes
> might look something like this:
>
> class Pipe {
> has $stem;
> has $bowl;
> }
>
> class Pipe::Bowl {
> has $composed_of;
> has $color;
> has $size;
> }
>
> class Pipe::Stem {
> has $composed_of;
> has $color;
> has $length;
> has $filter = bool::false;
> }
>
> You would then model the different pipes you sell;
>
> class MagrittePipe {
> has $stem = Pipe::Stem.new(
> :composed_of<ebony>,
> :color<black>,
> :length<short>
> );
> has $bowl = Pipe::Bowl.new(
> :composed_of<mahogany>,
> :color<brown>,
> :size<medium>
> );
> }
>
> Now, you might say, why not make the MagrittePipe an instance of Pipe,
> and give the Pipe class a few more attributes, like a name. Well, if
> you did that then you couldn't subclass it of course.
>
> class MagrittePipe::SpecialEngravedAnniversayEdition {
> is MagrittePipe;
> does Engraved[$engraving_text = "Ceci n'est pas une pipe"];
> does SpecialEdition[$type<Anniversay>];
> }
>
> Now, what does all this have to do with metamodel?
>
> Well, using introspection, it becomes very simple to discover various
> qualities about your inventory, enough to probably even autogenerate
> the HTML pages for your online-web store (powered by Perl 6 of
> course). And lets not forget the uber-cool Perl 6 Object Database
> which you are using to store your real-time inventory in (all
> metamodel powered of course). And of course if you want, you can use
> the DistributedObjectProxy metaclass which will automatically make
> your objects distributed so that your door-to-door Pipe saleforce can
> update your inventory in real time from their cellphones. And your R&D
> department can use the built-in (but as yet unspeced) logic
> programming features of Perl 6 to mine your customer information from
> your (previously mentioend) object database and genetically "grow"
> new, more desireable Pipe products (which is easy to do since your
> metaclasses are programatically composable (and no I don't mean eval
> $code)).
>
> Of course, I am just dreaming here, but .... maybe I am not! Most of
> this is already possible using CLOS (see the Franz's AllegroCL 8.0
> it's bad*ss IMO), so why can't we have it?
>
> Anyway, I hope that doesn't make your head hurt too much Matt ;)

Now that everyone is on the same page, I will go about responding

> class Pipe {
> has $stem;
> has $bowl;
> }
>
> class Pipe::Bowl {
> has $composed_of;
> has $color;
> has $size;
> }
>
> class Pipe::Stem {
> has $composed_of;
> has $color;
> has $length;
> has $filter = bool::false;
> }

so far I am mostly with you, except one question. Does <has $filter =
bool::false;> just provide a default?

>
> You would then model the different pipes you sell;
>
> class MagrittePipe {
> has $stem = Pipe::Stem.new(
> :composed_of<ebony>,
> :color<black>,
> :length<short>
> );
> has $bowl = Pipe::Bowl.new(
> :composed_of<mahogany>,
> :color<brown>,
> :size<medium>
> );
> }
>
> Now, you might say, why not make the MagrittePipe an instance of Pipe,
> and give the Pipe class a few more attributes, like a name. Well, if
> you did that then you couldn't subclass it of course.

Actually, I was going to ask why not make MagrittePipe inherit from Pipe.

> Well, using introspection, it becomes very simple to discover various
> qualities about your inventory, enough to probably even autogenerate
> the HTML pages for your online-web store (powered by Perl 6 of
> course). And lets not forget the uber-cool Perl 6 Object Database
> which you are using to store your real-time inventory in (all
> metamodel powered of course). And of course if you want, you can use
> the DistributedObjectProxy metaclass which will automatically make
> your objects distributed so that your door-to-door Pipe saleforce can
> update your inventory in real time from their cellphones. And your R&D
> department can use the built-in (but as yet unspeced) logic
> programming features of Perl 6 to mine your customer information from
> your (previously mentioend) object database and genetically "grow"
> new, more desireable Pipe products (which is easy to do since your
> metaclasses are programatically composable (and no I don't mean eval
> $code)).

I think you mis-understand me. I do not question the value of a
powerful meta-model. Quite the contrary I want to see Perl 6 have a
meta-model more powerful and accessible then CLOS. I see it as a
necessity for a language that plans to truely scale in the future.

What I do question is the usefullness of having bare class names
represent these "prototype objects". I just don't really understand
what they are for or do.

Stevan Little

unread,
Feb 7, 2006, 7:32:18 PM2/7/06
to Matt Fowles, perl6-l...@perl.org
On 2/7/06, Matt Fowles <uber...@gmail.com> wrote:
> Stevan~
>
> I am going to assume that you intended to reply to perl 6 language,
> and thus will include your post in its entirety in my response.

Yes, sorry... I missed the "reply to all" button on the gmail UI by a
few pixels I guess. Thank you for forwarding.

> Now that everyone is on the same page, I will go about responding
>

# snip some code ....

> >
> > class Pipe::Stem {
> > has $composed_of;
> > has $color;
> > has $length;
> > has $filter = bool::false;
> > }
>
> so far I am mostly with you, except one question. Does <has $filter =
> bool::false;> just provide a default?

Yes, that is a default value. I assume that most Pipe smokers don't
like filters in their pipes, I might be wrong on that one because I am
not a pipe smoker :)

> > You would then model the different pipes you sell;
> >
> > class MagrittePipe {
> > has $stem = Pipe::Stem.new(
> > :composed_of<ebony>,
> > :color<black>,
> > :length<short>
> > );
> > has $bowl = Pipe::Bowl.new(
> > :composed_of<mahogany>,
> > :color<brown>,
> > :size<medium>
> > );
> > }
> >
> > Now, you might say, why not make the MagrittePipe an instance of Pipe,
> > and give the Pipe class a few more attributes, like a name. Well, if
> > you did that then you couldn't subclass it of course.
>
> Actually, I was going to ask why not make MagrittePipe inherit from Pipe.

Ooops, forgot that part it should infact inherit from Pipe. And of
course you can do that dynamically with the metamodel ;)

> > Well, using introspection, it becomes very simple to discover various
> > qualities about your inventory, enough to probably even autogenerate
> > the HTML pages for your online-web store (powered by Perl 6 of
> > course). And lets not forget the uber-cool Perl 6 Object Database
> > which you are using to store your real-time inventory in (all
> > metamodel powered of course). And of course if you want, you can use
> > the DistributedObjectProxy metaclass which will automatically make
> > your objects distributed so that your door-to-door Pipe saleforce can
> > update your inventory in real time from their cellphones. And your R&D
> > department can use the built-in (but as yet unspeced) logic
> > programming features of Perl 6 to mine your customer information from
> > your (previously mentioend) object database and genetically "grow"
> > new, more desireable Pipe products (which is easy to do since your
> > metaclasses are programatically composable (and no I don't mean eval
> > $code)).
>
> I think you mis-understand me. I do not question the value of a
> powerful meta-model. Quite the contrary I want to see Perl 6 have a
> meta-model more powerful and accessible then CLOS. I see it as a
> necessity for a language that plans to truely scale in the future.
>
> What I do question is the usefullness of having bare class names
> represent these "prototype objects". I just don't really understand
> what they are for or do.

Well, to be totally honest, I think only Larry truely understands
their usage, but to the best of my understanding they are intented to
serve a number of roles;

(Larry, please correct me if I am wrong here)

- to allow for introspection of the class.

After all ^Foo.can() is really just a series of method calls to the
Foo metaobject. And besides ^Foo.meta.can() is 5 more characters to
type!!

- provide an invocant for "class" methods.

Larry does not like the class-method/instance-method distinction (in
fact it seems he doesn't even like the class/instance distinction
either), and has declared that a "class method" is really just a
method of the class which does not access any instance attributes.
Well, this complicates the type signature of the invocant, and we need
an invocant that the type-checker can check.

In Perl 5, classes were just package names which were just strings.
This will not work in Perl 6 in the presence of a reasonably decent
type checker, the class needs to be *something*. Now Larry has also
declared that he does not like the idea of a "class object", I think
this is because that means that a properly typed method signature for
a class method would look like this:

class Foo {
method foo (Class $class:) {
say "I am a class method, and proud of it";
}
}

According to the signature, this method takes any Class instance as an
invocant. Well
thats just not right because it should only accept the Class instance
which represents the Foo class. But we can't (at least I dont think we
can) be that specific, at least not easily enough to also allow this
method to be called by an instance of Foo as well.

So, the solution, use "prototype instances" for "class objects". So
now we can properly type our class method for both Foo and $foo like
this:

class Foo {
method foo (Foo $class:) {
say "I am a class method, and proud of it";
}
}

And whalla, we have a class/instance method ala Perl 5 and it is
properly type checkable too.

Of course I might be totally wrong here, but this is my best grasp on
the subject.

Stevan

Matt Fowles

unread,
Feb 7, 2006, 10:18:24 PM2/7/06
to Stevan Little, perl6-l...@perl.org
Stevan~

On 2/7/06, Stevan Little <stevan...@gmail.com> wrote:
>

> Well, to be totally honest, I think only Larry truely understands
> their usage, but to the best of my understanding they are intented to
> serve a number of roles;

I agree with you about that, which is part of what bothers me.

Perl 6 allows dispatch on value (if I am not mistaken). Thus, just as we have a

sub fact( Int 0 ) { return 0; }
sub fact( Int $n ) { return $n * fact($n-1); }

Why not have class methods take the form

class Foo {
method foo (Class Foo) {


say "I am a class method, and proud of it";
}
}

They are still well types (I think), and properly restricts the types
allowed for foo. After all Foo is just a specific instance of the
class Class.

Stevan Little

unread,
Feb 7, 2006, 10:26:41 PM2/7/06
to Matt Fowles, perl6-l...@perl.org
On 2/7/06, Matt Fowles <uber...@gmail.com> wrote:

Larry is going to have to answer the why part of that descision.
However, I would venture to guess that dispatch on value is much
harder to grok in this case than dispatch on type. Especially since it
requires that you understand (at least partially) the metamodel.

> After all Foo is just a specific instance of the class Class.

Shhh... class objects don't exist ... I was never here,... I will I
count to three and when I snap my fingers you will awaken and will
have forgotten all about class Class.

1 ... 2 ... 3 ... *snap*

Matt Fowles

unread,
Feb 8, 2006, 11:27:33 AM2/8/06
to Stevan Little, perl6-l...@perl.org
Stevan~

... What!?!? Where was I? Oh, yeah. As I was saying, I think we
just take C++'s object system exactly.

Larry Wall

unread,
Feb 8, 2006, 12:10:04 PM2/8/06
to perl6-l...@perl.org

That's a good description of what set off the initial alarm bells, but
I think what "pushed me over the edge", er, was the more general
problem of hypothetical calls to MMD, the "if I were to call this,
what would happen?" problem:

my &mmdref := &foo:($dog, $cat, $pickle);
my &mmdref := &foo:(Dog, Cat, Pickle);

I want to be able to ask what function (or set of functions) I'd get
regardless of whether I actually have objects of that type. I want
to do it with real objects and not just types because I see it as a
kind of currying, so the syntax has to support value-based dispatch
when values are specified, but type-based dispatch in general.

And that's when I started thinking that normal people don't actually
think about types the way type theorists think about types, and we
should give normal people a way to be vague when that helps them
linguistically. The type theorists can say ^Dog when they know
they mean the class and not a dog, and the normal people can say
Dog and let the system dwim depending on which method is called.

That's the part I'm pretty sure about. The part I'm not so sure about
is the think I've been mulling for a month or so since people started
carping "But how do I mark class methods as special?" The current
solution is that, if you want them to be class methods explicitly,
you use something like the

method ^howmany () {...}

Dog.^howmany

notation to explicitly put them into a different namespace attached to
the metaclass object so they don't get confused with ordinary methods.
People get into trouble when they inherit class methods, so it seems
like a namespace issue to me, with a solution that involves putting them
somewhere where you have to work a little harder to say which class
method you're really interested in. But I'm less sure of this part
of it.

Well, hey, at least I'm not in danger of confusing category:<x y>
notation with package::<x y> notation like I did yesterday. Durn
slices... It's been kind of a rough week, and it's hard to think
clearly (and even harder to express myself clearly) when so many
other things are happening, like work.

'Course, it could just be senility setting in...wouldn't be the first time...

Larry

Jonathan Lang

unread,
Feb 8, 2006, 7:33:43 PM2/8/06
to perl6-l...@perl.org
Consider "my Dog $spot". From the Perl6-to-English Dictionary:
Dog: a dog.
$spot: the dog that is named Spot.
^Dog: the concept of a dog.

Am I understanding things correctly?

If so, here's what I'd expect: a dog can bark, or Spot can bark; but
the concept of a dog cannot bark:
can Dog "bark"; # answer: yes
can $spot "bark"; # answer: yes
can ^Dog "bark"; # answer: no

--
Jonathan "Dataweaver" Lang

Stevan Little

unread,
Feb 8, 2006, 10:35:06 PM2/8/06
to Jonathan Lang, perl6-l...@perl.org

Yes, that is correct, because:

Dog.isa(Dog) # true
$spot.isa(Dog) # true
^Dog.isa(Dog) # false

In fact ^Dog isa MetaClass (or Class whatever you want to call it).

At least that is how I see/understand it.

Stevan

Jonathan Lang

unread,
Feb 8, 2006, 11:34:31 PM2/8/06
to Stevan Little, perl6-l...@perl.org
Stevan Little wrote:
> Yes, that is correct, because:
>
> Dog.isa(Dog) # true
> $spot.isa(Dog) # true
> ^Dog.isa(Dog) # false
>
> In fact ^Dog isa MetaClass (or Class whatever you want to call it).
>
> At least that is how I see/understand it.

OK. To help me get a better idea about what's going on here, what
sorts of attributes and methods would ^Dog have?

--
Jonathan "Dataweaver" Lang

Stevan Little

unread,
Feb 9, 2006, 9:22:57 AM2/9/06
to Jonathan Lang, perl6-l...@perl.org
On 2/8/06, Jonathan Lang <dataw...@gmail.com> wrote:

Well, a metaclass describes the behaviors and attributes of a class,
and ^Dog is an *instance* of the metaclass. So actually ^Dog would not
actually have attributes and methods since it is an instance. That
said, I think ^Dog would probably respond to methods like these (some
of which are described in S12):

^Dog.name # Dog
^Dog.version # 0.0.1 (or something similiar of course)
^Dog.authority # cpan:LWALL or email:la...@wall.org

^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL

I would like to see some methods like this:

# dynamically add a method that
# Dog and $spot would respond to
^Dog.add_method(bark => method () { ... });

Which would be like doing this in Perl 5:

no strict 'refs';
*{'Dog::bark'} = sub { ... };

And of course if you can add a method, you will need to be able to
fetch and delete them as well, so a &get_method and &remove_method
would be in order as well.

And if you can add methods, surely you can add attributes, so
&(add|get|remove)_attribute would be needed.

^Dog.add_attribute(:label<$fur>, :access<rw>);

Would be equivalent to saying this:

class Dog is reopened {
has $fur is rw;
}

And ^Dog would also provide access to infromation about super and
subclasses as well. So &superclasses and &subclasses methods would
make sense too. We would also need methods to deal with Role
relationships as well.

So, given the above items, the class MetaClass might look something like this:

class MetaClass {
has $name is rw;
has $version is rw;
has $authority is rw;

has @superclasses;
has @subclasses;

has %methods;
has %attributes;

method identifier { ... }

method superclasses { ... }
method subclasses { ... }

method add_method { ... }
method get_method { ... }
method remove_method { ... }

method add_attribute { ... }
method get_attribute { ... }
method remove_attribute { ... }
}

So given this, you could almost look at this code:

class Foo-0.0.1-cpan:JRANDOM {
has $bar is rw;

method baz (Foo $self:) { ... }
}

As being roughly equivalent to the following code:

^Foo := MetaClass.new();
^Foo.name('Foo');
^Foo.version(0.0.1);
^Foo.authority(:cpan<JRANDOM>);

^Foo.add_attribute(:label<$bar>, :access<rw>);
^Foo.add_method(baz => method (Foo $self) { ... });

Of course this is mostly unspecced, and it is still unclear exactly
how much of this meta-level API will be accessible in Perl 6 itself.
And as far the the Pugs work on this goes, we plan to have something
similar to the above available in the next release (6.28.0).

Hope this helps.

Stevan

Jonathan Lang

unread,
Feb 9, 2006, 10:37:18 AM2/9/06
to Stevan Little, perl6-l...@perl.org
Stevan Little wrote:

> Jonathan Lang wrote:
> > OK. To help me get a better idea about what's going on here, what
> > sorts of attributes and methods would ^Dog have?
>
> Well, a metaclass describes the behaviors and attributes of a class,
> and ^Dog is an *instance* of the metaclass. So actually ^Dog would not
> actually have attributes and methods since it is an instance.

Huh? A dog can bark; so the Dog class should have a method called
'bark'. Or does 'can' not mean what it seems to mean?

> That said, I think ^Dog would probably respond to methods like
> these (some of which are described in S12):

OK; apparently, what I meant when I asked "what methods and attributes
does ^Dog have?" is what you're talking about when you speak of which
methods ^Dog will respond to. To me, an object has whatever methods
that it responds to.

> ^Dog.name # Dog
> ^Dog.version # 0.0.1 (or something similiar of course)
> ^Dog.authority # cpan:LWALL or email:la...@wall.org
>
> ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL

Would it be valid to speak of ^$spot? If so, what would ^$spot.name be?

> I would like to see some methods like this:
>
> # dynamically add a method that
> # Dog and $spot would respond to
> ^Dog.add_method(bark => method () { ... });
>
> Which would be like doing this in Perl 5:
>
> no strict 'refs';
> *{'Dog::bark'} = sub { ... };

IIRC, you can always create a new method for a class, even outside of
its definition, simply by ensuring that the first parameter to be
passed in will be an object of that type:

method bark (Dog $_) { ... }

or maybe

method Dog.bark () { ... }

> And of course if you can add a method, you will need to be able to
> fetch and delete them as well, so a &get_method and &remove_method
> would be in order as well.

To fetch a method, why not have .can() return a reference to the
method upon success? I might even go so far as to treat can() as an
lvalue, using the assignment of a coderef as an alternate way of
adding or changing the object's behavior on the fly:

method bark (Dog $_:) { ... };
Dog.can("bark") = method () { ... }; # Teach the dog a new trick
Dog.can("bark") = true; # inform the dog that it ought to know how
to bark, without telling it how, yet; equivalent to a literal "=
method { ... }".
Dog.can("bark") = false; # tell the dog to forget how to bark.
Dog.can("bark") = undef; # Ditto.

(Doing this to Dog DWIMs to modifying the behavior of all dogs at once
- you're declaring that "dogs can bark" or "this is how dogs bark",
whereas doing it to $spot DWIMs to modifying the behavior of $spot
only: "$brutus.can('bark') = false": my best friend's pet dog seems to
have lost the capacity to bark in its old age; that doesn't mean that
dogs in general can't bark.)

Similar things might be done with .has (for attributes), .isa (for
superclasses), and .does (for roles).

--
Jonathan "Dataweaver" Lang

Stevan Little

unread,
Feb 9, 2006, 11:48:22 AM2/9/06
to Jonathan Lang, perl6-l...@perl.org
On 2/9/06, Jonathan Lang <dataw...@gmail.com> wrote:
> Stevan Little wrote:
> > Jonathan Lang wrote:
> > > OK. To help me get a better idea about what's going on here, what
> > > sorts of attributes and methods would ^Dog have?
> >
> > Well, a metaclass describes the behaviors and attributes of a class,
> > and ^Dog is an *instance* of the metaclass. So actually ^Dog would not
> > actually have attributes and methods since it is an instance.
>
> Huh? A dog can bark; so the Dog class should have a method called
> 'bark'. Or does 'can' not mean what it seems to mean?

^Dog is an instance of the MetaClass, while Dog (no ^ sigil) is the
"class" (actually it's a prototypical instance of the class which the
metaclass ^Dog describes, but you dont really need to know that to use
it).

^Dog.can(bark) # false
Dog.can(bark) # true

This is a very important distinction. Saying "Dog class has a method
called 'bark'", implies the following statements are true

- Dog will respond to the method called "bark".

- Given my Dog $spot, $spot will respond to the method called "bark".

- ^Dog (the metaclass instance which describes a class called "Dog")
does *not* respond to the method called "bark".

- ^Dog (since it describes the class called "Dog") manages all of the
methods which Dog and $spot will respond too, one of which is called
"bark".

There is a clear line between the meta-level (where ^Dog lives) and
the user-level (where Dog and $spot) live. This is a line which is
heavily blurred in Perl 5, and in many OO languages (aside from
Smalltalk, CLOS and a few others) the meta-level is just not
accessible at all from user-land.

> > That said, I think ^Dog would probably respond to methods like
> > these (some of which are described in S12):
>
> OK; apparently, what I meant when I asked "what methods and attributes
> does ^Dog have?" is what you're talking about when you speak of which
> methods ^Dog will respond to. To me, an object has whatever methods
> that it responds to.

I disagree, an object is an instance of a class. A class "has" the
methods that the object will respond too. You would not want to store
all the methods in each instance, it would not make sense. Each
instance needs to share a set of methods, and those methods are stored
in the class.

Well what is a class?

In Perl 5 a class is simply a package, and the subs in that package
are methods. In Perl 6 however, a class will be an instance of another
class, the MetaClass. These two things are really not that different
when you think about it.

- A Perl 5 package holds methods for you by storing them in the symbol
table. You can add, get, remove these methods from the symbol table
using the symbol table API.

- A Perl 6 class holds methods for you by storing them inside an
instance variable in an instance of the MetaClass, and you can add,
get, remove these methods by using the methods of MetaClass.

Of course you have a conceptual circulatiry issue now because well,..
what is a MetaClass? Well it could be an instance of a MetaMetaClass,
but what is that an instance of? This could go on forever (turtles all
the way down as it is sometimes called).

But in practice you either just stop and say "this is as far as it
goes", or you bootstrap your class model somehow and "tie the knot".
I prefer the boostrapping as it is much more elegant and tends to
allow for much more flexibility.

> > ^Dog.name # Dog
> > ^Dog.version # 0.0.1 (or something similiar of course)
> > ^Dog.authority # cpan:LWALL or email:la...@wall.org
> >
> > ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL
>
> Would it be valid to speak of ^$spot? If so, what would ^$spot.name be?

There is no such thing as a ^$spot. The ^ is the "class" sigil, and
will hold metaclass instances only, just as variables with % will
only holds hashes, and variables with @ will only holds arrays, etc.

> > I would like to see some methods like this:
> >
> > # dynamically add a method that
> > # Dog and $spot would respond to
> > ^Dog.add_method(bark => method () { ... });
> >
> > Which would be like doing this in Perl 5:
> >
> > no strict 'refs';
> > *{'Dog::bark'} = sub { ... };
>
> IIRC, you can always create a new method for a class, even outside of
> its definition, simply by ensuring that the first parameter to be
> passed in will be an object of that type:
>
> method bark (Dog $_) { ... }

I don't think this is true unless it is a multi method, in which case
it is not actually a method of the of the class, but instead just
DWIMs because of MMD and the fact we allow an invocant calling style
freely.

> or maybe
>
> method Dog.bark () { ... }

Yes that works too. But TIMTOWTDI, and each has it's own benefits.
Your above approach works fine while you are writing the code, but is
not as useful for dynamically adding a method at runtime (unless you
use eval(), but that gets ugly). Using the metaclass API dynamically
adding a method to a class at runtime is trivial, again, think of it
as being no different that doing this in Perl 5:

# deep within a function somewhere ...
if ($some_condition_is_true) {
no strict 'refs';
*{$class . '::' . $method_name} = $method;
}

It would just look a little different.

# deep within a function somewhere ...
if ($some_condition_is_true) {
$class.add_method($method_name => $method);
}

In fact, if you want to experiment with this type of metaclass API, I
have a module for doing this in Perl 5 here
(http://search.cpan.org/~stevan/Class-MOP), it is fairly well
documented and the code is heavily commented.

> > And of course if you can add a method, you will need to be able to
> > fetch and delete them as well, so a &get_method and &remove_method
> > would be in order as well.
>
> To fetch a method, why not have .can() return a reference to the
> method upon success? I might even go so far as to treat can() as an
> lvalue, using the assignment of a coderef as an alternate way of
> adding or changing the object's behavior on the fly:
>
> method bark (Dog $_:) { ... };
> Dog.can("bark") = method () { ... }; # Teach the dog a new trick
> Dog.can("bark") = true; # inform the dog that it ought to know how
> to bark, without telling it how, yet; equivalent to a literal "=
> method { ... }".
> Dog.can("bark") = false; # tell the dog to forget how to bark.
> Dog.can("bark") = undef; # Ditto.

I see one major problem with this, and that is that .can() will search
up the class heirarchy of which Dog is a part of. So even though
.can() returns true, that does not mean the method is defined in Dog,
it could be defined in Mammal or LifeForm or even the base Object. If
.can() was an lvalue then what method am I modifying? This is big-time
"action at a distance" and I don't like it at all.

> (Doing this to Dog DWIMs to modifying the behavior of all dogs at once
> - you're declaring that "dogs can bark" or "this is how dogs bark",
> whereas doing it to $spot DWIMs to modifying the behavior of $spot
> only: "$brutus.can('bark') = false": my best friend's pet dog seems to
> have lost the capacity to bark in its old age; that doesn't mean that
> dogs in general can't bark.)

Adding methods to instances is a feature which Ruby has (they call
them singleton methods). And which I think Perl 6 should have too,
but I think the same problems with your API proposal exist with $spot
as they do with Dog.

> Similar things might be done with .has (for attributes), .isa (for
> superclasses), and .does (for roles).

Again, .isa() is not local, so just because Dog.isa(Mammal) returns
true does not mean that Mammal is a direct superclass of Dog. The same
applies to Roles and attributes as well.

It is important to remember that the metaclass instance ^Dog only
describes Dog, and not any of it's superclasses or roles. It is only
the local class, and nothing more.

Stevan

Jonathan Lang

unread,
Feb 9, 2006, 7:07:36 PM2/9/06
to Stevan Little, perl6-l...@perl.org
Stevan Little wrote:
> Jonathan Lang wrote:
> > OK; apparently, what I meant when I asked "what methods and attributes
> > does ^Dog have?" is what you're talking about when you speak of which
> > methods ^Dog will respond to. To me, an object has whatever methods
> > that it responds to.
>
> I disagree, an object is an instance of a class. A class "has" the
> methods that the object will respond too. You would not want to store
> all the methods in each instance, it would not make sense. Each
> instance needs to share a set of methods, and those methods are stored
> in the class.

I think that we're talking past each other: you're trying to educate
me on how a programmer should think about objects and classes; I'm
trying to figure out how a non-programmer thinks of them.

To non-programmers (and amateur programmers), objects aren't instances
of classes; classes are categories of related objects. Objects have
behaviors and characteristics; classes are a convenient shorthand for
describing behaviors and characteristics common to a set. Objects
come first, while classes are thought of in the context of objects.
The same implementation can be used for both perspectives: "dogs can
bark; Spot is a dog; therefore, Spot can bark" is a form of reasoning
that underlies using the class-and-instance model for the "back-end"
implementation of the object-and-category paradigm.

"classes have methods; objects respond to them" is part of the
classes-and-instances paradigm; but that isn't really how people
think.

In terms of practical differences: under the classes-and-instances
paradigm, if you want to create an object whose behavior differs
slightly from a given class, you need to create a subclass that has
the desired behavior and to create the object as an instance of that
subclass. With the object-and-category paradigm, there's nothing that
insists that every object's behavior must conform precisely to the
behaviors described by its classes; the latter are "merely" rules of
thumb to apply to the former until you learn differently, and
behaviors can be added, removed, or tweaked on an individual basis.
This is why (last I checked) "but" creates a behind-the-scenes
'singleton' subclass for the new object instead of demanding that a
new subclass be explicitly created, and why I suggested the
possibility of adding, replacing, or removing methods for individual
objects as well as for classes (which, presumably, would also be
implemented under the hood by replacing the object's class by a
'singleton' subclass).

> > > ^Dog.name # Dog
> > > ^Dog.version # 0.0.1 (or something similiar of course)
> > > ^Dog.authority # cpan:LWALL or email:la...@wall.org
> > >
> > > ^Dog.identifier # returns the string Dog-0.0.1-cpan:LWALL
> >
> > Would it be valid to speak of ^$spot? If so, what would ^$spot.name be?
>
> There is no such thing as a ^$spot.

OK. The only reason I was thinking in those terms was because of the
possibility that $spot might be based on one of those
behind-the-scenes customized subclasses that I mentioned earlier: if

my Dog $brutus but cannot("bark");

How do you access the subclass of Dog that $brutus is the instance of?

> > IIRC, you can always create a new method for a class, even outside of
> > its definition, simply by ensuring that the first parameter to be
> > passed in will be an object of that type:
> >
> > method bark (Dog $_) { ... }
>
> I don't think this is true unless it is a multi method, in which case
> it is not actually a method of the of the class, but instead just
> DWIMs because of MMD and the fact we allow an invocant calling style
> freely.

I was under the impression that the distinction between a method and a
multi-method was how many of the parameters get used to dispatch:
methods aren't really "owned" by classes, any more than class
definition is a declarative process; it just looks that way on the
surface. Am I wrong about this?

> > or maybe
> >
> > method Dog.bark () { ... }
>
> Yes that works too. But TIMTOWTDI, and each has it's own benefits.

I'm aware of that, and was proposing this as Another Way.

> Your above approach works fine while you are writing the code, but is
> not as useful for dynamically adding a method at runtime (unless you
> use eval(), but that gets ugly).

I was under the impression that class definition was fundamentally a
functional process dressed up as a declarative process. "method
Dog.bark () { ... }" would seem to me to be a means of continuing that
process "after the fact" - that is, adding a method to a class after
you've left the class definition block. It seems to serve exactly the
same purpose as using the metaclass API. That is, I see it as being
alternate syntax for "^Dog.add_method(bark => method () { ... })".

> > To fetch a method, why not have .can() return a reference to the
> > method upon success? I might even go so far as to treat can() as an
> > lvalue, using the assignment of a coderef as an alternate way of
> > adding or changing the object's behavior on the fly:
> >
> > method bark (Dog $_:) { ... };
> > Dog.can("bark") = method () { ... }; # Teach the dog a new trick
> > Dog.can("bark") = true; # inform the dog that it ought to know how
> > to bark, without telling it how, yet; equivalent to a literal "=
> > method { ... }".
> > Dog.can("bark") = false; # tell the dog to forget how to bark.
> > Dog.can("bark") = undef; # Ditto.

_This_, OTOH, was originally intended as a replacement for
^Dog.add_method(), not merely as an alternative to it. That said, I'm
not averse to it being an alternative; there's something nice about
being able to use a single call with a hash of coderefs to add a batch
of methods all at once.

> I see one major problem with this, and that is that .can() will search
> up the class heirarchy of which Dog is a part of. So even though
> .can() returns true, that does not mean the method is defined in Dog,
> it could be defined in Mammal or LifeForm or even the base Object. If
> .can() was an lvalue then what method am I modifying? This is big-time
> "action at a distance" and I don't like it at all.

It's action-at-a-distance that only occurs when you're using can() in
the context of an rvalue - that is, when you're querying about the
status of existing methods. When used as an lvalue - that is, when
assigning something to it - no searching would take place; the
assignment would be made to whatever called it. Assign to a class,
and you've modified that class (not any of its superclasses); assign
to an object, and you've added, replaced, or removed a singleton
method. That is,

Dog.can("bark") = method () { ... }

would be exactly equivalent to

^Dog.add_method(bark => method () { ... });

Still, perhaps I was stretching the metaphor somewhat. "How does a
dog bark?" is a different question from "can a dog bark?" &can
addresses the latter question; &fetch_method would address the former.
So instead of trying to force it all into &can, where it probably
doesn't belong, you might be better off doing something like:

&coderef = ^Dog.method{'bark'};
^Dog.method{'bark'} = method () { ... };
delete ^Dog.method{'bark'}
^Dog.method = (sit => method () { ... }, roll_over => method () { ... });

And so on, using hash operations to fetch, add, replace, or remove
individual methods. Likewise with attributes, classes, and roles.

In the objects-and-categories paradigm, "^" would signify that I'm
wanting to deal with the nature of whatever the thing is, rather than
dealing with the thing itself. So "Dog" means "a dog"; "^Dog" means
"a dog's nature". "can $spot 'bark'" would be similar to "exists
^$spot.method<bark>", or, in English, "does the ability to bark exist
in Spot's nature?" The only possible difference might be that the
latter only consults Spot's nature itself, whereas the former consults
Spot's nature as well as the nature of any classes that Spot is in and
the nature of any roles that Spot can do.

--
Jonathan "Dataweaver" Lang

Thomas Sandlass

unread,
Feb 12, 2006, 1:16:01 PM2/12/06
to perl6-l...@perl.org
Stevan Little wrote:

> ^Dog is an instance of the MetaClass, while Dog (no ^ sigil) is the
> "class" (actually it's a prototypical instance of the class which the
> metaclass ^Dog describes, but you dont really need to know that to use
> it).
>
> ^Dog.can(bark) # false
> Dog.can(bark) # true

Wasn't the ^ sigil dropped in favor of a 0..^n list creation op?
So the first line is spelled

::Dog.can(bark) # false

instead?

> Of course you have a conceptual circulatiry issue now because well,..
> what is a MetaClass? Well it could be an instance of a MetaMetaClass,
> but what is that an instance of? This could go on forever (turtles all
> the way down as it is sometimes called).
>
> But in practice you either just stop and say "this is as far as it
> goes", or you bootstrap your class model somehow and "tie the knot".
> I prefer the boostrapping as it is much more elegant and tends to
> allow for much more flexibility.

I agree. Your cicularity is basically an a-priori infinity conceptually
one level outside of the meta system.

And there will be an orthogonal type/kind system.


> > IIRC, you can always create a new method for a class, even outside of
> > its definition, simply by ensuring that the first parameter to be
> > passed in will be an object of that type:
> >
> > method bark (Dog $_) { ... }
>
> I don't think this is true unless it is a multi method, in which case
> it is not actually a method of the of the class, but instead just
> DWIMs because of MMD and the fact we allow an invocant calling style
> freely.

Yes, the question of ownership of methods is still
somewhat unresolved. I think we need to distinguish
something I've called slots in an object from free
(multi) methods that are defined outside of the class
definition block. BTW, do the outsiders have access
to the private data slots with the $! twigil?


> > or maybe
> >
> > method Dog.bark () { ... }
>
> Yes that works too.

Shouldn't that read Dog::bark? Why the dot?
--
$TSa.greeting := "HaloO"; # mind the echo!

Jonathan Lang

unread,
Feb 12, 2006, 2:54:18 PM2/12/06
to Thomas Sandlass, perl6-l...@perl.org
Thomas Sandlass wrote:
> > > or maybe
> > >
> > > method Dog.bark () { ... }
> >
> > Yes that works too.
>
> Shouldn't that read Dog::bark? Why the dot?

Because I'm not 100% with the proper syntax of things. The intent was
to add a bark() method to Dog during runtime.

--
Jonathan "Dataweaver" Lang

TSa

unread,
Feb 14, 2006, 8:47:05 AM2/14/06
to perl6-l...@perl.org
HaloO,

Larry Wall wrote:
> That's a good description of what set off the initial alarm bells, but
> I think what "pushed me over the edge", er, was the more general
> problem of hypothetical calls to MMD, the "if I were to call this,
> what would happen?" problem:
>
> my &mmdref := &foo:($dog, $cat, $pickle);
> my &mmdref := &foo:(Dog, Cat, Pickle);

What name does the system have that maintains the dispatch relevant
information? I mean the information that is *not* the implementation
sharing meta system. I would call that the type lattice. But hadn't
we coined the name kind system or was that considered a joke?

How are they linked to the & and :: sigils?
Both share the feature of injecting bare words into their surrounding
grammar. But the & system is centered around --> arrow types and
dispatch while :: is concerned with non-arrow dispatch relevant
information. Right? How disjoint are ::foo and &foo? Is :: subsuming
all data variable sigils?


> I want to be able to ask what function (or set of functions) I'd get
> regardless of whether I actually have objects of that type. I want
> to do it with real objects and not just types because I see it as a
> kind of currying, so the syntax has to support value-based dispatch
> when values are specified, but type-based dispatch in general.

What does type-based dispatch distinguish from the value-based one?
To me values are just more specific types. Variables are just ways
to express your degree of unspecificity. A value can render a
predicate "built by SomeClass" true. IIRC, SomeClass{$foo} is the
syntax for that in theory theory. Correct me if I'm wrong, please.


> And that's when I started thinking that normal people don't actually
> think about types the way type theorists think about types, and we
> should give normal people a way to be vague when that helps them
> linguistically. The type theorists can say ^Dog when they know
> they mean the class and not a dog, and the normal people can say
> Dog and let the system dwim depending on which method is called.

I would like to make a different split through the set of programmers:
the insiders and the outsiders. The former are interested in the
internal features of an object/value the latters in the guarrantied
features. So, after picking a particular knode in the kind/type lattice
the insiders start in join direction, the outsiders in meet direction!

The inside oriented programmers try to maintain the subtypehood when
they add data or code so that the enhanced class/object remains viable
for the non-upgraded parts and more specific in the overwritten stuff.
Note that veering out of the subtype relation as an insider is *not*
prevented by the type system! But it breaks an interface contract.
The outsiders use type constraints on variables or arguments.


> That's the part I'm pretty sure about. The part I'm not so sure about
> is the think I've been mulling for a month or so since people started
> carping "But how do I mark class methods as special?" The current
> solution is that, if you want them to be class methods explicitly,
> you use something like the
>
> method ^howmany () {...}
>
> Dog.^howmany

What exactly does the ^ mean these days? Is it a unary prefix
for canonical list construction, a sigil, a twigil and dispatch
multiplicity like .?, .+ and .*, or do I miss something?


> notation to explicitly put them into a different namespace attached to
> the metaclass object so they don't get confused with ordinary methods.

I would make the pure versus non-pure split more important. A class
method is one that does *not* change the state of the object it is
called on. And isn't that indicated with the 'is pure' trait?
BTW, are we talking about inherited methods or are we also considering
submethods?


> 'Course, it could just be senility setting in...wouldn't be the first time...

Feels familiar...
--

Stevan Little

unread,
Feb 14, 2006, 11:07:14 PM2/14/06
to Thomas Sandlass, perl6-l...@perl.org
On 2/12/06, Thomas Sandlass <Thomas....@barco.com> wrote:
> > > IIRC, you can always create a new method for a class, even outside of
> > > its definition, simply by ensuring that the first parameter to be
> > > passed in will be an object of that type:
> > >
> > > method bark (Dog $_) { ... }
> >
> > I don't think this is true unless it is a multi method, in which case
> > it is not actually a method of the of the class, but instead just
> > DWIMs because of MMD and the fact we allow an invocant calling style
> > freely.
>
> Yes, the question of ownership of methods is still
> somewhat unresolved. I think we need to distinguish
> something I've called slots in an object from free
> (multi) methods that are defined outside of the class
> definition block. BTW, do the outsiders have access
> to the private data slots with the $! twigil?

I think that multimethods defined outside of the scope of the class
should not have access to the classes data slots, it should use the
accessors. And those multimethods should live in the package in which
they are defined. The class implementation can stash refs to
multimethods which apply to it for optimization reasons, but this has
nothing to do with the language design itself.

As far as method name disambiguation, we should use the calling style
(invocant vs. normal function call) to determine which method to call.

I am sure there are other edge cases to be uncovered here as well, but
I can't think of them at the moment.

Stevan

0 new messages