Re: Aliasing methods in CPAN roles

2009-10-20 Thread Raphael Descamps
Am Montag, den 19.10.2009, 16:43 -0700 schrieb Jon Lang:
 Raphael Descamps wrote:
  I personally don't understand why we don't have a exclude and alias
  operator in Perl 6 but I have not read all the synopses and don't have
  an overview.
 
 I don't think that it's explicitly spelled out anywhere; but the
 reason is fairly straightforward: exclude and alias would break the
 interface.

You're of course right!

It's clearly explained in Apocalypse 12 (Conflict Resolution):
A role without implementation degenerates to an interface.

I don't know why but I didn't realised before that not implementing
exclude and alias was in fact an important design decision: I have
probably read to much traits papers and not enough Apocalyses ;)

On one side you lose flexibility to resolve some composition conflicts
but the fact that a role also define a contract is of course a big win,
particulary for a language like perl 6 supporting optional statical
typing. The traits paper only focus on dynamic typing.
It also explain why perl 6 as a so strong support for delegation, as it
is the proposed way to solve composition conflicts.

It's time to read Apacalyse 12 again as I am now able to anderstand
it :)



Re: unusual invocants

2009-10-20 Thread Mark J. Reed
On Mon, Oct 19, 2009 at 11:47 PM, Jon Lang datawea...@gmail.com wrote:
 Because a method is part of a role, and ought to abide by the same
 terms by which the role abides.  If Logging doesn't do Numeric, it
 shouldn't have any methods in it that won't work unless it does.

100% agreed.

So what the OP wants to do is declare a method that is available on
all those invocants - and only those invocatnts - which do all of
roles X, Y, and Z.  Granted, you can declare a new role XandYandZ that
does X, Y, and Z, and define the method there, but that won't work on
$foo unless you declare explicitly  '$foo does XandYandZ' .  The goal
is to have the method show up no matter how $foo comes to do all three
roles.

This is an interesting idea.  Currently, it doesn't work because
there's no place for such a method to live, so perhaps there could be
a way to declare a method space for arbitrary combinations of roles,
a sort of meta-role.  It's an odd duck, but it does sort of fall out
of the multiple-dispatch semantics, which already let you base
implementation chioce on arbitrary combinations of roles...


-- 
Mark J. Reed markjr...@gmail.com


Re: unusual invocants

2009-10-20 Thread Matthew Walton
On Tue, Oct 20, 2009 at 2:32 PM, Mark J. Reed markjr...@gmail.com wrote:
 On Mon, Oct 19, 2009 at 11:47 PM, Jon Lang datawea...@gmail.com wrote:
 Because a method is part of a role, and ought to abide by the same
 terms by which the role abides.  If Logging doesn't do Numeric, it
 shouldn't have any methods in it that won't work unless it does.

 100% agreed.

 So what the OP wants to do is declare a method that is available on
 all those invocants - and only those invocatnts - which do all of
 roles X, Y, and Z.  Granted, you can declare a new role XandYandZ that
 does X, Y, and Z, and define the method there, but that won't work on
 $foo unless you declare explicitly  '$foo does XandYandZ' .  The goal
 is to have the method show up no matter how $foo comes to do all three
 roles.

 This is an interesting idea.  Currently, it doesn't work because
 there's no place for such a method to live, so perhaps there could be
 a way to declare a method space for arbitrary combinations of roles,
 a sort of meta-role.  It's an odd duck, but it does sort of fall out
 of the multiple-dispatch semantics, which already let you base
 implementation chioce on arbitrary combinations of roles...

Well, if you could put a where clause on your invocant you could do that...

method m($invocant where { $_ ~~ X and $_ ~~ Y and $_ ~~ Z }: Int $a,
Int $b) { ... }

The STD.pm bot in #perl6 thinks where clauses on invocants are
allowed, but Rakudo currently seems to completely ignore them. I'm not
sure what the proper behaviour should be.

Matthew


lvalue methods

2009-10-20 Thread Jon Lang
I recently attempted to write a sample mutable role that made use of a
number of lvalue methods, and I had a bear of a time getting it to
work.  Could we arrange for a more intuitive option to be available?
For example, allow the programmer to pass a writer code block in
through the rw trait, and assume that the default codeblock is a
reader codeblock.  Something like:

method x() is rw( { $.x = $_ } ) { return $.x }

The idea is that if this is being called as an rvalue, the { return .x
} block would be called, but if it's being called as an lvalue, the {
.x = $_ } block would be called.

The above example is of course trivial.  A more serious example might
be one based off of a coordinate system:

role point {
has Num $x, Num $y;
method angle() is rw( { $.x = .r * cos($_); $.y = .r * sin($_)
} ) { return atn($.y/$.x) }
method r() is rw( { $.x = $_ * cos(.angle); $.y = $_ *
sin(.angle) } ) { return sqrt($.x * $.x + $.y * $.y ) }
}

This strikes me as being much more readable than the current approach
of explicitly returning a proxy object.  I'd even be fine if the above
were treated as syntactic sugar for the creation of a proxy object -
that is, have:

