Parrot and PGE will save the day (was Re: "as if" [Was: Selective reuse of storage in &bless.] )

2006-01-20 Thread Rob Kinyon
On 1/20/06, Nicholas Clark <[EMAIL PROTECTED]> wrote:
> On Fri, Jan 20, 2006 at 04:20:54PM -0500, Rob Kinyon wrote:
> > Pros: Larry doesn't have to do anything more on the WMoT.
> > Cons: The community, for some reason, really wants this
> > auto-translator, even though there wasn't one for P4->P5 and P5->P6 is
> > a greater leap than P4->P5 was.
>
> But (as I understood it) the P4->P5 leap was not intended to be so great
> that a translator would be needed. In fact, that confuses cause and effect.
> Because the technology wasn't there to write a translator, it constrained the
> size of the leap. The important part was that for Perl 5 to still be Perl,
> it had to keep running the vast majority of Perl scripts.
>
> In fact, Perl 5 still strives to maintain Perl 1 compatibility (and the
> perl5-porters joke is that even thinking about breaking this is the fastest
> way to summon the thought, er backwards compatibility police with a script
> he's been running unchanged since 1987). Why else can you still:
>
> $ perl -le '$h{1} = "Perl"; print values h'
> Perl
> $ perl -le 'push a, "Perl"; print @a'
> Perl

Now, that's an unadvertised feature! I think I need to revisit some golfs ...

> I believe that the translator is seen as needed (even by @Larry, I think)
> to maintain the same level of continuity in the Perl 5->6 transition as
> Perl 4->5 - your existing monolithic script runs on the newer Perl
> interpreter, and you can edit (within that same file) as and when you need
> to.
>
> Otherwise you're in the situation where you can only inter-operate languages
> the whole file level. Which means that it's the same actions to migrate from
> Perl 5 to (say) Python as from Perl 5 to Perl 6. And somehow I think that
> $Larry has some bias about which language he'd prefer everyone to find it
> easiest to migrate to, even if he's too modest to admit it.

Please don't take offense at this, but I believe you're using 20th
century thinking. The two most important features in Perl6 aren't -in-
Perl6 - they're Parrot and the PGE. Both of them make a translator
unnecessary. More precisely, they make a file-in-P5 to file-in-P6
translator unnecessary because you can have block-level
interoperability.

I'm making a few assumptions here:
1) Since PGE isn't part of Perl6 (because it's written in PIR), it
can be used as the parser/lexer/etc. for any language, not just Perl6.
2) Since PGE can be lexically-scoped, one can change the entire
grammar within a given block, including how variables are referenced,
subroutines are called, etc.
3) Since everything is, at the heart, just a PMC, so long as the
appropriate PIR is emitted, it doesn't matter how the userside code is
written so long as the right parser/lexer/whatever is used to
translate it to PIR.

So, if all three assumptions hold, then your monolithic Perl5 script
can easily inline any Parrot-targeted language you want, simply by
doing the following:
1) Use Ponie.
2) Within a block, import the appropriate PGE module(s) to
redefine the grammar to P6 and do what you need to do.

No translator needed.

Rob


perl6-language@perl.org

2006-01-20 Thread Stevan Little
Larry Wall wrote:
> On Fri, Jan 20, 2006 at 09:35:13PM +0800, Audrey Tang wrote:
> My original intent was #2, hence the wording in A12.  But to speak to
> some of Stevan's concernes, there's something going on here which is
> not quite "Object does Hash".  It's more like "Object can do Hash",
> in the linguistic sense that a "Noun can do Verb", but nonetheless
> remains a noun.  A fallback role is not the same as a normal role.
> Maybe there's some way to mixin in a fallback Hash role without
> clobbering a real Hash role that is already there, so that if your
> Hash container is an object you don't see methods for its keys.
>
> Something like this might also let us distinguish p5ish scalars that
> are simultaneously Num and Str from scalars that, say, intrinsically
> do Num but can emulate Str in a pinch without caching the result.
> I don't think we have a good way of expressing that distinction right
> now.

