Live data from Hacker News

What's New in C# 14: Null-Conditional Assignments

blog.ivankahl.com

141–150 of 174 posts

Re: What's New in C# 14: Null-Conditional Assignments

#141
post #34

I’m having a hard time imagining where this is useful. If I’m trying to assign to a property, but encounter an intermediate null value in the access chain, just skipping the assignment is almost never going to be what I want to do. I’m going to want to initialize that null value.

I'm also not sure I have a lot of code where this would be useful, but adding it to the language I don't feel makes it worse in any way; in fact, it makes it more consistent since you can do conditional null reads and conditional null method invocations (w/ `?.Invoke()`), so why not writes too.

Adding something is always gonna make things worse by default and has to be proven to be useful. Otherwise you have bloat and "yet another way of doing the one thing".

I'm a fan of this notation because it's consistent but language design should not just add features because it doesn't hurt.

Re: What's New in C# 14: Null-Conditional Assignments

#142

So like ruby's '&.' null safe chaining

Yes but they already had it for non-assigning uses.

Ruby is a true OOP programming language unlike all the ones who just pretend to be. It's similar to Smalltalk in many regards. In Ruby only nil and false are falsy (and they are both objects with their respective classes) so for non-boolean types we can just use ||=. It works with undefined variables as well. This strong typing also means we can use the = operator in if statements.

Compare that with PHP where the "0" string is falsy and where even the array has no class (so no methods).

Re: What's New in C# 14: Null-Conditional Assignments

#143

Earlier quoted context omitted.

Hi there! One of the lang designers here. That's been part and parcel for C# for over 10 years at this point. When we added `?.` originally, it was its nature that it would not execute code that was now unnecessary due to the receiver being null. For example: Settings?.SetRetryPolicy(new ExponentialBackoffRetryPolicy()); This would already not run anything on the RHS of the `?.` if `Settings` was null. So this featur…

I get that the language syntax is now (slightly) more regular. But also, reading the code will mean keeping track of (slightly) more possible outcomes.

Sure. But that was the case prior to this feature as well. Previously you'd have to store the variable somewhere and null check it. Those could all lead to different outcomes. This just encapsulates that pattern safely in a regular manner. :)

Re: What's New in C# 14: Null-Conditional Assignments

#144

The thing I enjoy most about C# is the depth/levels of progressive enhancement you can do. Let's say in the first instance, you write a proof of concept algorithm using basic concepts like List , foreach, stream writing. Accessible to a beginner, safe code, but it'll churn memory (which is GC'd) and run using scalar CPU instructions. Depending on your requirements you can then progressively enhance the memory churn,…

That is the promise we could already have had in the 1990's with languages like Eiffel, Oberon and Modula-3, and it has taken us about 30 years to finally become mainstream.

C# is not the only one offering these kind of capabilities, still big kudos to the team, and the .NET performance improvements blog posts are a pleasure to read.

Re: What's New in C# 14: Null-Conditional Assignments

#145
post #133

Strange that they chose to make it `a?["b"] = c;` rather than to use the same syntax as TypeScript (`a?.["b"] = c;`). Honestly I like the C# better, and I was initially not super thrilled about the choice to include the period in the TS case, but since there is some overlap between the language design teams I assumed they would be the same.

Maybe because in JS/TS, `a ? ["b"]` is a valid syntax, so they had to insert the dot to parse properly.

Re: What's New in C# 14: Null-Conditional Assignments

#146

Cute, but is this actually needed? It's one more thing to remember, one more thing to know the subtleties of, and for what? To save writing a very readable and unambiguous line of code? It feels like the C# designers have a hard time saying "no" to ideas coming their way. It's one of my biggest annoyances with this otherwise nice language. At this point, C# has over 120 keywords (incl. contextual ones) [0]. This is a…

> Cute, but is this actually needed? It's one more thing to remember, one more thing to know the subtleties of, and for what? Hi there! C# language designer here :-) In this case, it's more that this feature made the language more uniform. We've had `?.` for more than 10 years now, and it worked properly for most expressions except assignment. During that time we got a large amount of feedback from users asking for t…

Thanks for the reply and for your work on C#.

I should have been clearer in my message. This specific feature is nice, and the semantics are straightforward. My message is more about some the myriad of other language features with questionable benefits. There's simply more and more "stuff" in the language and a growing number of ways to write the same logic but often with subtle semantic differences between each variant. There are just too many different, often overlapping, concepts. The number of keywords is a symptom of that.

Re: What's New in C# 14: Null-Conditional Assignments

#147
post #4

Looks interesting & I'm excited to try this out myself. I like the more verbose null/error handling personally in professional code, but maybe that's because im still working in framework! I'll certainly be using these in my personal projects that'll be on .NET 10

You can use newer LangVersion in framework too.

True. I'll go nag the senior to start updating that for the 100th time.

Re: What's New in C# 14: Null-Conditional Assignments

#148
post #122

Earlier quoted context omitted.

Thank you for all the hard work on C#! I’ve been loving the past 5 years of developments and don’t agree with the parent comment here. p.s. I will take the opportunity to say that I dream of the day when C# gets bounded sum types with compiler enforced exhaustive pattern matching. It feels like we are soooo close with records and switch expression, but just missing one or two pieces to make it work.

Thanks @klysm! I think we're getting close to that. `unions` are a big part of this discussion, and we're working very hard to hopefully get them in soon :)

I can’t wait! I’ll be frothing at the mouth when that lands

Re: What's New in C# 14: Null-Conditional Assignments

#149

Earlier quoted context omitted.

False dichotomy. The problem is that the syntax implements a solution that is likely wrong in many situations and pairs with a bad program design. Maybe when we have this: what?.could?.possibly.go?.wrong = important_value() Maybe we want code like this: if (!what) what = new typeof(what); // default-construct representative instance if (!what.could) what.could = new typeof(what.could); if (!what.could.possibly.go) wh…

NullReferenceException, in line 7. you didn't null check possibly.go.

Rather, what I didn't null check is "possibly". That's because it doesn't have a question mark in the original expression that I'm starting from.

Re: What's New in C# 14: Null-Conditional Assignments

#150

Earlier quoted context omitted.

False dichotomy. The problem is that the syntax implements a solution that is likely wrong in many situations and pairs with a bad program design. Maybe when we have this: what?.could?.possibly.go?.wrong = important_value() Maybe we want code like this: if (!what) what = new typeof(what); // default-construct representative instance if (!what.could) what.could = new typeof(what.could); if (!what.could.possibly.go) wh…

I wonder, does the important_value function get called and the value discarded or never called at all? Looks like a footgun if it has side-effects.

Not calling the function would be evidence of further derangement in the design.

Such a thing has been perpetrated in C. In C, you can repeat designated initializers. like

  foo f = { .a = x(), .a = y() }
The order in which the expressions are called is unspecified, just like function arguments (though the order of initialization /is/ specified; it follows initialization order).

The implementaton is allowed to realize that since .a is being initialized again by y(), the earlier initialization is discarded. And it is permitted not to emit a call to x().

That's just like permitting x() not to be called in x() * 0 because we know the answer is zero.

Only certain operators in C short-circuit. And they do so with a strict left-to-right evaluation discipline: like 0 && b will not evaluate b, but b && 0 will evaluate b.

The initializer expressions are not sequenced, yet they can be short-circuited-out in left-to-right order.

Consistency? What's that ...

Post reply on HN