Re: Are proposals for new language methods considered?

2016-01-31 Thread Will Coleda
The language is intended to evolve; the specification will change as we go.

If you have a proposal, go ahead and make it, see what traction it
gets on the list.

On Sun, Jan 31, 2016 at 8:27 AM, Tom Browder <tom.brow...@gmail.com> wrote:
> I would like to propose some new Str and IO::Path methods if such
> would be considered.
>
> Best regards,
>
> -Tom



-- 
Will "Coke" Coleda


Re: Are proposals for new language methods considered?

2016-01-31 Thread Tom Browder
On Sun, Jan 31, 2016 at 5:01 PM, Will Coleda  wrote:
> The language is intended to evolve; the specification will change as we go.
>
> If you have a proposal, go ahead and make it, see what traction it
> gets on the list.

Is there any specific format for a proposal?  If not, is there a
successful example available for reference?

Thanks, Will.

Best,

-Tom


Re: Are proposals for new language methods considered?

2016-01-31 Thread Will Coleda
Nope. Most people just show up on #perl6 and chat, or make a pull
request or open an RT.

On Sun, Jan 31, 2016 at 6:10 PM, Tom Browder  wrote:
> On Sun, Jan 31, 2016 at 5:01 PM, Will Coleda  wrote:
>> The language is intended to evolve; the specification will change as we go.
>>
>> If you have a proposal, go ahead and make it, see what traction it
>> gets on the list.
>
> Is there any specific format for a proposal?  If not, is there a
> successful example available for reference?
>
> Thanks, Will.
>
> Best,
>
> -Tom



-- 
Will "Coke" Coleda


Re: Are proposals for new language methods considered?

2016-01-31 Thread Tom Browder
On Sun, Jan 31, 2016 at 5:20 PM, Will Coleda  wrote:
> Nope. Most people just show up on #perl6 and chat, or make a pull
> request or open an RT.

Gotcha, thanks.

-Tom


Are proposals for new language methods considered?

2016-01-31 Thread Tom Browder
I would like to propose some new Str and IO::Path methods if such
would be considered.

Best regards,

-Tom


[perl6/specs] beb870: Spec action objects/methods

2015-07-05 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: beb870dbff3460b981055034ee5b6e72307b7d34
  
https://github.com/perl6/specs/commit/beb870dbff3460b981055034ee5b6e72307b7d34
  Author: Rob Hoelz r...@hoelz.ro
  Date:   2015-07-04 (Sat, 04 Jul 2015)

  Changed paths:
M S05-regex.pod

  Log Message:
  ---
  Spec action objects/methods


  Commit: e4f79178aa87db3fd51ca50eeb38451c86cc7b42
  
https://github.com/perl6/specs/commit/e4f79178aa87db3fd51ca50eeb38451c86cc7b42
  Author: Rob Hoelz r...@hoelz.ro
  Date:   2015-07-04 (Sat, 04 Jul 2015)

  Changed paths:
M S99-glossary.pod

  Log Message:
  ---
  Link to action objects section in glossary


Compare: https://github.com/perl6/specs/compare/ace089e004fe...e4f79178aa87

[perl6/specs] 66d345: Detail action methods + dynvar behavior

2015-07-05 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: 66d345c46eb3e16bdb2f3257bb2265bb803f610c
  
https://github.com/perl6/specs/commit/66d345c46eb3e16bdb2f3257bb2265bb803f610c
  Author: Rob Hoelz r...@hoelz.ro
  Date:   2015-07-05 (Sun, 05 Jul 2015)

  Changed paths:
M S05-regex.pod

  Log Message:
  ---
  Detail action methods + dynvar behavior




[perl6/specs] 5a57b9: Add blurb about symlink (lstat) methods

2015-02-12 Thread GitHub
  Branch: refs/heads/newio
  Home:   https://github.com/perl6/specs
  Commit: 5a57b95040c9581e63cc51c4b682365e67a94bcb
  
https://github.com/perl6/specs/commit/5a57b95040c9581e63cc51c4b682365e67a94bcb
  Author: Elizabeth Mattijsen l...@dijkmat.nl
  Date:   2015-02-12 (Thu, 12 Feb 2015)

  Changed paths:
M S16-io.pod

  Log Message:
  ---
  Add blurb about symlink (lstat) methods




[perl6/specs] f07639: Don't use accessor methods in their own implementa...

2015-01-16 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: f0763966964429f9bb835783635f97d6a3423c31
  
https://github.com/perl6/specs/commit/f0763966964429f9bb835783635f97d6a3423c31
  Author: Rob Hoelz r...@hoelz.ro
  Date:   2015-01-15 (Thu, 15 Jan 2015)

  Changed paths:
M S05-regex.pod

  Log Message:
  ---
  Don't use accessor methods in their own implementation

name should not be defined in terms of name with no terminating
condition




[perl6/specs] 1a4d94: Change Range excludes_* methods to dashes

2015-01-03 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: 1a4d949358408eb3e7b5a7461264f4f356c8eeb9
  
https://github.com/perl6/specs/commit/1a4d949358408eb3e7b5a7461264f4f356c8eeb9
  Author: Lucas Buchala lucasbuch...@gmail.com
  Date:   2014-11-25 (Tue, 25 Nov 2014)

  Changed paths:
M S03-operators.pod
M S32-setting-library/Containers.pod

  Log Message:
  ---
  Change Range excludes_* methods to dashes


  Commit: b983b23af7be05288ffa0c2d9a553e7dd6735665
  
https://github.com/perl6/specs/commit/b983b23af7be05288ffa0c2d9a553e7dd6735665
  Author: Moritz Lenz mor...@faui2k3.org
  Date:   2015-01-01 (Thu, 01 Jan 2015)

  Changed paths:
M S03-operators.pod
M S32-setting-library/Containers.pod

  Log Message:
  ---
  Merge pull request #74 from lucasbuchala/range-excludes

Change Range excludes_* methods to dashes


Compare: https://github.com/perl6/specs/compare/8969a7418661...b983b23af7be

[perl6/specs] a80149: Hint a bit at is export for methods

2014-08-13 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: a8014958d3f4ebb5c02cb4c840fea487ce788a0b
  
https://github.com/perl6/specs/commit/a8014958d3f4ebb5c02cb4c840fea487ce788a0b
  Author: Elizabeth Mattijsen l...@dijkmat.nl
  Date:   2014-08-11 (Mon, 11 Aug 2014)

  Changed paths:
M S11-modules.pod

  Log Message:
  ---
  Hint a bit at is export for methods


  Commit: ce07358d1a24f48837c616e9606d00ac03291036
  
https://github.com/perl6/specs/commit/ce07358d1a24f48837c616e9606d00ac03291036
  Author: Elizabeth Mattijsen l...@dijkmat.nl
  Date:   2014-08-11 (Mon, 11 Aug 2014)

  Changed paths:
M S29-functions.pod

  Log Message:
  ---
  Some cleanup/additions to S29


Compare: https://github.com/perl6/specs/compare/aa6f2438d000...ce07358d1a24

[perl6/specs] b3fceb: lock() is now Lock.new and its methods

2014-08-13 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: b3fceb8cf355d008ef29df432c60438aee6bf3d6
  
https://github.com/perl6/specs/commit/b3fceb8cf355d008ef29df432c60438aee6bf3d6
  Author: Elizabeth Mattijsen l...@dijkmat.nl
  Date:   2014-08-11 (Mon, 11 Aug 2014)

  Changed paths:
M S29-functions.pod

  Log Message:
  ---
  lock() is now Lock.new and its methods




[perl6/specs] f017ef: Further refinement on IO.x methods

2014-05-25 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: f017efdf4b971510b64beffc9d0086583b28943a
  
https://github.com/perl6/specs/commit/f017efdf4b971510b64beffc9d0086583b28943a
  Author: Elizabeth Mattijsen l...@dijkmat.nl
  Date:   2014-05-26 (Mon, 26 May 2014)

  Changed paths:
M S32-setting-library/IO.pod

  Log Message:
  ---
  Further refinement on IO.x methods




[perl6/specs] f4b120: [S15] Replace .compose/.decompose methods.

2013-12-14 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: f4b12007dbcae35464a0e9fa3497c1f48c0b85b0
  
https://github.com/perl6/specs/commit/f4b12007dbcae35464a0e9fa3497c1f48c0b85b0
  Author: lue rnd...@gmail.com
  Date:   2013-12-13 (Fri, 13 Dec 2013)

  Changed paths:
M S15-unicode.pod

  Log Message:
  ---
  [S15] Replace .compose/.decompose methods.

Left behind from the move to multiple string types.


  Commit: e020cb1303504cc8902aec7c834601b2afab868c
  
https://github.com/perl6/specs/commit/e020cb1303504cc8902aec7c834601b2afab868c
  Author: lue rnd...@gmail.com
  Date:   2013-12-13 (Fri, 13 Dec 2013)

  Changed paths:
M S15-unicode.pod

  Log Message:
  ---
  [S15] Fix ord(s) to work on all Stringy.

This presumes that Unicodey does Stringy. If not, then you simply need
to add the signatures for Unicodey things where these changes were made.

Additionally, some clarification on .chr(s).


Compare: https://github.com/perl6/specs/compare/9c555ea63fe0...e020cb130350

[perl6/specs] 8f30d2: nodal ok on normal methods too, not just protos

2013-07-14 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: 8f30d2d1ebdf4c96f1f110bad0e0884f613811f8
  
https://github.com/perl6/specs/commit/8f30d2d1ebdf4c96f1f110bad0e0884f613811f8
  Author: Larry Wall la...@wall.org
  Date:   2013-07-13 (Sat, 13 Jul 2013)

  Changed paths:
M S03-operators.pod

  Log Message:
  ---
  nodal ok on normal methods too, not just protos





[perl6/specs] 415f99: Add IO::Handle methods encoding and open (really!)...

2013-05-28 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: 415f998968a441cd2b58f85c0007814a5d7c05dd
  
https://github.com/perl6/specs/commit/415f998968a441cd2b58f85c0007814a5d7c05dd
  Author: labster bsla...@gmail.com
  Date:   2013-05-27 (Mon, 27 May 2013)

  Changed paths:
M S32-setting-library/IO.pod

  Log Message:
  ---
  Add IO::Handle methods encoding and open (really!), cleanup slurp
Minor cleanup in IO::Spec.  TODO: Pipes





[perl6/specs] 696068: Change IO::Path stringification, add new methods.

2013-04-01 Thread GitHub
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs
  Commit: 696068389ab2e29cd0f85a136350fee614acf379
  
https://github.com/perl6/specs/commit/696068389ab2e29cd0f85a136350fee614acf379
  Author: Brent Laabs bsla...@gmail.com
  Date:   2013-03-28 (Thu, 28 Mar 2013)

  Changed paths:
M S32-setting-library/IO.pod

  Log Message:
  ---
  Change IO::Path stringification, add new methods.
.Str returns full path instead of basename
.path is now a no-op (so Str.path.path still returns IO::Path)
.contents is now documented - lists the directory
.is-absolute, .is-relative, .absolute, .relative added





[perl6/specs] 09c9f5: [S32::Exception] mention methods resumable and res...

2012-07-12 Thread GitHub
  Branch: refs/heads/io-refactor
  Home:   https://github.com/perl6/specs
  Commit: 09c9f53eaf763ee58508641e4758fa764743b22f
  
https://github.com/perl6/specs/commit/09c9f53eaf763ee58508641e4758fa764743b22f
  Author: Moritz Lenz mor...@faui2k3.org
  Date:   2012-07-12 (Thu, 12 Jul 2012)

  Changed paths:
M S32-setting-library/Exception.pod

  Log Message:
  ---
  [S32::Exception] mention methods resumable and resume





[perl6/specs] 953a85: [S32::IO] all .read methods should return a Buf. T...

2011-09-23 Thread noreply
  Branch: refs/heads/master
  Home:   https://github.com/perl6/specs

  Commit: 953a85bcfbb8a22aaac883268cfc5ce03bdcdcc0
  
https://github.com/perl6/specs/commit/953a85bcfbb8a22aaac883268cfc5ce03bdcdcc0
  Author: Moritz Lenz mor...@faui2k3.org
  Date:   2011-09-23 (Fri, 23 Sep 2011)

  Changed paths:
M S32-setting-library/IO.pod

  Log Message:
  ---
  [S32::IO] all .read methods should return a Buf. This is not C.




r32013 -[S02] spec which methods Nil responds to,

2010-08-16 Thread pugs-commits
Author: lwall
Date: 2010-08-16 19:49:53 +0200 (Mon, 16 Aug 2010)
New Revision: 32013

Modified:
   docs/Perl6/Spec/S02-bits.pod
Log:
[S02] spec which methods Nil responds to,
and that it propagates Nil on unrecognized methods


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2010-08-16 14:30:39 UTC (rev 32012)
+++ docs/Perl6/Spec/S02-bits.pod2010-08-16 17:49:53 UTC (rev 32013)
@@ -14,7 +14,7 @@
 Created: 10 Aug 2004
 
 Last Modified: 16 Aug 2010
