33 ms·
This is some of the most exciting stuff happening in the unix world these days. My mind was blown after reading two posts on Oil's author blog, a few years ago
by enriquto 7y ago
This is some of the most exciting stuff happening in the unix world these days.
My mind was blown after reading two posts on Oil's author blog, a few years ago:
* Shell has a Forth-like Quality: https://www.oilshell.org/blog/2017/01/13.html https://www.oilshell.org/blog/2017/01/13.html
and
* Pipelines Support Vectorized, Point-Free, and Imperative Style: https://www.oilshell.org/blog/2017/01/15.html https://www.oilshell.org/blog/2017/01/15.html
Warning: these writings can change your view on the shell language. Now you probably think, as many of us did, that shell is a cute little hack, useful for one-off throwaway stuff, but not really fit for serious work. Afterwards, you will start to see the shell as a glorious, essential element of our civilization, worth of respect and deserving our careful attention. Pipes are an essential programming tool that must be supported by the core language and not by a library construct (as in python).
- jstimpfle 7y agoI've written many, many shell scripts, back as a sysadmin, and because I wanted it to not be a cute little hack. I know all the tricks described on the blogpost and many more. I have an intimate understanding how the quoting works and how we can work around its limitations. Let me tell you: shell is sort of a local optimum for one-off throwaway stuff, because it makes commonly needed thing accessible with so few keystrokes. But also, shell is a cute little hack. It's literally impossible to write robust programs in it.
- cabalamat 7y ago> It's literally impossible to write robust programs in it. This is why I never write shell scripts more than about 4 lines long or with any control flow statements in it -- I use Python for that. The Python might be a bit longer, but at least I'll understand it when I come back to it 6 months later.
- mjevans 7y agoI would _like_ to use Python (2) for that, but it's EOL/effectively EOL, and Python 3 made the _wrong_ call with respect to Unicode support. Source code is Unicode? Great. Forcing _everything_ to have an Encoding when the surrounding world isn't an academically clean environment? Nope, this means Unicode Enforcement and Error Handling in what should be simple programs. I don't mind have __optional__ libraries for handling Encoding conversions, corrections, and errors... but if I'm working with a legacy filesystem, human input, or anything else, the only basic language support I want or need is transparency of bits/bytes. Let a programmer decide if or where things are validated and what to do about handling invalid input at that moment; do not force the issue upon them.
- kragen 7y agoI agree; at Satellogic we had on-orbit error-handling problems due to Python 3's string encoding, where coercing binary data into a Unicode string caused an exception in our exception handler. Python did eventually acquire a sensible (lossless, errorless) way to convert back and forth between binary and Unicode — UTF-8B, known as surrogateescape, described in PEP 383. Unfortunately, it isn't the default everywhere. PEP 540 makes it default in some cases. This is the reason Oil is written in its own private fork of Python 2 instead of in Python 3.
- chubot 7y agoYes those kinds of errors are extremely common... In fact 2 days ago I was visiting a well-known company in SF, and someone mentioned the reason for an aborted Python 3 rollout: a database contained utf-16 surrogate pairs mis-encoded in utf-8. To me this is the same problem I had with HTML and DOM mentioned on the other thread (which I will reply to!). The analogy is HTML files : DOM :: string data :: Python strings. I've long had a rant about "models/abstraction vs. reality", which is basically: Reality always wins :) The DOM is an overabstraction of HTML to the point of causing bugs and performance degradation; ditto for Python strings and "real world" textual data. I'd rather solve "honest problems" than self-inflicted problems caused by the wrong abstraction. A lot of software is basically "undoing" problems caused by other software, not addressing something in the application domain. PEP 383 and 540 seem to be clear instances of that. (And note that I said Python is an amazing achievement in the appendix of this post, which is simultaneously true :) )
- adwn 7y ago> at Satellogic we had on-orbit error-handling problems due to Python 3's string encoding, where coercing binary data into a Unicode string caused an exception in our exception handler. Woah. If you're using a dynamic programming language for mission-critical software and your tests don't properly cover "coercing binary data into a Unicode string", then your problems run way deeper than Python 2 vs 3. This isn't restricted to on-orbit software. Your GSE ("ground support equipment", for those not in the industry) also shouldn't have that kind of quality problems.
- chubot 7y agoIt's literally impossible to write robust programs in it. Right, that's the whole point of Oil! You can make those programs robust without rewriting them entirely. Run them with Oil, and then flip a few switches to enable stricter behavior. Here are a few examples: Oil's Stricter Semantics Solve Real Problems http://www.oilshell.org/blog/2019/08/16.html http://www.oilshell.org/blog/2019/08/16.html But there are a dozen more. The key point is that bash's codebase has kind of "topped out" in the sense that it's hard to add anything without breaking something else. On the other hand, the Oil interpreter is reasonable, small, and you can add features to it, and fix things. Anyone who knows about programming languages might be able to read the type definitions in osh/runtime.asdl (and frontend/syntax.asdl) and learn a lot about how shell works.
- ashkankiani 7y agoAt that point, just use an actual programming language instead of a shell...
- coldtea 7y agoThat misses the whole point - that there shouldn't be any difference. Shells already behave like programming languages just bad ones. The reason people use them over a "bona fide" programming language is their command line editing, easy process handling, first class support for job control, access to environment and pipes. One could use a non-shell programming language, but then he'd have a much harder time with all the later - even though he'll have a much better time with abstraction, programming correctness, error handling, first class data structures, and so on. So we're in an either (shell+easy command line use+process handling/job control/pipes etc) or (programming language+better syntax-cohesion-correctness-better error handling-libraries-first class data structures-and on on). There are things in IT that can't be combined because one is a tradeoff to the other. This is not such a case - this is just a historical accident: crappy language features in shells and crappy job control features in programming languages. But there's no reason one can't have all those latter things in a proper programming language. Which is what Oil is.
- chalst 7y ago> It's literally impossible to write robust programs in it. It's hard, verbose, and littered with snafus, but it is also a solved problem. POSIX and C shell are a source of quoting difficulties. The semantics of Plan9's rc and now fish are much more straightforward. I think that shells could be a robust technology if we were less fixated on faithfully capturing familiar idioms.
- coldtea 7y ago>Let me tell you: shell is sort of a local optimum for one-off throwaway stuff, because it makes commonly needed thing accessible with so few keystrokes. But also, shell is a cute little hack. It's literally impossible to write robust programs in it. But there's no essential reason why it has to be this way. It's just that the first UNIX shell was a minimal and ad-hoc design, and the rest just accumulated BS craft in an unguided and even more ad-hoc way, without any vision or cohesion. Then POSIX came, and we got stuck with those (or hardly better versions, like zsh). If by shell we define it as a programming language that has: first class support for job management, first class support for pipes, handy primitives for one-liners and file/text/job processing then there's absolutely no reason why such a language can't be much better than what we have. For example, just off the top of my head: - proper argument parsing (not just the BS hacks e.g. Bash allows) - proper vectors and maps (not the primitive hacks bash allows - "shift" is so idiotic...) - proper syntax (consider the BS [ vs [[ dichotomy in bash, or the millions of edge cases) - proper exception/error handling (no just the primitive "traps" or checking $?) - better expandability (e.g. consider the crappy kludge that autocomplete options are set) - proper functions (not the arg1=$1 BS - shell could e.g. automatically assign to named arguments) - namespacing - packages, libraries. How many times people write and rewrite the same BS shell functions or primitives? "source" doesn't cut it.
- chubot 7y agoThank you for the kind words! And I mentioned in a sibling comment, I regret not finishing that series... My plan was to "finish" Oil and then publish them. So people would not only learn something but also have something to try. I didn't realize it would take this long :) But we've made steady progress the whole time. --- The other posts in this series are about xargs, the "$0 dispatch pattern", and the "run.sh" pattern. They are very practical, though again more abstract than you might see in most shell scripts. I won't argue if someone says the syntax is ugly -- the point is as you say, that the structure of the programs valuable and not possible or not easy/idiomatic in other languages. For example the way I run comparative benchmarks is to print a list of tasks to stdout, and then have a loop that consumes it (usually with xargs). You can control parallelism that way (with xargs -P), and you can filter the tasks, or you can even distribute them to other machines. I currently run benchmarks on two machines. https://github.com/oilshell/oil/blob/master/benchmarks/osh-parser.sh#L80 https://github.com/oilshell/oil/blob/master/benchmarks/osh-p... https://www.oilshell.org/release/0.7.0/benchmarks.wwz/osh-parser/ https://www.oilshell.org/release/0.7.0/benchmarks.wwz/osh-pa... Also, I wrote this page that shows the whole website is basically a shell script. (And it's not that simple, despite looking simple!) http://www.oilshell.org/site.html http://www.oilshell.org/site.html So yes hopefully I can make these patterns a little prettier in Oil because they are very worthwhile. For example "xargs" is really like "each" in JavaScript, but it can be serial or parallel. If Oil reaches it goals, then one thing I'd like to do is run a lot of performance and correctness tools (dynamic and static analysis) on open source software, and report them on my site. I think there's a lot of room for this kind of knowledge to make open source better. There are knowledge bottlenecks where people don't understand how code works, so they write a lot of new code, which is better in some ways but worse in others. Related to that is that I want to write a post about benchmarks/uftrace.sh and several other tools I used to speed up Oil: https://github.com/oilshell/oil/tree/master/benchmarks https://github.com/oilshell/oil/tree/master/benchmarks I mentioned uftrace here; it's very shell-friendly: https://news.ycombinator.com/item?id=22089814 https://news.ycombinator.com/item?id=22089814 ----- But yes I will prioritize finishing the series since you reminded me of it :) I managed to get 7 posts this month but then I went back to coding. Thanks for the encouragement!
- theamk 7y agoThis feels great until your program reaches some complexity threshold and you start hitting core limitation of the shell execution model. Then you have to use high-numbered file descriptors, named temporary files, PIPESTATUS, etc... - and your neat programming model becomes ugly and full of hacks. Sometimes shell is really the best even for complex stuff - for the example in initrd or during machine provisioning - but in most cases, having any sort of non-trivial flow control in shell is a bad idea.
- enriquto 7y ago> any sort of non-trivial flow control in shell is a bad idea. It is often a bad idea in other programming languages also. Yet, some complex control flow constructs are straigthforward in shell but very difficult in other languages. How do you ls *.jpg | grep 2019 | while read x ; do echo convert ... $x album/$x done | xargs -L 1 -P 32 in javascript or python, for example?
- jstimpfle 7y agoWow, there are 7 ways this can easily fail, and the script might not even notice. How do you write in a normal language? With roughly 3 times the amount of keystrokes, but in a much more robust way. And if something fails, you will actually get a Python exception.
- enriquto 7y agoIf I understand correctly, the whole point of Oil is to make a shell in which this kind of code is perfectly correct and robust.
- chubot 7y agoYes exactly, see my sibling response. This is a perfect use case for the "xargs $0 dispatch" pattern I mentioned, and maybe I will use it in that blog post. Your example does have some quoting problems which is understandable / common, but in Oil the obvious way should be the right way. That's not true in shell! https://news.ycombinator.com/item?id=22161847 https://news.ycombinator.com/item?id=22161847 Thanks again for the encouragement!
- braindeath 7y ago> Afterwards, you will start to see the shell as a glorious, essential element of our civilization, worth of respect and deserving our careful attention. Nah. There should be (probably is) a term for the phenomenon/trope where you can take something that was not carefully designed in the first place (like basically all of Unix) and then down the line you can hyper-analyze the hell out of certain bits of it and wax poetic about the few elegant bits that are inevitably there (even BASIC will work, yes) - while conveniently ignoring the whole is still a steaming pile. Lord knows that's what happened with "Unix" starting in the 90s, and Javascript in the 2000s.
- modo_mario 7y ago>Lord knows that's what happened with "Unix" starting in the 90s, and Javascript in the 2000s. What do you mean with this bit?
- jacobush 7y agoUnix: a shift from the pragmatic view that Unix is 80% nice and "worse is better" to a mystic longing for a time when everything was a file and you could compose things from well understood utilities which did one thing. (Which never existed, that dream was Plan9.) Javascript: the idea that it's actually a nice language anyone should use except under duress.
- ailideex 7y ago> something that was not carefully designed in the first place (like basically all of Unix) While I would generally agree that the Unix shell language (of which bash is a superset) and the bash language itself is not the most elegant and well designed things in the world - and that it should be used in a limited way and there are better options in most cases - I do have to say that to me at least it is significantly better than PowerShell which, while it clearly had a lot of design work put into it, seemed to have been designed by someone who has never used a shell or a terminal and maybe only had some limited interaction with a computer of any kind.
- pjmlp 7y agoNot really, REPLs (all the way back to the first Lisp environments) are much more than most shells born on UNIX. Even the best ones like Fishshell, are somehow pale to the scripting environment from Lisp Machines/Interlisp-D, Smalltalk transcript, XDE and Oberon UI scripting. Function composition, interoperability with the OS APIs, inline display of graphics and data-structures, and just-in-time debugging. That is how it should be.
- Grumbledour 7y agoQuestion is, how do we get there today? And XDE? I haven't heard of that one. Could you give me some pointers, please?
- pjmlp 7y agoWe get there by not placing UNIX in a pedestal, being open minded and appreciate the dedication of several people that keep doing the thankless work to digitize the history of computing. XDE was the developer environment for the Mesa programming language on Xerox Alto. https://en.wikipedia.org/wiki/Mesa_(programming_language) https://en.wikipedia.org/wiki/Mesa_(programming_language) https://archive.org/details/bitsavers_xeroxxdeXDDEConceptsandPrinciplesSep85_6240532/mode/2up https://archive.org/details/bitsavers_xeroxxdeXDDEConceptsan... When Mesa evolved into Mesa/Cedar, it got further improved. https://archive.org/details/bitsavers_xeroxparcteCedarProgrammingEnvironmentAMidtermRepo_13518000/mode/2up https://archive.org/details/bitsavers_xeroxparcteCedarProgra...
- Grumbledour 7y agoThanks, that looks really interesting! It seems, the Alto just keeps on giving and giving. Though if you don't know what you are looking for, that stuff can be really hard to find.
- pjmlp 7y agoIndeed, we were very lucky at my university, the CS library was full of gems like these.