4 ms·
why does every attempt to replace C++ make syntax of the new language significantly uglier than C++? why do I need to type "let" and "fn", etc? why not make t
by vasilipupkin 4y ago
why does every attempt to replace C++ make syntax of the new language significantly uglier than C++?
why do I need to type "let" and "fn", etc?
why not make the syntax very similar if you actually want to make it easy to migrate?
- audunw 4y agoIt's somewhat related to solving one of C/C++'s real problems: the syntax is very context sensitive. That makes tool development harder. Personally I think it's great that most new languages seem to move in roughly the same direction when it comes to syntax.. like "x: int" instead of "int x" for variable declaration, and something similar on functions "fn", "fun" or "function" prefix before functions "let"/"const" for constants and/or single assignment variables "var" for variables etc. I think there's a reason so many language designers are making similar decisions on these things.
- vasilipupkin 4y agowhy is this great? what's the reason? x: int is significantly less readable than int x and involves typing one more character. Why? what is the advantage of type int fn foo versus int foo() {} ? why type var in front of a variable when int x makes it clear its a variable?
- steveklabnik 4y ago“Significantly less readable” is subjective. It is simpler to parse, and degrades better with type inference. That’s 90% of it, I’d imagine.
- vasilipupkin 4y agosure, well, it's not subjective if you have to type more characters to basically achieve the same thing. I guess I just don't really understand why you have to fix C++ shortcomings while also changing things that work fine. Is there a C++ developer who is having trouble declaring variables as int x? By making big changes to syntax, you are just making it less likely this ever gets truly adopted.
- runevault 4y agoA language with good type inference lets you type less because you don't need the colon or the type, where as a language with it first you always have to type something like var for a "figure it out" type.
- aardvark179 4y agoSimple types may be easier, complex types are a real pain for both humans and compilers, and they end up hiding the name in the middle of the thing. Brevity is neither the only nor most important thing on which to judge syntax.
- duped 4y agoauto + implicit coercion + pass by value semantics and copy constructors create real bugs and pitfalls in C++ code. Avoiding these semantics and deferring to explicit syntax leads to better code. Optimizing for character count is dead.
- int_19h 4y agoSomething like "int* a, b" not doing what people expect it to do is a very common C++ footgun.
- PaulDavisThe1st 4y agoFrom TFA: // Returns the smallest factor of `n` > 1, and // whether `n` itself is prime. fn SmallestFactor(n: i32) -> (i32, bool) { This is so unlike C++ I cannot see how anyone can consider it a successor language. It might, in fact, be a much better language, but it is not a successor when you're going to change syntax this much, and in a way that will be hard to automate (precisely because of the "most vexing parse" problem(s).
- yoz-y 4y agoSwift is a successful successor to Objective-C and their syntaxes and idioms are worlds apart. It’s about what class of problems you can solve in the language.
- PaulDavisThe1st 4y agoI don't agree with your analysis. But that's fine.
- jack_h 4y agoIs that really so different from the following C++ equivalent? auto SmallestFactor(int32_t n) -> std::pair<int32_t, bool> { ... }
- PaulDavisThe1st 4y agoI guess I don't understand what role the -> plays there. I must be too old school, I suppose.
- alpaca128 4y agoI can't speak for the C++ example, but in your code snippet `->` points to the return type. The function takes an integer argument and effectively turns it into a tuple, so: `f(i32) -> (i32, bool)`.
- int_19h 4y agoIn this particular example, all it does is reverse the order of return type wrt arguments and function name. I still find this syntax more readable with complicated return types because you no longer have to carefully parse it to see where the type ends and the name begins. In the more general case, having the return type follow the function name means that it can reference parameters in sizeof(), decltype() etc.
- kps 4y agoEven C can't be parsed purely syntactically; you need to know whether or not an identifier names a type. C++ is worse: https://en.wikipedia.org/wiki/Most_vexing_parse https://en.wikipedia.org/wiki/Most_vexing_parse
- vasilipupkin 4y agoright, so some simplifications or improvements are fine, but it doesn't follow that we should now have to type var, let or fn everywhere - it just makes the body of code a lot uglier auto time_keeper = TimeKeeper(Timer()); this is nice and clean
- Koshkin 4y agoCopy constructor much? (Also, I would take var over auto any day, to be honest; but no, they had to override the old useless keyword for some mysterious reason.)
- int_19h 4y agoThe reason is obvious: to avoid adding a new keyword and breaking existing code that might use it as an identifier.
- MindSpunk 4y agoWhich if you projected the same syntax to 'let' syntax you get: let time_keeper = TimeKeeper(Timer()); Which is one less character to type.
- nayuki 4y agoIt sounds like you are not familiar with the most vexing parse. https://en.wikipedia.org/wiki/Most_vexing_parse https://en.wikipedia.org/wiki/Most_vexing_parse , https://stackoverflow.com/questions/14077608/what-is-the-purpose-of-the-most-vexing-parse https://stackoverflow.com/questions/14077608/what-is-the-pur... Also pointer/multiplication ambiguity: https://medium.com/@bartobri/exploring-the-ambiguous-nature-of-the-sizeof-operator-45b6dd2b8b67 https://medium.com/@bartobri/exploring-the-ambiguous-nature-... , https://softwareengineering.stackexchange.com/questions/124570/why-pointer-symbol-and-multiplication-sign-are-same-in-c-c https://softwareengineering.stackexchange.com/questions/1245... , https://stackoverflow.com/questions/41331871/how-c-c-parser-lexer-makes-the-difference-between-of-pointer-and-of-mu https://stackoverflow.com/questions/41331871/how-c-c-parser-...
- alpaca128 4y ago> why type var in front of a variable when int x makes it clear its a variable? Unless `int x` is followed up by an opening parenthesis, in which case it suddenly is a function definition and not a variable. Which also means a parser now needs lookahead for one of the most common statements in the language. `let` means variable, always. Not only that but in most cases (>90%) you can omit the type as it's obvious. Now you just have to type `let s` instead of `String s`, with the difference that `let` also tells you this variable is immutable, which isn't even possible in many languages in the first place. > involves typing one more character Who cares. 99% of devs don't, otherwise they'd use APL or its relatives, where the entire Conway's Game of Life is a single line. There are more important factors than the number of symbols on screen.
- pjmlp 4y agoNot every, see Circle. The only that really has a chance.
- unrealhoang 4y agoNot for long, https://github.com/seanbaxter/circle/blob/master/new-circle/README.md#new_decl_syntax https://github.com/seanbaxter/circle/blob/master/new-circle/...
- pjmlp 4y agoExcept just like with C++ being a C superset at source code level, Circle is a C++ superset, no need to rewrite existing code, that is the big difference.
- unrealhoang 4y agoThen it's still C++'s syntax, and Circle's syntax is still "ugly". Every modern languages adopt the "ugliness" style of type after name to solve most vexing parse, yet somehow C/C++ programmers are still confident in their "beautiful" syntax.
- pjmlp 4y agoSyntax being ugly isn't the problem for migration, rather 40 years of history deploying code into production.
- unrealhoang 4y agoThat's irrelevant to the discussion about syntax being ugly.
- pornel 4y agoIn the context of a language that needs to coexist with C++ codebases, it is a weird decision. However, Carbon's syntax makes technical sense, and is in line with many contemporary languages (Rust, TypeScript, Swift, Kotlin). It is easier to parse, which is important for tooling and IDEs. `fn name` is easy to grep for. `let` works well with type inference and destructuring assignment, which are becoming standard features in modern languages (although Carbon still supports C-style aggregate initializers, which is not so great).