Re: Junctions of classes, roles, etc.

2005-05-04 Thread Thomas Sandlaß
Abhijit Mahabal wrote:
When you dispatch, what happens would depend upon WALKMETH (according to 
the pseudocode for CALLONE in A12). Usually the first inherited method 
would get called.
Ohh, yes, that thing. I forget about it. And actually I hope that
there's a version among the standard pragmas that gives an error.
Or actually this option should go to the typechecker and then the
WALKMETH would nicely find a single, most specific method to call :)
But the important thing for me in this thread is that there are no
junctive bark methods in the alien beast classes! Well, unless the
WALKMETH of choice implements them =:)
--
TSa (Thomas Sandlaß)



Re: Junctions of classes, roles, etc.

2005-05-02 Thread Thomas Sandlaß
David Storrs wrote:
Let's move this away from simple types like Str and Int for a moment.
If you consider them simple...

Tell me what this does:
class Tree { 
  method bark() { die Cannot instantiate a Tree--it is abstract! }
}
class Birch { 
  method bark() { return White, papery }
}
class Oak { 
  method bark() { return Dark, heavy }
}
class Dog {
  method bark() { print Woof, woof!; return bow wow }
}
Four 'pure' classes so far.

class AlienBeastie isa Tree isa Dog {}
Here you get an error/warning of a composition time conflict between
Tree::bark and Dog::bark. BTW, it's 'is' not 'isa'. My preferred
syntax for multiple inheritance is the junctive notation 'is Tree  Dog'
for subclassing because it nicely allows for superclassing with
'is Tree | Dog'.
class WhiteAlienBeastie isa Birch isa Dog {}
Same for Birch::bark and Dog::bark.
class HeavyAlienBeastie isa Oak isa Dog {}
Same.

sub Foo(Tree|Dog $x) { $x.bark() }
This might dispatch correctly for 'pure' Trees, Dogs etc.
but not for your mixed classes above.
Regards,
--
TSa (Thomas Sandlaß)



Re: Junctions of classes, roles, etc.

2005-05-02 Thread Abhijit Mahabal
On Mon, 2 May 2005, [ISO-8859-1] Thomas Sandlaß wrote:
David Storrs wrote:
 Tell me what this does:
 class Tree {  method bark() { die Cannot instantiate a Tree--it is 
 abstract! }
 }
 class Birch {  method bark() { return White, papery }
 }
 class Oak {  method bark() { return Dark, heavy }
 }
 class Dog {
  method bark() { print Woof, woof!; return bow wow }
 }
Four 'pure' classes so far.

 class AlienBeastie isa Tree isa Dog {}
Here you get an error/warning of a composition time conflict between
Tree::bark and Dog::bark.
I don't think so; I had come to the same conclusion before realising that 
we are talking inheritance here, not roles. So no trouble at class 
composition time. Superclasses do not enter the picture while composing.

You'd be right if s/isa/is/ and then s/is/does/, of course.
When you dispatch, what happens would depend upon WALKMETH (according to 
the pseudocode for CALLONE in A12). Usually the first inherited method 
would get called.

TSa (Thomas Sandlaß)
regards,
abhijit

Re: Junctions of classes, roles, etc.

2005-05-02 Thread David Storrs
On Mon, May 02, 2005 at 06:49:10PM +0200, Thomas Sandlaß wrote:
 David Storrs wrote:
 Let's move this away from simple types like Str and Int for a moment.
 
 If you consider them simple...

When compared to

arbitrary-class-that-was-defined-by-
arbitrary-programmer-of-
arbitrary-and-unknown-skill-level

then yes, I consider them to be extremely simple.


 Tell me what this does:
 
 class Tree { 
   method bark() { die Cannot instantiate a Tree--it is abstract! }
 }
 class Birch { 
   method bark() { return White, papery }
 }
 class Oak { 
   method bark() { return Dark, heavy }
 }
 class Dog {
   method bark() { print Woof, woof!; return bow wow }
 }
 
 Four 'pure' classes so far.

