~andyc/oil

dd9a2e8ac31ac9562fa165a6705654f707043b82 — Andy Chu 17 days ago eb9c60f
[oil-language] Get rid of True / False / None

More updates to the Oil vs. Python doc.
3 files changed, 53 insertions(+), 38 deletions(-)

M doc/oil-language-tour.md
M doc/oil-vs-python.md
M oil_lang/grammar.pgen2
M doc/oil-language-tour.md => doc/oil-language-tour.md +1 -5
@@ 587,7 587,7 @@ Let's go through Oil's Python-like data types and see the syntax for literals.

#### Null and Bool

JavaScript-like spellings are preferred for these three "atoms":
Oil uses JavaScript-like spellings these three "atoms":

    var x = null



@@ 597,10 597,6 @@ JavaScript-like spellings are preferred for these three "atoms":
      echo 'yes'
    }  # => yes

For compatibility with Python, you can also use `None`, `True`, and `False`.
But that breaks the rule that types are spelled with capital letters (e.g.
`Str`, `Dict`).

#### Int

There are many ways to write integers:

M doc/oil-vs-python.md => doc/oil-vs-python.md +48 -27
@@ 21,13 21,13 @@ Language](oil-language-tour.html).
### Same as Python

- Integers: `123`, `1_000_000`, `0b1100_0010`, `0o755`, `0xff`
- Floats: `1.023e6` (not in V1 of Oil)
- Floats: `1.023e6` (not in the first cut of Oil)
- Lists: `['pea', 'nut']`

### Changed

- Booleans and null: `true`, `false`, and `null` are preferred, but `True`,
  `False`, and `None` are accepted for compatibility.
- `true`, `false`, and `null` (like JavaScript) rather than `True`, `False`,
  and `None` (like Python).  In Oil, types are spelled with capital letters.
- String literals are like **shell** string literals, not like Python.
  - Double Quoted: `"hello $name"`
  - Single quoted: `r'c:\Program Files\'` 


@@ 35,7 35,7 @@ Language](oil-language-tour.html).
    - Unicode literals are `\u{3bc}` instead of `\u03bc` and `\U000003bc`
- Dicts: use **JavaScript** syntax, not Python
  - Unquoted keys: `{age: 42}`
  - Bracketed keys: `{[myvar + 1]: 'value'}
  - Bracketed keys: `{[myvar + 1]: 'value'}`
  - "Punning": `{age}`

### New


@@ 44,13 44,16 @@ Language](oil-language-tour.html).
  - Unicode `\u{03bc}`
  - Backslash: `\n`  `\\`  `\'`
  - Pound `#'a'`
- `%symbol` (used in eggex now, but could also be used as interned strings)
- Shell-like list literals: `%(pea nut)` is equivalent to `['pea', 'nut']`
- Unevaluated expressions
  - Block `^(ls | wc -l)`
  - Unevaluated expression: `^[1 + a[i] + f(x)]`
  - Arg list: `^{42, verbose = true}`

<!--
`%symbol` (used in eggex now, but could also be used as interned strings)
-->

### Removed

- No tuple type for now.  We might want Go-like multiple return values.


@@ 63,16 66,26 @@ Language](oil-language-tour.html).

## Operators

### Note: Oil Does Less Operator Overloading

Oil doesn't overload operators as much because it often does automatic string
<-> int conversion (like Awk):

- `a + b` is for addition, while `a ++ b` is for concatenation.
- `a < b` does numeric comparison (with conversion).  `cmp()` could be for
  strings.

### Same as Python

- Arithmetic `+ - * / **`
- Arithmetic `+ - * /`, and `**` for exponentiation
- Comparison `< > <= =>`
- Bitwise `& | ~ ^`
- Logical `and or not`
- Ternary `0 if true else 1`
- Ternary `0 if cond else 1`
- Indexing: `s[i]` evaluates to an integer?
- Slicing: `s[i:j]` evaluates to a string
- Equality `== != in  not in`
- Equality `== !=`
- Membership `in  not in`
- Function Call: `f(x, y)`
  - What about splat `*` and `**`?



