Thu, 01 Jun 2006

Join Map Ord Split

Just when you thought Perl couldn't get more unreadable, someone[0] comes up with something like this:

print join ", ", map ord, split //, $foo;

This mess of perl might be easier to understand if I put the brackets in:

print join (", ", map( ord, split( //, $foo)));

What this does is split $foo into a list of characters. It then uses map to run ord() on each item in the list to return a new list containing the numeric character values. We then join these again with ", " to make the output easier to read.

david% perl -e 'print join ", ", map ord, split //, "word";'
119, 111, 114, 100

The map function is familiar to functional programmers and is very powerful, but beware it can reduce the clarity of your code.

[0] Me

[] | # Read Comments (7) |

Comments

It seems to me that the problem with the legibility of the code is the sequencing operator being a comma. If it was a pipe it would be a lot clearer. Oh, and backwards :)
Posted by Jon at Thu Jun 1 14:49:20 2006
It can be made (arguably) more readable with =>, the "fancy comma":

% print join ", " => map ord() => split //, $foo
119, 111, 114, 100

The parens after ord are needed because => quotes to the left.

One problem is that => looks like flow is going in the opposite direction to the truth. I believe Perl 6 has <== which feeds the output of the thing on the right into the thing on the left, and a corresponding ==> which does the opposite and makes Jon happy. :-)
Posted by resiak at Thu Jun 1 15:55:10 2006
Uhm, imagine that that said `perl -le 'print join ", " => map ord() => split //, $foo'` :-)
Posted by resiak at Thu Jun 1 15:56:14 2006
Well, here's one example where the perl is no less readable than the python!

The transliteration is

$ python -c "print ', '.join(map(str, map(ord, 'word')))"
119, 111, 114, 100

but I'd probably just use

$ python -e "print map(ord, 'word')"
[119, 111, 114, 100]

since the resulting list is printed in a legible enough form.

I think perl and python are so close in this case because they both spell out the function names ("map", "print") in real English words (or abreviations, "ord") that you could search the documentation for and not too much "executable punctuation" (implicit loop variables, etc.).  Hey, they even use the same words!
Posted by Stefan at Thu Jun 1 20:16:11 2006
Oops, make the second line read "python -c" as well of course  :)
Posted by Stefan at Thu Jun 1 20:20:48 2006
The first version reminds me of

join ", " . map ord . split "" $ foo

in (pseudo-) Haskell, although

join ", " $ map ord $ split "" $ foo

would be closer in meaning.

I find higher-order functions to more often make code I read more, not less, clear, but my mind may be warped.
Posted by tennin at Thu Jun 1 22:16:24 2006
map is a great function and one which I wish belong to Java's collection classes for a long time (we'll ignore the lack of function pointers for the time being).

I think the bigger issue around clarity is the optional use of parenthesis. I've seen it a lot in Ruby code. For a very few cases, omitting brackets can make the line of code read like a sentence, but more often than not I find it obscures things. My preference is one way to do things so you can easily recognize it, so I'll always use brackets in my method calls in Ruby, and similarly in Java I'll wrap my if statements with { }.
Posted by Miles Barr at Fri Jun 2 00:13:12 2006

Name:


E-mail:


URL:


Comment:


Please enter "fudge" to prove you are a human