How are types related to classes and roles?

5 views
Skip to first unread message

Thomas Sandlaß

unread,
Feb 23, 2005, 12:21:02 PM2/23/05
to Perl 6 Language
HaloO,

I'm very puzzled about what is meant by type and class in Perl6.
In the sort ruling
http://groups-beta.google.com/group/perl.perl6.language/msg/1eb1ed4608f5604d
we saw a system of types that allow to nicely dispatch into different version
of &sort. OTOH every class or role name can serve the same purpose.
Built-in value types like Str and Int seem to be auto-coercive instead of
MMD, in particular when playing together with dedicated operators like
binary '+' versus '~'. And how does all this combine with the notion of context?
I guess that basically influences method selection.

Take the following example:

# part 1
class Cyclic[uint $base] is Int
{
multi *postfix:<++> ( Cyclic[uint $base] $i )
returns Cyclic[uint $base]
{
return (($i as uint) + 1) % $base;
}
multi *infix:<+> ( Cyclic[uint $base] $x, Int $y )
returns Cyclic[uint $base]
is symmetric
{
return abs( ($x as uint) + $y ) % $base;
}
...
}

# part 2
sub foo( Int $begin, Int $end )
{
while $begin < $end
{
...
$begin++; # assumes Int axiom: $i + 1 > $i
}
}

#part 3
my Cyclic[8] $cyclic = 3;

foo( $cyclic, 10 ); # never returns?


Does the design intent to catch such "surprises"?
E.g. by giving an error at the line 'class Cyclic[uint $base] is Int'?
But how should the violation of an abstract property of Int be checked
by the compiler?
Can this just be remedied by source code review and human reasoning?
Is there a chance for designers of classes like Int to prevent method
overriding which violates some constraints?
If yes, how are these constraints specified?
my Cyclic[7] enum DayOfWeek <Mon Tue Wed Thu Fri Sat Sun>;


Another thing: does the above definition work together with enums?

my Cyclic[7] enum DayOfWeek <Mon Tue Wed Thu Fri Sat Sun>;
my DayOfWeek $day = Fri;
say "Fri = {$day}, Sat = {$day + 1}, Sun = {$day + 2}, Mon = {$day + 3}";

Does that say "Fri = Fri, Sat = Sat, Sun = Sun, Mon = Mon"?


Regards,
--
TSa (Thomas Sandlaß)


Larry Wall

unread,
Feb 23, 2005, 3:17:19 PM2/23/05
to Perl 6 Language
On Wed, Feb 23, 2005 at 06:21:02PM +0100, Thomas Sandlaß wrote:
: HaloO,

:
: I'm very puzzled about what is meant by type and class in Perl6.
: In the sort ruling
: http://groups-beta.google.com/group/perl.perl6.language/msg/1eb1ed4608f5604d
: we saw a system of types that allow to nicely dispatch into different
: version
: of &sort. OTOH every class or role name can serve the same purpose.
: Built-in value types like Str and Int seem to be auto-coercive instead of
: MMD, in particular when playing together with dedicated operators like
: binary '+' versus '~'.

One can view the auto-coercion as a form of MMD if you allow the
autogeneration of any necessary coercion methods. However, it's not
exactly a coercion to Str or Int--it's more like promotion to a Scalar
that is able to pretend it is either Str or Int. Or you can view it
as a kind of cached conversion. The ~ operator doesn't demand the
Str type--it only demands something which can fulfill the string role.

: And how does all this combine with the notion of context?

Lazily, for the most part. In some cases we can determine context at
compile time, but often not. Certainly a subroutine cannot determine
what context it was called in until it's actually called, unless we
venture into return-value MMD, which has problems resolving against
parameter MMD.

: I guess that basically influences method selection.

Up to a point. At some point we effectively have to mix in methods
if we want to have allomorphic types like Perl 5 scalars.

: Take the following example:


:
: # part 1
: class Cyclic[uint $base] is Int
: {
: multi *postfix:<++> ( Cyclic[uint $base] $i )
: returns Cyclic[uint $base]
: {
: return (($i as uint) + 1) % $base;
: }
: multi *infix:<+> ( Cyclic[uint $base] $x, Int $y )
: returns Cyclic[uint $base]
: is symmetric
: {
: return abs( ($x as uint) + $y ) % $base;
: }
: ...
: }
:
: # part 2
: sub foo( Int $begin, Int $end )
: {
: while $begin < $end
: {
: ...
: $begin++; # assumes Int axiom: $i + 1 > $i
: }
: }
:
: #part 3
: my Cyclic[8] $cyclic = 3;
:
: foo( $cyclic, 10 ); # never returns?
:
:
: Does the design intent to catch such "surprises"?
: E.g. by giving an error at the line 'class Cyclic[uint $base] is Int'?

I don't see how. I suspect there are gazillions of ways to violate Liskov
substitutability that are in the realm of the halting problem.

: But how should the violation of an abstract property of Int be checked
: by the compiler?

I don't think that's going to be Perl's job. Where Perl 6 is going with
this it to give the programmer enough tools that they don't feel like they
have to use inheritance to do subtyping. The whole point of a subtype is
to violate Liskov, so that's why it's a separate concept.

: Can this just be remedied by source code review and human reasoning?

"Yes" and "no" are both correct answers to such a question.

: Is there a chance for designers of classes like Int to prevent method


: overriding which violates some constraints?
: If yes, how are these constraints specified?

Sure, just use DBC to supply complete regression tests as PRE and
POST blocks. Your program is not gonna run very fast though...

Oh, wait, maybe you want compile-time constraints. Sorry, I'm no
good at those. One could, I suppose, set up some kind of expert
system that will reason about code, and at least tell you when it
can and can't decide. But usually we just call that sort of thing
compile-time strong-typing, and most current Perl programmers don't
like it very much. They tend to be more into late-binding solutions.
It's possible to bridge that gap somewhat with type inferencing, but
I'm no expert in that either.

