These are just surface syntax, so who cares? Humph. I do. I care way too much about syntax. Anyway:
- Haskell definitions use =, not def/define/defun. Small change, but it just looks a little cleaner. (I think there is at least one Lisp that uses =, and Arc uses it for state changes.)
- Haskell avoids nested parentheses with compose/apply syntax. In other words you get this:
sort . concat . map (Str.split ‘ ‘) . Str.split ‘\n’ $ s
instead of this:
(sort (concat (map (Str.split ‘ ‘) (Str.split ‘\n’ s))))
This is a lot less scary for most people, but it makes it more obvious that we’re just writing backward OO syntax with less punctuation:
s.split(’n').map(Str.split(’ ‘)).concat.sort
I don’t know about you, but the three snippets become progressively harder to type and (I suspect) easier to read for most people.
- This last difference is not really syntax. When prototyping I eventually learned to read the syntax of compiler errors almost as well as runtime exceptions thrown by Python. It’s still not quite as good but I have got nearly as fast for almost all prototyping code*.
Other than that, Haskell reminds me a lot of Scheme now that I’m more or less fluent. Just with a lot of extra stuff—this is a big language, not a small one**. That’s OK with me, that’s why I stopped using Scheme (that, and the libraries).
*That last bit is the occasional algorithm that is more naturally imperative than functional. I’m still not much good with Haskell’s imperative features.
**Ergo, I am not using a lot of the stuff that’s not like Scheme. Yet.