-Version: 221
+Version: 222
 
 This document summarizes Apocalypse 2, which covers small-scale
 lexical items and typological issues.  (These Synopses also contain
@@ -2153,14 +2153,23 @@
 you can think of Perl 5 references as a degenerate form of CCapture
 when you want to refer only to a single item.
 
-There is a special CParcel value named CNil.  It means there is no
-value here.  It is the undefined equivalent of the empty C() list, except 
that the
-latter is defined and means there are 0 arguments here.  The CNil value 
returns
-itself if you iterate it or try to get a positional value from it, but
+There is a special CParcel value named CNil.  It means there
+is no value here.  It is the undefined equivalent of the empty
+C() list, except that the latter is defined and means there are
+0 arguments here.  The CNil value returns itself if you iterate
+it or try to get a positional value from it via subscripting, but
 interpolates as a null list into flat context, and an empty CSeq
-into slice context.  Since method calls are performed directly on
-any object, CNil.defined returns CFalse while C().defined returns 
CTrue.
+into slice context.  In either case, a warning is issued.
 
+Since method calls are performed directly on any object, CNil
+can respond to certain method calls.  CNil.defined returns
+CFalse (whereas C().defined returns CTrue).  CNil.so also
+returns CFalse.  CNil.ACCEPTS is always false.  CNil.perl and
+CNil.Str return CNil.  CNil.Stringy returns '' with a warning.
+CNil.Numeric returns 0 with a warning.  Any undefined method call
+on CNil returns CNil, so that CNil propagates down method
+call chains.
+
 Assigning CNil to any scalar container causes the
 container to throw out any contents and restore itself to an
 uninitialized state (after which it will contain a type object



r31680 -[S32/Temporal] Added to Date: There are also Cweek, Cweek-year, Cweek-number, Cweekday-of-month, and Cday-of-year methods, which work just like their DateTime equivalents.

2010-07-14 Thread pugs-commits
Author: Kodi
Date: 2010-07-14 16:35:46 +0200 (Wed, 14 Jul 2010)
New Revision: 31680

Modified:
   docs/Perl6/Spec/S32-setting-library/Temporal.pod
Log:
[S32/Temporal] Added to Date: There are also Cweek, Cweek-year, 
Cweek-number, Cweekday-of-month, and Cday-of-year methods, which work 
just like their DateTime equivalents.

Modified: docs/Perl6/Spec/S32-setting-library/Temporal.pod
===
--- docs/Perl6/Spec/S32-setting-library/Temporal.pod2010-07-14 14:35:21 UTC 
(rev 31679)
+++ docs/Perl6/Spec/S32-setting-library/Temporal.pod2010-07-14 14:35:46 UTC 
(rev 31680)
@@ -16,7 +16,7 @@
 Created: 19 Mar 2009
 
 Last Modified: 14 Jul 2010
-Version: 11
+Version: 12
 
 The document is a draft.
 
@@ -244,6 +244,9 @@
 $d.days-in-month# 31
 $d.Str  # '2010-12-24'
 
+There are also Cweek, Cweek-year, Cweek-number, Cweekday-of-month,
+and Cday-of-year methods, which work just like their DateTime equivalents.
+
 =head2 Arithmetics
 
 $d.succ # Date.new('2010-12-25')



r31598 -[S32/Temporal] Clarified the distinction between time and now, specified what formatters and time zones should actually do, and dropped some formatting methods.

2010-07-09 Thread pugs-commits
Author: Kodi
Date: 2010-07-09 19:43:53 +0200 (Fri, 09 Jul 2010)
New Revision: 31598

Modified:
   docs/Perl6/Spec/S32-setting-library/Temporal.pod
Log:
[S32/Temporal] Clarified the distinction between time and now, specified what 
formatters and time zones should actually do, and dropped some formatting 
methods.

Modified: docs/Perl6/Spec/S32-setting-library/Temporal.pod
===
--- docs/Perl6/Spec/S32-setting-library/Temporal.pod2010-07-09 17:12:58 UTC 
(rev 31597)
+++ docs/Perl6/Spec/S32-setting-library/Temporal.pod2010-07-09 17:43:53 UTC 
(rev 31598)
@@ -48,31 +48,32 @@
 are the aspects of time that are felt to be stable enough to belong in
 the core.
 
+Note that in this document, the term POSIX time means the number of
+seconds since midnight UTC of 1 January 1970, not counting leap seconds.
+This is the same as the output of the ISO C Ctime function except that it
+includes a fractional part.
+
 =head1 Ctime
 
-Returns an CInstant representing the current time as measured in
-atomic seconds since the Unix epoch, suitable for feeding to some of the
-CDateTime constructors.
+Returns the current POSIX time. Use the Cnow function for an
+epoch-agnostic measure of atomic seconds (i.e., an CInstant).
 
 =head1 CDateTime
 
 A CDateTime object describes the time as it would appear on someone's
-calendar and someone's clock. You can create a CDateTime object from
-the CInstant returned by the Ctime function:
+calendar and someone's clock. You can create a CDateTime object from an
+CInstant or from any object that does the CNumeric role; in the latter
+case, the argument is interpreted as POSIX time.
 
-my $now = DateTime.from-epoch(time);
+my $now = DateTime.new(now);
+my $now = DateTime.new(time); # same thing
 
-This is such a common use case, that there's a CDateTime.now
-constructor that does this for you:
+Or you can use named arguments:
 
-my $now = DateTime.now();
-
-General dates can be specified through the Cnew constructor:
-
 my $moonlanding = DateTime.new( :year(1969), :month(7), :day(16),
 :hour(20), :minute(17) ); # UTC time
 
-The full list of named arguments is as follows:
+This form allows the following arguments:
 
 :year   required
 :month  defaults to 1   range 1..12
@@ -80,25 +81,34 @@
 :hour   defaults to 0   range 0..23
 :minute defaults to 0   range 0..59
 :second defaults to 0   range 0.0..^62.0
-:timezone   defaults to '+' (UTC)
-:formatter  defaults to an iso8601 formatter, see below
 
-Another multi exists with CDate :date
-instead of C:year, C:month and C:day (and the same defaults as listed
-above).
+Another multi exists with CDate :date instead of C:year, C:month and
+C:day (and the same defaults as listed above).
 
-A shorter way to send in date and time information to is providing a
-single string with a full ISO8601 date and time. The example from above
+All four of the aforementioned forms of Cnew accept two additional named
+arguments. C:formatter is a callable object that takes a CDateTime and
+returns a string. The default formatter creates an ISO 8601 timestamp (see
+below). C:timezone is a callable object that takes a CDateTime and
+returns a two-element list giving the difference from UTC in (possibly both
+negative, but not of opposite signs) hours and minutes. Alternatively,
+C:timezone can be a two-element CSeq, which is interpreted as a static
+offset from UTC. The default time zone is C(0, 0) (i.e., UTC).
+
+A shorter way to send in date and time information is to provide a
+single string with a full ISO 8601 date and time. The example from above
 would then be
 
 my $moonlanding = DateTime.new( '1969-07-16T20:17:00Z' ); # UTC time
 
-The general form is C[date]T[time][offset], with [date] given
-as C-MM-DD and [time] given as Chh:mm:ss.
+The general form is C[date]T[time][offset], with [date] given as
+C-MM-DD and [time] given as Chh:mm:ss. The final CZ is a short
+form for C+, meaning UTC. (Note that while this form of Cnew
+accepts all of C+, C-, and CZ, the default formatter for
+CDateTime always expresses UTC as CZ.) The general notation for the C
+offset  is C+hhmm or C-hhmm. As before, a C:formatter argument is
+permitted. The C:timezone, if not supplied, is assumed to be a static
+offset equal to the offset in the given timestamp.
 
-The final CZ is a short form for C+, meaning UTC time. The
-general notation for the C offset  is C+hhmm or C-hhmm.
-
 With all the above constructors, if you attempt to pass in values that
 are outside of the ranges specified in the list above, you'll get an
 exception.  An exception will also be thrown if the particular day
@@ -107,12 +117,19 @@
 done against leap seconds. This class also explicitly does not check
 against ambiguous or invalid local times caused by Daylight Saving Time.
 
+There's one additional

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 :)



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: 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: Aliasing methods in CPAN roles

2009-10-19 Thread Raphael Descamps
Am Freitag, den 16.10.2009, 10:54 +0400 schrieb Richard Hainsworth:
 Arising out of Freezing Roles is a related question.
 
 Suppose I download a module from CPAN with a role I want to use, but it 
 introduces a method that I want that is in conflict with an existing 
 method (say one taken from another CPAN module).
 
 How should the method be aliased to prevent it from causing a conflict 
 at class composition time?

I personally don't anderstand 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.

In the thread Re: YAPC::EU and Perl 6 Roles in last july I already
said the following:
---snipp---
 The brilliant idea with traits is that it bring back the control to
 the class consuming the trait and conflicts have to be solved
 explicitly. The traits paper propose 3 different operators to solve
 such conflicts: overriding, excluding or aliasing.
 
 I definitively think that perl 6 roles should also have an excluding
 operator because I think that *every* composition conflicts arrising
 should be solvable by the class comsuming the role.
---snapp---

As a side note, Johnatan give us a example about how to make an alias
with user defined traits, but it doesn't help here because a trait is
bound to a definition:
http://use.perl.org/~JonathanWorthington/journal/39504
My anderstanding is also that that kind of aliasing as defined with a
trait is deep: If you alias a recursive method, the call will be done
to the aliased one (or am I wrong?).
In the original traits paper the aliasing is not deep: to respect the
flattening property, the semantic of the role must not change, so
aliasing a recursive method will call the original method. It's a known
theoretical weakness of the traits paper and freezing roles try to
solve this problem.

Finally, the interaction between module and role is also interesting and
it's not clear to me how Perl 6 solve it: I send a question this August
to the mailinglist but sadly had no reply, see Perl 6 modules and
classboxes?:
---snipp---
As Perl 6 will be supporting multiple versions installed of the same
module and also support import with lexical scoping, I was asking myself
if it was possible to combine some of the interresting properties of
classboxes like local rebinding, flattening property and the idea that
import takes precedence over inheritance.

I am absolutly not sure if it fit to the Perl 6 module concept as a
whole, but I will be happy to read your comments and what you think
about it.

A few pointers:

classboxes+traits introduction:
http://scg.unibe.ch/archive/papers/Berg05dTraitsClassbox.pdf

For an in depth description, you can also read the Ph.D. thesis:
http://scg.unibe.ch/archive/phd/bergel-phd.pdf

To develop the classbox concept, the autors also introduced a module
calculus, which also help to describe the difference existing beetween
different modules systems: (such a module calculus can also help to
better anderstand the interaction beetween different languages): 
http://scg.unibe.ch/archive/papers/Berg05cModuleDiversity.pdf
---snapp---

Raphael




Re: Aliasing methods in CPAN roles

2009-10-19 Thread David Green

On 2009-Oct-18, at 3:44 pm, Jon Lang wrote:

David Green wrote:

I would expect that   role Logging { method log(Numeric $x:) {...} }
means the invocant is really of type Numeric  Logging, without  
Logging having to do Numeric.  On the other hand, I can see that  
strictly that might not make sense, so perhaps I really do need to  
create a compound NumLog type first, so I can have method  
log(NumLog:)?

I think you should need to do this.


That's cumbersome, though.  I don't want to create some new type, that  
happens to do Numeric and Logging (in addition to other stuff it might  
do); I want to affect everything else that does both roles.  That is,  
I don't want my special log() method to work only for other types that  
explicitly do NumLog; I want it to work for any type that directly  
does Numeric does Logging.


In fact, I can already refer to that combination without needing to  
create a compound type; for example, in a signature I can say  
(Numeric Logging $x:).  I want my log() method to apply to $x there,  
even though it's Numeric Logging and not NumLog.


I don't like dangling methods outside of any role though, either.   
What I want to be able to do is say:

role Logging { method log(Numeric $x:) {...} }

and have it treat the invocant as something that does Logging  
(naturally, since it's part of the Logging role), and that also does  
Numeric (as specified in the sig).  It's too reasonable a thing to do  
not to have a reasonable way to express it.


Of course, I could do something like this:
role Logging
{
method log
{
given self
{
when Numeric {...}
when Stringy {...}
etc.
}
}
}

that is, I can do the dispatching myself.  But I shouldn't have to,  
especially in cases that are more complex than this simple example.



(But I'll suggest something new for - in general: what if $x -  
Numeric with no $n variable were shorthand for $x - Numeric $x  
is rw, i.e. a shorthand that used the same variable name inside  
the block as the one being passed in?  That would be useful in  
cases like this where we don't particularly want to rename $x.)


It wouldn't always be workable; for instance, @a - Numeric,  
Stringy { ... } would grab the first two element of @a and would put  
them into parameters; but there would be no obvious names to assign  
to those

parameters.


Yes, and I think it's OK for a shortcut like that to be available only  
in simple cases.



-David



Re: Aliasing methods in CPAN roles

2009-10-19 Thread 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.

Take Stringy as an example: when a class says does Stringy, it's
making certain promises about its syntax and semantics: e.g., it will
have a method say, and method say should result in sending a
string of text to an output stream.  Thus, any routine that asks for
Stringy $x as one of its parameters should be able to put $x.say
in its code and get the expected results.

But if Foo does Stringy but excludes or aliases .say, a routine that
asks for a Stringy $x but receives a Foo $x will run into problems the
moment $x.say shows up in its code.  If .say was excluded, the
semantics are no longer available at all.  If it was aliased, the
semantics are still available under another name; but that does the
routine no good, because it has no idea what the new name is, or even
that it exists.  Either way, $x.say will not do what the routine
intended it to do.  The interface is broken.

--
Jonathan Dataweaver Lang


Re: Aliasing methods in CPAN roles

2009-10-19 Thread Jon Lang
Raphael Descamps wrote:
 In the original traits paper the aliasing is not deep: to respect the
 flattening property, the semantic of the role must not change, so
 aliasing a recursive method will call the original method. It's a known
 theoretical weakness of the traits paper and freezing roles try to
 solve this problem.

It's a problem that doesn't exist if you don't alias.  However, you
run into another problem; namely, what to do if two roles provide
semantically incompatible definitions for the same method.  To be
fair, ailasing doesn't solve the problem either, for the reasons that
I outlined in my last post (i.e., aliasing breaks the interface).  And
freezing roles doesn't solve the problem either; it just specifies
which role is broken in the combined interface.  As far as I can tell,
there are only two solutions that actually solve the problem: don't
compose two roles that have incompatible methods, or find a way for
the incompatible definitions to coexist under the same name.

The former approach works off of the theory that if the names are the
same, the semantics ought to be compatible; and thus incompatible
semantics are a sign of poor design of the base roles.  In an
environment where the programmer has the ability to rewrite everything
with which he's dealing, this makes a great deal of sense.  But as
Richard pointed out, CPAN is a counterexample to this: it is
unreasonable to assume that two modules imported from CPAN, written in
isolation by different authors, will never provide conflicting roles
due to nothing more than conflicting naming conventions - roles that,
in concept, ought to be able to be used together.

As I understand things, Richard's proposed solution is to alias one of
the offending methods during the import, effectively rewriting the
source module to use a different name for the offending method, for
the sole purpose of exporting to the target application.  IMHO, this
only works if you follow the chain of compositions all the way and
alias everything.  That is:

   role Foo { method x; }
   role Bar does Foo { method x; }
   role Baz does Foo { method x; }

If you want to alias Bar.x on import, there should be an implicit
aliasing of Foo.x as well, which would lead to the implicit aliasing
of Baz.x too.  It's the only way to avoid broken interfaces: you need
to change all related interfaces to remain compatible with the one
that you change, both up and down the composition chain.  Needless to
say, this strikes me as impractical, due to the effort involved in
figuring out what needs to be aliased and what doesn't.


Another possibility would be to borrow a page from XML Namespaces,
which addressed a similar problem: allow the programmer to require
imported elements to be referenced in terms of the module from which
they were imported.  E.g.:

use Kennel prefix Foo; # imports role Dog
use Forest prefix Bar; # imports role Tree
class Dogwood does Foo-Dog does Bar-Tree  { ... }
my $dogwood is Dogwood;
$dogwood.Foo-bark;
$dogwood.Bar-bark;

The idea here is that prefix Foo and prefix Bar cause every name
that gets imported from that module to be prefixed with that string.
So class Dogwood wouldn't have a bark method: it would have a
Foo-bark method and a Bar-bark method.  IOW, the above would be
equivalent to:

role Foo-Dog { ... method Foo-bark { ... } ... }
role Bar-Tree { ... method Bar-bark { ... } ... }
class Dogwood does Foo-Dog does Bar-Tree  { ... }
my $dogwood is Dogwood;
$dogwood.Foo-bark;
$dogwood.Bar-bark;

-- 
Jonathan Dataweaver Lang


Re: Aliasing methods in CPAN roles

2009-10-18 Thread David Green

On 2009-Oct-17, at 1:55 am, Jon Lang wrote:
This implies that both Logging and Math do Numeric, since the  
invocant ought to be of a type that the class does.


I would expect that
role Logging { method log(Numeric $x:) {...} }
means the invocant is really of type Numeric  Logging, without  
Logging having to do Numeric.  On the other hand, I can see that  
strictly that might not make sense, so perhaps I really do need to  
create a compound NumLog type first, so I can have method log(NumLog:)?


Or can I create a method outside of any role:
role Numeric {...}
role Logging {...}
method log(Numeric Logging $x:) {...}

(of course, that might be implicitly creating an anonymous compound  
type for me...)



I think that what you're actually looking for (for the purpose of  
illustration) is Logging::log:(Numeric $x:) and Numeric::log: 
(Numeric $x:).


Oh, yes!

If $x does Numeric and $x does Logging, then it has a class that has  
already encountered the potential conflict and resolved it in some  
way.  For example:


   class Baz does Numeric does Logging {
   method log(Numeric $x:) {$x.Numeric::log;}
   method log(Logging $x:) {$x.Logging::log;}
   } #`Baz postpones the decision until it knows which role it's  
being asked to play: Numeric or Logging.


Baz illustrates my proposal: if $x is a Baz, it will need to check  
the context to see if it's supposed to be acting like a Numeric or  
like a Logging, and will act accordingly - or it will complain about  
ambiguity if it can't figure out which role to play.  And the  
definition for Baz works because Logging does Numeric.


I suppose given that I want Logging's method log(Numeric Logging:)  
rather than its log(Any Logging:), the second method there should  
really be:

method log(Numeric Logging $x:) {$x.Logging::log;}

You cannot define a class that does Logging and does Numeric without  
defining at least one log method, because they conflict; and a class  
must somehow resolve all such conflicts.


OK; although it seems reasonable to have some sugar for the obvious  
kind of keep them all methods like in this example.  In fact, we  
probably have that already, by declaring a proto log that makes the  
others all work according to their sigs.  And my mistake was thinking  
that you could have the same sig doing different things, but really  
the second sig is log(Numeric Logging:).


(The only way to have the same sig twice would be something like if  
Logging defined a special version of log() for Numeric objects, while  
Numeric defined a special log() for Logging objects -- but  
semantically that ought to mean the same thing in both cases, so we do  
want a single method to handle that.)


In the Baz case, it addresses the matter by making two options  
available according to the role being played: Numeric or Logging.   
All you have to do then is to somehow indicate which role is being  
played.


If you can't tell by the routine's signature, my own preference  
would be to make it explicit by means of a given block:


   given Logging $x { .log } # logs like a Logging
   given Numeric $x { .log } # logs like a Numeric


I also thought given sounded good for this, but it would have to  
work differently from a normal given: if $x doesn't do Logging, then  
it needs to skip the block.  (Also, it looks very close to casting:  
given Logging($x).  Maybe something a bit more visually distinctive  
would be helpful, something like given $x as Logging, etc.?)



But I could see other alternatives:
   .log given Logging $x; # assumes the inclusion of a given  
statement modifier.


I think given, as either a modifier or a block, is the prettiest  
syntax.



   $x - Numeric $n { ... ; $n.log ; ... }


What I like about this is using a sig to apply the context, so no new  
syntax is needed.


(But I'll suggest something new for - in general: what if $x -  
Numeric with no $n variable were shorthand for $x - Numeric $x is  
rw, i.e. a shorthand that used the same variable name inside the  
block as the one being passed in?  That would be useful in cases like  
this where we don't particularly want to rename $x.)



   $x.log:(Logging:);



And I like this way because it's the most compact, inline way to  
indicate it.



-David



Re: Aliasing methods in CPAN roles

2009-10-18 Thread Jon Lang
David Green wrote:
 Jon Lang wrote:

 This implies that both Logging and Math do Numeric, since the invocant
 ought to be of a type that the class does.

 I would expect that
    role Logging { method log(Numeric $x:) {...} }
 means the invocant is really of type Numeric  Logging, without Logging
 having to do Numeric.  On the other hand, I can see that strictly that might
 not make sense, so perhaps I really do need to create a compound NumLog type
 first, so I can have method log(NumLog:)?

I think you should need to do this.

 Or can I create a method outside of any role:
    role Numeric {...}
    role Logging {...}
    method log(Numeric Logging $x:) {...}

 (of course, that might be implicitly creating an anonymous compound type for
 me...)

Last I checked, all methods must be members of a class or role.

 I think that what you're actually looking for (for the purpose of
 illustration) is Logging::log:(Numeric $x:) and Numeric::log:(Numeric $x:).

 Oh, yes!

 If $x does Numeric and $x does Logging, then it has a class that has
 already encountered the potential conflict and resolved it in some way.  For
 example:

   class Baz does Numeric does Logging {
       method log(Numeric $x:) {$x.Numeric::log;}
       method log(Logging $x:) {$x.Logging::log;}
   } #`Baz postpones the decision until it knows which role it's being
 asked to play: Numeric or Logging.

 Baz illustrates my proposal: if $x is a Baz, it will need to check the
 context to see if it's supposed to be acting like a Numeric or like a
 Logging, and will act accordingly - or it will complain about ambiguity if
 it can't figure out which role to play.  And the definition for Baz works
 because Logging does Numeric.

 I suppose given that I want Logging's method log(Numeric Logging:) rather
 than its log(Any Logging:), the second method there should really be:
    method log(Numeric Logging $x:) {$x.Logging::log;}

I suppose that that would work, too.

 (The only way to have the same sig twice would be something like if Logging
 defined a special version of log() for Numeric objects, while Numeric
 defined a special log() for Logging objects -- but semantically that ought
 to mean the same thing in both cases, so we do want a single method to
 handle that.)

And if you limit yourself to referencing types that the method's role
does, this won't be an issue.

 If you can't tell by the routine's signature, my own preference would be
 to make it explicit by means of a given block:

   given Logging $x { .log } # logs like a Logging
   given Numeric $x { .log } # logs like a Numeric

 I also thought given sounded good for this, but it would have to work
 differently from a normal given: if $x doesn't do Logging, then it needs
 to skip the block.  (Also, it looks very close to casting: given
 Logging($x).  Maybe something a bit more visually distinctive would be
 helpful, something like given $x as Logging, etc.?)

IMHO, given $x { ... } is effectively syntactic sugar for $x - $_
{ ... }, and given Numeric $x { ... } would be syntactic sugar for
$x - Numeric $_ { ... }.  If $x doesn't do Numeric, the default
behavior should be a fail.

   $x - Numeric $n { ... ; $n.log ; ... }

 What I like about this is using a sig to apply the context, so no new syntax
 is needed.

 (But I'll suggest something new for - in general: what if $x - Numeric
 with no $n variable were shorthand for $x - Numeric $x is rw, i.e. a
 shorthand that used the same variable name inside the block as the one being
 passed in?  That would be useful in cases like this where we don't
 particularly want to rename $x.)

It wouldn't always be workable; for instance, @a - Numeric, Stringy
{ ... } would grab the first two element of @a and would put them into
parameters; but there would be no obvious names to assign to those
parameters.

-- 
Jonathan Dataweaver Lang


Re: Aliasing methods in CPAN roles

2009-10-17 Thread Jon Lang
David Green wrote:
 Aha, so the bark:(Dog:) syntax identifies the method by its signature as
 well, thus distinguishing it from the .bark:(Tree:) method.  This works fine
 when the sigs can distinguish the invocants, which is very common.  However,
 I could have ambiguous methods even including the signatures.  Suppose I
 have a Logging role that provides a log() method for printing some info
 about a variable.  In particular, I have method log(Numeric $x:) { ... }
 because I want to handle Nums specially (say, round them off before
 printing).  Meanwhile, suppose I also have Math::log(Numeric $x:).

So you have Logging::log:(Numeric $x:), and you have
Math::log:(Numeric $x:).  This implies that both Logging and Math do
Numeric, since the invocant ought to be of a type that the class does.
 (And incidentally, this brings up another issue: as written, Math
isn't a class; it's a module.  Modules generally don't do roles,
assuming that they even can.)

Note further that in the setting, you actually have Math::log:(Numeric
$x).  Modules usually don't have methods, and so their routines
generally don't have invocants.

I think that what you're actually looking for (for the purpose of
illustration) is Logging::log:(Numeric $x:) and Numeric::log:(Numeric
$x:).  Continuing on with that:

 If $x does Numeric and does Logging, then $x.log won't be able to decide
 which method to call, unless maybe it's in a sub like foo(Numeric $x) that
 can know to provide Numeric context to $x.

If $x does Numeric and $x does Logging, then it has a class that has
already encountered the potential conflict and resolved it in some
way.  For example:

class Foo does Numeric does Logging {
method log(Numeric $x:) {$x.Numeric::log;}
} # Foo picks out the method from Numeric.

class Bar does Numeric does Logging {
method log(Numeric $x:) {$x.Logging::log;}
} # Bar picks out the method from Logging.

class Baz does Numeric does Logging {
method log(Numeric $x:) {$x.Numeric::log;}
method log(Logging $x:) {$x.Logging::log;}
} #`Baz postpones the decision until it knows which role it's
being asked to play: Numeric or Logging.

If $x is a Foo, then $x.log will always behave like Numeric::log; if
$x is a Bar, then $x.log will always behave like Logging::log.

Baz illustrates my proposal: if $x is a Baz, it will need to check the
context to see if it's supposed to be acting like a Numeric or like a
Logging, and will act accordingly - or it will complain about
ambiguity if it can't figure out which role to play.  And the
definition for Baz works because Logging does Numeric.

You cannot define a class that does Logging and does Numeric without
defining at least one log method, because they conflict; and a class
must somehow resolve all such conflicts.

 Outside foo, or inside a sub
 like bar(Any $x), I need some other way to indicate which log method I
 mean.  $x.log:(Numeric:) won't work here, because both roles provide a
 method with that name and signature.

As I indicated above, it will work, because $x.WHAT will have
addressed the matter already.  In the Foo and Bar cases, it addresses
the matter by picking one or the other and preventing access to the
one it doesn't pick; this is a viable stratagem if Logging and Numeric
are semantically similar (and, seeing as how Logging does Numeric,
they probably are).  In the Baz case, it addresses the matter by
making two options available according to the role being played:
Numeric or Logging.  All you have to do then is to somehow indicate
which role is being played.

If you can't tell by the routine's signature, my own preference would
be to make it explicit by means of a given block:

given Logging $x { .log } # logs like a Logging
given Numeric $x { .log } # logs like a Numeric

But I could see other alternatives:

.log given Logging $x; # assumes the inclusion of a given
statement modifier.
$x - Numeric $n { ... ; $n.log ; ... }
$x.log:(Logging:);

The point is that you're never going to have two different
log:(Numeric:) methods in the same class.

-- 
Jonathan Dataweaver Lang


Re: Freezing role methods

2009-10-16 Thread Richard Hainsworth

Ovid wrote:

At the BBC, we never encounter this because semantically different methods are 
renamed and semantically identical methods are refactored (aliasing and 
excluding being code smells).  However, if roles start making their way on to 
the CPAN, you won't necessarily have control over the source code, forcing you 
to fork or simply not use the role in question.  Regrettably, that defeats the 
purpose of roles -- namely, to facilitate code reuse.
  
Taking this idea further. If roles make their way to CPAN, and code 
reuse becomes practical, aliasing and excluding are no longer code 
smells, but appropriate ways of filtering what is wanted from generic code.




Re: Aliasing methods in CPAN roles

2009-10-16 Thread David Green

On 2009-Oct-16, at 12:54 am, Richard Hainsworth wrote:
Is there syntactic sugar for aliasing the conflicting method? Eg.  
something like

does XML :db-writexml-db-write;


There needs to be something more than sugar: making a new class or  
role with different methods will break substitutability.  However, we  
could have a feature which aliases a method name in a given scope or  
context; elsewhere, the original name would still be visible.  So you  
could pass your new XML-plus-SQL object to do-xml-stuff(XML $x) and it  
would know to treat it as an XML object with the proper .db-write  
method.


(Incidentally, we could use something similar for renaming imported  
symbols, though in that case it would be only sugar.  Currently, we  
can choose to import something or not, but if a module exports  
something, it presumably has a good reason; rather than simply not  
importing the sub/etc., it would be handy to be able to import it  
under another name.


use Bar foo;# import Bar::foo
use Baz :fooboo;# import Baz::foo as boo()
use Baz foo='boo';   #  or spelled this way
)


Moreover, suppose that the two modules have roles with the same  
name, eg., suppose XML-Database-Module and SQL-Database both define  
a role 'Writable'. How could these one (or both) of these roles be  
aliased?



I suppose the polite thing would be for them to define roles (or  
anything else) inside their own namespaces: XML-Database- 
Module::Writable.



Meanwhile, on 2009-Oct-14, at 7:58 pm, Jon Lang wrote:
Another clarification: there's a subtle but important difference  
between $dogwood.bark:(Dog:).() and $dogwood.Dog::bark().  The  
former calls a Dogwood method that has an invocant that does Dog;  
the latter calls a Dog method.  That is:


   $dogwood.bark:(Dog:).(); # calls Dogwood::bark:(Dog:)
   $dogwood.Dog::bark();# calls Dog::bark:()


Aha, so the bark:(Dog:) syntax identifies the method by its signature  
as well, thus distinguishing it from the .bark:(Tree:) method.  This  
works fine when the sigs can distinguish the invocants, which is very  
common.  However, I could have ambiguous methods even including the  
signatures.  Suppose I have a Logging role that provides a log()  
method for printing some info about a variable.  In particular, I have  
method log(Numeric $x:) { ... } because I want to handle Nums  
specially (say, round them off before printing).  Meanwhile, suppose I  
also have Math::log(Numeric $x:).


If $x does Numeric and does Logging, then $x.log won't be able to  
decide which method to call, unless maybe it's in a sub like  
foo(Numeric $x) that can know to provide Numeric context to $x.   
Outside foo, or inside a sub like bar(Any $x), I need some other way  
to indicate which log method I mean.  $x.log:(Numeric:) won't work  
here, because both roles provide a method with that name and signature.


What if all roles' methods got automatic aliases, to a long(er) name,  
e.g. the .log method could be referred to as such, or  
as .Logging`log()?  That at least would provide a fully-qualified way  
to refer to methods no matter where they came from originally, and  
also allow short names to be used where unambiguous.


(I guess this parallels what we already have for subs, etc., except  
methods would be automatically exported into new roles or classes so  
that we can use short names.  I don't know what the actual syntax  
should be -- I only used ` above for lack of anything better, since  
the obvious .Logging::log means something else.)



