Re: Extending classes in a lexical scope?

2009-01-14 Thread Ovid
- Original Message 


> As far as I know, "Perl6Array" should _not_ be showing up in
> Perl 6's namespace, and if it is doing so, that's a reportable
> bug.

I was just being sloppy.  I was using that in PIR, not Rakudo, and I mistyped 
the type -- er, I wrote the wrong class name in writing that email.

 
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: Extending classes in a lexical scope?

2009-01-13 Thread Patrick R. Michaud
On Mon, Jan 12, 2009 at 02:02:38PM -0800, Larry Wall wrote:
> 
> As for Perl6Array, that's a rakudo type, not a Perl 6 type, so I
> can't speak for it.  I'd just as soon that the name not show up in
> Perl 6's namespace, if I had my druthers.

As far as I know, "Perl6Array" should _not_ be showing up in
Perl 6's namespace, and if it is doing so, that's a reportable
bug.

The only reason that Rakudo even uses "Perl6Array" instead of
"Array" is that Parrot already defines an "Array" class, and as
yet Parrot doesn't allow other HLLs to create classes with the
same names as existing ones (TT #71).  So, Rakudo works around 
this issue by internally prefixing some classes with "Perl6" --
but it really is intended to be purely internal.  When Parrot
fixes its class registry bug then we'll get rid of these 
internal workarounds as well.

Pm


Re: Extending classes in a lexical scope?

2009-01-12 Thread Larry Wall
On Mon, Jan 12, 2009 at 04:38:07PM -0800, Jon Lang wrote:
: No, you don't understand me.  The Foo/Bar example I was giving was
: independent of your example.  Rephrasing in your terms, consider the
: possibility of a class that's derived from Array, for whatever reason;
: call it "Ring".  Now you decide that you want to redefine Array to
: include a shuffle method, and so you implement an "Array version 2.0".
:  Would you be given a "Ring version 2.0" that derives from Array
: version 2.0, or would you have to explicitly ask for it?

When a Ring object refers to Array that reference is supposed to be
virtual, so at least going that direction, the Ring object will be
implemented in terms of Array 2.0, if that is the meaning of Array to
the current object.  Extending that back into BUILD time, this implies
that in "class Ring is Array", the new Ring object needs to know how
to make Array virtual even though the object isn't constructed yet.
Neat trick, if we can pull it off...

Possibly when we compile the Ring protoobject in a lexical scope
with Array ::= Array:ver<2.0>, at that point we can record with the
new Ring alias that any new Ring object made with that protoobject
must use Array:ver<2.0>.  Or something like that.  For the situation
to arise, the lexical scope must know about Ring objects somehow.
This would handle the explicit

use Ring;

case, but I'm not so sure about indirect Ring objects that come
in from elsewhere.  They might have already been constructed with
Array:ver<1.0>.  Not sure what we can do about that.  It doesn't seem
like the kind of info you want to carry around with every object,
so you end up attaching it to the type.  If you get an object of two
different versions, at some point you end up re-inventing version
control merges for object attributes, and then you're probably
just hosed.

Or you just call it a "sync" and pretend it's no problem. :)

Larry


Re: Extending classes in a lexical scope?

2009-01-12 Thread Jon Lang
Ovid wrote:
> - Original Message 
>
>> From: Jon Lang 
>
>> > Actually, I'd prefer to go much further than this:
>> >
>> >  use Core 'MyCore';
>> >
>> > And have that override core classes lexically.
>> >
>> > That solves the "but I want it MY way" issue that many Perl and Ruby
>> programmers have, but they don't shoot anyone else in the foot.
>>
>> Since 'use' imports its elements into the current lexical scope, the
>> version-based approach can do this.
>>
>> The only catch that I can think of has to do with derived classes:
>> does the existence of a customized version of a class result in
>> same-way-customized versions of the classes that are derived from the
>> original class?  That is, if I added an "updated" version of Foo, and
>> Bar has previously been defined as being derived from Foo, would I get
>> a default "updated version" of Bar as well?  Or would I have to
>> explicitly update each derived class to conform to the updated base
>> class?
>
>
> I'm not sure I understand you.  If 'Bar' inherits from 'Foo' and 'Foo' has 
> extended the core Array class to lexically implement a .shuffle method, then 
> I would expect 'Bar' to have that also.

No, you don't understand me.  The Foo/Bar example I was giving was
independent of your example.  Rephrasing in your terms, consider the
possibility of a class that's derived from Array, for whatever reason;
call it "Ring".  Now you decide that you want to redefine Array to
include a shuffle method, and so you implement an "Array version 2.0".
 Would you be given a "Ring version 2.0" that derives from Array
version 2.0, or would you have to explicitly ask for it?

As long as you limit your use of class inheritance, the above remains
manageable.  But consider something like the Tk widgets implemented as
a class hierarchy; then consider what happens if you reversion one of
the root widgets.  If you manually have to reversion each and every
widget derived from it, and each and every widget derived from those,
and so on and so forth, in order for your changes to the root to
propagate throughout the class hierarchy...

Instead, I'd rather see an approach where you need only reversion the
base class and those specific derived classes where problems would
otherwise arise due to your changes.

-- 
Jonathan "Dataweaver" Lang


Re: Extending classes in a lexical scope?

2009-01-12 Thread Larry Wall
On Mon, Jan 12, 2009 at 02:43:37PM -0800, Ovid wrote:
: Actually, I'd prefer to go much further than this:
: 
:   use Core 'MyCore';
: 
: And have that override core classes lexically.

We're already speccing a way to substitute a different prelude from
the command line, in order to desugar -n and -p switches.  There could
certainly be a use-ish way to do that too.  And maybe "substitute"
is the wrong concept here.  It probably needs to be nestable, so that
we are installing an additional lexical wrapper outside the current
scope, but inside whatever the previous prelude scope provided.
Maybe call it "underriding" instead of "overriding".  :)