method x() is rw( { $.x = $_ } ) { return $.x }

be exactly equivalent to something like:

method x($val) is rw { return new Proxy:
FETCH = method { return $.x },
STORE = method { $.x = $_ }
}

...but without the programmer having to worry about how to access the
role's attributes from within the proxy object.

-- 
Jonathan Dataweaver Lang


Re: unusual invocants

2009-10-20 Thread David Green

On 2009-Oct-20, at 7:55 am, Matthew Walton wrote:
On Tue, Oct 20, 2009 at 2:32 PM, Mark J. Reed markjr...@gmail.com  
wrote:
On Mon, Oct 19, 2009 at 11:47 PM, Jon Lang datawea...@gmail.com  
wrote:

Because a method is part of a role, and ought to abide by the same
terms by which the role abides.  If Logging doesn't do Numeric, it
shouldn't have any methods in it that won't work unless it does.


100% agreed.

So what the OP wants to do is declare a method that is available on  
all those invocants - and only those invocatnts - which do all of  
roles X, Y, and Z.  Granted, you can declare a new role XandYandZ  
that does X, Y, and Z, and define the method there, but that won't  
work on $foo unless you declare explicitly  '$foo does  
XandYandZ' .  The goal is to have the method show up no matter how  
$foo comes to do all three roles.


Right.

This is an interesting idea.  Currently, it doesn't work because  
there's no place for such a method to live, so perhaps there could  
be a way to declare a method space for arbitrary combinations of  
roles, a sort of meta-role.  It's an odd duck, but it does sort of  
fall out of the multiple-dispatch semantics, which already let you  
base implementation chioce on arbitrary combinations of roles...


Yes, and while the answer could always be don't do that, the concept  
doesn't seem particularly strange or undesirable.  Maybe rather than  
hide a Numeric method inside a Logging role where people wouldn't  
expect to find it, we could do it this way:


role Numeric Logging { method log {...} }

or something alone those lines.

Well, if you could put a where clause on your invocant you could do  
that...
method m($invocant where { $_ ~~ X and $_ ~~ Y and $_ ~~ Z }:  
Int $a, Int $b) { ... }



I would expect $foo where {$_ ~~ X} and X $foo simply to be  
different ways of writing the same thing, but whatever works!



-David



Re: lvalue methods

2009-10-20 Thread David Green

On 2009-Oct-20, at 8:04 am, Jon Lang wrote:
The above example is of course trivial.  A more serious example  
might be one based off of a coordinate system:


   role point {
   has Num $x, Num $y;
   method angle() is rw( { $.x = .r * cos($_); $.y = .r *  
sin($_) } ) { return atn($.y/$.x) }
   method r() is rw( { $.x = $_ * cos(.angle); $.y = $_ *  
sin(.angle) } ) { return sqrt($.x * $.x + $.y * $.y ) }

   }

This strikes me as being much more readable than the current  
approach of explicitly returning a proxy object.  I'd even be fine  
if the above were treated as syntactic sugar for the creation of a  
proxy object -


And/or some sugar for using special STORE methods on a variable, e.g.:

has $angle is set { $.x = .r * cos($_); $.y = .r * sin($_) };

(Well, in this example that makes extra storage space for the $angle  
attribute which we don't actually want, but there are many cases where  
an easy way to override STORE is really what is useful rather than an  
lvalue sub.)


But one of the problems with lvalue subs that don't simply return a  
variable (or equivalently, my is set example) is that you can't say  
things like temp lvalue() unless temp is receiving an actual  
variable to work on.


In the case where angle() (or $.angle) is changing $.x and $.y, should  
trying to temporize it do temp $.x and temp $.y as well?  Should  
it be impossible?  Can Perl tell whether it should be impossible or  
not?  Does it need to be illegal to change other variables inside a  
STORE?



Meanwhile, the flip side to wanting an easy way to do is set is that  
often when someone reaches for an lvalue sub, all he really wants is a  
way to pass an arg to the sub that looks like assignment.  For example  
wanting foo($x) = $y to be a prettier way to write foo($x, $y).   
This could be handled by, say, having a special rvalue keyword in  
signatures, e.g.:


sub foo($x, rvalue $y?) { ... }

foo(42); # $y is undef
foo(42) = 24;# $y is 24
foo(42, 24); # syntax error

This has the advantage of often doing what people want, and the  
disadvantage of not working with temp, etc.  At least Perl could  
know that temp isn't allowed to work with such subs, though.  On the  
other hand, something that looks like an assignment ought to work like  
an assignment, including temp


Especially since if you want something that looks more assignment-y  
than passing a regular arg, we already have a way to do that, namely,  
using the == syntax to feed args into a slurpy parameter.  But in  
your angle example, we really do want an assignment because the net  
result is to assign stuff.  Perhaps method angle is setting ($.x,  
$.y) ... to indicate that whatever is done to angle should really  
affect $x and $y, and any other attributes that aren't specified may  
not be used.



-David



