jacques has asked for the wisdom of the Perl Monks concerning the following question:

Recently on #perl, someone brought up that scalar assignment with a single-line loop was not as desirable as a more functional approach. For example:
$select_dfn .= "$_, " foreach (@columns);
Versus...
$select_dfn .= join '', map "$_, ", @columns;
Personally, the first approach makes more sense to me at first glance. Which one would you use and why?

Replies are listed 'Best First'.
Re: Scalar assignment with loop iterator considered bad?
by BrowserUk (Patriarch) on Jul 22, 2005 at 18:39 UTC

    For that particular piece of code I'd use

    $var = join ', ', @columns;

    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.
      Your code doesn't do the same thing. It leaves out the last comma.

        Fair enough

        $var = join( ', ', @columns ) . ', ';

        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.
Re: Scalar assignment with loop iterator considered bad?
by Zaxo (Archbishop) on Jul 22, 2005 at 18:44 UTC

    I'd do it the third way, $select_dfn .= join ', ', @columns, ''; Preference for the styles you show is a matter of taste between procedural and functional. Benchmarking might show a reason to choose between them in a particular language (like Perl).

    After Compline,
    Zaxo

Re: Scalar assignment with loop iterator considered bad?
by tilly (Archbishop) on Jul 22, 2005 at 19:45 UTC
    There are a lot of people on #perl with a lot of opinions. While I agree with people who would use a join approach, of those two I would pick the first because it has the smallest number of "moving parts". It is therefore a conceptually simpler line of code.

    I'm not a big one for labels. Just because one approach is labelled "functional" doesn't mean that it is better. Use whatever is simplest for the job at hand. Besides, the person doing the labelling doesn't know what functional means - the presence of the .= operator makes neither version functional.

    The only advantage of the second one is that you can chain together maps to add complexity. However even that advantage is questionable since chains of maps lead to so much complexity that the maintainer is likely to balk while trying to figure out what it is doing (let alone what it is supposed to do).

Re: Scalar assignment with loop iterator considered bad?
by Roy Johnson (Monsignor) on Jul 22, 2005 at 20:39 UTC
    It's interesting that they didn't say in what way it was less desirable. It made me wonder whether they weren't thinking of the trouble caused by declaring a my variable in a modified statement:
    my $foo .= ",$_" for qw(1 2 3); print "$foo\n";
    Because there is no block, $foo is in scope for the print. But for reasons I can't really explain, it's not handled as you might expect, and $foo is undefined in the print. If you declare $foo separately prior to the for, then it works as expected.

    Caution: Contents may have been coded under pressure.
      I suppose this construct does indeed create a block, even if there isn't any curly bracket. That a very good reason to prefer the "map" or the "join" versions: no hidden scope problem.
        The best explanation I can find is here.

        Caution: Contents may have been coded under pressure.
Re: Scalar assignment with loop iterator considered bad?
by ysth (Canon) on Jul 22, 2005 at 18:46 UTC
    Whichever felt best to me?

    Did they define "desirable"? The first one could result in multiple reallocs of the string buffer, but that's not such a big deal.

Re: Scalar assignment with loop iterator considered bad?
by Adam (Vicar) on Jul 22, 2005 at 19:30 UTC
    In this particular scenario, I'd use join(). Why write code to do what a native perl function will do for you? From a functionality perspective, letting join() do the work is probably better than concatenating a bunch of stuff in a loop. I'm sure you could come up with some example where looping was better - if, say, you were doing other stuff at the same time.
Re: Scalar assignment with loop iterator considered bad?
by socketdave (Curate) on Jul 22, 2005 at 18:39 UTC
    So, the functional version is more functional because it doesn't explicitly loop?