I've forgotten the $ in some usage of do or a final argument lambda twice in the last week even.
I think it's worth solving these (superficial?) syntax issues even if they only affect the comfort of a third of all Haskell programmers.
I've forgotten the $ in some usage of do or a final argument lambda twice in the last week even.
I think it's worth solving these (superficial?) syntax issues even if they only affect the comfort of a third of all Haskell programmers.
I can understand that the syntax may be unpleasant, but I don't think having to memorise even more precedence rules makes a language more pleasant.
When I read and write Haskell, my default "mode" is to see whitespace as function application, i.e. if I see "A B" then I assume "A" is being applied to "B". Hacks like "A $ B" interfere with this, since I have to mentally back-track and re-parse them as "$ (A) (B)".
> I've forgotten the $ in some usage of do or a final argument lambda twice in the last week even.
This is exactly the kind of thing I was lamenting. Rather than (ab)using "$", why not do the more natural thing, which every other language does, and use parentheses for grouping?
Instead of "forgetting the $" in
atomically do
v <- readTVar tv
writeTVar tv $! v + 1
Why not use parentheses for the job they're designed for, and write: atomically (do
v <- readTVar tv
writeTVar tv $! v + 1)
Likewise, for withForeignPtr fptr \ptr -> c_memcpy buf ptr size
You can use parentheses and never "forget the $" withForeignPtr fptr (\ptr -> c_memcpy buf ptr size)
Parentheses are a universally understood syntax for grouping, they're supported in editors (e.g. finding matching pairs, checking if they're balanced, etc.), they always work in the same way, have no interference with other constructs or edge-cases, etc.Don't get me wrong, the "$" function is really useful, for example in "map ($ arg) [func1, func2, func3]", but I don't see the point of abusing it to avoid parentheses. I do sometimes use it myself, but whenever there are multiple infix functions around, I'll tend to use "redundant" parentheses for grouping.
Firstly, to get this out of the way, you shouldn't be using significant indentation when generating code unless you have a good reason; use parentheses, curly braces and semicolons instead https://en.wikibooks.org/wiki/Haskell/Indentation#Explicit_c...
Now, I wouldn't say parentheses and offside rules "don't mix well", but I'll grant that there are interactions to keep in mind.
It's true that Haskell's indentation edge-cases are unfathomable, although thankfully I've never run into any. I have no strong preferences either way regarding significant whitespace, as long as there's an "escape hatch" for code generation (i.e. the braces and semicolons I linked to above).
Regarding Python, its lambdas aren't "single line", they're "single expression"; that expression can cover as many lines as you like (e.g. see my SO answer http://programmers.stackexchange.com/a/252546/112115 ).
When learning Haskell, after being a long time Python programmer, I used to think Haskell's indentation rules were complicated. These days, I find it awkward to indent Python code, and end up second-guessing the interpreter a lot.
Maybe that's because I'm fond of using 2D code layout and vertical alignment to indicate relationships between lines, which is quite natural in Haskell. Python's indentation seems to be limited to counting blocks, so it's hit or miss whether adding extra spaces to align things will cause it to choke or not.
edit: Having looked at Reason more closely, I now see where the confusion came from. Sorry, I didn't mean to deceive you.
Both purescript and agda have this
IMHO a Rust-style type `Option<HashMap<String, Vec<u32>>>` is a little noiser than the Haskell-style type `Maybe (Map String [Int])`, but not fatally so. Maybe there are much worse cases though?
I am not a fan of C#'s `Func<a,b>` at all.
I have been using Haskell for around a decade and hate every infix operator spam I have to throw in there to please this syntax irregularity.
Other than this, I quite like Haskell syntax, but I remember initially hating it. It took many weeks to get used to it.