# 

This file is automatically generated. _Do not edit._

Unknown Heading


### $$ - _function arguments pseudo-array_ - keywords - ^$$

Equivalent to Javascript’s `arguments` and can be used the same way.

    .. $$

Best to refer to good documentation on this elsewhere.



### INFINITY - _constant representing infinity_ - keywords - ^Infinity

Represents an infinitely large value.

    

Generally obtained by attempting to evaluate an expression with a divisor of zero.

    debug 1/0

    > Infinity



### Iterator - _name-of-the-Iterator method_ - keywords - ^Iterator

When creating an object you want to provide an invisible iterator for, use this keyword as the name of the
process.

    Iterator process (as [parameter list])
      [block]

This will be a little gritty, because ES6 is gritty. When you name an object process **Iterator** (note
the specific uppercase initial), the function won't be assigned to the object trait `object.Iterator`. Instead,
it will be assigned to `object[Symbol.iterator]`.

The bad news is that this means you can't specifically refer to that trait by name in SAI without
using the convoluted approach of `object[~Symbol.iterator]` (because **Symbol** is a global and globals
must use the global scoping prefix).

The good news is this means you probably won't ever *have to* refer to it by name, because all of SAI's
comprehensions, as well as the **iterate** statement, and ES6's `for-of` loop, all implicitly check for
the existence of the `Symbol.iterator` function and will use it if present.

    object Tally 1.0.0
    instance:
      bag empty
    Count task
      set bag[$] to (self default 0) + 1
    Iterator process
      each bag
        yield: key, it

    set inventory to create 'Tally'
    inventory.Count 'apple'
    inventory.Count 'banana'
    inventory.Count 'apple'
    iterate inventory
      debug it

    > [ 'apple', 2 ]
    > [ 'banana', 1 ]

In the example, when we **iterate** over `inventory`, a check is made to see if the object to iterate
has an **Iterator** process, which in this case it does, so it is called, and then iteration takes place
over the result. See the **iterate** construct for more on this.

Note that this sleight-of-hand doesn't apply to an object **task** (as opposed to **process**)
named "Iterator"; in fact SAI will not let you use that name for an object task, because doing so would
break expectations of what an iterator is supposed to do (e.g. yield things).  Gah, the cruft, it burns.



### NaN - _not-a-number_ - keywords - ^NaN

**NaN** (capitalization matters) means Not a Number.

    .. NaN

**NaN** is returned from some library calls on failure to convert a value into a
number.  (The **number** operator returns 0 instead.)

    debug ~parseInt('The one ring.')
    > NaN

    debug number 'The one ring.'
    > 0

The _only_ way to test for **NaN** is to use the **isNaN** operator.

    debug NaN = ~parseInt('The one ring.')
    > false  // !

    debug NaN is ~parseInt('The one ring.')
    > false  // !!!!

    debug isNan ~parseInt('The one ring.')
    > true



### ARRAY - _expression-oriented list literal_ - keywords - ^array

Used to specify the creation of a plain array of mathematical values; e.g. the result of a series
of expressions. As opposed to **list**, which is a plain array of bare literals.

    .. array [expr], [expr], ... (;)
    .. array
      [expr], [expr], ...
      [expr]
      ...

In general, the **colon** structure constructor will figure out what you want, but when you want
to be specific about creating an array of expressions, use **array**. Compare with **list**,
**fields** and **traits**.

Arrays may be specified on one line:

    debug array 1+1, 2*3, 'Fred'

    > [ 2, 6, ‘Fred’ ]

Or multiple lines in the form of an indented block:

    debug array
      width * ~Math.cos(angle)
      height * ~Math.sin(angle)

    > [  7.0710678118654755, 3.5355339059327373 ]

Or a combination of both:

    debug array
      1, 1, 2, 5
      14, 42, 132, 429
      1430, 4862

When using an array literal in an expression that might make the end of the array a matter of question, use a **semicolon** to close the array literal:

    debug array 5, 3, 2, 7, 4; has it%2

    > [ 5, 3, 7 ]

Or enclose the array in parenthesis:

    debug (array  4, 3, 2, 1) by it

    > [ 1, 2, 3, 4 ]

Arrays can be nested by use of either parenthesis or semicolons, or by using multiple levels of indent. Note that commas separate expressions on one line but are not included at the end of a line.

    debug array
      array 1, 2, 3;, array 4, 5, 6
      array
        7, 8, 9

    > [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ]



### AS - _pronoun renaming clause_ - keywords - ^as

As declares named locally scoped variables within a code block based on values passed into the block.
(In general, **as** is optional because one can usually access such passed-in values through pronouns.)

    .. [pipe operator] as var1, var2, etc...
    .. [construct] as var1, var2, etc...
    .. ( [expression] as var 1)

**As** can be used in conjunction with almost any SAI function that creates pronouns.  You use __as__ to
give those pronouns specific names, rather than the generic ones. Named pronouns are generally ephemeral.

    // incomplete list
    switch [expr] (as [trial var])
    catch (as [error var])
    if [expression] (as [trial var])
    exists [expression] (as [it var])
    with [expression] (as [it var])

An example of **if** value reclamation with **as**:

    if @keydown as charcode
      switch charcode
        case 27
          @Escape
        case 32
          @Continue

Every construct that can accept __as__ pronoun renaming will indicate this in the documentation.

#### as with iterators

    // incomplete list
    iterate [expr] (as [it var])
    each [expr] (as [it var] (, [key var] ) )
    ply [expr] (as [it ident] (, [key var] ) )
    count [expr] (as [counter var])

