From ac7a40a0e743c55a946b7d47decbbb2045a76b5c Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Mon, 16 Jul 2018 17:23:09 -0700 Subject: [PATCH 1/3] Update null-coalescing-assignment proposal with changes from LDM. --- proposals/null-coalescing-assignment.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/proposals/null-coalescing-assignment.md b/proposals/null-coalescing-assignment.md index 6523df5..00b6eef 100644 --- a/proposals/null-coalescing-assignment.md +++ b/proposals/null-coalescing-assignment.md @@ -10,6 +10,8 @@ Simplifies a common coding pattern where a variable is assigned a value if it is null. +As part of this proposal, we will also loosen the type requirements on `??` to allow variables typed with the unconstrained type parameter to be used on the left-hand side. + ## Motivation [motivation]: #motivation @@ -37,7 +39,23 @@ assignment_operator ; ``` -Which follows the [existing semantic rules for compound assignment operators](https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#compound-assignment). What that means is that an operation of the form `x ??= y` is processed as if written `x = (x ?? y)` (except `x` shall be computed once). However, we permit the assignment to `x` (of its existing value) to be elided in the case that `x` is not null. +Which follows the [existing semantic rules for compound assignment operators](https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#compound-assignment), except that we elide the assignment if the left-hand side is non-null. The rules for this feature are as follows. + +Given `a ??= b`, where `A` is the type of `a`, `B` is the type of `b`, and `A0` is the underlying value type of `A` if `A` is the nullable type. +1. If `A` does not exist or is a non-nullable value type, a compile-time error occurs. +2. If `B` is not implicitly convertible to `A` or `A0`, a compile-time error occurs. +3. The type of `a ??= b` is `A`. +4. `a ??= b` is evaluated at runtime as `a ?? (a = b)`, except that `a` is only evaluated once. + +Note that rule 4 means that if `B` is implicitly convertible to both `A` and `A0`, we will prefer the conversion to `A` over `A0`. + +For the relaxation of the type requirements of `??`, we update the spec where it currently states that, given `a ?? b`, where `A` is the type of `a`: + +> 1. If A exists and is not a nullable type or a reference type, a compile-time error occurs. + +We relax this requirement to: + +1. If A exists and is a non-nullable value type, a compile-time error occurs. ## Drawbacks [drawbacks]: #drawbacks From 7a80baa4793725fbf2b79955f1e7c40dc0ecce08 Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 19 Jul 2018 10:46:09 -0700 Subject: [PATCH 2/3] Address PR feedback. --- proposals/null-coalescing-assignment.md | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/proposals/null-coalescing-assignment.md b/proposals/null-coalescing-assignment.md index 00b6eef..d58a038 100644 --- a/proposals/null-coalescing-assignment.md +++ b/proposals/null-coalescing-assignment.md @@ -10,7 +10,7 @@ Simplifies a common coding pattern where a variable is assigned a value if it is null. -As part of this proposal, we will also loosen the type requirements on `??` to allow variables typed with the unconstrained type parameter to be used on the left-hand side. +As part of this proposal, we will also loosen the type requirements on `??` to allow an expression whose type is the unconstrained type parameter to be used on the left-hand side. ## Motivation [motivation]: #motivation @@ -41,14 +41,13 @@ assignment_operator Which follows the [existing semantic rules for compound assignment operators](https://github.com/dotnet/csharplang/blob/master/spec/expressions.md#compound-assignment), except that we elide the assignment if the left-hand side is non-null. The rules for this feature are as follows. -Given `a ??= b`, where `A` is the type of `a`, `B` is the type of `b`, and `A0` is the underlying value type of `A` if `A` is the nullable type. +Given `a ??= b`, where `A` is the type of `a`, `B` is the type of `b`: + 1. If `A` does not exist or is a non-nullable value type, a compile-time error occurs. -2. If `B` is not implicitly convertible to `A` or `A0`, a compile-time error occurs. +2. If `B` is not implicitly convertible to `A`, a compile-time error occurs. 3. The type of `a ??= b` is `A`. 4. `a ??= b` is evaluated at runtime as `a ?? (a = b)`, except that `a` is only evaluated once. -Note that rule 4 means that if `B` is implicitly convertible to both `A` and `A0`, we will prefer the conversion to `A` over `A0`. - For the relaxation of the type requirements of `??`, we update the spec where it currently states that, given `a ?? b`, where `A` is the type of `a`: > 1. If A exists and is not a nullable type or a reference type, a compile-time error occurs. @@ -65,7 +64,7 @@ As with any language feature, we must question whether the additional complexity ## Alternatives [alternatives]: #alternatives -The programmer can write `(x = x ?? y)` or `if (x == null) x = y;` by hand. +The programmer can write `(x = x ?? y)`, `if (x == null) x = y;`, or `x ?? (x = y)` by hand. ## Unresolved questions [unresolved]: #unresolved-questions From a9c33ef740c926847d6297219b0bddadf2d873fd Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Thu, 19 Jul 2018 11:06:18 -0700 Subject: [PATCH 3/3] the -> and --- proposals/null-coalescing-assignment.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/null-coalescing-assignment.md b/proposals/null-coalescing-assignment.md index d58a038..35ab3a1 100644 --- a/proposals/null-coalescing-assignment.md +++ b/proposals/null-coalescing-assignment.md @@ -10,7 +10,7 @@ Simplifies a common coding pattern where a variable is assigned a value if it is null. -As part of this proposal, we will also loosen the type requirements on `??` to allow an expression whose type is the unconstrained type parameter to be used on the left-hand side. +As part of this proposal, we will also loosen the type requirements on `??` to allow an expression whose type is an unconstrained type parameter to be used on the left-hand side. ## Motivation [motivation]: #motivation