Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^10: Data Structures

by BrowserUk (Patriarch)
on May 08, 2008 at 12:15 UTC ( [id://685448]=note: print w/replies, xml ) Need Help??


in reply to Re^9: Data Structures
in thread Data Structures

Wait, your confusing me now :P

:) I'll take it that this is now redundant. My objections are not "whether" OO or Moose are useful, powerful desirable. Just when.

And the 'bugs' I alluded to were purely hypothetical. The point being that as systems become more complex, the costs of managing and negotiating between the sub-component authors grows exponentially. Users of complex systems have to take that into account when deciding if the benefits of re-use of those complex systems outweigh the costs to them. Including when things go wrong inside those systems.

If a users application requires, and will benefit from, a large proportion of the features--code generation, introspection, etc.--that Moose provides in buckets, then it's a no-brainer to stand on the shoulders of those that write and maintain that complex, powerful and well-designed system, rather than starting from scratch.

For the OPs application, as described, I do not think those criteria are met.

The guys over at Best Practical are trying to replace all my XS usage with Pure Perl alternatives,

Whilst I think that Pure Perl alternatives have some merit, I also think that the (further) performance hit of removing all the XS code from Moose would be a mistake. Most XS code will compile on Win32/AS, with only minor changes. The difficulty is in locating them.

Oh, please do, I would love to convert you :)

I don't need converting to the benefits of OO--used appropriately. As far as Moose is concerned, I'm already convinced that is is "best of breed" for projects requiring its featured. Far better than most everything else in the Class::* and Object::* name-spaces.

Could you be more specific as to what you mean? I would happily remove a dependency if the replacement were as simple as that.

