# 

This file is automatically generated. _Do not edit._

Unknown Heading


### 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



### 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.



### 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.



### SINGLETON - _singleton object access_ - operators - ^singleton

Creates one instance of SAI object by name.

    .. singleton [expr] [parameters]

Creates one instance of SAI object by name. If the object has already been created, returns a
reference to it. The scope is that maintained by the runtime library.

Like __create__, __singleton__ will attempt to find the object’s source by using the `SAI.config.Loader`
function, which defaults to `SAI.GetSourceFromPaths`, which tries to find a file named `[expr].sai`
in the provided paths.

    reference:
      Tally 'Tally ^1.0.0'
    ..

    set inventory to singleton Tally

(The example follows best practices of placing object names in a **reference** section, aliasing
versioned names into literals.)

Singleton objects are useful for library functions, APIs to external resources, tallies, caches,
message managers and so on.

Since the reference to the singleton object is maintained by the library, singleton objects are
never garbage collected (and cannot be destroyed) once created. If you might need to release resources
held by a singleton before the end of the application, you must make allowances for that in your
object's API; e.g. by crafting a `.Cleanup` task.

See also __new__, which is a direct link to Javascript's `new`, and __create__, which will make a new
object each time.



### 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’.”



### 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'



### 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)



### 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



### | SET - _replacement operator_ - pipers - ^set

A chainable comprehension operator that allows direct reference and replacement of the incoming dataset within an expression or code block, using the  **it**  pronoun.

    ... | set [expr]
    ... | set (AS var1, var2...) [indent code block]
    ... | set USING [function reference]
    

**Set** can be used with an expression:

    debug 4 | set 5*it+2 | set it/7

    > 3.142857142857143

**Set** can use an indented code block:

    debug friends by .age | set
      set .length to 3

    > [ { name: 'Doug', age: 18, province: 'ON' },
    >    { name: 'John', age: 19, cat: true, dog: true, province: 'ON' },
    >    { name: 'Marshal', age: 21, dog: true, province: 'ON' } ]

_If you don’t specifically **return** a value or object from within an **set** code block, the original value will be used (as in the example above). In other words, there is an implicit `return it` at the end of every **set** block._

**Set** supports the **using** clause, in which case the function specified receives the original value as its first parameter, and the return value is passed forward. The two debug statements below are equivalent

    set ExtractFirst to task
      return $[0]

    debug friends #cat | set Extract(it)
    debug friends #cat | set using Extract

    > { name: 'Sara', age: 23, cat: true, province: 'ON' }
    > { name: 'Sara', age: 23, cat: true, province: 'ON' }

You must specifically return a value in the function called by **set using**.



### 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.



### 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.)



