|
|
|
|
|
by Stammon
2224 days ago
|
|
> UNIX commands are more an accident of history than a cohesive, coherent, composable design. PowerShell was designed. It was designed by one person, in one go, and it is beautiful. I'm curious about that design and would love to learn about it. Note, that I'm not interested in learning how to actually use powershell as a developer, but understand the abstraction design choices, that went into it. Every time I tried to learn about that, I'd find recommendations about Books with 1000+ pages and similarly time consuming resources. Do you have an recommended read for understanding the design choices, that went into powershell, while not learning the details, that a everyday windows would need? Things I care about:
-How do Lamdas work?
-Arrays are Objects. How exactly? -Typesystem
-Are there native wrappers for the kernel APIs how do they fit into the objectmodel?
-Since to my understanding no shortflags exist, how is verbosity avoided?
-How thight are interfaces defined. If a tool provides a new interface in a new version, can old tools still work with it? |
|
Generally, PowerShell simply embraces the UNIX concept, but with a clean slate. Being based on the .NET runtime, it inherits much of its low-level functionality, such as being able to call into WMI, COM+, and Win32 APIs.
But what it's really about is keeping things in strongly typed objects until the last second when they are formatted for display. The original UNIX pipes formatted output immediately, because C is not object oriented. So everything ends up as a byte/char stream, and then to glue commands together you often have to parse & split the output. There's ways around this, but it's inconsistent and not at all general.
So whereas in bash you would see only 2 or 3 commands in a row with a pipe symbol in between them, in PowerShell you would often be able to chain 10 or even 20 commands in a row in a single pipe. You build up pipelines almost like SQL queries, which is easy because the data passing between each step is structured.
The other big win that I see over legacy shells that got built up over decades is the discoverability and consistency. The naming is consistent, and all the commands publish detailed metadata that integrates with both the help system and tab complete.
Issues like verbosity are simply sidestepped. PowerShell is verbose to read, which makes it readable. Typing it is fast, because you can tab complete not just the command names, but the parameter names, and even the parameter values in most cases. No other shell can do this. It has aliases, so if you prefer 'ps', you can use that instead of the canonical 'Get-Process' command name.
Generally all commands simply extend a .NET class called "Cmdlet", which defines functions such as Begin(), Process(), and End() that handle pipeline input. Declarative parameters can be defined, which the shell engine hooks up for you automatically. For calling external APIs, you can do whatever .NET can do, which is pretty much everything in Windows and Linux with only a handful of exceptions (no inline assembly language).
In terms of interfaces, it's a little bit too weakly typed for my taste. When binding parameters or pipelines, the engine goes through a complex process of figuring out what you meant. It can go wrong. The classic example is that some search or query commands can either return a single object or an array, and making this consistent is a bit of a pain.
It supports lambdas, they're simply a block of code with squiggly brackets around them, e.g.: { echo "foo" }. You can do all sorts of fun things with them, like capture a closure with simply: { ... }.GetNewClosure()
Install PowerShell 7 on Linux, type in {}. and press tab to cycle through the list of functions you can call on an expression block. I like toying around with things like .Ast. The engine exposes some crazy powerful things directly, such as being able to generate code for remote RPC wrappers automatically, etc...