I think the best thing we can do here is to encourage a culture in
which people recognize the fundamental difference between extending
a base class and constraining a subtype, and learn to use composition
and delegation where appropriate instead of inheritance. That's why
we've given different keywords to all those concepts. It's a matter
of giving people the mental tools to think straighter. It's another
one of those natty little psychological problems that partially prove
and partially disprove the Sapir-Whorf hypothesis, which is generally
true when you want it to be false, and false when you want it to be true.

: my Cyclic[7] enum DayOfWeek <Mon Tue Wed Thu Fri Sat Sun>;


:
: Another thing: does the above definition work together with enums?

Seems like a natural fit insofar as both are subtype constraints.

: my Cyclic[7] enum DayOfWeek <Mon Tue Wed Thu Fri Sat Sun>;


: my DayOfWeek $day = Fri;
: say "Fri = {$day}, Sat = {$day + 1}, Sun = {$day + 2}, Mon = {$day + 3}";
:
: Does that say "Fri = Fri, Sat = Sat, Sun = Sun, Mon = Mon"?

I suspect that could be made to work as long as you don't also expect
DayOfWeek to have Int semantics, or the semantics of some further
subtype of DayOfWeek. This is not valid inheritance here.

The basic problem is that our inheritance is trying to model Platonic
ideals, but as Aristotle pointed out, the real world doesn't actually
have much use for Platonic ideals in its actual workings...

Larry

Autrijus Tang

unread,
Feb 24, 2005, 11:45:45 AM2/24/05
to Perl 6 Language
On Wed, Feb 23, 2005 at 12:17:19PM -0800, Larry Wall wrote:
> : And how does all this combine with the notion of context?
>
> Lazily, for the most part. In some cases we can determine context at
> compile time, but often not. Certainly a subroutine cannot determine
> what context it was called in until it's actually called, unless we
> venture into return-value MMD, which has problems resolving against
> parameter MMD.

Ugh. Pugs currently does return-value based MMD, and it has indeed
the core reason behind my recently-reported dilemma on MMD tiebreaking.
If we lose retval-MMD, many sensible cases can then be resolved without
the need of "is default".

However, retval-based MMD is neccessary to ensure compile-time
dispatch, and plays really well with type inferencing in general.
So another solution is to mark ambiguate retval-based dispatches as
ill-typed, and let the programmer resolve it by explicit type
annotation. But making it default is probably too much B&D.

So, I think late binding is a sensible (and practical) default, but
do you think it may be a good thing to have a type inference mode that
assign static contexts to expressions, and prebind as much as possible?
It may be possible to enable via a pragma or a compiler switch...

Thanks,
/Autrijus/

Larry Wall

unread,
Feb 24, 2005, 12:42:30 PM2/24/05
to Perl 6 Language
On Fri, Feb 25, 2005 at 12:45:45AM +0800, Autrijus Tang wrote:

: On Wed, Feb 23, 2005 at 12:17:19PM -0800, Larry Wall wrote:
: > : And how does all this combine with the notion of context?
: >
: > Lazily, for the most part. In some cases we can determine context at
: > compile time, but often not. Certainly a subroutine cannot determine
: > what context it was called in until it's actually called, unless we
: > venture into return-value MMD, which has problems resolving against
: > parameter MMD.
:
: Ugh. Pugs currently does return-value based MMD, and it has indeed
: the core reason behind my recently-reported dilemma on MMD tiebreaking.
: If we lose retval-MMD, many sensible cases can then be resolved without
: the need of "is default".

Though not all.

: However, retval-based MMD is neccessary to ensure compile-time


: dispatch, and plays really well with type inferencing in general.
: So another solution is to mark ambiguate retval-based dispatches as
: ill-typed, and let the programmer resolve it by explicit type
: annotation. But making it default is probably too much B&D.

Depends on where it has to be marked. Anyone can choose their B&D
level within their own lexical scope, as long as they don't impose
it on other lexical scopes.

: So, I think late binding is a sensible (and practical) default, but


: do you think it may be a good thing to have a type inference mode that
: assign static contexts to expressions, and prebind as much as possible?
: It may be possible to enable via a pragma or a compiler switch...

It's certainly something to explore. If I recall, I took some kind of
compromise position in the Apocalypse where I said we probably wouldn't
treat return-type-MMD with the same authority as parameter MMD, but
we might be able to use return type as a tie-breaker on otherwise
equivalent routines. Basically, instead of writing a single routine
with a big switch statement in it, you'd be able to write multiple
routines with the same parameters but different return types as a
form of syntactic sugar over the switch statement. It's not clear if
such an approach would buy us anything in terms of type inferencing,
except insofar as sub declarations are easier to mine the return types
out of than an embedded switch statement. Maybe that buys us a lot,
though, just as having class metadata available at compile time is
a big improvement over Perl 5's @ISA.

Anyway, I don't profess to have thought deeply about type inferencing.
But I do know that I don't want to turn Perl 6 into ML just yet...

Larry

Nicholas Clark

unread,
Feb 24, 2005, 12:17:50 PM2/24/05
to Autrijus Tang, Perl 6 Language
On Fri, Feb 25, 2005 at 12:45:45AM +0800, Autrijus Tang wrote:
> On Wed, Feb 23, 2005 at 12:17:19PM -0800, Larry Wall wrote:
> > : And how does all this combine with the notion of context?
> >
> > Lazily, for the most part. In some cases we can determine context at
> > compile time, but often not. Certainly a subroutine cannot determine
> > what context it was called in until it's actually called, unless we
> > venture into return-value MMD, which has problems resolving against
> > parameter MMD.

> However, retval-based MMD is neccessary to ensure compile-time


> dispatch, and plays really well with type inferencing in general.
> So another solution is to mark ambiguate retval-based dispatches as
> ill-typed, and let the programmer resolve it by explicit type
> annotation. But making it default is probably too much B&D.

