princepawn has asked for the wisdom of the Perl Monks concerning the following question:
After reading the docs for Class::Roles and the
original whitepaper on the subject, I understand the motivation for roles: to support code re-use with a finer grain of control and compositional fluency than classes with single/mult. inheritance can.
However, I think that prototype-based OOP does this as well (e.g., Class::Prototyped) and am not sure why one solution should be preferred over another, particularly if one is going to ship standard with Perl 6.
Re: Will role-based programming be part of the standard Perl 6 distribution?
by chromatic (Archbishop) on Dec 22, 2003 at 17:21 UTC
|
Yes, roles will be part of the standard Perl library.
One benefit of roles that you do not mention (and, to me, the largest benefit) is that they're less restrictive than inheritance (and work better with prototyping). does() doesn't enforce how a class fulfills a role. isa() does.
| [reply] [d/l] [select] |
|
| [reply] |
|
| [reply] [d/l] [select] |
Re: Will role-based programming be part of the standard Perl 6 distribution?
by stvn (Monsignor) on Dec 22, 2003 at 23:36 UTC
|
To start with, coming from Javascript, and programming my fair share of OO Javascript, I can say that while i really liked prototype inheritance, but I found it not only difficult to work with at times, but downright impossible to explain its powerful aspects to anyone who was used to class-based OO. They are too stuck with the whole "class is a template not an object" idea, prototype-like stuff requires meta-classes in those languages, and that is just,.. well, lets not even get into meta-classes, they are so poorly understood and hardly ever agreed upon its not worth it.
As for Scott's comments about the GOD object and the state of Perl OO, I couldn't agree more with your assessments (although I dont think them as "across the board" as you seem too). But I dont agree that delegation and not inheritance are the ways to go. Delegation is a technique that has its place if it fits the domain model, but is not something that should replace inheritance. C++ programmers tend to lean towards delegation, and it (along with alot of the prevailing OO "wisdom") is really a direct symptom of the limitations of C++, not of OO. Just as some of the more convoluted Java-based "wisdom" (and some Design Patterns) tends to be a direct result of Java's single inheritance model. IMHO this is the language leading the direction of the theory. Its the cart before the horse.
Personally I like multiple inheritance. Not Mix-Ins. They are a different thing altogether, a sort of multiple inheritance hack if you will. But i would never ever think of trying multiple inheritance in C++, its cripplingly complex. Not because of the concept, but because of the implementation. And lets not even bother with Java and its sad excuse for multiple-inheritance in Interfaces. Java Interfaces are a waste of bytes.
For well done multiple inheritance, take a look at Eiffel. Sure the syntax of the language is downright weird, but the concepts are sound. Bertrand Meyer is one really smart muthafu... shut yo mouth.
Eiffel's solution to method conflict in multiple inheritance is to provide facilities to rename, undefine and join said methods. That's genius (again IMHO), and it solves 99% of all the multiple-inheritance complaints of C++.
As for roles, I like the idea, but I think the implementation is overkill. It seems to me to be a shortcut, rather than a solution. (And no i have not read the whole paper yet, I skimmed it a week ago when i saw it posted on the Perl 6 language list. I plan to give it a closer read over the holidays). But Roles, to me, seem to be a combination of multiple-inheritance and interface polymorphism. So why not just do multiple-inheritance with interface polymorphism?
I am currently constructing a class library/object framework at my company, in which we have implemented role-like behavior using multiple-inheritance and interface polymorphism in plain old OO Perl. I have created both a "redefines" and an "undefine" feature along with something I call a Dispatchable interface (which allows very specific method resolution (kinda like SUPER, but more specific)) to implement those Eiffel concepts in Perl.
We have a series of "interfaces" (and yes, our interfaces can have implementations unlike Java) that implement various bit of functionality (to be truthful, some dont actually implement anything but stub methods and are really just marker interfaces). Interfaces have no constructors and therefore cannot be instantiated. Some examples are: Printable, Cloneable, Dispatchable, Curryable, Comparable, Serializable, Sequencable, Throwable, Traversable, etc (you can get the idea from the names i think).
I have no base class (i dont believe in them), and so the hierarchy is wide and shallow instead of deep and complex. Multiple Inheritance is easy to control and manage within the framework, I have an IndexedTree class which i really nothing more than a combination of my Sequencable and Traversable interfaces with some renames and undefines. In fact, with very little work I can make a object capable of stringification, pretty reasonable deep cloning, method currying (basically pre-packaging a method and its instance as an anonymous subroutine along with your choice of pre-assigned arguments), and comparison abilities (the <=> is overloaded). An array like object is pretty much slapping a Sequenceable interface with a constructor and your done, same for hash-like object with the Keyable interface. Singletons can be implemented by implementing the interface and one method call (to initialize the instance).
Of course, we have not yet released this class lib, I am hoping to do so in early 2004 under the LGPL. (If anyone is interested in knowing more about it and possibly helping build/test/document it, feel free to msg me and I will see what i can do.)
As for Scott comments about type safety, I agree, type safety is cool. I love Ada 95 and that has to be the most draconian type model of them all (it had to be, the language was invented for the US Dept. of Defense to be used on its embedded software projects (read: nuke missiles)). But then again, look at languages like ML, which uses type inference rather than forcing you into some arcane type model. Mark Jason Dominus has a great presentation in ML and its type model, and how it all plays with Perl on his site , here is the link, its a good read.
So while I might agree with Scott that current Perl based OO is maybe not so good, I think that it is not the fault of Perl (which it seems from something you say Scott you dont either, but I am somewhat confused by your rant at the end).
In the end, I have found perl to be a great language to implement an OO framework in (better than the 12-15 other languages I have messed with and programmed in). Its freedom and flexibility can lead to bad ideas and even worse implementations, but that user-error, not Perl's fault.
Don't give up Scott, nothing is lost forever, the Perl community has it fair share of bad programmers, but so does every other language community (Java for example has ALOT). Perl's best hackers tend to be very smart and adaptable people, cut 'em some slack. :o )
-stvn
(p.s. - updated some wording, and formatting, as well as re-arranged some paragraphs so it reads a little smoother)
(p.p.s. - I just started reading the Traits/Roles paper, and it seems that is pretty much what I have been doing all along with my Interfaces, although I am a little more premisive with object state variables (but not too permissive))
| [reply] |
Re: Will role-based programming be part of the standard Perl 6 distribution?
by simonm (Vicar) on Dec 22, 2003 at 22:58 UTC
|
I also spent some time reading the Traits paper after browsing the perl6-language list, inspired by ackme's sighting.
As I understand it, the approach the language team is taking, inspired by the Traits paper, aims to provide a common framework that will support a range of programming approaches: role-oriented, prototype-based, design-by-contract and/or aspect-oriented.
Update: Cf this from Larry:
: Where can I read up on roles a little more?
Well, it's not nearly as general as we're making it, but the
inspiration for it comes in part from the "Traits" paper:
http://www.cse.ogi.edu/~black/publications/TR_CSE_02-012.pdf
Basically, I'm attempting to take their concept and unify it with
properties, interfaces, generics, aspects, and mixins. Among other
things...
| [reply] |
Re: Will role-based programming be part of the standard Perl 6 distribution?
by scrottie (Scribe) on Dec 22, 2003 at 20:24 UTC
|
OO has existed for 30 years but hasn't been well understood
by a significant group of programmers until now - and probably
only 5 of them program Perl. Every bit of modern literature
you'll pick up - "Refactoring: Improving the Design of
Existing Code", "Design Patterns: Elements of Reusable
Object Oriented Code", "Object Orienged Design Heuristics",
or any other book written in the last 10 years that has
sold well on the subject, all agree: delegation, not composition, is the only way to fly. That is, the
only way to code with any sembelence of structure,
modularity, robustness, and run-time and compile-time
dynamicness.
"does" muddies the water, trying to make essentially
inheritance (composition) more "powerful", but it isn't the right
kind of power, and like computed symbol table entries
and eval, the power lures programmers into doing things
the wrong way because the wrong way is just SO easy,
atleast initially.
The problem with inheritance, in a nutshell, is as
you compose and compose, you wind up with one huge
object that is an amalgamation of now no longer
distinct parts - an "everything". Sort of like
"everything" in the "Everything Engine". Each node
is an embodiment of potentially everything. It includes
all of the code. When one node relates to another,
it relates to another everything. This isn't a critism
of the everything engine - many programmers accidentaly
discover that they've written exactly this through
constant promotation of objects or records in a database.
Saying to yourself over and over again "well, this is
kind of like that, and sometimes it might need to do
that, so we'll just make them both the same thing".
Do you see where this is going? There is no relationship
between parts, no structure. Aggregation (considering
a structure of several objects)
becomes
almost impossible. Multiplicity (where one object has
several of a subpart rather than just the one it
gets through inheritance) becomes impossible.
This isn't bizarre and it isn't the least bit of a
surprise to anyone who sticks their head out of the
perl camp now and then. This is known as the
God Object, and Perl programmers are infamous for
repeating this sin over and over and over. We're
called amatures and hacks because of our gross and
sustained ignorance. Perl projects seldom stay
maintainable as they grow large and are often thrown
away and replaced with Java because of this blind
spot in our collective software engineering know-how.
In Perl 4, when you used a "toolbox" module that had
all of your routines in one place - that was a god object.
In Perl 5, when you download a CPAN module that tries
to be OO but is actually itself one huge object with
no decomposition, that's a god object. Most fit this description - DBI, LWP/HTTP::*, and a few others are
notable exceptions.
Adding more and more logic to a given class to
compose something that embodies all of the behavior
you want is also known as
Mix Ins.
This is one mechanism that god objects are arrived
at by and one that Perl 6 is quite proud of. Hello?
And Perl 6 is formalizing all of this after two generations
of Perl. When it should be making delegation easier.
Delegation is, in a word, structure. Rather than
objects being (isa) other things, they reference them.
The other object is seperate. Messages are propogated
across the structure according to the
Law of Demeter, which says that objects in a structure
should only depend on the interface of objects
immediately next to them, and those objects should
depend on those immediately next to it, and messages
should be propogated. The opposite is one object knowing
and being dependent and hardcoded to the structure of
the entire jumbled of objects - a trait of god objects
and the only practise of Perl programmers.
Perl can't do objects right. It isn't a problem anywhere
in C code - it is a cultural one. It is like trying to
teach apes to hold tea parties. Perl will never stand
on the same ground as Java, C++, C#, or any other language
currently in fashion for thier object support.
Larry Wall asked that the cultural be reinvented
along with the language - very astute indeed. I've
been evangalizing, doing PerlMongers presentations,
blathering on IRC, trying to explain to perlers what
type safety is, why 80% of new code written is
in a language that has it, and why they should understand
how it works even if they don't use it. You know how
far I've gotten? No where. Perlers have their heads up
their arses just as far as any Atari or Amiga users
ever had and more and more it seems like Perl is going
to go the way of the Atari ST. I'm sorry, I try really
hard not to be inflamitory, but if I didn't *try*
to sound a wake-up call, I wouldn't be doing my part.
So, for once, princepawn is right on - there is very
little advantage to making inheritance more complex.
It is a strawman for the real problem, but the
problem stems from an ignorance that perlers will do
nothing about.
-scott
(edited repeatedly to make use of terminology
consistent, include the link to mixins, re-arrange the
slurs slightly)
| [reply] |
|
| [reply] |
|
Did you read the Traits paper?
I did and even though they mentioned prototype-based programming as related work, they did not mention any shortcomings of it or how traits (Perl roles) improves on it.
| [reply] |
|
|
chromatic, form your own assessment and espouse its
relative virtues. This is the formula:
1. Take something that needs to be said. "You're wrong!"
or "You missed a some nit!" aren't things that need be
said. The impact on the world is negligable.
2. Explain it. Paint a picture of what, why, and how.
Why is it good? What do people need to know? What tricks
are there? What pitfalls?
3. When other people do this, don't pretend that their
argument is propped up on one leg and try to kick the
leg out when it isn't. Specifically, if there are flaws
in their logic that lead to a faulty conclusion, it may
or may not be worth pointing that out. If their premise
is wrong, same. Attacking one point as if it to invalidate
everything said is naive and misleading to readers.
In this case, my post was a survey of issues. Though
you question one of my premises, it is not a critical one -
in fact, it was an issue I wanted readers to make up their
own minds about. You've only managed to state something
that should be obvious.
4. As long as we're talking about elemetary formal
logic, if one thing can't be proved (it was never
said that traits are mixins for certain, though it
was implied by Piers atleast, therefore there is no
confession) that doesn't automatically make the
opposite true. Truth and provability are seperate things.
The modest writer will post opinions as opinions,
not as an interpretation of anothers words, and not
as something infinately defensible. I've tried to
follow in the modest writers footsteps. Again, the
reader should find their own truth - this is only
evidence and opinion, some mine, some popular.
The reader that limits themselves to what is provable
does nothing but this sort of political nitpicking.
You're asking me to take issue with a source - the
traits document (which ghostview/ghostscript renders flawlessly). I'd ask you to do the same - I've
summerized popular opinion on the topic and made a
classification that is correct according to an outsiders
view of perl. Your turn - go read "Object Oriented
Design Hueristics". And don't cop that "I graduated
from college, I know everything there is to know about
OO" attitude. I hate that. C++ programmers used to do
that before the designpatterns/refactoring revoluation.
Now everyone studiously improves their skills without
boast or complain after college - except Perl programmers
and other script kiddies.
5. Get a life. I don't mean to single you out, chromatic -
I'm addressing everyone that mindlessly replies to posts.
Do you have the same attitude in real life, walking around,
trying to push everything over just to see if maybe
it will fall, or to make people think that maybe it
will fall? If you only want to chime in as agreeing or
disagreeing, upvote or downvote.
I hate this sort of henclucking. Since I haven't formally
renounced it yet, I thought I would do so once, just
so that I'm on record. So, anytime that you reply
to a post of mine in the future and I fail to resond
in a never-ending contest of one-upmanship, do me a
favor, and just assume that the lack of reply means
"I've said what I have to say, and I don't like how
you work". Now, in the past, other poeple have pointed
out things that were useful and interseting - not just
to me, but to anyone reading - and to those people -
you know who you are - I'm grateful.
-scott
Addendum:
PS - okey, maybe I don't like you for other reasons,
haven't had my coffee, am just bitter because no
one uses typesafety.pm and am probably wrong. I'll take
a more careful look - if they do infact allow delegation
I'll be seriously impressed. Still, I really really
need the negitive exp - I'm starting to itch past
level 4 and there are too many exp whores here. Whores!
Whores!
| [reply] |
|
|
Please don't assume that Perl 6 will not support delegation. (At least, don't assume it so hard...)
| [reply] |
|
Maybe if typesafety ran on as many platforms as perl, perl users may be more inclined to give it a try.
| [reply] |
|
Sort of like "everything" in the "Everything Engine". Each node is an embodiment of potentially everything.
I don't think you understand how the Everything Engine works, and furthermore, I don't think that presenting a false understanding in order to draw an even more flawed analogy will bring you closer to proving your thesis.
Rather, it makes you look foolish and ignorant.
| [reply] |
|
|