Pulled out of the discussion in PR #8205:
What if PowerShell automatically worked as if you had invoked the equivalent of the snippet below at the top of every script/script module?
using namespace System.Management.Automation
using namespace System.Management.Automation.Language
using namespace System.Management.Automation.Runspaces
I think that, plus type acceleration for aliases/shorthand type names and outliers that are in namespaces from which you only care about a few types, would make working with the .NET side of PowerShell much easier. Is there a downside to automatically using some core namespaces that are among the most frequently used in PowerShell?
Only we need to look possible type name conflicts.
Possible fix is to add the types in PowerShellAssemblyLoadContext.InitializeTypeCatalog(). typeCatalog.
There are definitely some name conflicts, one I've ran into similar issues with the System.Reflection namespace in particular (e.g. MethodAttributes exists in both System.Reflection and SMAL)
As long as an explicit using namespace takes priority I don't think that would be too big of an issue though.
Copying over what @SteveL-MSFT said in the PR where this issue came from:
@KirkMunro using namespace is a good option to make scripts a bit more readable, but can affect runtime performance during discovery of types so we wouldn't want to include the SMA namespaces by default. One of the things we discussed that could help in the future is allowing using system.management.automation.actionpreference as actionpreference to get custom type accelerators within your script.
We had planned, at one point, to have an aliasing mechanism as part of the using statement:
using type zork = some.long.type
so you could create you're own type aliases. In fact it's partially implemented (see parser.cs:4681).
@SteveL-MSFT and @BrucePay, what are your thoughts on this approach, which would make the need for type accelerators and aliases much less important when it comes to PowerShell itself, without sacrificing runtime performance:
Within the PowerShell parser, automatically recognize:
|This type|as this type|
|--|--|
|[S.M.A.whatever]|[System.Management.Automation.whatever]|
|[S.M.A.L.whatever]|[System.Management.Automation.Language.whatever]|
|[S.M.A.R.whatever]|[System.Management.Automation.Runspaces.whatever]|
That wouldn't require a specific feature (type aliases), and it would reduce the need for type accelerator bloat. When we're talking about PS types, we often say/type S.M.A.... already. This would be just applying how we talk about these things to the actual code we write.
Drop the dots, i.e. instead of using S.M.A. as the prefix, use SMA., and so on. I think I prefer with the dots though.
Use a numeronym instead, e.g. S26n in place of System.Management.Automation. 馃ぃ
If someone out there has S.M.A.whatever or similar class names, this would break those.
I think aliasing these namespaces in this particular manner is... not particularly effective, and probably would tend to make scripts less clear in reading, at least to folks unaware of this sort of shortcut (which will, inevitably, be the majority of the PS community in most cases; after all, _where_ would you document such a shortcut while being able to expect people will easily come across it?)
Considering we already have some shortcuts where we can, for example, often omit the System prefix for many namespaces (if not all?) in some cases that I see here and there, why not simply add Automation as a short-cut to System.Management.Automation? i.e., where you want to use System.Management.Automation.ErrorRecord you can effectively cut it in half and just use Automation.ErrorRecord.
This has the advantage of being _much_ less likely to collide with type names from other namespaces, and remains quite short and to the point, while being much more clear in intent (in my opinion) than an overly abbreviated S.M.A.L. shortcut and so forth. If we wanted to use a more explicit alias like PSAutomation or some such for this shortcut, I think that may also be worth considering.
I think we need to balance clarity of intent with the need to shorten that namespace length, and attempt to avoid causing unnecessarily avoidable collisions where we can here.
after all, where would you document such a shortcut while being able to expect people will easily come across it?
In a new about_types help file, which really should be written anyway to explain everything that is already there (e.g. being able to omit the System prefix, how the using statement works with types, how to create custom objects with custom type names, how to restrict script/function parameters to specific types, etc.), plus this as well.
Also I disagree that Automation.whatever is much less likely to collide with type names from other namespaces. On the contrary. Automation is much more likely to be used as a namespace name already than S.M.A.
I had also considered simply using PS or the PS prefix for the System.Management.Automation shortcut, but I don't like the shortcut being that far from the original name. With PowerShell already supporting pithy names in many cases, the S.M.A.*. approach fits. It also fits with the recent proposals on how to handle Intellisense with camel case command names.
The goal I'm trying to reach here is worthy of a solution: make working with overly verbose, native, common PowerShell types in PowerShell much easier by default, so that you get easy access to those types whether you're using PowerShell ad hoc or in a script.
My preference is still for automatic using (as proposed at the top of this issue), but if the PS team doesn't feel that's acceptable, what alternative do they propose?
Accidentally marked for review, but I don't think this is ready for review yet and needs more feedback to converge on a proposal.
It would be interesting to do a search to see how big a problem this actually is. Are people using using namespace s.m.a often? Are they using the fully qualified type names often? I realize there's a set of individuals using the SMA types regularly, but it's not clear to me if this is a problem worth solving.
The original request is for script/module.
I don't see a big problem to add the "using namespace" by necessity - this is rare operation.
So Steve raised the right question - how often is it needed?
On the other hand we could consider interactive session too: long names can be annoying.
The more I think about this, it's really not a big deal to throw using namespace at the top of a file. The only reason not to do so would be for supporting older versions of PowerShell, which this won't help with anyway.
On the other hand we could consider interactive session too: long names can be annoying.
Yeah, a better way to set using statements interactively would be nice. You can do it currently but tab completion doesn't check the TypeResolutionState, so it's generally easier to just use the full name anyway.
Pro tip - any using namespace statements in your profile work at the interactive prompt, at least until you interactively enter a using statement, at which point that using statement(s) will override what was previously specified (via your profile or interactively).
In other words, using namespace is sort of sticky in global scope.
@lzybkr Yeah that works, though it still completes the full type name. Going back and deleting the namespace after it completes isn't really worth it imo.
A while ago I threw together a really hacky TabExpansion2 that looks at the current TypeResolutionState. It works alright, but definitely needs to be disabled when in an editor.
Most helpful comment
The more I think about this, it's really not a big deal to throw
using namespaceat the top of a file. The only reason not to do so would be for supporting older versions of PowerShell, which this won't help with anyway.Yeah, a better way to set using statements interactively would be nice. You can do it currently but tab completion doesn't check the
TypeResolutionState, so it's generally easier to just use the full name anyway.