window.markdeepOptions={tocStyle:"medium"} Types

Contents

Types
  1.1  Type Names
  1.2  Type Unions
  1.3  Argument Count
  1.4  Defaults
  1.5  Void/Undefined
  1.6  Checking
  1.7  Limitations
  1.8  Miscellaneous

Javascript Shell Interpreter
 DOWNLOAD / DEVELOP / DEPLOY

Types Builtin Reference  Index  Fossil  Demos Log Test Debug Misc

   

Types

Jsi function-parameters can have types and/or default values:

function foo (a:number, b:string='ok'):number { return a+1; } foo('a', 9, 10);

Which provides warnings upon execution:

jsish foo.jsi
/tmp/foo.js:4: warning: got 3 args, expected 1-2, calling function foo(a:number, b:string="ok") (at or near "a") /tmp/foo.js:4: warning: type mismatch for argument arg 1 'a': "string" is not a "number" (at or near "a") /tmp/foo.js:4: warning: type mismatch for argument arg 2 'b': "number" is not a "string" (at or near "a") /tmp/foo.js:2: warning: type mismatch returned from 'foo': "string" is not a "number" (at or near "a")

Type-checking is provided at the function call interface only.

   

Type Names

Supported types are:

Type Description
number A double floating point value
boolean A boolean value
string A string value
function A javascript function
object A javascript object
array A javascript array
regexp A regular expression
userobj A userobj command, eg. from new Socket()
null A javascript null
undefined A value that is undefined
void Argument ommitted/no value returned
any Means any value is accepted/returned

Here is a function that returns nothing:

function foo (a:number):void { return; }

and another that can return anything:

function foo (n):any { return (n?99:"Ok"); }
   

Type Unions

It is not uncommon for a parameter to want to accept more than one type. For that we can use type-unions, multiple types separated with a pipe "|" character. eg:

function foo (a:number, b:number|string|boolean) { var typ = (typeof b); switch (typ) { case "number": return b+1; case "string": return b; case "boolean": return -1; default: throw "unhandled type: "+typ; } } foo(9,'a'); foo(9,9); foo(9,true);

Similarly return types can also use unions:

function foo (x):number|string { return x+x; }

Union types are used extensively by builtin commands.

   

Argument Count

In standard javascript any number of arguments may be passed in a function call, irregardless of the parameter list.

This is also true in Jsi when a function has no types. But the addition of at least one type activates checking for that function:

function bar (a, b) { return a+1; } function foo (a, b):number { return a+1; } bar(9); foo(9);
/tmp/foobar.js:4: warning: incorrect arg count in function call "foo()": got 1 args, but expected 2

Extra argument warnings can be avoided by adding an ellipsis "...”:

function fool (a:number, b:number, ...) { return console.args.length; } foo(9,9,9);

It is also possible to enable argument count checking for untyped functions, by setting typeCheck mode all.

   

Defaults

Default values allow functions to be called with fewer parameters, as in:

function foo (a, b=1) {} function bar (a=1, b=2) {} foo(9); bar();

A default value must be one of the primitives:

Type Description
number A double floating point value
boolean A boolean value
string A string value
null The null value
undefined An undefined value/var
void Argument may be ommitted

Also note that when a parameter is given a default value, all following it must as well, possibly using void:

function bar (a=1, b=true, c='ok', d=null, e=void, f=void) {}

Assigning a default value also implicitly assigns a type (except void). Thus the following are equivalent:

function quick(a:number=1) {}
function quick(a=1) {}

Types are or'ed, meaning the following accepts string as well:

function duck(a:number|boolean='quack') {}
   

Void/Undefined

A default-value of void is used to indicate that an argument may be ommitted.

function bag(a=void) {} var xyz; bag(); bag(xyz);
/tmp/big.jsi:4: warning: call with undefined var for argument arg 1 'a

To allow calls with an undefined argument, give a default-value of undefined:

function fig(a=undefined) {} var xyz; fig(xyz);

A function return type can not be undefined.

   

Checking

Type checking is used to issue warnings/errors for incorrect calls to a typed function.

When checking is enabled, it applies to any function containing at least one type or default value, eg:

function foo (a:number, b:string='ok'):number {}

In Jsi, the default checking state is:

There are several way a script can control type-checking:

The “use” directive can take multiple comma separated options:

"use run,error"; function foo (a:number, b:string='ok'):number {}

To repeat use must be on the first line (or 2nd if using #!).

Here is the list of modes accepted by use:

Type Description
parse Turn on parse-time checking
run Turn-on run-time checking
all Both parse and run, plus argument checking for untyped functions
error Runtime warnings are errors
strict Same as all and error
funcsig Emit warnings for named function calls with no prior declaration
noundef Disable strict warnings for calls to function with void passed an undefined var
nowith Disable using with expressions
asserts Enable run-time assert() checking. See assert
Debug Enable LogDebug() output. See logging
Trace Enable LogTrace() output
Test Enable LogTest() output

The "!” prefix can be used to invert a flag:

"use strict,!error";

Modes may also be set from the command-line:

jsish -T parse,run foo.jsi;    # Perform checking at parse and run time.

Type-check mode can also be changed via Interp.conf():

Interp.conf({typeCheck:['error','run','parse']}); // Promote warnings to errors .

And finally, via the environment:

JSI_INTERP_OPTS='{typeCheck:["error","run","parse"]}' jsish script.jsi

By default type checking is silently disabled after 50 warnings. But this can be changed with: “Interp.conf({typeWarnMax:0})"

   

Limitations

Although parse time checking is enabled with “use strict”, this is no-where close to the kind of type-checking available in C.

The first reason for this is that function arguments are frequently javascript variables which are dynamically typed. Thus only primitives arguments can be checked.

Secondly, at parse time calls to a function can not be checked prior to that functions definition. One option is a forward declaration, as in:

function f(a:number):number{} // Forward declaration. function b() { f(1,2); } function f(a:number):number { return a+1; }

Builtin commands have prototypes, which is basically why there is no problem statically checking them.

   

Miscellaneous

The rules for defining types in functions are:

If a function has no types or defaults, it is by default treated as normal javascript, and there will be no type-checking.

Builtin commands make extensive use of typed parameters.

In the Jsi code-base, these apply to:

var startOfMarkDeep=true; window.alreadyProcessedMarkdeep||(document.body.style.visibility='visible'); document.title=location.pathname.match(/\/([\w]+)1;

formatted by Markdeep 1.03