EDIT: I didn't mean to say that Haskell is as easy, or that the error messages are as good. I just mean that the error messages can give you a nice reminder of what you were working on, which I believe was the point of this post.
EDIT: I didn't mean to say that Haskell is as easy, or that the error messages are as good. I just mean that the error messages can give you a nice reminder of what you were working on, which I believe was the point of this post.
In haskell there are like a 100 ways of doing anything and it's very hard (for me at least) to figure out where even to begin. Elm tries to reduce options and lets noobs like me get going.
No, it was a couple years ago.
>compared to Haskell (which is also pure)
But which has both a real type system and a useful set of base libraries. The lack of basic stuff like monads is really painful in elm.
That said, in a recent HN post somebody said that the latest version of GHC has better error messages, which I agree would be welcome, but I haven't tried it.
Prelude> "foo" "bar"
<interactive>:3:1:
Couldn't match expected type ‘[Char] -> t’
with actual type ‘[Char]’
Relevant bindings include it :: t (bound at <interactive>:3:1)
The function ‘"foo"’ is applied to one argument,
but its type ‘[Char]’ has none
In the expression: "foo" "bar"
In an equation for ‘it’: it = "foo" "bar"
Yikes. Even worse, consider a similar situation with numbers: Prelude> 1 2
<interactive>:2:1:
Non type-variable argument in the constraint: Num (a -> t)
(Use FlexibleContexts to permit this)
When checking that ‘it’ has the inferred type
it :: forall a t. (Num a, Num (a -> t)) => t
Also the parser errors in Haskell are terrible. That the community has so long put up with "parse error (possibly incorrect indentation or mismatched brackets)" is a marvel to me, and is one of the most irritating errors to fix because of the (at least apparent) simplicity of improving it.The second error message, on the other hand, proves that the first one is a lucky accident.
No, the second error message just shows that there's more options there so the error message is vague and not very helpful. The first one is not an accident, it is the standard type mismatch error.
The compiler exposes that when numbers are involved it attempts (and fails) some fancy and unexpected reasoning involving forall, while with plain type constructors like [Char] it attempts (and fails) straightforward and intelligible pattern matching.
Figuring out the type of 1 and 2 might be more difficult than figuring out the type of "foo" and "bar", but the special rules should be hidden: a compiler that cares about practical usage would provide unified and clear error messages, possibly listing sets of alternative types it was unable to choose from.
And my point is that no it should not. "1 2" is more ambiguous, it could be more things, hence there is a more ambiguous error message.
Haskell is telling you 'you tried to apply a string literal to an argument as if it were a function, but it's not! It's a string literal. By the way, the string I'm talking about is "foo", which you tried to apply to "bar" in the expression "foo bar"'.
Yikes? It seems pretty helpful to me :)
Your second example is better, though.
Someone posted the output from Elm, which does this: https://news.ycombinator.com/item?id=11848467
Edit: checkout the elm error message page here http://elm-lang.org/blog/compilers-as-assistants
However, I'm left wondering... Elm seems to be using hardcoded knowledge about commonly used types such as strings and numbers in order to improve its error messages (I wonder why Haskell doesn't, by the way). What happens in Elm when an error occurs with more complex, user-defined types and operations?
If you're interested, there were a couple more examples shown elsewhere in this thread:
http://elm-lang.org/blog/compiler-errors-for-humans (an older version it seems)
https://twitter.com/st58/status/732908457217531904
https://twitter.com/GregorySchier/status/732830868562182144
Something I've just found is that the errors can also be output in a nice machine readable format, so the suggested fixes can be read in by your editor plugin.
And finally, this is wonderful, a specific repo for code that causes error messages and a request for people to submit error messages that are confusing: https://github.com/elm-lang/error-message-catalog
Also, although from a compiler's point of view it might make sense, the wording "The function ‘"foo"’ is applied to one argument, but its type ‘[Char]’ has none" doesn't make sense. It's clearly not a function if it doesn't take an argument. The same error message would be far clearer if it said something similar to "The expression ‘"foo"’ is being used as a function, but it is of type ‘[Char]’".
Also these are just two examples I rattled off the top of my head; the fact is that while the compiler is incredibly helpful in making sure your code is correct, it's less helpful in explaining itself. But, I also realize that producing good error messages is hard, and (I assume) significantly less interesting to many on the GHC team.
> "foo" "bar"
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm
You are giving an argument to something that is not a function!
3| "foo" "bar"
^^^^^
Maybe you forgot some parentheses? Or a comma?
Also > "foo" + "bar"
-- TYPE MISMATCH --------------------------------------------- repl-temp-000.elm
The left argument of (+) is causing a type mismatch.
3| "foo" + "bar"
^^^^^
(+) is expecting the left argument to be a:
number
But the left argument is:
String
Hint: To append strings in Elm, you need to use the (++) operator, not (+).
<http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#++>How do compiler errors look in Elm with generic functions involved, about which the compiler doesn't have any helpful hardcoded knowledge? (I.e. no "+" or strings involved).
Regarding hardcoded messages, there's been at some point talk in the community regarding allowing library authors to have some sort of hook to compiler that would make it possible to customize specific error messages along with a package.