wiki/structured/lang.oil.org

174 lines
5.6 KiB
Org Mode
Raw Normal View History

#+title: Oil shell
#+date: "2021-05-09 16:40:50 +08:00"
#+date_modified: "2021-06-14 22:26:24 +08:00"
#+language: en
2021-06-06 06:09:23 +00:00
#+property: header-args:oil :eval no
2021-06-05 00:32:50 +00:00
For future references, this note mainly notes Oil v0.8.11 and later versions.
2021-06-06 06:09:23 +00:00
Also, we'll be comparing to Bash shell (src_bash[:eval yes :results output]{bash --version}) as it is the most popular shell on the Unix world.
* What is Oil shell?
2021-06-05 00:32:50 +00:00
Ripping off from the [[https://www.oilshell.org/blog/2020/01/simplest-explanation.html][explanation page]]:
#+begin_quote
Oil is also aimed at people who know say Python or JavaScript, but purposely avoid shell.
#+end_quote
A modern shell attempting the replace Bash slowly.
The project has an ambitious goal with a wide scope.
2021-06-05 00:32:50 +00:00
It is known for its [[https://oilshell.org/blog][shell-oriented blog]] and the developer is very responsive and active with shell-related posts.
While there are multiple components in this project, we're focusing on two: *OSH and Oil shell*.
- *OSH is the bridge between Bash and Oil.*
It aims to be the most Bash-compatible shell that you can run most Bash scripts just fine.
The point of this component is improving what's under the hood, imposing sensible defaults on them, and getting a wide reach since Bash is the most popular shell.
While it may not run every Bash script in existence, the other point is to require minimal rewrites to run it with OSH.
- *Oil shell is the modern replacement of Bash* from its syntax and behavior.
It aims to be the shell for people familiar to Python, Ruby, JavaScript, and the like.
This is the other side of the bridge that OSH aims to reach.
2021-06-05 00:32:50 +00:00
* Overview of the Oil language
Oil is an entirely new programming language built from scratch.
It adds a hint of familiarity with Bash and takes a big queue of Python.
The following block should be sufficient for jogging your memory and a quick glance of what Oil is all about.
#+begin_src oil
var title = "Catenbury's Tale"
setvar title = "MS Fnd in a Lbry"
var keywords = %("metadata" "information overload" "information retrieval")
push :keywords "information organization"
var metadata = {}
setvar metadata['author'] = "Hal Draper"
setvar metadata['year'] = 1961
proc kebab_case(word) {
write -- $word | sed -E -e 's/./\L&/g' -e 's/s+/-/g' -e 's/[^.a-z0-9-]//g' -e 's/-+/-/g'
}
var title_slug = $(kebab_case $title)
{
var keywords = %("alternate universes" "aliens" "spaceships")
for i in @keywords { echo "keyword: $i" }
}
for i in @keywords { echo "keyword: $i" }
#+end_src
2021-06-06 06:09:23 +00:00
** Strings
While strings are similar to Bash strings[fn:: Really more like Python strings.], there are subtle differences.
2021-06-06 06:09:23 +00:00
Most notably, Bash splits the string when trying to do something.
#+begin_src bash
d='echo 3'
e='echo "The quick brown fox jumps over the lazy dog."'
parallel -- $d $e
#+end_src
It should throw an error because =parallel= interprets it as if it has 4 arguments due to the splitting — i.e., ~parallel -- echo 3 echo "The quick brown fox jumps over the lazy dog."~.
The solution here is to quote the variables in evaluation (e.g., ~parallel -- "$d" "$e"~).
Compare that to Oil...
#+begin_src oil
var d = 'echo 3'
var e = 'echo "The quick brown fox jumps over the lazy dog."'
parallel -- $d $e
#+end_src
If you want splitting, you could use =split= Oil function — e.g., ~@split(array_var)~.
2021-06-05 00:32:50 +00:00
** Arrays
Arrays are mostly similar to Bash arrays except you have more options.
- You can create a heterogenous list containing different types of data — e.g., ~var a = ['Dogs', 24, true ]~.
Useful for JSON compatability.
- A homogenous array is useful for data consistency.
It can accept a list of data of the same type — e.g., ~var b = %("foo" "bar" "baz")~.
You can iterate through an array with a loop.
#+begin_src oil
for i in @a { echo "word: $i" }
#+end_src
You can also add an item to the array with =push= keyword.
#+begin_src oil
push :a "biz"
# The expression mode equivalent
# You can also append associative arrays due to the expressiveness of the mode
_ a.append("biz")
#+end_src
2021-06-06 06:09:23 +00:00
** Conditionals
#+begin_src oil
# Ternary conditionals
echo $['dogs' if dogs == 'cute' else 'cats']
# If-else statements
if (4 == 5) {
echo "Alright, this is true."
} elif (1 > 5) {
echo "Another condition?"
} else {
echo "It seems you got me."
}
#+end_src
2021-06-05 00:32:50 +00:00
* Expression and command mode
2021-06-05 00:32:50 +00:00
- There are different ways [[https://www.oilshell.org/release/latest/doc/syntactic-concepts.html][how Oil can create an expressive language with the shell]].
It can parse different sublanguages with different lexer modes.
But there are dominantly two modes to keep in mind: expression and command mode.
2021-06-05 00:32:50 +00:00
- simply put:
+ *command mode is similar to Bash expressions*
+ *expression mode is akin to Python expressions*
2021-06-05 00:32:50 +00:00
- The addition of a Python-like expressiveness is how Oil can make a rich scripting exprience.
2021-06-05 00:32:50 +00:00
- command mode is what you see most of the time
- expression mode is activated when:
+ right-hand side of === — e.g., ~var a = 234~
+ the =_= keyword where output will be ignored — e.g., ~_ a.append(b)~
+ the === command where it will print the results — e.g., ~= 53~
+ you can interpolate expression mode expressions with =$[]= — e.g., ~echo $[4 + 43 + a]~, ~echo $[len(ARGV)]~
+ in =if= statements — e.g., ~if (true) { echo "WHOA" }~
2021-06-06 06:09:23 +00:00
* Tips and tricks
- Oil seems to evaluate in applicative order, evaluating only when the conditions passed — e.g., ~echo $['' + null if null else 'EEEEHHH']~ should print =EEEEHHH=.
+ Just like most modern mainstream languages... nice.
- Two operands of different types are considered unequal — e.g., ~'4' == 4~.
+ You can use Python-like type conversions like =Int=, =Bool=, and =Str= — e.g., ~Int('4') == 4~.