Low level programs contain a lot of ad hoc, buggy, and slow implementation of higher level languages. Paul Graham described an excellent idea in “Hackers and Painters”
If you solve a hard problem, the question is not whether you will use a powerful enough language, but whether you will (a) use a powerful enough language, (b) write a defacto interpreter for one, or (c) yourself become a human compiler for one.”
[…]
For example in the OO world you hear a good deal about “patterns.” I wonder if these patterns are not sometimes of case (c), the human compiler, at work.”
In short, as developers we like concise, unbloated languages that is sufficient for what we need.
In-list functions
I was reading Peter Norvig’s spell correct and discovered python had in-list comprehensions. It’s a nice feature which allows you to easily construct a list.
>>> [ x**2 for x in range(1,11) if x % 2 == 0 ]
[0, 4, 16, 36, 64]
It looks very readable. Now, ruby being my favourite language over python, I wanted to see if ruby had a similar feature. The best I can come up with is this:
2.0.0-p247 :017 > (1..10).to_a.map{|x| x**2 if x%2 == 0 }.compact
=> [4, 16, 36, 64, 100]
This isn’t as easy to comprehend. For instance, why is it necessary to have .compact
?
Why do we need to call .to_a
? Python wins in this case. I’m now a lesser fan of ruby and more of python.
Lastly, I checked this out in haskell – which many consider to be a dense language. It’s also a language I’m looking to do some coding in.
Prelude> [ x^2 | x [4,16,36,64,100]
Not bad. I’d argue that this is as easy as pythons – provided that you understand haskell syntax. Syntax wise, I suspect python is more wordy than haskell.
Ruby lambda vs. procs
In ruby, lambda and procs are pretty much the same, but not quite. Syntactically, they are similar.
lambda_larger_than_4 = lambda { |num| num if num > 4 }
proc_larger_than_4 = Proc.new { |num| num if num > 4 }
(-1..8).to_a.collect &lambda_larger_than_4
=> [nil, nil, nil, nil, nil, nil, 5, 6, 7, 8]
(-1..8).to_a.collect &proc_larger_than_4
=> [nil, nil, nil, nil, nil, nil, 5, 6, 7, 8]
However, there are two main differences.
- Lambda checks number of arguments passed to it and throws error. Proc ignores unexpected arguments and assigns nil to any missing.
- When lambda returns, control is passed to caller. When proc returns, control does not get passed back to caller.
The Mathematica version of the first example (from Aaron aaron@scaledinference.com):
Select[Range[1, 11], Mod[#, 2] == 0 &]^2