-David



Re: Freezing role methods

2009-10-15 Thread Richard Hainsworth

Ovid wrote:

I recently was trying to research some composition issues with roles and one of 
the researchers directed me to this paper:

http://scg.unibe.ch/archive/papers/Duca07b-FreezableTrait.pdf

Basically, the problem they have is this T1 (Trait 1) and T2 each implement a public x() 
method and other methods in T1 and T2 rely on their respective versions of x() and trying to rely on another version breaks those 
methods. When class C tries to compose these roles, it has a problem.  It can't exclude one x() because 
that breaks the role which needs the excluded x().  It can't override x() because you'll likely break both roles.  You *could* 
(this wasn't explained in the paper) extract those methods into C::x(), check your callers and dispatch as appropriate, but that 
would get very problematic, particularly with roles composed of other roles.
snip
How would Perl 6 approach this issue?
  

S14 states:
Roles may be composed into a class at compile time, in which case you 
get automatic detection of conflicting methods. A role may also be mixed 
into a class or object at run time to produce an anonymous derived class 
with extra capabilities, but in this case conflicting methods are 
overridden by the new role silently. In either case, a class is 
necessary for instantiation--a role may not be directly instantiated.


This indicates to me that for perl6 the conflict is detected and 
reported to the programmer to resolve. The compiler is not required to 
resolve the conflict.


Later S14 has:
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 proto stub in the class being constructed:


   proto method shake {...}



Am I wrong in thinking the spec answers the question?



Re: Freezing role methods

2009-10-15 Thread Ovid
--- On Thu, 15/10/09, Richard Hainsworth rich...@rusrating.ru wrote:

 From: Richard Hainsworth rich...@rusrating.ru
  Basically, the problem they have is this T1 (Trait
 1) and T2 each implement a public x() method and other
 methods in T1 and T2 rely on their respective versions of
 x() and trying to rely on another version breaks those
 methods. When class C tries to compose these roles, it has
 a problem.  It can't exclude one x() because that
 breaks the role which needs the excluded x().  It can't
 override x() because you'll likely break both roles. 
 You *could* (this wasn't explained in the paper) extract
 those methods into C::x(), check your callers and dispatch
 as appropriate, but that would get very problematic,
 particularly with roles composed of other roles.
  snip
  How would Perl 6 approach this issue?
    
 S14 states:
 Roles may be composed into a class at compile time, in
 which case you get automatic detection of conflicting
 methods. A role may also be mixed into a class or object at
 run time to produce an anonymous derived class with extra
 capabilities, but in this case conflicting methods are
 overridden by the new role silently. In either case, a class
 is necessary for instantiation--a role may not be directly
 instantiated.
 
 This indicates to me that for perl6 the conflict is
 detected and reported to the programmer to resolve. The
 compiler is not required to resolve the conflict.
 
 Later S14 has:
 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.
snip
 Am I wrong in thinking the spec answers the question?

Reading the paper I linked to could help to clarify the issue.  In short, there 
are times under my current understanding of roles where you *can't* resolve the 
conflicts.  Two roles, each providing and dependent upon a method x(), such 
that if either tries to use the other's x(), the code will fail. Thus, you 
cannot choose one x() over the other.

frozen traits suggests that the composing class determine which x() it wants 
and statically binding the other x() to its role, thus guaranteeing that no 
role can get the wrong x(), but still allowing classes full control over their 
composition.

I need to read the other responses more closely to understand their reasoning.  
So far, they seem wrong to me, but that's probably because I'm not reading them 
closely enough.

Cheers,
Ovid
--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Tech blog- http://use.perl.org/~Ovid/journal/
Twitter  - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6



Re: Freezing role methods

2009-10-15 Thread Matthew Walton
On Thu, Oct 15, 2009 at 10:07 AM, Ovid
publiustemp-perl6langua...@yahoo.com wrote:
 Reading the paper I linked to could help to clarify the issue.  In short, 
 there are times under my current understanding of roles where you *can't* 
 resolve the conflicts.  Two roles, each providing and dependent upon a method 
 x(), such that if either tries to use the other's x(), the code will fail. 
 Thus, you cannot choose one x() over the other.

 frozen traits suggests that the composing class determine which x() it 
 wants and statically binding the other x() to its role, thus guaranteeing 
 that no role can get the wrong x(), but still allowing classes full control 
 over their composition.

 I need to read the other responses more closely to understand their 
 reasoning.  So far, they seem wrong to me, but that's probably because I'm 
 not reading them closely enough.

What if there are genuinely situations when you cannot combine two
roles into the same class? Do all combinations have to be possible? As
TSa said, a role depending on one of its own public methods is asking
for trouble when it gets combined with something else with a
conflicting method, so perhaps what we should really be thinking about
is how to write well-behaved roles.


Re: Freezing role methods

2009-10-15 Thread Richard Hainsworth

Ovid wrote:

--- On Thu, 15/10/09, Richard Hainsworth rich...@rusrating.ru wrote:
  

Later S14 has:
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.


snip
  

Am I wrong in thinking the spec answers the question?


Reading the paper I linked to could help to clarify the issue.  In short, there are times 
under my current understanding of roles where you *can't* resolve the conflicts.  Two 
roles, each providing and dependent upon a method x(), such that if either tries to use 
the other's x(), the code will fail. Thus, you cannot choose one x() over the 
other.
  

The paper you linked to states:
2.2 Trait conflict resolution limits
While trait composition lets the class composer resolve conflicts by 
redefining in the composer or ...


The paper explains how conflicts arise and they are detected because 
fundamentally different methods have the same name.


But the assumption in the paper is that the class composer resolves 
the conflict, without further programmer intervention. The perl6 spec 
does not require the class composer to resolve the conflict only to 
detect it.


Given the explanation in the spec about conflict resolution, it is my 
understanding that it is

the programmer's task to rewrite to eliminate the conflict.



Re: Freezing role methods

2009-10-15 Thread Ovid
--- On Thu, 15/10/09, Richard Hainsworth rich...@rusrating.ru wrote:

 From: Richard Hainsworth rich...@rusrating.ru

 But the assumption in the paper is that the class
 composer resolves the conflict, without further programmer
 intervention. The perl6 spec does not require the class
 composer to resolve the conflict only to detect it.
 
 Given the explanation in the spec about conflict
 resolution, it is my understanding that it is
 the programmer's task to rewrite to eliminate the
 conflict.

Ugh. That's ambiguity in the paper.  Thanks for pointing that out. The specific 
intention is that the programmer has to specifically address this issue (in 
this case, by potentially freezing one or more methods).

At the BBC, we never encounter this because semantically different methods are 
renamed and semantically identical methods are refactored (aliasing and 
excluding being code smells).  However, if roles start making their way on to 
the CPAN, you won't necessarily have control over the source code, forcing you 
to fork or simply not use the role in question.  Regrettably, that defeats the 
purpose of roles -- namely, to facilitate code reuse.

Cheers,
Ovid
--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Tech blog- http://use.perl.org/~Ovid/journal/
Twitter  - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6



Freezing role methods

2009-10-14 Thread Ovid
I recently was trying to research some composition issues with roles and one of 
the researchers directed me to this paper:

http://scg.unibe.ch/archive/papers/Duca07b-FreezableTrait.pdf

Basically, the problem they have is this T1 (Trait 1) and T2 each implement 
a public x() method and other methods in T1 and T2 rely on their respective 
versions of x() and trying to rely on another version breaks those methods. 
When class C tries to compose these roles, it has a problem.  It can't 
exclude one x() because that breaks the role which needs the excluded x().  
It can't override x() because you'll likely break both roles.  You *could* 
(this wasn't explained in the paper) extract those methods into C::x(), check 
your callers and dispatch as appropriate, but that would get very problematic, 
particularly with roles composed of other roles.

The only way to handle this appears to be renaming one of the x() methods and 
trying to track down all code which relies on it and changing it.  This 
essentially violates the problem we're trying to solve with traits, er, roles.

In short, under the original traits model, you have roles you can't compose 
together.  The paper argues that in languages which have public and private 
methods, that the composing class is allowed to decide which x() method it 
needs (if any) and that it can *freeze* the other x() method.  That is to say, 
the x() in question would become private and statically bound to the invocants 
to ensure that they're always calling the correct x().

How would Perl 6 approach this issue?

Cheers,
Ovid
--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Tech blog- http://use.perl.org/~Ovid/journal/
Twitter  - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6


Re: Freezing role methods

2009-10-14 Thread Jon Lang
Ovid wrote:
 The only way to handle this appears to be renaming one of the x()
 methods and trying to track down all code which relies on it and
 changing it.  This essentially violates the problem we're trying to
 solve with traits, er, roles.

 In short, under the original traits model, you have roles you can't
 compose together.  The paper argues that in languages which have
 public and private methods, that the composing class is allowed to
 decide which x() method it needs (if any) and that it can *freeze* the
 other x() method.  That is to say, the x() in question would become
 private and statically bound to the invocants to ensure that they're
 always calling the correct x().

 How would Perl 6 approach this issue?

The fundamental problem is that there are times when you need both
versions of a given method to be available, but you don't want to
rename either of them.  This leads to a namespace clash.

The initial possibility that springs to mind would be to use longnames
to disambiguate between the two options - specifically, by means of
the invocant:

role T1 { method foo() }
role T2 { method foo() }
class C does T1 does T2 {
method foo(T1 $self:) { $self.T1::foo() }
method foo(T2 $self:) { $self.T2::foo() }
}

...or something to that effect.  You'd still have a disambiguation
issue, in that you'd somehow need to specify which hat an object of
class C is wearing when you try to call the method.  (I like this
approach because it requires you to explicitly identify that the class
is deferring the disambiguation, rather than having it silently occur
behind the scenes.)

Much of this could be handled implicitly, by means of which role was
requested when the object was passed into the current block:

sub bar (T1 $x) { ... }
sub baz (T2 $x) { ... }
my C $x;

bar $x;

Since bar is expecting an object that does T1, code within bar
should resolve the ambiguity involving foo in favor of foo:(T1:) -
that is, within the lexical scope of sub bar, $x is wearing its T1
hat.  Ditto with baz and T2.

In other cases, there may be no way to implicitly disambiguate.  In
those cases, there would need to be an explicit way to decide which
hat the object is wearing.  My gut instinct would be to use the same
syntax as is used to coerce an object into a particular class, but
with a role name instead of a class name.  It differs from coercion in
that it wouldn't actually change the underlying object; all it would
do would be to decide which role to favor when resolving disputes of
this sort.

In short, resolve the dilemma by allowing the class the option of
deferring the disambiguation until the method is called, and then to
try to resolve it first by means of the overall context in which the
call is made.

This Schrodinger's method approach doesn't fix everything; but I
suspect that it should usefully handle the majority of problems that
arise.

--
Jonathan Dataweaver Lang


Re: Freezing role methods

2009-10-14 Thread Ovid
--- On Wed, 14/10/09, Jon Lang datawea...@gmail.com wrote:

 From: Jon Lang datawea...@gmail.com

 The initial possibility that springs to mind would be to
 use longnames
 to disambiguate between the two options - specifically, by
 means of
 the invocant:
 
     role T1 { method foo() }
     role T2 { method foo() }
     class C does T1 does T2 {
         method foo(T1 $self:) {
 $self.T1::foo() }
         method foo(T2 $self:) {
 $self.T2::foo() }
     }
 
 ...or something to that effect.  You'd still have a
 disambiguation
 issue, in that you'd somehow need to specify which hat an
 object of
 class C is wearing when you try to call the method. 

Except that if a consumer of C needs foo(), they have to fully qualify the call 
to foo().  That violates encapsulation.
 
 Much of this could be handled implicitly, by means of which
 role was
 requested when the object was passed into the current
 block:
 
     sub bar (T1 $x) { ... }
     sub baz (T2 $x) { ... }
     my C $x;
 
     bar $x;

Same problem as above.  Works for C, but not for consumers of C which need to 
call foo().

 In other cases, there may be no way to implicitly
 disambiguate.  In
 those cases, there would need to be an explicit way to
 decide which
 hat the object is wearing.

I really don't think that deferring the decision works.  The freezing 
technique described in the paper allows the consumer, C, to statically bind the 
method foo() in the methods in the appropriate role which call it.  Dynamic 
binding defers the decision which causes implementation details to leak to 
consumers of C.  This means that if you change your roles, your consumers will 
potentially need to be rewritten.

Cheers,
Ovid
--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Tech blog- http://use.perl.org/~Ovid/journal/
Twitter  - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6


Re: Freezing role methods

2009-10-14 Thread David Green

On 2009-Oct-14, at 8:52 am, Ovid wrote:

--- On Wed, 14/10/09, Jon Lang datawea...@gmail.com wrote:
The initial possibility that springs to mind would be to use  
longnames to disambiguate between the two options - specifically,  
by means of the invocant:
...or something to that effect.  You'd still have a disambiguation  
issue, in that you'd somehow need to specify which hat an object  
of class C is wearing when you try to call the method.


Good, that's what I was looking for the last time this came up.  (http://www.nntp.perl.org/group/perl.perl6.language/2009/07/msg32164.html 
)


Except that if a consumer of C needs foo(), they have to fully  
qualify the call to foo().  That violates encapsulation.


I don't see that as an encapsulation problem.  A leaky encapsulation  
means we have to know how something works, but when I have to  
distinguish between $dogwood.Dog::bark and $dogwood.Tree::bark, I'm  
distinguishing between two wholly unrelated actions (that they happen  
to have some of the same letters in their names is completely  
coincidental).  So I have to know *what* a Dogwood object does; but I  
still don't have to know how it does it.


Or to look at it the other way around:  Since we refer to things by  
name, those names have to be unique everywhere; so let's start out  
with long, fully-qualified names everywhere: $dog.Dog::bark(),  
$tree.Tree::bark(), $i.Int::succ, etc.  Now everything's fine --  
except that our fingers are getting tired from all that typing.  We  
want to use shortcuts to say things like $dog.bark, because there's  
only one place that $dog can legitimately find a bark() method, and  
that's in the Dog class, so both we and Perl can easily figure out  
what is meant.


On the other hand, $dogwood.Dog::bark cannot be simplified by leaving  
out the Dog:: because then it would be ambiguous.  But if we look at  
it as starting with full names everywhere, and seeing what we can  
leave out (rather that starting with short names and having to add  
stuff in), I think it's not surprising.



In other cases, there may be no way to implicitly disambiguate.  In  
those cases, there would need to be an explicit way to decide which  
hat the object is wearing.


I really don't think that deferring the decision works.  The  
freezing technique described in the paper allows the consumer, C,  
to statically bind the method foo() in the methods in the  
appropriate role which call it.


The problem with freezing some methods into private ones is that  
those methods weren't meant to be private; if my role provides a .bark  
method, I need to be able to call it.


Dynamic binding defers the decision which causes implementation  
details to leak to consumers of C.  This means that if you change  
your roles, your consumers will potentially need to be rewritten.


But if you merely change the implementation of how bark() works  
(either one), nothing needs to be rewritten.  If you want to change  
from Tree::bark-ing to Dog::bark-ing, then you *should* be rewriting  
code, because you're completely changing what is going on, no less  
than if you changed from bark()ing to fetch()ing.



-David



Re: Freezing role methods

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

On Wednesday, 14. October 2009 12:18:30 Ovid wrote:
 You *could* (this wasn't explained in the paper) extract those
 methods into C::x(), check your callers and dispatch as appropriate, but
 that would get very problematic, particularly with roles composed of other
 roles.

I consider the dependence of T1 and T2 on their respective public
method implementation a design flaw of these methods. They should
each have a private service routine that in turn is called by the
public x method. But here is how this can be worked around in C:

  role T1
  {
 method foo { self.x }
 method x { say T1 }
  }
  role T2
  {
 method bar { self.x }
 method x { say T2 }
  }
  class C does T1 does T2
  {
 enum Source other from_foo from_bar
 has Source $!source = other;

 method foo { self!source = from_foo; T1::foo }
 method bar { self!source = from_bar; T2::bar }
 method x
 {
given self!source
{
   when from_foo { T1::x; self!source = other }
   when from_bar { T2::x; self!source = other }
   default { say C }
}
 }
   }

I admit that this is clumsy. So we need an automatic procedure
and some nice syntax. But it looks to me as code analysis of T1
and T2 is needed to generate the wrappers in C.

One point I don't like in the paper is that freezing methods
can be used to erase methods from a role. This is diametrically
opposed to the intent of roles to make a guaranty to provide
an interface.


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


Re: Freezing role methods

2009-10-14 Thread Jon Lang
David Green wrote:
 Or to look at it the other way around:  Since we refer to things by name,
 those names have to be unique everywhere; so let's start out with long,
 fully-qualified names everywhere: $dog.Dog::bark(), $tree.Tree::bark(),
 $i.Int::succ, etc.  Now everything's fine -- except that our fingers are
 getting tired from all that typing.  We want to use shortcuts to say things
 like $dog.bark, because there's only one place that $dog can legitimately
 find a bark() method, and that's in the Dog class, so both we and Perl can
 easily figure out what is meant.

 On the other hand, $dogwood.Dog::bark cannot be simplified by leaving out
 the Dog:: because then it would be ambiguous.  But if we look at it as
 starting with full names everywhere, and seeing what we can leave out
 (rather that starting with short names and having to add stuff in), I think
 it's not surprising.

On the gripping hand, if we have a function train(Dog $d), then we
can safely assume that within the lexical scope of train, $d is
supposed to be treated as a Dog.  So within that lexical scope, it
should be safe to leave off the Dog::.  If you pass $dogwood into
this method, the ambiguity between Dog::bark and Tree::bark gets
resolved in favor of the former; so $d.bark _still_ barks like a Dog,
even though $d is actually a Dogwood.  That's what I was meaning when
I talked about wearing hats: while it's within the train() sub,
$dogwood is wearing its Dog hat and barks like a Dog.

 I really don't think that deferring the decision works.  The freezing
 technique described in the paper allows the consumer, C, to statically bind
 the method foo() in the methods in the appropriate role which call it.

 The problem with freezing some methods into private ones is that those
 methods weren't meant to be private; if my role provides a .bark method, I
 need to be able to call it.

And more to the point, subs that aren't expecting a Dogwood should
still be able to accept it in its role as a Dog, call .bark, and
expect it to bark like a Dog.

-- 
Jonathan Dataweaver Lang


Re: Freezing role methods

2009-10-14 Thread David Green

On 2009-Oct-14, at 2:00 pm, Jon Lang wrote:

David Green wrote:
On the other hand, $dogwood.Dog::bark cannot be simplified by  
leaving out the Dog:: because then it would be ambiguous.


On the gripping hand, if we have a function train(Dog $d), then we  
can safely assume that within the lexical scope of train, $d is  
supposed to be treated as a Dog.  So within that lexical scope, it  
should be safe to leave off the Dog::.


Yes; and then my question from last time is whether the sig (Dog $d)  
soft-casts the arg such that the non-doggy bits of $d still remain,  
e.g. if inside train() we call a function chop(Tree $t), chop() will  
unambiguously see the Tree-half of the original Dogwood object.  Or  
will it be hard-cast such that the non-doggy bits are simply lost?   
(And if so, does an ordinary cast Foo($d) do the same thing, or is one  
hard and one soft, etc.?)


The soft way -- being able to cast $dogwood as a Dog and treat it  
unambiguously so, then to do the same thing treating it as a Tree  
object -- is the most flexible.  Split-personality Dogs may be rare,  
but I can imagine wanting to call common  utility roles (e.g. Logging)  
from any point down a calling chain.


However, I expect that my Dog $d = $dogwood would strip out  
everything else, on the grounds that you explicitly requested a pure  
Dog object.  Otherwise you could have said my $d = Dog($dogwood) or  
maybe my $dogwood.^WHAT $d = $dogwood instead.



-David



Re: Freezing role methods

2009-10-14 Thread Eirik Berg Hanssen
David Green david.gr...@telus.net writes:

 The soft way -- being able to cast $dogwood as a Dog and treat it
 unambiguously so, then to do the same thing treating it as a Tree
 object -- is the most flexible.  Split-personality Dogs may be rare,
 but I can imagine wanting to call common  utility roles (e.g. Logging)
 from any point down a calling chain.

  It may be the time of day, but I imagine the Tree type may have
something to say about Logging.


Eirik, logging off
-- 
Ever heard of .cshrc?
That's a city in Bosnia.  Right?
(Discussion in comp.os.linux.misc on the intuitiveness of commands.)


Re: Freezing role methods

2009-10-14 Thread Jon Lang
David Green wrote:
 Jon Lang wrote:
 David Green wrote:
 On the other hand, $dogwood.Dog::bark cannot be simplified by leaving out
 the Dog:: because then it would be ambiguous.

 On the gripping hand, if we have a function train(Dog $d), then we can
 safely assume that within the lexical scope of train, $d is supposed to be
 treated as a Dog.  So within that lexical scope, it should be safe to leave
 off the Dog::.

 Yes; and then my question from last time is whether the sig (Dog $d)
 soft-casts the arg such that the non-doggy bits of $d still remain, e.g.
 if inside train() we call a function chop(Tree $t), chop() will
 unambiguously see the Tree-half of the original Dogwood object.  Or will it
 be hard-cast such that the non-doggy bits are simply lost?  (And if so,
 does an ordinary cast Foo($d) do the same thing, or is one hard and one
 soft, etc.?)

Here, we need a bit of a clarification: are we talking roles or
classes?  Real example: Numeric is a role; Num is a class.  Both can
be used in signatures; but only classes can be used to create objects.
 That is, my Num $x; works; but my Numeric $x; doesn't.  As such,
you cannot coerce an object to a role; you can only coerce it to a
class that does that role.

And when passing parameters, you don't coerce the object at all.  You
smart-match the prospective object against the criteria provided by
the signature to determine whether or not it's acceptable.

...which is a long-winded way of saying that it would be like a soft
cast: all of the object's capabilities remain intact after being
passed as a parameter; the only thing that would change would be that
the lexical scope inside the routine would show a preference for the
Dog-like features of the object.  If you asked for a Dog, it's
reasonable to assume that you were given a Dog.

And the way I see it working, this preference would only show up in
one very specific circumstance: namely, when the object in question
has multiple methods that are distinguished from each other by their
invocant types.  When in a lexical scope that shows a preference for
$dogwood to play the role of a Dog, a call to $dogwood.bark() would
result in MMD looking at bark:(Dog $dogwood:) and bark:(Tree
$dogwood:) and choosing the former.  When in a lexical scope where the
preference is for $dogwood as a Tree, it would resolve the decision in
favor of the latter.  And if neither or both are preferred roles for
$dogwood, it would fail on account of too much ambiguity.

Another clarification: there's a subtle but important difference
between $dogwood.bark:(Dog:).() and $dogwood.Dog::bark().  The
former calls a Dogwood method that has an invocant that does Dog; the
latter calls a Dog method.  That is:

$dogwood.bark:(Dog:).(); # calls Dogwood::bark:(Dog:)
$dogwood.Dog::bark();# calls Dog::bark:()

And because of the flattening nature of role composition, the latter
doesn't work: after you have composed Dog and Tree into Dogwood,
objects that are based on Dogwood no longer have access to the methods
provided by Dog or Tree; they only have access to the methods that
Dogwood provides.  (Caveat: if Dogwood doesn't explicitly provide a
method corresponding to something found in Dog or Tree, it does so
implicitly.)  This is perhaps the most crucial difference between role
composition and class inheritance: once role composition is complete,
you can ignore the implementation details of the roles that were
composed; all that matters is the implementation of the role or class
into which they were composed.

 However, I expect that my Dog $d = $dogwood would strip out everything
 else, on the grounds that you explicitly requested a pure Dog object.
  Otherwise you could have said my $d = Dog($dogwood) or maybe my
 $dogwood.^WHAT $d = $dogwood instead.

With my Dog $d = $dogwood, $d is a Dog that was initialized using
values gleaned from $dogwood.

-- 
Jonathan Dataweaver Lang


Re: Freezing role methods

2009-10-14 Thread Darren Duncan

Jon Lang wrote:

Here, we need a bit of a clarification: are we talking roles or
classes?  Real example: Numeric is a role; Num is a class.  Both can
be used in signatures; but only classes can be used to create objects.
 That is, my Num $x; works; but my Numeric $x; doesn't.  As such,
you cannot coerce an object to a role; you can only coerce it to a
class that does that role.


Bad example.  Both of those would work.  Otherwise one of the main reasons for 
roles to exist, which is to be able to declare a container $x and say that it 
may hold anything that does role Y, wouldn't be possible.  Perhaps a better 
example is Num.new(...) works but Numeric.new(...) doesn't. -- Darren Duncan


Re: Freezing role methods

2009-10-14 Thread Jon Lang
Darren Duncan wrote:
 Jon Lang wrote:
 Here, we need a bit of a clarification: are we talking roles or
 classes?  Real example: Numeric is a role; Num is a class.  Both can
 be used in signatures; but only classes can be used to create objects.
  That is, my Num $x; works; but my Numeric $x; doesn't.  As such,
 you cannot coerce an object to a role; you can only coerce it to a
 class that does that role.

 Bad example.  Both of those would work.  Otherwise one of the main reasons
 for roles to exist, which is to be able to declare a container $x and say
 that it may hold anything that does role Y, wouldn't be possible.  Perhaps a
 better example is Num.new(...) works but Numeric.new(...) doesn't. --

You are, of course, correct.  I think that what I meant to say was my
$x is Num vs. my $x is Numeric.


-- 
Jonathan Dataweaver Lang


Re: Freezing role methods

2009-10-14 Thread Mark Morgan
On 10/14/09, Ovid publiustemp-perl6langua...@yahoo.com wrote:
 In short, under the original traits model, you have roles you can't compose
 together.  The paper argues that in languages which have public and
 private methods, that the composing class is allowed to decide which x()
 method it needs (if any) and that it can *freeze* the other x() method.
 That is to say, the x() in question would become private and statically
 bound to the invocants to ensure that they're always calling the correct
 x().

 How would Perl 6 approach this issue?

Hrm, to clarify for myself, would this imply that roles have a
specialised MRO, such that, they would resolve methods as (in order
from highest preference to lowest):

1/  Implemented by the class they're composed into.
2/  The role that the called method is defined in.
3/  Any roles that the role the method is called on are composed into.

This seems to be the only thing which would make sense.  This would
avoid unexpected action-at-a-distance, when two roles with
similarly-named internal methods (whether public or private) are
consumed into the same class, or to avoid roles having to know too
much about other roles which aren't composed into the current role's
implementations.

Mark.


Should .^methods be curried with the invocant?

2009-09-25 Thread Moritz Lenz
Consider this case:

class A { method m { say 'OH HAI' } };
my $m = A.new.^methods(:local).[0];

How should I invoke $m?
In current Rakudo this works:
$m(A.new);  # supply the invocant as first argument

But shouldn't be just $m() (invocant magically curried) or may
$m(A.new:) (invocant not curried, but marked with a colon)?

Cheers,
Moritz


Re: Should .^methods be curried with the invocant?

2009-09-25 Thread Daniel Ruoso
Em Sex, 2009-09-25 às 18:28 +0200, Moritz Lenz escreveu:
 class A { method m { say 'OH HAI' } };
 my $m = A.new.^methods(:local).[0];
 How should I invoke $m?
 In current Rakudo this works:
 $m(A.new);# supply the invocant as first argument
 But shouldn't be just $m() (invocant magically curried) or may
 $m(A.new:) (invocant not curried, but marked with a colon)?

Methods are only methods when they are dispatched as methods, otherwise
they are regular subs. The invocant in the capture is just the first
positional argument, so $m(A.new) is what you want, although $m(A.new: )
should have the same effect.

daniel





Re: RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)

2009-07-13 Thread Ovid

- Original Message 
 From: Jon Lang datawea...@gmail.com

 Right.  But as they were originally conceived, they were interfaces
 that could also handle code reuse, rather than units of code reuse
 that could also be used as interfaces.  From this perspective, it
 makes perfect sense that a role's methods can be overridden as easily
 as they are.

As originally conceived in Perl 6 or in the original traits papers?  In the 
original research, the purpose of roles was to allow the decoupling of 
responsibility and behavior (code reuse) found in inheritance-based OO systems. 
 Traits (roles) took over code reuse.

 But you make a good point: there are some (a few? most?) programmers
 who are going to want to use roles primarily for code reuse, and who
 will want it to be a little more difficult to override the code
 provided by a role (e.g., requiring the use of supersede and perhaps
 augment in order to replace the definition with a new one).

Just to give people some real data to play with (our system may not be 
representative), here's some sample source code and some imformation about our 
use of roles in the BBC.

package PIPs::ResultSource::Series;
use Moose;
extends 'PIPs::ResultSourceBase::BrandSeries';
with qw(
PIPs::ResultSource::Role::DoesParentChildRelationships
PIPs::ResultSource::Role::DoesTags
PIPs::ResultSource::Role::DoesContentObject
PIPs::ResultSource::Role::DoesInspector
PIPs::ResultSource::Role::DoesRelatedLinks
PIPs::ResultSource::Role::DoesIdentifiers
PIPs::ResultSource::Role::DoesChangeEvents
);

 
(The astute reader will not that the base class is awful, but it's been a long, 
hard slog to get this far).

Most of our classes which implement roles have similar preambles, but with 
different behaviors listed.

Other points of interest.  Only 11 of 114 classes which implement roles exclude 
any methods (none use method aliasing) and we currently have 40 roles 
implemented.  

Only three classes provide methods which override role's methods, but in the 
few cases they do, we explicitly exclude the methods from the role to make it 
clear that we need to do this.  We had more overriding of role's methods, but 
continual refactoring has pushed those into roles.

 
So we're very, very heavily on the use roles for shared behavior side.  The 
relative paucity of overridden role methods suggests to me that (for our code), 
the annoyance of having to be explicit for overridding a role's methods easily 
offset by how hard it's been to debug this issue.  That being said, the pain in 
debugging might have been a side effect of the fast transformation from a 
complex inheritance hierarchy to a roles-based system.

Cheers,
Ovid
--
Buy the book - http://www.oreilly.com/catalog/perlhks/
Tech blog- http://use.perl.org/~Ovid/journal/
Twitter  - http://twitter.com/OvidPerl
Official Perl 6 Wiki - http://www.perlfoundation.org/perl6


RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)

2009-07-12 Thread Daniel Ruoso
Em Sex, 2009-07-10 às 15:39 -0700, Jon Lang escreveu:
 The key to understanding roles is to note that roles don't implement
 methods; classes implement methods.

Er, while I see your point, Roles are not just interfaces... they are OO
components that can be plugged into other classes. They often are used
for type identity exactly because of that attribute, since you won't be
enforcing any hierarchy.

 Roles define which methods must be implemented, and suggest ways that
 they might be implemented; classes decide which implementation to use.
 Anything that breaks this paradigm is a Bad Thing.

That's not the common conception in Roles usage, specially in Moose. As
I said, Roles are not just interfaces, they are OO reuseable components.
The spec itself says:

Classes are primarily for instance management, not code reuse.
Consider using Croles when you simply want to factor out
common code.

The key issue here is Perl 6 wasn't yet used to the extent that
Moose::Roles are, and Moose people have identified that the use of Roles
as reusable components raised the issue when the class inadvertedly
overrides one of the methods that are implemented by one of the composed
roles.

I did think that this should be the expected behavior, but when the
people that is heavily using it says it took me a lot of time to
debug, it indicates that there's something wrong with the behavior.

So now I changed my mind, inheritance is about overriding behavior, so
when you implement a method in the subclass it is a natural thinking
that this should override the superclass, but when you think about it
really carefully this logic doesn't really map well to Roles
(considering roles as OO reuseable components).

That being said, I'd think the following as an interesting solution:

 role R1 {
   method foo() {...} # degenerates to interface
 }
 role R2 does R1 {
   method bar() {
 # some implementation
   }
   method baz() {
 # some implementation
   }
 }

 class Bla does R2 {
   method foo {
 # implementing here is natural, since the role only
 # declared a stub, it's even a warning not to implement it
   }
   supersede method bar  {
 # explicitly tells that I want to ignore the implementation
 # in the role. nextsame wouldn't find the role implementation.
   }
   augment method baz {
 # explicitly tells that I want to provide an additional
 # implementation besides the one in the role. nextsame would find
 # the role implementation.
   }
 }

In the above example, declaring a method without either supersede or
augment would result in a compile-time warning, while using augment
semantics by default.

dainel



Re: RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)

