Re: Ways to add behavior

2005-10-27 Thread Michele Dondi

On Wed, 26 Oct 2005, Rob Kinyon wrote:


I'd like to take this moment and point to my somewhat hand-wavy
metamodel proposal from last week. When Stevan and I were talking
about this, we called it a quark. Atom also works quite nicely,
but quarks are cooler.


They're also colorful. Does this mean we will have a colour trait? But 
most importantly, who is supposed to be $Muster_Mark?


Seriously, quark was originally chosen as a name because of the 
appearance of _three_ (somewhat mysterious) objects. Now it would 
indeed be cool to borrow the term in a CS context, especially in Perl, but 
it would be better suited in a naturally ternary (say, 
{property,structure}-wise) context.



Michele
--
Il tempo e' denaro, ma anche il denaro e' denaro.
- William Gibson, L'accademia dei sogni.


Re: Roles vs. Classes (was Re: Ways to add behavior)

2005-10-27 Thread Rob Kinyon
On 10/26/05, Larry Wall [EMAIL PROTECTED] wrote:
 On Wed, Oct 26, 2005 at 07:35:05PM -0700, chromatic wrote:
 : On Wed, 2005-10-26 at 21:58 -0400, Rob Kinyon wrote:
 :
 :  Plus, the argument is a straw man. Instead of:
 : 
 :  class Some::Class is also {
 :  }
 : 
 :  you would do:
 : 
 :  class My::Version {
 :  does Some::Class;
 :  }
 : 
 :  Problem solved.
 :
 : Don't forget the fun of modifying all existing uses of Some::Class to
 : use My::Version instead, if that's even possible.

 That should mostly be handled by virtualized class names.

Will I be able to do something like:

package Foo;
$*VERSION = 1.3.2;

use Foo-1.3.1;

role My::Foo { does Foo; ... }
alias My::Foo - Foo; # Or whatever the syntax should be

And, in my other code, use Foo; will DWIM?


Re: +$arg changed to :$arg

2005-10-27 Thread TSa

HaloO,

Larry Wall wrote:


: Yes, and dispatch as a runtime keyed access into a code multitude.
: The covariant part of the method's sig! The code equivalent to keyed
: data access into hashes.

Um, yeah.  Won't play in Peoria, though.


Where or what is Peoria?

What I mean with the covariant part of a method sig stems from
the paper G. Castagna. Covariance and contravariance: conflict
without a cause available from
ftp://ftp.di.ens.fr/pub/users/castagna/covariance.ps.gz



: The left -- is just the virtualizer call. I tend to call
: that slot accessor. The return value of a dispatch is the
: not yet invoked but curried on the invocant(s) method. This
: two stage propcess is in my eyes nicely indicated by the
: two --. But we could also but a : in the dispatch arrows
: like -:- or :- or -: which all look somewhat ugly.

I kind of like : for that, actually. :-)


I have no objections. Actually I associate it with
the label syntax. But I hope we have the same understanding
what

   multi method abc (A $a: B $b: C $c: X $x, Y $y) {...} #1

means in comparison to

   multi method abc (A $a, B $b, C $c: X $x, Y $y) {...} #2

where I think that #1 is a mono method on A that yields a
mono method on B which in turn yields a mono method on C.
That is *three* successive dispatches which could branch out
into different targets in each step. E.g. with D a subtype of B

   multi method abc (A $a: D $b: C $c: X $x, Y $y) {...} #3

The #2 target OTOH is a *single* target on the 3-tupel type :(A,B,C).
We could call the #1 and #3 dispatches tree-dispatch and #2
lattice-dispatch. Question is how do they relate to each other?
I would opt for :(A,B,C) beeing more specific than :(A). In other
words the cascaded dispatch competes in each step with n-tupel types.
E.g.

  multi method abc (A $a: D $b, C $c: X $x, Y $y) {...} #4

outperforms :(B) from #1 and :(D) from #3 with its :(D,C) (sub)signature.
Note that

  multi method abc (A $a: B $b, C $c: X $x, Y $y) {...} #5

