Remix.run Logo
mrkeen 5 days ago

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.

kazinator 4 days ago | parent [-]

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?

mrkeen 4 days ago | parent [-]

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

> 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
You cannot.

The semantics is conditional assignment, which already exists in the language. Hence the article repeatedly bludgeoning you with pairs of code snippets - whose semantics is the same - but there is a new syntax. So maybe you could say "there's no syntax change" in the sense that "there is only additional syntax, none of the old syntax as been modified".

When you insisted this was a change in semantics, I double-checked, because this would be a huge fuckup (and would explain why you're making such a fuss about it). A difference in semantics (in this case) would mean backward-incompatibility, and would break all codebases already using the syntax a.b?.c = foo. But old codebases do not use that syntax because that syntax does not exist before 14. Old codebases already do conditional assignment, which has not changed. After 14 they will have new syntactic sugar to carry out the old semantics.

This is what sibling comment meant semantically with "Apparently you do t use if in your code?" even if his syntax ("do t") was fucked up.

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

Asked about for years I guess: https://stackoverflow.com/questions/35887106/using-the-null-... (I.e. their semantics already works, but they want a better syntax (or sugar) to carry out the same semantics.)

And the discussion: https://github.com/dotnet/csharplang/discussions/6072

kazinator 2 days ago | parent [-]

Using older C#, a minimal program in which I have this expression:

  a.b?.c = foo
produces:

  Main.cs(19,9): error CS0131: The left-hand side of an assignment must be a variable, property or indexer
Note that it is not saying "syntax error". C# has parsed it. We have an assignment with a left hand side. The syntax already exists. There is just a semantic constraint error.

This error got replaced with code which allows that type of expression, and generates code for it rather than a diagnostic.

I can't say for sure that they did zero parser work for the feature, but it sure looks like in principle, you do not have to, for this case, given that it already parses.

(If they have a parser which handles semantic attributes in teh grammar like "assignable expression", then of course that gets adjusted.)

For reference:

  using System;

  public class A
  {
    public B b { get; set; }
  }

  public class B
  {
    public int? c { get; set; }
  }

  public class Program. 
  {
    public static void Main()
    {
      A a = new A { };
      int foo = 42;
      a.b?.c = foo;
    }
  }