Live data from Hacker News

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

blog.ivankahl.com

151–160 of 174 posts

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

#151
post #96

Null conditional assignment is bunk. When you have an expression P which names a mutable place, and you execute P := X, the contract says that P now exhibits the value X, until it is assigned another value. Conditional assignment fucks this up. When P doesn't exist, X is not stored. (Worse, it may even be that the expression X is not evaluated, depending on how deep the fuckery goes.) Then when you access the same ex…

> When you have an expression P which names a mutable place, and you execute P := X This isn't the case, though, is it? A normal member access (or indexer) expression may point to a mutable location (field, property). However, with conditional access expressions you get either a member access _or nothing_. And that nothing is not a mutable place. When you use any of the conditional operators, you split the following…

If the language allows := --- if that compiles and executes --- then is by definition a mutable place.

Once you introduce this misfeature, mutable places no longer have the property that they all record the assigned value and keep it until the next assignment.

Now, sure, you also don't have that property when you have operator overloading that allows assignment to be coded by the programmer; but that's a design decision under the programmer's control which affects only that code base, not the entire language and all its users.

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

#152

Null conditional assignment is bunk. When you have an expression P which names a mutable place, and you execute P := X, the contract says that P now exhibits the value X, until it is assigned another value. Conditional assignment fucks this up. When P doesn't exist, X is not stored. (Worse, it may even be that the expression X is not evaluated, depending on how deep the fuckery goes.) Then when you access the same ex…

A representative config.connection being made out of nothing sounds pretty bad to me. If you want to make sure the value doesn't disappear, you shouldn't be using conditional assignment in the first place. The config example isn't the best, but instead imagine if it was just connection.?retryPolicy. After you set connection?.retryPolicy it would be weird for reading it back to be null. But it would be just as weird f…

> If you want to make sure the value doesn't disappear, you shouldn't be using conditional assignment in the first place.

If it worked using "materialize-on-write" semantics, why wouldn't you, as an alternative to the verbose code which checks every path component that might not exist, and instantiates it before doing the assignment?

Obviously, you can't use it if you don't have materialize-on-write semantics in the assigned expression not that you shouldn't.

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

#153
post #97

Null conditional assignment is bunk. When you have an expression P which names a mutable place, and you execute P := X, the contract says that P now exhibits the value X, until it is assigned another value. Conditional assignment fucks this up. When P doesn't exist, X is not stored. (Worse, it may even be that the expression X is not evaluated, depending on how deep the fuckery goes.) Then when you access the same ex…

This is syntactic sugar only. No change in semantics. So I don't buy into any argument about what this change 'means'. And we all get to choose what we find ridiculous: i = i + 1 ? No it does not. Never has, never will. Connection is null? It's insane to type it as Connection then. null has type Null.

I don't understand what you are talking about.

The syntactic sugar already exits before this change. That is to say, in a version f C# without the feature, you can write this:

  a.b?.c = foo
It's not not well-formed semantically.

What the change does is allow the above to be well-formed semantically. If b isn't null, then it behaves like a.b.c = foo. Otherwise, the value of foo is discarded. (Perhaps foo isn't even evaluated?!)

The idea that there is no change in semantics, but only syntactic sugar is exactly backwards.

A particular meaning was assigned to combinations of syntactic sugar which were previously invalid.

That meaning involved making a design choice among multiple possible meanings.

Is there any public visibility to the design decision; what alternatives were considered for the semantics and rejected?

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

#155

More concise? Yes. More readable? I'm less convinced on that one. Some of those edge cases and their effects can get pretty nuanced. I fear this will get overused exactly as the article warns, and I'm going to see bloody questions marks all over codebases. I hope in time the mental overhead to interpret exactly what they're doing will become muscle memory...