2009-07-12 Thread David Green

On 2009-Jul-12, at 12:43 pm, Daniel Ruoso wrote:

role R1 {
  method foo() {...} # degenerates to interface
}


Just wondering: since merely declaring an interface will be common  
enough, should we be able to say simply method foo; inside a role,  
and drop the {...}?



class Bla does R2 {
  method foo {
# implementing here is natural, since the role only
# declared a stub, it's even a warning not to implement it
  }
  supersede method bar  {
# explicitly tells that I want to ignore the implementation
# in the role. nextsame wouldn't find the role implementation.
  }
  augment method baz {
# explicitly tells that I want to provide an additional
# implementation besides the one in the role. nextsame would find
# the role implementation.
  }
}


Works for me.  I thought having suggest to make it work the other  
way around sounded useful too, but perhaps you think in practice it  
wouldn't be worth it?



-David



Re: RFC: overriding methods declared by roles (Was: Re: Reusing code: Everything but the kitchen sink)

2009-07-12 Thread Jon Lang
Daniel Ruoso wrote:
 Jon Lang wrote:
 The key to understanding roles is to note that roles don't implement
 methods; classes implement methods.

 Er, while I see your point, Roles are not just interfaces... they are OO
 components that can be plugged into other classes. They often are used
 for type identity exactly because of that attribute, since you won't be
 enforcing any hierarchy.