I agree it is a hairy subject, but the more I think about this (and
the more i read about and play with CLOS) I think we might be able to
accomplish something very close to this by creating more special
purpose attribute meta-objects.

By moving much of the actual attribute accessing work to the attribute
meta-object, we can very easily have arbitrary object "types" since
all their access is mediated through the attribute meta-object.

In CLOS this would be accomplished by subclassing the standard-class,
and telling it to use the different attribute meta-object by default.
The of course you slap a juicy LISP macro around it, and you are ready
to go. Mm LISP macros :)

Basically my point is that the meta-classes and meta-objects govern
the behavior of the classes and object. So if we want to change the
behavior of our classes and objects, we just subclass the meta-classes
and meta-objects and specialize the behavior as we desire.

> This seems to imply that a given role like Hash could have two default
> implementations--one for an actual Hash container, and one that emulates
> a Hash by deferring to the Object.  It's sort of like a role that can
> delegate back to its own object.

This should all be possible with attribute meta-objects. Basically
when we encounter this type of need (in p5->p6 translated classes, or
otherwise), the compiler (or possibly the translator) needs to
discover this need, and change the metaclass appropriately. The self
delegation then Just Works.

Of course this is all just hand-waving right now since the current
metamodel does not support such deep magic. But hey, I have been
thinking it might be time for a v3 soon anyway :)

> Such issues arise whenever you start making statements of the form
> "I want to use an A as if it were a B."  The problem is much bigger
> than just how do I translate Perl 5 to Perl 6.  It's questions like:
>
> What makes a particular metaphor work?
> Will the cultural context support use of an A as if it were a B?
> How do we translate the user's thoughts to the computer's thoughts?
> How do we translate one user's thoughts to another user's thoughts?
> How do we know when such a translation is "good enough"?
> How do we know when our mental model of an object is adequate?
> How do we know when the computer's mental model of an object is adequate?
> What does adequate mean in context?

I am actually working with Rob Kinyon on a meta object protocol for
Perl 5 for our $work. It does not try to make Perl 5 anything it is
not, instead it only attempts to define the workings of the Perl 5
object system and provide clean hooks into it. It is in the very early
stages, and needs lots of testing, but it might help to bridge the two
models.

> Will the culture support partially instantiated objects?  :-)

Hmm, do you mean lazy objects? As in, only instantiated as much as is
absolutly necessary at a particular moment?

I recently read a paper on an extended version of CLOS (yay CLOS)
which demonstrated how lazy classes could be built, including ones
with strict initialization orders ($a must be initialized before $b,
but $b depends on $c, etc). But maybe this is not what you mean.

Or is this the "class but undef" idea again?

Audrey and I have "solved" this by creating a 'p6undef' repr type
which allows the class to be instantiated and methods called on it,
but if you try to access anything other than basic meta information,
it will fail (because it's just undef).

Actually, I think this partial object thing needs it own thread
really. But I will let you decide when you are ready for that one :)

Stevan


perl6-language@perl.org

2006-01-20 Thread Stevan Little
> On Thursday 19 January 2006 21:53, Stevan Little wrote:
> > With p5, you /can/ get to the underlying data structure. This is a
> > break which will hamper the backwards compatibility effort I think.
>
> With Perl 5, you can *appear* to get to the underlying data structure.  Yet
> tie() is basically free on Ponie and there's a metaclass mediating access to
> the underlying storage.  I think that makes the problem solvable.

Excellent.

> (Does using an alternate type of storage mean you need an alternate metaclass?
> Perhaps, perhaps not -- but the practical effects of syntax have to come from
> somewhere.)

Actually I was thinking this might be the best approach. I have been
dabbling more and more with CLOS lately and am not seeing where a
full-fledge attribute meta-object is probably a really good idea (in
the current model the meta-attribute is very very slim).

> As long as you can use Perl 5 classes in Perl 6 without rewriting all of the
> Perl 5 code, I'm happy.

Yes, this is the ultimate goal. I never wanted to get rid of &bless,
only to resolve what I saw as an inconsistency with the use of &bless
and some of the other aspects of the Perl 6 design.

