Re: enums and bitenums

2003-12-12 Thread Andy Wardley
Larry Wall wrote:
 Anyway, this all implies that use of a role as a method name defaults to
 returning whether the type in question matches the subtype.  That is,
 when you say:
 
 $foo.true
 $bar.red
[...]
 $bar.red
[...]
 $baz.Byte
 
 it's asking whether the Int property fulfills the Byte constraint, but
 that's getting kind of strange.

If the roles are first class objects then their traits are defined
as methods, right?

Boolean.true($foo)
Color.red($bar)
Int.byte($baz)

Then assuming that certain objects inherit certain roles, you could
use something like the Perl 5 $self-SUPER::new() syntax.  Only it would
look more like this:

$foo-Boolean.true
$bar-Color.red
$baz-Int.byte

 Another implication is that, if properties are subtypes, we can't use
 the same name as a cast method.  Since
 
 $baz.Byte
 
 only returns true or false, we'd need something like (yuck)
 
 $baz.asByte
[...or...]
 $baz.as(Byte)

Or:
  $baz-Byte

That would make something like this:

  $foo-Color.red

the same kind of thing as:

  $foo.as(Color).red

A



Vocabulary

2003-12-12 Thread Luke Palmer
So I'm seeing a lot of inconsistent OO-vocabulary around here, and it
makes things pretty hard to understand.

So here's how Perl 6 is using said inconsistent terms, AFAIK:

- attribute
  A concrete data member of a class.  Used with Chas.

- property
  An out-of-band sticky note to be placed on a single object.
Used with Cbut.

- trait
  A compile time sticky note to be placed on a wide variety of things. 
Used with Cis.

- role
  A collection of methods to be incorporated into a class sans
inheritance (and maybe some other stuff, too).  Used with Cdoes.

So for example:

class Dog
does Boolean# role
is extended # trait
is Mammal   # [1]
{
has $.tail; # attribute
has @.legs; # attribute
}

my $fido = Dog.new
but false;  # property

Hope that clears things up.

Luke

[1] This is a base class, which is an overloaded use of Cis.  Though,
upon A12 release, we'll probably find out that it's not overloaded but
instead, elegantly unified, somehow. 


Re: enums and bitenums

2003-12-12 Thread Eirik Berg Hanssen
Larry Wall [EMAIL PROTECTED] writes:

 On Thu, Dec 11, 2003 at 04:18:19PM -0700, Luke Palmer wrote:
 : Larry Wall writes:
 :  Anyway, this all implies that use of a role as a method name defaults to
 :  returning whether the type in question matches the subtype.

  Why?  Why should it be a method?  I would have though the smart
match operator would do the job better -- as well as be less painful
than the .does() method.  Hey, given that it removes the ambiguities,
I would call it less painful than use of a role as a method name.


 : If that's the case, how do we attach out-of-band properties on objects
 : that don't expect them, but only some of them (as was the original
 : intent for properties, IIRC):
 : 
 : my role onlyonced;
 : sub onlyonce($arg is rw) {
 : die onlyonce called twice on the same value if $arg.onlyonced;
 : $arg but= onlyonced;
 : }
 : 
 : Either that doesn't work at all, because you get an onlyonced not
 : found error, or it works because onlyonced is a declared role.  But
 : in the latter case I worry about namespace pollution.
 
 Okay, maybe I understand your worry now.  Are you worried that
 every object implicitly has boolean methods corresponding to every
 class/role/property name in scope?  I can see where that might
 cause some heartburn.

  ... and ditching those boolean methods might spare us those
heartburns.  What do we need them for, anyway, if the smart match
operator tests for out-of-band properties?

my role onlyonced;
sub onlyonce($arg is rw) {
die onlyonce called twice on the same value if $arg~~onlyonced;
$arg but= onlyonced;
}

  I for one would appreciate the visual clue that we access properties
and subclasses as roles ($foo~~bareword), while we access attributes
(with accessors) as methods ($foo.bareword).  Different things should
look different, right?


Eirik
-- 
[EMAIL PROTECTED]
  Just this .sig then
  nothing more


Re: Vocabulary

2003-12-12 Thread Jonathan Scott Duff
On Fri, Dec 12, 2003 at 04:23:02AM -0700, Luke Palmer wrote:
 So I'm seeing a lot of inconsistent OO-vocabulary around here, and it
 makes things pretty hard to understand.
 
 So here's how Perl 6 is using said inconsistent terms, AFAIK:
 
 - attribute
   A concrete data member of a class.  Used with Chas.
 
 - property
   An out-of-band sticky note to be placed on a single object.
 Used with Cbut.

I think an important aspect of properties that you left out here is
that they are run-time.

 - trait
   A compile time sticky note to be placed on a wide variety of things. 
 Used with Cis.
 
 - role
   A collection of methods to be incorporated into a class sans
 inheritance (and maybe some other stuff, too).  Used with Cdoes.

s/class/object/ 

Roles are like sticky behavior (as I understand them) just as properties
are sticky state. And I assume that roles are run-time so that you can
have your objects obtain new behavior (fullfill new roles) as needed
without having to use eval all the time.

I think I'm getting it but I'm not sure.  Does something like this
work?

my role Teach { ... }
my role Operate { ... }
my role Learn { ... }

my Person $frank;
{ temp $frank_the_teacher = $frank does Teach; ... }
{ temp $frank_the_doctor = $frank does Operate; ... }
{ temp $frank_the_student = $frank does Learn; ... }

I.e., we can use dynamic scoping to control how long an object
fulfills a particular role?  Maybe it could also be written like so:

my Person $frank;
{ my role Teach { ... }; $frank does Teach; ... }
{ my role Operate { ... }; $frank does Operate; ... }
{ my role Learn { ... } $frank does Learn; ... }

so that when the role goes out of scope, the object no longer
possesses the abilities of that role.

I confuse myself everytime I think about this stuff.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