Right.  But as they were originally conceived, they were interfaces
that could also handle code reuse, rather than units of code reuse
that could also be used as interfaces.  From this perspective, it
makes perfect sense that a role's methods can be overridden as easily
as they are.

But you make a good point: there are some (a few? most?) programmers
who are going to want to use roles primarily for code reuse, and who
will want it to be a little more difficult to override the code
provided by a role (e.g., requiring the use of supersede and perhaps
augment in order to replace the definition with a new one).  First and
foremost, this distinction between suggested ans mandatory
implementation is what I was trying to make a little more explicit in
my proposal: a suggested method can be overridden by the class with no
extra effort; a mandatory method requires that the class be explicit
about the override.

The next question is which of these approaches Perl 6 should use with
roles.  Currently, it's using suggested implementations; what I'm
hearing you say is that you'd rather have mandatory implementations.
IMHO, there's a time ans place for both; so I was trying to come up
with a compromise of sorts: a way of letting the programmer select the
approach that most suits his needs.

 Roles define which methods must be implemented, and suggest ways that
 they might be implemented; classes decide which implementation to use.
 Anything that breaks this paradigm is a Bad Thing.

 That's not the common conception in Roles usage, specially in Moose. As
 I said, Roles are not just interfaces, they are OO reuseable components.

FWIW, I never said that they're just interfaces.  Also, I question
whether that is or is not the common conception of role usage.  I
readily admit that it isn't so in the programming circles that you
travel in; but are you typical of the perl community in this regard?
This is not a rhetorical question; the way that we end up addressing
this issue hinges on this question: should roles provide suggested
implementations by default, or should they provide mandatory
implementations by default?  Even if Perl is rich enough to provide
for both, the decision of which way to go when no explicit decision
has been made is an important one.

 The spec itself says:

        Classes are primarily for instance management, not code reuse.
        Consider using Croles when you simply want to factor out
        common code.

Right: roles are preferable to classes when it comes to code reuse.
That doesn't necessarily mean that roles are _primarily_ intended for
code reuse.  They _might_ be; but if so, it's because they've grown
beyond their original concept.

 The key issue here is Perl 6 wasn't yet used to the extent that
 Moose::Roles are, and Moose people have identified that the use of Roles
 as reusable components raised the issue when the class inadvertedly
 overrides one of the methods that are implemented by one of the composed
 roles.

You know what?  Until Moose was mentioned in this conversation, I had
never heard of it.

 I did think that this should be the expected behavior, but when the
 people that is heavily using it says it took me a lot of time to
 debug, it indicates that there's something wrong with the behavior.

 So now I changed my mind, inheritance is about overriding behavior, so
 when you implement a method in the subclass it is a natural thinking
 that this should override the superclass, but when you think about it
 really carefully this logic doesn't really map well to Roles
 (considering roles as OO reuseable components).

That may indeed be the case.  It's entirely possible that we may want
to change things so that roles define mandated methods, and possibly
introduce interfaces as a variation of roles that define suggested
methods.  But we may instead want to keep roles as they are, and
define some other variation that works just like a role except that it
mandates its methods.

