Hacker News new | ask | show | jobs
by dkarapetyan 3952 days ago
I don't think it is fundamentally different. When I think of a shell I think of pipes and interactivity. What you pass between through the pipe is secondary. The fundamental nature of the shell is those two things and everything else is just sugar on top. PowerShell has that and more so I'd say it is not fundamentally different and in fact it is objectively better.
1 comments

The word "shell" in this context already means something. A text shell is a command line interpreter (https://en.wikipedia.org/wiki/Shell_(computing)#Text_.28CLI....). There are many shells that do not use the pipeline convention (e.g., irb), so your attempt to redefine it to promote PowerShell fails from the start.

PowerShell's object pipeline is functionally analogous to function chaining in languages like Ruby, Python, and JavaScript, not Unix pipelines. PowerShell's object pipeline does not exist outside of the .NET runtime and you can not stream objects between arbitrary executables outside of the .NET runtime.

You can't compare an apple to an orange and say one is "objectively better," no matter how hard PowerShell advertisers try to pretend their apple is an orange.

> PowerShell's object pipeline is functionally analogous to function chaining in languages like Ruby, Python, and JavaScript

No, in those languages function results are bound upon returning from the function. PowerShell's pipeline would be more like function chaining where each function is a co-routine that can yield partial results, which would make it considerable more complicated.

So your attempt at trivializing PowerShell fails from the start.

For your information, here is roughly how a PowerShell pipeline is set up, processed and torn down:

1. BeginProcess is invoked for each command in the pipeline, starting with the last command of the pipeline, working towards the first. When each command is initialized this way, it can start receiving objects from preceding command on the pipeline. Each command may start produce objects already during this phase, as all subsequent commands are ready to process them. If it produces objects, ProcessRecord of the subsequent command is invoked immediately. 2. ProcessRecord is invoked on the first command of the pipeline. If it yields objects, ProcessRecord of the subsequent command is invoked for each object, thus "pushing" objects through 3. EndProcess is invoked for the first command of the pipeline. It it yields objects, ProcessRecord of the subsequent command is invoked for each object. When EndProcess completes for the first command of the pipeline, EndProcess is invoked for the subsequent command and so forth until EndProcess has been invoked for all commands of the pipeline.

As you can see, each cmdlet has 3 phases: initialization, processing and completion. All cmdlets (functions?) become active at the same time, with the control flow passing to each command (function?) multiple times during each phase. This can be implemented in any turing complete language, but function chaining is a lame attempt at trivializing it. Throw in reactive sequences and it may get closer.

Consider how Sort-Object (alias sort) is implemented: It does nothing during BeginProcess, during ProcessRecord it adds to an internal collection but does not yield any objects (yet), during EndProcess it sorts and yields all of the collected records. This is clearly analogous to how sort in byte/text stream is implemented: When the process starts it does nothing but initialize and starts listening on stdin, for each "line" on stdin it adds to an internal collection, and when stdin is closed it sorts the collection and writes the "lines" to stdout. 3 phases.

Even so, it doesn't really matter how it is implemented, a shell is inherently about how you interact with the shell.

> PowerShell's object pipeline does not exist outside of the .NET runtime and you can not stream objects between arbitrary executables outside of the .NET runtime.

You are locked in the Unix view of the world and is unable to consider that long standing assumptions about "the way to do it" may need a refresh. If you want to leverage objects for system management then yes, you need a system-wide object model. Unix was not built with an object model. Windows was sort-of build with an object model (handles) but it is not versatile enough as a system-wide management model.

However, the good thing about objects is that they are abstractions which can easily wrap existing operating system concepts, such as files, processes, access control lists, drivers, users, groups, network connections etc. .NET is a mature object model and with a lot of tooling. Building PowerShell so that the abstractions over network adapters, users etc become represented by .NET classes enable a lot of tooling and infrastructure right from the beginning.

useerup, virtually everything in your comment is irrelevant handwaving and obfuscation, including a bunch of irrelevant comments about features that are internal to the PowerShell runtime.

No matter how much you want to try to talk around it, PowerShell is a .NET CLI, the object pipeline exists within its .NET runtime, and the commands are instances of .NET classes. Unix shells work primarily with arbitrary executables outside of the shell runtime using OS system calls to create pipelines with standard streams.

Here's the cold hard fact stated yet again: PowerShell's object pipeline is functionally analogous to function chaining in languages like Ruby, Python, and JavaScript, not Unix pipelines.

> Here's the cold hard fact stated yet again: PowerShell's object pipeline is functionally analogous to function chaining in languages like Ruby, Python, and JavaScript, not Unix pipelines.

Ok, what then is the functionally analogous function chaining of Ruby, Python or JavaScript to the following:

    cat log.txt -wait | sls "error"
A simple function chain will do.