Stevan


perl6-language@perl.org

2006-01-20 Thread Audrey Tang (autrijus)
On 1/21/06, Larry Wall <[EMAIL PROTECTED]> wrote:
> But maybe all this is already possible in the current setup, if
>
> role ObjectFakeHash does Hash {...}
> role Object does ObjectFakeHash {...}
> class Hash does Hash {...}

Yes, I think that's the way to go, as well as :coerce for explicit
class-based (instead of role-based) conversions.

Audrey


perl6-language@perl.org

2006-01-20 Thread Nicholas Clark
On Fri, Jan 20, 2006 at 04:20:54PM -0500, Rob Kinyon wrote:
> Pros: Larry doesn't have to do anything more on the WMoT.
> Cons: The community, for some reason, really wants this
> auto-translator, even though there wasn't one for P4->P5 and P5->P6 is
> a greater leap than P4->P5 was.

But (as I understood it) the P4->P5 leap was not intended to be so great
that a translator would be needed. In fact, that confuses cause and effect.
Because the technology wasn't there to write a translator, it constrained the
size of the leap. The important part was that for Perl 5 to still be Perl,
it had to keep running the vast majority of Perl scripts.

In fact, Perl 5 still strives to maintain Perl 1 compatibility (and the
perl5-porters joke is that even thinking about breaking this is the fastest
way to summon the thought, er backwards compatibility police with a script
he's been running unchanged since 1987). Why else can you still:

$ perl -le '$h{1} = "Perl"; print values h'
Perl
$ perl -le 'push a, "Perl"; print @a'
Perl


I believe that the translator is seen as needed (even by @Larry, I think)
to maintain the same level of continuity in the Perl 5->6 transition as
Perl 4->5 - your existing monolithic script runs on the newer Perl
interpreter, and you can edit (within that same file) as and when you need
to.

Otherwise you're in the situation where you can only inter-operate languages
the whole file level. Which means that it's the same actions to migrate from
Perl 5 to (say) Python as from Perl 5 to Perl 6. And somehow I think that
$Larry has some bias about which language he'd prefer everyone to find it
easiest to migrate to, even if he's too modest to admit it.

Nicholas Clark


perl6-language@perl.org

2006-01-20 Thread Jeff Stampes
I have to wonder how many other people just
edited /usr/share/games/fortune/perl and added:

%
Humans are not much into strong compile-time typing, and when they are,
we call it stereotyping, or racism, or whatever.
 -- Larry Wall in <[EMAIL PROTECTED]>

And now back to your regularly scheduled meaningful discussion already
in progress.
-- 
Jeff Stampes [ [EMAIL PROTECTED] ] -- Build and Release Tools
The older a man gets, the farther he had to walk to school as a boy.


perl6-language@perl.org

2006-01-20 Thread chromatic
On Thursday 19 January 2006 21:53, Stevan Little wrote:

> Okay, so when you say alternate storage then you mean that a class
> like this:
>
> class Foo {
>  has $.bar;
>  method new ($class, %params) {
>  $class.bless('p5Hash', %params);
>  }
>  method baz {
>   $.bar += 1;
>  }
> }
>
> should use a PMC representation of a p5 hash as it's storage, and
> that the method baz does the right thing here?

Yes.

> Because that makes sense to me. However, what doesn't make sense
> would be if I had to write &baz like this:
>
> method baz {
> self->{'bar'} += 1;
> }
>
> In other words, if this is just a detail of the storage, and does not
> affect user code at all, then I am okay with it. This though would
> mean that you would not have direct access to the underlying data
> structure (the p5 hash).

I don't think it's impossible, but it's fairly ugly and I'm okay if you can't 
do it by default from the Perl 6 side.  I certainly wouldn't use it.

From the Perl 6 side, I would rather use Perl 6 looking code.

> Okay, then I assume you mean it to behave the same way as with the
> p5hash, that it is completely transparent to the user that you are
> using a p5hash or a p6hash or a p6opaque?

From Perl 6?  Yes.

> In which case,.. I say okay. But note again that you have not
> provided access to the underlying data structure (the p6hash a.k.a -
> an instance of ^Hash).

Agreed.

> With p5, you /can/ get to the underlying data structure. This is a
> break which will hamper the backwards compatibility effort I think.

With Perl 5, you can *appear* to get to the underlying data structure.  Yet 
tie() is basically free on Ponie and there's a metaclass mediating access to 
the underlying storage.  I think that makes the problem solvable.

(Does using an alternate type of storage mean you need an alternate metaclass?  
Perhaps, perhaps not -- but the practical effects of syntax have to come from 
somewhere.)

As long as you can use Perl 5 classes in Perl 6 without rewriting all of the 
Perl 5 code, I'm happy.

-- c


perl6-language@perl.org

2006-01-20 Thread chromatic
On Friday 20 January 2006 07:14, Rob Kinyon wrote:

> I think this entire issue is rising out of the fact that very very few
> people in this discussion are familiar with the design of the MOP.
> Stevan and a few others are the primary movers and I'm lucky enough to
> have been Stevan's sounding board for a few pieces. Once you grok the
> MOP, it's really hard to imagine wanting to use bless().

I don't think that it's a fair assumption that, for example, I haven't 
followed the metamodel discussions and designs.  Nor do I think it's a fair 
assumption that people who want to interoperate with a lot of Perl 5 code 
should have to understand the finer points of metamodels and metaobject 
protocols in the default case.

-- c


perl6-language@perl.org

2006-01-20 Thread Rob Kinyon
On 1/20/06, Larry Wall <[EMAIL PROTECTED]> wrote:
[snip really cool blathering]

I don't have much to say on the deeper question, but I have a few
ideas on the P5 -> P6 translation question, especially as it relates
to OO:

1) Don't translate at all. Ponie, delegating to Parrot, is
supposed to handle all of that OO garbage in the same way that Ruby
and Python are going to interact with Perl6. Perl5 and Perl6 are as
similar as Ruby and Python, so you might as well write a translator
between them as one between Perl5 and Perl6.