And its also possible that I'm fundamentally wrong about this, and
that we _don't_ need both approaches available for roles.

 That being said, I'd think the following as an interesting solution:

  role R1 {
   method foo() {...} # degenerates to interface
  }
  role R2 does R1 {
   method bar() {
     # some implementation
   }
   method baz() {
     # some implementation
   }
  }

  class Bla does R2 {
   method foo {
     # implementing here is natural, since the role only
     # declared a stub, it's even a warning not to implement it
   }
   supersede method bar  {
     # explicitly tells that I want to ignore

Private methods in Roles (Was: Re: YAPC::EU and Perl 6 Roles)

2009-07-08 Thread Daniel Ruoso
Em Qua, 2009-07-08 às 12:49 -0700, Ovid escreveu:
 Behavioral:  if you are primarily relying on roles to provide behavior
 (as we do at the BBC), then silently discarding the role's behavior by
 providing a method of the same name in your class can lead to very
 confusing bugs.  I've lost a lot of time debugging this behavior.

That's actually a tipping point, and I'm thinking we never conceptually
extrapolated the use of Roles to a point that competing Roles in a
composition are bringing methods to the class that are actually relevant
to that roles, but doesn't mix well with the semantics of the composed
class.

Maybe what we need is a way to define methods that are not composed to
the class at all, but are there just for implementation sake. That could
probably mean that methods declared as privates in the role should not
be composed in the class, and the lookup of private methods should honor
the original place of declaration...

daniel



r25809 - docs/Perl6/Spec src/perl6 t/perl5 t/spec/S02-literals t/spec/S12-methods

2009-03-12 Thread pugs-commits
Author: lwall
Date: 2009-03-13 00:15:48 +0100 (Fri, 13 Mar 2009)
New Revision: 25809

Modified:
   docs/Perl6/Spec/S02-bits.pod
   docs/Perl6/Spec/S03-operators.pod
   docs/Perl6/Spec/S04-control.pod
   docs/Perl6/Spec/S12-objects.pod
   src/perl6/STD.pm
   t/perl5/roundtrip.t
   t/spec/S02-literals/pairs.t
   t/spec/S02-literals/sub-calls.t
   t/spec/S12-methods/instance.t
   t/spec/S12-methods/syntax.t
Log:
[STD] special named forms foo() .foo() and $.foo() no longer support
the dereferencing .() postfix syntax, since they don't actually do
any dereferencing!  You may still insert space using unspace however.
This decrease in consistency on the syntactic level is offset by an
increase in consistency on the semantic level, as suggested by rouso++.
(We'd already gotten rid of the dot forms of adverbs some time ago,
for similar reasons.  We just didn't quite carry the idea through.)


Modified: docs/Perl6/Spec/S02-bits.pod
===
--- docs/Perl6/Spec/S02-bits.pod2009-03-12 22:34:06 UTC (rev 25808)
+++ docs/Perl6/Spec/S02-bits.pod2009-03-12 23:15:48 UTC (rev 25809)
@@ -1597,7 +1597,7 @@
 
 Unlike in Perl 5, the notation Cfoo merely stands for the Cfoo
 function as a Code object without calling it.  You may call any Code
-object with parens after it (which may, of course, contain arguments):
+object by dereferencing it with parens (which may, of course, contain 
arguments):
 
 foo($arg1, $arg2);
 
@@ -1613,6 +1613,29 @@
 embedded comment
 ].($arg1, $arg2);
 
+Note however that the parentheses around arguments in the normal
+named forms of function and method calls are not postfix operators, so do
+not allow the C.() form, because the dot is indicative of an actual
+dereferencing operation, which the named forms aren't doing.  You
+may, however, use unspace to install extra space before the parens
+in the forms:
+
+foo()   # okay
+foo\ () # okay
+foo.()  # means foo().()
+
+.foo()  # okay
+.foo\ ()# okay
+.foo.() # means .foo().()
+
+$.foo() # okay
+$.foo\ ()   # okay
+$.foo.()# means $.foo().()
+
+If you Ido use the dotty form on these special forms, it will
+assume you wanted to call the named form without arguments, and
+then dereference the result of that.
+
 =item *
 
 With multiple dispatch, Cfoo may actually be the name of a set

Modified: docs/Perl6/Spec/S03-operators.pod
===
--- docs/Perl6/Spec/S03-operators.pod   2009-03-12 22:34:06 UTC (rev 25808)
+++ docs/Perl6/Spec/S03-operators.pod   2009-03-12 23:15:48 UTC (rev 25809)
@@ -2576,12 +2576,13 @@
 (except for postfix adverbs, which may follow the parentheses provided they
 would not attach to some other operator by the rules of precedence).
 
-Other than various forms of parentheses, all other postfixes are
+Other than parentheses, all other postfixes are
 disallowed immediately after a list operator, even if there are no
 arguments.  To add a postfix to an argumentless list operator you
 must write it as a function call with empty parentheses:
 
 foo.[]  # ILLEGAL
+foo.()  # ILLEGAL
 foo++   # ILLEGAL
 foo().[]# legal
 foo()++ # legal (if foo() is rw)
@@ -2613,7 +2614,7 @@
 say foo++;  ILLEGAL, need parens
 
 say foo($bar+1),$bazsay(foo($bar+1), $baz);
-say foo.($bar+1),$baz   say(foo($bar+1), $baz);
+say foo.($bar+1),$baz   ILLEGAL, need space or parens
 say foo ($bar+1),$baz   say(foo($bar+1, $baz));
 say foo .($bar+1),$baz  say(foo($_.($bar+1), $baz));
 

Modified: docs/Perl6/Spec/S04-control.pod
===
--- docs/Perl6/Spec/S04-control.pod 2009-03-12 22:34:06 UTC (rev 25808)
+++ docs/Perl6/Spec/S04-control.pod 2009-03-12 23:15:48 UTC (rev 25809)
@@ -1193,8 +1193,8 @@
 $scalar = ($x); # grouping parens because term expected
 if $term($x)# function call because operator expected
 if $term ($x)   # syntax error (two terms in a row)
-if $term.($x)   # valid function call with dot
-if $term\ .($x) # valid function call with unspace
+if $term.($x)   # valid function call with explicit dot deref
+if $term\ .($x) # valid function call with unspace and dot
 
 Outside of any kind of expression brackets, a final closing curly
 on a line (not counting whitespace or comments) always reverts

Modified: docs/Perl6/Spec/S12-objects.pod
===
--- docs/Perl6/Spec/S12-objects.pod 2009-03-12 22:34:06 UTC (rev 25808)
+++ docs/Perl6/Spec/S12-objects.pod 2009-03-12 23:15:48 UTC (rev 25809)
@@ -12,9 +12,9 @@
 
   Maintainer: Larry Wall la...@wall.org
   Date: 27 Oct 2004
-  Last Modified: 9 Mar 2009

Re: File test ops as string methods

2008-11-08 Thread Xiao Yafeng

 I've been thinking about that.  One interesting ramification of
 the current matching rule is that you could say either of:

foo.io ~~ :r :x

 or

foo ~~ :io(:r :x)

 where .io is whatever your casting method of choice is for turning
 a string into an object with the correct methods.  Somehow I think
 .filename is a bit too long, huffmanwise.


If io is casting method, which statement below is correct:

say ok if 1234.io  1000;

or

say ok if 1234.int 1000;


Re: .perl and other methods on Junctions?

2008-11-08 Thread Patrick R. Michaud
On Wed, Nov 05, 2008 at 11:28:00AM -0800, Larry Wall wrote:
 But it seems to me that if stringification of a junction returns a
 correct .perlish syntax, it's probably better to just let that happen
 lazily, on the assumption someone might want .perl to autothread for
 some reason, perhaps because .perl performs some kind of useful
 canonicalization prior to comparison.
 
 So I think the actual choice is driven by the fact that Str(Junction)
 is defined to work like you'd expect .perl to do if .perl did it,
 which it doesn't...

This all works for me, thanks for the clarification!

Pm


File test ops as string methods

2008-11-07 Thread Mark J. Reed
I'm sure this has been hashed out somewhere I wasn't looking, but i
would really prefer for pathname ops not to be mixed in to the Str
class.  Maybe they could be put in a Pathname subclass of Str, with a
simple literal syntax or short unary operator to build such a thing
from a string?


-- 
Sent from Gmail for mobile | mobile.google.com

Mark J. Reed [EMAIL PROTECTED]


Re: File test ops as string methods

2008-11-07 Thread Brandon S. Allbery KF8NH

On 2008 Nov 7, at 17:49, Mark J. Reed wrote:

I'm sure this has been hashed out somewhere I wasn't looking, but i
would really prefer for pathname ops not to be mixed in to the Str
class.  Maybe they could be put in a Pathname subclass of Str, with a
simple literal syntax or short unary operator to build such a thing
from a string?



I'm inclined to agree that Str is the wrong place for them.  I could  
see Str being autoconverted to some kind of File class which had them,  
though.


--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




Re: File test ops as string methods

2008-11-07 Thread Larry Wall
On Fri, Nov 07, 2008 at 05:49:54PM -0500, Mark J. Reed wrote:
: I'm sure this has been hashed out somewhere I wasn't looking, but i
: would really prefer for pathname ops not to be mixed in to the Str
: class.  Maybe they could be put in a Pathname subclass of Str, with a
: simple literal syntax or short unary operator to build such a thing
: from a string?

I've been thinking about that.  One interesting ramification of
the current matching rule is that you could say either of:

foo.io ~~ :r :x

or

foo ~~ :io(:r :x)

where .io is whatever your casting method of choice is for turning
a string into an object with the correct methods.  Somehow I think
.filename is a bit too long, huffmanwise.

Larry


Re: .perl and other methods on Junctions?

2008-11-05 Thread Larry Wall
On Tue, Nov 04, 2008 at 01:33:09PM -0600, Patrick R. Michaud wrote:
: Consider the code:
: 
: my $x = 3 | 'foo';
: my $y = $x.perl;
: 
: 
: Does $y end up as a junction of strings or as a single string?

I think it may not actually matter much, if subsequent stringification
of the junction produces a result with correct Perl syntax.

: Asking more directly, does .perl autothread over a Junction?
: If .perl does not autothread, then is there some way of knowing
: which methods autothread and which do not?

I think it would depend entirely on whether the Junction class defined
method .perl, or relied on the authothreading implementation triggered
by Object recognizing that it was handed a Junction.

But it seems to me that if stringification of a junction returns a
correct .perlish syntax, it's probably better to just let that happen
lazily, on the assumption someone might want .perl to autothread for
some reason, perhaps because .perl performs some kind of useful
canonicalization prior to comparison.

So I think the actual choice is driven by the fact that Str(Junction)
is defined to work like you'd expect .perl to do if .perl did it,
which it doesn't...

: (The question of method autothreading over junctions came up at
: the OSCON 2008 hackathon, but I don't know that it was ever
: resolved.  If it was and I've just forgotten or overlooked the
: resolution,  I'll be happy to have it pointed out to me.)

Well, at the time we thought there might need to be some kind of
VAR-like JUNCTION macro to give access to the Junction object, but
if the decision is just based on whether Junction defines the method
or not, that's not really necessary.

And with this semantics, it's also no problem going the other way.
If method .junk is defined in Junction, you can still force it to
autothread by saying $junction.Object::junk().

Larry


Re: fallback semantics of list methods

2008-06-16 Thread TSa (Thomas Sandlaß)
HaloO,

On Saturday, 14. June 2008 18:43:05 Daniel Ruoso wrote:
 Moritz convinced me that there's actually no real reason to support

   $nonlist.listmethod

I wouldn´t do that either. But I come to that conclusion from the
line of thought that it is generally a bad idea to block an Any
slot in a multi for a mere casting operation. The whole point of
type based dispatch is to name the intended type in the first place.
That is, a programmer choosing the item sigil $ in combination with
a list operation should be punished with a dispatch error if he doesn´t
know for sure that everything he sticks in the variable is a list
anyway. Note that the other way around is bloody easy in Perl 6. A
@ variable can handle items just fine!

I´m aware that this makes me opt for solution three, the dropping of
fallback from method to sub dispatch. But I consider that a good
thing. They are nicely distinct syntactically, so why mix them
semantically?


 And if we stop, and think for more two seconds, we realise that
 supporting that could end up having a lot of non-interesting side
 effects, because an exported sub with the signature :(Any, Str) is most
 likely to have a lot of false hits.

Technically there are no false hits on an Any slot ;)
In the case at hand it listifies the item and re-dispatches.
IOW, the false hits will be surprises for unaware programmers
who get unexpected dispatches silently.

BTW, there´s the same problem with stringification of the separator.
Combining that with  the listification would end up blocking *join:(Any,Any)
globally.


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


fallback semantics of list methods

2008-06-14 Thread Moritz Lenz
In the test suite and on IRC there was quite some confusion about how
list builtins are specced, and how they should behave in corner cases.

One is join():
our Str multi method join ( @values: Str $separator = ' ' )
our Str multi join ( Str $separator = ' ', [EMAIL PROTECTED] )

It is quite clear that the perl 5-style
   join 'sep', $value, $value2;
invocation remains valid, and
  @list.join($sep)
is the new method form.

The confusion arises what to do with
   'str'.join('other_str')
should be.

Fallback semantics in S12 suggest that since no matching multi method is
found, subs are tried - that is, the expression is interpreted as
   join('str', 'other_str')
yielding 'other_str'. t/spec/S29-list/join.t disagrees, and wants the
result to be 'str'.

Daniel Ruoso argued in favour of the tested behaviour, suggesting that
perhaps the specs should be updated accordingly, mostly because
   ('str').join('other_str')
would be confusing otherwise.

Patrick Michaud argued in favour of the specced behaviour, and I agree.
Mostly because nobody sane will write things like
'str'.join('other_str') with a literal string as the invocant in first
place. And if it's not a literal, and you want it to behave as list, the
invocant is either something that returns a list, or a variable with the
'@' sigil. We just need to be careful that everything that should return
really does that, even if it contains a single list.

Currently both pugs and rakudo make a b return a list (pugs actually
an array, but that's a different problem), but a is a Str.
If we'd just be more consistent and always return a list, I don't see a
problem with the spec. If not, it would be rather weird to have a
b.join('c') return 'abc', but a.join('c') return 'c'.

Consider
my $x = A.new();
$x.y = a;
say $x.y.join('b')
The output is different for the two possible declarations of class A:
class A { has $y is rw } # - b
class A { has @y is rw } # - a
not pretty IMHO.

So I see the following options:
 1) be more consistent with what returns a list
 2) Add a method with invocant Any for each list builtin
 3) drop method fallback, thus disallowing Str.join(Str) outright
 4) be lisp, make everything a list *g* (not serious)

I haven't thought a lot about the third option, and what it would mean
to the language as a whole, so I have no idea if it's a viable alternative.

Any thoughts on the topic are welcome. I hope I didn't confuse too much
here ;-)

Cheers,
Moritz

-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/


Re: fallback semantics of list methods

2008-06-14 Thread Larry Wall
On Sat, Jun 14, 2008 at 01:46:10PM +0200, Moritz Lenz wrote:
: In the test suite and on IRC there was quite some confusion about how
: list builtins are specced, and how they should behave in corner cases.
: 
: One is join():
: our Str multi method join ( @values: Str $separator = ' ' )
: our Str multi join ( Str $separator = ' ', [EMAIL PROTECTED] )
: 
: It is quite clear that the perl 5-style
:join 'sep', $value, $value2;
: invocation remains valid, and
:   @list.join($sep)
: is the new method form.
: 
: The confusion arises what to do with
:'str'.join('other_str')
: should be.
: 
: Fallback semantics in S12 suggest that since no matching multi method is
: found, subs are tried - that is, the expression is interpreted as
:join('str', 'other_str')
: yielding 'other_str'. t/spec/S29-list/join.t disagrees, and wants the
: result to be 'str'.

I want the result to be 'str'.

: Daniel Ruoso argued in favour of the tested behaviour, suggesting that
: perhaps the specs should be updated accordingly, mostly because
:('str').join('other_str')
: would be confusing otherwise.

More to the point,

$unknown.join('other_str')

needs to work well, I think.  And that means even if $unknown doesn't
know whether it's singular or plural.

: Patrick Michaud argued in favour of the specced behaviour, and I agree.
: Mostly because nobody sane will write things like
: 'str'.join('other_str') with a literal string as the invocant in first
: place. And if it's not a literal, and you want it to behave as list, the
: invocant is either something that returns a list, or a variable with the
: '@' sigil. We just need to be careful that everything that should return
: really does that, even if it contains a single list.

Patrick and I discussed it on the phone the other day and came to an
understanding, I think.

: Currently both pugs and rakudo make a b return a list (pugs actually
: an array, but that's a different problem), but a is a Str.
: If we'd just be more consistent and always return a list, I don't see a
: problem with the spec. If not, it would be rather weird to have a
: b.join('c') return 'abc', but a.join('c') return 'c'.

a.join('c') should return 'a'.

: Consider
: my $x = A.new();
: $x.y = a;
: say $x.y.join('b')
: The output is different for the two possible declarations of class A:
: class A { has $y is rw } # - b
: class A { has @y is rw } # - a
: not pretty IMHO.

Indeed.

: So I see the following options:
:  1) be more consistent with what returns a list
:  2) Add a method with invocant Any for each list builtin
:  3) drop method fallback, thus disallowing Str.join(Str) outright
:  4) be lisp, make everything a list *g* (not serious)
: 
: I haven't thought a lot about the third option, and what it would mean
: to the language as a whole, so I have no idea if it's a viable alternative.

I have been advocating for 2, and am considering doing 3 as well.
There's more than one way to do 2--we could, for instance, have some
magical syntax for saying that a class's invocant may be converted
from Any.  But what Patrick and I decided on Wednesday was that, for
now, we'd go with the simplest approach, which is not to invent any new
syntax or semantics, but simply have the Prelude install Any methods
as defaults for universal methods such as .join that want to convert
the invocant to a particular type across the language as a whole.
No fallback is then necessary, and the fact that the Prelude is
defining language-wide default semantics is not a problem at all,
because that's precisely what the Prelude is for.  And I don't see
any problem with the Any class claiming to own .join since subclasses
can still override if the like.

Larry


Re: fallback semantics of list methods

2008-06-14 Thread Daniel Ruoso
Sáb, 2008-06-14 às 09:20 -0700, Larry Wall escreveu:
 On Sat, Jun 14, 2008 at 01:46:10PM +0200, Moritz Lenz wrote:
 : Fallback semantics in S12 suggest that since no matching multi method is
 : found, subs are tried - that is, the expression is interpreted as
 :join('str', 'other_str')
 : yielding 'other_str'. t/spec/S29-list/join.t disagrees, and wants the
 : result to be 'str'.
 I want the result to be 'str'.

Just a sanity check here... Are we really going to change the order of
the parameters of 'join' from p5?

Are we aware that this is going to be a PITA for most p5 developers?

Do we realise that this is only necessary to support 

  $nonlist.join($separator)

Which, as moritz pointed out on IRC is a very specific corner case,
which only makes sense on something like:

  my $a = $cond ?? ( 1 ) !! ( 2, 3, 4 );
  $a.join(',');

Which would have the desired effect if used with the proper sigil:

  my @a = $cond ?? 1 !! (2,3,4);
  @a.join(',');

If we choose to avoid supporting $nonlist.listmethod (which sounds lame
anyway), we can keep the order of parameters in join

  join $separator, @list;
  join ', ', 1, 2, 3, 4;

Which is considerably saner than:

  join 1, 2, 3, 4, ', ';

Moritz convinced me that there's actually no real reason to support

  $nonlist.listmethod

And if we stop, and think for more two seconds, we realise that
supporting that could end up having a lot of non-interesting side
effects, because an exported sub with the signature :(Any, Str) is most
likely to have a lot of false hits.

daniel



Private methods in classes and roles