An example, renaming **it** and **key** in an each iterator:

    each friends first as value, field
      debug `${field}: ${value}

    > name: Sara
    > age: 23
    > cat: true
    > province: ON

#### as with comprehensions

    // incomplete list
    .. | by (as [a var], [b var] )
    .. | thru (as [it var] (, [key var] ) )
    .. | audit (as [it ident] (, [key var] ) )
    .. | into [expr] (as [sum var] (, [it var] (, [key var] ) ) )

An example, renaming **it** and **key** in the block handler of a **thru** comprehension:

    debug friends | thru as friend, index
      return `${index}) ${friend.name} lives in ${friend.province}

    > [ '0) Sara lives in ON',
        '1) Jon lives in QC',
        '2) Ellie lives in QC',
        '3) Marshal lives in ON',
        '4) Doug lives in ON',
        '5) Ann lives in QC',
        '6) Harry lives in QC',
        '7) Jenna lives in ON' ]

#### as parenthetic

    .. ( [expr] as [var] )

The parenthetic **as** assigns the value of the parenthesised expression to a named identifier. The assignment happens as soon as the parethesis is evaluated, so you can use the identifier in the same expression as the parenthetical, as long as the parenthetical is evaluated first.  _This is not a good style of coding_.

    set six to (1+2 as three)+three
    debug array three, six

    > [ 3, 6 ]



### BLANK - _an object with no traits_ - keywords - ^blank

The keyword **blank** creates a plain object with no traits.

    .. blank

It is the SAI equivalent of Javascript’s `{}`.

    set player to blank
    set player.age to 21
    debug player

    > { age: 21 }

Contrast __blank__ with __empty__.  A whiteboard can be blank; having nothing written on it.
You would not usually say it was empty.  While an array or a list is usually thought of as empty,
rather than blank.



### CHAIN - _verb chain initiation_ - keywords - ^chain

summary

    .. chain [expr]             // in an expression
      [comprehension/method]
      [comprehension/method]
      ...
    
    chain [expr]                // as a verb
      [comprehension/method]
      ...
    

The **chain** clause allows you to compose (string together) a series of operations that will
each be applied in turn to a value, object, collection or iterator.

**Chain** is another way of writing `value.method().method().method().method()` that offers cleaner
code and more possibilities. You start with an object, then apply a sequence of verbs to it. Each verb
is a new link in the chain.

    set mirror to task
      return chain $
        split ''
        reverse
        join ''
    debug mirror('A man, a plan, a canal, Panama!')

    > !amanaP ,lanac a ,nalp a ,nam A

In the previous case, each verb was a trait (a method) of the string itself.

You can also chain pipe operators:

      debug chain friends
        | has .cat
        | by .name
        | thru 'My friend ${.name} likes cats.'

      > [ 'My friend Ann likes cats.',
      >   'My friend Jon likes cats.',
      >   'My friend Sara likes cats.' ]

And because one of the pipers is **set**, you can actually chain any function at all.

    set double to task
      return chain empty
        concat $
        concat $

    debug chain fruit
      | set double(it)

    > [ 'Apple',
        'Banana',
        'Citron',
        'Apple',
        'Banana',
        'Citron' ]

Functions you use in **chain** typically return a value; this is used as the object to pass to
the next link in the chain. However, some methods and functions don't return a value, instead
modifying their context in-place. If a function returns **undefined**, **chain** will reuse the
previous object for the next call.

_Be careful: some built-in methods return unexpected values that can foil **chain**.
For example, **Array.push** is very irritating for this; you cannot chain **.push** because it
returns the new array length instead of either the array or **undefined**._

#### chain as a verb

You can also use `chain` as a verb, that is, at the beginning of a line. This is useful when the
end result of the chain isn't useful but the intermediate results are, which can often be the case
when parsing data.

    set population empty
    chain friends
      audit
        inc population[.province] to (self default 0) + 1
    debug population

    > [ ON: 4, QC: 4 ]

Arguably it might be better to code this particular example with a discrete iterator statement
like `ply`, but not every use case is as trivial as this example.

_Note: If you use chain as a verb in this way, and the final result of the chain is a generator,
it will be drained automatically._ Otherwise, the code within the chain may never be executed,
because without a drain, generators do nothing.



### CONTRACT - _requirements for child objects_ - keywords - ^contract

When defining an object, **contract** is used to specify tasks or traits that _children_ inheriting
from this object are intended to implement.

    contract:
      [task/trait name]
      [task/trait name]
      ...

Inheriting from an object that has contracts, and then not providing implementations for those contracts,
will result in a SAI exception.

    object fruit
    contract:
      Consume

    object apple
    inherit:
     fruit
    Consume task
      debug 'You ate an apple.'

    object pear
    inherit:
      fruit

    > exception thrown: “SAI: Contractually required task ‘Consume’ does not exist in object ‘pear’.”



### DEC - _decrement verb_ - keywords - ^dec

Decrements (reduces by 1) the value in the given variable.

    dec [var]

Example:

  set a to 2
  dec a
  debug a

  > 1



### DELETE - _a verb that deletes variables_ - keywords - ^delete

summary

    delete [variable]

When called on a variable or traits, undefines the named variable or attribute(s) of a variable.

    delete thisUnwantedValue
    delete goodObject.unwantedAttribute

This just calls the underlying Javascript version of **delete**, with all the same rules and caveats.

#### delete pipe operator

The __delete__ pipe operator has advanced functionality, which see.



### EMPTY - _an array with no items_ - keywords - ^empty

A literal value indicating an empty list/array.

    .. empty

The equivalent of Javascript’s `[]`, **empty** creates an Array with no elements.

    debug empty
    debug empty.length

    > []
    > 0



### ENUM - _literal number enumeration_ - keywords - ^enum

A convenience tool for initializing objects with sequential values.

    fields [identifier] enum, ( [identifier] enum, ... )

When declaring a set of fields, specifies a value 1 higher than the value of the previous
definition. If there is no previous definition, 1.

  debug fields a enum, b enum, c 10, d enum

  > { a: 1, b: 2, c:10, d: 11}



### EXISTS - _check for undefined_ - keywords - ^exists

Returns true if the following expression is _not_ `undefined`.

    .. exists [expr]

These three comparisons test the same thing and have the same effect:

    if undefined isnt var
      ...
    if exists var    // unary operator
      ...
    exists var       // flow control construct
      ...

The unary operator can be used in expressions, e.g.

    unless exists .name and exists .age
      return: error "Name and age are required."



### EXPECTS - _runtime paramater type validation_ - keywords - ^expects

Used to check whether a function’s named parameters (or any arbitrary object) has certain
traits, and optionally if those traits are of a particular type.

    ... task/promise/process expects [rules definition]

When used as the clause in a **task**, **promise** or **process** function definition. **expects**
adds run-time parameter checking to the function, passing the first argument (the one that holds
named parameters) through an *expects check* based on the rules that follow. If any expectations
are not met, a runtime error is thrown.

Names appearing in **expects** clauses, and thus being used to check parameters, _must_ be
preceeded by **$**. This is intended as a reminder that *named parameters are always
referenced with the $ scoping operator*.

#### expects rules

Rules for **expects** take the form of a set of traits. Their names correspond to names of
traits that must be found in the expression under test. The value, if not _true_, is interpreted
as an object type; the trait must be of that type (or a child of that type).

Any violations to the rules in a function call results in an error being thrown describing the problem.

Here's an example:

    AddStudent task expects $name string, $age number
      @students.push copy $
    ..
    @AddStudent name 'Sally', age '12'

    > Error: SAI: parameter exception in AddStudent
    > age should be number, but it's string

Expects adds a small amount of overhead at runtime. My thinking is that it would be good for integration
testing but during a production build the checks would be commented out, like one might do with assertions.
This would be a nice option to add to the SAI compiler someday.



### FALSE - _boolean value false_ - keywords - ^false

This is the `false` value.

    .. false

The opposite of __true__.



### FIELDS - _structure literal_ - keywords - ^fields

Used to specify the creation of a plain object with a set of key/value pairs. (Contrast with **traits**.)

    .. fields [key] [expr], [key] [expr], ... (;)
    .. fields
      [key] [expr], [key] [expr], ...
      [key] [expr]
      ...

In general, the **colon** structure constructor will figure out what you want, but when you want to be
specific about creating a plain object with of keyed values & expressions, use **fields**. Compare
with **list**, **array** and **traits**.

The **key** is an identifying word or other string, specified without quotes (although quotes may be used
if desired/necessary). If a **#** preceeds the key (a hashtag), the key will be assigned a
value of **true**. The **expr** is any valid literal, variable, object or expression.

Fields may be specified on one line:

    fields name 'Sera', class 'Rogue', level 21, #focus

    > { class: 'Rogue', level: 21, name: 'Sera', focus: true }

Or multiple lines in the form of an indented block:

    fields
      x width * ~Math.cos(angle)
      y height * ~Math.sin(angle)

    > { x: 0.5, y: 0.866 }

Or a combination of both:

    fields
      str 16, dex 34, mag 14   // no comma at end of line
      con 42, wil 21, cun 45

    > { str: 16, dex: 34, mag: 14, con: 42, wil: 21, cun: 45 }

When using a fields literal in an expression that might make the end of the literal a matter of question,
use a **semicolon** to close the literal, or enclose it in parenthesis:

    fields x 5, y 4, z 3; thru it*2
    (fields x 5, y 4, z 3) thru it *2

    > { x: 10, y: 8, z: 6 }

Fields initializers can be nested by use of either parenthesis or semicolons, or by using multiple
levels of indent.



### GET - _dynamic object attribute_ - keywords - ^get

Declares a _getter_ for a dynamic object trait; that is, a trait that has a value that is only
calculated upon request.

    object [name] [version]
    
    [ident] get
      [code]
      return [value]
    ( set ( given [ident] )
      [code]

A brief example:

    object Vector2 1.0.0

    magnitude get     // dynamic getter for 'magnitude' trait
      return Math.sqrt(x*x + y*y)
    set given m       // dynamic setter for 'magnitude' trait
      set a to angle
      set x to m * Math.cos(a)
      set y to m * Math.sin(a)

You can have a getter without a setter, and a setter without a getter.

    documentation get
      return '''
        Lots of information about this object.

    tally set given token
      inc _tally	oken



### GIVEN - _parameter declaration and static values_ - keywords - ^given

Use __given__ to name the parameters to a function, and to define immutable traits.

    .. given p1, p2, p3 ...
    
      - or -
    
    [ object declaration ]
    given [definition of values]

To declare parameters:

    set [ident] (given [$ var]) // dynamic trait
    .. task (given [parameter1], [parameter2], ...)
    .. process (given [parameter1], [parameter2], ...)
    .. promise (given [parameter1], [parameter2], ...)

An example of parameter naming:

    set tally to blank
    set AddRow to task given item, quantity
      set tally[item] to (self default 0) + quantity

    AddRow 'socks', 3
    AddRow 'pants', 6
    debug tally

    > { socks: 3, pants: 6 }

#### given object constants

Defines immutable traits when declaring an object. These traits are assigned to the object prototype
itself and locked/frozen; they cannot be changed and yet are available in every instance of an
object. Givens are useful for static data.

    object Apple
    instance: varietal 'unknown'
    given: species 'M. domestica'
    Describe task
      return 'undefined var undefined
    ..
    set apple to create 'Apple'
    set apple.varietal to 'Macintosh'
    debug !apple.Describe
    > M. domestica var Macintosh

**Given** traits can only be changed/overridden through inheritance.

    object Crabapple
    inherit: Apple
    given: species 'M. coronaria'
    ..
    set specimen to create 'Crabapple'
    debug !specimen.Describe
    > 'M. coronaria var unknown'



### INC - _value increment_ - keywords - ^inc

Increments (adds 1 to) the given variable.

    inc [var]

As in:

    set a to 1
    inc a
    debug a

    > 2

The __inc__ statement has special behaviour around values that are _undefined_ or evaulate to _falsy_; when you increment one of these values, it becomes `1`.  For example:

    set a to undefined
    inc a
    debug a

    > 1

This is useful when tallying with an array, e.g. the following construct automatically initializes array elements the way the standard `++` operator does not, such that the `tally` object will contain a log of word usage.

    set tally blank
    every word
      inc tallyit

Note that __dec__ does not have similar initialization functionality.



### INHERIT - _class heritage specification_ - keywords - ^inherit

Specify inheritance during object definition.

    inherit:
      [classname]
      ...

An object can have multiple parents at each level of inheritance, as in the following example.

    object Licensed
    instance: licenseTag false
    ..
    object Passengers
    instance: paxCount 0
    contract: paxMaximum
    ..
    object Automobile
    inherit: Licensed, Passengers
    ..
    object Sedan
    inherit: Automobile
    instance: paxMaximum 6
    ..
    set myCar to create 'Sedan'
    debug myCar
    > { licenseTag: false, paxCount: 0, paxMaximum: 6 }

    debug myCar.isa
    > Sedan

    debug myCar.isof
    > { Licensed:
       { version: '0.0.0-unspecified',
         isa: 'Licensed',
         load: './sample/Keywords/Licensed.sai' },
      Passengers:
       { version: '0.0.0-unspecified',
         isa: 'Passengers',
         load: './sample/Keywords/Passengers.sai' },
      Automobile:
       { version: '0.0.0-unspecified',
         isa: 'Automobile',
         load: './sample/Keywords/Automobile.sai',
         inherit: [ 'Licensed', 'Passengers' ] },
      Sedan:
       { version: '0.0.0-unspecified',
         isa: 'Sedan',
         load: './sample/Keywords/Sedan.sai',
         inherit: [ 'Automobile' ] } }

Note the use of **contract** in the _Passengers_ object; this requires any child object to offer
a `paxMaximum` trait. Contracts can be fulfilled by class functions (**task**/**process**/**promise**),
class traits (**given**) or **instance** traits.



### INSTANCE - _object instance variable declaration_ - keywords - ^instance

Define initial values for an object’s traits.

    instance:
      [varname] [initial value]
      ...

When an object is created, instance traits are assigned the given values before the
object’s **Instantiate** task is called.

    object Sock 1.0.0

    instance:
      colour 'Brown'
      pattern 'Argyle'
      size 'M'
      kind 'dress'

    Instantiate task
      debug @ select list colour, pattern, size, kind

    ....

    set aSock to create 'Sock'
    > { colour: 'Brown', pattern: 'Argyle', size: 'M', kind: 'dress' }

Instance traits, when declared with __instance__ or __given__, do not need to have their scope
indicated with `@` when used in their own object. Said another way, declared instance variables
are automatically scoped to the object. This is similar to the way that __reference__ values
don't need to use the `~` global scoping prefix.

The following are equivalent:

    instance:
      x 0
      y 0

    ...

    set x 34
    set @x 34          // this is not necessary

When referring to another object's instance variables, you will need to properly scope them:

    CopyPoint given point
      set x to point.x
      set y to point.y

Instance variables cannot be initialized with functions or "complex" expressions. The compiler will
warn you about it. Nevertheless, you should still declare all instance variables, even if you must start
them with `undefined`. That's because the compiler looks at the instance variables you've declared to
know what your instance variables are.

    object AppleCrate

    instance:
      sku '448893003'
      label ~GetLabel(.sku)  /// this won't work, instead:


    instance:
      sku '448893003'
      label undefined

    Instantiate task
      set label ~GetLabel(.sku)



### .isa - _object name attribute_ - keywords - ^.isa

All prototyped SAI objects have an **isa** trait that identifies the object name.

    .. [object].isa

Further details about the object and its inheritance are found in the **isof** trait.

    object Fruit 1.0.0
    Instantiate task
      debug 'I am a ${isa}'

    set a to create 'Fruit'
    > I am a Fruit

    object Pear 1.0.0
    inherit: Fruit

    set b to create 'Pear'
    > I am a Pear



### LIST - _literal-based array construction_ - keywords - ^list

Used to specify the creation of a plain array of literal values.

    .. list [term], [term], ... (;)
    .. list
      [term], [term], ...
      [term]
      ...

As opposed to **array**, which is an array of mathematical expressions.

The following are acceptable terms:

    true or false
    number literal
    string literal quoted with ' or " or ` or '''
    unquoted bare string literal
       all characters available except } , ) ; | [cr]
       (note the comma, that will trip you up; comma separates terms)
    an equal sign (=) followed by an expression
    a nested definition starting with :, list, array, traits, or fields

Lists may be specified on one line:

    debug list Apple, Banana, Citron

    > [ 'Apple', 'Banana', 'Citron' ]

Or multiple lines in the form of an indented block, or a combination:

    debug list
      Vladimir, Estragon
      Pozzo, Lucky, The Boy

    > [  'Vladimir', 'Estragon', 'Pozzo', 'Lucky', 'The Boy' ]

When using a list literal in an expression that might make the end of the array a matter of
question, use a **semicolon** to close the array literal:

    debug list Vash, Spike, Jack, Cat thru '${it} the cat'
    > { 'Vash', 'Spike', 'Jack', 'Cat the cat' ] // undesired result

    debug list Vash, Spike, Jack, Cat; thru '${it} the cat' // with semicolon
    > [ 'Vash the cat', 'Spike the cat', 'Jack the cat', 'Cat the cat' ]

Or enclose the array in parenthesis:

    debug (list Vash, Spike, Jack, Cat).length
    > 4

Arrays can be nested by use of either parenthesis or semicolons, or by using multiple
levels of indent. Note that commas separate expressions on one line but are not
included at the end of a line.



### LOCAL - _locally scoped variable declaration_ - keywords - ^local

Create a local variable that exists only within the current level of indent (or deeper).
Uses Javascript's `let` declaration. (And this is the only construct in SAI that does so.)

    local [varname] to [expr]

Syntax identical to **set** however the variable created is limited to the current block in
scope. (Normally, variables are scoped to the object method they’re used in.) **Local** causes the
generated Javascript to declare variables with the `let` keyword.

Javascript's scoping around global/local variables can be tricky and has caught even experienced
programmers multiple times.

**Local** allows you to do dumb things like this:

    set a 1
    if a is 1
      local a 2
      debug a
    debug a

    > 2
    > 1

In general, SAI is designed such that you should only very rarely need __local__ variables.



### MAIN - _indicates object should be instantiated at runtime_ - keywords - ^main

When using the compiler, native Javascript files of objects created with **main** will automatically
instantiate a single copy of the object when the file is required.

    object [objectname] main [objectversion]

In other words, when the `.js` file is required, in addition to defining a prototype, an object is
also instantiated (which causes any **Instantiate** task to run, thus conceivably launching a program).

Main also sets a flag in the **isof** property of the object, indicating it is the main object.

Have a look at the `bin` folder for `runner.sai` which uses the __main__ keyword to indicate it is
a program that should be run rather than just an object prototype.



### NOP - _no-operation statement_ - keywords - ^nop

No operation; no data; do nothing.

    nop

This statement (or one like it) is necessary as a syntactical placeholder when a white-space
indent is expected but you do not wish to put code in it.

    if x>26
      nop
    elsif x>13
      set x - 13
    elsif x>0
      set x + 13



### NULL - _a value that is no value_ - keywords - ^null

An empty value.

    .. null

Null is:

  - _falsy_
  - not `undefined`

I don’t have any example code for this.



### OBJECT - _object declaration_ - keywords - ^object

Begins the definition of an object.

    object [identifier] (main) [version]
    ...

Only one object definition is permitted per file.

In an object definition, the following sections are supported. See each keyword for more details.
Also review the _Defining an Object_ document.

    reference:
      [globally defined references]

    object [identifier] (main) [version]

    inherit:
      [list of objects to inherit from]

    contract:
      [list of traits that child objects must provide]

    given:
      [declaration of immutable object traits]

    instance:
      [declaration of initial trait values for each instance]

    get [trait name to implement dynamically]
      [code]
    set given [value]
      [code]

    [name] task/process/promise
      [code that implements this task/process/promise]

When a SAI object is created, the **Instantiate** task is executed on that obejct, allowing you to
perform instance-level initialization code. Notice the caps; by convention SAI methods are
capitalized, while attributes are lowercase.

If the **main** clause is included, the object is marked to be instantiated automatically when a
compiled `.js` version of the object is required. See **main** for slightly more detail.



### ORPHAN - _rescoping this_ - keywords - ^orphan

**Orphan** causes the __@__ scoping prefix within the function to refer to the context
of the function call, instead of the context of the function definition.

    orphan  
    

You probably want to use this in combination with **local** variable definitions.

For clarifications and example code on this, see **task**.

To do this on a case-by-case basis, use the __@@__ scoping prefix (which see).



### PROCESS - _generative function definition_ - keywords - ^process

Creates a function that is expected to **yield** one or more values.

    [identifier] process ( as [parameter list] )
      [yielding code block]
    
    .. process ( as [parameter list] )
      [yielding code block]

This is an ES6 feature. **Process** does exactly the same thing as **task** except the generated code
uses `function*` instead of `function`.

If you're not familiar with generators/yielding, here is a very simplified overview.

  set Candidates to process
    count 1 to 100 as x
      count 1 to 100 as y
        if 1<x and x<y and x+y<100
          yield: x x, y y, s x+y, p x*y

The Candidates process, when invoked, runs all of the code in the process up until the
first **yield**, then returns, handing you a process object, here stored in the variable `iter`:

  set iter Candidates()

That object is an _iterator_; it is a stateful representation of a `Candidates` process.
Each time you call a process, you get a new iterator. Once you have an iterator, you can _iterate_
through it. Each iteration returns the next value _yielded_ by the process.

Iteration takes place by calling the **.next** task on the iterator.

    debug iter.next()

    > { value: { x: 2, y: 3, s: 5, p: 6 }, done: false }

You can see that **.next** returns a simple object with two fields, **.value** and **.done**.
(In our iterator, the value is the first qualified candidate represented by a simple object with
four fields: x, y, s and p.)

**.value** holds whatever was **yield**ed. **.done** is a boolean flag that indicates whether the
iteration is complete; that is, whether another call to **.next** would result in a newly generated value.

Each time you call **.next** you will get a new value.

    debug iter.next()
    debug iter.next()
    debug iter.next()

    > { value: { x: 2, y: 4, s: 6, p: 8 }, done: false }
    > { value: { x: 2, y: 5, s: 7, p: 10 }, done: false }
    > { value: { x: 2, y: 6, s: 8, p: 12 }, done: false }

Here is a bit of code that will keep calling **.next** until the **.done** flag is set, saving
the result in a four item list.

    set cache to empty            // empty array
    dountil result.done           // check .done at the end of each loop
      set result iter.next()      // next iteration to result
      cache.push result           // save result in cache
    debug cache | limit -4        // print last four rows

    > [ { value: { x: 48, y: 50, s: 98, p: 2400 }, done: false },
        { value: { x: 48, y: 51, s: 99, p: 2448 }, done: false },
        { value: { x: 49, y: 50, s: 99, p: 2450 }, done: false },
        { value: undefined, done: true } ]

Once the **.done** flag is set, the iterator is said to be _exhausted_. Notice that **.value** is
*undefined* when the **.done** flag is set.

Processes, generators and iterators are very powerful tools because they allow computations to be
*lazy*, that is, for data to be generated only as it is needed, thus vastly reducing memory
requirements. (The Python language is very useful for scientific computing because it is a primarily
lazy language because large data sets can be manipulated with modest resources.)

SAI has many affordances for processes and iterators, including native support with all
comprehensions. As a very simple example, all of the above code could be replaced with this
simple expression:

    debug Candidates() | limit -4

    > [ { x: 48, y: 49, s: 97, p: 2352 },
        { x: 48, y: 50, s: 98, p: 2400 },
        { x: 48, y: 51, s: 99, p: 2448 },
        { x: 49, y: 50, s: 99, p: 2450 } ]

 (Notice how the limit comprehension itself deals silently with **.next** and **.done**, and
 automatically gives you just a list with only the **.value** of each iteration.)



### PROMISE - _declare a Promise-producing function_ - keywords - ^promise

Wraps the code block in a Promise-like function shell.

    object
    [identifier] promise ( as [parameter list] )
      [code block]
    
    .. promise ( as [parameter list] )
      [code block]

Along with **resolve** and **reject**, forms a convenient bit of syntactic sugar for making
Promise-like functionality.

Here is some sample code:

    set
      willIGetNewPhone promise given isMomHappy
        if isMomHappy
          resolve:
            brand 'Wangdoodle'
            colour 'paisley'
        else
          reject new ~Error 'Mom is not happy.'

      showOff promise given phone
        with phone
          debug 'Hey friend, I have a new ${.colour} ${.brand} phone'

      askMom task given happiness
        chain willIGetNewPhone(happiness)
          then showOff
          catch promise given e
            debug '${e} -- No phone for you.'

    askMom true
    askMom false

    > Hey friend, I have a new paisley Wangdoodle phone
    > Error: Mom is not happy. -- No phone for you.

The way **promise** works is best explained by just showing you what happens when you use it. We
wrap the code block in a Promise constructor, as follows:

    set doThing to promise given url
      HeyServer url, task given request, result
        if result.success
          resolve result
        else
          reject result
    ..
    debug doThing.toString()

    > function (p) {
    >   return new Promise(function($_resolve, $_reject) {
    >     var $url = p;
    >     $HeyServer($url, function(p, $result) {
    >       var $request = p;
    >       if (($56 = ($result.success))) {
    >         $_resolve($result);
    >       } else {
    >         $_reject($result);
    >       }
    >     });
    >   });
    > }

So basically it throws a **Promise** wrapper around the function and allows you to use
**resolve** and **reject** as statements. (The $56 in there is housekeeping for the **trial** pronoun;
V8 optimizes unused assignments like this away.)



### REFERENCE - _declare global values_ - keywords - ^reference

Import/declare global variables at the top of a **.SAI** source file.

    reference:
      [name] [expr]
      ...

This is the only way to make global variables; inside a reference declaration. The syntax
is the same as a **fields** structure definition, with name/value pairs separated by commas or newlines.

    reference:
      MIN 0, MAX 100
      express require('express')
      Vector2D 'Vector2D ^1.0.0'

    count to MAX
      debug key
    ..
    set @app express()
    ..
    set origin to create Vector2D 0, 0
    ..

Note: you cannot assign to reference variables or re-use them as locals. The following lines would
produce compile errors given the above references:

    local Vector2D
    set MIN -50



### REJECT - _mark a Promise as having failed_ - keywords - ^reject

Call the failed potential outcome for a function declared with **promise**.

    reject [expr1 (, expr2, ...)]
    reject  
    

This does not implicity end execution, however, the way **return** does.

For an example, see **promise**.



### RESOLVE - _mark a Promise as succeeding_ - keywords - ^resolve

Call the successful potential outcome for a function declared with **promise**.

    resolve [expr1 (, expr2, ...)]
    resolve  
    

Doesn't implicitly end execution the way **return** does, so make sure you mind the code path.

For an example, see **promise**.



### RETURN - _exit a function, returning a value maybe_ - keywords - ^return

Return a value to the caller of a **task**.

    return [expr1 (, expr2, ...)]
    return  
    

Works just like Javascript.

    set multiply to task given a, b
      return a*b

    debug multiply(2, 4)

    > 8



### SET - _variable assignment_ - keywords - ^set

Set is a busy keyword used in many situations where a result is calculated and then stored.

    see below for syntax reference

#### set dynamic trait declaration

    [identifier] set ( as [ident] )
      [code block]
    ( get
      [code block] )

Declare a _setter_ for a dynamic object trait. Cannot be used inside a function body.

This example object implements *Distance*, storing the value normalized to meters. You can get and set the value in centimeters and miles through the use of dynamic traits.

    object Distance 1.0.0
    instance: meters 0

    centimeters set given val
      set meters to val/100
    get
      return meters * 100

    miles set given val
      set meters to val * 1609.344
    get
      return meters / 1609.344

 And in use:

    set trip to create 'Distance'
    set trip.meters to 500
    debug trip.meters       // > 500
    debug trip.centimeters  // > 50000
    debug trip.miles        // > 0.31068559611867
    set trip.miles to 10
    debug trip.meters       // > 16093.44

#### set value assignment

    set [ident] to [expr]
    set [ident] [expr]  // the TO keyword is generally optional but it's a good idea to use it
    set [ident] ![function] ( [parameters] )
    set [ident] from [function] ( [parameters] )
    set [ident] [operator] [expr]
    set [ident] [unary operator]

Assign a value to an identifier. That's right, you don't use the equals sign for assignment.
Ugh, whose idea was that anyway?

    set a to 2
    set a from Math.pow self, 2
    set a Math.sqrt(a)
    set a * 4
    set a -
    debug a

    > -8

#### set multiple array value assignment

If you separate multiple identifiers with commas on the left, the assignment will assign each array
element on the right, starting at 0, to each identifier. As example:

    set a, b, c to: 1, 3, 5

For a fruity example:

    set a, b, c to fruit
    debug b
    > Banana

This is useful when dealing with small tuples or parsed data:

    GetPixel task given x,y
      return buffer.slice( (x+y*width)*4, 4 )

    set r, g, b, a to GetPixel(x,y)

This compiles to a Javascript construct similar to the following:

    var $_=GetPixel(x,y);
    $r=$_[0]; $g=$_[1]; $b=$_[2]; $a=$_[3];

#### Scoping and Set

All un-decorated, e.g. bare (`a` as opposed to `$a`), variables are scoped to the object method they're **set** in. For tighter scoping, you can use **local** in place of **set**, this causes the variable to be declared in-place using the Javascript keyword `let`.  _Be careful with variable scoping._

    set a 1
    if a is 1
      local a 2
      debug a
    debug a

    > 2
    > 1

#### set pipe operator

Documentation under separate cover.



### SUPER - _superclass function invocation_ - keywords - ^super

Call the previous ancestral version of the current object method.

    super ( [ parameters ] )
    .. super ( [ parameters ] )

This doesn't happen by default; if you want to chain backwards up the inheritance tree you must do it
with **super**.

Note there is *no other way* to access an overridden ancestral object method than by
using **super** within that specific overriding method itself. SAI is very strict about inheritance
that way. Don't even bother exploring the prototype chain.

    object Parent
    instance: name 'unknown'
    Instantiate task given name
      set @name to name

    object Child
    inherit: 'Parent'
    instance: age 'unknown'
    Instantiate task given name, age
      super name
      set @age to age

    set billy to create 'Child' 'Billy', 12
    debug billy

    > { name: 'Billy', age: 12 }

Contrary to what you might expect, **super** _does not_ use the **@** scoping prefix; that's
because super _always and only_ refers to the current object. You cannot call **super** on any other object.

If you want to pass arguments to a **super** method without specifying them discretely, the following
really ugly idiom gets the job done.

  super.apply @ $$



### SWAP - _value swapper_ - keywords - ^swap

Exchanges the values.

    swap [lvalue1] [lvalue2]

Intended as syntactic sugar, collapsing three ugly lines into one simple line.

    swap a b

This is functionally equivalent to the following Javascript:

    var temp1=a;
    var temp2=b;
    b=temp1;
    a=temp2;



### TASK - _define a function_ - keywords - ^task

Define a block of code as an object trait or anonymous function.

    [identifier] task ( given [parameters] ) / ( expects [parameters] )
      [code]
    
    .. [task] ( given [parameters] ) / ( expects [parameters] )
      [code]

It’s probably best to explain this by showing what Javascript is made.

#### task trait

The first example is a task trait on an object. It takes two standard parameters, name and value.

    Instrument task given name, value
      debug `${@context} ${name}: ${value}

Generated code:

    function (p, $value) {
      var $name = p,
        $ = this;
      console.log('' + $.context + ' ' + $name + ': ' + $value);
    }


You’ll note that the first parameter in a SAI-generated function is always `p`, which
is explained below. More importantly, however, note the assignation `$ = this`.

In SAI-generated code, the `$` variable is used as a buffer for the _this_ context.
When executing a task trait, SAI captures the current _this_ with `$=this` to
provide a reliable context for anonymous functions.

#### anonymous task

Here’s the same task but for anonymous use:

    set anon to task given name, value
      debug `${@context} ${name}: ${value}

Generated code:

    function (p, $value) {
      var $name = p;
      console.log('' + $.context + ' ' + $name + ': ' + $value);
    }

Notice how the anonymous task doesn’t capture `this.` into the `$` variable the
way the trait task does.

Thus, anonymous tasks automatically bind to the context that created them. This is usually
what you want when creating anonymous tasks, and is why the `var self=this` idiom has so
much traction in Javascript. SAI builds this idiom into the language.

However, if you don’t want this behaviour for a particular anonymous task, include
the **orphan** statement in it.

    set anon to task given name, value
      orphan
      debug `${@context} ${name}: ${value}

Generated code:

    function (p, $value) {
      var $name = p;
      var $ = this;
      console.log('' + $.context + ' ' + $name + ': ' + $value);
    }

Orphan anonymous tasks bind to the _calling_ context, rather than to the context that created them.

#### positional vs. named parameters

The second example is a task which expects two named parameters, $angle and $magnitude. As shown above, the first parameter in generated code is always `p`. Named parameters are passed as traits within `p`.

    SetPolar task expects $angle, $magnitude
      set x to $magnitude * Math.cos($angle)
      set y to $magnitude * Math.sin($angle)

Generated code:

    function (p) {
      var $ = this;
      _$AI.expectsThrow(p, {
        "angle": true,
        "magnitude": true
      }, 'SetPolar');
      $.x = (p.magnitude * Math.cos(p.angle));
      $.y = (p.magnitude * Math.sin(p.angle));
    }

When you use **expects**, a call to _expectsThrow_ is included to validate your assumptions.

This task is called by naming the parameters:

    SetPolar angle 45o, magnitude 3

Which generates this code:

    $.SetPolar({
      angle: 0.7853981633974483,
      magnitude: 3
    });

Notice how named parameters are encapsulated in a plain JS object and
passed in the first function call argument (which is always named `p`).

It is not necessary to use the **expects** clause to used named parameters. All **expects** does
for you is check to see if the names (and types) are as expected. Here is the function without it:

    SetPolar task
      set x to $magnitude * Math.cos($angle)
      set y to $magnitude * Math.sin($angle)

Generating this:

    function (p) {
      var $ = this;
      $.x = (p.magnitude * Math.cos(p.angle));
      $.y = (p.magnitude * Math.sin(p.angle));
    }

The use of named parameters with the **$** scoping prefix generates code that assumes the
first argument `p` will have the expected named traits.

Refer to the entry on **expects** for more on what it does.



### TO - _set clause syntax_ - keywords - ^to

__To__ is used in __set__ statements to separate the value being set from the value itself.

    set [lexpr] to [rexpr]

It is almost never necessary to actually use __to__ because the parser can almayst always figure
out what's going on.  Still, it looks clearer, so you should use it.

    set a to 5
    set a 5

Here's the only common case where there is confusion in the parser:

    set a - 5

What does that mean?

    set a to -5
    set a self - 5

The compiler complains about this construct specifically, and makes you specify.



### TRAITS - _declare a structure of literal strings_ - keywords - ^traits

Used to specify the creation of a plain object with a set of key/term pairs.

    .. traits [key] [term], [key] [term], ... (;)
    .. traits
      [key] [term], [key] [term], ...
      [key] [term]
      ...

(Contrast with **fields**.)  When you want to be specific about creating a plain object
from a set of of keyed values & literal terms, use **traits**.

The **key** is an identifying word or other string, specified without quotes (although
quotes may be used if desired/necessary). If a **#** preceeds the key (a hashtag),
the key will be assigned a value of **true**. The **term** is any valid
term (see **list** for a description of valid terms).

See **fields** for examples.



### TRUE - _boolean value true_ - keywords - ^true

The value TRUE, as in truthy, or not false.

    .. true

This is what all those __if__ statements test for, the holy grail itself.



### UNBOUND - _mark a method as context-free_ - keywords - ^unbound

An __unbound__ function is not 'attached' in any way (other than by name) to any instance of its
object.

    object ObjectName
    
    [name] unbound task
    [name] unbound process
    [name] unbound promise

When you declare an object function as __unbound__ the function no longer checks to see if it
has become orphaned in execution -- that is, if it's _this_ object is no longer
what it is supposed to be -- on a call to that function. Indeed, the _this_ context is specifically
undefined in an __unbound__ function.

__Unbound__ functions  cannot reference bareword (unqualified) instance or given variables,
or normal (bound) object functions. (They can access them with direct context, see the example
below.) They can also call other unbound functions.

    object Thing
    instance: name 'Fred'

    Bound task
      debug name    // Fred
      Unbound
      Unbound2 @
      Unbound3 @

    Unbound task
      debug name    // COMPILE ERROR, cannot use bareword instance variable within unbound task

    Unbound2 task given o
      debug o.name  // This is an access with direct context: the variable o. This prints 'Fred'

    Unbound3 task given o
      Unbound2 o    // This is okay, calling an unbound task within an unbound task
      Bound         // COMPILE ERROR, cannot call bareword bound function from an unbound task
      o.Bound       // But this is okay, because it's got a direct context.

So the question is why the heck would you ever mark a function __unbound__ and the answer is
sometimes when you're using callbacks, you might not be able to pass in a bound function.
Also, depending on your JS compiler, there may be a slight performance gain in marking small,
often used utility functions as __unbound__ so there is no need to perform binding checks.

It is reasonably safe to just declare things __unbound__ if you think you might want the
benefits; the compiler will holler if it thinks you're making a mistake.



### UNDEFINED - _the absence of a place_ - keywords - ^undefined

A literal indicating there is no variable, or no place for one.

    .. undefined

This compiles directly to Javascript’s `undefined`.



### USING - _function reference clause_ - keywords - ^using

Indicates in many looping constructs that logic is to be provided by a separate callback function.

    .. using [function reference]

Many pipe operators and loops provide a __using__ variant.

Have a look on the specific constructs to see how it's used.



### YIELD - _process product_ - keywords - ^yield

Produces the _next_ value in a __process__.

    yield [expr1 (, expr2, ...)]
    

Used with functions defined as **process**; see that keyword in this documentation,
and the EcmaScript 6 documentation for details.

    set OddNumbers to process
      set i to 1
      while true
        yield i
        set i + 2

    set myOdds OddNumbers()
    debug myOdds.next
    debug myOdds.next
    debug myOdds.next

    > { value: 1, done: false }
    > { value: 3, done: false }
    > { value: 5, done: false }

    iterate OddNumbers() | limit 4
      debug it

    > 1
    > 3
    > 5
    > 7



### YIELDING - _process inclusion_ - keywords - ^yielding

Yields to another process until that process is done yielding.

    yielding [expr1 (, expr2, ...)]
    

Equivalent to Javascript’s `yield *` syntax.
Essentially, **yielding** calls another process given a subroutine.

    // The Mirror process yields its first argument
    // then reverses it (in ASCII), yields that
    // then terminates

    set Mirror to process given str
      yield str
      yield str.split('').reverse().join('')

    // FruitSalad process is yielding an invocation of Mirror
    // for each fruit, then terminates

    set FruitSalad to process
      ply fruit
        yielding Mirror(it)

    // access each generated value in FruitSalad in turn
    iterate FruitSalad()
      debug it

    > Apple
    > elppA
    > Banana
    > ananaB
    > Citron
    > nortiC

In the example, Mirror yields twice, and FruitSalad yields to Mirror three times (once for each fruit), so the final iteration result is six values.