Pros: Larry doesn't have to do anything more on the WMoT.
Cons: The community, for some reason, really wants this
auto-translator, even though there wasn't one for P4->P5 and P5->P6 is
a greater leap than P4->P5 was.

2) Don't attempt to translate $x->{whatever} (or $x->[2] or
$x->('whatever') ... ) in isolation. If it occurs within a function
defined in a package that has a function that uses bless and it's the
first parameter, it's an attribute access. Otherwise, it's a hash
access.

Pros: It's a nice and easy rule which will work if the programmer
didn't violate encapsulation, only puts methods in classes, and is
generally an all-around nice guy.
Cons: See Pros.

3) Since about half of all classes in P5-land use some module in
Class::* to auto-generate stuff (thus providing a nice place to find
all the attribute names), ask the community to provide a translator
for each of those. Then, use #2 for the others.

Pros: The WMoT can punt in about half the cases.
Cons: The WMoT cannot punt in about half the cases.

Rob


perl6-language@perl.org

2006-01-20 Thread Larry Wall
On Fri, Jan 20, 2006 at 09:35:13PM +0800, Audrey Tang wrote:
: Note that A12 used to say that all Objects does Hash, and %$obj even
: returns private attributes when used inside the class scope.
: Fortunately, S12 doesn't mention anything like that, so I think the
: treatment above is safe.

We still need something to bridge that gap, whether that particular
mechanism is available or not.  The p5-to-p6 translator needs to
figure out what to do with things like this:

$x->{whatever}

In isolation, we can't know whether that should translate to

$x

or

$x.whatever

So either p5-to-p6 does type inferencing (from some very dynamic p5 code!)
or we fudge it to emit some construct that defers the decision to p6, at
either compile time or run time, but p6 compile time still only works if
we have a compile-time typed $x, which is likely to be undecidable for
a lot of code coming from the p5 universe.

On the assumption that p6 has to make the decision then, we have three
alternatives:

