in reply to Re^4: bloated 'if' formatting
in thread bloated 'if' formatting

At the point of invokation, those methods are returning their result based upon the internal state of their objects. By temporarially storing the (composite) values of the methods into variables whilst deferring the decision based upon them, you create a window for opportunity for the internal state of one or more of those objects to change, through injected code, delay or some other mechanism.
This sound very profound, but if you'd always follow this reasoning, you'd never break down complex statements into multiple statements, or for that matter, use subroutines.

Programming is about making trade-off. Yes, you create a window of opportunity for things to change. But your gain is simpler, easier to maintain code. It's a price I'm usually willing to pay.

Perl --((8:>*

Replies are listed 'Best First'.
Re^6: bloated 'if' formatting
by BrowserUk (Patriarch) on Oct 07, 2005 at 10:22 UTC
    This sound very profound, but if you'd always follow this reasoning, you'd never break down complex statements into multiple statements, ...

    And that sounds like a good refutation, but it misses the point completely.

    If you understand some of the thinking behind Functional Programming (FP) and referential transparency, you'll see that what I'm suggesting is very similar. In (some variants of) FP, you cannot save composite values into variables as there is no assignment. It's proponents will tell you that this leads to safe, provably correct code.

    I won't go that far, but I do suggest that avoiding the duplication of state where possible--and especially where that duplication creates 'used once intermediary variables' is Very Good Practice.

    I realise that you see this "simplification" but believe to be 'complexification'.

    Either way, you have the same number of unavoidable clauses and states. Spreading them out over several statements, and introducing addition states in order to do so, does not simplify things. All the original clauses and states are still there, and you've added new ones to the mix. In the process you have spread those clauses and states far apart and made it harder to see the overall picture.

    Have you ever tried to navigate your way across a strange city using one of those A5 sized "A-Z" style maps? If so, you'll recall how disorienting it is to see only a very localised picture! And how easy it is to find yourself heading in completely the wrong direction because you don't have the overall picture.

    Sheet maps may be less convenient to handle, but the ability to see both ends of the journey at the same time, or even just the overall direction in which you are going, makes it much easier to avoid getting sent off in entirely the wrong direction by some town planners idea of the perfect one-way system.

    As a many times maintenance programmer, of both my own code and that collectively written by dozens of people working thousands of miles away on different continents, I'd much rather spend 5 minutes understanding a single compound statement, than 1 minute on each of 10 statements and another 10 minutes flicking up and down the file, or between files, trying to understand how each of those 10 "simple" statements fit together.

    The problem with using lots of simple statements to implement what can (reasonably and clearly) be achieved with one (or two, or three) compound statements, is that it enables, and actively encourages, the maintenance programmer to dive straight into the middle of the indivisible group and understand the action of a single statement, without recognising the effect that action has on the other statements around it. Or the affect that making the "simple change" that seems obvious, will have upon them, as a group.

    The great benefit of high and very high level languages, and their ability to do a lot in a few statements, comes not (directly) from the reduction in typing. It comes from the fact that code that performs those few statements is used in many contexts. And, as a result, is exercised (system and integration tested as opposed to unit tested) by many different people. Many, many times.

    This means that the bulk of the work is being done by very well exercised code, with each application benefiting from the testing, explicit or implicit, that is done by every previous application that used the same statements.

    The simplest way to throw away those benefits is to avoid using the facilities that the language provides.

    ... or for that matter, use subroutines.

    That's a very wrong inference to draw from what I've said, or from the references I posted.

    I have no problem at all in using function or subroutines, but I do suggest that 'used once subroutines' should be used sparingly and with care.

    A function that is re-used, as part of a library say, very quickly gets used in many different circumstances. It's interface and documentation get exercised by multiple programmers. And it get called in many contexts. This quickly highlights any assumptions made by the programmer, and any close couplings it may have on context.

    Used once subroutines do not get this real-world exercising, and no amount of unit testing is a substitute. This means that the assumptions and contextual coupling do not become apparent until someone comes along and changes one end or the other without the benefit of the overview the original programmer had when he wrote them. That is when things start to go wrong--in horribly subtle ways.

    In FP, the F stands for Function(al), and subroutines (in Perl) are all functions. FP uses them in abundance. In that way, all intermediary values becomes automatically managed, anonymous values on the stack. Both those thing are important.

  • As they are anonymous, the programmer cannot refer to them explicitly, so there is no scope for him to inject code in the wrong place or modify their value or misinterpret their name or use.
  • The automatic management means that they come into being at just the right time; exist for just as long as they are needed; and go away when the aren't. Their scope is defined by structure of the code, not some arbitrary (mis)placement by the programmer.

    Maybe you are young and haven't been bitten enough times yet. Maybe you're just very good and never make the mistakes. Maybe you haven't had to share your code with others that aren't as careful as you.

    As always, I'm not advocating my preferences for anyone else. They evolved over time through (my) experience(s) and are what work for me. I set some store by reading reputable people and sites that confirm my conclusions, but I often don't modify my own practices solely because someone else says they do things differently--even when they are luminaries and/or offer sound reasoning to support their case--if it conflicts with my own experiences and conclusions.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.

      Maybe you are young and haven't been bitten enough times yet.

      58, going 59, coding since 1969. Bitten enough to know which trade offs to make.

      I do appreciate your reasoning. I share your concerns, but in my experience, if people add new code in random places, I've a bigger problem than just my statements no longer being together.

      I just sometimes prefer to split up complex statements into smaller parts. IMO, when modificiations are in order, simpler statements are less error prone than complex ones.

      Perl --((8:>*
        58, going 59, coding since 1969.

        I see you've arrived at your own conclusions via your own experiences. I tip my hat to you Sir.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        The "good enough" maybe good enough for the now, and perfection maybe unobtainable, but that should not preclude us from striving for perfection, when time, circumstance or desire allow.