Re: how typish are roles

2006-10-30 Thread TSa

HaloO,

Jonathan Lang wrote:

Larry Wall wrote:

But I'm still somewhat set against the notion of using logical ops to
do set theory.  (Even if you put parens around them.)


Understandably so.  Perhaps (u) and (n) would be better ASCII
equivalents for the union and intersection operators...


Hmm, I think using the dualism between set operations and
boolean operations is a good thing. Note that there is an
isomorphism between , || and ! for the logical side and
(), (|) and (!) for sets---DeMorgan etc. We could even
introduce low precedence versions (and), (or) and (not).
Well, and of course (^) and (xor) corresponding to ^^ and
xor. They all form nice mnemonics for each other.


Regards, TSa.
--


Re: where constraints as roles (was Re: how typish are roles)

2006-10-30 Thread TSa

HaloO,

Jonathan Lang wrote:

At its core, a type is nothing more than a constraint on the objects
that a given variable is allowed to handle; this would put Cwhere
clauses at the center of the type system, with roles coming in a very
close second due to the implicit use of .does() in the compact
syntax.


Great idea! I like the unification of everything typish under the
umbrella of (type) constraints. These predicates then need to be
amenable to subsumption and entailment forming the dispatch lattice.
Of course the sublanguage for where clauses has to be a restricted
subset of full Perl 6. Otherwise you can't do machine proofs. This
view is shared by mmd-draft.txt, it states that conceptually all
dispatch relevant informations are predicates.

Hmm, having regular expressions in where clauses already raises
the question if one can treat them programatically. E.g. a
'where /^aa.*bb$/' is strictly more specific than 'where /^a.*b$/'.
But can that be calculated in a deterministic fashion? Would
dispatch at least work on a case by case basis? Or would we get
ambiguity errors because of principal incomparability of the two
clauses? IOW, I fear this could only be put to work with two subset
declarations

  subset ab of Str where /^a.*b$/;
  subset aabb of ab where /^aa.*bb$/;

and the notion that the second subset by virtue of constraining
the possible values further produces a more specific subtype for
dispatch. That is nominal subtyping.

BTW, the above example is a good case for introducing the subtype
relation operator : because we have aabb : ab : Str but do we
also have aabb.does(ab) and ab.does(Str)? Could we also state that
aabb () ab () Str?


Regards, TSa.
--


Re: where constraints as roles (was Re: how typish are roles)

2006-10-30 Thread Jonathan Lang

TSa wrote:

IOW, I fear this could only be put to work with two subset
declarations

   subset ab of Str where /^a.*b$/;
   subset aabb of ab where /^aa.*bb$/;

and the notion that the second subset by virtue of constraining
the possible values further produces a more specific subtype for
dispatch. That is nominal subtyping.


Perl 6 already uses nominal subtyping: S02 - Types are officially
compared using name equivalence rather than structural equivalence.
There's further elaboration which addresses many of the concerns
involved with using nominal subtyping, so I'd suggest reading the
section in question before commenting.


BTW, the above example is a good case for introducing the subtype
relation operator : because we have aabb : ab : Str but do we
also have aabb.does(ab) and ab.does(Str)? Could we also state that
aabb () ab () Str?


Regards, TSa.
--




--
Jonathan Dataweaver Lang


Re: how typish are roles

2006-10-28 Thread Trey Harris

In a message dated Sat, 28 Oct 2006, chromatic writes:
When you specify a type to constrain some operation, you specify that 
the target entity must perform that role.


That statement is very concise and direct. If the fuzziness I observed 
about the identity of the basic building block of type was unintentional, 
this statement should be added to S06.


I think the question (which you didn't directly raise, but I've heard 
from others) of whether role or class will have primacy is kind of 
as pointless as asking whether subroutines or code blocks have 
primacy: you can't use the former without the latter; the former is a 
useful abstraction for the latter, especially when code gets larger or 
is meant for sharing; and while each have places where they're more 
appropriate, either can be used in place of the other given a bit of 
syntactic twiddling.


Well... maybe.  I believe strongly that you can build a really good 
system with roles as the fundamental abstraction and where classes are a 
specialization, but doing the other way around is much more difficult 
and less cohesive.


But I wasn't suggesting that, any more than I was suggesting that code 
blocks based on anonymous subroutines would be as cohesive as subroutines 
based on code blocks.  I was just saying that both roles and classes could 
be equally first-class participants in the type system by my reading of 
S06 and S12: I don't see any necessity, short a statement like yours I 
quoted above, for classes to be coerced into a role before they can act as 
a type.


Trey


where constraints as roles (was Re: how typish are roles)