would be ambigous in a pure regime because :(B,C) is not a strictly
more specific type than :(D).

After the successful selection of the target out of the targets #1
to #5 the contravariant part of the sig :(X,Y) is checked and then
the invocation procedes with binding the args to the params.



:   method doit (...) on (invocant sig) { ... }

I don't see how that relates.


Take the example #2 from above which could be written

  multi method abc (X $x, Y $y) on (A $a, B $b, C $c) {...}

and the cascading version as

  multi method abc (X $x, Y $y) on (A $a) on (B $b) on (C $c) {...}

or with the invocants at the front

  multi method on (A $a, B $b, C $c) abc (X $x, Y $y) {...}

But I'm not a native who could decide if 'method on' is the right
choice of preposition. Perhaps it should be 'method in'? But that
would further the conception of methods beeing inside of classes
which they are only in the special case of a dispatch implementation
through vtbls carried around by the objects. My old problem of 'is
the object or the method in charge'.

The metaphor that illustrates my point is that $ball.throw() looks
funny in my mind if you think of the $ball throwing itself. Compare
with $Larry.talk() where the talking style is inherent in $Larry.




: Well, we could take the ¢ sigil to form invocant twigils ¢$, ¢@, ¢%, ¢
: which look a bit nicer with ^ though: ^$, ^@, ^%, ^. The association
: with $^, @^, %^, ^ in placeholders is a bonus in my eyes because they
: are post dispatch on void invocants :)

Don't know what that means either.


'post dispatch on void' was a poor attempt to paraphrase that I see
a sub as a *very* unspecific method. That is a sub call in method style

  $x.foo();

dispatches to the sub foo only if there is no other applicable method at
all. Submethods in that view are methods that are specialized on Undef of
the respective class.

BTW, is ($x,$y).foo(1,2) valid multi method invocation syntax? Note that
if there is nothing else but

  sub foo ([EMAIL PROTECTED]) {...}

in scope it could be selected and called with

  @bar[0] = $x;
  @bar[1] = $y;
  @bar[2] = 1;
  @bar[3] = 2;



: The guiding theme in my line of thinking about twigils is that there's
: a void between their two chars. A pair of type constraint and uncaptured
: actual invocant type so to say. Well and we could capture it with
: 
:   method doit ( Constraint ^Actual $foo, NonInvocant $blahh ) {...}
: 
: to deal have it available inside. Am I makeing sense? Which impact all

: this has an the self method discussion I don't know, but ^. and .^ come
: to mind. The former would make ^.foo a method on the current invocant
: and a bare .^ would dispatch the current method on the topic or some such.

I haven't the foggiest clue if you're making sense.  And that's the
scary part.


OK, forget the part about self calls inside the method implementation and
let's look at the type variable aspect only. If I understand the concept
correctly then ^ splits the type aspect of a variable 

Re: +$arg changed to :$arg

2005-10-27 Thread Rob Kinyon
On 10/27/05, TSa [EMAIL PROTECTED] wrote:
 HaloO,

 Larry Wall wrote:

  : Yes, and dispatch as a runtime keyed access into a code multitude.
  : The covariant part of the method's sig! The code equivalent to keyed
  : data access into hashes.
 
  Um, yeah.  Won't play in Peoria, though.

 Where or what is Peoria?

It's an expression in the US. Peoria is a town in the state of
Illinois. It has a reputation for being conservative and a keeper of
American Values (whatever that means). So, when you say something
won't play in Peoria, you're saying that it's unlikely to be
accepted by the masses.

Rob


Re: +$arg changed to :$arg

2005-10-27 Thread TSa

HaloO,

Juerd wrote:

This aside, you could of course just double the colon. Or use a
semicolon.


Semicolon would give me the mnemonic of 'end of statement' seperating
the dispatched part from the checked part of the signature. Or it
reminds one of the array and hash slicing. Should we call dispatch
call or code slicing?

  :( Int, Int ; Str, Num -- Foo )

A slot call would then retrieve the method from the object first

  :( Item ^X -- ^X ; Foo, Bar -- Ret )

