Hacker News new | ask | show | jobs
by BrutallyHonest 3666 days ago
That's the biggest problem with adoption of academic-style (Haskell, OCaml etc.) functional programming languages.

The proponents believe that 'shorter = more readable'.

And if they would try to make it more readable it would start looking like Scala and C# (hence their popularity).

4 comments

The problem is that to some degree, shorter is more readable, but only where it allows easy interpretation of intent or allows more state to be visible at a time. Like most good things when taken to extremes, the positives are quickly outweighed by the negatives.

Keeping names informative is a good thing. Keeping names small enough that you don't have to scan across half a page when they are used is a good thing. Keeping thunk definition separate from control structures where it is used, when it's more than a line or two is generally a good thing. Finding the sweet spot when these and many other rules conflict is where experience comes in, and is part of the art of programming.

Don't blame Haskell, OCaml, etc. here. 90% of that syntax that is in the example is Swift specific and I agree it is cluttered and ugly. Swift would do better to stop trying to be like C/C++ and be more like ML (you can tell the language wants to be like ML, but I'm guessing there are internal politics to make it more C/C++-like for adoption reasons. There's even (or there were) a few design documents hinting at intentionally being C like).
I don't think the OP was "blaming" Haskell and OCaml as much as he was blaming the people trying to add Haskell and features and syntax to Swift and C++.

Haskell syntax works great for Haskell, because the whole language has consistent syntax for things like lazy evaluation and lambda functions. The problem is when people try to tack on those features to Swift or C++ and make it work with the ugly syntax from those languages, it ends up making it even uglier.

To me, the sample code looks like a bastardized mix of C++ and Haskell, and it's pretty hard to figure out what it's doing, even in the toy code samples.

Great point. Thank you for bringing out the distinction in OP's post.
I don't know, it seems to me that at least a few in the core swift team are well known C++ hackers. For example, in addition to Chris Lattner of LLVM fame, David Abrahams, which I believe is still the lead in charge of Swift standard library, was a founding member of Boost and, relevant to this post, (co-)author of Boost.Iterator. Doug Gregor which is also part of swift core team, is also a prominent ex-Booster.

Edit: Doug was of course also the principal author of the failed C++11 Concepts proposal

Similarly, there are people who will insist that the most "pythonic" solution to any problem is list comprehensions nested 3 levels deep.

It's OK to wonder "Can I do this one one line?" as long as you can step back and say "Yes but I'm not going to" sometimes.

That was one thing I really liked about the Google Python guideline posted here a few days ago: Their rule about list comprehensions. "three lines max, one for the element, one for the list generation and one for the filter clause - no nesting". That's the sweet spot.
And they're just wrong; that goes directly against the Zen of Python:

  Simple is better than complex.
  Flat is better than nested.
  Sparse is better than dense.
  Readability counts.
I too have a tendency to overuse list comprehensions over regular loops, but when they start nesting I know it's almost always time to break it up.
If anything, the problem with the given code snippets is that the code is needlessly cluttered by explicit type annotations for trivial things. Unfolding a lazy sequence is a short and sweet affair in Haskell and even ML (which doesn't enjoy the benefit of piggybacking on built-in lazy evaluation), where you only supply type annotations when inference can't possibly work (e.g., polymorphic recursion, which most code doesn't need).