Apple calls it macOS, we should be consistent (our documentation is mostly consistent I think, but we have $IsOSX which makes it inconsistent. I propose we make this breaking change now otherwise never.
While the name change is a great idea ("Call me $IsmacOS" sounds much more familiar... (jk)), can I suggest revisiting the polluting-the-user-variable-namespace issue?
$PSEdition
is already in Windows PowerShell, but the $Is*
variables aren't:
Creating a separate namespace for PS-controlled variables would solve the problem of name collisions once and for all - see https://github.com/PowerShell/PowerShell/issues/4394#issuecomment-322212340
$ps:IsWindows
, ... is only slightly more verbose, and, on the plus side, once you type $ps:
, IntelliSense could then helpfully limit the choices to the PS-controlled variable names.
$IsDarwin? It would cover any Apple operating system current and future.
@mklement0 perhaps if we're willing to make this breaking change, we should consider adding the prefix at the same time
I agree with the name change, but I'm thinking IsMacOS
is better. I see other languages have implemented isMacOS
in camelCase. IMO, IsMacOS
is the Pascal Case equivalent. Lower cased branding doesn't have to remain.
I also agree with @mklement0 that creating the ps:
variable scope and moving it there would be best.
@PowerShell/powershell-committee discussed this weighing different pros and cons. I think where we ended up is that for these specific variables, we'll stick with $IsWindows, $IsLinux, and $IsMacOS (staying with Pascal casing for consistency). Authoring a PSProvider is not a small effort and doesn't seem to provide enough value for discovery purposes and adding a new variable scope would break existing variable scope semantics.
TL;DR we'll just rename to $IsMacOS
For the general interop issue, we'll defer that to the RFC and don't believe these variables conflict with that resolution.
@SteveL-MSFT:
Understood.
the general interop issue
To be clear, the idea of a $ps:
namespace/scope is about _more_ than just interop: it's about _all PowerShell-controlled variables_, which fall into the following categories:
interop variables: platform abstractions, such as the variable discussed here and a variable pointing to the platform-appropriate folder for temporary files.
automatic, typically read-only variables: e.g., $PID
, $Host
, and $Matches
preference variables: e.g., $ErrorActionPreference
and $OFS
Representing each of these categories in its own namespace/scope is an option, but may be overkill (and more cumbersome to type).
I know we've discussed such an RFC, but I don't think it exists yet, does it?
I believe @joeyaiello was supposed to author that RFC we keep referencing...
One thing we discussed that was't captured in the summary is that a $ps: namespace would make sense for variables that affect powershell behavior (like the preference variables), but that would be a much bigger breaking change to move all the existing ones into that namespace and it doesn't seem beneficial enough (consider all the existing sample scripts on the internet). Similar argument for the automatic variables.
For other domains like interop which is new and thus not a breaking change, we may introduce a namespace for the TMP, USERPROFILE, etc... ones but we can defer this. Since the $Is ones are in use now and critical for basic portable scripts, we didn't want to defer this to be included as part of the interop RFC which wouldn't be implemented until after 6.0.0.
Why we don't use 'PS' prefix for the new variables?
I think using 'PS' prefix is good practice today and we should follow it.
I don't reject $ps: namespace idea but I am not fan it.
We discussed the ps
prefix as in PSIsWindows
, but we all agreed it's too ugly and probably harder to read. It's also not a variable that affects powershell core behavior so something like: "$InteropIsWindows" would be better. However, from a discovery standpoint, you can think of is
as the prefix.
Ugly if we haven't common naming rule. In C# we use naming rules and sometimes we see "ugly" but we follow common pattern.
I'll argue that a $PS
prefix also enhances discoverability in the context of all other automatic variables. $PSScriptRoot
, $PSVersionTable
are both describing the current environment and are also painful to read, but they are easy to enumerate.
@SteveL-MSFT:
but that would be a much bigger breaking change to move all the existing ones into that namespace and it doesn't seem beneficial enough (consider all the existing sample scripts on the internet)
That would indeed be a big breaking change, but I was suggesting to grandfather the existing variables in, i.e., to retain them in the user-variable namespace _and also_ surface them inside the $ps:
namespace.
Rather than a bunch of global variables, why couldn't this be put in a hashtable (one global variable) such as $PSInterop.IsMacOS
or $PSPlatform.IsMacOS
? Of course, the latter questions whether this info should be obtained from $PSVersionTable
(maybe $PSVersionTable.Platform.IsMacOS
).
$PS*
hashtables is also an interesting lightweight alternative in general to the $ps:
namespace/provider idea, for bundling preference and automatic variables too; all it would take is to declare all $PS*
variables as reserved by PS, which seems reasonable.
It's a nice way of grouping values, although it's a little verbose.
@mklement0 if we decide to have a namespace or hashtable for ps
variables, we would certainly grandfather existing ones and probably have scriptanalyzer rules moving people to use the new ones, but all of that is not required for 6.0.0. The $is* ones are necessary which is why we are special casing them for this release. I think it's fine if we end up with dupe $isWindows/etc... variables along with $interop:IsWindows or $interop.platform.IsWindows, etc...
Most helpful comment
I agree with the name change, but I'm thinking
IsMacOS
is better. I see other languages have implementedisMacOS
in camelCase. IMO,IsMacOS
is the Pascal Case equivalent. Lower cased branding doesn't have to remain.I also agree with @mklement0 that creating the
ps:
variable scope and moving it there would be best.