Comment by esrh
1 day ago
awesome! I have wanted something like this for a long time. Currently I use a janet fork <https://github.com/eshrh/matsurika> with some trivial additions, the most important of which is a `$` macro that does what the `sh` does here. I have two questions:
- I see that `sh` does not take in strings but instead lisp forms. How do you distinguish between variables that need to be substituted and commands? In my fork, the way to do variable substitution involves quasiquoting/unquoting. - Almost all of the features that make your language good for shell scripting are essentially syntactic features that can easily be implemented as a macro library for say, scheme. Why'd you choose to write in C++? Surely performance is not an important factor here. (I'm interested because I am currently working on a scheme-based shell scripting language).
can you give an example of how variable substitution in your language looks like?
one of the things i think a lisp for shell should have, and i agree that this may not be easy, but unix commands should be first class functions, as in, you should not need a $ or sh macro to make them work. the other thing is that strings should not be quoted, and so you need something else to designate variables like $path or ($ path)
Yes, i agree that unix commands should be first class. I did this for the super common stuff like ls and cp. As for substitution, I did exactly $ for substitution. You'd do something like ($ rsync -avP $src $dst), but I don't think I ever got around to implementing $() to evaluate forms. If you really need to do that then you have to quasiquote the whole expression and unquote the form you need to evaluate. This has been relatively ok for me though. I never implemented anything like pipes or redirection, I instead just send everything like that to bash.
This is not really relevant to your question, but I regret choosing janet for this, it's too opinionated and hacking on C is not as fun as lisp. I started writing my own version of schemesh in racket, but I never got far enough.