http://www.perlmonks.org?node_id=297195


in reply to Re: Think for yourself.
in thread is the use of map in a void context deprecated ?

Let me address various points somewhat out of order.
However, I find it difficult to believe there are people that find map in void context "unclear", "obfuscated" or "bad style". I can certainly understand people having problems with map. But I find it hard to believe there are seasoned Perl programmers that have no problem with map if the map is on the right hand side of an assignment, but are suddenly getting confused if they assignment disappears.
This argument rests on a basic fallacy that is easiest to explain by example.

It is trivial to demonstrate that any competent Perl programmer is unlikely to be seriously confused if a particular line of code is accidentally put at a different amount of indentation than it would normally have been. Certainly any programmer who finds it difficult to cope with this is in the wrong line of business.

Should we therefore conclude that indentation is not an important aspect of programming style?

Obviously not. And the reason is that stylistic questions are not fundamentally about whether or not a given programmer can figure out a situation, but rather about subtle points that affect the efficiency with which that programmer works. For instance cuing expectations about the structure of code - as indentation does - makes it easier to skim through and narrow down on the section that is likely to be of interest to work with at the moment. Therefore indentation style is definitely relevant to programming style, even though no programmer has trouble understanding it.

So it is with map. While I have no trouble understanding a map in void context, using a map for its side-effects violates my expectations of what map is for. Therefore reading code that uses maps for their side-effects is less efficient for me. The flip side is that reading code which tries to avoid interesting side-effects inside of maps can now be more efficient for me than it would be otherwise. Since I read and edit a great deal of my own code, and read and edit rather little that uses map for side-effects, this trade-off is a net win for me.

What is the difference between what these lines should do?
map do_something($_), @some_list; do_something($_) for @some_list;
They should do the same thing. But to my eyes the second reads much more clearly, and I believe that the same holds true at virtually any level of Perl expertise.
Well, they don't do the same thing; or rather, you cannot deduce from this code fragment whether they will do the same thing or not...
Note the placement of the word should. Buried in that is a normative expectation. Yes, you can abuse context in any way that you want. But I consider it poor style to use context for anything other than the formatting (or generation) of return results. Yes, I could hold constant an awareness that context could be so (to my eyes mis-)used. But amortized over the code that I deal with, my current expectations pay for themselves.

What is your feeling if you see:
user_defined_function {BLOCK} LIST;
Utter confusion? Or is this ok, as long as it's not called 'map'?
My opinion is that the author should try hard to set appropriate expectations in the function name and documentation. Furthermore I consider it the duty of the programmer who chooses whether or not to use that function to decide whether or not it is appropriate to use that given his or her environment.

BTW for future reference, a function of that exact form whose API strongly violates some people's expectations is on_release in ReleaseAction.

This does not, of course, justify deriding someone who has picked up the meme of map in void context. But it does indicate gently pointing out that there are clearer ways to do the same thing.
I disagree. It's ok to say that you have problems understanding the concept of map in void context, and that you prefer another style. But it's not ok to suggest that getting confused over a map in void context is something that all Perl programmers suffer from. Just point out it's your own personal preference.
While I will continue to point out that it is my personal preference and will continue to say why, after this discussion I certainly won't insinuate that map in void context is an undefensible stylistic choice. And the biggest single reason for that is Re: Re: Think for yourself.. That shows how maps in void context can arise as a natural leftover of a productive coding style.

Replies are listed 'Best First'.
Re: Think for yourself.
by Abigail-II (Bishop) on Oct 07, 2003 at 09:39 UTC
    While I have no trouble understanding a map in void context, using a map for its side-effects violates my expectations of what map is for.

    I think this is the main point where you and I differ. What makes "map" so holy that it shouldn't be used for side-effects? Who or what started this notion? Not Larry, otherwise he wouldn't have made $_ an alias for the list element being processed. Many functions in Perl have side-effects, both user defined and core functions. Why is it fine to have side-effects in a 'for', but not in a 'map'? It's not that 'map' is called 'apply_a_function_and_return_a_list_of_calculated_values'. 'map' just means 'map a function over a list' - and I've been familiar with both the name and its function longer than Perl exists.

    Abigail

      This is a good question. And I don't know the answer.

      I can try to answer where I picked up the notion though. I first saw map and grep actually used in a bad CGI book (whose title I have forgotten), where the author was trying to tell people to write loops like that. I thought the advice was silly, and it didn't take long before I learned enough to realize that the book was bad. Furthermore I noticed that people who were far more experienced than I sometimes criticized people for using map and grep for side-effects, and I filed that away as another fault of the book.

      When I later saw map and grep being used more appropriately, it was in the context of side-effect free transformations. Not long after that I ran across them in some material that I was reading about Lisp, and about functional languages, which advocated making functions side-effect free for a variety of reasons (mainly more transparent modularity and easier debugging). I took the notion back to my Perl, and began using map and grep fairly consistently, but always with side-effect free blocks.

      This stylistic choice became a habit, and the habit became an expectation, and that continued with rather little thought about the matter on my part until this week.

      So I guess that the answer is that the people who chanted against map and grep in void context set my original notions, and then the notion that it was good to actively avoid having them have side-effects came for me from other languages that I was trying to learn about.

      I doubt that many other Perl programmers who hold my opinion hold it for the same reason though.

      People often call "map" and "grep" functional programming techniques. Since in pure functional programming there are not side effects, this may explain why some people (including me) don't expect side effects in them.