Assuming we use ^ instead of ¢ as the captured type sigil. Which
leaves the question how arrow type invocant methods relate to
non-arrow type invocant methods? Hmm, non-arrow types can always
be regarded as :( void -- ^X ) and the usual contra-variant subtyping
rule would make :( ^X -- ^X ) more specific if void were more specific
than ^X. But I think the opposite is true! That is any value can go
to void context and be ignored. In other words void is a type close to
the universal type. By the same argument any method is more specific
than subs which have void as invocant type.

I like the outcome that a free method on the same type has higher
dispatch precedence than the corresponding slot call. YMMV, though.
OTOH, the free method might not have the privileged access that a
'inside class definition' method has. But then such a outside overrider
might just delegate to the insider routine through explicit slot access.
But how does that look like? I think

  method bar (Foo $x) # all params dispatched, hence ^ optional
  {
 say outside Foo :);
 $x.Foo::bar(); # slot call
  }

should do the trick. But then again, there might be no free methods
in Perl6.



I just really wouldn't like : to have two very different meanings in very
similar places.


I'm split on the issue because of the similarity to the label syntax. The
indirect object syntax is then the call continuation after the dispatch
target selection and invocants binding or some such.
--
$TSa.greeting := HaloO; # mind the echo!



Is there a way to generate an object without new?

2005-10-27 Thread Yiyi Hu
What I want to do, is a bit like...

class A {
has $.b;
method show { $.b.say };
};

A( b = 5 ).show;`


Thanks,

Xinming


Re: Is there a way to generate an object without new?

2005-10-27 Thread Luke Palmer
On 10/27/05, Yiyi Hu [EMAIL PROTECTED] wrote:
 What I want to do, is a bit like...

 class A {
 has $.b;
 method show { $.b.say };
 };

 A( b = 5 ).show;`

Yes, I definitely want this to be the way that case type instances are
created: all those .news everywhere could get annoying.

Anyway, assuming that class and sub namespaces are separate, which may
be a dubious assumption:

our A ::= A::new.assuming(A);

Or, more explicitly (and more readably IMO):

sub A (\$x) { A.new(*$x) }

Luke


Re: Is there a way to generate an object without new?

2005-10-27 Thread Juerd
Yiyi Hu skribis 2005-10-28  3:17 (+0800):
 class A {
 has $.b;
 method show { $.b.say };
 };
 A( b = 5 ).show;`

This is how some other language construct objects, but not how Perl does
it. In other words: you should not want this.

Perhaps it is possible to have a class export a sub to its user.

class A {
has $.b handles { 'show' = 'say' };
eval sub $?CLASS is export { $?CLASS.new(\$?ARGS) };
}

Not sure about the existence of $?ARGS, or how else to write it. Well,
@_, but the signature might be different.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: Is there a way to generate an object without new?

2005-10-27 Thread Matt Fowles
Juerd~

On 10/27/05, Juerd [EMAIL PROTECTED] wrote:
 Yiyi Hu skribis 2005-10-28  3:17 (+0800):
  class A {
  has $.b;
  method show { $.b.say };
  };
  A( b = 5 ).show;`

 This is how some other language construct objects, but not how Perl does
 it. In other words: you should not want this.

How does that logically follow?

Matt
--
Computer Science is merely the post-Turing Decline of Formal Systems Theory.
-Stan Kelly-Bootle, The Devil's DP Dictionary


Re: Is there a way to generate an object without new?

2005-10-27 Thread Juerd
Matt Fowles skribis 2005-10-27 15:52 (-0400):
  This is how some other language construct objects, but not how Perl does
  it. In other words: you should not want this.
 How does that logically follow?

They are two ways of expressing what I think. If they said exactly the
same thing, I wouldn't have felt the need to use both :)


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: Is there a way to generate an object without new?