2006-10-28 Thread Trey Harris

In a message dated Sat, 28 Oct 2006, Trey Harris writes:


In a message dated Sat, 28 Oct 2006, chromatic writes:
When you specify a type to constrain some operation, you specify that the 
target entity must perform that role.


That statement is very concise and direct. If the fuzziness I observed about 
the identity of the basic building block of type was unintentional, this 
statement should be added to S06.


Incidentally, this would mean that a Cwhere clause or junctive type 
defines an anonymous role, and a type parameter defines a lexical role, 
doesn't it?  Seems like a useful characteristic of these constructs to 
make explicit, perhaps in LS12/Roles.


I find this a little unintuitive given the way these typing particles are 
used, though... If I were insane in a different way than I actually am, I 
might think I could use this every constraint is a role behavior to 
write:


   sub pairs_up_to (Int $x where { $^x % 2 == 0 } ) {
   (1..^$x:by(2)) = (2..$x:by(2))
   }

   pairs_up_to(4)};# 1 = 2, 3 = 4

   try { pairs_up_to(3) }
   err say $!; # No compatible subroutine found

   my $even_three = 3 but where { $_ % 2 == 0 };  # Huh?
   try { pairs_up_to($even_three) }
   err say $!;# What?

Not a useful example, I admit--which is why I had assumed Cwhere 
constraints were not roles, because I can't think of a useful example of 
treating them as roles.  But I suppose if you're determined to shoot 
yourself in the foot like that, you'll find some way (like overloading 
C% so it always returns 0).


You could probably even make Perl be able to call the sub in the second 
Ctry, perhaps by making the anonymous roles generated by Cwhere first 
match by AST equivalence before testing their value against the constraint 
or something.


Not that I think Perl should be able to do that... I'm just saying I 
*might* think it would, given how roles usually work (and if I could come 
up with a less contrived case, I might actually expect it to).


But *why* wouldn't it work?  One of two reasons I think:

1. The first Cwhere clause in the sub signature defines a different
   anonymous role from the second Cwhere clause after Cbut, even
   though they're defined identically.  In that case, $even_three would
   have no practical difference from any other 3, because it merely mixes
   in a role that never gets used.

2. The assignment would throw a mistyped value exception, just like
   my Num $foo = 'hi, mom' does.  (Except it doesn't.  Should it?  I
   don't see a test that addresses this in the suite, nor something in
   the Synopses to say that that assignment should fail.)

In either case, Cwhere clauses create roles that values might do without 
even realizing they're doing them, and which mutable objects might do and 
then not do, willy-nilly, even in the course of the scope in which they 
were typed to do it... which I think is new unless I just haven't been 
paying attention.


sub saturate (Color $c where { $^c.saturation  100 } ) {
$c.saturation = 100;  # ???
correct_gama($c);
}

Did that mutation throw an exception, by changing $c's type to one it 
can't have in this sub?  If no, did we just lose gradual typing (assuming 
correct_gamma cares)?  Can we detect that, or do the roles created by 
Cwhere not participate in gradual typing?  If Cwhere constraints 
weren't roles, this would make sense to me again.


It's duck-typing, but a very different type of duck typing than, say Ruby 
has... it isn't a duck because it walks and quacks, but because when you 
examine it with your particular duckish litmus test (your Cwhere 
clause), the litmus test turns the duckish color (Bool::True) you're 
looking for.


A trifling issue, I guess, as you can just ignore how Cwhere works so 
long as it does work.  But when I see a statement like every X is really 
syntactic sugar for a Y, I want to poke at all the X's to see how they 
behave deeply as Y's.


Trey


Re: where constraints as roles (was Re: how typish are roles)

2006-10-28 Thread Larry Wall
My initial inclination is to say that where clauses in a signature
are only there for pattern matching, and do not modify the official
type of the parameter within the function body.  However, on a subset
the where clause is there precisely to contribute to the typing,
so if you want the extra constraints to apply to all uses of the
parameter variable within the body, you'd need to declare a subset
type that enforces it.

On the other hand, I can imagine that an alternative would be to say
that a where clause will always subsetize the official type;
that would imply that we'd need to add a when clause for mere
pattern matching.  Something to be said for making such a distinction,
if it can be taught.

Fuzzily yours,
Larry


Re: how typish are roles

2006-10-28 Thread Larry Wall
On Thu, Oct 26, 2006 at 03:17:27PM +0200, TSa wrote:
: HaloO,
: 
: I wrote:
: 2) We have AB and the A B juxtaposition to mean $_ ~~ A  $_ ~~ B
:which is an intersection (sub)type of A and B.
: 
: Is the AB form a legal alternative for the juxtaposition?

