Re: unusual invocants

2009-10-21 Thread Ovid
- Original Message 

 From: TSa (Thomas Sandlaß) tho...@sandlass.de

   So what the OP wants to do is declare a method that is available on
   all those invocants - and only those invocatnts - which do all of
   roles X, Y, and Z.  Granted, you can declare a new role XandYandZ
   that does X, Y, and Z, and define the method there, but that won't
   work on $foo unless you declare explicitly  '$foo does
   XandYandZ' .  The goal is to have the method show up no matter how
   $foo comes to do all three roles.
 
  Right.
 
 I have difficulty seeing the need for a method here. The distinguishing
 feature of a method is the access to the private data of an object that
 can hardly be granted by doing the three roles X, Y and Z. After all
 there's no unique implementation of these roles!

I believe I started this thread, unless we mean John Lang as the OP after the 
rename.

Private state is actually a separate issue and one which the traits 
researchers already dig into. I was asking the special case where:

1. A class consumes two (or more) roles
2. Each roles provides a method with an identical signature
3. The methods are not equivalent and neither role can rely on the other's 
method

 
With that, you have roles which cannot be composed. You must rewrite one (bad 
if you don't own it), or omit one..

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



r28868 - docs/Perl6/Spec

2009-10-21 Thread pugs-commits
Author: moritz
Date: 2009-10-21 09:55:53 +0200 (Wed, 21 Oct 2009)
New Revision: 28868

Modified:
   docs/Perl6/Spec/S06-routines.pod
Log:
[S06] more consistency on name collisions in signatures, masak++

Modified: docs/Perl6/Spec/S06-routines.pod
===
--- docs/Perl6/Spec/S06-routines.pod2009-10-21 02:51:54 UTC (rev 28867)
+++ docs/Perl6/Spec/S06-routines.pod2009-10-21 07:55:53 UTC (rev 28868)
@@ -503,7 +503,7 @@
 possible on those arguments that are bound to a final slurpy or
 arglist variable.)
 
-All parameters must either have a unique name (sigil included)
+All parameters must either have a unique name (sigil excluded)
 or be anonymous. Declaring a routine having two positionals with exactly
 the same name counts as a compile-time error. Renaming a named parameter
 can also cause forbidden name collisions:



r28870 - docs/Perl6/Spec

2009-10-21 Thread pugs-commits
Author: masak
Date: 2009-10-21 10:50:10 +0200 (Wed, 21 Oct 2009)
New Revision: 28870

Modified:
   docs/Perl6/Spec/S06-routines.pod
Log:
[S06] third attempt at describing elusive name collision

Modified: docs/Perl6/Spec/S06-routines.pod
===
--- docs/Perl6/Spec/S06-routines.pod2009-10-21 08:46:25 UTC (rev 28869)
+++ docs/Perl6/Spec/S06-routines.pod2009-10-21 08:50:10 UTC (rev 28870)
@@ -503,12 +503,16 @@
 possible on those arguments that are bound to a final slurpy or
 arglist variable.)
 