Dog is not pure according to the definition of pure class that I
know (no side effects in any method, constructor, or subclass).  Maybe
'pure class' means something else to you?


 class AlienBeastie isa Tree isa Dog {}
 
 Here you get an error/warning of a composition time conflict between
 Tree::bark and Dog::bark. 

So that I'm clear, is this your opinion/preference or is it based on
material from the SEAs?  If the latter, could you point me to the
relevant passage?

 My preferred
 syntax for multiple inheritance is the junctive notation 'is Tree  Dog'
 for subclassing because it nicely allows for superclassing with
 'is Tree | Dog'.

Again, so that I'm clear--this is your preference, and is not derived
from any authoritative source, correct?


 This might dispatch correctly for 'pure' Trees, Dogs etc.
 but not for your mixed classes above.

As I noted above, Dog is not 'pure' by the definition I know so I'm
not sure what to make of this statement.

--Dks


Re: Junctions of classes, roles, etc.

2005-05-02 Thread Luke Palmer
David Storrs writes:
 On Mon, May 02, 2005 at 06:49:10PM +0200, Thomas Sandla wrote:
  David Storrs wrote:
  class Tree { 
method bark() { die Cannot instantiate a Tree--it is abstract! }
  }
  class Birch { 
method bark() { return White, papery }
  }
  class Oak { 
method bark() { return Dark, heavy }
  }
  class Dog {
method bark() { print Woof, woof!; return bow wow }
  }
  class AlienBeastie isa Tree isa Dog {}
  
  Here you get an error/warning of a composition time conflict between
  Tree::bark and Dog::bark. 
 
 So that I'm clear, is this your opinion/preference or is it based on
 material from the SEAs?  If the latter, could you point me to the
 relevant passage?

As has been pointed out, there's no composition going on.  But we are
getting rid of search order problems, so you'll get an ambiguous method
call error at some point.  Whether this is at the time you create the
class or the time you try to call the method, I do not know.

 
  My preferred
  syntax for multiple inheritance is the junctive notation 'is Tree  Dog'
  for subclassing because it nicely allows for superclassing with
  'is Tree | Dog'.
 
 Again, so that I'm clear--this is your preference, and is not derived
 from any authoritative source, correct?

Not authoritative.  I, for one, really want the ability to superclass a
posteriori, but I'm not sure this is how you do it.

Luke


Re: Junctions of classes, roles, etc.

2005-05-01 Thread Aaron Sherman
On Sat, 2005-04-30 at 16:55 -0700, Brent 'Dax' Royal-Gordon wrote:
 Aaron Sherman [EMAIL PROTECTED] wrote:
  On Sat, 2005-04-30 at 22:24 +0800, Autrijus Tang wrote:

   That would be absolutely horrible.

  Str|Int is simply the type of Yes|1, isn't it? That would certainly
  make signature matching on different kinds of junctive types trivial.
 
 Nope.

You all seem to have some very strong opinions, and I'm unable to have a
discussion around absolutes like absolutely horrible and nope, so
all hypotheticals aside, I'll just concede that this is an uninteresting
way to spend our time.




Re: Junctions of classes, roles, etc.

2005-05-01 Thread Autrijus Tang
On Sun, May 01, 2005 at 10:59:59AM -0400, Aaron Sherman wrote:
 On Sat, 2005-04-30 at 16:55 -0700, Brent 'Dax' Royal-Gordon wrote:
  Aaron Sherman [EMAIL PROTECTED] wrote:
   On Sat, 2005-04-30 at 22:24 +0800, Autrijus Tang wrote:
 
That would be absolutely horrible.
 
 You all seem to have some very strong opinions, and I'm unable to have a
 discussion around absolutes like absolutely horrible and nope, so
 all hypotheticals aside, I'll just concede that this is an uninteresting
 way to spend our time.

Sorry.  I'll watch my language better in the future, and provide better
rationales to support my opinion. :-/