2008-05-16 Thread Moritz Lenz
S12 says (in the context of classes):


my method think (Brain $self: $thought)

(Such methods are completely invisible to ordinary method calls, and are
in fact called with a different syntax that uses ! in place of the .
character. See below.)

And later on, in the context of roles:

my method !foo ...
my method foo ...   # same, but foo is aliased to !foo

Am I right in assuming that the second example is valid only for roles?

I find this different syntax for classes and roles quite confusing. Is
it intended that way? I'd welcome a uniform syntax.

Cheers,
Moritz

-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/



Re: Private methods in classes and roles

2008-05-16 Thread Moritz Lenz
and a few more thoughts:

I wrote:
 S12 says (in the context of classes):
 
 
 my method think (Brain $self: $thought)
 
 (Such methods are completely invisible to ordinary method calls, and are
 in fact called with a different syntax that uses ! in place of the .
 character. See below.)

for private subs S12 also says

Generally you'd just use a lexically scoped sub, though.

my sub foo ...

[Conjectural: To put a private sub into the class, say

our sub !foo ...

]

Which lead me to the thought that 'my method foo' is a bad idea because
the lexical scoping of the 'my' is orthogonal to the scope of the class.

class A {
my method foo { }
}

class A is also {
method bar {
   # no way to access self!foo here
}
}

So is

our method !foo {}

allowed in classes? and is it the recommended way to declare private
methods?


-- 
Moritz Lenz
http://moritz.faui2k3.org/ |  http://perl-6.de/





Re: Private methods in classes and roles

2008-05-16 Thread John M. Dlugosz

Moritz Lenz moritz-at-casella.verplant.org |Perl 6| wrote:

S12 says (in the context of classes):


my method think (Brain $self: $thought)

(Such methods are completely invisible to ordinary method calls, and are
in fact called with a different syntax that uses ! in place of the .
character. See below.)

And later on, in the context of roles:

my method !foo ...
my method foo ...   # same, but foo is aliased to !foo

Am I right in assuming that the second example is valid only for roles?

I find this different syntax for classes and roles quite confusing. Is
it intended that way? I'd welcome a uniform syntax.

Cheers,
Moritz

  


I've asked about my method foo too, but had no response.  I would not 
think anything is unique to roles, rather, stuff defined in a role is 
remembered partly-digested and spilled into a class later.  You might 
want to look at what I've got thus far in my specdoc at 
http://www.dlugosz.com/Perl6/.  I plan on updating that section soon, 
but you get the idea of the formalism I'm bringing to it.


--John


Re: default parameters in methods

2008-04-11 Thread John M. Dlugosz

Larry Wall larry-at-wall.org |Perl 6| wrote:


All default expressions to any parameter are defined to run in the
context that assumes any parameters to their left are already bound,
so you may safely depend on self already being set.

  


OK, so there is no technical reason why it can't work that way.

But, self the keyword is not $self the parameter (it only works in 
methods), and there are issues of trust.  So I need to describe it properly.


--John


default parameters in methods

2008-04-10 Thread John M. Dlugosz
It is not specified in the Synopses as I recall, but I believe that this is 
useful enough that it must be made to work:

   method bytes (Encoding :$encoding = .encoding)
   returns Int

or even

   method bytes (Encoding :$encoding = self!encoding)
   returns Int

That is, a named-only parameter, which may be used as an optional adverb or 
extra parameter to affect details of the function, should default to a pre-set 
value inside the instance.

If this is not allowed, the beginning of the method would always have to check 
for defaults.  That should be automatic.  And it documents the situation nicely 
in the signature, without further explanation that if the parameter is not 
supplied...

This means that the default arguments run inside the context of the method 
call, and can do anything that you would expect from their lexical position.

--John


Re: default parameters in methods

2008-04-10 Thread Larry Wall
On Fri, Apr 11, 2008 at 03:35:37AM -, John M. Dlugosz wrote:
: It is not specified in the Synopses as I recall, but I believe that this is 
useful enough that it must be made to work:
: 
:method bytes (Encoding :$encoding = .encoding)
:returns Int
: 
: or even
: 
:method bytes (Encoding :$encoding = self!encoding)
:returns Int
: 
: That is, a named-only parameter, which may be used as an optional adverb or 
extra parameter to affect details of the function, should default to a pre-set 
value inside the instance.
: 
: If this is not allowed, the beginning of the method would always have to 
check for defaults.  That should be automatic.  And it documents the situation 
nicely in the signature, without further explanation that if the parameter is 
not supplied...
: 
: This means that the default arguments run inside the context of the method 
call, and can do anything that you would expect from their lexical position.

All default expressions to any parameter are defined to run in the
context that assumes any parameters to their left are already bound,
so you may safely depend on self already being set.

Larry


S12v58 edits on Methods

2008-04-03 Thread John M. Dlugosz
If you declare an explicit invocant for an Array type using an array 
variable...
Suggest:

The invocant may be given a sigil other than the C$ item sigil using the 
same rules as binding variables to class types as described in S02 under Names 
and Variables.  For example, if the class does the CPositional role, it may 
be declared with the C@ array sigil.

Naturally, declaring an explicit invocant for an Array type lets you use it in 
the usual way, such as using it in list context to produce its elements.


The word self is described as a keyword and as a function.  Be stronger about 
defining it.  I suggest,

Within the lexical scope of any method, the Cself keyword behaves as a 
function that returns the invocant in item context.  It is improper to use this 
pseudo-function in any manner other than to call it directly.  In particular, 
an implementation is not required to support taking a Capture to the function.  
Note, however, that you may Icall it from a closure.

Also note that, as is usual with Perl, the existance of keywords do not 
preclude the use of identifiers with the same name.  Although this is usually 
considerd bad form to make a variable named C$if, defining your invocant to 
be C$self is not deemed to be in bad taste.  However, defining C@self (or 
other sigil forms other than item) could indeed confuse someone reading the 
code, and is discouraged.


Per conversation with Audry, I suggest adding the following before Private 
methods are


Methods, like any other kind of Csub, behave as if defined with Cour by 
default, if no scope modifier is used.  This is described in S06 under Named 
subroutines.  However, it may be desirable to use the Cour keyword 
explicitly, as it offers the ability to put the return type before the method 
name, in the C style.




Re: our methods?

2008-04-02 Thread Audrey Tang
John M. Dlugosz 提到:
 In S29, there are definitions like
our Capture method shape (@array: ) is export
 But in S12 there is no mention as to what an our method is.  It states that 
 my is used to make private methods, and ^ to make class methods.
 I think this is a doc relic and should be fixed globally in that file.

S02/Return types:


If a subroutine is not explicitly scoped, it belongs to the current
namespace (module, class, grammar, or package), as if it's scoped with
the Cour scope modifier. Any return type must go after the name:


So this line:

our Capture method shape (@array: ) is export

is really the same as:

method shape (@array: ) of Capture is export

The prefixing of our is there to make the return (of) type stand out.

Cheers,
Audrey



Re: our methods?

2008-04-02 Thread John M. Dlugosz
I understand. Thank you.

This ought to be mentioned in S12. Perhaps after the treatment on my,
explain that our is the default, but saying it explicitly allows the
return type to be first.

--John

Audrey Tang audreyt-at-audreyt.org |Perl 6| wrote:
 John M. Dlugosz 提到:
   
 In S29, there are definitions like
our Capture method shape (@array: ) is export
 But in S12 there is no mention as to what an our method is.  It states 
 that my is used to make private methods, and ^ to make class methods.
 I think this is a doc relic and should be fixed globally in that file.
 

 S02/Return types:

 
 If a subroutine is not explicitly scoped, it belongs to the current
 namespace (module, class, grammar, or package), as if it's scoped with
 the Cour scope modifier. Any return type must go after the name:
 

 So this line:

 our Capture method shape (@array: ) is export

 is really the same as:

 method shape (@array: ) of Capture is export

 The prefixing of our is there to make the return (of) type stand out.

 Cheers,
 Audrey


   



our methods?

2008-04-01 Thread John M. Dlugosz
In S29, there are definitions like

   our Capture method shape (@array: ) is export

But in S12 there is no mention as to what an our method is.  It states that 
my is used to make private methods, and ^ to make class methods.

I think this is a doc relic and should be fixed globally in that file.


Re: when calling sets of methods, what happens to the return values?

2006-09-04 Thread Mark Stosberg
Mark Stosberg wrote:
 S12 describes a feature to call sets of methods at the same time:
 
   http://feather.perl6.nl/syn/S12.html#Calling_sets_of_methods
 
 I would like the spec to clarify what happens to the return values of
 all these methods.
 
 I'm fine with a simple answer, such as that they are not available, or
 only the first or last set of return values is returned.
 
 As a use case, we may use of basically this feature in
 CGI::Application in Perl5, as part the plugin system. Each plugin
 location is like a method name, and as we get to each point in the code,
 we look up through the inheritance tree, executing methods at each location.

So, Audrey implemented the beginning of this functionality:

$obj.*$meth, for single inheritance.

As part that she implemented return values. Her design was to compose
the final return value as an unconcatenated list of each method's return
value.

Example:

If C.foo returns (1,2,3) and D.foo returns(4,5,6)
you get
$obj.*$meth.[0][0] == 1
$obj.*$meth.[1][0] == 4

That works OK for me. If there's a downside, if there is a downside,
it's that it could be hard to track down where a mysterious return value
came from, since the return value object doesn't tell you exactly which
methods were called, and in which order.

Mark



when calling sets of methods, what happens to the return values?

2006-09-02 Thread Mark Stosberg
S12 describes a feature to call sets of methods at the same time:

  http://feather.perl6.nl/syn/S12.html#Calling_sets_of_methods

I would like the spec to clarify what happens to the return values of
all these methods.

I'm fine with a simple answer, such as that they are not available, or
only the first or last set of return values is returned.

As a use case, we may use of basically this feature in
CGI::Application in Perl5, as part the plugin system. Each plugin
location is like a method name, and as we get to each point in the code,
we look up through the inheritance tree, executing methods at each location.

In this case, I think we ignore the return values.

   Mark



Methods vs. Subs

2006-07-08 Thread Jonathan Lang

Is there anything that you can do with a sub (first parameter being
some sort of object) that you cannot do with a method?  Frex, given:

 multi method my_method($invocant:);

would

 topical_call := my_method.assuming :invocant$_;

be legal?

--
Jonathan Dataweaver Lang


Re: Methods vs. Subs

2006-07-08 Thread Larry Wall
On Sat, Jul 08, 2006 at 07:42:06AM -0700, Jonathan Lang wrote:
: Is there anything that you can do with a sub (first parameter being
: some sort of object) that you cannot do with a method?  Frex, given:
: 
:  multi method my_method($invocant:);
: 
: would
: 
:  topical_call := my_method.assuming :invocant$_;
: 
: be legal?

Yes, it's certainly legal, but it's not quite the same semantics.
A sub guarantees at compile time exactly which routine is going to
be called.  Your example would need a ::= to do that.  But even with
that it doesn't really guarantee which my_method you're going to get,
in the sense that .assuming is going to have to do a partial method
dispatch, and which method it finds will depend on the value of $_.
Furthermore, ::= would force that to mean the compile-time value of
$_, which is probably not what you want anyway.

As far as I can figure, there's no way of defining topical_call such
that it knows to .assume $_ as its invocant without actually evaluating
$_ at the time .assuming is called, since .assuming doesn't merely
set the default; it's a partial dispatch, and throws away the assumed
parameter slot entirely from the viewpoint of the subsequent caller.
It may well have to keep track of the slot for implementation,
however--as a partial dispatch, topical_call may in fact represent a
set of remaining candidates to be multi dispatched, and merely setting
one parameter with .assuming shouldn't imply that that's the entire
eventual parameter list.  That is, it mustn't assume that the supplied
parameters are delimited with semicolons in the receiving signature.
So for purposes of implementation, it does behave merely like a default.
Go figure...

Larry


Interesting Paper on Prototype Based OO w/ Multi-Methods

2006-01-27 Thread Stevan Little
Hello All,

