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


Perl 6's bless is (seriously) broken

2006-01-19 Thread Stevan Little

Hello,

I am forking this off the Perl 6 OO and bless thread since that  
seems to have gotten bogged down in what it all means to Perl 5  
interoperability. This was not really my intent with the original  
thread, but I think it is still a fruitful discussion so I will re- 
make my original point here with more detail.


First I need to establish a few things on which my argument rests.

So, S02 says that Perl 6 is an OO engine. Which means that a hash is  
not a literal thing but an instance of the class ^Hash. This means  
that a hash now has methods which can be called on it, and inherits  
from ^Object.


Because @Larry does not want the OO-ness of the language to get in  
the way of doing ones job, all the methods of ^Hash are either  
transformed into pseudo-built-in-functions using macros (see the Hash/ 
delete/UnaryForm part of S29), or would be aliased as multi-subs  
which dispatch using MMD.


Take this (very simplified) pseduo-code for exists:

  method Hash::exists (^Hash %h: Any $label) return Bool {
  %h{$label} ?? bool::true !! bool::false
  }

And lets assume that a macro has been written to make it callable in  
the built-in function style which will transform this:


  exists %h{'foo'}

Into this:

  %h.exists('foo');

Now, what happens when we bless a hash.

  class Foo {
  method new ($class: %params) {
  $class.bless(%params);
  }
  method bar ($self:) { ... }
  }

The result of Foo.new is an instance of ^Foo. In Perl 5, the hash  
would be tagged with the package name it was blessed into, but it  
would still be a hash reference, only now you could also call methods  
on it. This *won't* work the same in Perl 6 though. This is because,  
what is blessed is not a literal hash, but an instance of ^Hash. If  
we follow the Perl 5 logic, then we can now call methods on this  
blessed hash, but we cannot use the hash built-in functions since  
they are just macro transformations into method calls. Take this code  
example:


  my $foo = Foo.new({ one = 1, two = 2 });
  exists $foo{'one'}; # this will not work

The reason this the above code will not work is because exists $foo 
{'one'} will be transformed by the macro to $foo.exists('one'),  
which will fail since no Foo::exists exists. Even if we tried to do  
this (and assuming the macro would DWIM):


  Hash::exists $foo{'one'};

This would fail anyway since Hash::exists is expecting a ^Hash  
instance as it's invocant arg, and not a ^Foo instance, so it would  
fail on the parameter/argument type check.


I think this is a deep problem with how bless works, how the  
container types work, and maybe even how our MMD system works. I  
think we need to have a well reasoned solution to this which is  
devoid of any magic hand waving.


Thanks,

Stevan





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

2006-01-19 Thread Juerd
Stevan Little skribis 2006-01-19 15:45 (-0500):
   class Foo {
   method new ($class: %params) {
   $class.bless(%params);

Wouldn't that be %params.bless($class), or more directly,
%params.blessed = $class?

 This *won't* work the same in Perl 6 though. This is because,  
 what is blessed is not a literal hash, but an instance of ^Hash.

The mistake here is that Foo doesn't does Hash, I think. 

Sure, in Perl 5, you could have different kinds of references as
instances of the same class. But I don't recall ever having encountered
that.

 
Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


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

2006-01-19 Thread Rob Kinyon
To further extend Steve's argument (which I wholeheartedly agree
with), I wanted to point out one thing: bless has nothing to do with
OO programming as conceived of in Perl6. It does one thing and only
one thing:
 - tag a reference with a package name.

This is used in a few places:
- to determine what package the 'meth' function lives in when the
syntax $foo-meth( @parms ) is encountered
- to determine what ref() should return

There are no references in Perl6. In fact, the only think you have in
Perl6 is objects, so why do we need to take something that isn't an
object (which doesn't exist) and do anything to it, let alone tag it
with a package name? Packages don't have anything to do with the class
system. If you want to change the behavior of something at runtime,
you can do so through .meta, roles, mixins, traits, and the like.

bless was a brilliant idea for Perl5. It's wrong for Perl6.

Rob


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

2006-01-19 Thread chromatic
On Thursday 19 January 2006 13:10, Rob Kinyon wrote:

 bless was a brilliant idea for Perl5. It's wrong for Perl6.

Perhaps you meant to write Tagging a reference with a package name worked for 
Perl 5.  It's wrong for Perl 6.

Certainly I can agree with that.

Yet this whole discussion feels like the argument that there should be no 
system() operator in Perl 6 because the system() operator in Perl 5 returns 
the wrong value.

-- c


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

2006-01-19 Thread Juerd
Rob Kinyon skribis 2006-01-19 16:10 (-0500):
 There are no references in Perl6.

When you said that one can't use OO in Perl 5, I had something to say
because it's a recurring subject.

I have to admit, though, that I've never seen this statement, or
anything implying it. It's entirely new to me. 

Is your Perl the same as that of other people on this list? :)

 In fact, the only think you have in Perl6 is objects, so why do we
 need to take something that isn't an object (which doesn't exist)