Not that the tail should wag the dog, but as I remember it, parrot can do
return-value MMD "for free", because the continuation-passing style of
function calling means that actually there's no difference between a
function call and a function return. [It's all just one maze of non-local
gotos :-)] So if I understand it correctly, there's no speed hit in doing
return- value MMD. Just a sanity hit.

Nicholas Clark

Larry Wall

unread,
Feb 24, 2005, 12:28:14 PM2/24/05
to Perl 6 Language, Autrijus Tang
On Thu, Feb 24, 2005 at 05:17:50PM +0000, Nicholas Clark wrote:

I belive that mechanism doesn't actually combine with parameter MMD
to pick the original routine to call based on context. If I recall,
it only comes into play at the time you actually try to return.

Larry

Aaron Sherman

unread,
Feb 24, 2005, 1:36:32 PM2/24/05
to Larry Wall, Perl 6 Language
On Thu, 2005-02-24 at 12:42, Larry Wall wrote:
> On Fri, Feb 25, 2005 at 12:45:45AM +0800, Autrijus Tang wrote:
> : On Wed, Feb 23, 2005 at 12:17:19PM -0800, Larry Wall wrote:
> : > Certainly a subroutine cannot determine

> : > what context it was called in until it's actually called, unless we
> : > venture into return-value MMD, which has problems resolving against
> : > parameter MMD.
> :
> : Ugh. Pugs currently does return-value based MMD, and it has indeed
> : the core reason behind my recently-reported dilemma on MMD tiebreaking.
> : If we lose retval-MMD, many sensible cases can then be resolved without
> : the need of "is default".
>
> Though not all.

Is there any reason at all that 6.0 should have return MMD? I mean, it's
way-the-heck cool and all, but it became a "thing" when Parrot produced
this capability as a by-product of the way MMD was implemented in
conjunction with return continuations.... that doesn't mean we HAVE to
use it.

My gut feeling is that there are many places where Perl 6 has not had a
chance to get felt out (or is that up?) by the community, and we're
walking out on a dangerous limb by implementing features on top of some
of those questionable areas. Sometime after we've all gotten a sense of
what MMD means for Perl and how that differs from what MMD means to
other popular languages, perhaps then we should explore what return-MMD
could do for our lives.

Just a thought.

--
781-324-3772
a...@ajs.com
http://www.ajs.com/~ajs

Stéphane Payrard

unread,
Feb 24, 2005, 9:56:06 PM2/24/05
to Perl 6 Language

Giving scoping functions the status of list operators
would allow to drop parentheses when not used in conjunction
with initializer so one could write:

my $a, $b, $c;

instead of

my ($a, $b, $c);

Most people use scoping functions as the top most function of the
corresponding statement AST so that should not bite unsuspecting
people. Probably many more people that don't use stricture are
currently caught by the current convention that obliges to parenthesize
when multiple variables are declared. In a sense, so many people have
been bitten by surprising precedence, that they cargo-cult parentheses
as the list operator.

In my detestation of gratuitous parenthesses, I would additionally
propose a low precedence assignement operator if I could find a good
sign for it.

my $a, $b, $c := 1..3 ; # too bad := is already taken.
# set? I don't think so.
my $a, $b, $c set 1..3 ; # alphabetic like and, or, xor?
# and what precedence relative to them?


--
stef

Stéphane Payrard

unread,
Feb 24, 2005, 10:26:50 PM2/24/05
to Larry Wall, Perl 6 Language
On Thu, Feb 24, 2005 at 09:42:30AM -0800, Larry Wall wrote:

>
> Anyway, I don't profess to have thought deeply about type inferencing.
> But I do know that I don't want to turn Perl 6 into ML just yet...
>
> Larry
>

Speaking of ML, it appears to me that Perl6 rules are a mechanism that
can act very much like ML variant pattern matching. What I fail to see
in Perl6 is the equivalent of ML variant constructors.
Perhaps, you don't want to turn Perl 6 into ML just yet. :)
But if it comes for almost free...


--
stef

Luke Palmer

unread,
Feb 24, 2005, 10:09:46 PM2/24/05
to st...@payrard.net, Perl 6 Language
Stéphane Payrard writes:
>
> Giving scoping functions the status of list operators
> would allow to drop parentheses when not used in conjunction
> with initializer so one could write:
>
> my $a, $b, $c;
>
> instead of
>
> my ($a, $b, $c);

Hmm, but that kills the Perl 5 ability to do concise inline 'my's:

while my $line = =$fh {...}

However, since 'for' is getting revamped so that there isn't a need to
use inline 'my' as much, your proposal might be going somewhere. As you
point out, we don't have a low precedence equals, so we're just creating
a red herring:

my $x, $y; # fine
my $x, $y = (1, 2); # oops!

We have discussed making equals low precedence enough to eliminate the
parentheses in the standard swap:

$x, $y = $y, $x;

But there are a couple of arguments against that. First, Perl
programmers like to make assignments within listops. Second, the
parentheses make a nice visual "pill" so that you can easily see the
multiple assignment.

I don't think it's a good idea to make a new low precedence assignment.
Let's say we made it <-. Does that imply that there is also
low-precedence binding :<- and compile-time binding ::<- ? Those don't
look right. I think we're weighing making good ol' assignment low
precedence vs. having parentheses on 'my'.

Luke

Stéphane Payrard

unread,
Feb 24, 2005, 10:26:10 PM2/24/05
to Perl 6 Language, st...@payrard.net
On Fri, Feb 25, 2005 at 03:56:06AM +0100, Stéphane Payrard wrote:
>
> Giving scoping functions the status of list operators
> would allow to drop parentheses when not used in conjunction
> with initializer so one could write:
>
> my $a, $b, $c;
>
> instead of
>
> my ($a, $b, $c);

Too bad that in English there is no plural for my.
In French it would work fine