Hi there! Lang designer here. > More concise? Yes. Note: being more concise is not really the goal of the `?` features. The goal is actually to be more correct and clear. A core problem these features help avoid is the unfortunate situation people need to be in with null checks where they either do: if (some_expr != null) someExpr... Or, the more correct, but much more unweildy: var temp = some_expr; if (temp != null…

As a really long term C# engineer, I feel quite strongly that C# has become a harder and harder language over time, with a massive over abundance of different ways of doing the same thing, tons of new syntactic sugar, so 5 different devs can write five different ways of doing the same thing, even if it's a really simple thing!

At this point, even though I've been doing .net since version 2, I get confused with what null checks I should be doing and what is the new "right" and best syntax. It's kind of becoming a huge fucking mess, in my opinion anyway.

If you want a kind of proof of this, see this documentation which requires 1000s of words to try and explain how to do null/nullable: https://learn.microsoft.com/en-us/dotnet/csharp/nullable-ref...

Do you think most C# devs really understand and follow this entire (complex and verbose) article?

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

#156

Earlier quoted context omitted.

A representative config.connection being made out of nothing sounds pretty bad to me. If you want to make sure the value doesn't disappear, you shouldn't be using conditional assignment in the first place. The config example isn't the best, but instead imagine if it was just connection.?retryPolicy. After you set connection?.retryPolicy it would be weird for reading it back to be null. But it would be just as weird f…

> If you want to make sure the value doesn't disappear, you shouldn't be using conditional assignment in the first place. If it worked using "materialize-on-write" semantics, why wouldn't you, as an alternative to the verbose code which checks every path component that might not exist, and instantiates it before doing the assignment? Obviously, you can't use it if you don't have materialize-on-write semantics in the…

If it materialized instead, yeah that sentence wouldn't apply the same way. But materializing with a default constructor opens up many cans of worms. I would say it has significantly more downsides than short circuiting. Also it should use a different operator.

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

#157

More concise? Yes. More readable? I'm less convinced on that one. Some of those edge cases and their effects can get pretty nuanced. I fear this will get overused exactly as the article warns, and I'm going to see bloody questions marks all over codebases. I hope in time the mental overhead to interpret exactly what they're doing will become muscle memory...

Hi there! Lang designer here. > More concise? Yes. Note: being more concise is not really the goal of the `?` features. The goal is actually to be more correct and clear. A core problem these features help avoid is the unfortunate situation people need to be in with null checks where they either do: if (some_expr != null) someExpr... Or, the more correct, but much more unweildy: var temp = some_expr; if (temp != null…

Thanks for stopping by to comment!

I'd love to see some good examples of those bugs you referred to, in order to get some more context.

Is the intent of the second form to evaluate only once, and cache that answer to avoid re-evaluating some_expr?

When some_expr is a simple variable, I didn't think there was any difference between the two forms, and always thought the first form was canonical. It's what I've seen in codebases forever, going all the way back to C, and it's always been very clear.

When some_expr is more complex, i.e. difficult to compute or mutable in my timeframe of interest, I'm naturally inclined to the second form. I've personally found that case less common (eg. how exactly are you using nulls such that you have to bury them so deep down, and is it possible you're over-using nullable types?).

I appreciate what you're saying about nudging developers to the most correct pattern and letting the noise fade away. I always felt C# struck a good balance with that, although as the language evolved it feels like there's been a growing risk of "too many different right ways" to do things.

Btw while you're here, I understand why prefix increment/decrement could get complicated and why it isn't supported, but being forced to do car.Wheel?.Skids += 1 instead of car.Wheel?.Skids++ also feels odd.

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

#158

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,…

I have occasionally, just for fun, written benchmarks for some algorithm in C++ and an equivalent C# implementation, them tried to bring the managed performance in line with native using the methods you mention and others. I'm always surprised by how often I can match the performance of the unmanaged code (even when I'm trying to optimize my C++ to the limit) while still ending up with readable and maintainable C#.

JIT compilers can outperform statically compiled code by analysing at run time exactly what branches are taken and then optimising based on that.

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

#159
post #44

Earlier quoted context omitted.

Monad-maxxing has ruined many a language

This is a functor, not a monad. Also, it's implemented really poorly. If only more languages actually implemented monads well. You wouldn't need special case junk like this.

This is the kind of comment I wish I could print on every sheet of a roll of toilet paper

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

#160

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,…

[deleted]
Post reply on HN