So given something like:

#!/usr/bin/perl6 -p
use prelude MyPrelude;

Then OUTER of MyPrelude might be a -p looping scope, and OUTER of the
-p scope might be the standard Perl 6 Prelude.  And this happens a
compilation time, so the compiler knows while it's parsing that any
reference to Array mean MyArray, including any implicit references.

The mechanism by which we freeze a snapshot of the language (nice
mixed metaphor there) for the prelude is also the mechanism by which
we freeze a snapshot so we know what language eval() defaults to.
It doesn't default to standard Perl 6, but rather the language existing
at the moment the eval is compiled, which might have little resemblence
to standard Perl 6.

I really do believe in lexically-scoped language mutations: it's
not just a bullet point--it's what Perl 6 is Really All About, in
my ever-so-humble opinion.  To make that work right, every part of
your lexical scope needs to know *exactly* what language it's in,
including the parts that are intentionally inexact; any parts of
the language that are generic need to be explicitly parameterized,
not nebulously defined by some environment variable or by some rc
file or even by the current perl implementation.

As far as I'm concerned, everything else about Perl 6 is a bikeshed in
comparison, because everything else about Perl 6 can change gracefully
over time if we get this part right.  The current lexical context
determines the types that are visible, as well as the multimethods
that are visible on those types, including the operations used to
parse and mutute the language itself.  Seems simple enough...  :)

Larry


Re: Extending classes in a lexical scope?

2009-01-12 Thread Ovid
- Original Message 

> From: Jon Lang 

> > Actually, I'd prefer to go much further than this:
> >
> >  use Core 'MyCore';
> >
> > And have that override core classes lexically.
> >
> > That solves the "but I want it MY way" issue that many Perl and Ruby 
> programmers have, but they don't shoot anyone else in the foot.
> 
> Since 'use' imports its elements into the current lexical scope, the
> version-based approach can do this.
> 
> The only catch that I can think of has to do with derived classes:
> does the existence of a customized version of a class result in
> same-way-customized versions of the classes that are derived from the
> original class?  That is, if I added an "updated" version of Foo, and
> Bar has previously been defined as being derived from Foo, would I get
> a default "updated version" of Bar as well?  Or would I have to
> explicitly update each derived class to conform to the updated base
> class?


I'm not sure I understand you.  If 'Bar' inherits from 'Foo' and 'Foo' has 
extended the core Array class to lexically implement a .shuffle method, then I 
would expect 'Bar' to have that also.  There are two things involved:

