Re: Roles vs. Classes (was Re: Ways to add behavior)
On 10/27/05, Larry Wall <[EMAIL PROTECTED]> wrote: > On Thu, Oct 27, 2005 at 05:37:13AM -0400, Rob Kinyon wrote: > : Will I be able to do something like: > : > : package Foo; > > Hmm, you just started in Perl 5 mode. > > : $*VERSION = 1.3.2; > > Perl 5 would get confused here, so I'm presuming Perl 6. But Perl 6 > isn't likely to let you override the global run-time Perl version. > > : use Foo-1.3.1; > > That I think I understand. > > : role My::Foo { does Foo; ... } > > Okay, My::Foo does Foo here. Presumably it must "do" the Foo alias > that the use just installed. And presumably the Foo you just used > is a role that can be "done". Certainly you can't "do" the global > package Foo, assuming that's what your original package declared. > > : alias My::Foo -> Foo; # Or whatever the syntax should be > > I have no clue where you're intending to install that alias. > Are you trying to install a *Foo alias? A bare Foo is going to first > find the local alias to the Foo you used, and that hides the global > Foo that it would have found otherwise. I suspect you're trying to > say > > *Foo := My::Foo; > > : And, in my other code, "use Foo;" will DWIM? > > I don't know quite what you mean, so I don't know if it'll do what > you mean. If you're trying to establish a policy that defaults a > particular name to a particular version, the library interface will > probably give you a more straightforward way to set that up. Sorry. I'm not up on the syntax. I should do some serious backlog reading. What I'm trying to do is load role Foo 1.0, have My::Foo do Foo, then call My::Foo version 2.0 of Foo so that anyone else in my program will see My::Foo instead of the original Foo. Is this possible? Rob
Re: Roles vs. Classes (was Re: Ways to add behavior)
On Thu, Oct 27, 2005 at 05:37:13AM -0400, Rob Kinyon wrote: : Will I be able to do something like: : : package Foo; Hmm, you just started in Perl 5 mode. : $*VERSION = 1.3.2; Perl 5 would get confused here, so I'm presuming Perl 6. But Perl 6 isn't likely to let you override the global run-time Perl version. : use Foo-1.3.1; That I think I understand. : role My::Foo { does Foo; ... } Okay, My::Foo does Foo here. Presumably it must "do" the Foo alias that the use just installed. And presumably the Foo you just used is a role that can be "done". Certainly you can't "do" the global package Foo, assuming that's what your original package declared. : alias My::Foo -> Foo; # Or whatever the syntax should be I have no clue where you're intending to install that alias. Are you trying to install a *Foo alias? A bare Foo is going to first find the local alias to the Foo you used, and that hides the global Foo that it would have found otherwise. I suspect you're trying to say *Foo := My::Foo; : And, in my other code, "use Foo;" will DWIM? I don't know quite what you mean, so I don't know if it'll do what you mean. If you're trying to establish a policy that defaults a particular name to a particular version, the library interface will probably give you a more straightforward way to set that up. Larry
Re: Roles vs. Classes (was Re: Ways to add behavior)
On 10/26/05, Larry Wall <[EMAIL PROTECTED]> wrote: > On Wed, Oct 26, 2005 at 07:35:05PM -0700, chromatic wrote: > : On Wed, 2005-10-26 at 21:58 -0400, Rob Kinyon wrote: > : > : > Plus, the argument is a straw man. Instead of: > : > > : > class Some::Class is also { > : > } > : > > : > you would do: > : > > : > class My::Version { > : > does Some::Class; > : > } > : > > : > Problem solved. > : > : Don't forget the fun of modifying all existing uses of Some::Class to > : use My::Version instead, if that's even possible. > > That should mostly be handled by virtualized class names. Will I be able to do something like: package Foo; $*VERSION = 1.3.2; use Foo-1.3.1; role My::Foo { does Foo; ... } alias My::Foo -> Foo; # Or whatever the syntax should be And, in my other code, "use Foo;" will DWIM?
Re: Roles vs. Classes (was Re: Ways to add behavior)
On 10/26/05, Rob Kinyon <[EMAIL PROTECTED]> wrote: > What about: > > class Foo is also { > method foo() { ... } > } > > Where the second foo() is no longer what the first foo() did. Just overwrite the vtable. > Furthermore, let's say you have: > > class Bar isa Foo { > method floober() { ... } > } > > If they were roles, then role Bar could alias all the methods it > inherits from role Foo. In other words, it can cache all the method > lookups at compile-time. That's a substantial savings. If they're open > classes, the runtime has to throw out all the cached lookups the > moment any of the classes upstream are modified. This one is a little better. It is expensive to rejig all the cached methods, but that expense comes at the time when you reopen. If you never reopen, you never pay a penalty. > Plus, the argument is a straw man. Instead of: > > class Some::Class is also { > } > > you would do: > > class My::Version { > does Some::Class; > } > > Problem solved. Unless your module is the one creating the Some::Classes, or unless (as you point out above) there are existing subclasses of Some::Class, or unless some other thing that you didn't think of, which is the whole point of this discussion. There is no omniscient library writer; there is no omniscient language designer. :-) Luke
Re: Roles vs. Classes (was Re: Ways to add behavior)
On Wed, Oct 26, 2005 at 07:35:05PM -0700, chromatic wrote: : On Wed, 2005-10-26 at 21:58 -0400, Rob Kinyon wrote: : : > Plus, the argument is a straw man. Instead of: : > : > class Some::Class is also { : > } : > : > you would do: : > : > class My::Version { : > does Some::Class; : > } : > : > Problem solved. : : Don't forget the fun of modifying all existing uses of Some::Class to : use My::Version instead, if that's even possible. That should mostly be handled by virtualized class names. Larry
Re: Roles vs. Classes (was Re: Ways to add behavior)
On Wed, 2005-10-26 at 21:58 -0400, Rob Kinyon wrote: > Plus, the argument is a straw man. Instead of: > > class Some::Class is also { > } > > you would do: > > class My::Version { > does Some::Class; > } > > Problem solved. Don't forget the fun of modifying all existing uses of Some::Class to use My::Version instead, if that's even possible. -- c
Re: Roles vs. Classes (was Re: Ways to add behavior)
On 10/26/05, Luke Palmer <[EMAIL PROTECTED]> wrote: [snip] > Okay, an open class means you can add methods to it, right? So, let's > say you have this class: > > class Foo { > method foo() {...} > method bar() {...} > } > > And this code: > > my Foo $x = Foo.new; > $x.foo(); > $x.bar(); > > This might be compiled to the following pseudo intermediate code: > > my $x = Foo[0](); > Foo[1]($x); > Foo[2]($x); > > Now let's say you extend the class: > >class Foo is also { >method baz() {...} >} > > Is there any reason that the preceding pseudo intermediate code is no > longer valid? I don't see one; baz() is just installed in slot 3. So > why would you say it was faster to have it closed? What about: class Foo is also { method foo() { ... } } Where the second foo() is no longer what the first foo() did. Furthermore, let's say you have: class Bar isa Foo { method floober() { ... } } If they were roles, then role Bar could alias all the methods it inherits from role Foo. In other words, it can cache all the method lookups at compile-time. That's a substantial savings. If they're open classes, the runtime has to throw out all the cached lookups the moment any of the classes upstream are modified. Plus, the argument is a straw man. Instead of: class Some::Class is also { } you would do: class My::Version { does Some::Class; } Problem solved. Rob
Re: Roles vs. Classes (was Re: Ways to add behavior)
On Wed, 2005-10-26 at 19:22 -0600, Luke Palmer wrote: > But we find that many programmers make decisions that trade > readability and extensibility for an extra 1% of speed, even when they > are writing a command-line frontend to MPlayer[1]. If those people > are module writers, then we have a bunch of modules on CPAN that are > not friendly to the user who wants to use the module in the one way > the writer didn't expect. Worse, that's a *theoretical* 1% of speed based on non-profiled code. > And if you're going to use roles for everything because they're closed > and they will gain you 2% of speed on one particular backend, then > we'll have to make the same rule for them too. I know it sounds like > we're "babying" our programmers. We are, because it's such a > widespread superstition. I prefer to think of it as "Helping to prevent them from writing unreusable code." > And just to reinforce that it's a superstition: a theory defines a > vtable. If you extend the class in an incompatible way, you have to > make a new instance of its theory, defining new vtable slots. Once > the new vtable is created, it is just as fast as the old one. There > is no speed loss whatsoever for keeping your class open. Even further, don't forget that someone, somewhere will really need to do something you didn't think of. Either he extends your class somehow or works around it in an ugly, funky way. Which one is faster to write? Which one is faster to execute? Which one is more likely to be correct? Which one is more maintainable? -- c
Re: Roles vs. Classes (was Re: Ways to add behavior)
On Wed, Oct 26, 2005 at 08:48:12PM -0400, Rob Kinyon wrote: : If a role is an immutable class, that means that its internals cannot : be changed. Hence, the compiler can trust that it will be the same at : the end as at the beginning. Which means it's optimized. Which means : my objects run faster if I create them from roles than if I create : them from classes. And, given that this seems to be the sole : difference between them (mutability vs. immutability), why would I use : classes as my standard? Because it might be a premature optimization to the extent that it restricts flexibility before you know whether it's going to affect performance. Part of the power of Ruby on Rails reputedly comes from the fact that Ruby leaves its classes open by default. Larry
Re: Roles vs. Classes (was Re: Ways to add behavior)
On 10/26/05, Rob Kinyon <[EMAIL PROTECTED]> wrote: > On 10/26/05, chromatic <[EMAIL PROTECTED]> wrote: > > On Wed, 2005-10-26 at 20:29 -0400, Rob Kinyon wrote: > > > > > I would prefer to use roles as they're closed by default, leaving > > > "class" to be my powertool, if I need the power. > > > > I don't understand this desire; can you explain your reasoning? > > If a role is an immutable class, that means that its internals cannot > be changed. Hence, the compiler can trust that it will be the same at > the end as at the beginning. Which means it's optimized. Which means > my objects run faster if I create them from roles than if I create > them from classes. And, given that this seems to be the sole > difference between them (mutability vs. immutability), why would I use > classes as my standard? Okay, an open class means you can add methods to it, right? So, let's say you have this class: class Foo { method foo() {...} method bar() {...} } And this code: my Foo $x = Foo.new; $x.foo(); $x.bar(); This might be compiled to the following pseudo intermediate code: my $x = Foo[0](); Foo[1]($x); Foo[2]($x); Now let's say you extend the class: class Foo is also { method baz() {...} } Is there any reason that the preceding pseudo intermediate code is no longer valid? I don't see one; baz() is just installed in slot 3. So why would you say it was faster to have it closed? Indeed, it *could* be faster. But we find that many programmers make decisions that trade readability and extensibility for an extra 1% of speed, even when they are writing a command-line frontend to MPlayer[1]. If those people are module writers, then we have a bunch of modules on CPAN that are not friendly to the user who wants to use the module in the one way the writer didn't expect. So the reason we made classes open by default is so that people wouldn't have a chance to make that decision until they're more experienced. Indeed, no module writer can say that a class is closed; only the main program may say that, because the main program knows the most about how everything is used. The precise definition of "main program" is not well-defined yet, but it's there so that a module writer doesn't close himself off from the world without knowing how his module is even being used. And if you're going to use roles for everything because they're closed and they will gain you 2% of speed on one particular backend, then we'll have to make the same rule for them too. I know it sounds like we're "babying" our programmers. We are, because it's such a widespread superstition. And just to reinforce that it's a superstition: a theory defines a vtable. If you extend the class in an incompatible way, you have to make a new instance of its theory, defining new vtable slots. Once the new vtable is created, it is just as fast as the old one. There is no speed loss whatsoever for keeping your class open. Luke [1] This is a concrete example that I actually witnessed.
Re: Roles vs. Classes (was Re: Ways to add behavior)
On 10/26/05, chromatic <[EMAIL PROTECTED]> wrote: > On Wed, 2005-10-26 at 20:29 -0400, Rob Kinyon wrote: > > > I would prefer to use roles as they're closed by default, leaving > > "class" to be my powertool, if I need the power. > > I don't understand this desire; can you explain your reasoning? If a role is an immutable class, that means that its internals cannot be changed. Hence, the compiler can trust that it will be the same at the end as at the beginning. Which means it's optimized. Which means my objects run faster if I create them from roles than if I create them from classes. And, given that this seems to be the sole difference between them (mutability vs. immutability), why would I use classes as my standard? Rob
Re: Roles vs. Classes (was Re: Ways to add behavior)
On Wed, 2005-10-26 at 20:29 -0400, Rob Kinyon wrote: > I would prefer to use roles as they're closed by default, leaving > "class" to be my powertool, if I need the power. I don't understand this desire; can you explain your reasoning? (NB: "closed" here, as I use it, still *does not* correspond to licensing or availability of the source code.) -- c
Roles vs. Classes (was Re: Ways to add behavior)
> : 3) Aren't classes mutable and roles immutable by default only? Or has > : this changed? > > Of course. To change the default for a role, call it a class, and > to change the default for a class, call it a role. :-) Does this mean that roles are the recommended way to create immutable classes? Given that roles and classes now seem to differ only in their mutability, I can't see a reason why I would use class as my default object definer. I would prefer to use roles as they're closed by default, leaving "class" to be my powertool, if I need the power. Rob