mon $a; # French for C<my>, singular

# C<mes> as a list operator
mes $a, $b, $c; # French for C<my>, plural

--
stef

Uri Guttman

unread,
Feb 24, 2005, 11:09:24 PM2/24/05
to st...@payrard.net, Perl 6 Language
>>>>> "SP" == Stéphane Payrard <st...@payrard.net> writes:

SP> On Fri, Feb 25, 2005 at 03:56:06AM +0100, Stéphane Payrard wrote:
>>
>> Giving scoping functions the status of list operators
>> would allow to drop parentheses when not used in conjunction
>> with initializer so one could write:
>>
>> my $a, $b, $c;
>>
>> instead of
>>
>> my ($a, $b, $c);

SP> Too bad that in English there is no plural for my.
SP> In French it would work fine

SP> mon $a; # French for C<my>, singular

SP> # C<mes> as a list operator
SP> mes $a, $b, $c; # French for C<my>, plural

well, our is a form of a plural my but it is not a plural of the things
that are mine/ours but rather the group owning it (which is the
namespace).

so we can try: all, mine, these, those, them
and the brooklynese variants: dese, dose, dem. :)
southern variant: y'all or yall.
maybe yall is expanded as yall mine!

yall $a, $b, $c = 1 .. 3 ;

larry?

uri

PS if this gets in, i will stop being so bigoted against southern accents! :)

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

Rod Adams

unread,
Feb 24, 2005, 11:37:08 PM2/24/05
to Luke Palmer, st...@payrard.net, Perl 6 Language
Luke Palmer wrote:

>We have discussed making equals low precedence enough to eliminate the
>parentheses in the standard swap:
>
> $x, $y = $y, $x;
>
>

$x, $y <== $y, $x;


-- Rod Adams

Stéphane Payrard

unread,
Feb 24, 2005, 11:38:35 PM2/24/05
to Perl 6 Language

>

You have got to find a plural form for all the kind of scopes
supported by Perl. Ant that gets us half-way because of the =
assignement operator precedence which is wrong in your example.

--
stef


Luke Palmer

unread,
Feb 25, 2005, 12:05:21 AM2/25/05
to Rod Adams, st...@payrard.net, Perl 6 Language

Heh, oh yeah. I guess I wasn't so off suggesting <-, then.

Well, there's half the problem. Now we just need to determine if 'my' can
leave its post as a unary declarator.

Luke

Uri Guttman

unread,
Feb 25, 2005, 12:21:13 AM2/25/05
to Luke Palmer, Rod Adams, st...@payrard.net, Perl 6 Language
>>>>> "LP" == Luke Palmer <lu...@luqui.org> writes:

LP> Rod Adams writes:
>> Luke Palmer wrote:
>>
>> >We have discussed making equals low precedence enough to eliminate the
>> >parentheses in the standard swap:
>> >
>> > $x, $y = $y, $x;
>> >
>> $x, $y <== $y, $x;

LP> Heh, oh yeah. I guess I wasn't so off suggesting <-, then.

LP> Well, there's half the problem. Now we just need to determine if
LP> 'my' can leave its post as a unary declarator.

that fixes Stéphane's problem with my yall proposal. and yall solves the
unary my problem. :)

uri

Rod Adams

unread,
Feb 25, 2005, 12:27:42 AM2/25/05
to Perl 6 Language
Luke Palmer wrote:

>Now we just need to determine if 'my' can leave its post as a unary declarator.
>
>

Don't see why not... If you ever need it unary, you can just put the ()
back in.

The question becomes which is more common:
Scoping a single variable in a list context, or scoping several
variables at once. Likely the later.


This also reminds me of the thought someone had a while back about
making = not copy in list context, making people use ==>/<== for all
list assignments. It would certainly take care of the :

$x, $y = $y, $x;

problem that will have people scratching their heads. (assuming that
doesn't trigger a warning/error). Overall, I like the protection it
provides, but dislike the extra three keystrokes it means for something
I use so often.

-- Rod Adams


Rod Adams

unread,
Feb 25, 2005, 12:44:44 AM2/25/05
to Uri Guttman, Perl6 Language List
Uri Guttman wrote:

>that fixes Stéphane's problem with my yall proposal. and yall solves the
>unary my problem. :)
>
>

Stop misusing "y'all" before this Texan has to hurt you.
And y'all wonder why we hate you damn yankees. Can't even speak properly
up there.

:-)

We should instead have a list attribute, so we can say:

$x, $y, $z are mine! mine! mine!;

(Must be spoken like a three year old when read.)

-- Rod Adams


Uri Guttman

unread,
Feb 25, 2005, 12:54:20 AM2/25/05
to Rod Adams, Perl6 Language List
>>>>> "RA" == Rod Adams <r...@rodadams.net> writes:

RA> Uri Guttman wrote:
>> that fixes Stéphane's problem with my yall proposal. and yall solves the
>> unary my problem. :)
>>
>>

RA> Stop misusing "y'all" before this Texan has to hurt you.
RA> And y'all wonder why we hate you damn yankees. Can't even speak
RA> properly up there.

RA> :-)

be glad your (losing) battle with damian was on email. between his VERY
southern accent and yours ... :) you should try to meet him at a conf
this spring/summer.

RA> We should instead have a list attribute, so we can say:

RA> $x, $y, $z are mine! mine! mine!;

RA> (Must be spoken like a three year old when read.)

but what does unary postfix ! mean? and does are distribute across mines?

Patrick R. Michaud

unread,
Feb 25, 2005, 1:12:20 AM2/25/05
to Uri Guttman, Rod Adams, Perl6 Language List
On Fri, Feb 25, 2005 at 12:54:20AM -0500, Uri Guttman wrote:
> >>>>> "RA" == Rod Adams <r...@rodadams.net> writes:
>
> RA> Uri Guttman wrote:
> >> that fixes Stéphane's problem with my yall proposal. and yall solves the
> >> unary my problem. :)
> >>
> RA> Stop misusing "y'all" before this Texan has to hurt you.
> RA> And y'all wonder why we hate you damn yankees. Can't even speak
> RA> properly up there.
>
> RA> :-)
>
> be glad your (losing) battle with damian was on email. between his VERY
> southern accent and yours ... :)

