in reply to Memory efficiency, anonymous vs named's vs local subroutines

Further to GrandFather's reply: Not only is it difficult to figure out how such code works, even then it probably doesn't work the way you (thanos1983) think it does.

Consider the "Variable "$x" will not stay shared at ..." warning(s) you get when you run such code (you are running your code with warnings enabled, right?):

Variable "%s" will not stay shared
    (W closure) An inner (nested) *named* subroutine is referencing a
    lexical variable defined in an outer named subroutine.

    When the inner subroutine is called, it will see the value of the
    outer subroutine's variable as it was before and during the *first*
    call to the outer subroutine; in this case, after the first call to
    the outer subroutine is complete, the inner and outer subroutines
    will no longer share a common value for the variable. In other
    words, the variable will no longer be shared.

    This problem can usually be solved by making the inner subroutine
    anonymous, using the "sub {}" syntax. When inner anonymous subs that
    reference variables in outer subroutines are created, they are
    automatically rebound to the current values of such variables.
(See perldiag.) Anonymous subroutines allow proper closures to be formed and maintained.

WRT local-ized subroutine names (or anything else, for that matter), remember that a localized thingy is visible within the scope of all subroutines subsequently invoked within the localizing scope. I.e., its localization is dynamic. A lexical variable (e.g., one holding a code reference) is visible only within the scope of the block in which it is defined, i.e., its scope is, well, lexical. To me, lexical scope is much to be prefered over dynamic scope unless you have a very clear (and well documented) reason for choosing the latter.

As to the difference in memory usage between local-ized and lexical subroutines: I must admit I've done no research or experimentation, but I doubt there is any significant difference.


Give a man a fish:  <%-(-(-(-<

Replies are listed 'Best First'.
Re^2: Memory efficiency, anonymous vs named's vs local subroutines
by thanos1983 (Parson) on Jul 18, 2015 at 19:05 UTC

    Hello AnomalousMonk,

    Thank you for your time and effort. You are right, no matter what tutorial, article I read all they say the same. The possibility when you nesting functions to mess up your code is really high. You assume that your code does one thing, but in reality it does 10 others on the background.

    I will stick in simple named functions, for every simple implementation called at the main script.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
      I will stick in simple named functions...

      Simplicity is always a good goal and a good yardstick for judging your code. But I don't want to discourage you from using anonymous lexical subroutines: they work, and they work the way you think they work! In fact, Dominus wrote a whole book (freely available here — and highly recommended!) that's essentially just a zillion ways to use anonymous lexical subroutines.


      Give a man a fish:  <%-(-(-(-<

      I will stick in simple named functions
      For usual plain-vanilla subroutines, e.g. just pieces of code that you want to use several times and/or call from different places in your program, and that will usually take zero, one or more input parameter(s) and return one or more return value(s), named subroutines are certainly simpler, easier to understand and to maintain. And that's what I would be using in such cases.

      There are, however, some slightly more advanced techniques that are using anonymous subs and give you a lot of power, just as references to anonymous arrays and hashes allow you to build nested data structures (arrays of arrays, arrays of hashes, etc.) that would be very tedious or in some cases next to impossible to build with named arrays or named hashes.

      I would also recommend to every reader the Higher Order Perl book, by Mark Jason Dominus, mentioned above by AnomalousMonk, in my view the best CS book I've read in the last ten years. It is available on line on the author's site. Just one word of warning, though: it is not for pure beginners, you need to have at least an intermediate level Perl to really take advantage of it (although the first 2 or 3 chapters are probably accessible to "advanced beginners").

      Among the things that anonymous functions make possible or, at least, make usually much easier or more generic:

      • Callback functions (subs passed as a parameter to another sub)
      • Dispatch tables (arrays or hashes of code refs to define program behavior depending on a certain parameter)
      • Function generators and function factories (functions that return many other functions depending on the input parameters)
      • Iterators (functions returning values usually one at a time, on demand)
      • Closures (functions that maintain alive part of their run-time environment)
      • More generally, higher-order functions and abstract generic functions, and quite a few other things that I can't explain in just one line here.
      In very strict terms, probably none of the techniques above absolutely requires anonymous subs, but only using anonymous subs will really unleash their full power.