From c4cb77dc5d2e3f7034e35b76c89bd009d9fb2383 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Mon, 26 Aug 2019 15:38:18 -0700 Subject: [PATCH 1/7] Null conditional operators for coalescing, assignment and member access --- 1-Draft/RFCNNN-Null-conditional-operators.md | 140 +++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 1-Draft/RFCNNN-Null-conditional-operators.md diff --git a/1-Draft/RFCNNN-Null-conditional-operators.md b/1-Draft/RFCNNN-Null-conditional-operators.md new file mode 100644 index 00000000..08f181f7 --- /dev/null +++ b/1-Draft/RFCNNN-Null-conditional-operators.md @@ -0,0 +1,140 @@ +--- +RFC: +Author: Aditya Patwardhan +Status: Draft +SupercededBy: +Version: 0.1 +Area: Language +Comments Due: 09/30/2019 +Plan to implement: Yes +--- + +# Null conditional operators for coalescing, assignment and member access + +The RFC proposes to introduce new operators for null coalescing, null conditional assignment and null conditional member access. +The operators provide the script authors a short-hand for performing null checks. + +## Motivation + + As a PowerShell script author, + I can use null conditional operators, + so that null condition checks are more succinct. + +## User Experience + +### Null assignment operator - `?=` + +Assign the value to the variable if the variable value is null or the variable does not exist. + +```powershell +$x ?= 'new value' +${x}?='new value' + +$x? ?= 'new value' +${x?}?='new value' +``` + +### Null coalescing operator - `??` + +If the left hand side is null then return the right hand side, else return the right hand side. + +```powershell +$x = $null +$x ?? 100 +100 +``` + +```powershell +$x = 'some value' +$x ?? 100 +some value +``` + +```powershell +$x? = 'some value' +${x?}??100 +some value +``` + +### Null conditional member access operators - `?.` and `?[]` + +Null member access operators can used on scalar types and array types. +Return the value of the accessed member if the variable is not null. +If the value of the variable is null, then return null. + +```powershell +$x = $null +${x}?.property +${x?}?.property + +${x}?[0] +${x?}?[0] +``` + +## Specification + +The RFC proposes four new operators, the null assignment operator `?=`, the null coalescing operator `??`, and the two null conditional member access `?.` and `?[]`. + +### Null assignment operator - `?=` + +The `?=` operator check the left hand side to be null or undefined and assigns the value of right hand side if null, else the value of left hand side is not changed. + +```powershell +$todaysDate ?= (Get-Date) +``` + +The value of `Get-Date` is assigned to `$todaysDate` if it is null or undefined, if not null, the value is not changed. + +### Null coalescing operator - `??` + +The `??` operator checks the left hand side to be null or undefined and returns the value of right hand side if null, else return the value of left hand side. + +```powershell +(Get-Module Pester -ListAvailable) ?? (Install-Module Pester) +``` + +If the module `Pester` is not installed, then install the module. + +### Null conditional member access operators - `?.` and `?[]` + +The `?.` and `?[]` operators access the specified member if the value of the variable is not null. +If it is null, then null is returned. + +```powershell +${x}?.propname +${x}?[0] +``` + +The property `propname` is accessed and it's value is returned only if `$x` is not null. +Similarly, the indexer is used only if `$x` is not null. +If `$x` is null, then null is returned. + +### Additional considerations + +The `?=` and `??` operators are binary operators and check for the value of the left hand side to be null or an undefined variable. +They can be used with a space between the variable name and the to operator. +If the left hand side is null, then `?=` assigns the right hand side to the variable while, the `??` operator returns the right hand side. +When they are used without a space between variable name and the operator, a `{}` must be used around the variable name. + +The `?.` and `?[]` operators are member access operators and do not allow a space in between the variable name and the operator. + +PowerShell allows `?` as part of the variable name. +Hence disambiguation is required when the operators are used without a space between the variable name and the operator. +To disambiguate, the variables must use `{}` around the variable name like: `${x?}?.propertyName` or `${y}?[0]`. + +## Alternate Proposals and Considerations + +### Disallow `?` in variable names + +It was considered to disallow `?` in variable names, to avoid confusion whether the operator is a null conditional operator or the variable name has `?` in it. +This proposal was rejected to maintain backward compatibility. + +### Prefer new operators when tokenizing variable names + +It was considered to look ahead when tokenizing the variable names and check for `?=`, `??`, `?.` or `?[]`. +If the token is found the assume that it is a null conditional check and not a member access of a variable name ending in `?`. +To maintain backward compatibility and this proposal was rejected. + +### Use a different sigil for null-conditional operators + +It was determined that the familiarity of `?.` and `??` operators to `C#` programmers will make usage of the new operators easier to understand than introducing new sigils. From 8449c4b8560c7a8657e3ea45c532d9ba6d950a6d Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 27 Aug 2019 16:41:05 -0700 Subject: [PATCH 2/7] Update 1-Draft/RFCNNN-Null-conditional-operators.md Co-Authored-By: Joel Sallow (/u/ta11ow) <32407840+vexx32@users.noreply.github.com> --- 1-Draft/RFCNNN-Null-conditional-operators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-Draft/RFCNNN-Null-conditional-operators.md b/1-Draft/RFCNNN-Null-conditional-operators.md index 08f181f7..85d55246 100644 --- a/1-Draft/RFCNNN-Null-conditional-operators.md +++ b/1-Draft/RFCNNN-Null-conditional-operators.md @@ -36,7 +36,7 @@ ${x?}?='new value' ### Null coalescing operator - `??` -If the left hand side is null then return the right hand side, else return the right hand side. +Return the left hand side if it is not null, else return the right hand side. ```powershell $x = $null From 6dfa2c3b4b0ad9077c6041508e33528cf4823efa Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 26 Sep 2019 17:54:02 -0700 Subject: [PATCH 3/7] Address feedback and move member access operators to additional considerations --- 1-Draft/RFCNNN-Null-conditional-operators.md | 98 ++++++++++---------- 1 file changed, 50 insertions(+), 48 deletions(-) diff --git a/1-Draft/RFCNNN-Null-conditional-operators.md b/1-Draft/RFCNNN-Null-conditional-operators.md index 85d55246..acf0af21 100644 --- a/1-Draft/RFCNNN-Null-conditional-operators.md +++ b/1-Draft/RFCNNN-Null-conditional-operators.md @@ -11,7 +11,8 @@ Plan to implement: Yes # Null conditional operators for coalescing, assignment and member access -The RFC proposes to introduce new operators for null coalescing, null conditional assignment and null conditional member access. +The RFC proposes to introduce new operators for null coalescing, null conditional assignment. +Null conditional member access is being moved to additional consideration section. The operators provide the script authors a short-hand for performing null checks. ## Motivation @@ -22,16 +23,16 @@ The operators provide the script authors a short-hand for performing null checks ## User Experience -### Null assignment operator - `?=` +### Null assignment operator - `??=` Assign the value to the variable if the variable value is null or the variable does not exist. ```powershell -$x ?= 'new value' -${x}?='new value' +$x ??= 'new value' +${x}??='new value' -$x? ?= 'new value' -${x?}?='new value' +$x? ??= 'new value' +${x?}??='new value' ``` ### Null coalescing operator - `??` @@ -56,31 +57,16 @@ ${x?}??100 some value ``` -### Null conditional member access operators - `?.` and `?[]` - -Null member access operators can used on scalar types and array types. -Return the value of the accessed member if the variable is not null. -If the value of the variable is null, then return null. - -```powershell -$x = $null -${x}?.property -${x?}?.property - -${x}?[0] -${x?}?[0] -``` - ## Specification -The RFC proposes four new operators, the null assignment operator `?=`, the null coalescing operator `??`, and the two null conditional member access `?.` and `?[]`. +The RFC proposes four new operators, the null assignment operator `??=`, the null coalescing operator `??`, and the two null conditional member access `?.` and `?[]`. -### Null assignment operator - `?=` +### Null assignment operator - `??=` -The `?=` operator check the left hand side to be null or undefined and assigns the value of right hand side if null, else the value of left hand side is not changed. +The `??=` operator check the left hand side to be null or undefined and assigns the value of right hand side if null, else the value of left hand side is not changed. ```powershell -$todaysDate ?= (Get-Date) +$todaysDate ??= (Get-Date) ``` The value of `Get-Date` is assigned to `$todaysDate` if it is null or undefined, if not null, the value is not changed. @@ -95,33 +81,13 @@ The `??` operator checks the left hand side to be null or undefined and returns If the module `Pester` is not installed, then install the module. -### Null conditional member access operators - `?.` and `?[]` - -The `?.` and `?[]` operators access the specified member if the value of the variable is not null. -If it is null, then null is returned. - -```powershell -${x}?.propname -${x}?[0] -``` - -The property `propname` is accessed and it's value is returned only if `$x` is not null. -Similarly, the indexer is used only if `$x` is not null. -If `$x` is null, then null is returned. - ### Additional considerations -The `?=` and `??` operators are binary operators and check for the value of the left hand side to be null or an undefined variable. +The `??=` and `??` operators are binary operators and check for the value of the left hand side to be null or an undefined variable. They can be used with a space between the variable name and the to operator. -If the left hand side is null, then `?=` assigns the right hand side to the variable while, the `??` operator returns the right hand side. +If the left hand side is null, then `??=` assigns the right hand side to the variable while, the `??` operator returns the right hand side. When they are used without a space between variable name and the operator, a `{}` must be used around the variable name. -The `?.` and `?[]` operators are member access operators and do not allow a space in between the variable name and the operator. - -PowerShell allows `?` as part of the variable name. -Hence disambiguation is required when the operators are used without a space between the variable name and the operator. -To disambiguate, the variables must use `{}` around the variable name like: `${x?}?.propertyName` or `${y}?[0]`. - ## Alternate Proposals and Considerations ### Disallow `?` in variable names @@ -131,10 +97,46 @@ This proposal was rejected to maintain backward compatibility. ### Prefer new operators when tokenizing variable names -It was considered to look ahead when tokenizing the variable names and check for `?=`, `??`, `?.` or `?[]`. +It was considered to look ahead when tokenizing the variable names and check for `??=`, `??`, `?.` or `?[]`. If the token is found the assume that it is a null conditional check and not a member access of a variable name ending in `?`. To maintain backward compatibility and this proposal was rejected. ### Use a different sigil for null-conditional operators It was determined that the familiarity of `?.` and `??` operators to `C#` programmers will make usage of the new operators easier to understand than introducing new sigils. + +### Null conditional member access operators - `?.` and `?[]` + +Null member access operators can used on scalar types and array types. +Return the value of the accessed member if the variable is not null. +If the value of the variable is null, then return null. + +```powershell +$x = $null +${x}?.property +${x?}?.property + +${x}?[0] +${x?}?[0] + +${x}?.MyMethod() +``` + +The `?.` and `?[]` operators access the specified member if the value of the variable is not null. +If it is null, then null is returned. + +```powershell +${x}?.propname +${x}?[0] +${x}?.MyMethod() +``` + +The property `propname` is accessed and it's value is returned only if `$x` is not null. +Similarly, the indexer is used only if `$x` is not null. +If `$x` is null, then null is returned. + +The `?.` and `?[]` operators are member access operators and do not allow a space in between the variable name and the operator. + +PowerShell allows `?` as part of the variable name. +Hence disambiguation is required when the operators are used without a space between the variable name and the operator. +To disambiguate, the variables must use `{}` around the variable name like: `${x?}?.propertyName` or `${y}?[0]`. From e41f35b753e13903326a81d47170e8329d328574 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Fri, 11 Oct 2019 15:48:12 -0700 Subject: [PATCH 4/7] Add operator precedence change --- 1-Draft/RFCNNN-Null-conditional-operators.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/1-Draft/RFCNNN-Null-conditional-operators.md b/1-Draft/RFCNNN-Null-conditional-operators.md index acf0af21..54cf82c4 100644 --- a/1-Draft/RFCNNN-Null-conditional-operators.md +++ b/1-Draft/RFCNNN-Null-conditional-operators.md @@ -81,6 +81,19 @@ The `??` operator checks the left hand side to be null or undefined and returns If the module `Pester` is not installed, then install the module. +### Updates to operator precedence + +The operator precedence token flags will be updated to add gaps and place the null coalesce opeator at position 7, above comparison and below add/subtract. +Currently, the binary operator mask is set at `0x07`, which will be updated to `0x0f`. +This will ensure that `??` is evaluated before operators like `-eq`, `-and`, `-bor` etc, but after `+` and `-`. + +This enables scenarios like: +```PowerShell +'x' -eq $null ?? 'x' evaluates to 'x' -eq ($null ?? 'x') + + 2 + $null ?? 3 evaluates to 2 + ($null ?? 3) +``` + ### Additional considerations The `??=` and `??` operators are binary operators and check for the value of the left hand side to be null or an undefined variable. From 7a8f5f7c998d5623bcd4e7729b8c77abbaa65a0a Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 15 Oct 2019 10:50:14 -0700 Subject: [PATCH 5/7] Fix typo in operator precedence example --- 1-Draft/RFCNNN-Null-conditional-operators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/1-Draft/RFCNNN-Null-conditional-operators.md b/1-Draft/RFCNNN-Null-conditional-operators.md index 54cf82c4..ee44ccac 100644 --- a/1-Draft/RFCNNN-Null-conditional-operators.md +++ b/1-Draft/RFCNNN-Null-conditional-operators.md @@ -91,7 +91,7 @@ This enables scenarios like: ```PowerShell 'x' -eq $null ?? 'x' evaluates to 'x' -eq ($null ?? 'x') - 2 + $null ?? 3 evaluates to 2 + ($null ?? 3) + 2 + $null ?? 3 evaluates to (2 + $null) ?? 3 ``` ### Additional considerations From c5eb257dc4e59109f6b792c6cbf2a99e35c559da Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Thu, 6 Feb 2020 17:12:02 -0800 Subject: [PATCH 6/7] Move null member access for specification section --- 1-Draft/RFCNNN-Null-conditional-operators.md | 74 ++++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/1-Draft/RFCNNN-Null-conditional-operators.md b/1-Draft/RFCNNN-Null-conditional-operators.md index ee44ccac..3fe585f3 100644 --- a/1-Draft/RFCNNN-Null-conditional-operators.md +++ b/1-Draft/RFCNNN-Null-conditional-operators.md @@ -81,43 +81,6 @@ The `??` operator checks the left hand side to be null or undefined and returns If the module `Pester` is not installed, then install the module. -### Updates to operator precedence - -The operator precedence token flags will be updated to add gaps and place the null coalesce opeator at position 7, above comparison and below add/subtract. -Currently, the binary operator mask is set at `0x07`, which will be updated to `0x0f`. -This will ensure that `??` is evaluated before operators like `-eq`, `-and`, `-bor` etc, but after `+` and `-`. - -This enables scenarios like: -```PowerShell -'x' -eq $null ?? 'x' evaluates to 'x' -eq ($null ?? 'x') - - 2 + $null ?? 3 evaluates to (2 + $null) ?? 3 -``` - -### Additional considerations - -The `??=` and `??` operators are binary operators and check for the value of the left hand side to be null or an undefined variable. -They can be used with a space between the variable name and the to operator. -If the left hand side is null, then `??=` assigns the right hand side to the variable while, the `??` operator returns the right hand side. -When they are used without a space between variable name and the operator, a `{}` must be used around the variable name. - -## Alternate Proposals and Considerations - -### Disallow `?` in variable names - -It was considered to disallow `?` in variable names, to avoid confusion whether the operator is a null conditional operator or the variable name has `?` in it. -This proposal was rejected to maintain backward compatibility. - -### Prefer new operators when tokenizing variable names - -It was considered to look ahead when tokenizing the variable names and check for `??=`, `??`, `?.` or `?[]`. -If the token is found the assume that it is a null conditional check and not a member access of a variable name ending in `?`. -To maintain backward compatibility and this proposal was rejected. - -### Use a different sigil for null-conditional operators - -It was determined that the familiarity of `?.` and `??` operators to `C#` programmers will make usage of the new operators easier to understand than introducing new sigils. - ### Null conditional member access operators - `?.` and `?[]` Null member access operators can used on scalar types and array types. @@ -153,3 +116,40 @@ The `?.` and `?[]` operators are member access operators and do not allow a spac PowerShell allows `?` as part of the variable name. Hence disambiguation is required when the operators are used without a space between the variable name and the operator. To disambiguate, the variables must use `{}` around the variable name like: `${x?}?.propertyName` or `${y}?[0]`. + +### Updates to operator precedence + +The operator precedence token flags will be updated to add gaps and place the null coalesce opeator at position 7, above comparison and below add/subtract. +Currently, the binary operator mask is set at `0x07`, which will be updated to `0x0f`. +This will ensure that `??` is evaluated before operators like `-eq`, `-and`, `-bor` etc, but after `+` and `-`. + +This enables scenarios like: +```PowerShell +'x' -eq $null ?? 'x' evaluates to 'x' -eq ($null ?? 'x') + + 2 + $null ?? 3 evaluates to (2 + $null) ?? 3 +``` + +### Additional considerations + +The `??=` and `??` operators are binary operators and check for the value of the left hand side to be null or an undefined variable. +They can be used with a space between the variable name and the to operator. +If the left hand side is null, then `??=` assigns the right hand side to the variable while, the `??` operator returns the right hand side. +When they are used without a space between variable name and the operator, a `{}` must be used around the variable name. + +## Alternate Proposals and Considerations + +### Disallow `?` in variable names + +It was considered to disallow `?` in variable names, to avoid confusion whether the operator is a null conditional operator or the variable name has `?` in it. +This proposal was rejected to maintain backward compatibility. + +### Prefer new operators when tokenizing variable names + +It was considered to look ahead when tokenizing the variable names and check for `??=`, `??`, `?.` or `?[]`. +If the token is found the assume that it is a null conditional check and not a member access of a variable name ending in `?`. +To maintain backward compatibility and this proposal was rejected. + +### Use a different sigil for null-conditional operators + +It was determined that the familiarity of `?.` and `??` operators to `C#` programmers will make usage of the new operators easier to understand than introducing new sigils From 177eaa219982e6b8e963b600f5ef4dbcd9c26e88 Mon Sep 17 00:00:00 2001 From: Joey Aiello Date: Wed, 19 Feb 2020 15:18:30 -0800 Subject: [PATCH 7/7] Prepare RFC0051 (null conditional operators) for merging as Final --- .../RFC0051-Null-conditional-operators.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename 1-Draft/RFCNNN-Null-conditional-operators.md => 5-Final/RFC0051-Null-conditional-operators.md (99%) diff --git a/1-Draft/RFCNNN-Null-conditional-operators.md b/5-Final/RFC0051-Null-conditional-operators.md similarity index 99% rename from 1-Draft/RFCNNN-Null-conditional-operators.md rename to 5-Final/RFC0051-Null-conditional-operators.md index 3fe585f3..2334cef5 100644 --- a/1-Draft/RFCNNN-Null-conditional-operators.md +++ b/5-Final/RFC0051-Null-conditional-operators.md @@ -1,7 +1,7 @@ --- -RFC: +RFC: 0051 Author: Aditya Patwardhan -Status: Draft +Status: Final SupercededBy: Version: 0.1 Area: Language