Indeed, Damian might just say that the answer to this problem is
to *again* use junctions, and eliminate the 'm' in C<my>, leaving:

y all($x, $y, $z) = 1..3;

Sorry, couldn't help myself. :-) :-) :-)

Pm

Uri Guttman

unread,
Feb 25, 2005, 1:26:33 AM2/25/05
to Patrick R. Michaud, Rod Adams, Perl6 Language List
>>>>> "PRM" == Patrick R Michaud <pmic...@pobox.com> writes:

PRM> On Fri, Feb 25, 2005 at 12:54:20AM -0500, Uri Guttman wrote:
>> >>>>> "RA" == Rod Adams <r...@rodadams.net> writes:
>>
RA> Uri Guttman wrote:
>> >> that fixes Stéphane's problem with my yall proposal. and yall solves the
>> >> unary my problem. :)
>> >>
RA> Stop misusing "y'all" before this Texan has to hurt you.
RA> And y'all wonder why we hate you damn yankees. Can't even speak
RA> properly up there.
>>
RA> :-)
>>
>> be glad your (losing) battle with damian was on email. between his VERY
>> southern accent and yours ... :)

PRM> Indeed, Damian might just say that the answer to this problem is
PRM> to *again* use junctions, and eliminate the 'm' in C<my>, leaving:

PRM> y all($x, $y, $z) = 1..3;

PRM> Sorry, couldn't help myself. :-) :-) :-)

AAUUUUGGHHHH!!!!!!

but the () snuck back in and one of the goals is to remove
them. actually i like the () to mark a list context.

so would it be:

y all $x, $y, $z <== 1..3;

and all() doesn't have ordering since it is set-like (hi rod! :), so how
do 1..3 get assigned?

Struan Judd

unread,
Feb 24, 2005, 10:44:43 PM2/24/05
to perl6-l...@perl.org
Luke Palmer wrote:
> I don't think it's a good idea to make a new low precedence assignment.
> Let's say we made it <-. Does that imply that there is also
> low-precedence binding :<- and compile-time binding ::<- ? Those don't
> look right. I think we're weighing making good ol' assignment low

surely they could be
<:- and <::-
those look a lot nicer :)

> precedence vs. having parentheses on 'my'.
>
> Luke

TTFN, Struan

Aldo Calpini

unread,
Feb 25, 2005, 2:04:02 PM2/25/05
to st...@payrard.net, Perl 6 Language
Stéphane Payrard wrote:
> # set? I don't think so.
> my $a, $b, $c set 1..3 ; # alphabetic like and, or, xor?
> # and what precedence relative to them?

well, I'm not sure the feature is good, but I have some idea about the
sign that could be used for this :-)

we have all sort of verb forms in Perl6 (is, has, does) so the natural
choice seems to be:

my $a, $b, $c are 1..3;

perhaps it could also be made to DWIM for:

my @colours are $red, $green, $blue;

or, more prosaically, we could coerce the fat pipe operator to work as a
slurpy assignment in this case:

my $a, $b, $c <== 1..3; # hmmm... am I breaking something here?

or we could even just use an hyper-equal:

my $a, $b, $c »=« 1..3;

if not for low precedence assignment, "are" could still be used as a
(low precedence) "plural" type declaration, as in:

my $spot, $fido, $billy are Dog; # not Dogs, alas

but I'm afraid this wouldn't be terribly useful either.

ok, enough ranting.

cheers,
Aldo

Thomas Sandlaß

unread,
Feb 27, 2005, 5:48:29 PM2/27/05
to Perl 6 Language
HaloO,

Larry Wall wrote:
> On Fri, Feb 25, 2005 at 12:45:45AM +0800, Autrijus Tang wrote:
> : So, I think late binding is a sensible (and practical) default, but
> : do you think it may be a good thing to have a type inference mode that
> : assign static contexts to expressions, and prebind as much as possible?
> : It may be possible to enable via a pragma or a compiler switch...

Well, that is the optimizer everybody keeps talking about. And the more
type input it has, the better it can pre-select multi methods. A very
interesting feature for later versions of Perl 6 could even allow to perform
complete program optimization where code passages in modules that can't be
pre-selected on local information alone could be optimized when all type
information is available.


> It's certainly something to explore. If I recall, I took some kind of
> compromise position in the Apocalypse where I said we probably wouldn't
> treat return-type-MMD with the same authority as parameter MMD, but
> we might be able to use return type as a tie-breaker on otherwise
> equivalent routines.

I guess "equivalent routines" shall mean "same specificity of invocant type"?
At that point to choose the multi with the lower return type seems tricky
and might lead to surprises. Note the following little diagram where the two
operators

<: subtype
:> supertype

---which BTW would make nice standard operators :) ---
are used to show the function subtyping and method selection in one picture:

method selection covariant
+-------------------------- <: ----------------------+
| |
multi sub f2 ( Inv2 : Arg2 ) returns Ret2 <: multi sub Ret1 f1 ( Inv1 : Arg1 )
| | | |
subtyping of | covariant +---- <: ------------+ |
Code objects | |
+------------------- :> -----------------------------+
contravariant


For method selection the short names have to be the same of course. The Arg
types are handled as type errors at runtime or compile time, right?
No tertiary tie breaking? :)


