Oil Language Influences

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.

Table of Contents
General Philosophy
Major Influences
POSIX Shell
bash and ksh
Python
JavaScript
Ruby
Perl
Julia
Awk
make, find and xargs
Minor Influences
Tcl
PHP
Lua
Haskell

General Philosophy

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:

Major Influences

POSIX Shell

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

bash and ksh

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"

Python

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:

JavaScript

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
}

Ruby

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

Perl

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.

Julia

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
  '''
}

Awk

Oil gets its regex match operator from Awk:

if (mystr ~ /digit+/) {
  echo 'Number'
}

(We don't use Perl's =~ operator.)

make, find and xargs

Features influenced by these languages are planned, but not implemented.

Minor Influences

Tcl

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

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).

Lua

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.

Haskell

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

Generated on Sat Feb 19 18:43:17 EST 2022