-All parameters must either have a unique name (sigil excluded)
-or be anonymous. Declaring a routine having two positionals with exactly
-the same name counts as a compile-time error. Renaming a named parameter
-can also cause forbidden name collisions:
+A signature containing a name collision is considered a compile time
+error. A name collision can occur between positional parameters, between
+named parameters, or between a positional parameter and a named one.
+The sigil is not considered in such a comparison, except in the case of
+two positional parameters -- in other words, a signature in which two
+or more parameters are identical except for the sigil is still OK (but
+you won't be able to pass values by that name).
 
-:($a, $a)   # wrong, two a
+:($a, $a)   # wrong, two $a
+:($a, @a)   # OK (but don't do that)
 :($a, :a($b))   # wrong, one a, one a through renaming
 :($a, :a(@b))   # wrong 
 :(:$a, :@a) # wrong



Re: unusual invocants

2009-10-21 Thread Mark J. Reed
On Wed, Oct 21, 2009 at 3:47 AM, Ovid
publiustemp-perl6langua...@yahoo.com wrote:
 I was asking the special case where:

 1. A class consumes two (or more) roles
 2. Each roles provides a method with an identical signature
 3. The methods are not equivalent and neither role can rely on the other's 
 method


 With that, you have roles which cannot be composed. You must rewrite one (bad 
 if you don't own it), or omit
 one..

Rather than disallow the composition, I'd say that any class, role, or
object that does both roles must override the method in question.
Which takes us back to Jon's branch of the thread: it would be nice to
be able to declare such an override in a general way that will apply
to any such composition that doesn't otherwise override it locally.
But what should that declaration look like?


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


Re: unusual invocants

2009-10-21 Thread Jon Lang
Jonathan Worthington wrote:
 Ovid wrote:

 I was asking the special case where:

 1. A class consumes two (or more) roles
 2. Each roles provides a method with an identical signature
 3. The methods are not equivalent and neither role can rely on the other's
 method

  With that, you have roles which cannot be composed. You must rewrite one
 (bad if you don't own it), or omit one..

 When a role is composed into a class, it does quite literally become as if
 it were declared within the class itself (appears directly in the methods
 list), but equally does not lose its lexical scoping relationship with the
 role it was declared in either. Would it help to say that when a method
 declared within a role invokes another method, then we first search the
 methods within that role's lexical scope? Therefore:

 role Drinking {
   method buy_beer() {
       self.go_to_bar();
       ...
   }
   method go_to_bar() {
       ...
   }
 }

 role Gymnastics {
   method go_to_bar() {
   }
 }

 class DrunkGymnast does Drinking does Gymnastics {
   method go_to_bar() {
       # something to resolve the conflict here
   }
 }

 This way, the method buy_beer will always consider methods in its lexical
 scope first and thus find the role's go_to_bar rather than the one in the
 class. Of course, if the role's lexical scope had no methods of that name
 declared within it we'd go elsewhere.

This is close to what I've been suggesting in terms of checking which
hat the object is wearing (or, alternately, which role it is
performing).  The main difference is that the final say _must_ be
given to the class, because only the class knows enough about the
implementation to be sure to do the right thing.  For instance, what
if you want the DrunkGymnast who goes to the bar in the Drinking sense
to automatically be given a citation for doing so?  class DrunkGymnast
is the place where this issue must be addressed.  Or worse: if you
have her go_to_bar in the Drinking sense, you set a flag that
indicates that she's drunk; and if you have her go_to_bar in the
Gymnastics sense while she's drunk, the call should fail.  This can
only be done if you can define two distinct go_to_bar methods within
the class, because Perl no longer has a want mechanism that would
allow one method to handle both cases.

This is where my proposal for disambiguating the two of them according
to the invocant comes in.  Ovid need not be right about his statement
#2: while the two methods have the same short names (e.g.,
go_to_bar) and accept the same arguments (e.g., none), they don't
necessarily have the same signatures, because they can use the
invocant's type to address the in the Drinking sense and in the
Gymnastics sense concept that I was using in the previous paragraph.
As such, the two methods can have the same names and the same
parameter lists, but still have different signatures (and thus
different long-names): go_to_bar:(Drinking:) and
go_to_bar:(Gymnastics:).

The trick would lie in making the compiler smart enough to DWIM in
most cases (by figuring out for itself which sense you mean), and in
providing an easy-to-use means of explicitly choosing a sense to cover
the remaining cases.

I have some more thoughts on this; but I'm on a time crunch at the
moment, and would really like to get some feedback on the above before
proceeding further: have I missed anything in my reasoning?

-- 
Jonathan Dataweaver Lang


Parrot 1.7.0 African Grey Released!

2009-10-21 Thread Jonathan Leto
  Come, let us hasten to a higher plane
  Where dyads tread the fairy fields of Venn,
  Their indices bedecked from one to ''n''
  Commingled in an endless Markov chain!

  I'll grant thee random access to my heart,
  Thou'lt tell me all the constants of thy love;
  And so we two shall all love's lemmas prove,
  And in our bound partition never part.

  Cancel me not — for what then shall remain?
  Abscissas some mantissas, modules, modes,
  A root or two, a torus and a node:
  The inverse of my verse, a null domain.

   -- Stanisław Lem, Love and Tensor Algebra

On behalf of the entire Parrot team, I'm proud to announce Parrot
1.7.0 African Grey. Parrot is
a virtual machine aimed at running all dynamic languages.

Parrot 1.7.0 is available on Parrot's FTP site [0], or you can follow
the download
instructions on our website.  For those who would like to develop on
Parrot, or help
develop Parrot itself, you can check out the latest and best source
code with Subversion:

svn co https://svn.parrot.org/parrot/trunk parrot

For the most recent list of languages that target Parrot and their
status, consult the Parrot Trac Wiki [2].

[0] - ftp://ftp.parrot.org/pub/parrot/releases/devel/1.7.0/
[1] - http://parrot.org/download
[2] - https://trac.parrot.org/parrot/wiki/Languages

New in 1.7.0:

- Functionality
 + Parrot_capture_lex has been added to the PARROT_EXPORT API
 + PARROT_MAX_ARGS has been increased from 8 to 16 to allow for
   ops that take more than 8 args
- Performance
 + The profiling runcore now caches metadata for improved performance
- Maintenance and cleanup
  + Expanded the Parrot debugger documentation
  + Parrot debugger now uses the new Parrot STRING API
  + Continue to port rest of internals to use the STRING API
- Deprecations
 + The JIT subsystem has been removed and is being written from the
   ground up. More information can be found at
   https://trac.parrot.org/parrot/wiki/JITRewrite
 + Implicit optional named parameters (eligible in 2.1)
 + Continuation-based ExceptionHandlers (eligible in 2.1)
 + Use of undocumented variables in class_init (eligible in 2.1)
 + Parrot_oo_get_namespace (eligible in 2.1)
- Bugfix
  + Improved line number tracking in IMCC
- Tests
  + Converted many more Perl 5 tests to PIR
  + Expanded test coverage of the CallSignature, Namespace, FixedPMCArray,
ResizeableIntegerArray and ExceptionHandler PMCs

Happy Hacking!

-- 

Jonathan Leto
jonat...@leto.net
http://leto.net


Re: unusual invocants

2009-10-21 Thread TSa

HaloO,

Jon Lang wrote:

I have some more thoughts on this; but I'm on a time crunch at the
moment, and would really like to get some feedback on the above before
proceeding further: have I missed anything in my reasoning?


I fully understand what you mean, I hope. But note that all instances
of the class that does the two roles do both roles. So the object at
hand can't select the dispatch target. So it has to come from the
*environment* of the call. I consider this as very problematic because
essentially you have to import that into the object so that it can be
carried for a while---this is what you call wearing a role hat. We
should keep the class dispatch as simple as possible and not mix in
the environment of the call into the meaning of an object!

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: unusual invocants

2009-10-21 Thread Jon Lang
TSa wrote:
 Jon Lang wrote:

 I have some more thoughts on this; but I'm on a time crunch at the
 moment, and would really like to get some feedback on the above before
 proceeding further: have I missed anything in my reasoning?

 I fully understand what you mean, I hope. But note that all instances
 of the class that does the two roles do both roles. So the object at
 hand can't select the dispatch target. So it has to come from the
 *environment* of the call. I consider this as very problematic because
 essentially you have to import that into the object so that it can be
 carried for a while---this is what you call wearing a role hat. We
 should keep the class dispatch as simple as possible and not mix in
 the environment of the call into the meaning of an object!

Usually, I'd agree with you - and even here, I'd say that if you can
somehow resolve the dilemma without reference to the environment, that
would be preferable.  However, the only options that appear to be
available without it are the two that Ovid outlined: rewrite one of
the roles, or omit one of them.  Both of these options become
impractical once you account for the likes of CPAN:

* Rewriting one of the roles may not be possible if the programmer
doesn't own either of the offending roles; and even if it is possible,
it likely involves a massive search-and-replace operation that isn't
easily automated.

* Omitting one of the roles is reasonable as long as you can guarantee
that the overall concepts that the roles represent shouldn't be mixed
(as is arguably the case for the traditional Dogwood example); but
it's less than satisfactory when the only reason they can't be mixed
is that each role's author made an unfortunate naming choice for one
of the methods.

My proposal isn't perfect, either: if an established routine fails to
place the appropriate hat on the schizophrenic object, the
environment-based disambiguation won't DWIM and the programmer will be
forced to explicitly resolve the conflict before passing the object
into that routine.  Still, I don't get the same sense of it being a
potential show-stopper the way that I get from the alternatives.

But, as always, the devil's in the details.  Perhaps someone _can_
provide a means of rewriting one of the roles in a way that won't
break anything (the interface, the compiler's back, or the
programmer's mind).  And it may turn out that my proposal is
unworkable once we start looking into the details of how it would be
implemented.

You mentioned that my approach involves importing a bit of the
environment into the object for a while.  How might this be done in a
way that won't wreak havoc?  One possibility would be to hide it away
as a trait of WHAT, and then look for that trait when it comes time to
disambiguate the schizo invocants:

sub party(Drinking $x) { # $x.WHAT:role = Drinking
... $x.go_to_bar; ... # same as $x.go_to_bar:(Drinking:)
}

sub compete(Gymnast $x) { # $x.WHAT:role = Gymnast
... $x.go_to_bar; ... # same as $x.go_to_bar:(Gymnast:)
}

sub joke($x) { $x.WHAT:role is not set
... $x.go_to_bar; ... # can't be resolved without more information

given Gymnast $x { # $x.WHAT:role = Gymnast
... joke($x); ... # the joke is about a Gymnast's bar.
}

Likewise, a method that originated in Drinking (such as .buy_beer)
would set self.WHAT:role to Drinking, thus resulting in any call to
.go_to_bar getting the right method from the class. (Thanks for the
example, Jonathan; I hadn't thought of that rather obvious case.)  If
DrunkGymnast replaces .buy_beer or adds a new method that calls
.go_to_bar, it won't automatically have knowledge of which hat it
should be wearing; but that's OK, because it's expected to know about
both hats, and can explicitly don the right one before (or when)
calling the conflicted method.  It's only those environments that
can't be expected to know about the dual possibilities that concern
me.

What other problems might arise, and how might they be solved?

-- 
Jonathan Dataweaver Lang


Re: unusual invocants

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

On Wednesday, 21. October 2009 12:40:06 Mark J. Reed wrote:
 Rather than disallow the composition, I'd say that any class, role, or
 object that does both roles must override the method in question.

The problem that Ovid posed needs to be resolved in the dispatch
tables seen in certain methods of a class. So the solution is not
overriding the offending method x but the calls to it in methods
foo and bar! The interesting thing is that you have to dig that
information out from the source of the roles T1 and T2. I doubt
that a programmer making the dependency mistake also documents it ;)
I've never seen a call graph of a library in any documentation.


 Which takes us back to Jon's branch of the thread: it would be nice to
 be able to declare such an override in a general way that will apply
 to any such composition that doesn't otherwise override it locally.
 But what should that declaration look like?

Here is a direct syntax for the freeze feature of the paper:

  class C does T1 does T2
  {
  freeze T1::x for foo;
  freeze T2::x for bar;
  method x {...} # for all other methods
  }

The implementation is strait forward: on entry to foo and bar
the dispatch table of the invocant is temporarily patched to
contain the right x. After the call the original is restored.

Heretic question: would it make sense to have a method registry
for roles in CPAN? At least for a set of 'standard' modules that
then allow arbitrary role combinations without conflict.


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