StratifiedJS 0.14: Shiny New SJS Features

June 18, 2013 by Tim Cuthbertson

We're pleased to announce the release of Stratified JavaScript version 0.14. This release brings a large number of language improvements and refactoring of the standard library.

The library formerly known as 'Apollo'

We're deprecating the "Apollo" name in favour of "StratifiedJS" - which will now refer to both the language and our reference implementation. For brevity, this may be shortened to "SJS". Where it would otherwise be ambiguous, clarify with "implementation" or "language" - e.g "The StratifiedJS implementation".

In line with this, we've started distributing StratifiedJS via npm and bower, under the package name stratifiedjs.

Due to the name change, when upgrading you will need to update references using the old name:

  • The apollo command-line executable has been renamed to sjs
  • oni-apollo.js has been renamed to stratified.js
  • oni-apollo-node.js has been renamed to stratified-node.js
  • The standard library hub has been renamed from "apollo:" to "sjs:" - so require('apollo:cutil') becomes require('sjs:cutil')
  • URL changes (the old URLs will still work for some time, but we recommend using the new ones):

    Stack traces

    Previous versions of StratifiedJS only included the module and line where an exception was thrown. StratifiedJS 0.14 adds full stack traces for SJS code, which greatly aids tracking down where errors came from.

    Language changes

    StratifiedJS 0.14 brings with it a number of useful language-level features that improve expressiveness and clarity, as well as adding some constructs that are difficult or impractical to express in vanilla Javascript.

    These features are explain in more detail on the StratifiedJS language reference page.

    String interpolation

    "foo #{bar} baz", equivalent to "foo " + bar + " baz"

    Quasi-quotes

    A richer form of interpolation that allows the code to control how embedded values are converted / represented. This allows for e.g. interpolation of strings with automatic escaping of HTML characters.

    One place we're already using this is in the logging module. While string interpolation is usually not sufficient, quasi-quotes allow the called function to process the individual parts, and join them by whatever means is appropriate for that use.

    var name = { first: "john", last: "smith" };
    logging.print("New user: #{name}");
    // prints: New user: [Object object]
    logging.print(`New user: ${name}`);
    // prints: New user: { first: "john", last: "smith" }
    

    As another example, this would also enable you to create a function for doing safe HTML interpolation:

    var input = "Nasty <script>";
    html(`Your input is: ${input}`);
    // -> "Your input is: Nasty &lt;script&gt;"
    

    The double-dot operator

    This operator reads similarly to the regular dot operator (to access a property), but it works somewhat like a UNIX pipe. We're sure that you'll love it once you start using it, but the full explanation is a little long to reproduce here - you should check out the full description on the language features page.

    Blocklambdas

    Similar to blocks in ruby, these are particularly useful for implementing custom control-flow operations (such as the new sequence::each iterator). They have some important (and useful) semantic differences compared to a normal anonymous function, check the language reference page for the full story.

    Arrow syntax

    Are function shorthand that can only consist of a single expression, which is returned from the function. e.g: (x) -> x + 1 or, the "fat arrow" variant: (x, y) => this.add(x, y) which keeps the current value of this, i.e it's equivalent to: (function(x, y) { return this.increment(x, y); }).bind(this);

    Parentheses around arguments are optional, so the following are both valid:

    var increment = x -> x + 1;
    var returnOne = -> 1;
    

    Standard Library changes:

    Note that in StratifiedJS 0.14, the standard library hub has changed from "apollo:" to "sjs:". So instead of require('apollo:cutil'), use require('sjs:cutil').

    New modules:

    array
    Array-specific functionality extracted from the old common module
    assert
    Assertion functions, mainly for use in tests
    compare
    Deep equality object comparisons
    dashdash
    command-line options parsing, tracking node-dashdash
    events
    Event-specific functionality extracted from the cutil module
    function
    Functional utilities extracted from the old the old common module
    jsondiffpatch
    JSON diff-and-patch utilities, trcking JsonDiffPatch
    lru-cache
    Least-Recently-Used cache implementation
    marked
    Markdown implementation, tracking marked
    nodejs/
    Contains nodejs-only modules (previously at the top level, e.g nodejs-http)
    numeric
    Functions for numeric linear algebra computations, tracking numericjs.com
    object
    Object utilities extracted from the old common module
    quasi
    Runtime support for the new quasiquote syntax
    sequence
    Replaces the old collection module, adds support for the lazy Stream type as well as arrays
    shell-quote
    Utilities for parsing / escaping POSIX-style argument strings
    sjcl
    The Stanford JavaScript Crypto Library, tracking crypto.stanford.edu/sjcl/
    string
    String utilities extracted from the old common module
    sys
    SJS runtime utilities, replacing sjs:apollo-sys
    test/
    Tools for defining and running cross-environment test suites
    url
    URL utilities functionality extracted from the http module
    webapi/
    This folder holds all web API bindings (previously at the top level, e.g yql, freebase, google)
    wraplib
    Utility for creating SJS wrappers for callback-heavy Javascript code
    xbrowser/
    Contains xbrowser-only modules (previously at the top level, e.g dom)

    Removed modules:

    common
    Replaced by the more specific array, object, string and function modules
    collection
    Replaced by the new sequence module
    jquery-binding
    Doesn't really belong in a standard library. The new double-dot operator and wraplib module provide less invasive approaches for working with regular JS libraries

    The logging module:

    The logging format interface has been simplified. Since StratifiedJS 0.14 now includes support for both string interpolation ("hello #{name}") and quasi-quotes (`hello ${person}`), the old string-formatting functionality of the logging functions is no longer necessary. Now, every argument passed to a logging function (e.g logging.info) is simply passed through to the underlying console method without any formatting. The one exception to this is quasi-quoted arguments, which will be concatenated after passing any non-string embedded values through `debug.inspect`. i.e:

    var name = { first: "John", last: "Smith" };
    logging.info(`${name} has logged in`);
    // will print:
    // INFO: { first: "John", last: "Smith" } has logged in.
    

    As a side effect, the logging module no longer supports format strings (i.e. logging.setFormat()). It now uses a formatter function - see the documentation for logging.setFormatter() for details.

    The browser-based debug.console:

    The in-browser console functionality (previously in the sjs:debug module) has been moved into its own module at xbrowser/console.

    Coming soon:

    We're busy at work on an SJS-based framework for creating webapps, including effortless client-server communications, SJS user interface widgets (using the new quasiquote syntax), and more. Stay tuned!