5 ms·
The thing I struggle most with with Haskell is the direction towards cleverness that code seems to tend towards. I guess a lot of it may be a mindset issue - b
by deckiedan 11y ago
The thing I struggle most with with Haskell is the direction towards cleverness that code seems to tend towards.
I guess a lot of it may be a mindset issue - but the way the python forces simplicity is quite appealing to me. I've heard similar thoughts from people who like Go.
'Good' refactoring in Pythonland tends to mean often splitting things into smaller functions.
In Haskell, it can mean making functions 'points free', which is clever, can result in very nice looking one-line functions, which are totally incomprehensible unless you know exactly what types all the functions involved take and return. Or moving the logic out into combinators or higher order functions which can be used in many places, but become increasingly abstract in name and in variables.
Partial application & currying are amazing, and often results in very elegant solutions - but again, unless you know beforehand how many arguments a function takes, it's easy to miss that someone is talking about a curried function, and not the result of said function.
The crazy math-oriented naming of variables by single letters rather than by 'accumulator' or 'first_input' or whatever, especially in tutorials, API documentation, etc. also require an extra mental effort each time. It reminds me a bit of perl, in that way. Just because you can write code as a one-liner, doesn't mean it's always a good idea. Python refuses to let you write code as a one-liner (beyond very simple things), and so the tendency to name things extremely laconically is reduced. Pylint and other tools even throw warnings when you try to use single-letter variable names.
The argument always is, 'You can write complex & hard to understand code in any language!'. Yes. That's true. Of course. But also, languages are more than just the syntax, the culture and available libraries & documentation are quite a big thing too.
The direction of Haskell code is, at least in my feeling, towards increasingly abstract concepts. The direction of Python code is, IMHO, towards simplicity.
Another, perhaps related issue is Exceptions. In simple scripting / basic applications, you could have a whole bunch of different exceptions raised, and honestly, you don't care which one.
For instance, saving a file. If there's a permission error, out of HD space, invalid filename for this disk format, network timeout on NFS, restrictions on what kind of data can be put in this filetype, whatever. Some of these may be IOErrors, some may be json encoding errors, or whatever. Often, I don't care which it is, I just want to throw up an error message saying, "Something went wrong: %s." % err.msg. Being able to ignore exceptions in the small, write very simple & concise code that can raise many different kinds of exceptions, and only catch them further up where it makes sense can often mean I can lump many unrelated types of exceptions together by what area of the application they're part of.
I feel like Python is moving in the direction of a better compile-time experience with the new type annotation stuff in the latest 3.x version. I really miss that security when working in Python.
- phamilton 11y agoI think step one of Haskell is thinking in types. Step two is then to stop thinking in types. The string conversions lib is a great example. The function `cs` has about 20 definitions based on different types of input and output. Instead of being named TextToString or BytesToText, etc. There is just one function `cs` that can be used anywhere and everywhere. Supporting multiple input types is nothing special, but by inferring the output type from the context of the call you, as a developer, can safely ignore types. That was (and is) a difficult concept to wrap my head around. I do, however, find myself paying less attention to types until the compiler informs me I have a mismatch.