💾 Archived View for soviet.circumlunar.space › zwatotem › diff › pwsh.gmi captured on 2023-05-24 at 18:26:51. Gemini links have been rewritten to link to archived content
⬅️ Previous capture (2022-04-28)
-=-=-=-=-=-=-
As a tradition I'll tell something from the misterious land of my life. I got back to studying. And I did in a real fasion - I'm back at the university building. I can finally focus on a real work, and I get the natural encouragement needed to boost up my productivity. Seeing people working remotely from the university makes me kind of ashamed of myself.
After years of cmd being the default shell for Windows, Microsoft decided to create something new and modern. And they delivered. If I were to describe powershell in one sentence I would say it's a incredibly successful attempt to cross an object oriented programming environment with the traditional sense of system utility shell. In powershell every built in command returns an object or a collection thereof. What we see on the screen are not the objects themselves, but their string representations, controlled by Out-Default (or Out-Host for that matter) cmdlet.
So in pronciple we have this familiar REPL or read-eval-print-loop. But that's not the end of possible syntax. Powershell supports all the objects from .NET environment, and by extension all their methods and operators, so integer or double arthmetics is native type of expression in Powershell. Additionally we can enclose expressions in parentheses, and continoue extending them. The syntax is complemented with some control flow constructs, like if, while, for, foreach; and these provide familiar syntax for most developers of modern programming languages.
However, enclosing expressions in parentheses is tedious, so powershell, as any serious system shell has a pipe operator, which enables us to pass the data from one expression to the next.
After some time of contemplation on Powershell I started looking closer at design of the language, and discovered several things that make it really annoying. It turns out not everything is as beautiful as it seems at the first glance.
- Powershell has a well defined structure, that makes it easy to manipulate objects that we get.
- The idea of location (analog to working directory) is expanded and can be applied to any domain, if we bother to implement it. For example we could implement a provider, that would let us use cd command to change current git revision, and ls command to list the changes in the current revision. This potential isn't that much used unfortunately; the only so called PSProviders right now are Registry (Windows only), Alias, Environment, FileSystem, Function and Variable.
- Names for cmdlets and functions are very verbose and actually tell, what they are supposed to do. Also all the parameters are tab-completable, which makes their discoverability very easy.
- Powershell has a built-in help system, which is hard to grasp at the beginning, but it becomes a learning companion later on.
- Powershell is modular, which means that we can create our own modules, which can be loaded and used in our scripts. The most popular repository of Powershell modules is PowershellGallery.
- Some symbols were reserved in the language for some weird reason, and as a result operators like == < > are replaced by user-unfriendly constructs like -eq, -lt, -gt, etc.
- Powershell has no automatic variable for the last returned value. As a result if you make a one time computation, and you don't assign the result to a variable, you may permanently lose it.
- The legacy of having to accept native system executables in a role analog to builtin cmdlets proves to be troublesome. They traditionally have very strange behaviour, having a list of string parameters as an input, but also accepting streamed input through stdin; returning a single integer, but also streaming output through stdout and stderr; and finally being able to have other arbitrary side effects and being effected by the environment. That doesn't really fit with an idea of a cmdlet that has a well defined list of parameters, and a single return value of any predeclared type.
- I think development of powershell got out of hands when they decided to make it possible to write powershell modules with Powershell itself. The syntax for some parts of a language is confusing, especially for defining how a function should process piped input. In my opinion an idea of making it an SQL for system administration was a good idea, but it should be better thought out. The trouble begins, when you have collection output, but next function in the pipeline is expecting a single value. Then you have to use a Foreach-Object cmdlet to iterate over the collection, which makes everything more complicated. I think Powershell should have different kind of pipe operators, that would modify how the next expressing is applied and how the outputs are aggregated. (Possibly borrow from Haskell's list monad with concatMap and >>= operator)
- Powershell doesn't really run natively in .NET. Its runtime is created on top of .NET, but it doesn't really sit **inside** and it's feelable. For example there is no easy way to create a custom object, rather you create something called PSObject, which is a confusing layer of abstraction.
I'm yet to see other .NET languages than C# and Powershell. F# seems to be interesting exploration of the world of pipe exectuion. I also plan to see Iron Python and especially Iron Ruby. I heard they enable you to create dynamic objects in .NET runtime, the same dynamics you know from C#. Also it has concise syntax and good solution for variable scoping. So I'm actually intrigued by the idea of Iron Ruby being a possible replacement for Powershell, with the right implementation for a REPL and a right set of modules/libraries for system administration.
That's all I don't believe I managed to compose this text in a finite amount of time. Stand by for more of these things. Next up maybe a roadmap for my personal project or maybe something else.