Live data from Hacker News

Closh – Bash-like shell based on Clojure

github.com

101–110 of 138 posts

Re: Closh – Bash-like shell based on Clojure

#101
One of the tricky things about shells is the interaction between fork and pthreads. For example, if you fork while another thread holds a lock, you risk deadlock.

node uses pthreads for certain asynchronous operations like stat(). How does Closh handle forking when there are multiple threads?

Re: Closh – Bash-like shell based on Clojure

#102
post #85

This is interesting, but I feel that making shell support such a first-class citizen is a mistake. Shell languages basically treat system binaries as functions, which causes you to lose a lot of power with everything being a string. Using system binaries (cat, echo, etc.) isn't really necessary for a modern command language due to the ubiquity of scripting languages and module systems. It's much more powerful to writ…

> I'm not sure how this would work with Python or JS. .method().method()?

Exactly what yoavm said. The pipelining that shell languages do allows for more complex and more arbitrary data transformations. I feel that doing this in Python would be difficult, but I'm not very familiar with it. In scheme you can do something like this:

  (define (pipe . exprs)
    (if (null? (cdr exprs))
        (car exprs)
        (apply pipe (cons ((cadr expr) (car expr))
                          (cddr expr)))))

  (pipe '(3 4 5) (lambda (x) (map 1+ x))) ;; '(4 5 6)

Re: Closh – Bash-like shell based on Clojure

#103
post #16

Earlier quoted context omitted.

what's the tradeoff of clojurescript over native clojure? wouldn't the java clojure runtime be much faster?

Steady-state performance tends to be better on the JVM but startup performance is always much better on top of JavaScript. That makes it an enticing trade off for shells which is a process that you start new ones of constantly and where the performance of the shell itself is often not very important. (Performance-critical or hard-to-duplicate code like, say, line editing code, can be done equally well on either platf…

Why not just make a server that starts up once in the background and then a lightweight c frontend to the server that essentially just pipes every keystroke to the server?

Re: Closh – Bash-like shell based on Clojure

#104
post #91

Earlier quoted context omitted.

JavaScript looks nothing like the “created in 10 days” version to which you speak. I would highly suggest you take an uncomfirmation(?) biased look at the language as it is now. Asyncs simplicity is arguably a reason why it’s a good platform to build off of. I agree I would rather have a single binary, and node may not be the best platform for shells on this point.

> JavaScript looks nothing like the “created in 10 days” version to which you speak. It has improved, sure. But not only in the direction that makes me happy. But you cannot undo some bad design choices, without it becoming a different language. > I would highly suggest [...] I write JS at times. It hurts badly. Not everyone feels it. Maybe coming from PHP or Perl it does not even hurt that much. But after writing so…

"Maybe coming from PHP or Perl"

I don't know about PHP (my experience with it is limited), but coming from Perl, Perl is a breath of fresh air in comparison.

Then again, to me Haskell makes even the worst JAPH-style Perl one-liners look readable in comparison, so maybe I'm not the best judge of language design.

Re: Closh – Bash-like shell based on Clojure

#105
post #80

Earlier quoted context omitted.

Is this satire?

It'd better be.

I don't think it is. In the words of Bill Clinton: "it's the economy, silly". Economic/social factors trump technical aspects 99% of the time, the 1% being technical revolutions. And Java or C# or Lisp being better than Javascript doesn't fall into the "revolution" category. Ergo Javascript everywhere :)

Re: Closh – Bash-like shell based on Clojure

#106
post #89

Earlier quoted context omitted.

> I'm not sure how this would work with Python or JS. .method().method()?

I think the concept of piping is actually more similar to function(function()) than .method().method(), because you're not limited to the scope of your initial object's methods. And the truth is that functionB(functionA()) reads much worse than functionA | functionB , so yeah I agree that this is something that shell scripting languages got right.

For reference, various functional languages do indeed treat something like 'foo |> bar' as equivalent to 'bar(foo)' (I've used this extensively in Elixir, where it's standard practice; I'm pretty sure this is derived from F# and/or Clojure, both of which - IIRC - use the same operator for the same purpose).

It's not really perfect parity with what a shell typically offers, though, since a shell's pipeline steps (usually) run in parallel and indefinitely, consuming an input stream and producing an output stream (whether those streams are text, rich objects, audio/video data, or something else entirely). Elixir/Erlang are well-suited to achieving that parity by spinning up processes and using message passing for I/O, but Elixir's pipeline operator doesn't really do that (last I checked).

Re: Closh – Bash-like shell based on Clojure

#107
post #71
post #64

Looking forward to the day I can write backend code in clojure, frontend code in clojurescript, write all my terminal commands in clojure and use an IDE that is configurable via clojure code.

Ideally, we want a Symbolics Clojure Machine.

I suspect that a hardware JVM implementation would get you halfway there.

Re: Closh – Bash-like shell based on Clojure

#108
post #24
post #9

Earlier quoted context omitted.

I really like this idea and I really like Clojure. Though I'm curious about performance. And do you know if anyone is doing something similar with Racket? (Looks like there is a Common Lisp shell http://www.cliki.net/CLISP-Shell )

eshell is another lispy shell that's been in Emacs for a very long time. Elisp is probably my least favorite lisp that's commonly available, but eshell probably has the largest user base and is certainly the most mature out of all of these contenders. You can reasonably use eshell as your primary shell.

Until you type '|', since eshell will buffer each process's output in an emacs buffer. It doesn't actually stream between pipes, which basically makes it useless for a complicated pipeline.

Re: Closh – Bash-like shell based on Clojure

#109
post #85

This is interesting, but I feel that making shell support such a first-class citizen is a mistake. Shell languages basically treat system binaries as functions, which causes you to lose a lot of power with everything being a string. Using system binaries (cat, echo, etc.) isn't really necessary for a modern command language due to the ubiquity of scripting languages and module systems. It's much more powerful to writ…

> I'm not sure how this would work with Python or JS. .method().method()?

This is object-oriented method chaining. Not the same thing as functional composition (piping is essentially just left-to-right composition), which is what's mentioned in the OP.

It's also nowhere near as flexible, because it requires the return value to be responsible for providing a set of APIs for the next method call on every step of the chain, whereas each function in a functional composition can operate on any arbitrary input/output.

There's actually a proposal for a pipeline operator in JS that I personally really like: https://github.com/tc39/proposal-pipeline-operator

I have no idea if it's getting enough traction to get standardized anytime soon though.

In lieu of that, I personally just use Ramda's `pipe` function: http://ramdajs.com/docs/#pipe

Which accomplishes the same thing, but with a bit more ceremony, and not quite as convenient in a scripting setting.

Re: Closh – Bash-like shell based on Clojure

#110
post #58
post #29

Nice, I've been waiting for a good modern shell to replace ZSH. Fish just wasn't enough of an improvement for me to abandon ZSH. This is an area where most open-source developers have avoided, as it's a "solved" problem, but it really isn't. I'm currently waiting on Elvish [1] to mature. It's written in Go [2], but they're developing a new language on top of it for shell scripting, which I tried for a week. It's a ni…

> This is an area where most open-source developers have avoided, as it's a "solved" problem, but it really isn't. I've found the complete opposite to be the case. This is one area where there are hundreds of different shells out there as it seems a "cool" thing to try since it's basically just an extension of writing your own language. Most never go beyond pet projects though. If you're curious about Go shells, I'm…

> This is one area where there are hundreds of different shells out there... Most never go beyond pet projects though.

I have had the same experience. For every scripting/interpreted language out there, there is at least one person who thinks "ooh, wouldn't it be neat if I could use this as a shell?" or, almost as often, "to program my text editor?" Soon they realize that interactive programs like shells and text editors are hard to get right. There are thousands of special cases and non-obvious features that have only been found by hard experience. These programs must also interact with a computing world that has evolved over decades.

Most programmers give up at this point. A few persist, and of those, a few end up creating something genuinely useful to more than themselves and a couple of friends. I'm not sure if I would call shells a "solved" problem, but I don't believe the incredible amount of work required to make a sufficiently better one is worth it.

Post reply on HN