Re: class interface of roles

2006-10-19 Thread Ruud H.G. van Tol
Larry Wall schreef:

> I suspect ordered composition is going to be rare enough that we can
> simply dehuffmanize it to
> 
> $x does A;
> $x does B;
> $x does C;

Maybe use a list-like notation? 

  $x does (A, B, C,) ;
  $x does (A ; B ; C) ;

  $x does [A, B, C,] ;
  $x does [A ; B ; C] ;

-- 
Groet, Ruud


Re: class interface of roles

2006-10-19 Thread TSa

HaloO,

Larry Wall wrote:

You've got it inside out.  Unordered is just "does A | B | C" or
some such, the | there really being coerced to a set construction,
not a junction.  In fact, & would work just as well.  I only used |
because it's more readable.  Autocoercion of junctions to sets is,
of course, conjectural.  You really have

does set(A,B,C)


I would like "does A & B & C" mean the intersection type of A, B and C.
That is a supertype of all three roles. In addition we might need
negation to get what Jonathan Lang envisoned for the Complex type that
does Num & !Comparable. IOW, I'm opting for a role combination syntax
by means of logical operators that operate on the intension set of the
involved roles. Could we get that?

BTW, the synopsis reserve Foo[Bar] and Foo{Bar} for type theoretical
operations. The former is used for parametric types. How is the latter
used?


Regards, TSa.
--


Re: class interface of roles

2006-10-19 Thread TSa

HaloO

TSa wrote:

I would like "does A & B & C" mean the intersection type of A, B and C.
That is a supertype of all three roles. In addition we might need
negation to get what Jonathan Lang envisoned for the Complex type that
does Num & !Comparable. IOW, I'm opting for a role combination syntax
by means of logical operators that operate on the intension set of the
involved roles. Could we get that?


And while we're at it, could we also introduce the subtype operator <:
and perhaps >: as the supertype operator? This would come in handy for
expressing type constraints in does clauses.
--


Re: class interface of roles

2006-10-19 Thread Jonathan Lang

Ruud H.G. van Tol wrote:

Larry Wall schreef:

> I suspect ordered composition is going to be rare enough that we can
> simply dehuffmanize it to
>
> $x does A;
> $x does B;
> $x does C;

Maybe use a list-like notation?


What happens when you try to mix ordered and unordered composition?
Under the current syntax, to compose roles A and B together, and then
C once A and B are done, one could say:

   $x does A | B does C;

Under my original suggestion, this would be:

   $x does A does B & does C;

Under Larry's suggestion, this would be:

   $x does A does B;
   $x does C;

How would you handle it?

If ordered composition is something that can be done in a single
statement, then unordered composition syntax needs to be nestable
inside ordered composition syntax - and since the goal here is to have
"does A does B" always represent unordered composition, that's what
would need to nest.

--

Despite having suggested a possible syntax for ordered composition, I
think that Larry is right in claiming that a sequence of separate
composition statements is more than sufficient in both syntax and
clarity to handle those cases where ordered composition is needed.

--
Jonathan "Dataweaver" Lang


Re: class interface of roles

2006-10-19 Thread Jonathan Lang

TSa wrote:

And while we're at it, could we also introduce the subtype operator <:
and perhaps >: as the supertype operator? This would come in handy for
expressing type constraints in does clauses.


Isn't one of those called ".does()"?

--
Jonathan "Dataweaver" Lang


Re: class interface of roles

2006-10-19 Thread TSa

HaloO,

Hmm, no one seems to read the article! There actually is another class
GenLocSquare that combines GenSquare and GenPointMixin. With that we
get a modified version of my code as follows:


role GenEqual
{
   method equal( : GenEqual $ --> Bool ) {...}
}

role GenPointMixin
{
   has Int $.x;
   has Int $.y;
   method equal( ::?CLASS GenEqual $self: ::?CLASS $p --> Bool )


This additional GenEqual type bound on the self type is all
that is needed to get the superclass interface as described
in the article.


   {
  return super.equal(p) and  # <-- handwave


return call($p) and  # normal superclass call, but I still
 # think that super.equal reads better.


 self.x == $p.x and self.y == $p.y;
   }
}

class GenSquare does GenEqual does GenPointMixin


  class GenSquare does GenEqual


{
   has Int $.side;
   method equal ( : ::?CLASS $p --> Bool )
   {
  return self.side == $p.side;
   }
}


And finally the combined class

  class GenLocSquare is GenSquare does GenPointMixin
  {}

I initially dropped it because I thought that roles can see
the pre-composed class somehow. But as Jonathan explained they
don't---at least not in compile-time class composition. And
for runtime composition you get the empty class for free!


Regards, TSa.
--


Re: class interface of roles

2006-10-19 Thread Dr.Ruud
"Jonathan Lang" schreef:

> role R does A does B does C { ... } # unordered composition
> $x does A does B does C; # ordered composition
> $y does A | B | C; # unordered composition
> 
> I'd like to see it done something like:
> 
> role R does A does B does C { ... } # unordered composition
> $x does A & does B & does C; # ordered composition
> $y does A does B does C; # unordered composition

And I was on the line of:

 role R does A | B | C { ... } # unordered composition
 $x does ( A, B, C ) ; #   ordered composition
 $y does A | B | C ;   # unordered composition

but I would like early and late binding to be explicit. 
Maybe the coder will use () around the run-time ones.

-- 
Affijn, Ruud

"Gewoon is een tijger."


Re: class interface of roles