1.  Liskov should be respected, when appropriate 
(http://www.oreillynet.com/onlamp/blog/2008/02/the_liskov_substitution_princi.html)
2.  'Bar' is coupled to 'Foo' and needs to know 'Foo's implementation (a 
charming anti-inheritance argument).  See #1 :)

Or did you mean something completely different?
 
Note that Liskov is great, but has issues at times when composition is unclear.

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: Extending classes in a lexical scope?

2009-01-12 Thread Jon Lang
Ovid wrote:
> Actually, I'd prefer to go much further than this:
>
>  use Core 'MyCore';
>
> And have that override core classes lexically.
>
> That solves the "but I want it MY way" issue that many Perl and Ruby 
> programmers have, but they don't shoot anyone else in the foot.

Since 'use' imports its elements into the current lexical scope, the
version-based approach can do this.

The only catch that I can think of has to do with derived classes:
does the existence of a customized version of a class result in
same-way-customized versions of the classes that are derived from the
original class?  That is, if I added an "updated" version of Foo, and
Bar has previously been defined as being derived from Foo, would I get
a default "updated version" of Bar as well?  Or would I have to
explicitly update each derived class to conform to the updated base
class?

-- 
Jonathan "Dataweaver" Lang


Re: Extending classes in a lexical scope?

2009-01-12 Thread Ovid
- Original Message 

> From: Moritz Lenz 

> > That is the preferred way to avoid action-at-a-distance in P6.
> 
> so if I do that, will a 'my @a' use that new Array class?
> 
> Actually I'd prefer it if there were some kind of mechanism to set a
> default implementation type, so that I could write something along these
> lines:
> 
> class MyArray is Array { ... }
> use Container :Array;
> 
> then is this lexical scope all Array declarations and all Prelude
> operations that return Arrays return one of the type that I specified.


Actually, I'd prefer to go much further than this:

  use Core 'MyCore';

And have that override core classes lexically.
 
That solves the "but I want it MY way" issue that many Perl and Ruby 
programmers have, but they don't shoot anyone else in the foot.

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: Extending classes in a lexical scope?

2009-01-12 Thread Moritz Lenz
Larry Wall wrote:
> : however, I believe
> : that it _is_ possible to derive a new class whose "name" differs from
> : an existing class only in terms of version information, such that it
> : is substituted for the original class within the lexical scope where
> : it was defined, barring explicit inclusion of version information when
> : the class is referenced.
> 
> That is the preferred way to avoid action-at-a-distance in P6.

so if I do that, will a 'my @a' use that new Array class?

Actually I'd prefer it if there were some kind of mechanism to set a
default implementation type, so that I could write something along these
lines:

class MyArray is Array { ... }
use Container :Array;

then is this lexical scope all Array declarations and all Prelude
operations that return Arrays return one of the type that I specified.

Cheers,
Moritz


Re: Extending classes in a lexical scope?

2009-01-12 Thread Larry Wall
On Mon, Jan 12, 2009 at 03:38:04AM -0800, Jon Lang wrote:
: Ovid wrote:
: > Is it possible to modify the core Perl6Array class like that (without extra 
keywords)?  If so, is it possible for each programmer to make such a change so 
that it's lexically scoped?
: 
: AFAIK, it is not possible to modify a core class;

Well, you can always say

class Array is also { ... }

Classes are open by default and may only be closed by the
application-level optimizer, if no one requests the class remain
open permanently.  However, we do not glorify monkeytyping to the
extent that, say, Ruby culture does.

As for Perl6Array, that's a rakudo type, not a Perl 6 type, so I
can't speak for it.  I'd just as soon that the name not show up in
Perl 6's namespace, if I had my druthers.

: however, I believe
: that it _is_ possible to derive a new class whose "name" differs from
: an existing class only in terms of version information, such that it
: is substituted for the original class within the lexical scope where
: it was defined, barring explicit inclusion of version information when
: the class is referenced.

That is the preferred way to avoid action-at-a-distance in P6.

Larry


Re: Extending classes in a lexical scope?

2009-01-12 Thread Jon Lang
Ovid wrote:
> Is it possible to modify the core Perl6Array class like that (without extra 
> keywords)?  If so, is it possible for each programmer to make such a change 
> so that it's lexically scoped?

AFAIK, it is not possible to modify a core class; however, I believe
that it _is_ possible to derive a new class whose "name" differs from
an existing class only in terms of version information, such that it
is substituted for the original class within the lexical scope where
it was defined, barring explicit inclusion of version information when
the class is referenced.

-- 
Jonathan "Dataweaver" Lang


Extending classes in a lexical scope?

2009-01-12 Thread Ovid
Let's say two people want to add a 'shuffle' method to all arrays.  Alice wants 
to have it look like this:

  method shuffle (*...@array is rw) {
  @array .= pick(*);
 }

Bob wants it to look like this:

  method shuffle (*...@array is rw) {
  @array = @array[0 .. @array/2] Z @arr...@array/2+1 .. @array];
  }

 
Thus, each wants to do the following, being able to modify the array in place:

  my @array = ^10;
  @array.shuffle;

Is it possible to modify the core Perl6Array class like that (without extra 
keywords)?  If so, is it possible for each programmer to make such a change so 
that it's lexically scoped? 

Oh, and the difference between those, for lurkers:

  perl6 $ perl6 -e 'my @a = ; [...@a[0..@a/2] 
z...@a[@a/2+...@a]].perl.say'
  ["a", "e", "b", "f", "c", "g"]
  perl6 $ perl6 -e 'my @a = ; @a .= pick(*); @a.perl.say'
  ["g", "a", "f", "c", "e", "d", "b"]

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