In this case, the reason I called this absolutely horrible:

my Str|Int $x;
$x.method(); # calls .method twice

Is because to me, it is conceptually no difference to:

sub foo (Str|Int $x) { $x.method() }; 

In both cases, the junctive type is used to construct a new type that is a
supertype of both Str and Int, for type checking purposes.  If it
silently promotes the variable itself to a Junction for autothreading,
that will render such type construction unusable, as it will be doing
two highly orthogonal things with a single syntax.

Again, my apologies for using strong words without adequate justification.

Thanks,
/Autrijus/


pgpvkCR2varmo.pgp
Description: PGP signature


Re: Junctions of classes, roles, etc.

2005-05-01 Thread David Storrs
On Sat, Apr 30, 2005 at 09:13:26AM -0500, Abhijit Mahabal wrote:
 On Fri, 29 Apr 2005, Brent 'Dax' Royal-Gordon wrote:
 
 David Storrs [EMAIL PROTECTED] wrote:
 Could we see some code that shows why this is a good idea?  My initial
 reaction is horror; I can very easily see huge numbers of subtle,
 hard-to-reproduce bugs coming out of this.  
 I'm quite willing to believe that there are [good results], but I'm not
 coming up with them.


 What do you think this is?
 
sub foo(Str | Int $bar) { ... }
 
 I believe you mean sub foo(Str^Int $bar){...} ( something that is Int or 
 Str but not both). But that, too, just reduces the amount of code and is 
 merely a shortcut for:
   multi sub(Str $bar){...}
   multi sub(Int $bar){...}
 
 I do not see how any auto-threading occurs in that code. It is completely 
 innocuous in that sense, and I don't think that is what horrified
 David. 

Indeed, you're right on the money, Abhijit.  Thanks for stating it so
well.


Let's move this away from simple types like Str and Int for a moment.
Tell me what this does:


class Tree { 
  method bark() { die Cannot instantiate a Tree--it is abstract! }
}
class Birch { 
  method bark() { return White, papery }
}
class Oak { 
  method bark() { return Dark, heavy }
}
class Dog {
  method bark() { print Woof, woof!; return bow wow }
}
class AlienBeastie isa Tree isa Dog {}
class WhiteAlienBeastie isa Birch isa Dog {}
class HeavyAlienBeastie isa Oak isa Dog {}

sub Foo(Tree|Dog $x) { $x.bark() }


Ignore for the moment that this is stupid code--it's semantically and
(AFAIK) syntactically valid.  So, what happens when I do each of these:

Foo( new AlienBeastie() );
Foo( new WhiteAlienBeastie() );
Foo( new HeavyAlienBeastie() );

??

--Dks


Re: Junctions of classes, roles, etc.

2005-04-30 Thread Abhijit Mahabal
On Fri, 29 Apr 2005, Brent 'Dax' Royal-Gordon wrote:
David Storrs [EMAIL PROTECTED] wrote:
On Thu, Apr 28, 2005 at 03:28:41PM +0200, Ingo Blechschmidt wrote:
so we had junctions of Code references some days ago, what's with
junctions of Class and Role objects? :)
Could we see some code that shows why this is a good idea?  My initial
reaction is horror; I can very easily see huge numbers of subtle,
hard-to-reproduce bugs coming out of this.  On the other hand, I do
not immediately see major applications...most of what I can see is
things that reduce the amount of code needed, but don't actually
accomplish anything fundamentally new.  What do junctions of
Class|Role objects give us that can't be achieved in other ways?
I'm quite willing to believe that there are such things, but I'm not
coming up with them.
What do you think this is?
   sub foo(Str | Int $bar) { ... }
I believe you mean sub foo(Str^Int $bar){...} ( something that is Int or 
Str but not both). But that, too, just reduces the amount of code and is 
merely a shortcut for:
	multi sub(Str $bar){...}
	multi sub(Int $bar){...}