> Basically, instead of writing a single routine
> with a big switch statement in it, you'd be able to write multiple
> routines with the same parameters but different return types as a
> form of syntactic sugar over the switch statement. It's not clear if
> such an approach would buy us anything in terms of type inferencing,
> except insofar as sub declarations are easier to mine the return types
> out of than an embedded switch statement. Maybe that buys us a lot,
> though, just as having class metadata available at compile time is
> a big improvement over Perl 5's @ISA.
>
> Anyway, I don't profess to have thought deeply about type inferencing.
> But I do know that I don't want to turn Perl 6 into ML just yet...

Hasn't type inferencing become easy with the full power of junctions?
I imagine the compiler annotating the AST with types from the leaves up.
At multi calls which can't be pre-selected at compile time a one() junction
of all possibly matching multi's return types is assigned.

BTW, How many types does Int|Str|Num produce?
All these: Int|Str|Num, Int|Str, Int|Num, Str|Num, Int, Str, Num?
Or just the last three? What is then the role of Int^Str^Num?

Is the syntax

type Criterion ::= KeyExtractor
| Comparator
| Pair(KeyExtractor, Comparator)
;

used in the sort ruling still current? There the RHS looks more like
a grammar rule alternation which is checked in turn than a real any()
junction.

Thomas Sandlaß

unread,
Feb 28, 2005, 10:34:33 AM2/28/05
to Aaron Sherman, Perl 6 Language
HaloO Aaron,

you wrote:
> Is there any reason at all that 6.0 should have return MMD? I mean, it's
> way-the-heck cool and all, but it became a "thing" when Parrot produced
> this capability as a by-product of the way MMD was implemented in
> conjunction with return continuations.... that doesn't mean we HAVE to
> use it.

Am I missing something, but the only thing I've figured out so far is that
Parrot uses ternary MMD for its builtin binary ops like ADD, MUL, OR, etc.
They are ternary to prevent a final copy or conversion of the result to the
target register. Where is the general MMD mechanism?

Will the Perl 6 MMD be directly implemented in Parrot or on top of it?
I guess Parrot needs to do it for language interoperability, right?

Thomas Sandlaß

unread,
Feb 28, 2005, 12:45:38 PM2/28/05
to Aaron Sherman, Perl 6 Language
HaloO Aaron,

you wrote:
> Um... I think you're thinking of operator overloading, which in Parrot
> actually does use the MMD facility under the hood, but MMD is nominally
> a separate facility. You should glance at the PDDs, as they have far
> more detail than I'm aware of.

You mean the ones in the docs/pdd directory of the Parrot CVS?
There's nothing about MMD.

What I mean is mails from Leo like these from December 2004:
http://groups-beta.google.com/group/perl.perl6.internals/msg/1579a27d9f695ebb
http://groups-beta.google.com/group/perl.perl6.internals/msg/de8a10bd920709a1

The opcodes for 'callmethod_MMD_3_sig "func"' and 'callmethod_MMD_n "func", n'
are simply not there yet, right? Neither are opcodes for making entries into
the dispatch tables/trees. Does Perl 6 actually need predicate dispatch?
After all we can specify closures and smart matches in the 'where' of multi
method parameter types!

Sorry, if this is the wrong list for discussing these Parrot details.
--
TSa (Thomas Sandlaß)

Aaron Sherman

unread,
Feb 28, 2005, 12:06:32 PM2/28/05
to Thomas Sandlaß, Perl 6 Language
On Mon, 2005-02-28 at 10:34, Thomas Sandlaß wrote:

> Am I missing something, but the only thing I've figured out so far is that
> Parrot uses ternary MMD for its builtin binary ops like ADD, MUL, OR, etc.
> They are ternary to prevent a final copy or conversion of the result to the
> target register. Where is the general MMD mechanism?

Um... I think you're thinking of operator overloading, which in Parrot


actually does use the MMD facility under the hood, but MMD is nominally
a separate facility. You should glance at the PDDs, as they have far
more detail than I'm aware of.

> Will the Perl 6 MMD be directly implemented in Parrot or on top of it?


> I guess Parrot needs to do it for language interoperability, right?

I would expect so, yes.....

Aaron Sherman

unread,
Feb 28, 2005, 1:34:11 PM2/28/05
to Thomas Sandlaß, Perl 6 Language
On Mon, 2005-02-28 at 12:45, Thomas Sandlaß wrote:

> Sorry, if this is the wrong list for discussing these Parrot details.

Yeah, you really want to be in p6i, not p6l. These guys think a Parrot's
just a bird that says funny things and sits on a pirate's shoulder ;-)

PS: http://cpan.uwinnipeg.ca/htdocs/parrot/mmd.html

Leopold Toetsch

unread,
Feb 28, 2005, 1:12:59 PM2/28/05
to Thomas Sandlaß, perl6-l...@perl.org
Thomas Sandlaß <Thomas....@orthogon.com> wrote:

> Am I missing something, but the only thing I've figured out so far is that
> Parrot uses ternary MMD for its builtin binary ops like ADD, MUL, OR, etc.

actually binary, dispatch is based on (left, right) operands.

> They are ternary to prevent a final copy or conversion of the result to the
> target register. Where is the general MMD mechanism?

No. The destination has currently to exist. But I'll very likely put in
variants that create the destination.

Currently a static 2-dimensional MMD table is used. This will be
replaced by a dynamic lookup and caching.

> Will the Perl 6 MMD be directly implemented in Parrot or on top of it?
> I guess Parrot needs to do it for language interoperability, right?

Yep.

leo

Leopold Toetsch

unread,
Feb 28, 2005, 1:20:06 PM2/28/05
to Thomas Sandlaß, perl6-l...@perl.org
Thomas Sandlaß <Thomas....@orthogon.com> wrote:

> The opcodes for 'callmethod_MMD_3_sig "func"' and 'callmethod_MMD_n
> "func", n' are simply not there yet, right?

No. The problem is that at function call time there is no indication
that a MMD subroutine should be called. So Parrot will just do a full
MMD search, if no other indication is there that it's just a plain
subroutine.