Not in a signature.  It's ambiguous with A B where B is declaring a
routine type that returns A.  Might be made to work in parens someday.
But I'm still somewhat set against the notion of using logical ops to
do set theory.  (Even if you put parens around them.)

Larry


Re: where constraints as roles (was Re: how typish are roles)

2006-10-28 Thread Jonathan Lang

Trey Harris wrote:

Trey Harris writes:
 chromatic writes:
 When you specify a type to constrain some operation, you specify that the
 target entity must perform that role.

 That statement is very concise and direct. If the fuzziness I observed about
 the identity of the basic building block of type was unintentional, this
 statement should be added to S06.


S02 already has q[A variable's type is a constraint indicating what
sorts of values the variable may contain. More precisely, it's a
promise that the object or objects contained in the variable are
capable of responding to the methods of the indicated role.]


Incidentally, this would mean that a Cwhere clause or junctive type
defines an anonymous role, and a type parameter defines a lexical role,
doesn't it?  Seems like a useful characteristic of these constructs to
make explicit, perhaps in LS12/Roles.


IMHO, this gets it backward.  You shouldn't turn Cwhere clauses and
junctive types into roles; you should turn roles and junctive types
into Cwhere constraints: Foo $x is, in effect, shorthand for
something like $x where { .does(Foo) }, while Foo | Bar Baz $x
becomes something like $x where { .does(Foo) || .does(Bar) 
.does(Baz) }.

At its core, a type is nothing more than a constraint on the objects
that a given variable is allowed to handle; this would put Cwhere
clauses at the center of the type system, with roles coming in a very
close second due to the implicit use of .does() in the compact
syntax.  IMHO, @Larry got overly precise in the above S02 quote:
s[More precisely] = Usually.

--
Jonathan Dataweaver Lang


Re: where constraints as roles (was Re: how typish are roles)

2006-10-28 Thread chromatic
On Saturday 28 October 2006 09:15, Larry Wall wrote:

 My initial inclination is to say that where clauses in a signature
 are only there for pattern matching, and do not modify the official
 type of the parameter within the function body.  However, on a subset
 the where clause is there precisely to contribute to the typing,
 so if you want the extra constraints to apply to all uses of the
 parameter variable within the body, you'd need to declare a subset
 type that enforces it.

Right; it's awfully difficult to have nominal typing in a room full of 
blank Hello my name is tags.

 On the other hand, I can imagine that an alternative would be to say
 that a where clause will always subsetize the official type;
 that would imply that we'd need to add a when clause for mere
 pattern matching.  Something to be said for making such a distinction,
 if it can be taught.

-- c


Re: how typish are roles

2006-10-26 Thread TSa

HaloO,

I wrote:

2) We have AB and the A B juxtaposition to mean $_ ~~ A  $_ ~~ B
   which is an intersection (sub)type of A and B.


Is the AB form a legal alternative for the juxtaposition?
--


Re: how typish are roles

2006-10-25 Thread Trey Harris

In a message dated Wed, 25 Oct 2006, TSa writes:

from the recent threads 'class interface of roles', 'set operations for 
roles' and 'signature subtyping and role merging' I wonder how typish 
roles actually are. Some seem to consider roles as lightweight particles 
that serve to compose classes. I see them as the heavyweights in the 
type department. Doing a role is like a contract about certain 
functionality. So, what does @Larry think?


I'll let @Larry speak for @Larry, but at one point I was told that when 
CArray or CHash appear in signatures, those are roles, not classes; if 
you examined a particular Array or Hash, the class would be some 
implementation of the Array or Hash role, perhaps something like 
CPugsSparseArray or CParrotOpaqueHash or so on. So I'd tend to agree 
that roles are the heavyweights in the type department.


I've spent a few minutes with no luck trying to draw the actual discussion 
out of the #perl6 logger, but I'm pretty sure this was the gist.


My (probably lame) interpretation of the Weltanschauung of Perl's typing 
is that roles, classes, type parameters, and type sets (junctive types, 
subsets, and mixtures thereof) are all equally relevant to the type 
system, and are all equally typish (though perhaps some are more 
primitive and some are more sugary).