Could you live with @foo being an array, and @foo in scalar context
returning a reference to that array? And with arrays being interfaces to
underlying Arrays, which are objects, which makes arrays non-objects
that can be used *as* objects?

Perl still has non-object types. They may represent objects internally,
but they work differently from what we've historically been calling
objects. Especially in assignment, the differences are huge, because an
object is considered a reference, while real scalars, arrays and
hashes evaluate to (a list of) their values, or a useful representation
(like the number of elements) when used in non-OO fashion.

 bless was a brilliant idea for Perl5. It's wrong for Perl6.

I think it's needed to be able to convert Perl 5 code
semi-automatically.

But you have probably thought about this more than I, so I'll ask you:
what's the alternative?


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


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

2006-01-19 Thread Juerd
Juerd skribis 2006-01-19 22:18 (+0100):
 Could you live with @foo being an array, and @foo in scalar context
 returning a reference to that array? And with arrays being interfaces to
 underlying Arrays, which are objects, which makes arrays non-objects
 that can be used *as* objects?

This turns everything is an object into everything can be used with
OO syntax, which I think is more true.

Alternatively and simultaneously, everything represents an object.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


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

2006-01-19 Thread Stevan Little


On Jan 19, 2006, at 4:10 PM, Rob Kinyon wrote:

Packages don't have anything to do with the class
system.


Actually ^Class.isa(^Package) ;)

Stevan



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

2006-01-19 Thread Stevan Little

Juerd,

On Jan 19, 2006, at 4:10 PM, Juerd wrote:

Stevan Little skribis 2006-01-19 15:45 (-0500):

  class Foo {
  method new ($class: %params) {
  $class.bless(%params);


Wouldn't that be %params.bless($class), or more directly,
%params.blessed = $class?


Nope, according to S12:

  As in Perl 5, a constructor is any routine that calls bless. Unlike
  in Perl 5, you call it as a method on the class, passing the  
candidate

  as the first argument.

It then does on to give this code example:

  $object = $class.bless({k1 = $v1, k2 = $v2, ...});

In fact all example using bless us it as a method of the $class.


This *won't* work the same in Perl 6 though. This is because,
what is blessed is not a literal hash, but an instance of ^Hash.


The mistake here is that Foo doesn't does Hash, I think.


But we cannot automagically inject a role into a class, for a number  
of reasons.


1) thats just plain evil
2) what if the role conflicts with other roles being does-ed by Foo?  
Debugging hell there.
3) What if Foo wants to have a .keys, .value, .exists, etc? Do they  
shadow the Hash version? What if Foo.keys is implemented using  
Hash.keys? Many issues abound here.



Sure, in Perl 5, you could have different kinds of references as
instances of the same class. But I don't recall ever having  
encountered

that.


bless([] = 'Foo');
bless({} = 'Foo');
bless(\*Foo = 'Foo');
bless(\(my $var) = 'Foo');

It silly, but you could do it. However this is not really related to  
my point. The issue I am describing looks more like this in perl 5:


  package Hash;
  sub new { ... }
  sub keys { ... }
  sub values { ... }
  sub exists { ... }

  package Foo;

  sub new {
  my ($class, $hash) = @_;
  ($hash-isa(Hash)) || die hash needs to be an instance of Hash;
  bless($hash, $class);
  }