Another problem is language interoperbility. As e.g. python has no
syntax for MMD, above opcodes would be useless - Python wouldn't be
able to call any of the MMD builtins.

leo

Thomas Sandlaß

unread,
Mar 4, 2005, 3:12:10 PM3/4/05
to Larry Wall, Perl 6 Language
HaloO Larry,

you wrote:
> One can view the auto-coercion as a form of MMD if you allow the
> autogeneration of any necessary coercion methods. However, it's not
> exactly a coercion to Str or Int--it's more like promotion to a Scalar
> that is able to pretend it is either Str or Int. Or you can view it
> as a kind of cached conversion. The ~ operator doesn't demand the
> Str type--it only demands something which can fulfill the string role.

I don't understand which role roles play :)
Since they are not instanciable they are well suited to be interpreted
as (abstract) types in other languages or type generators.
A very interesting thing is that they can be arranged into a lattice
if any() and all() junctions on roles give their lubs and glbs.
So having e.g. two roles A and B

role A { ... }
role B { ... }

we get first the rhomb shaped Hasse Diagram:

A|B lub (lowest upper bound)
/ \
/ \
A 0 B
/ \ / \
/ \ / \
/ A&B \ glb (greatest lower bound)
/ 1 / \ 2 \
/ / 3 \ \

In the cones below A and B respectively are classes that do A or B:

class X does A { ... }
class Y does B { ... }

The roles themself beeing the least member of these classes---uninstanciable "pure"
behaviour. The intersection type/role A&B is multiple inheritance (or is that
"roling"?):

class Z does A does B { ... }
class Z does A & B { ... } # valid syntax?

The junctive classes in area 0 are special because they need to do special
stuff *between* A and B. The prime example for this is

class Scalar does Str | Int { ... }

This syntax can be seen as some kind of superclassing or superroling:
a Scalar can go where no plain Str or Int can go!
BTW, what does a class that is specified without a role?
I think it would do the lub of of roles: Any. Right?

The above assumes that type checking and MMD is on behave of roles
and that classes are used for single dispatched methods only. So an
implementor of Scalar has to do some extra work for the any-junctive
behaviour, like the multiroling implemention has to resolve potential
conflicts between composed roles. Unfortunately I have no clear idea
of what these extras are and to what extent they can be enforced by
the compiler. Typically a class like Scalar mostly brings in coercions
and mixed multi methods, i.e. they are a bit less restricted in what multis
they are allowed to define---if of course Perl 6 is using implementation
side type checks at all.


> I think the best thing we can do here is to encourage a culture in
> which people recognize the fundamental difference between extending
> a base class and constraining a subtype, and learn to use composition
> and delegation where appropriate instead of inheritance. That's why
> we've given different keywords to all those concepts. It's a matter
> of giving people the mental tools to think straighter.

Does this toolset support F-bounded polymorphism? And how is its syntax?
To illustrate this question I've rephrased the examples and adjusted the
explainations from the Cecil Manual in Perl 6 below. The original can be
found at

http://www.cs.washington.edu/research/projects/cecil/www/Vortex-Three-Zero/doc-cecil-lang/cecil-spec-86.html

This subsection describes an example of advanced use of the Cecil type
system, F-bounded polymorphism. As we will see, no special support for
this powerful idiom is needed in the type system -- it is made
possible by allowing constraints to be recursive, whereby a type
variable can appear in its own bound.

For our first example, let us consider an abstract object ordered and
a binary method >. A binary method is a method that expects two
arguments of similar types; the > method can be applied, for example,
to two numbers or two strings, but not a string and a number. We would
like to define this method once, in the Ordered role, and have other
classes, such as Num and Str, inherit it. The simplest way to
achieve it seems to be as follows:

role Ordered
{
multi method infix:«<=» ( Ordered $x, Ordered $y ) returns bool
{
...
}
multi method infix:«>» ( Ordered $x, Ordered $y ) returns bool
{
return not $x <= $y
}
}

class Num does Ordered { ... }
class Str does Ordered { ... }

This code, however, leads to an undesirable effect. Since > and <= are
defined for Ordered and Num and Str are its subclasses, we are
required to write implementations of <= to compare a num and a string,
which we may not want. To avoid mixing of subclasses of ordered, we
can apply F-bounded polymorphism as follows:

role Ordered[ type ::T where { T <= Ordered[T] } ] # op '<=' defined for types?
role Ordered[ type ::T where { T does Ordered[T] } ]
role Ordered[ ::T does Ordered[T] ] # operator 'does' allowed here?
role Ordered[ Ordered[::T] ::T ]
role Ordered[ Ordered[T] ::T ] # too short, because T is not known before ::T?
{
multi method infix:«<=» ( T $x, T $y ) returns bool
{
...
}
multi method infix:«>» ( T $x, T $y ) returns bool
{
return not $x <= $y
}
}

class Num does Ordered[Num] { ... }
class Str does Ordered[Str] { ... }

class Scalar does Ordered[Num|Str] { ... } # Perl 6 actually has that

Now method > can be instantiated with Num for T (because the
instantiated constraint Num <= Ordered[Num] can be solved: there is a
corresponding declaration in the program) or with Str for T, but
cannot with Str|Num for T (which would be required in order to
compare a Num and a Str).

With this scheme, in addition to defining binary methods itself,
ordered and all its subtypes can inherit binary methods from other
objects, for example:

role Comparable[ type ::T where { T <= Comparable[T] } ]
role Comparable[ ::T does Comparable[T] ]
role Comparable[ Comparable[::T] ::T ]
role Comparable[ Comparable[T] ::T ]
{
multi method infix:«==» ( T $x, T $y ) returns bool
{
...
}
multi method infix:«!=» ( T $x, T $y ) returns bool
{
return not $x == $y
}
}

role Ordered[ type ::T ] does Comparable[T]
{
multi method infix:«<=» ( T $x, T $y ) returns bool
{
...
}
multi method infix:«>» ( T $x, T $y ) returns bool
{
return not $x <= $y
}
}