Write $x.whatever, fall back to hash subscript on method call failure
Write $x, fall back to method call on non-hash
Write $x.punt('whatever'), and take an extra redispatch hit every time

My original intent was #2, hence the wording in A12.  But to speak to
some of Stevan's concernes, there's something going on here which is
not quite "Object does Hash".  It's more like "Object can do Hash",
in the linguistic sense that a "Noun can do Verb", but nonetheless
remains a noun.  A fallback role is not the same as a normal role.
Maybe there's some way to mixin in a fallback Hash role without
clobbering a real Hash role that is already there, so that if your
Hash container is an object you don't see methods for its keys.

Something like this might also let us distinguish p5ish scalars that
are simultaneously Num and Str from scalars that, say, intrinsically
do Num but can emulate Str in a pinch without caching the result.
I don't think we have a good way of expressing that distinction right
now.

This seems to imply that a given role like Hash could have two default
implementations--one for an actual Hash container, and one that emulates
a Hash by deferring to the Object.  It's sort of like a role that can
delegate back to its own object.

For simplicity, we might prefer to leave the Hash role alone as a
normal hash, and provide some way of registering emulation fallback
capabilities, in a tie-ish sort of way, but tied to types instead
of to individual containers, so you could know to look for a FakeHash
role or some such.

But rather than forcing people to register fallbacks, it might be a lot
nicer to establish some intrinsic relationship between a role actually
does the thing and a role that merely fakes it in terms of something else.

But maybe all this is already possible in the current setup, if

role ObjectFakeHash does Hash {...}
role Object does ObjectFakeHash {...}
class Hash does Hash {...}

So ObjectFakeHash would just grab the Hash interface but override the
default implementation.  I think that would give us the fallback semantics
I'm looking for without doing great violence to anything else.

But maybe someone can come up with a better way.  Maybe we can come
up with some kind of lexically scoped solution instead, if we decide
it's just a language emulation issue.  But my hunch is that it's
a deep tagmemic/metaphorical problem we're trying to solve here.
Such issues arise whenever you start making statements of the form
"I want to use an A as if it were a B."  The problem is much bigger
than just how do I translate Perl 5 to Perl 6.  It's questions like:

What makes a particular metaphor work?
Will the cultural context support use of an A as if it were a B?
How do we translate the user's thoughts to the computer's thoughts?
How do we translate one user's thoughts to another user's thoughts?
How do we know when such a translation is "good enough"?
How do we know when our mental model of an object is adequate?
How do we know when the computer's mental model of an object is adequate?
What does adequate mean in context?
Will the culture support partially instantiated objects?  :-)

That's tagmemics, folks.  The main problem with tagmemics is that, while
it helps you ask good questions, it doesn't give you easy answers for 'em...

Anyway, I'd still kinda like to find some way to use an object
"as if" it were a hash, partly to solve my immediate problem, but
also because I think a good computer language might address the
"as if" problem better than any of them do currently.  In general,
hypotheticality is still something that humans are much better at
than computers.  We're still just nipping around the edges with "fail",
"let", environmental variables, STM, roles, and junctions.  But we'll
not get true AI until a computer can understand a sentence like

In a hole in the ground there lived a hobbit.

as if it were a human.  A human has the ability to exec

perl6-language@perl.org

2006-01-20 Thread Rob Kinyon
On 1/19/06, chromatic <[EMAIL PROTECTED]> wrote:
> On Thursday 19 January 2006 19:50, Rob Kinyon wrote:
>
> > Nothing. Just like it's not a problem if Perl6 uses one of the
> > Ruby-specific PMCs for storage. In fact, the alternate $repr idea is
> > specifically to allow for the use of foreign datatypes as storage.
> > Luke's excellent example is to use a C-struct as your storage.
>
> ... but ...
>
> > Storage of what? What are you trying to do that you need to use an
> > object to store your attributes? Why aren't you just using the method
> > -that- object is using?
>
> I can't reconcile these two paragraphs.

The second paragraph was referring solely to where you're dealing with
Parrot datatypes only. If you have to go outside of Parrot (to a C
lib, for instance), then you do need to know about the storage
specifics.