Why would you ever want to do such a think in Perl 5? So why would  
that be how bless works in Perl 6?


Stevan



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

2006-01-19 Thread Stevan Little

Juerd,

On Jan 19, 2006, at 4:21 PM, Juerd wrote:

Juerd skribis 2006-01-19 22:18 (+0100):

Could you live with @foo being an array, and @foo in scalar context
returning a reference to that array? And with arrays being  
interfaces to

underlying Arrays, which are objects, which makes arrays non-objects
that can be used *as* objects?


This turns everything is an object into everything can be used with
OO syntax, which I think is more true

Alternatively and simultaneously, everything represents an object.


Well, if everything is NOT an object, then the synopsis need to  
reflect this. I was under the impression that everything was an  
object, some of that object-ness is more hidden in some than  
others, but it does not mean they are not still objects.


My point though was not to debate OO theory, but to reconcile a  
problem in the Synopsis and it's description/usage of bless.  
Currently it is broken, and we need to fix it.


One fix, yes, is to say arrays and hashes are not objects, they are  
literals as in perl 5. Personally I am not sure that is a good  
approach, and seems to contradict more of the Synopsis then it agrees  
with.


Stevan



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

2006-01-19 Thread Juerd
Stevan Little skribis 2006-01-19 16:59 (-0500):
 But we cannot automagically inject a role into a class, for a number  
 of reasons.
 1) thats just plain evil

But then, so is bless, so the two can play along.

 2) what if the role conflicts with other roles being does-ed by Foo?  
 Debugging hell there.

Very good point.

 3) What if Foo wants to have a .keys, .value, .exists, etc? Do they  
 shadow the Hash version? What if Foo.keys is implemented using  
 Hash.keys? Many issues abound here.

Even better point.

 Sure, in Perl 5, you could have different kinds of references as
 instances of the same class. But I don't recall ever having  
 encountered
 that.
 bless([] = 'Foo');
 bless({} = 'Foo');
 bless(\*Foo = 'Foo');
 bless(\(my $var) = 'Foo');

Okay, now I did encounter it...


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


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

2006-01-19 Thread Juerd
Stevan Little skribis 2006-01-19 17:06 (-0500):
 This turns everything is an object into everything can be used with
 OO syntax, which I think is more true
 Alternatively and simultaneously, everything represents an object.
 Well, if everything is NOT an object, then the synopsis need to  
 reflect this.

I was more thinking along the lines of NOT everything is an object,
but some things are.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


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

2006-01-19 Thread Jonathan Scott Duff
On Thu, Jan 19, 2006 at 11:07:49PM +0100, Juerd wrote:
 Stevan Little skribis 2006-01-19 16:59 (-0500):
  2) what if the role conflicts with other roles being does-ed by Foo?  
  Debugging hell there.
 
 Very good point.

Aren't role conflicts resolved at composition time (possibly by
failure)?  That doesn't sound like debugging hell to me, but rather
clear indication of a problem and the location of that problem.

-Scott
-- 
Jonathan Scott Duff
[EMAIL PROTECTED]


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

2006-01-19 Thread Stevan Little


On Jan 19, 2006, at 5:09 PM, Juerd wrote:

Stevan Little skribis 2006-01-19 17:06 (-0500):
This turns everything is an object into everything can be used  
with

OO syntax, which I think is more true
Alternatively and simultaneously, everything represents an object.

Well, if everything is NOT an object, then the synopsis need to
reflect this.


I was more thinking along the lines of NOT everything is an object,
but some things are.


sarcasm
Hmm, maybe we can add an Object context then. It would allow an  
something to be an object only when it is convienent for it to be so. ;)

/sarcasm

Stevan


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

2006-01-19 Thread Stevan Little


On Jan 19, 2006, at 5:19 PM, Jonathan Scott Duff wrote:

On Thu, Jan 19, 2006 at 11:07:49PM +0100, Juerd wrote:

Stevan Little skribis 2006-01-19 16:59 (-0500):

2) what if the role conflicts with other roles being does-ed by Foo?
Debugging hell there.


Very good point.


