4 ms·
I use *sh at home, and Powershell at work. Powershell has a lot of really cool and genuinely useful concepts. There's the obvious like piping objects instead of
by GrantMoyer 2y ago
I use *sh at home, and Powershell at work. Powershell has a lot of really cool and genuinely useful concepts. There's the obvious like piping objects instead of raw bytes, but there's also things like first class parameter validation, automatic array flattening, multi-threading, full .NET API interoperation, and more.
Unfortunately, it also has some real sore points for use as an interactive shell, and even some outright broken behavior. Some that I lament most frequently:
- Powershell has native tab-completion support, but the word-of-god dictated "Verb-Noun" command naming scheme means almost every command shares a common prefix with a slew of entirely unrelated commands, making tab-completion painful.
- Power shell has sparse built-in support for funtional style list manipulation or data structures beyond lists. There's a "map" command (%), but no reduce, zip, tail, etc. These feel like they'd fit in perfectly to the design of the language, but they're just missing. Also, pipes are lazy, but lists are always strict, which can cause friction.
- most operators are strangely named, such as "-eq" for ==, which hurts legibility.
- There're lots of unvoidable brackets, meaning you often need to jump around the line while writing out a command incrementally. For example, to get filenames, you either need to write `(Get-Item).Name` or `Get-Item | %{$_.Name}`. It'd be nice to have something like `Get-Item |. Name` as an option.
- It's impossible to pipe raw bytes between commands/executables; raw bytes are interpreted as strings. This means, for example, it's impossible to pipe a file to `patch`, because the contents will be decoded into strings, piped as strings, then re-encoded with line endings changed, which `patch` rightfully refuses to apply.
- Running Powershell scripts is disabled by default (WTF?)
By comparison, *sh's heavily favor interactive use. For example, you can put io redirections at the start or end of a line, tab-completion is often very good, it's often possible to avoid brackets (ex. with xargs), background/foreground job management, etc.
Overall, I often find Powershell more pleasant to use than *sh, especially when writing scripts. But for interactive use, I often wish Powershell was a little smarter and a little dumber at the same time.
- nu11ptr 2y agoWhy is automatic array flattening a good thing? This has caused more bugs than I can count. Every time I make an array I have to check if it has a length of 1 and do something special with it or else the script blows up. Best I can tell this is a huge foot gun anti-feature. What am I missing?
- GrantMoyer 2y agoIt's a foot gun, and the behavior is often surprising until you get used to it and sometimes after, but Powershell would be very painful to write without it. Basically all functions return a list in Powershell, including all user-defined functions, so you'd need to unwrap singleton lists all over the place.
- nu11ptr 2y agoBut if they COULD be lists of >1 then by unwrapping it you have two scenarios to handle instead of one. How is this an improvement? And if it is ALWAYS a list of one why return a list?
- GrantMoyer 2y agoAll Powershell functions are basically python generator functions. It could have been designed to have more traditional functions, but I find generators fit well into a language based on piping streams of values between functions. Usually, the distinction between a single item, a flat list, and a list of lists isn't important in Powershell, because commands are written with Powershell's behavior in mind. It's extra painful when it does matter, but it's a trade off against being more verbose every time it doesn't matter. Ultimately, it's personal preference; for an interactive shell, I like the tradeoff Powershell made, and I think it's a cool design space to explore, but I do think there's a lot of room to improve the implentation of the concept to make it less surprising and less painful to choose the alternate behavior when needed.
- LeonB 2y agoThis works: Get-Item | % Name
- GrantMoyer 2y agoWelp, I wish I'd learned that earlier.
- vips7L 2y agoI switched to menu completion and the tab completion isn’t as painful with all the choices.