Re: unusual invocants

2009-10-20 Thread TSa (Thomas Sandlaß)
HaloO,

On Tuesday, 20. October 2009 18:35:36 David Green wrote:
  So what the OP wants to do is declare a method that is available on
  all those invocants - and only those invocatnts - which do all of
  roles X, Y, and Z.  Granted, you can declare a new role XandYandZ
  that does X, Y, and Z, and define the method there, but that won't
  work on $foo unless you declare explicitly  '$foo does
  XandYandZ' .  The goal is to have the method show up no matter how
  $foo comes to do all three roles.

 Right.

I have difficulty seeing the need for a method here. The distinguishing
feature of a method is the access to the private data of an object that
can hardly be granted by doing the three roles X, Y and Z. After all
there's no unique implementation of these roles!

Perl 6 is a hybrid language as far as dispatch is concerned. There is
the class based method dispatch that I call slot dispatch because the
usual implementation is to have the objects carry a ref to a slot table.
The other dispatch is the type based MMD. Unfortunately this also
goes by the name of method. This is because other languages use classes
as types and conflate the two dispatch regimes that Perl 6 clearly
separates. There used to be fail-over from class dispatch to MMD but
this didn't work---even though I forgot what the exact problems were ;)

So in the end the only problem is that the calling conventions of
$object.method versus method($object) are not interchangeable. But
it makes the priority clear. In the $object.method case the object
is the primary concept. We think of it as the object doing something.
In many cases to its own state. In the method($object) case the method
is the primary concept. The object influences how it is done or what
is the output. The method can of course call mutating methods on the
object but this is a secondary concern.


Regards, TSa.
-- 
The unavoidable price of reliability is simplicity -- C.A.R. Hoare
Simplicity does not precede complexity, but follows it. -- A.J. Perlis
1 + 2 + 3 + 4 + ... = -1/12  -- Srinivasa Ramanujan


r28864 - docs/Perl6/Spec

2009-10-20 Thread pugs-commits
Author: masak
Date: 2009-10-21 00:03:48 +0200 (Wed, 21 Oct 2009)
New Revision: 28864

Modified:
   docs/Perl6/Spec/S06-routines.pod
Log:
[S06] same-named non-anon positionals are a compile error

Modified: docs/Perl6/Spec/S06-routines.pod
===
--- docs/Perl6/Spec/S06-routines.pod2009-10-20 21:54:09 UTC (rev 28863)
+++ docs/Perl6/Spec/S06-routines.pod2009-10-20 22:03:48 UTC (rev 28864)
@@ -16,8 +16,8 @@
 
 Created: 21 Mar 2003
 
-Last Modified: 10 Oct 2009
-Version: 120
+Last Modified: 21 Oct 2009
+Version: 121
 
 This document summarizes Apocalypse 6, which covers subroutines and the
 new type system.
@@ -503,6 +503,10 @@
 possible on those arguments that are bound to a final slurpy or
 arglist variable.)
 
+All positional parameters must either have a unique name (sigil included)
+or be anonymous. Declaring a routine having two positionals with exactly
+the same name counts as a compile-time error.
+
 =head2 Named arguments
 
 Named arguments are recognized syntactically at the comma level.



r28865 - docs/Perl6/Spec

2009-10-20 Thread pugs-commits
Author: moritz
Date: 2009-10-21 00:15:32 +0200 (Wed, 21 Oct 2009)
New Revision: 28865

Modified:
   docs/Perl6/Spec/S06-routines.pod
Log:
[S06] extend uniq name constraint to named parameters too

Modified: docs/Perl6/Spec/S06-routines.pod
===
--- docs/Perl6/Spec/S06-routines.pod2009-10-20 22:03:48 UTC (rev 28864)
+++ docs/Perl6/Spec/S06-routines.pod2009-10-20 22:15:32 UTC (rev 28865)
@@ -503,10 +503,16 @@
 possible on those arguments that are bound to a final slurpy or
 arglist variable.)
 
-All positional parameters must either have a unique name (sigil included)
+All parameters must either have a unique name (sigil included)
 or be anonymous. Declaring a routine having two positionals with exactly
-the same name counts as a compile-time error.
+the same name counts as a compile-time error. Renaming a named parameter
+can also cause forbidden name collisions:
 
+:($a, $a)   # wrong, two a
+:($a, :a($b))   # wrong, one a, one a through renaming
+:($a, :a(@b))   # wrong 
+:(:$a, :@a) # wrong
+
 =head2 Named arguments
 
 Named arguments are recognized syntactically at the comma level.



Re: unusual invocants

2009-10-20 Thread Matthew Walton
On Tue, Oct 20, 2009 at 5:35 PM, David Green david.gr...@telus.net wrote:
 I would expect $foo where {$_ ~~ X} and X $foo simply to be different
 ways of writing the same thing, but whatever works!

Yes, but the where clause lets you test against multiple types at
once. They don't participate in multiple dispatch in the same way
though. Whether it should be possible to attach a where clause to an
invocant appears to be unresolved.