> > No. My objection to bless() is BUILD() and CREATE(). There's already a
> > mechanism in the P6 OO system for specifying the internal
> > representation of the instance.
>
> This is Perl.  The "there should be one obvious way to do it" ship, canoe,
> raft, and water wings have sailed, paddled, floated, and inflated.

And there is. You can create your own meta-object protocol on top of
p6opaque or any other representation you want. This is *Perl6* - you
can rewrite the whole damn grammar if you want to. You can use another
VM if you want to. (PIL^N runs on Javascript!)

I think this entire issue is rising out of the fact that very very few
people in this discussion are familiar with the design of the MOP.
Stevan and a few others are the primary movers and I'm lucky enough to
have been Stevan's sounding board for a few pieces. Once you grok the
MOP, it's really hard to imagine wanting to use bless(). It's
literally like trying to explain to a BASIC programmer why recursion
is good or trying to explain to a C programmer why automatic memory
management is handy. The frames of reference are so different that the
meaning being trasmitted is not the meaning being received.

Rob


Re: Perl 6's &bless is (seriously) broken

2006-01-20 Thread Rob Kinyon
On 1/20/06, Juerd <[EMAIL PROTECTED]> wrote:
> Note, by the way, that JS has "primitive" strings, and Strings, only the
> latter being objects. Fortunately for us, though, a string is
> automatically promoted to a String when the string is USED AS an object.

In other words, according to userland, everything is an object.

> > But, if you must use the WMoT, then I suspect the following will happen:
> > 1) The WMoT notices your use of &bless and marks that package as a
> > class and that method as a constructor.
> > 2) It creates a Perl6 class for your use, noting the accesses into
> > the Perl5 reference that you used and calling those attributes.
> > 3) It then creates your BUILD() method, putting all the non-bless
> > components of your new() into it.
>
> Doesn't solve the problems as mentioned in this thread, like overlapping
> methods.

Yeah it does because all $repr's are p6opaque with direct access being
converted into attribute access. No method overlap.

Rob


perl6-language@perl.org

2006-01-20 Thread Audrey Tang
Stevan Little wrote:
>> I realize one of Stevan's objections is "But if you use a Hash, does your
>> object automatically support the .keys method and .kv and so on?" to
>> which I
>> reply "No, of course not.  That's silly.  It just uses the Hash for
>> *storage*."
>> Is that your objection to bless()?
> 
> Yes, that is my objection, because while the alternate storage approach
> discussed above is actually a very interesting feature, it does not fit
> with the p5 vision of &bless.
> 
> With p5, you /can/ get to the underlying data structure. This is a break
> which will hamper the backwards compatibility effort I think.

It is possible to have one's cake and eat it too.  Consider:

Foo.bless($x)

where $x contains an Bar object.  We can check if Foo is a subtype to
Bar -- for example, Foo.bless({some => 'hash'}) would check whether Foo
conforms to the Hash interface.

If so, then we safely reuse the underlying representation for storage:

class Foo does Hash { has $.a; has $.b }
my %args = (a => 1, b => 2);
my $obj  = Foo.bless(%args);
%args.{'a'} = 999;
say $obj.a; # 999
say $obj.{'a'}; # 999

If not, we explode $x into named arguments and dispatch to .CREATE to
make an p6opaque representation. Hash and Array are thus turned to
pairs; a Scalar would have to contain an arglist or a pair, otherwise
it'd fail the named-only prototype check.  To wit:

class Bar { has $.a; has $.b }
my %args = (:a<1>, :b<2>);
my $obj = Bar.bless(%args);
%args.{'a'} = 999;
say $obj.a; # 1, not 999
say $obj.{'a'}; # Error -- no such method: postcircumfix:<{ }>

Note that A12 used to say that all Objects does Hash, and %$obj even
returns private attributes when used inside the class scope.
Fortunately, S12 doesn't mention anything like that, so I think the
treatment above is safe.

Audrey




signature.asc
Description: OpenPGP digital signature


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