in reply to Re^6: How could we "implement" Open Classes in Perl ?
in thread How could we "implement" Open Classes in Perl ?

Okay. Now take everything I say from here on in with a handful of salt because I've done little enough with javascript, and what I did do was a long time ago.

Let's say you have a 10 x 10 grid of these objects each with a getLeft(), getRight(), getUp() and getDown() (Yeah baby! :) methods.

That's 100 objects and 400 functions, no attributes.

But, if you gave each object knowledge of it's own position within the grid. Ie. if each had an x and y attribute, then you would only need 4 methods which took those x,y coords and returned the appropriate values based upon them.

So, you end up with 100 objects, 200 attributes and 4 functions.

Now, if you are calling those get*() methods a lot. then your method would avoid testing the boundary condition over and over, and that could add up to something significant in performance terms, and you would have traded memory for speed. A performance optimisation! Slightly faster, but simpler?

But, now try that another way. Instead of creating a function to return the adjacent objects, or storing the x,y pair as attributes. Store the adjacent objects as attributes.

Now you have 100 objects, 400 attributes and no functions. And no runtime condition testing! 400 object references has to take less space than 400 function references + the 400 code trees. And there are no function calls or runtime condition tests. You've saved memory and made the runtime faster still.

You can hold off on purchasing that octo-cored terabyte memoried superserver until next year's budget round. Or, if this is clientside js, then you've avoided alienating 50% of your potential market by allowing your app to run on their 4 year old hardware without upgrading :)


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.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."
  • Comment on Re^7: How could we "implement" Open Classes in Perl ?

Replies are listed 'Best First'.
Re^8: How could we "implement" Open Classes in Perl ?
by dragonchild (Archbishop) on Jun 27, 2008 at 20:58 UTC
    I'm also taking advantage of a few other facts in Javascript:
    • Methods are attributes. There is no inheritance in JS, meaning that every object has a direct reference to every one of its methods.
    • Identical functions are referenced (in most implementations). This means that identical code gets a reference to the existing version, not a new function.

    I could store the adjacent objects as attributes, but that prevents me from expanding my object model later on if, for some reason, the getLeft() method isn't static anymore. This future-proofs me.


    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      • This means that identical code gets a reference to the existing version, not a new function.

        Okay. That reduces your solution to 100 objects, 364 functions and zero attributes.

      • This future-proofs me.

        <voice type="clouseau"> Ah ha! The old it-future-proofs-me ploy. Very good. </voice>


      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.
        100 objects, 100 functions, and zero attributes. There is a function that returns each object. It gets slotted into attributes that may have different names. But, it's the same code. You would think that there's actually 101 functions - 100 for each object and 1 for null. But, the 1 for null is already provided by the runtime.

        As for the "future-proof ploy", the key is that it doesn't cost me anything to do things a way that allows me to have options down the road. For example, I could have a maze that shifts over time through the use of secret doors, etc. Using methods, I just have to change the method and the effect occurs at the location of the change. Using a normal design, getLeft() would have to know about all the different possible scenarios. This means that getLeft() would have updated every time a new method of changing the connections between the rooms comes up. Using this method, a new method of changing connections could be added without getLeft() ever having to be aware that it was changed. All of a sudden, we have a plugin system without any work.


        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      Identical functions are referenced (in most implementations). This means that identical code gets a reference to the existing version, not a new function.

      Hm. Quite hard to verify this, but I've succeeded in disproving it for 3 browser-based implementations and 2 standalone.

      If you load the following into a browser, and click the "allocate array" link, and check the memory consumption when the "Hi there" alert is displayed, you'll see the memory consumed by an array of 10000 references to a single function.

      <html> <head> <title>Javascript test</title> <script type='text/javascript'> var func = function () { return 12345; }; var size = 100000; var array; function allocateArray() { array = new Array( size ); for( var i = 0; i < size; i++ ) { array[ i ] = func; } alert( 'Hi there' ); } function populateArray() { for( var i=0; i < size; i++ ) { array[ i ] = function () { return 12345; }; } alert( "How's it goin'?" ); } </script> </head> <body> <a href=# onclick=allocateArray()>Allocate array</a> <a href=# onclick=populateArray()>Populate array</a> </body> </html>

      If you then click the "populate array" link, and again check the memory when the alert is shown, you'll see the memory consumed when those function references are replaced by references to an "identical" function that's declared in-line.

      If the JS interpreter was intelligent enough to recognise that the implementations are identical and somehow 'contant fold' them, there would be no increase in the memory consumption. The reality is, it at least quadruples in every implementation I've tested.

      BTW. It's really not a good idea to iterate arrays using for( ... in ..) as you do in Re^6: How could we "implement" Open Classes in Perl ?. See the highlighted box here for details.


      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.