Re: enums and bitenums

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 04:05:25PM +0100, Eirik Berg Hanssen wrote:
: Larry Wall [EMAIL PROTECTED] writes:
: 
:  On Thu, Dec 11, 2003 at 04:18:19PM -0700, Luke Palmer wrote:
:  : Larry Wall writes:
:  :  Anyway, this all implies that use of a role as a method name defaults to
:  :  returning whether the type in question matches the subtype.
: 
:   Why?  Why should it be a method?  I would have though the smart
: match operator would do the job better -- as well as be less painful
: than the .does() method.  Hey, given that it removes the ambiguities,
: I would call it less painful than use of a role as a method name.

Having slept on it overnight, I've come to the same conclusion.

:  : If that's the case, how do we attach out-of-band properties on objects
:  : that don't expect them, but only some of them (as was the original
:  : intent for properties, IIRC):
:  : 
:  : my role onlyonced;
:  : sub onlyonce($arg is rw) {
:  : die onlyonce called twice on the same value if $arg.onlyonced;
:  : $arg but= onlyonced;
:  : }
:  : 
:  : Either that doesn't work at all, because you get an onlyonced not
:  : found error, or it works because onlyonced is a declared role.  But
:  : in the latter case I worry about namespace pollution.
:  
:  Okay, maybe I understand your worry now.  Are you worried that
:  every object implicitly has boolean methods corresponding to every
:  class/role/property name in scope?  I can see where that might
:  cause some heartburn.
: 
:   ... and ditching those boolean methods might spare us those
: heartburns.  What do we need them for, anyway, if the smart match
: operator tests for out-of-band properties?

And also, smart match is the right place to put dwimmery, not method lookup.

: my role onlyonced;
: sub onlyonce($arg is rw) {
: die onlyonce called twice on the same value if $arg~~onlyonced;
: $arg but= onlyonced;
: }
: 
:   I for one would appreciate the visual clue that we access properties
: and subclasses as roles ($foo~~bareword), while we access attributes
: (with accessors) as methods ($foo.bareword).  Different things should
: look different, right?

I still think that you can access the role itself as a method, but only
if it's really there.  In that case the different thing is trying to be
the same.  A simple property should behave like an attribute when it can.

Larry


Re: Vocabulary

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 04:23:02AM -0700, Luke Palmer wrote:
: So I'm seeing a lot of inconsistent OO-vocabulary around here, and it
: makes things pretty hard to understand.

Agreed.

: So here's how Perl 6 is using said inconsistent terms, AFAIK:
: 
: - attribute
:   A concrete data member of a class.  Used with Chas.

Declared with Chas is a little more precise.

: - property
:   An out-of-band sticky note to be placed on a single object.
: Used with Cbut.

Maybe applied with?

: - trait
:   A compile time sticky note to be placed on a wide variety of things. 
: Used with Cis.

Fine.  (Though I like to hyphenate compile-time when it's an adjective,
and not when it's a noun.  Same for run-time, just to be consistent.)

: - role
:   A collection of methods to be incorporated into a class sans

A role can also supply one or more attributes.

: inheritance (and maybe some other stuff, too).  Used with Cdoes.

Here it gets a little fuzzier.  A role can be applied to a class
at compile time via does, or to an object at run time via but.
A property is a simple kind of role that supplies a single attribute.
The type of a property is identical to its role name.  Roles can have
subtypes that function as enums when the subtypes are constrained to a
single value.  You can use one of these subtypes without specifically
implying the role name.  So saying

$bar but Red

might give you a value with the property Color.  You can write the corresponding
boolean test using the smart match operator:

$bar ~~ Red

and it (smartly) picks out the Color property to compare with, provided
it's unambiguous.  You can use that syntax to compare against any
subtype or junction of subtypes:

$bar ~~ RedishWhiteish # pinkish

: So for example:
: 
: class Dog
: does Boolean# role
: is extended # trait
: is Mammal   # [1]
: {
: has $.tail; # attribute
: has @.legs; # attribute
: }
: 
: my $fido = Dog.new
: but false;  # property
: 
: Hope that clears things up.

Yes, it does.

: Luke
: 
: [1] This is a base class, which is an overloaded use of Cis.  Though,
: upon A12 release, we'll probably find out that it's not overloaded but
: instead, elegantly unified, somehow. 

If not, it'll be easy to turn it into an isa.

Larry


Re: enums and bitenums

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 09:36:45AM +, Andy Wardley wrote:
: Larry Wall wrote:
:  Anyway, this all implies that use of a role as a method name defaults to
:  returning whether the type in question matches the subtype.  That is,
:  when you say:
:  
:  $foo.true
:  $bar.red
: [...]
:  $bar.red
: [...]
:  $baz.Byte
:  
:  it's asking whether the Int property fulfills the Byte constraint, but
:  that's getting kind of strange.
: 
: If the roles are first class objects then their traits are defined
: as methods, right?
: 
: Boolean.true($foo)
: Color.red($bar)
: Int.byte($baz)

Potentially, though roles are more properly thought of as types than classes.
That is, they're abstract sets of values.  You can instantiate one sufficiently
well to take a reference to it, so that you can do

$someobject but= $somerole;

But it's not really an object in its own right, and it's not clear that
you can call any of the methods it defines unless it's part of an object.

: Then assuming that certain objects inherit certain roles, you could
: use something like the Perl 5 $self-SUPER::new() syntax.  Only it would
: look more like this:
: 
: $foo-Boolean.true
: $bar-Color.red
: $baz-Int.byte

Well, we can't use - because we're using that for something else.
But it's certainly true that we'll have to have some mechanism for
disambiguating Color.green from Blackberry.green.  After all,

Blackberry.green == Color.red

Or maybe it's

Blackberry::green == Color::red

I'm not sure how subtypes are related to types yet, syntactically speaking.
Might even be

Blackberry[green] == Color[red]

:  Another implication is that, if properties are subtypes, we can't use
:  the same name as a cast method.  Since
:  
:  $baz.Byte
:  
:  only returns true or false, we'd need something like (yuck)
:  
:  $baz.asByte
: [...or...]
:  $baz.as(Byte)
: 
: Or:
:   $baz-Byte
: 
: That would make something like this:
: 
:   $foo-Color.red
: 
: the same kind of thing as:
: 
:   $foo.as(Color).red

I'm thinking the ordinary method

$foo.Color

implies

$foo.as(Color)

meaning that we're viewing $foo through the Color filter.  If you want to
match against a value, however, you'd have to say

$foo.Color == green

or

$foo.Color ~~ green

In the latter case, you can just say

$foo ~~ green

as long as green is unambiguous.  I don't know the syntax for
disambiguating on the green end yet.  Maybe one of

$foo ~~ Color::green
$foo ~~ Color.green
$foo ~~ Color[green]

Or maybe something else.

The interesting question to me is what

$ref = \$foo.as(Color);

returns.  It looks like a typed reference to me, but it's still
a reference to the object in $foo, or can behave as one somehow.
I don't think it should generate a reference to the bare role, because
roles aren't intended to be first class objects (though you can force
them to be, I think).  Roles are supposed to encapsulate abstractions
without implying objecthood.  I think roles are a little bit like
quarks--they're fine in theory, but it's scary to have loose ones
floating around.

