Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

perl6 & OO

by chance (Beadle)
on Feb 18, 2004 at 23:04 UTC ( #330086=perlmeditation: print w/replies, xml ) Need Help??

I apoligize if this is too broad/big of question for this forum. Not sure where else to ask.

Are the object-oriented features of perl6 already mostly figured out? or are they still completely up in the air?

I tried to figure this out by googling and perusing dev.perl.org/perl6/, but just couldn't.

I for one like perl5's object system just fine. I can understand why some people don't, but if I think too long about losing ability to set things up exactly how I want them, it feels like getting kicked in the stomach. I've seen some people refer to it as "tacked on", but I see at as very elegant and minimalist.

Replies are listed 'Best First'.
Re: perl6 & OO
by Ovid (Cardinal) on Feb 18, 2004 at 23:48 UTC

    I won't comment on the Perl 6 00, but I couldn't help but notice this comment:

    I see [perl5's object system] at as very elegant and minimalist.

    Perl 5 OO is great, but once I started working with other OO languages, I realized that there are some features that are missing.

    I want to be able to do method overloading based on signatures. That's not build into Perl. In Java, it's simple"

    public void foo(int x) { // do something with x } public void foo(int x, int y) { // do something with x and y }

    In Java, the number of arguments and their types will determine which method is called. In Perl, you generally have to build your own dispatch method (there are CPAN modules to do this) and this is prone to bugs.

    I would like a clean separation of class and instance data. In Java, I can simply use the "static" keyword.

    Want private variables and methods? Use the "private" keyword. They're not too hard to do in Perl, but that seems like an accident. I frequently use anonymous subs attached to lexical variables to get private methods, but that's not intuitive to a new Perl programmer.

    Protected methods in Java can only be used by the class or its subclasses. Trying to prevent a calling program from using them is fairly easy, but it's not built in to Perl.

    And the "canonical" example of a Perl constructor:

    sub new { my ($class, %data) = @_; bless \%data, $class; }

    Now anyone who wants to violate encapsulation can do so by reaching directly into the object. Also, you lose the benefit of using "strict".

    This is not to say that Perl's OO is awful. Multiple inheritence can be good (if you really need it -- delegation is typically better), but Java's "interface" hack doesn't allow them to solve their single-inheritance limitation.

    Cleanly building a bunch of accessors and mutators on the fly in Perl is a breeze. Not so for Java. You typically have to cut-n-paste the code (if I recall correctly, EJB can solve this problem).

    Perl's OO is very easy to use and I quite like it, but it does have some limitations and people should be aware of them.

    Cheers,
    Ovid

    New address of my CGI Course.

      When you try to code Perl like Java, yes, you run into the problems you mention. But i never try to code Perl like Java ... that's why we got Java! ;)

      Personally, i think that Perl's OO IS kinda awful, but it works great for me and my small team that uses it. My friend who codes Java with a large Java team still has nightmares to deal with, everyday day. Is that Java's fault? I don't think so ... i think the people with whom you work matter more than the tool you choose. And, generally speaking of course, if you work with some not-so-talented people, then maybe your team should be using Java instead of Perl. ;)

      jeffa

      L-LL-L--L-LL-L--L-LL-L--
      -R--R-RR-R--R-RR-R--R-RR
      B--B--B--B--B--B--B--B--
      H---H---H---H---H---H---
      (the triplet paradiddle with high-hat)
      

      Exactly. I'd like methods give compile errors if their arguments if they are the wrong type. Even using mechanisms like strict, etc, Perl is a little dangerous when it comes to OO syntax. When I'm writing a straightforward non-OO app, this is fine, and I can deal with it, but when I really want objects, I want Perl to understand them and enforce them, rather than allowing them to be scalars. I think this could be accomodated for in the oft-unused Perl message-signature feature, which right now only takes basic types.

      Also, it's really odd what determines when a class has a certain method. For instance, if I have a "$program->run" and a "$dog->run" I don't want to be able to call $foo->run() and have it work with both dogs and programs. I want method overloading. I want cleaner inheritance and things like "super()". I'd like to be able to specify virtuality and non-virtuality.

      Having a dog run and a program run? This does not make sense. Chewbacca lives on Endor, and this does not make sense. Therefore we must have more strongly-checked OO.

      I started my OO life learning C++ and Java, grew to love Java, grew to hate Java, but it wouldn't be bad if Perl became a little more mainstream in it's OO. Just don't repeat Java's failings -- inconsistant API, lack of multiple inheritance, exception hell, etc. Perl already has a leg up since it has a much stronger base library -- so a little cleaner OO syntax to go with that library, that would be great.

      My only OO heresy is that I despise "getter and setter" methods. Maybe that's not heresy, maybe those methods are against the spirit of message passing (I think they are). Anyhow, Perl doesn't have to mandate style as far as java does, where a programmer is cast down for making a public variable. It should, however, start to treat objects as though they have types.

        I think this could be accomodated for in the oft-unused Perl message-signature feature, which right now only takes basic types.

        Apoc. 6 went through a total revamp of subroutines signatures. You can still use them like:

        sub foo { my ($bar, $baz) = @_; . . . }

        If you really want to, but if you did that, you'd be missing out on a lot of really cool stuff. I'm not so sure I personally want rigidly-enforced typing, but some of the signatures make calling conventions easier and make it obvious when we've called something incorrectly. At the same time, little flexibilty is lost over doing a complete check of @_ before we get to the actual code of the subroutine.

        Type systems applied to objects is one way to solve the problem of $dog->bark vs. $tree->bark, but I'm not sure if it's the best. Delegation and Traits (both widely talked about in Perl6 development) are potentially much better.

        My only OO heresy is that I despise "getter and setter" methods.

        Hardly heresy. Having lots of accessors and mutators (i.e., methods which provide direct access to private data) is a sign of poor class design. I won't go as far to say that they should be absolutely forbidden. Whenever I enter such a debate, I hear this Drunken Scottish Object Programmer saying:

        Ya can't just spread aaaccessors and muuutators all over your class design there ladie. You're screwwen the whole point!

        But then again, maybe I should get the voices in my head checked out.

        ----
        : () { :|:& };:

        Note: All code is untested, unless otherwise stated

        For instance, if I have a "$program->run" and a "$dog->run" I don't want to be able to call $foo->run() and have it work with both dogs and programs.

        What's wrong with each providing a run method? If I'm iterating over a collection, I will not be putting both a program and a dog in the same collection. If I do, I probably have a serious confusion in my code. But what if I have a list of animals?

        foreach my $animal (@animals) { $animal->run; }

        That's what polymorphism is all about. Fortunately, that's very easy to do in Perl. Perl does provide many of the most useful OO features in Perl. What it lacks is easy to use encapsulation.

        As for getters and setters, can you think of any popular language with OO features that doesn't allow them? This isn't a Perl issue as far as I know. It's an issue with programmers treating objects as structs with methods calls. In fact, this is not a Bad Thing, so long as it's used appropriately.

        I think this could be accomodated for in the oft-unused Perl message-signature feature, which right now only takes basic types.

        Can you provide an example? I'm curious. If you're referring to prototypes (I don't think you are), then you should be aware that those are checked at compile time while method dispatch is resolved at runtime, thus making prototypes useless on method calls.

        Cheers,
        Ovid

        New address of my CGI Course.

      sub foo { my $self=shift; if (@_==1) { // do something with single arg } elsif (@_==2) { // do something with two args } }

      Point is that in a language like perl we can a) simulate the behaviour of java, b) we can provide behaviour that java plain and simple cant provide.

      Incidentally what do we do with

      foo(@bar);

      Which version of foo should be called? Should the langauge simulate the if that i put inside the sub above? If so what do you do when you have a situation that doesnt make sense? For instance if @bar contains 3 vars. What should it do? Call the var version and ignore the third? Die?


      ---
      demerphq

        First they ignore you, then they laugh at you, then they fight you, then you win.
        -- Gandhi


        Your first example shows a limitation with Perl. By being forced to use a conditional to deal with the number of arguments, we automatically introduce more chances for bugs because every conditional is an opportunity for bugs to arise. The fewer conditionals you have, the fewer bugs you're likely to have. Obviously you can't avoid them, but fewer should be needed with proper OO design. With Java, the method called is automatically the one you want. Not so with Perl. What happens when you want to handle one, two, or three arguments with different behavior if the optional third argument is a string or a float? In Java, that's four methods. In Perl, typically it's an ugly if/else construct with the logic handled in the method or then dispatched to to the other four methods.

        As for the case of foo(@bar), Java wouldn't handle that the way a Perl programmer is expecting because it doesn't turn that array into an argument list. Instead, it would dispatch it to a method that takes an Array object. To simulate that in Perl, create an array object or pass the array by reference.

        This also brings up a strength of Perl that's a limitation in Java and many other languages. In Perl, are functions and methods are implicitly variadic (they take a variable number of arguments). If you code your methods right, this can be useful, but it can also mean that arguments fall off the end.

        Because of Perl's behavior, strange bugs are available. Consider this:

        sub foo { return @foo } $object->bar($wibble, foo());

        Some people might be fooled into thinking they're passing at least two arguments. However, if @foo is empty, then &foo will return an empty list and when the list is flattened into the argument list of &bar, you'll only have one argument:

        $ perl -MData::Dumper -e 'sub foo {@a}; bar(1,foo()); sub bar {print D +umper \@_}' $VAR1 = [ 1 ];

        Again, I love Perl, but the lack of useful prototypes can really hamper the language at times.

        Cheers,
        Ovid

        New address of my CGI Course.

      Ovid wrote:

      Protected methods in Java can only be used by the class or its subclasses. Trying to prevent a calling program from using them is fairly easy, but it's not built in to Perl.

      Actually, protected methods in Java can also be used by classes in the same package. Nevertheless, your point is well-taken. I was working on a project recently where I wished that I had some way of faking protected (and, yes, I am aware of Class::Fields, but that wasn't an option at the time--long story).

      Benedictus

        "Protected" has a different definition in pretty much every langauge that has it as a feature. It all encompasses the idea that objects that are friends get extra operations on each other. In Perl, you can emulate the feature using caller by checking the package of the code that called you. It's a flexible solution (you get fine-grained control over who gets to call you and who doesn't), but it can get sloppy fast.

        ----
        : () { :|:& };:

        Note: All code is untested, unless otherwise stated

Re: perl6 & OO
by hardburn (Abbot) on Feb 18, 2004 at 23:42 UTC

    Apoc. 12 hasn't been released yet, and even then there is likely to be some changes between it and what is ultimately produced in the first stable version of Perl6.

    I think it's important that when you talk about Perl5 objects, you need to speicify a little more. Usually, people are talking in terms of bless, but Perl5 has many other concepts which qualify as object systems that have nothing to do with bless, and some others that use bless in less traditional ways.

    The bless object system is rather tacked on because of its implementation using references to common Perl types and the way it looks up methods. While there is no good way of implementing multiple inheirtance, Perl's method lookup is slow. Further, it's harder to enforce the interface because Perl lacks useful subroutine prototypes.

    I was able to put some ideas I had about flexibilty onto firmer foundations when I read the ReiserFS whitepaper. It contains this axiom:

    The flexibility of a system depends on the number of possible connections between components.

    It goes on to say that you can increase the number of possible connections between components either by increasing the number of components or by increasing the number of components that know how to talk each other. For instance, any Unix program that knows how to write data to STDOUT can talk to any other Unix program that knows how to read data from STDIN (though it also has to have some understanding of what the data looks like).

    To know how to talk to each other, each component needs an agreed upon way of talking to another component, i.e. a protocol. In terms of objects, the interface is your protocol. Break your interface, and suddenly components can't talk to each other anymore, and thus flexibility is reduced.

    This is why, IMHO, having strict interfaces is actually a net increase for flexibility. Sure, your individual object might be less flexible, but by being loose with your implementation, you've made other parts of the system harder.

    That's why I think Perl5's bless objects are so tacked on. The flexibility of implementation provides too many ways to break object privacy, thus breaking the interface, and thus making an overall less flexible system.

    ----
    : () { :|:& };:

    Note: All code is untested, unless otherwise stated

      The truly flexible system will provide both "glue" flexibility and "lego" flexibility. Perl 5 is good at "glue" flexibility, but not so good at "lego" flexibility. Perl 6 is trying to provide both kinds of flexibility.
Re: perl6 & OO
by Abigail-II (Bishop) on Feb 18, 2004 at 23:29 UTC
    Are the object-oriented features of perl6 already mostly figured out?
    Considering Larry hasn't even released an apocalypse about OO in Perl6, and that features change even years after their apocalypse was released, I doubt this is the case.
    I for one like perl5's object system just fine. I can understand why some people don't, but if I think too long about losing ability to set things up exactly how I want them, it feels like getting kicked in the stomach.
    Yeah, that's why I prefer to program in C instead of Perl. Noone is going to tell me how to implement my hashes or regexps!

    Abigail

Re: perl6 & OO
by chromatic (Archbishop) on Feb 19, 2004 at 01:27 UTC

    Are the object-oriented features of perl6 already mostly figured out?

    Yes.

Re: perl6 & OO
by awwaiid (Friar) on Feb 19, 2004 at 15:59 UTC

    I've always thought that OO is better conceptualized as a fancy syntax for passing a datastructure as the first argument to a function. The really important part of OOP is not objects but rather modules... keeping code clean compartmentalized. In perl the syntax boost is on the object-users' end and not so much on the object-implementors' end... making the overall syntactical sugar slightly less sweet. I think it does go in line with the rest of Perl, however... considering the parameter passing technique for example.

    So though I agree that the current way is nice and minimalist, I think that a bit more sugar wouldn't hurt :)

      No. Thinking about objects in terms of fancy data strucutres tends to lead to bad OO design. One of my personal rules is that bad OO is worse than no OO at all. Perl's bless object system doesn't help this state, because it comes right out and says "Hi, I'm a datastructure, and now I'm an object, too!", whereas most languages have the good sense to hide this dirty little secret.

      The trick to thinking in OO is to stop thinking about the underlieing data. You can know it's there, but you don't touch it yourself. Instead, you're calling methods that provide the means to munge the data in predefined ways.

      ----
      : () { :|:& };:

      Note: All code is untested, unless otherwise stated

        I think you bring up a very important point about OOP. Perhaps this is the difference between an imperative view and a functional view. Your view, which I'm taking to be the imperative view, might say that we do things with objects. We command them to keep track of a new setting or to tell us about themselves.

        In the functional view we would instead say that an object is more of an expert -- an expert at manipulating a specific data structure. We give it the old data structure and ask for a manipulation and it gives us back a new data structure. You could think of each and every method as a function which maps the old datastructure onto the new one. Often functional languages which have objects use this viewpoint, and for me Perl does too.

        But thats one of the reasons that perl is so cool... you can look at it either way :)

      This fairly well summarizes my views of (the most important part of) OO. Essentially you want to manage instances and scope. Polymorphism, inheritance, and encapsulation are given as the 3 tenets, but the first is the concept of keeping instance data and functions clean and orderly. It's possible to write code in a non-OO way that reaps 80% of the gains. You can go a heck of a long way with C code that always takes pointers to structs as first arguments...it's just less sugary. Perl is somewhere between that C-style and languages that fully support require OO. I'd like it to move a little more right, but not all the way to the right.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://330086]
Approved by Ovid
Front-paged by Trimbach
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2021-10-17 15:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My first memorable Perl project was:







    Results (71 votes). Check out past polls.

    Notices?