Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

> Angle brackets require unbounded parser look-ahead or type information in certain situations

I wonder how this is solved in Java, and C++, and C#, and...



It is solved by doing unbounded parser look-ahead (if you need that) or by requiring that all tools have full type information to understand programs (if you need that).

It is definitely better for tooling not to need either, both for human readers and mechanical tools

The example in the mail shows that using angle brackets with Go would require full type information, making simple tools like gofmt impossible.


Note that C#, Pascal don't "know" about known types during parsing like parsing C/C++ requires, it knows how a type is formatted, what it's looking for is: '<' ValidType (',' ValidType)+ '>'

If that's there, it's a generic, else it's an identifier, and somewhere up the parsing chain will take that up as LessThan.


> making simple tools like gofmt impossible.

So now we're making language design decisions based on the limitations of the bonus linter?

My opinion of Golang drops more and more with every new detail I learn about it...


One of the benefits of Go is super fast compilation time. Unlimited look ahead is likely to make the compiler slower. Ergo, it’s not a great idea.


Parser speed is negligible contributor to slowness in any compiler. rustc has a couple of places were it performs bounded lookahead to supply suggestions for incorrect code, but the grammar of the language is regular. 3rd party tools don't have to worry about it, and users get accurate suggestions. The cost is 1) you have to implement a more complex parser while 2) making people go "you already know what I meant, just take it without me using the 'ugly' turbofish". It think this is the correct approach for language design.


Go has a lot of problems, but continung to support gofmt's quest including the simplicity it desires isn't one of them.


You can see the trade-off made here in Rust. When parsing a type, Vec<i32> is no problem, but the constructor of that type (in an expression!) must be written Vec::<i32>::new().

This operator is affectionately called the "turbofish" and can often be avoided because of very good type inference.


And this is why the Turbofish exists in Rust.

https://github.com/rust-lang/rust/blob/master/src/test/ui/ba...

The key to parsing that is line 35. Is the line a tuple containing two booleans, the first the result of a less than, the second the result of a greater than, or is the line a templated function call, with two template arguments, "woe" and "is"?

(It is the former in Rust, and the latter is the apparently magical third option of

  oh::<woe, is>(me)
though of course "woe" and "is" would need to be types, not variables, in that case.)


No way. Really very informative, thank you! And I will stick with C++, thank you!


I believe the point they are making isn't that it's impossible. It's that with the way they have parsing now, the complexity of using angle brackets vs the complexity of the other options make the other options much more desirable. That seems both entirely reasonable, and language/parser dependent.


This article has good discussion of this problem:

https://blog.dyvil.org/syntax/2016/04/19/angle-bracket-gener...


Thanks! I was trying to figure out why angle brackets would be a problem and this article really explains it well (consider I know very little about any of this!).


Parser lookahead...

They even say that it is possible, but it makes producing useful error messages harder and makes the parser more complicated. they are not saying it is not possible, they are just saying it's not preferred to do.


In some languages unbounded parser lookahead is enough. But parser lookahead does not solve the ambiguous Go example given in the mail. Only type information would.


Why doesn't the same idea of adding a type keyword work there too?

a, b := w<type x,y>(z)


They solve it by using time consuming multi-pass compiling


parser look ahead makes the compiler complex and slower and that goes against the Go goals


C++ is famously Turing-complete to parse - not a desirable state of affairs.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: