1. Hengist Podd
  2. entoli


# entoli

entoli (phonetic Greek) = command, instruct

## Examples

Turtle drawing:

  Pen down, move forward 100mm, turn left 90°, move forward 5.5cm, pen up.

Notification handler:

  When alarm rings: say “It's a beautiful morning!”, get up,
  make breakfast [coffee {milk: 5ml, sugar: none}, toast];
  eat {while: reading paper}, walk the dog 1.25km.

## About

An experimental end-user language design, stealing ideas on semantic simplicity
and syntactic friendliness from Logo and AppleScript respectively, while also
[hopefully] avoiding their various pitfalls and errors.

Entoli syntax captures most of the readability of AppleScript, most of the
writeability of Logo, and should support spoken input and output as well.

## Features (implemented/partially-implemented/TBC)

* Unary commands, with white space allowed in case-insensitive names and no
  explicit separators (e.g. parentheses) needed to distinguish [most] argument

    move forward 100
    write "Hello"

* More complex arguments can be passed as records (tuple values with optional
  labels), which are automatically pattern matched against handler's expected
  parameter requirements. The command:

    ask user {"Please enter a number:", as: 1 thru 10}

  will be dispatched to the following handler:

    to ask user {prompt: text, as: type, giving up after: optional seconds}: …

  and the `prompt`, `as`, and `giving up after` values matched, coerced, and
  bound to the new stack frame.

* Arguments are evaluated by the receiving handler, avoiding the need for
  special forms or lambdas in order to pass lazily-evaluated arguments:

    if {false, quit}

  (`if` is a command that evaluates its second `action` value only if its
  first `test` value evaluates to true.)

* English-like punctuation for separating commands:

  * commas separate multiple commands; periods terminate a list of commands:

      Foo, bar, baz.

  * semi-colons connect related commands, acting as "pipes" that pass the result
    of the first command as the first argument to the next, reducing the need
    for explicit nesting:

      Ask user {"Type a number:"}; prefix "You entered "; write {to: screen}.

* Few data types, e.g. integer, float, unit types, text, date, etc. are all
  represented by `text` values, which are in turn automatically annotated with
  additional coercion and constraint information as they are consumed:

    "Hello, World!"

* No variables. Values are added to a scope using the `store` command:

    store {42, in: current age}

  and retrieved by a command of the given name:

    current age
    -> 42

  with a convenient `NAME:VALUE` shorthand for write-once storage (constants):

    first name: "Bob"
    last name: "Smith"

* Homoiconic syntax, with the option to inject custom operators as syntactic
  sugar for existing commands:

    4 + 2 / 3

  is sugar for:

    '+' {4, '/' {2, 3}}

  (Single-quoting a token explicitly identifies it as a name, even when
  overloaded as an operator.)


    if 2 + 2 = 4 do
      say "Reality OK."
    done else do
      say "Must be a Monday!"

  is sugar for:

    'else' {left: if {test: '=' {'+' {2, 2}, 4}, action: (say "Reality OK.")},
            right: (say "Must be Monday.", quit {})}

  (`else` is an operator that evaluates its right operand only if the left
  operand returns `did nothing`; similar to Icon's success/failure mechanism.
  `do … done` is syntactic sugar for a block.)

* Other stuff, e.g. user documentation will be added directly to code as «...»
  annotations, and since code is data the whole lot can be introspected and
  manipulated by modern tooling (help systems, static checkers, autosuggest,
  autocomplete, autocorrect, etc). Incremental parsing should provide live
  syntax checking and auto-correct/user-prompt when errors or ambiguities are
  found. i.e. Fuzzy user input is accepted and embraced - the editor should
  assist the user in arriving at finished code that is canonically correct.

## Status

* Barely proof-of-concept; slowly progressing.

* Some parser bugs, changes, and TODOs not yet done.

* Swift-entoli bridging APIs still to be finalized; library glue generator
  to implement.