2006-10-19 Thread Jonathan Lang

Larry Wall wrote:

Though actually, now that I think about it, the cascaded notation
in S12 is illegal according to S03, since "does" is classified as
non-chaining, which implies non-associative.


Wait a minute.  Isn't "chaining" specifically referring to the idea
that "A op B op C" implicitly becomes something like "A op B && B op
C"?  That would seem to be unrelated to the concept of associativity,
other than the fact that you can't have chaining without
associativity.  Why would "does" have to be chaining in order to be
associative?

--
Jonathan "Dataweaver" Lang


set operations for roles

2006-10-19 Thread Jonathan Lang

In "class interface of roles", Dr.Ruud wrote:

And I was on the line of:

 role R does A | B | C { ... } # unordered composition
 $x does ( A, B, C ) ; #   ordered composition
 $y does A | B | C ;   # unordered composition

but I would like early and late binding to be explicit.
Maybe the coder will use () around the run-time ones.


Note that compile-time "is" and "does" declarations can be applied
before the curly braces or inside them; if applied inside, each one is
treated as a separate statement:

   class Foo is A is B does R { ... }

   class Foo {
   is A;
   is B;
   does R;
   ...
   }

Unless you put a restriction that the body can have no more than one
"does" statement, I would expect the symmetry between these two cases
to be maintained:

   role R {
   does A;
   does B;
   ...
   }

   role R does A does B { ... }

And since one of the basic principles of multiple role composition is
that ordered composition should not be encouraged, this syntax should
represent unordered composition if it remains at all (and I think it
should).  And if unordered composition can be done this way at
compile-time, it ought to be doable in an analogous way at runtime as
well.

That said, TIMTOWTDI.  I could see "does A | B | C" being used as a
valid alternative to "does A does B does C" on the theory that '|' is
being used like a union operator and 'A', 'B', and 'C' can be viewed
as sets of methods.

One thing which should be considered when deciding whether or not to
permit this sort of syntax is that the availability of a union-ish
operator implies the availability of other set-like operators, such as
"does A & B" or "does A - B".  The problem with these latter
definitions is that, conceptually, the new role is not a superset of
either of the old ones:

   role R1 does A { ... }
   R1.does(A) # true: R1 can do everything that A can.
   A.does(R1) # false: A can't neccessarily do everything that R1 can.

   role R2 does A | B { ... }
   R2.does(A) # true: R2 can do everything that A can.
   A.does(R2) # false: A can't neccessarily do everything that R2 can.

   role R3 does A & B { ... }
   R3.does(A) # false: R3 can't neccessarily do everything that A can.
   A.does(R3) # false: A can't neccessarily do everything that R3 can.

This dissonance comes from the fact that "does" is being used in two
different ways here: as an instruction to help define a class or role
based off of another role or roles, and as a test of whether something
is a semantic superset of a role.  As long as the former only adds to
or changes the roles that it composes, the two concepts are in synch;
but once you allow subsets of roles to be composed, the symmetry
breaks.

And because you have the ability to add methods to R3 that aren't in A
or B, you can't make use of the fact that A & B is a subset of A for
type-checking purposes.

--

Hmm... how about allowing something analogous to binding as the basis
for set-like role composition:

   role Foo ::= A; # Foo.does(A) and A.does(Foo)
   role Foo ::= A | B; # Foo.does(A) and Foo.does(B)
   role Foo ::= A & B; # A.does(Foo) and B.does(Foo)
   role Foo ::= A - B; # A.does(Foo)

The first case would merely make Foo synonymous with A; nothing special here.

The second case would be equivalent to "role Foo does A does B { }".

The third case would create a new role that includes only those
methods that both A and B have; in addition, it would modify the
definitions of both A and B so that they compose Foo.

The fourth case would include those methods that are in A but not in
B, and would modify the definition of A so that it composes Foo.

These modifications to A and B won't change their existing behavior;
they'll merely add to the range of types that A and B will match.

In all of these cases, you don't get to add functionality to the new
role.  If A and B have methods that conflict, both A | B and A & B
will include an undefined method instead.  If you want to add
functionality, compose Foo into something else and add the
functionality there.

One could try to extend this notion: "A | B" creates an anonymous role
that composes A and B; "A & B" creates an anonymous role that both A
and B compose (for type-checking purposes only); "A - B" creates an
anonymous role that A composes (again, for type-checking purposes
only).  These expressions can be used in "does", or they can be bound
to a name using '::=' (or ':=' at runtime).  If parentheses get used,
you could have something akin to ordered composition, with the
innermost set operators being evaluated first: so "(A | B) | C" would
compose an anonymous role that merges A and B, and would then compose
C into the result - meaning that if A and B have conflicts, C can
resolve them.  So strictly ordered composition could be done as:

  role Foo does (((A) | B) | C) { ... }

making it visually explicit as to what gets done when.  This would
require that '&' and '|' (and possibly '-') be

Interrogative statements

2006-10-19 Thread Jonathan Lang

Let's say that I want

   $expression?;

to mean the same thing as the statement

   $_ = $expression;

That is, any statement that ends with a '?;' instead of a ';'
evaluates in scalar context instead of void context and stores the
result as the topic '$_'.  (I was going to suggest '?' intead of '?;',
but a quick review of the specs pointed out that this would be
ambiguous wrt the ? prefix operator.)

Is perl 6 powerful enough to enable this sort of thing with its
existing tools, or would the parser need to be altered?

--
Jonathan "Dataweaver" Lang