auto main() -> int {
cout << "hello world\n";
}
The difference between the two is mostly the : and the =. The colon is for declarations being written: i : int = 0;
Instead of int i = 0;
main is the variable/function above and its type is ()->int and it’s being assigned, i.e. defined, hence the =. This syntax removes a ton of parsing complexity and makes the language more regular. Functions are defined and assigned similarly to variables.On another note, anything with "->" is just painful to write, same thing with the (in his proposal) ":_" instead of "=" for function arguments. Just annoying.
template<typename T>
void hello(T msg) {
std::cout << "Hello " << msg << "\n";
}
hello: (msg: _) = {
std::cout << "Hello " << msg << "\n";
}
I kind of like this, actually, because so many people I've worked with are afraid of templates in C++, but they seem to have no trouble with essentially equivalent code using generics (in other statically typed languages) or dynamically typed languages where it "just works" (until it doesn't). Not that we'll be adopting this any time soon, but I suspect they'd be more amenable to this form when `template` seems to make them quake in their boots. void hello(auto msg){
...
}
Is legal today (since C++20 IIRC) and it is equivalent to your first example.As for -> being painful to write - that's obviously subjective, but more importantly, given that it's the operator you use to access members via pointer-like things (including smart pointers and iterators), it's already pervasive in C++.
Would you people object to ':' for assign and single '=' for equality ?
int i:42
if i=42 print "ok"Practically speaking I find : to be challenging to quickly scan out of source visually. In golang this objection is muted slightly because struct initialization usually ends up being clearly indented by the formatter.
int i = 0; // pretty
i : int = 0; // ugly
i will stick to c++03 thank u very much.
Something like "i: int" is superior (at least in Scala), because the type annotation is optional. You can drop it, and just say "val i = 42". I believe it simplifies the parser as well.
There is a reason many modern languages are adopting the style.
i: int 0 = ;
int x = 0 "There is an integer x with value 0"
x: int = 0 "x is an integer with value 0"
x: int 0 = "x is an integer that is zero valued"
The last one is awkward, the first one is harder to read.
int i; // i is a local int
int i(); // i is a global function returning an int
int i(0); // i is a local int initialized to 0.
Yes, there's uniform initialization now. But this whole thing was a problem in the first place because of poorly designed declarator syntax that doesn't extend well and is difficult to parse unambiguously.It can actually get worse, to the point where it's impossible to tell whether a given line of code is a declaration or not. E.g. "a<b>c" can be a declaration "a<b> c", or it can be an expression "((a < b) > c)", depending on what "a" is, exactly. This can be taken to 11 with templates:
template<size_t N = sizeof(void*)> struct a {
template<int> struct b {};
};
template<> struct a<sizeof(int)> {
enum { b };
};
enum { c, d };
a::b<c>d;
The meaning of this code now depends on whether sizeof(int)==sizeof(void*) for a given implementation on which it runs. Now, granted, this isn't the kind of thing you'd find in real world code outside of IOCCC and the likes; but it's legal, so the tooling has to be able to process it anyway. And by "tooling" I mean anything that has to parse C++ at some point - not just the compilers, but also debuggers, IDEs etc.syntax "beauty" is just a matter of how used to it you are (excl brainfuck ofcourse). Admitting this, is quite a big present one can give to him/her self.
Been using Scala for 7 years, and it has never even occurred to me this was a "burden".
Think of it like font kerning. Some people notice it, some don't, but most people prefer good kerning even if they never think about it.
Does `{` not require shift on your keyboard?
You misread my comment. I'm talking about cases where existing prevalent syntax for that construct does NOT already require holding Shift. Python is better in this respect since ":" requires fewer presses of Shift than "{" or "}". This is not the case when you go from "int x = 1;" to "x: int = 1;".
Moreover, the inconvenience of going from 1 Shift to 2 is not the same as the burden of going from 0 to 1. Especially because you can often combine the 2 into 1 without releasing the modifier key in between.
And furthermore, variable declarations are far more common than class or function declarations, so you can't weight them equally.
Most programmers I know use native+US layouts (like you), a minority always uses US (like me), almost nobody uses a native layout to code.
What I would do is this:
- Replace them with a single quote -> E' instead of È or É and so on.
- Ignore all uncommon marks.
In most contexts, it is perfectly acceptable to do that. A native speaker would understand without giving it a second thought or considering it impolite. I write emails to my boss like that.
If I had to make something meant for the public (say a UI, or a document), then I'd switch to the Italian layout for that purpose only and then go back to the US one.
if (cond) { } requires 4 presses of Shift (or 2, if you combine them).
if cond: foo requires 1 press of Shift.
I'm not sure what part of my comment makes you believe that I think the latter comes out worse than the former. If anything, the fewer keypresses probably strongly helped Python's success without people necessarily realizing it. Moreover, this might very well be one thing hindering more widespread adoption of Python's type annotations.
You also need to consider how common each construct is. A class declaration requiring 20 excessive keystrokes is not necessarily worse than a variable declaration requiring 1 excessive keystroke.
Most of the time you spend thinking about what you should be typing.
So optimizing for the number of keystrokes is optimizing for the wrong metrics
Also consider this: lots of hugely frequent characters and symbols that don't require SHIFT in EN-US keyboards do in other keyboards layouts, for example Spanish. So this cannot be a consideration, at least not a major one.
It's kind of weird to see you assert that with no attempt to establish its truth when Scala is something like... the ~20th most popular language? Whereas Python, C, C++, Java, VB, C#, etc. are right at the top. So either this is one of the (obviously many) factors hindering wider adoption of Scala, in which case the relative popularity is entirely consistent with this, or it isn't a factor, in which case the it would make sense to present at least some evidence to the contrary given that your assertion goes against the popularity rankings.
> Also consider this: lots of hugely frequent characters and symbols that don't require SHIFT in EN-US keyboards do in other keyboards layouts, for example Spanish. So this cannot be a consideration, at least not a major one.
I'm pretty sure the popularity of {most software technologies} outside the US and inside the US are very far from being independent variables.
The barrier to adoption of Scala has to do its functional programming side, as well as its complex libraries and types.
Kotlin also uses ": type" syntax, by the way. As does Python!
> I'm pretty sure the popularity of {most software technologies} outside the US and inside the US are very far from being independent variables.
It's hard to understand your point. Are you arguing that programming languages are less popular outside the US? Or "most software technologies"?
So let's sum it up: SHIFT concerns are very minor in comparison to other programming language ergonomics (in which need I remind you, C++ never fared very well), and the ": type" syntax is very common and mainstream in programming languages, with no hindrance to adoption.
The two examples on Wikipedia are both caused by this, even though it's not explicitly spelled out:
int i(int(my_dbl)); // two calls to int's constructor
// in Java/C# style syntax:
int i = new int(new int(my_dbl)); //no ambiguity
TimeKeeper time_keeper(Timer());
// in Java/C# style syntax:
TimeKeeper time_keeper = new TimeKeeper(new Timer());
C++ could have also chosen to reserve a keyword for initialization even for in-place values, just like they did with `new`, but they chose to re-use function call syntax instead.I would also say that just moving the type after the variable name doesn't fully solve the issue - it's the : syntax for initialization that does this. Here is a hypothetical C++ where the syntax remained the same as today, but (return) type was moved at the end of a declaration:
typedef double my_dbl;
typedef int i;
foo (my_dbl double ) void {
i int (int(my_dbl));
//unambigous: i is an int initialized with an int constructed from my_dbl
f (double) int; //unambigous: f is a function from double to int
g int (my_dbl); //unambigous: g is an int constructed from my_dbl
bar((my_dbl)i);
//ambigous: calling bar with i cast to double, or calling it with a function from my_dbl to i (double to int)?
} X *y;
Are you declaring a pointer, or are you performing multiplication? It depends on what “X” is. variable: Type [= initial_value];
// initializes foo to an int with an initial value of 43
foo: int = 43;
// initializes main to a (presumably, as I haven't read the
// spec yet, const)pointer to a function that takes no
// arguments and returns an int.
main: () -> int = {
...
}Similar story with C strings vs Pascal strings, another can of worms.
x := 5
Where you can optionally insert the type between the colon and equals, otherwise it is deduced x : int = 5[0] https://cstheory.stackexchange.com/questions/43971/why-colon...
90s fashion is also trendy right now. Which is great because a few years ago it was 80. The cycle continues!
For another example, Python goes all the way back to 1991, with v1.0 in 1994. But it didn't really start to trend until early 00s.
Sure, if we redefine "recent" or "current" we can twist words to reach whatever conclusion. In reality, this ": type" syntax is neither new nor recent, nor is it "a current trend". Kotlin is also not recent. A decade is a lot.
You conveniently left Scala out, I suppose because it didn't fit your argument.
> "For another example, Python goes all the way back to 1991"
Well, since we are discussing Python, the syntax for its type hints looks like what exactly? And it was discussed as far back as 2014. Is that "recent"?
Nevertheless, it is definitely the case that the "name: type" syntax is noticeably more trendy now than it was, say, 15 years ago. Sure, there were plenty of languages that had it already back then, including Scala (and ML, and Delphi, and ...). But how many of them were mainstream? Whereas now, this syntax is embraced by Python and TypeScript.
And not even OP claimed that the syntax itself is new or recent; I mean, everybody who knows about Pascal knows how old it really is! They literally said "it's an old idea" that is "currently trendy".
x : t = e
Was called "headform" and was the only syntactic form for the whole language. (Expressions used a shunting yard algorithm to desugar into a sequence of headform.)The language included modules, classes, parameterics, functions, constraints, ..., whatever.
ducks
ML uses `name: type = value`. It came out over a decade before C++ and just one year after C.
Besides, it makes it trivial for text editors to implement "go to definition", and many other niceties without a real semantic parser.
ALGOL, the := in programming languages used for assignment comes from IAL which became ALGOL 58. It's definitely not a modern development. Go reintroduced it to popular mainstream languages, sort of. Except they still use = for assignment and := is used when it's also declaring a new variable.
Unless you now have named loops in modern C++ now this removing goto is problematic.
It was done in the very distant past. It was done in the intervening time. And it's done now. "Modern" trend?
Why not take this opportunity to streamline the calling syntax? Streams are no different than regular function calls, e.g.
cout.output("hello").output("world\n")
Even so there is now std::format
Y U NO fn??!? So close, and yet so obviously wrong.
I still haven't read enough about syntax 2 to understand if it allows any other use of ( after a : but if yes, a keyword like fn or fun would make the parser much more regular.