Why Sponsor Oil? | source | all docs for version 0.15.0 | all versions | oilshell.org
Almost all syntax in Oil comes from another language. This doc lists some of those influences.
It's mostly trivia for the curious, but it may help you remember the syntax.
At a high level, Oil is a bash-compatible shell language that adds features from popular dynamic languages.
Its design is more conservative than that of other alternative shells. Our goals are to:
The command and word syntax comes from shell:
ls | wc -l # pipeline
echo $var "${var} $(hostname)" # variable and command sub
echo one; echo two # sequence of commands
test -d /tmp && test -d /tmp/foo # builtins and operators
Oil's own shell-like extensions:
echo $[42 + a[i]] # Expression substitution
echo $strfunc(x, y) # Inline Function Calls
We implement many bash semantics, like "named references" for out variables:
f() {
local -n out=$1 # -n for named reference
out=bar
}
myvar=foo
f myvar
echo $myvar # prints "bar"
But clean up the syntax:
proc f(:out) { # "out param" declared with :
setref out = 'bar'
}
var myvar = 'foo'
f :myvar # caller prefixes the var name with :
echo $myvar # prints "bar"
Oil's expression language is mostly Python compatible. Expressions occur on
the RHS of =
:
var a = 42 + a[i]
var b = fib(10)
var c = 'yes' if mybool else 'no'
Proc signatures resemble Python:
proc mycopy(src, dest='/tmp') { # Python-like default value
cp --verbose $src $dest
}
Differences:
Oil uses JavaScript's dict literals:
var d1 = {name: 'Alice', age: 10} # Keys aren't quoted
var d2 = {[mystr]: 'value'} # Key expressions in []
var name = 'Bob'
var age = 15
var d3 = {name, age} # Omitted values taken from surrounding scope
Blocks use curly braces, so most code resembles C / Java / JavaScript:
if (x > 0) {
echo 'positive'
} else {
echo 'zero or negative'
}
var i = 5
while (i > 0) {
echo $i
setvar i -= 1
}
Oil has Ruby-like blocks:
cd /tmp {
echo $PWD # prints /tmp
}
echo $PWD
proc foo(x, &block) { run(block) }
var myblock = &(echo $PWD)
(Julia has something like blocks too.)
The :out
syntax for references to variable names also looks like Ruby (and
Clojure):
read :line # populate $line variable
push :myarray one two three # append to array
The @
character comes from Perl (and PowerShell):
var myarray = %(one two three)
echo @myarray # @ is the "splice" operator
echo @arrayfunc(x, y)
for i in @(seq 3) { # split command sub
echo $i
}
Perl can be viewed as a mixture of shell, awk, and sed. Oil is a similar agglomeration of languages, but it's statically parsed.
Multiline strings in Oil use similar whitespace stripping rules:
proc p {
# Because leading and trailing space are stripped, this is 2 lines long
var foods = '''
peanut
coconut
'''
}
Oil gets its regex match operator from Awk:
if (mystr ~ /digit+/) {
echo 'Number'
}
(We don't use Perl's =~
operator.)
Features influenced by these languages are planned, but not implemented.
Oil uses proc
and setvar
, which makes it look something like Tcl:
proc p(x) {
setvar y = x * 2
echo $y
}
p 3 # prints 6
But this is mostly superficial: Oil isn't homoiconic like Tcl is, and has a detailed syntax. It intentionally avoids dynamic parsing.
However, Data Definition and Code Generation in Tcl (PDF) shows how Tcl can be used a configuration language:
change 6/11/2003 {
author "Will Duquette"
description {
Added the SATl component to UCLO.
}
}
Oil's blocks would allow this to be expressed very similarly:
change 6/11/2003 {
author = "Will Duquette"
description = '''
Added the SATl component to UCLO.
'''
}
(This mechanism is still being implemented.)
PHP has global variables like _REQUEST
and _POST
.
Oil will have _argv
, _match()
, _start()
, etc. These are global variables
that are "silently" mutated by the interpreter (and functions to access such
global data).
Oil also uses a leading =
to print expressions in the REPL.
= 1 + 2
Lua's implementation as a pure ANSI C core without I/O was also influential.
Oil also uses ++
to concatenate strings and lists:
mystr = a ++ b
mystr = "$a$b" # very similar
mylist = c ++ d
mylist = %( @c @d ) # also converts every element to a string