I do not see how any auto-threading occurs in that code. It is completely 
innocuous in that sense, and I don't think that is what horrified David. 
What was troublesome was, I think:
	my Str|Int $x;
	$x.foo(); # runs two methods and returns a junction

I would like to be able to read the above code to mean:
type X ::= Scalar where Str|Int;
my X $x;  # $x = non int/non string now a runtime error
$x.foo(); # no different from if you had just said my $x
Feel free to tell me I am barking up the wrong tree if that is what I am 
doing.

--abhijit


Re: Junctions of classes, roles, etc.

2005-04-30 Thread Aaron Sherman
On Sat, 2005-04-30 at 22:24 +0800, Autrijus Tang wrote:
 On Sat, Apr 30, 2005 at 09:13:26AM -0500, Abhijit Mahabal wrote:
  I do not see how any auto-threading occurs in that code. It is completely 
  innocuous in that sense, and I don't think that is what horrified David. 
  What was troublesome was, I think:
  my Str|Int $x;
  $x.foo(); # runs two methods and returns a junction
 
 That would be absolutely horrible.

Then tell me what $!.can(chars) returns, assuming that $! is
implemented as an any junction of Int and Str values? My take would be
that it returns false|true, which is true in a boolean context, but feel
free to talk me out of it.

Str|Int is simply the type of Yes|1, isn't it? That would certainly
make signature matching on different kinds of junctive types trivial.

  I would like to be able to read the above code to mean:
  type X ::= Scalar where Str|Int;
  my X $x;  # $x = non int/non string now a runtime error
  $x.foo(); # no different from if you had just said my $x
 
 This is my current understanding in the implementation.

That's not a junction, and thus should not use junction syntax.

I'm not opposed to having such a construct, but re-using junction syntax
is going to cause massive headaches for anyone trying to learn the
language.

Also, what is:

$x = ::(Int) | ::(Str)
my ::($x) $y;

at which stages of the execution of that code? Are you saying that $x
does not contain a junction, or that a junction used as a type does not
create a junction value?

If the latter, then what is the type of Yes|1?




Re: Junctions of classes, roles, etc.

2005-04-30 Thread Abhijit Mahabal
On Sat, 30 Apr 2005, Aaron Sherman wrote:
On Sat, 2005-04-30 at 22:24 +0800, Autrijus Tang wrote:
On Sat, Apr 30, 2005 at 09:13:26AM -0500, Abhijit Mahabal wrote:
I do not see how any auto-threading occurs in that code. It is completely
innocuous in that sense, and I don't think that is what horrified David.
What was troublesome was, I think:
my Str|Int $x;
$x.foo(); # runs two methods and returns a junction
That would be absolutely horrible.
Then tell me what $!.can(chars) returns, assuming that $! is
implemented as an any junction of Int and Str values?
If $! were explicitely Yes|1, then I agree that it returns false|true.
I believe that in the code you wrote..
$x = ::(Int) | ::(Str)
my ::($x) $y;
$x is a junction, and $y is not a junction. type, to me, is just a 
sticky note attched to an object. I would not like to see autothreading on 
every junctive sticky. In the code above, if there were a method called 
.type(), then $y.type() would indeed return a junction, but not by running 
two methods and orring their output.

Str|Int is simply the type of Yes|1, isn't it?
Hmmm... I am not sure. Maybe the type is just Junc or something.
Str|Int is also the type of 7 and of yes.
Moreover, if the return type of a method is junctive, would you want that 
menthod to autothread too?

--abhijit
Abhijit Mahabal  http://www.cs.indiana.edu/~amahabal/


Re: Junctions of classes, roles, etc.

