Re: Perl 6's bless is (seriously) broken
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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