[Israel.pm] Perl vs. Ruby on Two Idioms

Shlomi Fish shlomif at iglu.org.il
Sun Jun 22 13:49:29 PDT 2008


On Sunday 22 June 2008, Yitzchak Scott-Thoennes wrote:
> On Sun, June 22, 2008 2:06 am, Shlomi Fish wrote:
> > On Saturday 21 June 2008, Adam Fine wrote:
> >> The natural Ruby equivalent to your Perl solution would be:
> >> h = {}
> >> a.map {|k| h[k] = true}
>
> That's not equivalent - it's quite a different thing to be referring
> to h in the implicit loop.  I'm curious to know if there really isn't
> a ruby equivalent to my %h = map { $_ => 1 } @a;

Yes, so would I.

>
> > Yes, but this takes two statement. Cognitively, it is one operation and
> > so I want to do it in a single statement.
>
> Someone else commented that the declaration is a separate operation.
> But I find being able to declare at point-of-first-use a really great
> feature for encouraging limited variable scope.
>
> >> Even this is clearer than the Perl solution, of which it is a direct
> >> translation.
> >
> > I have no problem reading the Perl solution, and neither would any
> > intermediate Perl programer. And doesn't the map call build a long list?
>
> Yes, if you are referring to the perl map.  But building a pairlist and
> assigning it to a hash is simpler to read (once over the "hurdle" of
> determining that the map is building a pairlist), IMO, than a loop that
> is tweaking the hash on each iteration.
>
> >> But if this is a clarity contest, then here's the clearest
> >> Ruby solution I could think of:
> >>
> >> h = {}
> >> for key in a h[key] = true end
> >
> > This uses a loop (which is probably slow) and is 4 lines long. It's not a
> >  clarity contest, and there is no problem in the clarity of the Perl
> > program.
> >
> >> It doesn't get much cleaner than that :)
> >> The direct Perl translation of my last solution is:
> >>
> >> my %h; for my $i (@a) { $h{$i} = 1; }
> >>
> >> It's pretty obvious which form is clearer :)
>
> That may be clearer than the a.map above, but still less clear IMO than
> the perl hash assignment.  If that is saying the ruby "for key" is
> clearer than the perl "for my $i", how so? - I just don't get it.
>
> > The former one to me, which is probably also faster.
>
> Let's not get into that; any of the suggestions is fast enough
> given reasonable constraints on the inputs.  And wth potentially
> unbounded inputs, the iterative approaches become mandatory.

Well, I still dislike the explicit looping (in Perl or otherwise) because it's 
less idiomatic. I once said on Hackers-IL:

{{{{{{{{{{{{{{{{{{{{{
[Me:]
> > Some software engineering paradigms (most notably Extreme Programming)
> > claim a code need not be much more modular than it should be to accomodate
> > for all of its features.
>
[Oleg:]
> I am not sure I understand the statement. It sounds like
> "overengineering is bad," which is sensible. On a more general note,
> it seems to me that the useful elements of extreme programming are
> sensible but not original.
>

[Me:]
Actually it does mean that "overengineering is bad". A code can never be
too modular. But then again, you have to stop somewhere if you want to get
a working one.
}}}}}}}}}}}}}}}}}}}}}}

( http://tech.groups.yahoo.com/group/hackers-il/message/2495 )

So what I said was valid English, but there was a more idiomatic way to say 
it. Similarly, in Perl it would be preferable to use the map { $_ => 1} over 
the loop, because it's shorter and more idiomatic. This is because code is 
also meant to communicate meaning to fellow programmers, and not just the 
computer.

>
> >> To sum up, we translated directly your solution to Ruby,
>
> Nope.  See above.
>
> >> and ended up
> >> with cleaner code.
>
> Nope.  See above.
>
> >> Then we demonstrated what must be one of the clearest
> >> solutions possible, implemented in Ruby.
>
> Nope.  See above.
>
> >> Then we translated the clear
> >> solution back to Perl, and clarity was degraded.
>
> Nope.  See above.
>
> Some other perl constructs that I'd be curious to see ruby equivalents
> of, where possible:
>
> my %h; @h{@a} = (1) x @a;
>
> my %h; @h{@a} = ();  ... if (exists $h{$foo}) { ... }
>

So would I. Although in the case of using the hash as a set I prefer to use 
exists(...) too normally. Sometimes I use $count{$line}++ or $count{$word}++ 
to do word counts.

BTW, is the excellent presentation that that Jerusalem.pm Perler (a woman) 
gave on the Israeli Perl Workshop available online?

Regards,

	Shlomi Fish

P.S: unrelated to that you may enjoy my recent photos from a ride I took to 
Park Hayarkon on Friday. Here's the set:

http://www.flickr.com/photos/shlomif/sets/72157605725109009/

-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
Interview with Ben Collins-Sussman - http://xrl.us/bjn8s

The bad thing about hardware is that it sometimes works and sometimes doesn't.
The good thing about software is that it's consistent: it always does not
work, and it always does not work in exactly the same way.



More information about the Perl mailing list