Recently on #perl6 putter found the Slate language
(http://slate.tunes.org/) in our search for some information about
Smalltalk. Slate is a prototype based OO language which uses multi
method dispatch instead of more traditional method dispatch. As I
flipped through some of the papers on the site, I couldn't help
thinking back to some of the more recent musing of Larry on the Perl 6
object model. The paper which is most complete is this one:

http://tunes.org/~eihrul/ecoop.pdf

Or for those with shorter attention spans, there are some slides which
give a high level overview of what is in the paper. That can be found
here:

http://tunes.org/~eihrul/talk.pdf

I think there is definitely some valuable information to be found in
here, which we can use in the further development of the Perl 6 obejct
model.

Stevan


Re: Class methods vs. Instance methods

2006-01-20 Thread Miroslav Silovic

[EMAIL PROTECTED] wrote:


: class Dog {
: method tail { brown and short }
: };
:
: class Chihuahua is Dog {
: has $.color;
: method tail { $.color _  and short }
: };
:
: You can say Dog.tail, Dog.new.tail, Chihuahua.new.tail, but not
: Chihuahua.tail. That's extremely counter-intuitive.

I don't think it's counterintuitive.  You've defined Dog with an
invariant .tail but not Chihuahua.  It's doing exactly what you asked
for under a prototype view of reality.
   



Except there are no such things as classes in a prototype view of
reality. Everything is an instance and there are no such things as
class methods. The entire idea that an object (::Dog) can call methods
that are for another object ($fido) is ... well ... it's a little off.

That's like saying any object can call any method from any other
object so long as that method is invariant.
 



In a prototype-instance system,

instance(Dog) isa class(Dog)
instance(Chihuahua) isa class(Chihuahua) isa class(Dog)
instance(Chihuahua) isa instance(Dog)

Note that instances inherit doubly, from own class and from parent's 
instance.


But this does not imply that:

class(Chihuahua) isa instance(Dog)

So I don't see a problem.

   Miro




Re: Class methods vs. Instance methods

2006-01-19 Thread Audrey Tang (autrijus)
On 1/19/06, Matt Fowles [EMAIL PROTECTED] wrote:
 Could you provide a concrete example of the advantage of this approach
 please?  Failing that can you try and expand on your gut feeling a
 bit?

May or may not be of use, but Larry's view sounds a bit like reconcilling the
(again considered irreconcilable) gap between nominal and structural subtyping:

http://cakoose.com/wiki/type_system_terminology#13

Where the empty class object is the degenerate case of the smallest possible
structural type, so it can be fulfilled by anything more structurally
rich as long
as they share the same nominal constraint.

Audrey


Re: Class methods vs. Instance methods

2006-01-19 Thread Rob Kinyon
On 1/18/06, Audrey Tang (autrijus) [EMAIL PROTECTED] wrote:
 http://cakoose.com/wiki/type_system_terminology#13

Any practical programming language with structural subtyping will
probably let you create and use aliases for type names (so you don't
have to write the full form everywhere). However, the underlying type
system will only consider the structure of the type when doing its
job.

What's wrong with Perl doing things that way? duck-typing with names
... sounds like a plan to me ...

Rob


Re: Class methods vs. Instance methods

2006-01-19 Thread Audrey Tang
Rob Kinyon wrote:
 Any practical programming language with structural subtyping will
 probably let you create and use aliases for type names (so you don't
 have to write the full form everywhere). However, the underlying type
 system will only consider the structure of the type when doing its
 job.
 
 What's wrong with Perl doing things that way? duck-typing with names
 ... sounds like a plan to me ...

The thing is that people using .does(Name) and .isa(Name) is probably
expecting a nominal answer, not a structural one.

Although I do think Visual Basic's explicit duck-subtypes makes a lot of
sense:

my subset Duck where {
has $.half_life;
can doom:();
can quake:(-- Wolfenstein);
};

then you can apply it as a ducktype with names:

my Duck $donald = some_function();
$donald.quake; # assured to return a Wolfenstein object

It's already part of S12, by the way.

Audrey



signature.asc
Description: OpenPGP digital signature


Re: Class methods vs. Instance methods

2006-01-19 Thread chromatic
On Thursday 19 January 2006 06:48, Rob Kinyon wrote:

 Any practical programming language with structural subtyping will
 probably let you create and use aliases for type names (so you don't
 have to write the full form everywhere). However, the underlying type
 system will only consider the structure of the type when doing its
 job.

 What's wrong with Perl doing things that way? duck-typing with names
 ... sounds like a plan to me ...

Accidental structural equivalence is a problem -- it's one of the things wrong 
with C's so-called type system, for example.

I like to think of roles as nominally-tagged (and checked) structural 
subtyping.  When you're *defining* a type, its structure matters.  When 
you're *using* it, its behavior matters.  It would be nice to keep those two 
separate.

-- c


Class methods vs. Instance methods

2006-01-18 Thread Rob Kinyon
Today on #perl6, Audrey, Stevan and I were talking about $repr. A
tangent arose where Audrey said that the difference between class
methods and instance methods was simply whether or not the body
contained an attribute access.

Is this true? If it is, then I think it violates polymorphism as
demonstrated by the following:

class Dog {
method tail { brown and short }
};

class Chihuahua is Dog {
has $.color;
method tail { $.color _  and short }
};

You can say Dog.tail, Dog.new.tail, Chihuahua.new.tail, but not
Chihuahua.tail. That's extremely counter-intuitive.

I think that class methods should be explicitly defined as class
methods and you cannot call a class method upon an instance, just as
you cannot call an instance method upon a class. Plus, this should be
determinable (for the most part) at compile time, which is a bonus,
imho.

Thanks,
Rob


Re: Class methods vs. Instance methods

2006-01-18 Thread Larry Wall
On Wed, Jan 18, 2006 at 01:56:53PM -0500, Rob Kinyon wrote:
: Today on #perl6, Audrey, Stevan and I were talking about $repr. A
: tangent arose where Audrey said that the difference between class
: methods and instance methods was simply whether or not the body
: contained an attribute access.
: 
: Is this true? If it is, then I think it violates polymorphism as
: demonstrated by the following:
: 
: class Dog {
: method tail { brown and short }
: };
: 
: class Chihuahua is Dog {
: has $.color;
: method tail { $.color _  and short }
: };
: 
: You can say Dog.tail, Dog.new.tail, Chihuahua.new.tail, but not
: Chihuahua.tail. That's extremely counter-intuitive.

I don't think it's counterintuitive.  You've defined Dog with an
invariant .tail but not Chihuahua.  It's doing exactly what you asked
for under a prototype view of reality.

: I think that class methods should be explicitly defined as class
: methods and you cannot call a class method upon an instance, just as
: you cannot call an instance method upon a class. Plus, this should be
: determinable (for the most part) at compile time, which is a bonus,
: imho.

I believe this is already determinble at compile time for the most part.

But I have a strong gut-feeling that over the long term it's going to
be important to be able to view a given object as either a partially
instantiated class or a partially undefined object, and for that we have
to break down the false class/instance dichotomy.  And to the extent
that the dichotomy *isn't* false, we're trying to sweep classness into
the .meta object, which is the *real* class object in Perl 6.

Larry


Re: Class methods vs. Instance methods

2006-01-18 Thread Matt Fowles
Larry~

On 1/18/06, Larry Wall [EMAIL PROTECTED] wrote:

 But I have a strong gut-feeling that over the long term it's going to
 be important to be able to view a given object as either a partially
 instantiated class or a partially undefined object, and for that we have
 to break down the false class/instance dichotomy.  And to the extent
 that the dichotomy *isn't* false, we're trying to sweep classness into
 the .meta object, which is the *real* class object in Perl 6.

Perhaps I am just being short sighted, but I never saw this as a false
dichotomy.  In fact, every time I hear about these partially
instatiated I cringe in horror about the strange halfway lands we
might end up in... Oh no, this method can only be called on an object
that is 3/4 initialized, and you supplied one that is 2/3 initialized
that causes undefined behavior.

Could you provide a concrete example of the advantage of this approach
please?  Failing that can you try and expand on your gut feeling a
bit?

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


Re: Class methods vs. Instance methods

2006-01-18 Thread Rob Kinyon
On 1/18/06, Larry Wall [EMAIL PROTECTED] wrote:
 On Wed, Jan 18, 2006 at 01:56:53PM -0500, Rob Kinyon wrote:
 : Today on #perl6, Audrey, Stevan and I were talking about $repr. A
 : tangent arose where Audrey said that the difference between class
 : methods and instance methods was simply whether or not the body
 : contained an attribute access.
 :
 : Is this true? If it is, then I think it violates polymorphism as
 : demonstrated by the following:
 :
 : class Dog {
 : method tail { brown and short }
 : };
 :
 : class Chihuahua is Dog {
 : has $.color;
 : method tail { $.color _  and short }
 : };
 :
 : You can say Dog.tail, Dog.new.tail, Chihuahua.new.tail, but not
 : Chihuahua.tail. That's extremely counter-intuitive.

 I don't think it's counterintuitive.  You've defined Dog with an
 invariant .tail but not Chihuahua.  It's doing exactly what you asked
 for under a prototype view of reality.

Except there are no such things as classes in a prototype view of
reality. Everything is an instance and there are no such things as
class methods. The entire idea that an object (::Dog) can call methods
that are for another object ($fido) is ... well ... it's a little off.

That's like saying any object can call any method from any other
object so long as that method is invariant.

 : I think that class methods should be explicitly defined as class
 : methods and you cannot call a class method upon an instance, just as
 : you cannot call an instance method upon a class. Plus, this should be
 : determinable (for the most part) at compile time, which is a bonus,
 : imho.

 I believe this is already determinble at compile time for the most part.

 But I have a strong gut-feeling that over the long term it's going to
 be important to be able to view a given object as either a partially
 instantiated class or a partially undefined object, and for that we have
 to break down the false class/instance dichotomy.  And to the extent
 that the dichotomy *isn't* false, we're trying to sweep classness into
 the .meta object, which is the *real* class object in Perl 6.

I'm sure you understand the distinction you're making. I know I don't
and I've been trying to follow this discussion for the past year. I'm
may not be the brightest bulb in the chandelier, but I'm no 15W dimmer
switch, either.

Frankly, you should be using people like me, Matt Fowles, and the
other  programmers on the list as sounding boards. If we're having
problems understanding the concept, then how are we going to explain
partially-instantiated classes on Perlmonks or #perl or clmp? Like
it or not, we're the sergeants in the Perl army. We're the guys
explaining all this stuff to the privates coming up the ranks. It may
be a nice extension to have, but I'm not sure this should be part of
the standard MOP.

Rob


Re: private methods and role composition

2005-11-08 Thread Larry Wall
On Sat, Nov 05, 2005 at 11:35:38AM -0800, Jonathan Lang wrote:
: First off: is there a way to declare a method as being private to a role?

We're still batting around the notion of private methods.  Certainly
with a lexically scoped sub you can get most of the same benefit.
Trust could then perhaps simply be exportation of the sub to another
scope, though naming another lexical scope is problematic, and if
you export into a package the name becomes public property.  So the
import needs to be into a different lexical scope that happens to be
governed by a particular trusted class name.

Lexically scoped methods or submethods are also a syntactic possibility:

my method foo {...}
my submethod BUILD {...}

If this is how you write private methods, though, these have to be
totally invisible to the ordinary dispatcher.

And just as has defaults to private in the absence of a twigil, perhaps
it does on methods too:

has $foo;   # short form private
has $!foo;  # long form private (but same variable as $foo)
has $.foo;  # public virtual interface to private $!foo

has method foo; # short form private?
has method !foo;# long form private?
has method .foo;# public? same as method foo

But that's a little strange--has should probably indicate that
each object maintains its own copy.  Maybe it's really the underlying
delegation mechanism:

has method foo = some_other_foo();  # init at BUILD time

So probably my is still better for private methods, and tends to
keep weirdness out of the package's public interface.  It would be
nice if the package only contains public method names and private
metadata is confined to the meta object (whether class or proto based).

: Second: can a role reclassify as private a method that is composed
: into it from another role?

I don't see much point.  Private methods are non-virtual, and
shouldn't be inherited, or block the inheritance of anything public.
Private methods are really just subs in disguise.  We allow them
to be called with something resembling ordinary dispatch syntax
(probably via $!foo and $obj!foo() these days) but the public and
private dispatch mechanisms have no overlap.

Larry


private methods and role composition

2005-11-05 Thread Jonathan Lang
First off: is there a way to declare a method as being private to a role?

Second: can a role reclassify as private a method that is composed
into it from another role?

--
Jonathan Dataweaver Lang


Re: Custom Metaclass and Inheritance of Class Methods

2005-10-14 Thread Rob Kinyon
 == CONCLUSION / WRAP-UP

 So, now that I have sufficiently bored you all to tears, I will do a
 quick re-cap of the main question, and the possible solutions.

 Should metaclasses be inherited along normal class lines?

 Meaning that if Foo uses a custom metaclass, and Bar isa Foo, then
 Bar also uses that metaclass.

 If we say yes, then I think it is clear that in order to get a sane
 method and predictable resolution order the custom metaclass would
 always need to precede the inherited eigenclass in the superclass
 list. (see the last example above).

 If we say no, then we need to introduce another anyonomous class into
 our mix, which we call an 'x' class. The 'x' class would need to use
 a breath-first dispatch order in order to produce a sane and
 predictable method resolution order.

I would like to expand on my position in the discussion Steve and I
had, which is the no position. The crux of my view is that Foo is an
instance of some custom metaclass. Bar is an instance of Class (for
the sake of argument). Foo and Bar are unrelated, save for the fact
that instances created by Bar's new() function will have access to all
the behaviors and state that instances created by Foo's new() function
will have.

This is why I also feel that class methods shouldn't have the same MRO
as instance methods, but that's a moot discussion.

Rob


Custom Metaclass and Inheritance of Class Methods

2005-10-13 Thread Stevan Little

Hey All,

So, given the abundance of positive responses ;) for my class  
methods don't inherit proposal, I have decided to withdraw that  
proposal (see my last response on the thread). Of course, this means  
we now have to work out the details of exactly *how* they get  
inherited in all situations. The trickiest one being in the presence  
of custom metaclasses. So, onto the questions.


(NOTE: if you get bored about half-way through this mail (and you  
probably will), there is a conculsion/wrap-up at the very bottom that  
you can probably safely skip ahead too)


Should custom metaclasses are inherited along normal subclass lines?

This would mean that if Foo uses CustomMeta as it's metaclass, any  
subclass of Foo will do the same. This is something Larry mentioned,  
and something I had been thinking about a lot myself and discussed  
recently with Rob Kinyon. I drew a diagram in my response to Larry  
that looked like this:


  Class
^
:
CustomMeta
^
:
  eFoo...eBar
^  ^
|  |
   Foo...Bar

This shows the structure which would be created. The result is that  
method dispatch would go like this:


Bar.foo
  eBar.get_method(foo)
eFoo.get_method(foo)
  CustomMeta.get_method(foo)
Class.get_method(foo)
  ! No Method Found Error !

I think this makes sense in many ways since CustomMeta can  
theoretically add capabilities to the Foo class, which one would want  
inherited by subclasses of Foo. (NOTE: if CustomMeta adds instance  
methods to Foo, they will get inherited, mostly I am talking about  
class functionality here)


However, I can also see where it would make sense for this *not* to  
behave this way. But if we the opposite approach, the eigenclass/ 
metaclass hierarchy begins to get more complex.


To start with, we would need to create another anon-class (called  
xFoo here) which uses multiple inheritence to inherit from eFoo and  
CustomMeta, then eBar would inherit from eFoo (and through eFoo, to  
Class), this would keep CustomMeta out of Bar's method dispatch path.


  Class
^^...
:   :
CustomMeta  :
^   :
:   :
  xFoo...eFoo...eBar
^   ^
|   |
   FooBar

The resulting method dispatch paths would be:

Bar.foo
  eBar.has_method(foo)
eFoo.has_method(foo)
  Class.has_method(foo)
! Method Not Found Error !

Note the lack of CustomMeta in the dispatch path, where as in the  
above example it was there.


This on it's own is not too bad, however, when we add another  
metaclass, it starts to get busier. Our anon-class xBar must inherit  
from eBar and CustomMeta2 (just like xFoo did). Then eBar must be  
connected to eFoo in order to inherit from it, but not pic up any of  
CustomMeta's methods.


  Class...
^^... :
:   : :
CustomMeta  :CustomMeta2
^   : ^
:   : :
  xFoo...eFoo   xBareBar
^   ^ ^:
|   :.|:
| |
   Foo..Bar

The method dispatch path for this is pretty much the same as above,  
with the addition of CustomMeta2. This example now actually brings up  
another issue.


What should the superclass ordering be within the x* classes?

If eBar comes first, followed by CustomMeta2, then we get the  
following method dispatch path:


Bar.foo
  xBar.has_method(foo) # xBar should never have any of it's own method
eBar.has_method(foo)
  eFoo.has_method(foo)
CustomMeta2.has_method(foo) # this would fall here under C3
  Class.has_method(foo)
! Method Not Found Error !

But if CustomMeta2 comes first, followed by eBar, then we get the  
following method dispatch path:


Bar.foo
  xBar.has_method(foo)
CustomMeta2.has_method(foo)
  eBar.has_method(foo)
eFoo.has_method(foo)
Class.has_method(foo)
  ! Method Not Found Error !

The question really is, which has precedence, the custom metaclass,  
or the local class methods (including class methods inherited along  
normal class lines)?


Now, all these method dispatch paths are using the C3 MRO. And  
personally I find neither of these approaches to be the best. One  
alternate (but kind of whacky) approach would be to not use C3 here,  
but instead use breath-first traversal.


Now, this may seem really odd at first, but given the highly regular  
structure of these class groupings, it might make the most sense.  
Here is what that method dispatch path might look like:


Bar.foo
  xBar.has_method(foo)
eBar.has_method(foo)
  CustomMeta2.has_method(foo)
eFoo.has_method(foo)
  Class.has_method(foo)
! Method Not Found Error !

Notice how the eBar (which hold's Bar's class methods) is first,  
followed by the CustomMeta2 class, the followed by eFoo, then onto  
Class.


This specialized dispatching behavior could (I

Class Methods, Eigenclasses and $?CLASS

2005-10-10 Thread Stevan Little

Evening all,

So I am in the process of adding class-methods into the meta-model  
using eigenclasses. Eigenclasses are a ruby thing (and also a CLOS  
thing IIRC), in which an anon-class is inserted between an instance  
and it's class, essentially replacing the instance's class. The anon- 
class then adds the original class to it's superclass list. This is  
best shown visually I think:


 ::Class
^
:  -- eFoo is a subclass of Class
:
 ::eFoo   # eFoo is also an instance of Class
|
|  -- eFoo is the class of Foo
V
  ::Foo

The dispatching of instance methods is still the same, and everything  
just works. Well... almost everything.


There is a slight issue/inconsitency with how $?CLASS works.

class Foo {
method bar (Class $c:)  { $?CLASS }
method baz (Foo $self:) { $?CLASS }
}

Within the bar class-method, the natural inclination is to think  
that $?CLASS will refer to ::Foo. However, in order to be consistent  
it actually refers to the eigenclass between ::Foo and ::Class, lets  
call it ::eFoo. This is because methods are associated with the class  
which contains them. In the baz instance-method, $?CLASS does refer  
to ::Foo, since ::Foo is the class which contains baz.


It seems to me that this inconsistency could be very problematic,  
especially since eigenclasses should really be an invisible  
implementation detail.


I am not 100% sure of what is the correct approach here, so I thought  
I would ask the group. Any thoughts guys/gals?


Thanks,

Stevan




Re: Class Methods, Eigenclasses and $?CLASS

2005-10-10 Thread Luke Palmer
On 10/10/05, Stevan Little [EMAIL PROTECTED] wrote:
   ::Class
  ^
  :  -- eFoo is a subclass of Class
  :
   ::eFoo   # eFoo is also an instance of Class
  |
  |  -- eFoo is the class of Foo
  V
::Foo

 The dispatching of instance methods is still the same, and everything
 just works. Well... almost everything.

How do you explain this:

class Foo {
method bar (Class $class:) { class method }
}
say Foo.bar;# class method
my $foo = Foo.new;
say $foo.bar;   # class method

Assuming that that is valid Perl.

Luke


Re: Class Methods, Eigenclasses and $?CLASS

2005-10-10 Thread Stevan Little

Luke,

On Oct 10, 2005, at 7:47 PM, Luke Palmer wrote:

How do you explain this:

class Foo {
method bar (Class $class:) { class method }
}
say Foo.bar;# class method
my $foo = Foo.new;
say $foo.bar;   # class method

Assuming that that is valid Perl.


It is valid Perl 5, however (IMHO) it is *not* valid Perl 6.

To start with, the type of the invocant is Class, which $foo is not  
derived from (it is an instance of something which itself is an  
instance of Class).


I think that

  $foo.class.bar()

should work. And changing the method defintion to be

  method bar (Class|Foo $class:) { ... }

should work, but the code as you wrote it should not. Which means  
that when we deal with Perl 5 classes within Perl 6, we should likely  
give them an implied signature of (Class|Foo $self:) or some other  
weirdness (I haven't thought that far down the line yet).


Class methods are strange creatures, in Perl 5 they were nothing  
different than instance methods. In Java (static methods), they are  
really just odd functions which need to be qualified by a class name.  
Python doesn't even really have them (you have to jump through odd  
hoops to make the method callable). Ruby uses Eigenclasses, and  
CLOS uses something akin to eigenclasses. I am not sure how Smalltalk  
handles things, but my guess is that class methods on Foo are  
instance methods of classFoo, or some such.


They are ugly beasties no matter what, but eigenclasses (so far) seem  
to be the prettiest of the uglies.


Stevan




  1   2   3   4   >