If you allow a, b = f < t1, t2 > ( c ), it can only be parsed if you know whether f is generic (if it's not, then a and b are bools), which requires whole program parsing because f could be defined above, below, or in another file.
Basically, if you want to have a sane grammar, don't use angle brackets for generics or pipes for lambdas. It looks good to humans but really screws up the computers.
IIRC, Elm uses this approach to disambiguate '.' and unary minus in function applications.
The major nuisance is that you need to somehow handle "<<" and ">>" properly: either by a "lexer hack"; or by lexing only single "<" and ">", and recombining them in the parser when appropriate; or by splitting "<<" and ">>" in the parser when appropriate; or by not having "<<" and ">>" in the first place.
specification: https://go.googlesource.com/proposal/+/refs/heads/master/des...
https://play.golang.org/p/NQL1rVp-wVC -- it's trying to interpret that as (1<2)<3, and the types make no sense for that.
> It does not [support chained comparisons], so the argument is very much valid.
Was your comment to the effect of "although Go does not support chained comparisons, it is syntactically valid for a comparison operator to be passed the result of a comparison so the issue can still arise"?
That's valid, but I would have expected "but" in place of "so".
(sorry if it seems I'm picking nits; I'm just trying to understand and explaining my attempts)
Not saying the grammar would be context-free though.
Relying on that is going to prevent you from including numbers as things you can be generic over (without some additional syntax for that case). That may or may not be something you care about.
Whats wrong with pipes? The only conflict I can think of is LOGICAL-OR || but afaik no language lets you shove shit between the pipes and still be an OR
There are several possible solutions in language syntax (and it's possible you won't like any of them).
One is to use whitespace to disambiguate. a < b is parsed as a comparison, a< b or a<b as an opening angle bracket.
Another is to keep track of the type while parsing, and parse a < b as an angle bracket only if a is known to be callable.
Yet another would be to require some fancy quotes instead, like f«a, b» for generics, sidestepping the problem completely.
x[1] : array[int]
would be parsed as cast(item(ident("x"), int("1")), item(ident("array"), ident("int")))
Then the semantic disambiguation (`x[1]` -> expression, `array[int]` -> type) would be done in the next stage.Was that what you were referring to?