Moreover, Num can have subtypes, such as Int or Float, which can be
compared with each other, but not with Str or its subtypes:

class Int is Num {...}
class Float is Num {...}
3 != 3.14 # legal


Sorry if this is too brain-dead!
--
TSa (Thomas Sandlaß)

Chromatic

unread,
Mar 4, 2005, 3:36:04 PM3/4/05
to Thomas Sandlaß, Perl 6 Language
On Fri, 2005-03-04 at 21:12 +0100, Thomas Sandlaß wrote:

> The roles themself beeing the least member of these classes---uninstanciable "pure"
> behaviour. The intersection type/role A&B is multiple inheritance (or is that
> "roling"?):

I don't understand the question (I don't recognize the words "lubs" or
"glbs", for example), but I don't think this has anything at all to do
with multiple inheritance.

Generalizing types on a class based on inheritance is micromanagement.
It cares too much about how polymorphism works. This is why putting
abstract, uninstantiable classes in languages that don't support
multiple inheritance is a cure worse than the disease -- it recognizes
that there's a problem with forcing all type equivalence to go through
inheritance, but it adds a second type system alongside the first and
classes again have to know too many details about how one particular
class marks its equivalence.

I don't think that roles are necessarily unsubstantiable; class and role
names should occupy the same namespace. It ought to be possible to have
class A with a particular set of methods and class B with a set of
methods of the same name and similar enough semantics for the entire set
of behavior of those methods and be able to mark class B as performing
the A role and to be able to pass B objects into code that asks for A
objects and have things just work without A or B necessarily having to
share code and definitely without them being related to each other in
any sort of inheritance relationship.

Maybe there's not enough behavior in a role to make it a full class, but
there's enough behavior that it's useful across classes horizontally and
it deserves its own name.

Maybe that's not helpful, but I did warn that I didn't understand the
question!

-- c

Thomas Sandlaß

unread,
Mar 4, 2005, 4:33:26 PM3/4/05
to chromatic, Perl 6 Language
HaloO chromatic,

you wrote:
> I don't understand the question (I don't recognize the words "lubs" or
> "glbs", for example), but I don't think this has anything at all to do
> with multiple inheritance.

Sorry, that was given only in the picture:
lub = least upper bound (also known as supremum)
glb = greatest lower bound (infimum)
see e.g. http://www-rohan.sdsu.edu/~gawron/mathling/poset/posets.pdf


> I don't think that roles are necessarily unsubstantiable; class and role
> names should occupy the same namespace.

That is the case in Perl 6, isn't it? Makes sense to me. And subs are
in the same name space as well, right?


> It ought to be possible to have
> class A with a particular set of methods and class B with a set of
> methods of the same name and similar enough semantics for the entire set
> of behavior of those methods and be able to mark class B as performing
> the A role

Hmm, like that?

class A { ... }
class B does A { ... }


> and to be able to pass B objects into code that asks for A
> objects and have things just work without A or B necessarily having to
> share code and definitely without them being related to each other in
> any sort of inheritance relationship.

Types/roles and classes form different hierarchies. The former is
partially ordered by checking the does relation the latter by checking
the isa relation. By letting classes do roles you create families
of objects that do a certain behaviour but don't share the same
implementation. On the other hand areas of code happen to require
certain functionality. The entity that checks that they are met is the
typechecker. My question basically is about how you declare your
intensions so that the type checker can DWYM. E.g. if you were to specify
comparability so that you are just comparing the right things.


> Maybe there's not enough behavior in a role to make it a full class, but
> there's enough behavior that it's useful across classes horizontally and
> it deserves its own name.

My question is not about completeness of roles versus classes but about
how the Perl 6 type system shall work. Or better which assertions it is supposed
to make about code. This is very usefull when it comes to programming in the
large and of course it allows good optimization if the typecheker can proof
e.g. that no dynamic dispatch is needed because there is only one statically
determinable match anyway.


> Maybe that's not helpful, but I did warn that I didn't understand the
> question!

I'm struggling, too.
--
TSa (Thomas Sandlaß)

Thomas Sandlaß

unread,
Mar 4, 2005, 5:13:07 PM3/4/05
to Perl 6 Language
I wrote:
>
> A|B lub (lowest upper bound)
> / \
> / \
> A 0 B
> / \ / \
> / \ / \
> / A&B \ glb (greatest lower bound)
> / 1 / \ 2 \
> / / 3 \ \
>

I was a bit lax in explaining my picture and it's relation
to type junctions. A, B, A|B and A&B are roles. In the areas
0..3 you find classes that do the roles in the surrounding cone.
They are not related to each other by subtyping!

Outside are the classes and roles none(A,B). The subtype relation
is vertical with more general towards the top. I'm a bit unsure
what the one-junction A^B really means but the classes that do
it are located in area 1+2 ;)

I hope that helps.
--
TSa (Thomas Sandlaß)

Thomas Sandlaß

unread,
Mar 7, 2005, 12:16:21 PM3/7/05
to Perl 6 Language
HaloO,

another self-reply :)

I've added a little hack that classifies strings
into these areas 0 to 3 to illustrate my idea of
a type lattice on which composes the background
of the Perl 6 Type System. Pattern matching and
type systems are related but the question for
Perl 6 is: how exactly?

The topmost type Any has a very nice mnemonic: it's
the any-junction of all types that have no direct
supertype---their lub. Likewise there could be a None
that is the none-junction of all types that have no
subtype---their glb.

This means the Any actually depends on the loaded
program. If it only uses e.g. the unrelated types
A, B and C then Any is A|B|C. Likewise for programs
that implicitly handle strings and do numerics one
gets Any = Str|Num.

BTW, are Num and Int distinct or is there a
relation: Int is/does Num?

p6-type-match.pl
Reply all
Reply to author
Forward
0 new messages