So it seems to me that $foo.Color has to return some kind of typed ref
to $foo, so that things like

$foo.Color = purple;

can work as expected.  Staring at that, it seems apparent that .Color
is simply an lvalue subroutine just like any other rw attribute.  An
lvalue sub can be thought of as a typed reference, I suppose.  It gets
more interesting if the role has multiple attributes though.  What
would

\$foo.RGB

return, I wonder, such that

$foo.RGB = ($r,$g,$b)

would work?

Larry


RE: enums and bitenums

2003-12-12 Thread Austin Hastings


 -Original Message-
 From: Larry Wall [mailto:[EMAIL PROTECTED]
 Sent: Thursday, December 11, 2003 1:04 PM

 [Warning: speculation ahead.]

Noted.

 I've been thinking that enums might just be subtypes of roles/properties.
 After all, when you say

 0 but true

 it might really mean

 0 but Boolean[1]

 whereas

 1 but false

 means

 1 but Boolean[0]

 That is, type boolean can be thought of as enum(false,true).

 So we might have a role declaration somewhere that says something like:

 role *Boolean[Bit ?$val] does Property {
   bit $.boolean = $val;
 }
 role *false does Boolean[0];
 role *true does Boolean[1];

 That's what the semantics might look like, but of course people would
 probably want an enum or bitenum wrapper macro for real code.  No reason
 it couldn't be a standard macro though.  Or even part of the
 grammar--we've
 never shied away from defining one construct in terms of another for
 teaching purposes.  We define Cuse in terms of CBEGIN and Crequire,
 and Crequire in terms of Cdo.  Perl 6 will do more of that, because
 it makes things easy to learn.


Supertypes, eh? An enum is a limited-range thingy (int, usually), which fits
the description of a role, but also has magic words involved.

  package RGB;

  enum Color does Int[0..0xFF_FF_FF] {
has $Red   = 0xFF_00_00;
has $Green = 0x00_FF_00;
has $Blue  = 0x00_00_FF;
  }

Since the possible values are possibles, I don't like Chas unless we
provide that Chas means possible value in an enum-decl.

Is Cenum a primitive type only?

Or can we enumerate objects? As in,

  class RGB {
has byte $.red;
has byte $.green;
has byte $.blue;
  }

  enum Color does RGB {
has $Red= RGB[red = 0xFF, blue = 0x00, green = 0x00];
has $Green  = RGB[red = 0xFF, blue = 0x00, green = 0x00];  # Squares
mean compile time (const)?
has $Blue   = RGB[red = 0xFF, blue = 0x00, green = 0x00];
  }


 A lot of this is negotiable, but I think it's a feature that you
 can't have an enum without it being associated with a unique type
 name/property.  It's also appealing to me that enum values live
 in the type namespace, since they're really subtypes (that is, types
 that restrict values ranges of real types).  There's nothing says
 a subtype has to have only one value:

 role Bit[Int ?$val] does Int[0|1];

 Of course, I'm handwaving a lot here by using a junction.  For
 integer subtypes you'd typically want a range:

 role Byte[Int ?$val] does Int[0..255];

I don't understand the purpose of your [Int ?$val] parameter. Doesn't the
Cdoes Int[0..255] declare the constraint entirely?

   role PHB does Employee[$.job_title == manager  $.experience  5];



 That implies that the argument to Int[] has to be able to take a range.
 I confess I don't know what the real declaration of Int looks like
 yet.  Certainly the first arg isn't simply an Int.  That only works
 for enums. The arg has to represent some kind of generic constraint.
 Pity the optimizer...

  macro does is parsed(/ class [ given_block ] /) {...}

 Anyway, this all implies that use of a role as a method name defaults to
 returning whether the type in question matches the subtype.  That is,
 when you say

 $foo.true

 it's asking whether the Boolean property fulfills the true constraint.
 When you say

 $bar.red

 it's asking whether the Color property fulfills the red constraint.
 I suppose when you say

 $baz.Byte

 it's asking whether the Int property fulfills the Byte constraint, but
 that's getting kind of strange.

This is bad. Better to treat a role as a matchable constraint, and ask:

  if $foo ~~ true {...}

  given $bar { when red {...}}

  unless $baz ~~ Byte {...}

We've already got a constraint matching syntax. But for cases where you want
to be explicit, or when you risk confusion using ~~, we can recycle Cdoes
somehow:


  if $foo.does(true)
or
  if $foo.can(true)
or
  if $foo.would(true)
or

   role ChuckWood does WoodChuck[does .chuck(Wood)];   # Internal Cdoes
for has-method-p?

   my $how_much is Quantity of Wood = $woodchuck.can_chuck if
$woodchuck.could(ChuckWood)

