Why Sponsor Oils? | source | all docs for version 0.21.0 | all versions | oilshell.org
The YSH expression language borrows heavily from Python. In fact, it
literally started with Python's Grammar/Grammar
file.
This doc describes the differences, which may help Python users learn YSH.
If you don't know Python, A Tour of YSH explains the language from the clean-slate perspective.
(TODO: A separate doc could compare commands/statements like for
and if
.)
YSH has dynamic types, much like Python. These are the main data types:
Null Bool Int Float List Dict
Quick example:
var x = null
var y = f(true, 42, 3.14)
var z = [5, 6, {name: 'bob'}]
Every data type can be written as a literal. Literals generally look like Python, so this section describes what's the same, and what's changed / added / and removed.
123
, 1_000_000
, 0b1100_0010
, 0o755
, 0xff
1.023e6
['pea', 'nut']
Atoms are true
, false
, and null
(like JavaScript) rather than True
,
False
, and None
(like Python).
Int
.String literals are like shell string literals, not like Python.
"hello $name"
r'c:\Program Files\'
$'line\n'
(TODO: change to J8 Notation)
\u{3bc}
instead of \u03bc
and \U000003bc
Dicts use JavaScript syntax, not Python syntax.
{age: 42}
{[myvar + 1]: 'value'}
{age}
Shell-like list literals: :| pea nut |
is equivalent to ['pea', 'nut']
"Quotation" types for unevaluated code:
^(ls | wc -l)
^[1 + a[i] + f(x)]
Units on number constants like 100 MiB
(reserved, not implemented)
global
and nonlocal
. (We would
prefer objects over closures.)enumerate()
, keys()
, values()
, and items()
.Like literals, YSH operators resemble Python operators. The expression 42 + a[i]
means the same thing in both languages.
This section describes what's the same, and what's changed / added / removed.
YSH doesn't overload operators as much because it often does automatic
Str
↔ Int
conversions (like Awk):
a + b
is for addition, while a ++ b
is for concatenation.
a < b
does numeric comparison, not lexicographical comparison of strings.
strcmp()
for strings.)Arithmetic + - * /
and comparison < > <= =>
. They also convert strings
to integers or floats. Examples:
'22' < '3'
is true because 22 < 3
is true.'3.1' <= '3.14'
is true because 3.1 <= 3.14
is true.Integer arithmetic: //
integer division, %
modulus, **
exponentiation.
Bitwise & | ~ ^ << >>
Logical and or not
Ternary 0 if cond else 1
Slicing: s[i:j]
evaluates to a string
Membership in
, not in
Identity is
, is not
Function Call: f(x, y)
=== !==
, because we also have ~==
.++
, not +
. Again, +
is always addition....
not *
: f(...myargs)
.s ~ /d+/
s ~~ '*.py'
42 ~== '42'
$
and @
mydict.key
as an alias for mydict['key']
%
. Use ${x %.3f}
instead. (unimplemented)@
for matrix multiply.1:5:2
because 0::2
could conflict with
module::name
(could be restored).This section may be useful if yo know JavaScript.
YSH uses ===
and ~==
for exact and type-converting equality, while JS
uses ===
and ==
.
Expressions are more like Python:
and or not
while JS uses && || !
. In shell, && || !
are already used in the command language (but they're somewhat less
important than in YSH).0 if cond else 1
, while in JS it's cond ? 0 : 1
.Same differences as above, versus Python:
s ++ t
for string concatenation rather than s + t
The runtime behavior of YSH is also similar to Python and JavaScript.
Bool
and Int
are totally separate types. YSH is like JavaScript, where
they aren't equal: true !== 1
. In Python, they are equal: True == 1
.
Strings are bytes, which may UTF-8 encoded, like Go. (In Python 3, strings are sequences of code points, which are roughly integers up to 221.)
We avoid operators that cause "accidentally quadratic" behavior.
in
on List
, since that's a linear search. Only in
on Dict
.++=
operator on strings.undefined
like JavaScript.