I’ve been trying to implement an Elm compile (here) in my free time and I found a weird edge case in the language syntax with the prefix minus. Using the elm repl I get the following output:
> 1 - 2
-1 : number
> 1 -2
-- TOO MANY ARGS ----------------------------------------------------------- elm
This value is not a function, but it was given 1 argument.
4| 1 -2
^
Are there any missing commas? Or missing parentheses?
> 1- 2
-1 : number
> 1-2
-1 : number
In the second example there is an error because the prefix minus has higher priority that the function application, but in fourth example there is no error.
I want to know how the compiler determines the priority of the prefix minus, unfortunately I don’t know Haskell well enough to just read the compiler source code.
That sounds like a really fun project! I hope we hear more about it someday . To answer your question, when the elm parser sees - it first parses it as a binary operator. Then it does an explicit check for this exact scenario: if I just parsed a minus sign, and there’s no trailing space, then convert it to a negation. At least, that’s my best attempt at translating the Haskell. Here are the exact lines if you want to dig more.
Thanks for your attempt to translate the Haskell code, even if it’s similar to Elm, I get lost at those $ and <-
Seems like I just need to handle the special case, the problem is that I don’t have the position of the tokens when parsing, I plan to add that in the near future for better error reporting, but for now I will have to use different tokens for the - and - with spaces.
Also since the project is in Rust I can compile it to WebAssembly, so you will probably hear about the project soon.
Totally an opinion and clearly not on parity with how elm currently works but I say make infix operators not surrounded by whitespace a syntax error. elm-format isn’t going to let you get away with writing 1-2, 1- 2 or 23|>String.fromInt, I can’t recall a time I’ve seen anyone use those forms, and elm is a whitespace significant language anyway.
On a related note, 1<-2 produces:
I do not recognize the (<-) operator.
34| let _ = 1<-2
^^
Is there an `import` and `exposing` entry for it? Maybe you want (-) or (<)
instead?