Unless you're actually composing or inheriting from something, you 
shouldn't care whether its type derives from a role, a class, a type set, 
or a type parameter.  (And if you are composing or inheriting from it, 
you're not so much interested in its typishness as its behavior.  Your new 
type will be/do whatever type(s) it inherited/composed, and will also 
be/do itself; beyond that, you shouldn't care)


My gut feeling is that in real-world Perl 6 code we'll see a lot of both 
classes and roles being used as types.  Roles will be more common typing 
particles when interacting with the Perl core or parts of other large code 
bases, and when you desire type safety.  Classes will be more common when 
you just have a local need to have something to instantiate, or you want 
SMD or MMD.  When programming in the large, the benefits of having a role 
will often be clearer; when programming in the small, a class will often 
(Cbut not always ;) be more expeditious.


I think the question (which you didn't directly raise, but I've heard from 
others) of whether role or class will have primacy is kind of as 
pointless as asking whether subroutines or code blocks have primacy: 
you can't use the former without the latter; the former is a useful 
abstraction for the latter, especially when code gets larger or is meant 
for sharing; and while each have places where they're more appropriate, 
either can be used in place of the other given a bit of syntactic 
twiddling.


I know that S12 states The type system of Perl consists of roles, 
classes, and subtypes but I don't have a clear picture of the inner 
workings or the formal model of this type system. E.g. what actually 
constitutes a type? How are the classes related to types? There is this 
fuzzy concept that a class is also a role of the same name as far as 
typing is concerned. How is the subtyping relation defined?


I can read S12 as saying that classes always do an eponymous role, and so 
role is what typing is really based on.  Or alternatively, since when a 
role is used as if it were a class, it constructs an anonymous class that 
composes it, that class is what typing is really based on.  But I don't 
see that it matters one way or the other; they seem functionally 
equivalent to me--as would having type based on Cwhere subsets, or 
having all these things participate equally, or any other angle you might 
want to look at it from.  The behavior seems pretty ecumenical to me.


In other words, I agree that it's fuzzy, but I personally read the 
fuziness as intentional, so as to allow implementations flexibility and 
prevent bad dependencies on particular inner workings of the type 
system.


Trey


Re: how typish are roles

2006-10-25 Thread TSa

HaloO,

Trey Harris wrote:
In other words, I agree that it's fuzzy, but I personally read the 
fuziness as intentional, so as to allow implementations flexibility and 
prevent bad dependencies on particular inner workings of the type system.


Thanks for the support. I figured that I've asked the same question more
than a year ago. I want to summarize what we have so far.

1) In type constraint position we can say things like A|B to effectively
   mean a supertype of A and B by virtue of $_ ~~ A || $_ ~~ B.

2) We have AB and the A B juxtaposition to mean $_ ~~ A  $_ ~~ B
   which is an intersection (sub)type of A and B.

3) The junctive ops |,  and ^ can be used in where clauses to form
   type constraints. How does that apply to any(), all(), one() and
   none()? Are they allowed as well? With none() we effectively get
   type complement.

4) The junctive ops and the set operators (|) and () are *not* yet
   available as type constructors in role definitions, that is things
   like 'role does A()B'. To comply with 2) this should create an
   intersection type even though it joins the interfaces of A and B.

Does recursive use of roles in their own definition produce F-bounds?

  role A does Gen[A] {...}

or perhaps

  role A where A.does(Gen[A]) {...}


Regards, TSa.
--


Re: how typish are roles

2006-10-25 Thread Jonathan Lang

TSa wrote:

I want to summarize what we have so far.

1) In type constraint position we can say things like A|B to effectively
mean a supertype of A and B by virtue of $_ ~~ A || $_ ~~ B.


Right.  This would be equivalent to Any where {.does(A) or .does(B)}.


2) We have AB and the A B juxtaposition to mean $_ ~~ A  $_ ~~ B
which is an intersection (sub)type of A and B.


Not according to my reading of S06: if you want to force a parameter
to match both of two different roles, you must use a where clause.


3) The junctive ops |,  and ^ can be used in where clauses to form
type constraints. How does that apply to any(), all(), one() and
none()? Are they allowed as well? With none() we effectively get
type complement.


AFAICT, any() can be used (almost) anywhere that infix:| can be;
ditto with the other junctive ops and their associated functions.  In
particular, I see no reason why they would be forbidden in where
clauses.  (The one case where any might not be usable as a
substitute for infix:| is point 1, above.  Even then, I'm not really
certain that it can't be used.)


4) The junctive ops and the set operators (|) and () are *not* yet
available as type constructors in role definitions, that is things
like 'role does A()B'.


Correct.  If there's a queue being maintained for post 6.0 features,
I'm hoping that it's in the queue; but it isn't going to be a 6.0
feature AFAIK.


Does recursive use of roles in their own definition produce F-bounds?

   role A does Gen[A] {...}


I don't see why not.  Heck, while it would usually be silly to do so,
I could even see cyclic role definitions working:

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

or even

  role A does A { ... }

(though why any role would ever want to compose itself is beyond me.)

--
Jonathan Dataweaver Lang