Aren't role conflicts resolved at composition time (possibly by
failure)?  That doesn't sound like debugging hell to me, but rather
clear indication of a problem and the location of that problem.


Role conflicts are resolved when a role (or set of roles) is composed  
into a class. In this case the (automatically generated) code would  
look something like this:


method new ($class: %params) {
my $self = $class.bless(%params);
$self does Hash;
return $self;
}

Or it would have to detect it in the class definition itself, in  
which case it would add a does Hash; to the class def somewhere.


The reason this would be debugging hell (IMO at least) is that *I*  
never told it to does Hash, so as far as I knew there was no clashes  
in the roles I composed. Sure if was educated in the finer points of  
Perl 6 I would know what happened, but a random newbie would be half- 
way to PHP by now.


Stevan



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

2006-01-19 Thread Rob Kinyon
On 1/19/06, Juerd [EMAIL PROTECTED] wrote:
 Rob Kinyon skribis 2006-01-19 16:10 (-0500):
  There are no references in Perl6.
 I have to admit, though, that I've never seen this statement, or
 anything implying it. It's entirely new to me.

 Is your Perl the same as that of other people on this list? :)

There are no references in Perl6 in the way Perl5 conceives of references.

 Perl still has non-object types. They may represent objects internally,
 but they work differently from what we've historically been calling
 objects. Especially in assignment, the differences are huge, because an
 object is considered a reference, while real scalars, arrays and
 hashes evaluate to (a list of) their values, or a useful representation
 (like the number of elements) when used in non-OO fashion.

No. Objects are *NOT* considered references in most languages other
than Perl5. Even in C++, the least OO language that could be
considered OO, you can have non-reference objects.

I'd say learn Ruby to know what OO is, but I happen to know you
already know a nearly-pure OO language - Javascript. Every single
'thing' in JS is an object - you can hang methods off of a string
literal or a number. Most objects in JS aren't references.

  bless was a brilliant idea for Perl5. It's wrong for Perl6.

 I think it's needed to be able to convert Perl 5 code
 semi-automatically.

 But you have probably thought about this more than I, so I'll ask you:
 what's the alternative?

Well, there's two scenarios - you either run your P5 code using Ponie
or you attempt to use Larry's Wondrous Machine of Translation.

Me, I choose the former. Now, I don't worry about how objects are
mediated between languages - Ponie and Parrot have to do that for me.
And, before you start worrying, this is a feature that was planned
into Parrot from Day 1. Ruby and Python and Perl6 all have to
interoperate, including inheritance from each others' classes. Perl5
- Perl6 will be no different.

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.

That's it. No bless in Perl6 needed.

Rob


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

2006-01-19 Thread Juerd
Rob Kinyon skribis 2006-01-19 20:54 (-0500):
   There are no references in Perl6.
  Is your Perl the same as that of other people on this list? :)
 There are no references in Perl6 in the way Perl5 conceives of references.

There are references in Perl 6.

Do note that @foo evaluates to a reference to itself in scalar context,
which isn't some magical auto-referencing thing. Likewise, a reference
to an array is dereferenced when used as an array. This is automatic,
but still not quite magical.

References, their terminology, and their semantics still very much exist.

 I'd say learn Ruby to know what OO is, but I happen to know you
 already know a nearly-pure OO language - Javascript.

Somehow that makes me think you don't happen to know that I already know
Ruby too. :)

 Every single 'thing' in JS is an object - you can hang methods off of
 a string literal or a number. Most objects in JS aren't references.

They are what one would call a reference if the language were Perl. I'm
very strictly limiting my jargon to Perl's, unless explicitly stated
otherwise.

For example, PHP's references are not references, but more like
pointers and/or symbolic references, depending on which you choose to
call references in PHP.

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.

   bless was a brilliant idea for Perl5. It's wrong for Perl6.
  I think it's needed to be able to convert Perl 5 code
  semi-automatically.  But you have probably thought about this more
  than I, so I'll ask you: what's the alternative?
 Well, there's two scenarios - you either run your P5 code using Ponie
 or you attempt to use Larry's Wondrous Machine of Translation.

How would the latter work, if there's no bless?

 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.


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html