Why Sponsor Oils? | blog | oilshell.org
After garbage collector progress in Oil 0.8.8, and addressing user feedback in the Oil 0.8.9, I started working on the Oil language again. For context, the language has only existed since 2019, despite the fact that the Oil project as a whole is 5 years old.
I ended up making rapid progress in several areas, and took notes on Zulip. This post expands on the thread Notes for Oil 0.9.0 (requires login).
I expect 0.9.0 to be one of the biggest releases ever!
Rather than fully explaining each feature, this post enumerates #blog-topics. Not all the work is done, but I want to broach these topics now so the code doesn't get too far ahead of the blog.
As always, feel free to ask questions in the comments.
The features in this section are mostly done, but still need user feedback.
Oil Has Python-Like Multi-Line Strings, But Enhanced Like Julia.
'''
and """
). I
mentioned this possibility in November's Proposed Changes to Oil's
Syntax.$var
interpolation is
allowed, and how whitespace is stripped.Oil Has a Lightweight Module System.
module
builtin. This feature is about organizing
code into files, rather than "modularity" per se. The natural unit of
composition in the Oil is still the proc
(shell function).runproc
builtin to help with the "task file" pattern.
(related to Shell Scripts Are Executable
Documentation).use
mechanism, but Oil's modules are built on top of source
. This
is better because any new feature must compose with all the old
features.module
mechanism can be statically
analyzed by tools for single-file deployment.I use the #real-problems tag to describe Oil's solutions to problems found "in the wild" (via user feedback and production code).
Relative Imports
$_this_dir
. For
details, see issue 587, and the linked Hacker News
complaint. (These
complaints are absolutely true and valid, but also feel like "groundhog
day".)Oil Fixes Shell's Error Handling. This post can start from my Hacker
News comment demonstrating
an old yet surprising "feature" of set -e
/ errexit
.
lobste.rs
have found these claims
offputting,
so I want to a good job of explaining it clearly.run
builtin was renamed to try
. It doesn't work like
try
/catch
, but I think try
suggests that the builtin is related to
error handling, unlike run
.Chris Siebenmann prolifically documents shell issues on his blog, a rich source of #real-problems.
run
builtin.shopt --set sigpipe_status_ok
, which is on in option group
oil:basic
.He also wrote that The Bourne shell and Bash aren't the right languages for larger programs, and I agree. Oil addresses all of his complaints, though it's not all documented:
dkms
(a program to manage Linux kernel modules) is a
4000-line shell script, which is hard to manage in a single file.$1
, etc., and I agree.test
and
expr
.Here's a 2008 post from Chris's blog saying essentially the same thing:
Unfortunately I don't think there's a really good Unix programming language to replace the Bourne shell, which is one of the reasons that writing programs in the Bourne shell remains so tempting.
So that's why I say that these posts feel like "groundhog day", despite being valuable and correct. Instead of documenting shell's limitations for future generations, we should fix shell. That's not easy, as it has to be done in a compatible way.
But this is the purpose of the Oil project! Below I mention A Tour of
Oil, which will show that Oil isn't encumbered by much legacy at all. (We
extend bash's
shopt
mechanism to achieve this.)
I want to take another stab at Python vs. Shell question in the Oil FAQ. It's a persistent question, and came up again in the HotOS Slack channel.
This short response that found some agreement, and I will incorporate it into the FAQ:
I would say the biggest misconception is that it's either/or. Python and bash go well together. The basic calculus is to write 200 lines of shell calling 200 line Python script, rather than 1000 lines of Python, and the whole thing runs faster.
The work in this section isn't done yet, but thinking about how to describe it is useful. I like documentation-driven development!
Shell is fundamentally string-based, which is error prone. Oil adds mechanisms to make this style correct. String safety is just as important than memory safety (which Rust has raised awareness of).
These mechanisms deserve a few pedagogical posts as background. Over years of professional programming, I've noticed that seemingly simple things like backslash escaping cause confusion in practice!
argv
array, e.g. using Python's
subprocess.call()
.'\''
trick.sh -c 'echo "$1"' dummy0 "$untrusted"
'\''
solution. I learned about this from contributor Greg Price a few years
ago!$$
, like Make.''
.&
and so forth.$[x]
and _ESCAPE
. Mentioned in the HotOS
notes.I mentioned this problem in Comments on Build Systems and CI Services, and I've made some progress recently.
I also call it the Shell-in-{YAML,Docker,systemd,Chef,Vagrant,Python} problem, and mentioned it at the end of my BayLisa 2019 Notes.
bin/oven
is a sandboxed interpreter that will evaluate Oil and
print JSON (which valid YAML), Ninja, and more. It's like
bin/oil
, but it can't do any I/O. It can't use the kernel at all..cows
file
extension; the config files should still end with .oil
.use dialect ninja
, which requires the "shvar"
_DIALECT=ninja
. A shvar is a dynamically-scoped variable that the
shell itself uses, akin to the boolean shopt mechanism. More on this
below.block_to_dict()
, block_source_code()
The declarative part of shell can be used for multiple purposes:
I started docs on these features and need to finish them:
The most important doc is:
I notice that I'm reusing shell mechanisms to turn OSH into Oil, like shopt
and source
. This is good because it keeps the language smaller.
These generic concepts/mechanisms are an orthogonal axis to features like the module system and declarative configuration. I want to explain:
shopt
and shvar
: Shell Options and "Stack-Oriented" Variables (similar to
dynamic scope)
shopt
: booleans like simple_word_eval
, which are organized into
groups like oil:basic
shvar
: I recently added this builtin, and I like how it didn't add very
much new to the execution model of shell!
IFS
, _DIALECT
, _ESCAPE
_status
aka $?
_this_dir
for relative imports (mentioned above)_buffer
for the new "builtin sub" featureappend
builtin vs append()
function
This post helped me write my TODO list:
$_this_dir
, which addresses
#real-problems.bin/oven
. This is the missing
"declarative part" of shell.When drafting this post, many other #blog-topics came up, like those related to distributed systems, #software-architecture and dev tools. I've moved those to the next post.
With apologies for these dense notes, let me know if you have questions!