11 ms·
There are several technical advantages to the types-to-the-right style. For one, it's often easier to write a parser for: having an explicit let or val keyword
by andolanra 8y ago
There are several technical advantages to the types-to-the-right style. For one, it's often easier to write a parser for: having an explicit let or val keyword makes it immediately obvious to a parser without lookahead that the statement in question is a declaration, and not an expression. This is less of a problem in languages like Java, where the grammar of types is simpler, but in C and C++, if you begin a line with
foo * bar
then it's not yet clear to the parser (and won't be until after more tokens are observed) whether this is a variable declaration for bar or a statement multiplying foo and bar. This isn't a problem for name-then-type syntaxes.
On a related note, it's also often advantageous for functions to indicate their return type last, as well, especially when the return value of the thing might be a function of an earlier argument. There are plenty of examples of this in functional or dependently-typed languages, but even C++ (which historically has listed the return type of a function first) has added an alternate (slightly clunky) syntax for function types where you can specify the return type after the arguments for this reason:
template<typename Container, typename Index>
auto
foo(Container& c, Index i)
-> decltype(c[i])
{ ... }
- jeffrallen 8y agoCame here to say exactly this. The post's author has no idea what language designers are thinking about.
- chubot 8y agoPlease reconsider your tone. It sounds like you were disappointed that you didn’t get to show off something you know, so you chose to insult someone else instead. The site would be better without such comments. This might make you feel better but it’s just noise that hundreds of people have to skip over.
- HumanMusic 8y agoI did not get that meaning from the post at all. You should consider your tone, one might be lead to think you believe yourself some sort of paragon of propriety. I'd also advise a side course of thicker skin.
- tomca32 8y agoPost's author is a member of Jetbrains Kotlin team. I wouldn't say he has no idea what language designers are thinking about since he's one of them.
- paulddraper 8y agoAnd on case of inference, It also makes the grammar simpler if the thing that is optional follows the thing that is required.
- lisper 8y agoType-to-the-right also makes it a lot easier to find the initial definition of a variable or a function.
- WalterBright 8y agoI recently updated my editor (https://github.com/DigitalMars/med https://github.com/DigitalMars/med) to highlight in yellow all search matches on the screen. It works so damn well I am disgusted with myself for not thinking of this decades ago. It neatly finds the first use, etc. It also does a word search so `it` does not highlight when searching for `i`.
- jstimpfle 8y agoThat's why C is usually parsed with a symbol table, which is the way it was meant to be parsed. When parsing "foo * bar;", then it should be clear after parsing "foo" whether the statement is a variable declaration or an expression syntax. (It's a variable declaration if "foo" is registered as a type in the symbol table). The advantage of this style is that types align nicely to the left and no additional keywords (like let) are required. The disadvantage is that parsing becomes highly contextual. We can't start with parsing somewhere in the middle of a file.
- thedufer 8y agoThat seems insufficient - what if foo is both a type and a variable?
- colanderman 8y agoIt can't be. (Additionally, in C++, where `struct/enum/class foo` can be shortened to `foo`, the variable interpretation is always preferred.)
- millstone 8y agoMostly it just seems silly to use * for both pointers and arithmetic. We're not hurting for sigils even in ASCII.
- jstimpfle 8y agoIn C, for example dollar-sign and at-sign are unused and could be used for pointers. But I don't like those. Both are visually clunky characters. Personally I like how it is in Pascal - caret sign for pointer types, and postfix unary operator caret for dereference, like^.this which doesn't need an additional syntax ( like->this is just (* like).this in C). But now, caret is usually also the XOR operator. The deeper problem is that Pascal cannot use caret as XOR binary operator since postfix operators cannot easily be distinguished from binary operators with only 1 token lookahead - it would require more lookahead or type resolution to determine that it's not a binary operator. While in C the deref operator is a prefix which can be distinguished from binary operators without lookahead.
- stefan_ 8y agoOkay, but I have no problem with the parsers of any C or C++ compiler. I don't care to make it easier for the machine.
- diroussel 8y agoIn type to the right Language’s it’s also easier to grep for assignment or function declaration. And for me, easier to read.
- mehrdadn 8y agoEasier for the machine means easier for people to write tooling for the language. Imagine if you could ast.parse() C++ code the same way you could for Python code.
- tigershark 8y agoYou can easily parse c# or f# that are probably more complex than C++, so maybe it’s not so impossible?
- Gladdyu 8y agoI doubt those are more complex to parse than C++, as C++ parsing is undecidable. http://blog.reverberate.org/2013/08/parsing-c-is-literally-undecidable.html http://blog.reverberate.org/2013/08/parsing-c-is-literally-u...
- tigershark 8y agoC# compiler can generate a huge amount of code from simple and small programs: https://mattwarren.org/2017/11/08/A-DoS-Attack-against-the-C-Compiler/ https://mattwarren.org/2017/11/08/A-DoS-Attack-against-the-C... But you can very easily get the AST. Obviously it may happen that you have to wait until the hell is frozen to get a result, but generally it doesn’t happen in code that you see day to day..
- mehrdadn 8y ago
- colanderman 8y ago> it's not yet clear to the parser Not at all. C/C++ grammar is explicitly contextual. `foo * bar` is a declaration if-and-only-if `foo` was previously declared as a type. Otherwise it is an expression. The subsequent tokens have zero bearing on this. Nor is this a good argument for types-to-the-right. If C named pointer types like `⋆foo` instead of `foo⋆` [stars used to avoid formatting glitches], then putting the type to the right as `bar * foo` would be equally ambiguous as your example.
- naniwaduni 8y agoplausible misread: "it's not at all clear"
- Guvante 8y agoI don't know of any language that has type on right without a non-ambiguous marker like `let`. That is what avoid ambiguity.
- colanderman 8y agoThe ambiguity issue the GP raised in type-on-the-left languages is also trivially solved by requiring `let`. That's not an argument for either style.
- Technetium_Hat 8y agoPython has (optional) types on the right, and no variable declaration keyword.
- WalterBright 8y agoThe parsing problems have long been solved. The `foo * bar;` issue is solved in D by the observation that the * operator returns a value, and no use of the value is made here, so it must be a declaration. No symbol table lookup is necessary. (D explicitly does not rely on a symbol table to parse.) It is possible that the * operator is overloaded and the overload has side effects that are relied upon here, but D discourages overloading arithmetic operators for non-arithmetic uses, and considers the side-effect only case as particularly wretched and so has no problem not supporting it. Lookahead issues are also trivial to solve, so shouldn't be a factor in modern language design.
- adrianmonk 8y ago> having an explicit let or val keyword Surely you can have such a keyword in either case. Both of these are certainly possible: var int x = 1 var x int = 1 I don't see that as an advantage of types to the right so much as an advantage of choosing to define the grammar to include a terminal symbol that makes parsing easier. It is true that newer languages seem to be more likely have a keyword like 'var', but that has less to do with types left or right and more to do with type inference. If types are optional, then there needs to be something that remains which identifies it as a variable declaration.
- pjmlp 8y agoThat basic example falls down with more complex examples, unless only basic typenames are allowed in variable declarations.
- adrianmonk 8y agoOK, I see what you're saying, and I have to partially agree. You could say there are two parsing challenges: knowing that you are inside a declaration (as opposed to an expression, statement, etc.), and parsing the parts of the declaration once you know you are in it. If you have a (required) keyword like "var", then the first challenge is solved in any case. (And that is the challenge that was actually mentioned in the above comment.) But yeah, the second challenge exists, and since variable names are exactly one token long (in any language I know of), it's easier for them to come first. Sometimes. It depends on the language, though: if the language has a separator terminal symbol ("var int : x"), then I don't see how the order matters. Some languages do and some don't.