It's not just about simple substitution. It also about choosing to use some of them.

  • Sub::Uplevel

    From the Caveats:

    Well, the bad news is uplevel() is about 5 times slower than a normal function call. XS implementation anyone?

    Perl's function calls are already slow. Moose places (of necessity for its function) many extra layers of function call over raw access. Rather than adding another layer, who's only purpose is to deceive, it would far better (for everyone) to give full traceback (ala Carp cluck/croak)), than to impose the performance & misinformation penalties of "hiding the truth".

  • Sub::Exporter. a sophisticated exporter for custom-built routines.

    There's a lot going on inside this module. That's a result of the power of the features it can provide.

    The question is: Is Moose using or benefiting from that power? Would Exporter or Exporter::Lite, or even just a custom import() serve Moose equally well for its needs, and avoid some of the overhead?

  • Sub::Name -(re-)names a subroutine.

    What does return subname 'Moose::Role::extends' => sub {... }; buy you that

    *Moose::Role::extends = sub{ ... }; (or even: sub Moose::Role::extends {...} doesn't?

    (I think I may understand the reasoning behind not using the latter, but better that you decide one way or another yourself

FWIW, to use Moose, you really just need to read...

Sophisticated systems require a good deal of good documentation. My comments were simply to defuse the notion that use of accessors/getters simplifies maintenance of nested, built-in data-structures.

The question here is: do you need or benefit from the sophisticated system (for your specific application)?.

For this application, loose wrappings around built-in data-types, my conclusion is no. That in no way detracts from Moose when used for that for which it is intended.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re^11: Data Structures
by stvn (Monsignor) on May 21, 2008 at 20:40 UTC

    Sorry, been meaning to respond for a while, but been busy. I do agree with you that if OO is not appropriate, then don't use OO. I have been a huge fan of functional programming for a while, and honestly if I could use OCaml/LISP/Scheme/etc for $work, I would, but there is basically no decent libraries and lots of academic "abandonware". That said I am also not a big fan of YAGNI, and since at $work we typically maintain our apps as well as write them, I prefer to treat even small projects as if they might grow large (which they typically do, at least for us). But anyway, this is all a matter of style and environment. So let me just address the dependencies you listed.

    Sub::Uplevel

    This is not my dependency, but a dependency for Test::Exception, which I consider a key part of any good testing toolbox. So that one is not going anywhere unless the Test::Exception author removes it. Moose does not ever use it itself.

    Sub::Exporter

    Well to start with, Exporter is gotta be the biggest piece of bloatware in the perl core modules. I hate that module with a passion, just thinking about how bad it is makes my skin crawl. I never cared for Exporter::Lite either, it is better, but really the @EXPORTS and @EXPORTS_OK stuff is that makes me stay away, I don't like having to make public variables to export stuff.

    Sub::Exporter on the other hand is awesome. Not only is just for exporting subs (who the hell exports variables anymore really), but it can do all sorts of fun tricks. You couldn't do this with Exporter:

    package LOL::Cat; use Moose 'has' => { -as => 'i_can_haz' }; i_can_haz 'cheeseburger' => ( is => 'rw', trigger => sub { print "NOM NOM" } ); LOL::Cat->new->cheeseburger('KTHNXBYE');;
    Really, I think Nuff said there :P

    Sub::Name

    Well first let me say that we have made this dependency entirely optional now as part of the whole "make XS optional" thing that the Best Practical people asked for.

    What does return subname 'Moose::Role::extends' => sub {... }; buy you that *Moose::Role::extends = sub{ ... };
    To start with the CV will still have the name "__ANON__" and will not seem to come from the "Moose::Role" package (unless you did that code within the Moose::Role package itself). I think that it is important to maintain this internal consistency when building classes. But anyway, it's optional now so you can skip it.

    -stvn

      Starting at the end (cos the the challenge was interesting:).

      Sub::Exporter on the other hand is awesome. ... but it can do all sorts of fun tricks. You couldn't do this with Exporter:

      Who needs Exporter :)

      package LOLCat; use pudu 'has' => { -as => 'i_can_haz' }; i_can_haz 'cheeseburger' => ( is => 'rw', trigger => sub { print "NOM NOM" } ); 1;
      #! perl -slw use strict; use LOLCat; LOLCat->new->cheeseburger('KTHNXBYE'); __END__ c:\test>t-pudu.pl NOM NOM

      And what is actually required inside pudu.pm to make that happen?

      It's minimal, just enough to meet the requirements of the challenge, but I hope it is enough to show that much of what Moose does, could be met without large dependency chains, and rather more efficiently. (Especially once you drop the need for bondage and discipline!)

      I guess that sums up my feelings about a lot of this kind of module. (Sub::Exporter et al.) At their core, they provide a single, useful mechanism. But then, almost inevitably, they feel the need to add to that basic mechanism a bunch of "fun tricks", which whilst fun, often aren't required by most of their users. And the provision of those additional features, as much for the sake of having something to put in the POD as anything else, leads to complexity and bloat. Not just because of the presence of the additional code to provide those extra, little-used features. But also in additional code in the core, oft-used features in order to support the little used ones. With the result that code that only needs the core, useful mechanisms is often paying a penalty for the support of features that they don't use.

      For the authors of these modules, they only test & benchmark their code from one level above, and the penalty seems minor. But once you get to the level of a complex framework like Moose, that utilises several of this type of module, and uses two, three & four levels deep chains of them, each adding its own layer of "fun tricks" and their associated (unnecessary) overhead, the individually small deltas start to add up.

      Now imagine me writing my graphics application using Moose. I have a hierarchy of classes: Solids inherit from WireFrames inherit from Lines inherit from Point3D; and the core of my application is doing hidden Line and hidden Face removals on complex Solids before rendering to a View2D--the very stuff where Class/Object mechanisms like Moose are at their most useful and productive. And at each layer of my application I'm picking up the products of the deltas below Moose and compounding them over the layers of my application above Moose.

      The result is that small, negative performance delta don't just add up, but multiply up, and my app is running 2 or 3 or 4 times more slowly because of the presence of features in the lowest levels that I, nor most other Moose users will ever use.

      If you are really up for a challenge?

      tos recently posted a behemoth of a piece of really quite awful code. (No disrespect meant tos. Its given me hours of fun exploring it). It sets out to be OO, but throws everything into one huge file because he's taken a bunch of short cuts (global vars mainly) to work around things he didn't understand how to do using Perl's DIY OO mechanisms. I had a couple of attempts at splitting it up into modules and making it work, but never really had the motivation to see it through.

      It runs a 3D Rubix Cube (3x3, 4x4 or 5x5) simulation using Tk as the display tool, making extensive use of OO (mostly) to perform the math. It runs, in its presented, messy, badly structured form, with a surprising turn of speed. You can spin and rotate the cube in 3 dimensions using the mouse, and (when it doesn't crash) the graphics keep up with you.

      The challenge is for us to agree the Moose-style class definitions for the 8 classes required by the Rubix Cube application:

      package matob; package point3d; package line3d; package vec3d; package rect3d; package cube3d; package slice; package qb;

      and then you port it to Moose and I'll extend pudu just enough to meet that specification. We could then compare, from all aspects, the results.

      I realise that this is more than just a couple of hours work and that you're a busy guy, busy doing $work and maintaining Moose. But the results would make for a very good demonstration of the power of Moose (he said trying to tempt :).


      (*)I mentioned "bondage & discipline" above. I realise that this is what a lot of your customers are asking for, and you are supplying that need. I did start to question that need here, but decided that it was irrelevant to the subject and besides, I feel a meditation on the subject coming on, so I've deferred that for another thread. And for the record. The more I learn about what Moose does (and the way it does it for the most part), the more impressed and enthralled I am by it. I'm even more impressed by what you and your team have pulled together so quickly.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        Your argument against Sub::Exporter does not make sense to me, it seems as if you are saying that I should only provide as much features as my user base uses and that the extra bits inside Sub::Exporter that I am not using are slowing me down. To start with Moose is not a simple one-size-fits-all module, some people use it as a simple accessor generator and base.pm replacement, but others use it as a full fledged metaprogramming system and hit on edge cases I never even imagined to exist. Now, very few people have taken advantage of the extra bits that Sub::Exporter adds, basically anyone who has done what is described in the "EXTENDING AND EMBEDDING MOOSE" section of the Moose POD. However, that said I do not think that providing a broken (Exporter) or minimal (hand-coded to the exact spec) would be a superior solution, it would only mean then when people wanted/needed those extra features I would have to add them or say "no sorry I used Exporter and it sucks to bad" or "Well it will take me a while to add that to my hand-coded solution". Sure you can make an argument for speed, but not all of us are as speed obsessed as you seem to be. Perl is getting faster (the Moose and Class::MOP test suites both run noticably faster in 5.10) and computers in general are getting faster (the argument that Moores law has a ceiling really doesnt apply to this specifically so lets not go there). You can also make an argument for "extra dependencies", but honestly I dont see the problem with dependencies. If we were coding Python and this was 3-4 years ago and there was no decent module repository and dependency management tool, or better yet, if we were coding Java today,.. then I could understand that argument. But we have CPAN, and despite the number of problems it has, the benefits of it far outweigh them. There is (IMO of course) absolutely no excuse for not using the CPAN as much as possible. This is not to say that people shouldnt re-invent wheels, I think that is an excellent way to learn and grow as a programmer, and if you wheel is better then please upload it. But anyway, I digress, and honestly I think we will have to agree to disagree on many of these points.

        It's minimal, just enough to meet the requirements of the challenge, but I hope it is enough to show that much of what Moose does, could be met without large dependency chains, and rather more efficiently. (Especially once you drop the need for bondage and discipline!)

        Hmm, not really, not really at all. Where is the MOP? Method modifiers? Roles? And what about types? You call it B&D, but really its much more about sanity checking, if you have only ever used the strong type systems of Java/C++/C#/Ada then I would understand your dislike, but if you explored the more superior type systems that are offered in ML/Haskell/OCaml, then you would feel differently I suspect. Again, seems here that you are advocating only providing as many features as you need for a given usage. This may create efficient code with minimal dependencies, but this does not promote generic re-usable solutions. Sure, this can be your choice in the trade-off, but it is not mine.

        Hmm,.. I am almost starting to think you have a background in embedded systems or something, given this obsession with efficient code that can run in a small space with few dependencies.

        I guess that sums up my feelings about a lot of this kind of module. (Sub::Exporter et al.) At their core, they provide a single, useful mechanism. But then, almost inevitably, they feel the need to add to that basic mechanism a bunch of "fun tricks", which whilst fun, often aren't required by most of their users

        I disagree completely on this with regard to Sub::Exporter, every feature that it provides is useful and well thought out. I know for a fact that RJBS uses a good portion of them in his $work code too, they are not just "fun tricks". I suggest you give this set of slides a look, he goes over a lot of what Sub::Exporter can do and where it is useful.

        Again, it seems your only looking at the surface features and what the top layer provides and not digging deeper to see the possibilities. I believe that modules like Sub::Exporter and Moose are "disruptive" modules, meaning they force you to stop and rethink previously held assumptions and ways of doing things. Just as Moose is helping to rid the Perl world of hackish DIY-OO programming, so too could Sub::Exporter be used to fix some really ugly and horrid code in some other modules (I wish I had the time to show an example of this, perhaps I will at some point).

        If you are really up for a challenge?

        No thanks, the code looks like a mess and I am not really in the mood to detangle that. If you want to clean it up and port it to Moose I will be glad to work with you in making sure it is as Moosey as it can possibly be.

        But the results would make for a very good demonstration of the power of Moose.

        I totally disagree, this is a performance intensive application, and Moose has well known performance issues. If I didn't know better I would think you were stacking the deck against Moose here ;)

        -stvn

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://685448]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-23 18:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found