2005-10-27 Thread Larry Wall
On Thu, Oct 27, 2005 at 01:30:44PM -0600, Luke Palmer wrote:
: On 10/27/05, Yiyi Hu [EMAIL PROTECTED] wrote:
:  What I want to do, is a bit like...
: 
:  class A {
:  has $.b;
:  method show { $.b.say };
:  };
: 
:  A( b = 5 ).show;`
: 
: Yes, I definitely want this to be the way that case type instances are
: created: all those .news everywhere could get annoying.

On the other hand, it potentially makes these mean very different things:

A @x
A(@x)

and that's a problem.  Semantically, it would certainly be possible
to teach any kind to respond to .() and attempt to clone or bless
itself into a new object, but syntactically if we introduce A as a
list operator we can never use it as a bare type mark on a variable
like @x without some declarator out front.  So either we rule out
bare A $x as a coercion or cast, or we rule out bare A as a list
operator, which would make the parens required.

But even with parens, we can't easily make A([EMAIL PROTECTED]) mean both of
these simultaneously:

@args[0].as(A)
A.new([EMAIL PROTECTED])

Well, okay, maybe if we're really sneaky about our MMD, we could make
that work most of the time.  But it kind of loses the distinction
of making a new A out of something else vs making the current thing
look like an A without necessarily cloning it.  That probably needs
syntactic relief anyway.  Maybe A! is a hard cast and A? is a soft cast.
Needs more waffling.  Er, more thought.

: Anyway, assuming that class and sub namespaces are separate, which may
: be a dubious assumption:
: 
: our A ::= A::new.assuming(A);

The variables are separate in the symbol table, but both of them
try to warp the grammar to recognize a bare 'A'.  It's not clear
what will happen in that case.  If the original ^A is really ^*A,
then defining A will likely just hide the outer meaning of A.  On the
other hand, with our definition of package aliasing, the global name
includes version and author, and the current scope has an A alias to
that long name, and that might collide with the A name of A in
the current scope.

: Or, more explicitly (and more readably IMO):
: 
: sub A (\$x) { A.new(*$x) }

Sorry, A is introduced immediately, so you've just written a nice
infinite recursion.  I'd suggest

   sub A (\$x) { ::A.new(*$x) }

Larry


Re: Roles vs. Classes (was Re: Ways to add behavior)

2005-10-27 Thread Larry Wall
On Thu, Oct 27, 2005 at 05:37:13AM -0400, Rob Kinyon wrote:
: Will I be able to do something like:
: 
: package Foo;

Hmm, you just started in Perl 5 mode.

: $*VERSION = 1.3.2;

Perl 5 would get confused here, so I'm presuming Perl 6.  But Perl 6
isn't likely to let you override the global run-time Perl version.

: use Foo-1.3.1;

That I think I understand.

: role My::Foo { does Foo; ... }

Okay, My::Foo does Foo here.  Presumably it must do the Foo alias
that the use just installed.  And presumably the Foo you just used
is a role that can be done.  Certainly you can't do the global
package Foo, assuming that's what your original package declared.

: alias My::Foo - Foo; # Or whatever the syntax should be

I have no clue where you're intending to install that alias.
Are you trying to install a *Foo alias?  A bare Foo is going to first
find the local alias to the Foo you used, and that hides the global
Foo that it would have found otherwise.  I suspect you're trying to
say

*Foo := My::Foo;

: And, in my other code, use Foo; will DWIM?

I don't know quite what you mean, so I don't know if it'll do what
you mean.  If you're trying to establish a policy that defaults a
particular name to a particular version, the library interface will
probably give you a more straightforward way to set that up.

Larry


Re: Roles vs. Classes (was Re: Ways to add behavior)

2005-10-27 Thread Rob Kinyon
On 10/27/05, Larry Wall [EMAIL PROTECTED] wrote:
 On Thu, Oct 27, 2005 at 05:37:13AM -0400, Rob Kinyon wrote:
 : Will I be able to do something like:
 :
 : package Foo;

 Hmm, you just started in Perl 5 mode.

 : $*VERSION = 1.3.2;

 Perl 5 would get confused here, so I'm presuming Perl 6.  But Perl 6
 isn't likely to let you override the global run-time Perl version.

 : use Foo-1.3.1;

 That I think I understand.

 : role My::Foo { does Foo; ... }

 Okay, My::Foo does Foo here.  Presumably it must do the Foo alias
 that the use just installed.  And presumably the Foo you just used
 is a role that can be done.  Certainly you can't do the global
 package Foo, assuming that's what your original package declared.

 : alias My::Foo - Foo; # Or whatever the syntax should be

 I have no clue where you're intending to install that alias.
 Are you trying to install a *Foo alias?  A bare Foo is going to first
 find the local alias to the Foo you used, and that hides the global
 Foo that it would have found otherwise.  I suspect you're trying to
 say

 *Foo := My::Foo;

 : And, in my other code, use Foo; will DWIM?

 I don't know quite what you mean, so I don't know if it'll do what
 you mean.  If you're trying to establish a policy that defaults a
 particular name to a particular version, the library interface will
 probably give you a more straightforward way to set that up.

Sorry. I'm not up on the syntax. I should do some serious backlog reading.

What I'm trying to do is load role Foo 1.0, have My::Foo do Foo, then
call My::Foo version 2.0 of Foo so that anyone else in my program will
see My::Foo instead of the original Foo. Is this possible?

Rob


Role Method Conflicts and Disambiguation

2005-10-27 Thread Stevan Little

Hello all,

I have a question about method conflict resolution works for roles,  
and I cannot seem to find this in any of the Apoc/Syn documents.


Here is the basic issue:

role Foo {
method foo { ... }
method bar { ... }  # we will use this later :)
}

role Bar {
method foo { ... }
}

role FooBar {
does Foo;
does Bar;
}

Now, at this point we have a method conflict in suspension since  
(according to A/S-12) method conflicts do not throw an error until a  
role is composed into a class. This means that when I do this:


class MyClass does FooBar {}

an exception is thrown. Unless of course MyClass has a foo method,  
which will disambiguate the conflict. My question then is, can FooBar  
(the role) disambiguate the foo conflict?


role FooBar {
does Foo;
does Bar;
method foo { ... }
}

Now, on the surface this seems obvious, of course the FooBar role  
should be able to disambiguate. However, when we expand the example  
other issues show up.


role Baz {
does Foo;
}

class MyClass2 does FooBar does Baz {}  # Will this die?

Now, since MyClass2 actually does Foo twice, does that mean bar  
creates a conflcit? Since bar would be found through FooBar and Baz.  
I would think the answer here would be no, and that we would build  
some kind of unique list of roles so as to avoid repeated consumption  
like this.


But thats not all, we have a potential problem with foo again. Baz  
will provide foo from Foo, but FooBar will provide it's own foo  
(which we used to disambiguate). So our disambiguation is not  
ambiguated again.


/ Possible Solutions /

A (deceptively) simple solution to this is that MyClass2 needs to  
disambiguate. But this means that our roles are not really black  
boxes anymore. In order to properly disambiguate this we need to know  
where all the foo methods are coming from (Foo, Bar and FooBar), and  
potentially what is inside these foo methods (especially in the case  
of FooBar since it is attempting to disambiguate, it's behavior could  
be very specific). It probably would also become important to know  
what other methods foo interacts with since we potentially have 3  
different expected versions of foo.


In the end, we will have probably looked inside every method defined  
in Foo, Bar, FooBar and Baz in order to properly write MyClass2.  
IMHO, this is sort of defeating the usefulness of roles at this point.


Another simple (but maybe slightly unintuitive) solution would be to  
not allow roles to disambiguate at all.


(Quick side note: Doing this means that roles like FooBar (which  
carry with them a suspended conflict) would be restricted in what  
types of behaviors they can provide. Basically they would only be  
able to provide new behaviors which are unrelated to those provided  
by Foo and Bar. If it were to try to use methods from Foo or Bar, it  
would really end up needing to disambiguate.)


This actually makes MyClass2 somewhat simpler now, since it only need  
to disambiguate between foo from Foo, and foo from Bar. Of course  
this is only marginally better, since you would still need to look  
inside all the methods of Foo, Bar, FooBar and Baz to see how foo is  
being used so you could disambiguate properly.


...

So what do you all think??

Stevan