2005-04-30 Thread Brent 'Dax' Royal-Gordon
Aaron Sherman [EMAIL PROTECTED] wrote:
 On Sat, 2005-04-30 at 22:24 +0800, Autrijus Tang wrote:
  On Sat, Apr 30, 2005 at 09:13:26AM -0500, Abhijit Mahabal wrote:
   I do not see how any auto-threading occurs in that code. It is completely
   innocuous in that sense, and I don't think that is what horrified David.
   What was troublesome was, I think:
   my Str|Int $x;
   $x.foo(); # runs two methods and returns a junction
 
  That would be absolutely horrible.
 
 Then tell me what $!.can(chars) returns, assuming that $! is
 implemented as an any junction of Int and Str values? My take would be
 that it returns false|true, which is true in a boolean context, but feel
 free to talk me out of it.

`$!` is an `Exception` (or somesuch) object, not a `Str|Int`, but in
general, that depends on the contents of the variable.  If a Str|Int
was assigned a `Str`, `can` would be true; if it were assigned an
`Int`, `can` would be false.  If it were assigned a disjunction of a
`Str` and an `Int`, it'd return `true|false`, which evaluates to
`true`.

 Str|Int is simply the type of Yes|1, isn't it? That would certainly
 make signature matching on different kinds of junctive types trivial.

Nope.  The type `Str|Int` doesn't mean this variable contains a
disjunction of `Str`s and `Int`s; it means This variable can contain
either a `Str` or an `Int`.  (Actually, it means this variable can
contain anything consistent with a Str or Int, which also includes
subclasses and certain junctions.)  When you see a declaration like:

my Foo $bar;

Think of it as being like:

my $bar where { $_ ~~ Foo };

 If the latter, then what is the type of Yes|1?

I suspect it's `Disjunction of Str | Int`.

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Re: Junctions of classes, roles, etc.

2005-04-29 Thread David Storrs
On Thu, Apr 28, 2005 at 03:28:41PM +0200, Ingo Blechschmidt wrote:

 so we had junctions of Code references some days ago, what's with
 junctions of Class and Role objects? :)


Could we see some code that shows why this is a good idea?  My initial
reaction is horror; I can very easily see huge numbers of subtle,
hard-to-reproduce bugs coming out of this.  On the other hand, I do
not immediately see major applications...most of what I can see is
things that reduce the amount of code needed, but don't actually
accomplish anything fundamentally new.  What do junctions of
Class|Role objects give us that can't be achieved in other ways?

I'm quite willing to believe that there are such things, but I'm not
coming up with them.

--Dks


Re: Junctions of classes, roles, etc.

2005-04-29 Thread Brent 'Dax' Royal-Gordon
David Storrs [EMAIL PROTECTED] wrote:
 On Thu, Apr 28, 2005 at 03:28:41PM +0200, Ingo Blechschmidt wrote:
  so we had junctions of Code references some days ago, what's with
  junctions of Class and Role objects? :)
 
 Could we see some code that shows why this is a good idea?  My initial
 reaction is horror; I can very easily see huge numbers of subtle,
 hard-to-reproduce bugs coming out of this.  On the other hand, I do
 not immediately see major applications...most of what I can see is
 things that reduce the amount of code needed, but don't actually
 accomplish anything fundamentally new.  What do junctions of
 Class|Role objects give us that can't be achieved in other ways?
 
 I'm quite willing to believe that there are such things, but I'm not
 coming up with them.

What do you think this is?

sub foo(Str | Int $bar) { ... }

Or this one, which is even more important?

sub foo(Any | Junction $bar) { ... }

-- 
Brent 'Dax' Royal-Gordon [EMAIL PROTECTED]
Perl and Parrot hacker

I used to have a life, but I liked mail-reading so much better.


Re: Junctions of classes, roles, etc.

2005-04-28 Thread Thomas Sandlaß
Ingo Blechschmidt wrote:
Hi,
so we had junctions of Code references some days ago, what's with
junctions of Class and Role objects? :)
I like them! In the type lattice A|B is the lub (lowest upper bound)
of A and B. And AB is the glb (greatest lower bound) of A and B.
Both are cases of multiple inheritance with possible conflicts. But
A|B is more general than each of A and B, while AB is more specific
than both.

  role A { method foo() { 42 } }
  role B { method foo() { 23 } }
  class Test does A|B {}
