It’s all pretty gibberish. It’s just unabated OOP nonsense that doesn’t serve any real purpose and is incredibly difficult to maintain (unrestricted global mutation is never a good idea).
Sure, but those are people who hate JavaScript for the sake of it. The rational ones hate it for its inconsistencies because the one thing JS gets right is its syntax.
Eh, I haven’t touched C# since 2001. I agree that the more verbose style is more explicit, and so more readable. That said, I can figure most of the new style out from context.
=> is clearly a closure declaration operator, similar to JavaScript.
x ??= y is shorthand for “assign y to x if x is not set, and return x” which is kind of nice.
There must also be some shorthand going on for getter properties being the same as methods w/o an arglist (or even a ()).
The only part that has me stumped is the unary question-mark operator: privatestatic Singleton? _instance = null; I can think of a half-dozen things that could be, but I cannot decide what it’s doing that the original question-mark-free version isn’t.
The only thing that’s not obvious to me is that ??= doesn’t seem to invoke new Singleton() if it’s already defined, essentially short-circuiting. Otherwise I would have to look up the semantics of it if I were worried about that constructor having side effects or doing something heavy.
As others said, it means nullable, but to put it in more intuitive, less-jargony way - it’s a question mark bc you don’t know if the value is actually there or not. It could be a Singleton, but it isn’t until you check if there is a value. Whereas if you have, idk, int a no question mark, then you’re saying you actually have data.
Essentially with C# 8, they “removed” null and reused the idea of null references in creating what is essentially an Option like in other languages. You either have some data of some type, or none (a null reference, in this case). By default, everything has to be there. Then when you need null, e.g. you may not have something initialized or an operation could fail, you explicitly grab for it. Thus it reduces null pointer bugs. If you don’t need nullability, you can ensure that you don’t accidentally write in an issue. It safety checks statements and parameters.
I agree that the more verbose style is more explicit, and so more readable.
On its face, its readable. But when you’re dealing with 10,000 lines of code in a file, it becomes this ugly morass of extra nothingness to scroll through.
The only part that has me stumped is the unary question-mark operator: private static Singleton? _instance = null;
It transforms a strict variable into a nullable variable. I most commonly see it with primitive types.
So, for instance
int myInt = null
is an illegal assignment, but
int? myInt = null
works fine.
Why does a public class instantiation need this? Idfk. That might be extraneous. But I wouldn’t throw away the whole code block rewrite over that one character.
I can figure most of the new style out from context.
=> is clearly a closure declaration operator, similar to JavaScript.
x ??= y is shorthand for “assign y to x if x is not set, and return x” which is kind of nice.
Man, I’ve successfully stayed away from C# for a few years now, but that’s wild to me that the x ??= y operator would be intuitive to you.
This could’ve easily been two or three operations, without being much more verbose, but actually being somewhat intuitively readable for most devs…
Well, I did have the older version on the left as a kind of rosetta stone for this. Plus, this kind of “init and/or return” pattern shows up a bunch of places, so it makes sense someone would want a quick version that’s harder to screw up or has fewer side-effects.
I’ve also spent years investigating better ways to do things through various versions of C++, D, Rust, Go, and TypeScript. After a while, the big-picture patterns start to emerge and you see different camps start to converge on the same kinds of things. Stuff like these weird features start to feel like learning a new slang term for something you’ve felt, but could never say so succinctly.
In the case of ??= it’s a more formalized Python x = x or y or x = x || y in JavaScript. The catch is that not all languages treat assignments like expressions that can be returned, so you get a clunky return as a separate statement; return (x = x or y) doesn’t always fly. That friction is all over the place, and it’s natural to want a shorthand for this very thing.
Sure enough, after searching a bit, ??= shows up in JS, PHP, and even Ruby has a version.
C# 8.0 came out 6 years ago at this point, and it’s syntax is aping that of Javascript’s ES6 update which is 10 years old, which was in turn aping that of earlier functional languages. There are a lot of engineers who have learned how to code using predominantly modern syntax, so the one on the right is “textbook” to them.
And being textbook isn’t a reason to keep doing something forever. The syntax on the left is overly verbose and leaves more room for unexpected behaviour-changing lines of code. The syntax on the right is concise and scannable in a way that doesn’t require jumping back and forth between lines to follow.
I prefer if-expressions where possible. For example, this is valid Rust:
letx = if is_y {
y
} else {
z
};
(Can also be on a single line.)
This is the same syntax as the normal if-statement, except the compiler forces you to add an else-branch, if you want to ‘return’ a value from it.
Don’t tell anyone, but the ternary operator is when the C designers realized that being purely procedural is cumbersome AF. 🙃
Unfortunately, they decided that expressions need to look like math, so now JS devs get to write random question marks and colons across many, deeply nested lines of code.
When you’re an old-head who recognizes the old style it is easy to read the old style.
When you’re a new-head who recognizes the new style it is easy to read the new style.
When you’ve never seen C# before, they’re both gibberish.
When you’ve got experience with both, it can get a little confusing but you’ll catch on without too much difficulty.
But its fucking wild to think the left side is more readable than the right side, simply because it is more verbose.
It’s all pretty gibberish. It’s just unabated OOP nonsense that doesn’t serve any real purpose and is incredibly difficult to maintain (unrestricted global mutation is never a good idea).
When you were forced to learn Java and want to run away seeing C#.
I have no C# experience and both styles look fine to me. /shrug
I have loads of experience with C# and both styles look fine to me. /shrug
Same here. Also, this syntax is common in modem JavaScript, I don’t get the hate.
I think you might have just explained the hate 😅
Sure, but those are people who hate JavaScript for the sake of it. The rational ones hate it for its inconsistencies because the one thing JS gets right is its syntax.
yeah, in kotlin as well, except its ‘?:’ instead of ‘??=’
Eh, I haven’t touched C# since 2001. I agree that the more verbose style is more explicit, and so more readable. That said, I can figure most of the new style out from context.
=>
is clearly a closure declaration operator, similar to JavaScript.x ??= y
is shorthand for “assign y to x if x is not set, and return x” which is kind of nice.There must also be some shorthand going on for getter properties being the same as methods w/o an arglist (or even a
()
).The only part that has me stumped is the unary question-mark operator:
private static Singleton? _instance = null;
I can think of a half-dozen things that could be, but I cannot decide what it’s doing that the original question-mark-free version isn’t.The only thing that’s not obvious to me is that
??=
doesn’t seem to invokenew Singleton()
if it’s already defined, essentially short-circuiting. Otherwise I would have to look up the semantics of it if I were worried about that constructor having side effects or doing something heavy.The question mark makes it nullable
My favourite operator to go with the question mark is the exclamation mark. I remember it as the “I swear to God I’m not null!” operator.
As others said, it means nullable, but to put it in more intuitive, less-jargony way - it’s a question mark bc you don’t know if the value is actually there or not. It could be a Singleton, but it isn’t until you check if there is a value. Whereas if you have, idk,
int a
no question mark, then you’re saying you actually have data.Essentially with C# 8, they “removed” null and reused the idea of null references in creating what is essentially an Option like in other languages. You either have some data of some type, or none (a null reference, in this case). By default, everything has to be there. Then when you need null, e.g. you may not have something initialized or an operation could fail, you explicitly grab for it. Thus it reduces null pointer bugs. If you don’t need nullability, you can ensure that you don’t accidentally write in an issue. It safety checks statements and parameters.
Thanks. That makes a hell of a lot more sense now.
On its face, its readable. But when you’re dealing with 10,000 lines of code in a file, it becomes this ugly morass of extra nothingness to scroll through.
It transforms a strict variable into a nullable variable. I most commonly see it with primitive types.
So, for instance
is an illegal assignment, but
works fine.
Why does a public class instantiation need this? Idfk. That might be extraneous. But I wouldn’t throw away the whole code block rewrite over that one character.
Man, I’ve successfully stayed away from C# for a few years now, but that’s wild to me that the
x ??= y
operator would be intuitive to you.This could’ve easily been two or three operations, without being much more verbose, but actually being somewhat intuitively readable for most devs…
Well, I did have the older version on the left as a kind of rosetta stone for this. Plus, this kind of “init and/or return” pattern shows up a bunch of places, so it makes sense someone would want a quick version that’s harder to screw up or has fewer side-effects.
I’ve also spent years investigating better ways to do things through various versions of C++, D, Rust, Go, and TypeScript. After a while, the big-picture patterns start to emerge and you see different camps start to converge on the same kinds of things. Stuff like these weird features start to feel like learning a new slang term for something you’ve felt, but could never say so succinctly.
In the case of
??=
it’s a more formalized Pythonx = x or y
orx = x || y
in JavaScript. The catch is that not all languages treat assignments like expressions that can be returned, so you get a clunkyreturn
as a separate statement;return (x = x or y)
doesn’t always fly. That friction is all over the place, and it’s natural to want a shorthand for this very thing.Sure enough, after searching a bit,
??=
shows up in JS, PHP, and even Ruby has a version.Edit: more context.
Nullable:
Type?
meansType
ornull
🤝
deleted by creator
C# 8.0 came out 6 years ago at this point, and it’s syntax is aping that of Javascript’s ES6 update which is 10 years old, which was in turn aping that of earlier functional languages. There are a lot of engineers who have learned how to code using predominantly modern syntax, so the one on the right is “textbook” to them.
And being textbook isn’t a reason to keep doing something forever. The syntax on the left is overly verbose and leaves more room for unexpected behaviour-changing lines of code. The syntax on the right is concise and scannable in a way that doesn’t require jumping back and forth between lines to follow.
Boiling down multi-line expressions into single line statements has been a trend in Comp-Sci for a while.
That
format has been around for decades.
I generally prefer it to clunky if-statements
I prefer if-expressions where possible. For example, this is valid Rust:
let x = if is_y { y } else { z };
(Can also be on a single line.)
This is the same syntax as the normal if-statement, except the compiler forces you to add an else-branch, if you want to ‘return’ a value from it.
Don’t tell anyone, but the ternary operator is when the C designers realized that being purely procedural is cumbersome AF. 🙃
Unfortunately, they decided that expressions need to look like math, so now JS devs get to write random question marks and colons across many, deeply nested lines of code.