Re: How are types related to classes and roles?

2005-03-07 Thread Thomas Sandlaß
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?
Regards,
--
TSa (Thomas Sandlaß)
#! /usr/bin/perl

$s = @ARGV[0];

if ($s =~ /(^aa.*$)|(^.*bb$)/) # perl6: $s ~~ m:overlap/(^aa.*$)|(^.*bb$)/
{
   print success:  $1  $2\n; 
}
else
{
   print match:  $1  $2\n;
}

if  ($s =~ /^aa.*$/  || $s =~ /^.*bb$/ || $s =~ /^.*aa.*bb.*$/) { print :  A|B\n;  }
if  ($s !~ /^aa.*$/   $s !~ /^.*bb$/  $s !~ /^.*aa.*bb.*$/) { print : none(A,B)\n; }

if (($s =~ /^aa.*$/   $s !~ /^.*bb$/) ||
($s !~ /^aa.*$/   $s =~ /^.*bb$/)   ) { print :  A^B\n;  }
if  ($s =~ /^aa.*$/){ print :  A\n;}
if  (   $s =~ /^.*bb$/) { print :B\n;  }
if  ($s =~ /^aa.*$/   $s =~ /^.*bb$/) { print :  AB\n;  }


print ===\n;

if  ($s =~ /(aa.*)/) { print aa = $1\n; }
if  ($s =~ /(.*bb)/) { print bb = $1\n; }

if  ($s =~ /aa.*/ || $s =~ /.*bb/)  { print :  A|B\n;  }
if  ($s !~ /aa.*/  $s !~ /.*bb/)  { print : none(A,B)\n; }

if (($s =~ /aa.*/   $s !~ /.*bb/) ||
($s !~ /aa.*/   $s =~ /.*bb/)   ) { print :  A^B\n;  }
if  ($s =~ /aa.*/)  { print :  A\n;}
if  ( $s =~ /.*bb/) { print :B\n;  }
if  ($s =~ /aa.*/   $s =~ /.*bb/) { print :  AB\n;  }





Re: How are types related to classes and roles?

2005-03-04 Thread Thomas Sandlaß
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
/ \ / \
   /   \   /   \
  / AB \   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 AB 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
   {
 ...
   }
   

Re: How are types related to classes and roles?

2005-03-04 Thread chromatic
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 AB 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



Re: How are types related to classes and roles?

2005-03-04 Thread Thomas Sandlaß
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ß)



Re: How are types related to classes and roles?

2005-03-04 Thread Thomas Sandlaß
I wrote:
A|B lub (lowest upper bound)
   /   \
  / \
 A   0   B
/ \ / \
   /   \   /   \
  / AB \   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 AB 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ß)


Re: How are types related to classes and roles?

2005-02-28 Thread Thomas Sandlaß
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?
Regards,
--
TSa (Thomas Sandla)



Re: How are types related to classes and roles?

2005-02-28 Thread Aaron Sherman
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.


-- 
 781-324-3772
 [EMAIL PROTECTED]
 http://www.ajs.com/~ajs



Re: How are types related to classes and roles?

2005-02-28 Thread Thomas Sandlaß
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)


Re: How are types related to classes and roles?

2005-02-28 Thread Aaron Sherman
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

-- 
 781-324-3772
 [EMAIL PROTECTED]
 http://www.ajs.com/~ajs



Re: How are types related to classes and roles?

2005-02-28 Thread Leopold Toetsch
Thomas Sandlaß [EMAIL PROTECTED] 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


Re: How are types related to classes and roles?

2005-02-28 Thread Leopold Toetsch
Thomas Sandlaß [EMAIL PROTECTED] 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


Re: How are types related to classes and roles?

2005-02-27 Thread Thomas Sandlaß
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.
Regards,
--
TSa (Thomas Sandlaß)


Re: How are types related to classes and roles?

2005-02-24 Thread Nicholas Clark
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 BD.

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


Re: How are types related to classes and roles?

2005-02-24 Thread Larry Wall
On Thu, Feb 24, 2005 at 05:17:50PM +, Nicholas Clark 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:
:   : 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 BD.
: 
: 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.

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


Re: How are types related to classes and roles?

2005-02-24 Thread Larry Wall
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 BD.

Depends on where it has to be marked.  Anyone can choose their BD
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


Re: How are types related to classes and roles?

2005-02-24 Thread Stéphane Payrard
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


How are types related to classes and roles?

2005-02-23 Thread Thomas Sandlaß
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ß)



Re: How are types related to classes and roles?

2005-02-23 Thread Larry Wall
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