I wanted to make sure this question had a chance to get addressed, so I
am seperating it from the other thread which has digressed into the
depths of the metamodel (much to my delight too).
So..., as described in the other thread, the following statements are
true about the metamodel.
1) MetaClass is a subclass of Object
2) MetaClass is an instance of MetaClass
So the following code should be true (given a random instance $obj).
$obj.meta.isa(MetaClass);
$obj.meta.isa(Object);
Because after all, the object returned from $obj.meta should be a
MetaClass instance right?
However, Syn/Apoc 12 shows that the following is true if $foo is an
instance of the Foo class.
$foo.meta.isa(Foo)
And that $foo.isa(Foo) actually is just an alias for $foo.meta.isa(Foo).
So I am sure you can see my problem here.
The p5 prototype currently handles it as such:
$foo->isa(Foo) # returns true if $foo is an instance of Foo
$foo->meta->isa(MetaClass) # returns true since $foo->meta returns a
MetaClass instance
$foo->meta->is_a(Foo) # returns true, note the added '_'
Personally I am not a fan of the 'is_a' name, I just did it one day,
and it sort of stuck. But I do think we need to find a way to
differentiate between the two questions:
- What class are you an instance of?
- What class are you describing?
The first question can be asked of anything which inherits from Object.
The second question is really only relevant to MetaClass instances.
Thoughts, Comments, Suggestions?
Thanks,
- Stevan
The A12 verbiage was intended to indicate delegation rather than
aliasing, so there's certainly room for calling a different method
name in the meta class.
: So I am sure you can see my problem here.
:
: The p5 prototype currently handles it as such:
:
: $foo->isa(Foo) # returns true if $foo is an instance of Foo
: $foo->meta->isa(MetaClass) # returns true since $foo->meta returns a
: MetaClass instance
: $foo->meta->is_a(Foo) # returns true, note the added '_'
:
: Personally I am not a fan of the 'is_a' name, I just did it one day,
: and it sort of stuck.
Well, hey, I'm not a fan of the "isa" name, so I guess we're even.
: But I do think we need to find a way to
: differentiate between the two questions:
:
: - What class are you an instance of?
: - What class are you describing?
So why not just use "describes"? Then maybe Object.isa(Foo) delegates
to $obj.meta.describes(Foo).
: The first question can be asked of anything which inherits from Object.
: The second question is really only relevant to MetaClass instances.
:
: Thoughts, Comments, Suggestions?
My suggestion would be to assume that the Apocalypses are primarily
intended to be entertaining rather than factual. :-)
Larry
On Aug 9, 2005, at 6:18 PM, Larry Wall wrote:
> : Personally I am not a fan of the 'is_a' name, I just did it one day,
> : and it sort of stuck.
>
> Well, hey, I'm not a fan of the "isa" name, so I guess we're even.
fair enough :)
> : But I do think we need to find a way to
> : differentiate between the two questions:
> :
> : - What class are you an instance of?
> : - What class are you describing?
>
> So why not just use "describes"? Then maybe Object.isa(Foo) delegates
> to $obj.meta.describes(Foo).
I like that, but is it appropriate for subclasses as well?
Or should Object.isa(Foo) just use WALKCLASS and check the hierarchy
itself using .describes()?
> : The first question can be asked of anything which inherits from
> Object.
> : The second question is really only relevant to MetaClass instances.
> :
> : Thoughts, Comments, Suggestions?
>
> My suggestion would be to assume that the Apocalypses are primarily
> intended to be entertaining rather than factual. :-)
Already assumed :)
However, I need to start somewhere.
Thanks,
Stevan
Hmm. We have a similar problem with the new class-set notation.
These two things:
$a.does(Foo);
Bar.does(Foo);
Mean two different things:
$a (e) Foo; # or whatever we decide for `elem`
Bar (<=) Foo;
"does" is a nice dwimmy name--it works linguistically for both of
those concepts--but it would be nice to have two names that are
unambiguous for the two cases that "does" delegates to.
Of course, we could use "element" and "subset", but that doesn't work
well for people who don't like to think of types in terms of sets.
Infinite sets aren't exactly beginner-friendly.
Any ideas? I've never been very good at coming up with good names.
Luke
Luke Palmer wrote:
> On 8/9/05, Larry Wall <la...@wall.org> wrote:
>
>>So why not just use "describes"? Then maybe Object.isa(Foo) delegates
>>to $obj.meta.describes(Foo).
>
>
> Hmm. We have a similar problem with the new class-set notation.
> These two things:
Did I miss something? What is the class-set notation?
> $a.does(Foo);
> Bar.does(Foo);
>
> Mean two different things:
Really?
> $a (e) Foo; # or whatever we decide for `elem`
> Bar (<=) Foo;
>
> "does" is a nice dwimmy name--it works linguistically for both of
> those concepts--but it would be nice to have two names that are
> unambiguous for the two cases that "does" delegates to.
I interpret .does as the Perl6 equivalent of the <: operator
used in type theory to denote the subtype relation. The usual
rules for linking a class hierarchy and the type lattice is
to define classes as type instanciators. That is, all *direct*
instances share the "type" that they were created by the same
class instance. This direct-instance-of type is not uncontstraintly
transitive.
class A {...}
class B is A {...} # B.does(A) needs a check!
my B $b = B.new;
$b.does(A); # unknown
BTW, I hope that the imperative dynamic role enforcing operator
$b does X;
works in such a way that former constraints that become violated
by this operation lead to expelling the object $b refers to
e.g. from ::T.does(B). I hope no one expects &infix:does to be
a cheap operation? It should involve type contraint computations
that reposition $b in the type lattice.
I'm not sure how the .isa method works exactly. But I think it
simply traverses the inheritance hierachy "upwards" such that
$b.isa(A) returns true in the above example.
> Of course, we could use "element" and "subset", but that doesn't work
> well for people who don't like to think of types in terms of sets.
> Infinite sets aren't exactly beginner-friendly.
Same applies to F-bounded polymorphism.
> Any ideas? I've never been very good at coming up with good names.
How about
$b.by(B); # $b created by class B
$b.from(B); # instanciated from B
$b.of(B); # like nobility names if that is how it works in english
This check is not transitive. Thus $b.from(A) is false.
--
$TSa.greeting := "HaloO"; # mind the echo!
A new development in perl 6 land that will make some folks very happy.
There is now a Set role. Among its operations are (including
parentheses):
(+) Union
(*) Intersection
(-) Difference
(<=) Subset
(<) Proper subset
(>=) Superset
(>) Proper superset
(in) Element
(=) Set equality
I believe the unicode variants are also allowed.
And now we're doing away with junctive types in favor of set types.
This was mostly because:
(A|B) (<=) A
Expands to
A (<=) A || B (<=) A
Which is true. Such a type can not exist, lest every type be equal to
every other type.
So now Type does Set, so we have:
A (+) B # type representing a value that is either A or B
A (*) B # type representing a value that is both A and B
A (-) B # type representing a value that is A but not B
etc.
So types are merely sets of (hypothetical, eventual) instances,
together with a few operations to make introspection etc. easier.
You might even get Piers's all-instance introspection by Foo.elements.
That's not a guarantee though.
> > $a.does(Foo);
> > Bar.does(Foo);
> >
> > Mean two different things:
>
> Really?
Yep:
$a.does(Foo) $a (in) Foo
Bar.does(Foo) Bar (<=) Foo
Assuming that $a is not a type.
If there is any extra structure beyond set structure that we need in a
type lattice, I think it's your job to tell us what that is.
Luke
And now some people will begin to wonder how ugly set values will look.
We should also tell them that lists (and possibly any-junctions)
promote to sets in set context, so that the usual way to write a set
of numbers and strings can simply be
<1 dog 42 cat 666.5>
: So now Type does Set, so we have:
:
: A (+) B # type representing a value that is either A or B
: A (*) B # type representing a value that is both A and B
: A (-) B # type representing a value that is A but not B
: etc.
:
: So types are merely sets of (hypothetical, eventual) instances,
: together with a few operations to make introspection etc. easier.
And the type syntactic slot coerces to a set list, so instead of
my Cat|Dog $meowoof;
we can write
my (Cat,Dog) $meowoof;
though we might still allow the | notation for that as well, if "any"
also promotes to set. (We can't allow unparenthesized & though, since
it's ambiguous with & as a sigil.) There are still places where we
can use junctions as type constraints, but there are no junctional
base types because they can't always fit into a type lattice. A type
junction just implies autothreading on the constraint checks, but
we won't try to reason with type junctions.
Larry
Probably not. <cough>unicode<cough>
: I'd guess that % would be appropriate, because a
: hash is simply "Set of Pair" where the membership equivalence class is
: simply $^member.key. What syntax is used to associate the equiv-class
: with a set?
At our meeting there was much discussion of the relationship of hashes
and sets. The resolution seems to be that sets are immutable values,
and you still want to use a hash with a fixed true value to get mutable
sets. It should be easy to interconvert sets and hash keys though.
But anyway, if we assume sets are values rather than containers,
they don't really need a sigil. (The problem with treating sets as
containers is that you can't do set theory on them. When you add to
a set, it is in fact a *different* set, and should have a different
identity.)
Larry
Well, I suppose we could hedge it as part of a collaboration:
$obj.meta.helps_describe(Foo).
$obj.meta.describes_part_of(Foo).
or going with existing memes:
$obj.meta.describes_any_of(Foo).
$obj.meta.describes_all_of(Foo).
: Or should Object.isa(Foo) just use WALKCLASS and check the hierarchy
: itself using .describes()?
I suppose that's also a possibility, unless you want the metaclass to
have control of those semantics as well.
: >My suggestion would be to assume that the Apocalypses are primarily
: >intended to be entertaining rather than factual. :-)
:
: Already assumed :)
:
: However, I need to start somewhere.
These days I'm just wondering where we'll stop. :-)
Larry
> A new development in perl 6 land that will make some folks very happy.
> There is now a Set role. Among its operations are (including
> parentheses):
>
> (+) Union
> (*) Intersection
> (-) Difference
> (<=) Subset
> (<) Proper subset
> (>=) Superset
> (>) Proper superset
> (in) Element
> (=) Set equality
>
Do Sets get a sigil? I'd guess that % would be appropriate, because a
On Wed, 10 Aug 2005, Larry Wall wrote:
> And now some people will begin to wonder how ugly set values will look.
> We should also tell them that lists (and possibly any-junctions)
> promote to sets in set context, so that the usual way to write a set
> of numbers and strings can simply be
>
> <1 dog 42 cat 666.5>
Groovy, but what about this?
<1 dog 42 cat 42>
Maybe a warning with an optional fatality under "use strict 'sets'"?
-dave
/*===================================================
VegGuide.Org www.BookIRead.com
Your guide to all that's veg. My book blog
===================================================*/
> A new development in perl 6 land that will make some folks very happy.
> There is now a Set role. Among its operations are (including
> parentheses):
>
> (+) Union
> (*) Intersection
> (-) Difference
> (<=) Subset
> (<) Proper subset
> (>=) Superset
> (>) Proper superset
> (in) Element
> (=) Set equality
It makes this folk very happy for one. I can see two very cool things
coming out of this off the bat:
1. You could create a very nice mini-language that is 99% already defined
in Perl6 for generating SQL or other RDBMS queries.
2. Writing a true RDBMS in Perl6 will be that much easier, because now all
I'll have to do is overload these for the appropriate object types
(relation, tuple, etc) and the code for doing various things will flow
very naturally.
- Flavio S. Glock
2005/8/10, Dave Whipp <da...@whipp.name>:
> -----Original Message-----
> From: Luke Palmer [mailto:lrpa...@gmail.com]
> Sent: Wednesday, August 10, 2005 11:53 AM
> To: TSa
> Cc: Perl6 Language List
> Subject: Re: $object.meta.isa(?) redux
>
>
> A new development in perl 6 land that will make some folks very happy.
> There is now a Set role. Among its operations are (including
> parentheses):
>
> (+) Union
> (*) Intersection
> (-) Difference
> (<=) Subset
> (<) Proper subset
> (>=) Superset
> (>) Proper superset
> (in) Element
> (=) Set equality
>
> I believe the unicode variants are also allowed.
>
> And now we're doing away with junctive types in favor of set types.
Will there be an operator for symmetric difference? I nominate (^).
Joe Gottman
That makes sense, although bear in mind that the existing Set module for
Perl 6, and the Set::Scalar and Set::Object modules for Perl 5 use % for
this (largely due to overloading restrictions, of course).
There is no unicode or mathematical operator for symmetric difference,
it seems.
Sam.
Note "there is now a Set role". Emphasis on role. There will be a
finite set class to go with it, but really these operators just
specify an interface (and a few default implementations when they can
be inferred). You can implement whatever you like that implements
this interface.
You might not want to call it a container, since it's not a container.
Luke
I usually see infix delta (which probably comes from /\, where \ is
set difference). That makes (^) seem all the sweeter, since it kinda
looks like a delta. But then maybe we should make set difference (\).
Luke
I doubt that should be any kind of warning or error. It's just that
your set will end up having four elements instead of five. But you
really don't want to warn in this case:
@myset (+) <1>;
By using the (+) operator (instead of the list concatenation, er,
operator?), the user is implying that he wants duplicates in @myset
thrown away.
Luke
Small issue, what comparison operator do you use to determine
duplicates? For example (possibly pathological case):
(undef but true) (+) (undef but false)
Actually, I'm going to make a stab at answering this myself. The
obvious answer is that you use the magic operator ~~ by default just
like for a case statement. But there does need to be some way to change
that when necessary.
We talked about that some in Portland. We figured ~~ was probably
too dwimmy to serve that purpose, and that what we really needed was
the same comparison that will have to be used for hashes that are
allowed to contain objects, but also want to store values as values.
Essentially immutable values want to compare as values but mutable
objects by reference as individual entities. At the moment we're
calling that operator "eqv", short for both "equivalent" and "equal
value".
It does need to be possible to change that, but since sets are
immutable values, we need only provide an alternate comparison to
the constructor, and the set itself needn't remember it. On the
other hand, hashes behaving like mutable sets need to remember their
comparison operator if it is not the default.
Larry
Larry Wall wrote:
> [..] but since sets are
> immutable values,
Does that imply they travel in $vars and are a subtype
of Value? Is Undef of Set the Set::Empty? Is Set::Empty false?
> we need only provide an alternate comparison to
> the constructor, and the set itself needn't remember it. On the
> other hand, hashes behaving like mutable sets need to remember their
> comparison operator if it is not the default.
The slot accessor paradigma again...
Isn't the comparator a free method subtype? Why interfering
at construction time?
I believe so.
: Is Undef of Set the Set::Empty?
I don't think so. The empty set should probably be considered a
defined value.
: Is Set::Empty false?
Presumably that would be useful.
: >we need only provide an alternate comparison to
: >the constructor, and the set itself needn't remember it. On the
: >other hand, hashes behaving like mutable sets need to remember their
: >comparison operator if it is not the default.
:
: The slot accessor paradigma again...
: Isn't the comparator a free method subtype? Why interfering
: at construction time?
I haven't the foggiest idea what you are asking, but here are some
random answers.
We don't want to force everyone to specify it every time, because defaults
are friendly.
Whose construction time? The hash's? Because that's when you'd want
to override the default.
Or are you just carping that you don't believe in OO-ness? The whole
point of OO is that objects have state.
If one of those answers doesn't suit, please feel free to make up another. :-)
Larry
you wrote:
> : >we need only provide an alternate comparison to
> : >the constructor, and the set itself needn't remember it. On the
> : >other hand, hashes behaving like mutable sets need to remember their
> : >comparison operator if it is not the default.
> :
> : The slot accessor paradigma again...
> : Isn't the comparator a free method subtype? Why interfering
> : at construction time?
>
> I haven't the foggiest idea what you are asking, but here are some
> random answers.
Trying to lift the fog ;)
My point is to distinguish between on-board methods and self-contained,
free methods that are not stored or referenced through a vtable
or similar device from every object. Since slots are a metaphor on the
smallest part of an object I call these method invocations slot calls.
The syntactical destinction as pair juxtaposition $obj:action() is an
idea to make it more obvious that :action is firstly retrieved from
$obj somehow and then invoked by applying .() while $obj.action() looks
up .action and then dispatches according to the type of $obj.
A Comparator would be a free method. As such it defines a meaning and
users can hook in more implementations for certain types. In this approach
the method information is needed at compile time before the "search" of
syntactical invocant expressions starts. E.g. '.foo' needs the invocant to
the left or from some standard variable if there is nothing syntactically.
> We don't want to force everyone to specify it every time, because defaults
> are friendly.
So you want to install a Comparator into a Hash instance that is used
for *all* contained values? Or for enforcing unique keys? Or are you
talking about a Comparator that is to be used when the hash is compared
to a set value? But that would be the Method subtype Comparator[Hash,Set]
anyway.
> Whose construction time? The hash's? Because that's when you'd want
> to override the default.
>
> Or are you just carping that you don't believe in OO-ness? The whole
> point of OO is that objects have state.
Yes, of course. I think it's more likely that I don't understand why
Perlkind is so obsessed with the container versus value distinction
on the language level. The only importance I see in this is that objects
are heavy-weight and as such recommend handling per reference and in-place
mutation. The latter is carried out at some level through slot calls
provided by the object itself. But more generic concepts are provided
through free methods where class implementors can hook into. If this
hooking shall happen on a larger scale than single methods, roles can
be used to compose classes.
With
my $set = set(1,2,3); # correct syntax?
my %hash = { 1 => true, 2 => true, 3 => true };
questions like
if %hash eqv $set {...}
if 3 (in) $set {...}
if %hash<3> {...}
have to be compiled to an actual test if the only thing you know
is that their result type is bool. If the compile time knowledge
is more specific---either true or false---then the test can be
skipped. E.g.
if 3 (in) set(1,2,3) { say 42; }
is just a verbose form of
say 42;
Ohh, perhaps you were talking about inhomogenious cases like
my $set = set(1,'2',Dog.new);
my %hash = { 1 => true, '2' => true, Dod.new => true };
such that you could force e.g. stringified comparison for
if $set eqv %hash {...}
> If one of those answers doesn't suit, please feel free to make up another. :-)
Another question or another answer?