(Sorry)

 Another implication is that, if properties are subtypes, we can't use
 the same name as a cast method.  Since

 $baz.Byte

 only returns true or false, we'd need something like (yuck)

 $baz.asByte

 Since class names are valid as bare names, perhaps we can improve
 that to

 $baz.as(Byte)

 (That doesn't mean you have to write an as method that contains a
 switch.  More likely as is a multi method within the class of $baz.)

Ugh.

UghUgh.

If a role is just a constraint, then there's no need to have a method at
all -- the type doesn't change.

  role FitsInByte does Int[0..255];

  my Byte $b;
  my Int  $i;

  $b = $i if $i ~~ FitsInByte;

Which leaves the .as() method for conversions:

  role ClassByte does Class[Byte];
  multi method Int::as(Int $i: ClassByte) returns Byte { $i % 256; }

  my Byte $b = 

RE: Vocabulary

2003-12-12 Thread Austin Hastings


 -Original Message-
 From: Jonathan Scott Duff [mailto:[EMAIL PROTECTED]
 Sent: Friday, December 12, 2003 11:13 AM
 To: Luke Palmer
 Cc: Language List
 Subject: Re: Vocabulary


 On Fri, Dec 12, 2003 at 04:23:02AM -0700, Luke Palmer wrote:
  So I'm seeing a lot of inconsistent OO-vocabulary around here, and it
  makes things pretty hard to understand.
 
  So here's how Perl 6 is using said inconsistent terms, AFAIK:
 
  - attribute
A concrete data member of a class.  Used with Chas.
 
  - property
An out-of-band sticky note to be placed on a single object.
  Used with Cbut.

 I think an important aspect of properties that you left out here is
 that they are run-time.

  - trait
A compile time sticky note to be placed on a wide variety
 of things.
  Used with Cis.
 
  - role
A collection of methods to be incorporated into a class sans
  inheritance (and maybe some other stuff, too).  Used
 with Cdoes.

 s/class/object/

 Roles are like sticky behavior (as I understand them) just as properties
 are sticky state. And I assume that roles are run-time so that you can
 have your objects obtain new behavior (fullfill new roles) as needed
 without having to use eval all the time.


This seems needlessly restrictive. If we're defining roles as having mixin
capabilities, we should be able to use them in classes. Laziness.

 role Work {...};
 role Management {...};

 class Employee {...};

 class Worker is Employee does Work;
 class Manager is Employee does Management;

 role PHB does Manager[does no Work];

 I think I'm getting it but I'm not sure.  Does something like this
 work?

   my role Teach { ... }
   my role Operate { ... }
   my role Learn { ... }

   my Person $frank;
   { temp $frank_the_teacher = $frank does Teach; ... }
   { temp $frank_the_doctor = $frank does Operate; ... }
   { temp $frank_the_student = $frank does Learn; ... }

 I.e., we can use dynamic scoping to control how long an object
 fulfills a particular role?  Maybe it could also be written like so:

   my Person $frank;
   { my role Teach { ... }; $frank does Teach; ... }
   { my role Operate { ... }; $frank does Operate; ... }
   { my role Learn { ... } $frank does Learn; ... }

 so that when the role goes out of scope, the object no longer
 possesses the abilities of that role.

 I confuse myself everytime I think about this stuff.

That's brilliant, if twisted. The object persists, but the behaviors expire.
There's a paradigm there, man. Write a book.

(It's double-e Eevil, too, but that's Damian's problem. :-)

=Austin



FW: Vocabulary

2003-12-12 Thread Austin Hastings

 -Original Message-
 From: Luke Palmer [mailto:[EMAIL PROTECTED]
 Sent: Friday, December 12, 2003 6:23 AM
 
 So I'm seeing a lot of inconsistent OO-vocabulary around here, and it
 makes things pretty hard to understand.
 
 So here's how Perl 6 is using said inconsistent terms, AFAIK:
 
 - attribute
   A concrete data member of a class.  Used with Chas.
 
 - property
   An out-of-band sticky note to be placed on a single object.
 Used with Cbut.
 
 - trait
   A compile time sticky note to be placed on a wide variety 
 of things. Used with Cis.

Did I miss something with IS and OF?

That is, I think:

  Cis means storage type, while Cof means trait or class:

  my @a is Herd of Cat;

declares a Herd (presumably a base class of some collection type) with the trait that, 
in this case, members will be of Class Cat.

Did this change when I wasn't looking?

 - role
   A collection of methods to be incorporated into a class sans
 inheritance (and maybe some other stuff, too).  Used with Cdoes.

No comment, since this is still hovering (see Larry's reply).

 
 So for example:
 
 class Dog
 does Boolean# role
 is extended # trait
 is Mammal   # [1]

The only difference I can see here between Cdoes Boolean and Cis extended would be 
the declaration of Boolean or extended (unless Cis can only be used with built-in 
traits, which seems unnecessarily restrictive...)

 {
 has $.tail; # attribute
 has @.legs; # attribute
 }
 
 my $fido = Dog.new
 but false;  # property
 
 Hope that clears things up.
 
 Luke
 
 [1] This is a base class, which is an overloaded use of Cis.  Though,
 upon A12 release, we'll probably find out that it's not overloaded but
 instead, elegantly unified, somehow. 

Thanks for bringing this out.

=Austin



RE: Vocabulary

2003-12-12 Thread Austin Hastings


 -Original Message-
 From: Larry Wall [mailto:[EMAIL PROTECTED]
 Sent: Friday, December 12, 2003 12:17 PM

 : - role
 :   A collection of methods to be incorporated into a class sans

 A role can also supply one or more attributes.

So a role can constrain values and add behavior and attributes. Presumably
it can do both at the same time?

  enum ParityMode values P_ODD P_EVEN P_NONE;

  role Byte
does Int[0..255]   # Value constraint
does { # extending by adding attributes  methods, and by
overriding the STORE method
  has ParityMode $.parity_mode = NONE;
  has bit $.parity;

   # .CONFORM is redundant with Value constraint above,
which autogenerates this.
  method CONFORM(Int $i) { SUPER  0 = $i = 255; }
  method STORE(Int $i: $v) { $i = .CONFORM($v) || fail; set_parity; }
  method set_parity {...}
};

 : inheritance (and maybe some other stuff, too).  Used
 with Cdoes.

 Here it gets a little fuzzier.  A role can be applied to a class
 at compile time via does, or to an object at run time via but.

Good. I like the mixin being available at either time. This makes properties
a lot more useful since I can provided default or normal values:

  role Celebrated
does Date
does {
  method celebrated($d) { return $d.date; }
  }

  class Birthday does Celebrated {
has $.date;
  }

  my Birthday $d = Birthday.new('February', 29, 2004) but
Celebrated('March', 01, 2004);

  print My birthday is celebrated $d.celebrated;

I presume that the linear order (compile time) or chronological order of
applying roles decides the order in which overlaid methods are
Cwraped/overlaid.

Which is it, by the way? Or is there MTOWTDI, such as a method modifier for
specifying polymorph behavior?

  method CONFORM is wrapped { ... call ... }

 A property is a simple kind of role that supplies a single attribute.
 The type of a property is identical to its role name.  Roles can have
 subtypes that function as enums when the subtypes are constrained to a
 single value.

This seems really clunky for enums. It works okay for boolean, but even
doing month-names is going to suck pretty hard:

  role Month;

  role January   does Month[0];
  role February  does Month[1];
  role March does Month[2];
  role April does Month[3];
  role May   does Month[4];
  role June  does Month[5];
  role July  does Month[6];
  role Augustdoes Month[7];
  role September does Month[8];
  role October   does Month[9];
  role November  does Month[10];
  role December  does Month[11];

  role Month does Int[January..December];

 You can use one of these subtypes without specifically implying the role
name.  So saying

 $bar but Red

 might give you a value with the property Color.

This is smart and helpful. I like it. However, there needs to be a way to
specify what to do when multiple roles share the same values. For example,
if I have NeededBy and Estimated roles:

  my $birthday = 02/29/2004 but March;
  my $ship_date = 01/01/01 but NeededBy(February);

 You can write the corresponding boolean test using the smart match
operator:

 $bar ~~ Red

 and it (smartly) picks out the Color property to compare with, provided
 it's unambiguous.  You can use that syntax to compare against any
 subtype or junction of subtypes:

 $bar ~~ RedishWhiteish   # pinkish


Disambiguation?

  $bar ~~ NeededBy(February)

or

  $bar.NeededBy ~~ February

=Austin



RE: enums and bitenums

2003-12-12 Thread Austin Hastings


 -Original Message-
 From: Larry Wall [mailto:[EMAIL PROTECTED]
 Sent: Friday, December 12, 2003 1:44 PM



 Potentially, though roles are more properly thought of as types
 than classes.
 That is, they're abstract sets of values.  You can instantiate
 one sufficiently
 well to take a reference to it, so that you can do

 $someobject but= $somerole;

 But it's not really an object in its own right, and it's not clear that
 you can call any of the methods it defines unless it's part of an object.

Presumably it will share whatever behavior Classes use to provide static
methods?

 : Then assuming that certain objects inherit certain roles, you could
 : use something like the Perl 5 $self-SUPER::new() syntax.  Only it would
 : look more like this:
 :
 : $foo-Boolean.true
 : $bar-Color.red
 : $baz-Int.byte

 Well, we can't use - because we're using that for something else.
 But it's certainly true that we'll have to have some mechanism for
 disambiguating Color.green from Blackberry.green.  After all,

 Blackberry.green == Color.red

 Or maybe it's

 Blackberry::green == Color::red

 I'm not sure how subtypes are related to types yet, syntactically
 speaking.
 Might even be

 Blackberry[green] == Color[red]

This syntax suggests a javascript-like similarity between classes (or
objects) and arrays. Do you want that?
Perhaps pretending hashiness would be truer to both Perl's roots and the
syntax used to construct things:

  my member_function = \Class{memberfunction};

  Blackberry{green} == Color{green}


 :  Another implication is that, if properties are subtypes, we can't use
 :  the same name as a cast method.  Since
 : 
 :  $baz.Byte
 : 
 :  only returns true or false, we'd need something like (yuck)
 : 
 :  $baz.asByte
 : [...or...]
 :  $baz.as(Byte)
 :
 : Or:
 :   $baz-Byte
 :
 : That would make something like this:
 :
 :   $foo-Color.red
 :
 : the same kind of thing as:
 :
 :   $foo.as(Color).red

 I'm thinking the ordinary method

 $foo.Color

 implies

 $foo.as(Color)

 meaning that we're viewing $foo through the Color filter.  If you want to
 match against a value, however, you'd have to say

 $foo.Color == green

 or

 $foo.Color ~~ green

 In the latter case, you can just say

 $foo ~~ green

 as long as green is unambiguous.  I don't know the syntax for
 disambiguating on the green end yet.  Maybe one of

 $foo ~~ Color::green
 $foo ~~ Color.green
 $foo ~~ Color[green]

 Or maybe something else.

 The interesting question to me is what

 $ref = \$foo.as(Color);

 returns.

I'll suggest:

  $ref = \$foo.as(Color);

be the same as:

  $ref = \$foo;
  $ref but= of Color; # Cof affects type assumptions, doesn't merely add
stuff.

So that $ref is typechecked as a Color, not as a Foo.

 It looks like a typed reference to me, but it's still
 a reference to the object in $foo, or can behave as one somehow.
 I don't think it should generate a reference to the bare role, because
 roles aren't intended to be first class objects (though you can force
 them to be, I think).  Roles are supposed to encapsulate abstractions
 without implying objecthood.  I think roles are a little bit like
 quarks--they're fine in theory, but it's scary to have loose ones
 floating around.

 So it seems to me that $foo.Color has to return some kind of typed ref
 to $foo, so that things like

 $foo.Color = purple;

 can work as expected.  Staring at that, it seems apparent that .Color
 is simply an lvalue subroutine just like any other rw attribute.  An
 lvalue sub can be thought of as a typed reference, I suppose.  It gets
 more interesting if the role has multiple attributes though.  What
 would

 \$foo.RGB

 return, I wonder, such that

 $foo.RGB = ($r,$g,$b)

 would work?

 Larry



Re: enums and bitenums

2003-12-12 Thread Paul Hodges
Larry said:
 The interesting question to me is what
 
 $ref = \$foo.as(Color);
 
 returns.  It looks like a typed reference to me, but it's still
 a reference to the object in $foo, or can behave as one somehow.
 I don't think it should generate a reference to the bare role,
 because roles aren't intended to be first class objects (though
 you can force them to be, I think).  Roles are supposed to
 encapsulate abstractions without implying objecthood.  I think
 roles are a little bit like quarks--they're fine in theory, but
 it's scary to have loose ones floating around.

Ok, wait a sec. Does that mean different references to the same critter
can have differing sets of aspects?

my Dog $Spot;
my $doggie = Dog.new();
my $meandog  = \$doggie.as(AttackDog);
my $nicedog  = \$doggie.as(LapDog);
if $me.away {
if $visitor.nephew {
   $Spot = $nicedog; 
} else {
   $Spot = $meandog; 
}
}

Now, if I'm away and someone show up, I presume that if it's my nephew
then $Spot.seeVisitor() will invoke the LapDog role's .wag() method,
but otherwise I expect it to invoke the AttackDog role's .Bark()
method. I realize there are other ways to get here but would this
*work*???

And btw, just a refresher on this assigning a ref thing -- would the
syntax have to change at *all*?


__
Do you Yahoo!?
New Yahoo! Photos - easier uploading and sharing.
http://photos.yahoo.com/


Re: Vocabulary

2003-12-12 Thread Stéphane Payrard
 
 A role can also supply one or more attributes.
 
 : inheritance (and maybe some other stuff, too).  Used with Cdoes.

The smalltalk paper you mentionned which talked about roles (under
the name of traits) said that roles were stateless.

What are the consequences of using stateful roles?

A related question. Will getter and setter methods will have the
same name as the underlying accessed attributes?


--
 stef


Re: Vocabulary

2003-12-12 Thread Dan Sugalski
At 9:16 AM -0800 12/12/03, Larry Wall wrote:
On Fri, Dec 12, 2003 at 04:23:02AM -0700, Luke Palmer wrote:
: - property
:   An out-of-band sticky note to be placed on a single object.
: Used with Cbut.
Maybe applied with?

: - trait
:   A compile time sticky note to be placed on a wide variety of things.
: Used with Cis.
Fine.  (Though I like to hyphenate compile-time when it's an adjective,
and not when it's a noun.  Same for run-time, just to be consistent.)
I would really, *really* like to kill the whole It's a sticky note! 
metaphor dead. If I understand the changes proposed in properties as 
part of the whole shift to roles thing they aren't anything like 
sticky notes at all, as they dynamically subclass the object.
--
Dan

--it's like this---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
  teddy bears get drunk


Re: enums and bitenums

2003-12-12 Thread Smylers
Larry Wall writes:

 I think roles are a little bit like quarks--they're fine in theory,
 but it's scary to have loose ones floating around.

Wow.

(And please can whoever looks after the quote of the day on Perl.com add
that one to the hopper ...)

Smylers



Re: enums and bitenums

2003-12-12 Thread Eirik Berg Hanssen
Larry Wall [EMAIL PROTECTED] writes:

 On Fri, Dec 12, 2003 at 04:05:25PM +0100, Eirik Berg Hanssen wrote:

 :   I for one would appreciate the visual clue that we access properties
 : and subclasses as roles ($foo~~bareword), while we access attributes
 : (with accessors) as methods ($foo.bareword).  Different things should
 : look different, right?
 
 I still think that you can access the role itself as a method, but only
 if it's really there.  In that case the different thing is trying to be
 the same.  A simple property should behave like an attribute when it can.

  When I wrote that, I still had in mind the boolean methods
corresponding to every class/role/property name in scope -- but I
think you mean something else when you speak of accessing the role.
Specifically, I think you mean what I would call accessing the role's
(main) attribute.  If so, we are still in agreement.  If not, I am
very much confused. :-)

  Red and Reddish (per your example) are not properties, given your
definition in the other thread.  So you are not arguing for Red and
Reddish to be accessible as methods, I gather.

  I can see this, I suppose:

$bar but= $foo.Color if $foo ~~ Color;
if $bar ~~ Reddish {
print $bar.hex_code; # hex_code is a method of the role,
 # and so can be accessed directly.

$bar.Color.red = 0;  # red is not a method of the role,
 # and must be accessed through the
 # role's main attribute (for which
 # red is an lvalue method, it seems).
}

  But this would all come about because the role defines an attribute
by the same name, not because method lookup scans the role namespace.
Or so I would hope.

  And then it is no different from being able to access as a method
any public attribute (or other method) that the role defines -- if the
role is really there.

  Or am I very much confused?


Eirik
-- 
Rudolph is at _least_ as real as a Cantor set or an untried recipe.
-- Joshua W. Burton [EMAIL PROTECTED]
([EMAIL PROTECTED])


Re: Vocabulary

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 07:12:40PM +0100, Stéphane Payrard wrote:
:  
:  A role can also supply one or more attributes.
:  
:  : inheritance (and maybe some other stuff, too).  Used with Cdoes.
: 
: The smalltalk paper you mentionned which talked about roles (under
: the name of traits) said that roles were stateless.

Though they did point out that state was one of the thing they
wanted to look into.

: What are the consequences of using stateful roles?

That's what we're trying to figure out.  :-)

It seems to me that as long as the attributes declared in the role are
elaborated into the real object at class composition time, there's
really very little problem with doing that part of it.  You have to
watch for collisions just as you do with method names, of course.
The tricky part comes later when you start to use it.  The trickiest
thing will be to know if some change in the rest of the object has
invalidated your role's state such that you have to recompute it.

: A related question. Will getter and setter methods will have the
: same name as the underlying accessed attributes?

Yes, the getter/setter method is the same name as the attribute.
(There's only one method, but it can be an lvalue method for rw
attributes).

Larry


Re: enums and bitenums

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 10:30:06PM +0100, Eirik Berg Hanssen wrote:
: Larry Wall [EMAIL PROTECTED] writes:
: 
:  On Fri, Dec 12, 2003 at 04:05:25PM +0100, Eirik Berg Hanssen wrote:
: 
:  :   I for one would appreciate the visual clue that we access properties
:  : and subclasses as roles ($foo~~bareword), while we access attributes
:  : (with accessors) as methods ($foo.bareword).  Different things should
:  : look different, right?
:  
:  I still think that you can access the role itself as a method, but only
:  if it's really there.  In that case the different thing is trying to be
:  the same.  A simple property should behave like an attribute when it can.
: 
:   When I wrote that, I still had in mind the boolean methods
: corresponding to every class/role/property name in scope -- but I
: think you mean something else when you speak of accessing the role.
: Specifically, I think you mean what I would call accessing the role's
: (main) attribute.  If so, we are still in agreement.  If not, I am
: very much confused. :-)
: 
:   Red and Reddish (per your example) are not properties, given your
: definition in the other thread.  So you are not arguing for Red and
: Reddish to be accessible as methods, I gather.

Not any more.

:   I can see this, I suppose:
: 
: $bar but= $foo.Color if $foo ~~ Color;
: if $bar ~~ Reddish {
: print $bar.hex_code; # hex_code is a method of the role,
:  # and so can be accessed directly.
: 
: $bar.Color.red = 0;  # red is not a method of the role,
:  # and must be accessed through the
:  # role's main attribute (for which
:  # red is an lvalue method, it seems).
: }
: 
:   But this would all come about because the role defines an attribute
: by the same name, not because method lookup scans the role namespace.
: Or so I would hope.

Yes.

:   And then it is no different from being able to access as a method
: any public attribute (or other method) that the role defines -- if the
: role is really there.
: 
:   Or am I very much confused?

No, I don't think you're confused.  Of course, I could be confused
about that...

Larry


Re: enums and bitenums

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 03:10:30PM -0800, Paul Hodges wrote:
: Ok, wait a sec. Does that mean different references to the same critter
: can have differing sets of aspects?
: 
: my Dog $Spot;
: my $doggie = Dog.new();
: my $meandog  = \$doggie.as(AttackDog);
: my $nicedog  = \$doggie.as(LapDog);
: if $me.away {
: if $visitor.nephew {
:$Spot = $nicedog; 
: } else {
:$Spot = $meandog; 
: }
: }
: 
: Now, if I'm away and someone show up, I presume that if it's my nephew
: then $Spot.seeVisitor() will invoke the LapDog role's .wag() method,
: but otherwise I expect it to invoke the AttackDog role's .Bark()
: method. I realize there are other ways to get here but would this
: *work*???

We might be able to make it work, though as you say, there are other
ways to get there, and the chances are that at least one of them will
be a better way.  Certainly when the Dog object's class is composed, it
will have to do something about the conflicting .seeVisitor methods
in the two roles.  It might well be better to encode that choice as
part of the dog's state rather than in the references to it.  On the
other hand, it might just fall out of our implementation that it does
the right thing with typed references, if the method dispatch to
the conflicting methods in the Dog class can have access to the reference
types to break ties.

: And btw, just a refresher on this assigning a ref thing -- would the
: syntax have to change at *all*?

Dunno.  I don't see anything obviously wrong with it, but then I never
could see very well...

Larry


Re: FW: Vocabulary

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 04:31:32PM -0500, Austin Hastings wrote:
:  - trait
:A compile time sticky note to be placed on a wide variety 
:  of things. Used with Cis.
: 
: Did I miss something with IS and OF?
: 
: That is, I think:
: 
:   Cis means storage type, while Cof means trait or class:
: 
:   my @a is Herd of Cat;
: 
: declares a Herd (presumably a base class of some collection type) with the trait 
that, in this case, members will be of Class Cat.
: 
: Did this change when I wasn't looking?

No, it hasn't changed.  Generally Cis specifies the storage class when
you're applying it to a variable.  We've just been using it a little
weirdly on things that aren't variables, such as class declarations.

:  - role
:A collection of methods to be incorporated into a class sans
:  inheritance (and maybe some other stuff, too).  Used with Cdoes.
: 
: No comment, since this is still hovering (see Larry's reply).

Flutter, flutter.

:  So for example:
:  
:  class Dog
:  does Boolean# role
:  is extended # trait
:  is Mammal   # [1]
: 
: The only difference I can see here between Cdoes Boolean and Cis extended would 
be the declaration of Boolean or extended (unless Cis can only be used with built-in 
traits, which seems unnecessarily restrictive...)

Traits are seeming a lot more like roles than like superclasses
these days.  But they may still be different beasties.  A role will
have some rules about how it's composed into a class, while a trait
can presumably do anything it jolly well pleases.  They may unify at
some point, but maybe only at a temperature of billions of degrees.

Larry


Re: Vocabulary

2003-12-12 Thread Casey West
It was Friday, December 12, 2003 when Luke Palmer took the soap box, saying:
: So I'm seeing a lot of inconsistent OO-vocabulary around here, and it
: makes things pretty hard to understand.

Awesome.  I've taken your original, plus comments so far and created
perlvocab.pod.  Lets give it a couple go-rounds and it can be stored
in CVS for safe keeping (and maintaining).  Send me diffs if you like.

Document below sig.

  Casey West

-- 
Usenet is like Tetris for people who still remember how to read. 
  -- Button from the Computer Museum, Boston, MA

=pod

=head1 NAME

perlvocab - Perl Vocabulary and Glossary

=head1 SYNOPSIS

This document authoritatively defines many potentially ambiguous terms in Perl.

=head1 DESCRIPTION

=head2 Object Oriented Terminology

=over 4

=item attribute

A concrete data member of a class.  Declared with Chas.

=item property

A run-time, out-of-band sticky note to be placed on a single object,
applied with with Cbut.

A property is a simple kind of role that supplies a single attribute.
The type of a property is identical to its role name.  Roles can have
subtypes that function as enums when the subtypes are constrained to a
single value.  You can use one of these subtypes without specifically
implying the role name.  So saying

$bar but Red

might give you a value with the property Color.  You can write the corresponding
boolean test using the smart match operator:

$bar ~~ Red

and it (smartly) picks out the Color property to compare with, provided
it's unambiguous.  You can use that syntax to compare against any
subtype or junction of subtypes:

$bar ~~ RedishWhiteish # pinkish

=item trait

A compile-time sticky note to be placed on a wide variety of things. 
Used with Cis.

=item role

A collection of methods and/or attributes to be incorporated into a class sans
inheritance (and maybe some other stuff, too).   A role can be applied to a class
at compile time via Cdoes, or to an object at run time via Cbut.

So for example:

class Dog
does Boolean# role
is extended # trait
is Mammal   # base class
{
has $.tail; # attribute
has @.legs; # attribute
}

my $fido = Dog.new
but false;  # property

In this example, CMammal is a base class, which is an overloaded use of Cis.  
Though,
upon A12 release, we'll probably find out that it's not overloaded but
instead, elegantly unified, somehow. 

=head1 AUTHOR

Luke Palmer, Original Document

Contributions by Larry Wall, and Jonathan Scott Duff

Compilation by Casey West

=cut


Re: Vocabulary

2003-12-12 Thread Larry Wall
On Fri, Dec 12, 2003 at 05:17:37PM -0500, Austin Hastings wrote:
:  -Original Message-
:  From: Larry Wall [mailto:[EMAIL PROTECTED]
:  Sent: Friday, December 12, 2003 12:17 PM
: 
:  : - role
:  :   A collection of methods to be incorporated into a class sans
: 
:  A role can also supply one or more attributes.
: 
: So a role can constrain values and add behavior and attributes. Presumably
: it can do both at the same time?

I suspect so.  Some added behaviors may only make sense on a constrained
set of values.

:   enum ParityMode values P_ODD P_EVEN P_NONE;
: 
:   role Byte
: does Int[0..255]   # Value constraint
: does { # extending by adding attributes  methods, and by
: overriding the STORE method
:   has ParityMode $.parity_mode = NONE;
:   has bit $.parity;
: 
:# .CONFORM is redundant with Value constraint above,
: which autogenerates this.
:   method CONFORM(Int $i) { SUPER  0 = $i = 255; }
:   method STORE(Int $i: $v) { $i = .CONFORM($v) || fail; set_parity; }
:   method set_parity {...}
: };

Yes, though CONFORM is likely to be spelled PRE.

And I'm not sure your STORE is gonna work by clobbering the invocant
reference like that.  More likely you have to assign to .value or some
such accessor provided by Int.  Or since roles compose into the class,
it may be okay for roles to access attribute variables directly,
and set $.value (presuming that's the attribute provided by Int).
Depends on how fancy we want to get with the cross checking at
composition time.

:  : inheritance (and maybe some other stuff, too).  Used
:  with Cdoes.
: 
:  Here it gets a little fuzzier.  A role can be applied to a class
:  at compile time via does, or to an object at run time via but.
: 
: Good. I like the mixin being available at either time. This makes properties
: a lot more useful since I can provided default or normal values:
: 
:   role Celebrated
: does Date
: does {
:   method celebrated($d) { return $d.date; }
:   }
: 
:   class Birthday does Celebrated {
: has $.date;
:   }
: 
:   my Birthday $d = Birthday.new('February', 29, 2004) but
: Celebrated('March', 01, 2004);
: 
:   print My birthday is celebrated $d.celebrated;

More generally, you can write the rest of the class knowing that the
role is there if it's compiled in.

: I presume that the linear order (compile time) or chronological order of
: applying roles decides the order in which overlaid methods are
: Cwraped/overlaid.

The original Traits paper specifies that it's illegal to compose two
methods of the same name into the class, and you have to rename one of
them to get them both visible.  This is why the authors specifically
rejected mixins, because they hide errors like this.

As for the relationship of Trait methods to other methods
declarations, an explicit method declaration in the class proper
overrides the composed methods, while composed methods override
anything else in the inheritance hierarchy.

: Which is it, by the way? Or is there MTOWTDI, such as a method modifier for
: specifying polymorph behavior?

The default way might well be the way specified in the Traits paper.
However, their underlying language didn't support any kind of multi
dispatch.  Perl 6 will be able to multi any set of names in the same
namespace as long as the arguments are differentiable by type.  So it
might be possible to insert a stub method declaration in the class
proper that says treat all composed methods of this name as multis.
That presumes the methods take differing arguments, of course.

:   method CONFORM is wrapped { ... call ... }

That would be another way to do it, except that you might still have
to switch on something to tell it which role method to call.

:  A property is a simple kind of role that supplies a single attribute.
:  The type of a property is identical to its role name.  Roles can have
:  subtypes that function as enums when the subtypes are constrained to a
:  single value.
: 
: This seems really clunky for enums. It works okay for boolean, but even
: doing month-names is going to suck pretty hard:
: 
:   role Month;
: 
:   role January   does Month[0];
:   role February  does Month[1];
:   role March does Month[2];
:   role April does Month[3];
:   role May   does Month[4];
:   role June  does Month[5];
:   role July  does Month[6];
:   role Augustdoes Month[7];
:   role September does Month[8];
:   role October   does Month[9];
:   role November  does Month[10];
:   role December  does Month[11];
: 
:   role Month does Int[January..December];

That's why I suggested some syntactic sugar for it.  But I admit that
treating each enum as a subtype is a stretch.  They could be constant
methods, for instance.  In any event, the various enum names should
probably be hidden in the Month role and not be exported by default.

:  You can use one of these subtypes without specifically implying the role
: name.