@@ 82,7 95,7 @@ Language](oil-language-tour.html).

### New

- Regex match: `s ~ /d+/`
- Eggex match `s ~ /d+/`
- Glob match `s ~~ '*.py'`
- Approximate Equality `42 ~== '42'`
- Oil sigils: `$` and `@`


@@ 90,42 103,50 @@ Language](oil-language-tour.html).

### Removed

- I removed slice step syntax `1:5:2` because `0::2` conflicts with
  `module::name`.  This was only necessary for Tea, not Oil.
- No string formatting with `%`.  Use `${x %.3f}` instead.
- No `@` for matrix multiply.
- I removed slice step syntax `1:5:2` because `0::2` conflicts with
  `module::name`.  This was only necessary for Tea, not Oil.

<!--
Do we need `is` and `is not` for identity?
-->

### Notes
## Oil vs. JavaScript

Oil doesn't overload operators as much, and does string <-> int conversion:
- Oil uses `==` and `~==` for exact and type-converting equality, while JS uses
  `===` and `==`.
- `mydict->key` instead of `mydict.key`.  We want to distinguish between
  attributes and keys (like Python does).
- Where Oil is consistent with Python
  - Oil expressions use `and or not` while JS uses `&& || !`.  In shell, `&& ||
    !` are already used in the command language (but they're somewhat less
    important than in Oil).
  - Oil's ternary operator is `0 if cond else 1`, while in JS it's `cond ? 0 :
    1`.
  - Precedence rules are probably slightly different (but still C-like), and
    follows Python's grammar
- Same differences as Oil vs. Python
  - `s ++ t` for string concatenation rather than `s + t`
  - Shell string literals rather than JS string literals

- `a + b` is for addition, while `a ++ b` is for concatenation.
- `a < b` does numeric comparison (with conversion).  `cmp()` could be for
  strings.
## Semantics

## Semantic Differences
Oil's syntax is a mix of Python and JavaScript, but the **semantics** are
closer to Python.

### Differences vs. Python

- Iterating over a string yields code points, not one-character strings.
  - `s[i]` returns an integer code point ("rune").
  - TODO: maybe this should be `runeAt()` and `byteAt()`?
- Bools and integers are totally separate types.  Oil is like JavaScript, where
  they aren't equal: `true !== 1`.  In Python, they are equal: `True == 1`.
- No "accidentally quadratic"
  - No `in` for array/list membership.  Only dict membership.
  - The `++=` operator on strings doesn't exist.
- Bools and integers are totally separate types.  Oil is like JavaScript, where
  they aren't equal: `true !== 1`.  In Python, they are equal: `True == 1`.

## Related Links

- [Issue 835: Make expression language compatible with Python](https://github.com/oilshell/oil/issues/835)

## TODO

- Test out `%symbol`
- `100 MiB`?  This should be multiplication?
- All the unevaluated expressions


- Unevaluated Expr, Block, ArgList

M oil_lang/grammar.pgen2 => oil_lang/grammar.pgen2 +4 -6
@@ 92,19 92,17 @@ atom: (
    # NOTE: These atoms are are allowed in typed array literals
  | Expr_Name | Expr_Null | Expr_True | Expr_False 
    # TODO: Allow suffixes on floats and decimals?
    # You could frame it as multiplication, so 100 M is 100 * M, where
    # M = 1_000_000
  | Expr_Float | Expr_DecInt | Expr_BinInt | Expr_OctInt | Expr_HexInt 

  | Char_OneChar  # char literal \n \\ etc.
  | Char_UBraced  # char literal \u{3bc}
  | Char_Pound    # char literal #'a' etc.

    # TODO: Expr_Symbol for %mykey
  | Char_Pound    # char literal #'A' etc.

  | dq_string | sq_string
    # Expr_Symbol could be %mykey
    
		# TODO: Char_OneChar like \n, and Expr_CharLiteral #'a' (up to 4 
		# utf-8 encoded bytes, which are decoded into an integer!)

  | sh_command_sub | braced_var_sub | simple_var_sub
  | sh_array_literal
    # Anonymous function.  Is this only in Tea mode?