Here you have to implement Test::foo.
Not doing so is a compile time error---or more
precisly a class composition time error.

  my Test $test .= new;
  my $ret = $test.foo; # 42|23?
Whatever Test::foo returns.

  role A {}
  role B { method foo() { 42 } }
  class Test does A|B {}
Here is no conflict, but it might be necessary to
implement the more general behaviour.

  my Test $test .= new;
  my $ret = $test.foo; # unthrown-exception undef|42?
No, $ret == 42 unless Test::foo() is implemented and returns
something else.
Regards,
--
TSa (Thomas Sandlaß)



Re: Junctions of classes, roles, etc.

2005-04-28 Thread Aaron Sherman
On Thu, 2005-04-28 at 09:51, Thomas Sandlaß wrote:
 Ingo Blechschmidt wrote:
  Hi,
  
  so we had junctions of Code references some days ago, what's with
  junctions of Class and Role objects? :)
 
 I like them! In the type lattice A|B is the lub (lowest upper bound)
 of A and B. And AB is the glb (greatest lower bound) of A and B.

That's not at all intuitively obvious because what you're describing is
not a junction. At least it doesn't seem like one to me (you're
describing a situation where the new class has a specific kind of
inheritance, not the situation where it's first ancestor is either all
or one of a set). The difference being that in the case of:

class x is yz {}
my x $a;
$a.foo();

The method foo will be invoked from both y and z simultaneously,
without conflict, and return a junction of the two results.

role A { method foo() { 42 } }
role B { method foo() { 23 } }
class Test does A|B {}
 
 Here you have to implement Test::foo.
 Not doing so is a compile time error---or more
 precisly a class composition time error.

Let's be clear about why you think that. Roles are not ordered, and thus
you must disambiguate the use of more than one. S12 says:

There are several ways to solve method conflicts. The first is
simply to write a class method that overrides the conflicting
role methods, perhaps figuring out which role method to call.

Alternately, if the role's methods are declared multi, they can
be disambiguated based on their long name. If the roles forget
to declare them as multi, you can force a multi on the roles'
methods by installing a multi stub in the class being
constructed:

multi method shake {...}

However, this is a junction, so:

class Test does A|B

is really saying that you compose two different classes called Test,
which you refer to singly through the magic of junctions. One Test is
composed of the base Test class plus A, and another is composed of the
base Test class plus B (well A plus Test and B plus Test if you think of
it in terms of which overrides which).

Now, I'm not saying that that's the way it MUST be, just that that seems
to be the way that junctions would work in that situation. If we decide
that | and  aren't really junction constructors in class/role
definitions, then we can make them whatever we want.


-- 
Aaron Sherman [EMAIL PROTECTED]
Senior Systems Engineer and Toolsmith
It's the sound of a satellite saying, 'get me down!' -Shriekback




Re: Junctions of classes, roles, etc.

2005-04-28 Thread Thomas Sandlaß
Aaron Sherman wrote:
Now, I'm not saying that that's the way it MUST be, just that that seems
to be the way that junctions would work in that situation.
I know, and I'm very confused about all these pseudo procedural uses
of junctions. And others seem to share my state of affairs.

If we decide
that | and  aren't really junction constructors in class/role
definitions, then we can make them whatever we want.
Ohh, yes please!  Actually I see the biggest potential of
junctions in the type system. E.g. the comparison operator =
could get return type -1^0^1. This is first of all good documentation
and secondly preserves valuable information for the optimizer.
The none() junction is most usefull for excluding types---e.g junctions.
So, in the extreme Perl6 might have a junctive type calculation
overlaying the value calculation. Thus when a junctive class is
needed the class composer can be triggered to make an instance thereof.
As you pointed out that might be possible and then continue to MMD
with that newly created class. Sounds very dynamic too me. And I've
not heard about a language that throws exceptions that say Can't create
class Foo does A|B because of conflicting methods bar().
Regards,
--
TSa (Thomas Sandlaß)