The None Programming Language

This manual aims to provide an introduction to programming with None, a description of None’s architecture and its different language levels, and a reference of all special forms, macros, functions and modules provided in the language repository.

Contents:

First Steps

Installation

TODO

  • LuaFileSystem (lfs) should be installed to enable bytecode caching

Using The Command-Line Interpreter

TODO

Architecture

None understands and transforms source code in multiple cleanly separated stages:

Order Stage Language Output
1 Parsing Data Interchange Format Abstract Syntax Tree
2 Expansion Macro Language Special Forms
3 Translation Dynamic Language Bytecode
4 Evaluation Bytecode Program Output

TODO

The Data Interchange Language

This chapter outlines the syntax of None source code at the data interchange format level from the perspective of nesting arbitrary expressions.

Syntax Tree Elements

The None parser has been designed for minimalism and recognizes only five types of syntax tree elements:

  • Comments
  • Numbers
  • Symbols
  • Strings
  • Lists

All further understanding of types is done with additional parsing at later stages that depend on language context and evaluation scope.

Comments

Comments are not skipped by the parser but stored as strings and stripped before expansion stage. A comment token is recognized by its ; prefix and scanned until the next newline character. Here are some examples for valid comments:

;mostly harmless
;123
;"test"
;(an unresolved tension
;; ;(another comment); ;;

Comments are first-class tokens and kept by the parser until the next processing stage. In naked notation, they contribute to syntax. For more information, see Pitfalls of Naked Notation.

Numbers

Numbers are atomic elements and internally stored as 64-bit floating point numbers, which gives them 52-bit integer precision. Here are some examples for valid numbers:

; positive and negative integers
0 23 42 -303 12 -1
; positive and negative floating point numbers
0.0 1.0 3.14159 -2.0 0.000003
; numbers in scientific notation
1.234e+24 -1e-12

Symbols

Symbols are atomic elements and internally stored as strings. They may contain any character from the UTF-8 character set except whitespace and any character from the set ;()[]{}, and the character / in naked notation (more on that later). Any symbol that parses as a number is also excluded. Here are some examples for valid symbols:

; classic underscore notation
some_identifier _some_identifier
; hyphenated
some-identifier
; mixed case
SomeIdentifier
; fantasy operators
&+ >~ >>= and= str+str
; numbered
_300

Strings

Strings are atomic elements and stored as such, scoped by " (double quotes). The \ escape character can be used to describe various control characters. Here are some examples for valid strings:

"single-line string"
"multi-
line
string"
"return: \n, tab: \t, backslash: \\, double quote: \"."

Lists

Lists are the only nesting type, scoped by the parenthesis characters ( and ). Lists can be empty or contain an unlimited number of elements, separated by whitespace. They typically describe expressions in None. Here are some examples for valid lists:

; empty list
()
; list containing a symbol, a string, a number, and an empty list
(print "hello world" 303 ())
; three nesting lists
((()))

Naked & Coated Expressions

Every None source file is parsed as a single expression, where the head element is the language name and all remaining elements are expressions.

The classic notation (what we will call coated notation) uses the syntax known to Lisp and Scheme users as restricted S-expressions:

(none ; None scripts and modules use this header

; there must not be any tokens outside the parentheses guarding the
; top level expression.

; statement expressions go here
(print "Hello World")
...

; the value returned when loaded as a module.
; scripts usually return null
null)

As a modern alternative, None offers a naked notation where the scope of expressions is implicitly balanced by indentation, an approach used by Python, Haskell, YAML, Sass and many other languages.

This source parses as the same expression in the coated example:

none
; a single element in a single line without sub-expressions is assumed to
; be a complete expression.

; multiple elements in a single line are transformed to an expression
print "Hello World"
...

; return null
null

Mixing Modes

Naked expressions can contain coated expressions, but coated expressions can only contain other coated expressions:

; compute the value of (1 + 2 + (3 * 4)) and print the result
(print
    (+ 1 2
        (* 3 4)))

; the same expression in naked notation.
; indented expressions are spliced into the parent expression:
print
    + 1 2
        * 3 4

; any part of a naked expression can be coated
print
    + 1 2 (* 3 4)

; but a coated expression can not contain naked parts
print
    (+ 1 2
        * 3 4) ; parsed as (+ 1 2 * 3 4), a syntax error

; correct version:
print (+ 1 2 (* 3 4))

Because it is more convenient for users without specialized editors to write in naked notation, and balancing parentheses can be challenging for beginners, the author suggests to use coated notation sparingly and in good taste. Purists and enthusiasts may however prefer to keep only the top level naked, as in most Lisp-like languages, and work exclusively with coated expressions otherwise.

Therefore None’s reference documentation describes all available symbols in coated notation, while code examples make ample use of naked notation.

Pitfalls of Naked Notation

As naked notation giveth the user the freedom to care less about parentheses, it also taketh away. In the following section we will discuss the various difficulties that can arise and how to solve them.

Single Element Expressions

Special care must be taken when expressions with single elements are used.

Here is a coated expression printing the number 42:

(print 42)

The naked equivalent declares two elements in a single line, which are implicitly wrapped in a single expression:

print 42

A single element on its own line is always taken as-is:

print
    42

What happens when we want to call functions without arguments? Consider this example:

; a coated expression in a new scope, printing a new line,
; followed by the number 42
(do
    (print)
    (print 42))

A naive naked transcription would probably look like this, and be very wrong:

do
    ; suprisingly, the new line is never printed, why?
    print
    print 42

Translating the naked expression back to coated reveals what is going on:

(do
    ; interpreted as a symbol, not as an expression
    print
    (print 42))

The straightforward fix to this problem would be to explicitly wrap the single element in parentheses:

do
    (print)
    print 42

Nudists might however want to use a line comment symbol that forces the line to be wrapped in an expression and therefore has the same effect:

do
    print ;
    print 42

This is possible because comments are first-class token and work as “empty symbols” that are kept until the next parsing stage. This allows to use ; as a helper to express complex trees in naked notation.

Wrap-Around Lines

There are often situations when a high number of elements in an expression interferes with best practices of formatting source code and exceeds the line column limit (typically 80 or 100).

In coated expressions, the problem is easily corrected:

; import many symbols from an external module into the active namespace
(import-from "OpenGL"
    glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
    GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
    glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP)

The naked approach interprets each new line as a nested expression:

; produces runtime errors
import-from "OpenGL"
    glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
    GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
    glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP

; coated equivalent of the expression above; each line is interpreted
; as a function call and fails.
(import-from "OpenGL"
    (glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT)
    (GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram)
    (glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP))

It comes easy to just fix this issue by putting each element on a separate line, which is not the worst solution:

; correct solution using single element lines
import-from "OpenGL"
    glBindBuffer
    GL_UNIFORM_BUFFER
    glClear
    GL_COLOR_BUFFER_BIT
    GL_STENCIL_BUFFER_BIT
    GL_DEPTH_BUFFER_BIT
    glViewport
    glUseProgram
    glDrawArrays
    ; comments should go on a separate line
    glEnable
    glDisable
    GL_TRIANGLE_STRIP

A terse approach would be to make use of the \ (splice-line) control character, which is only available in naked notation and splices the line starting at the next token into the active expression:

; correct solution using splice-line, postfix style
import-from "OpenGL" \
    glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT \
    GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram \
    glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP

Unlike in other languages, \ splices at the token level rather than the character level, and can therefore also be placed at the beginning of nested lines, where the parent is still the active expression:

; correct solution using splice-line, prefix style
import-from "OpenGL"
    \ glBindBuffer GL_UNIFORM_BUFFER glClear GL_COLOR_BUFFER_BIT
    \ GL_STENCIL_BUFFER_BIT GL_DEPTH_BUFFER_BIT glViewport glUseProgram
    \ glDrawArrays glEnable glDisable GL_TRIANGLE_STRIP

Tail Splicing

While naked notation is ideal for writing nested expressions that accumulate at the tail:

; coated
(a b c
    (d e f
        (g h i))
    (j k l))

; naked
a b c
    d e f
        g h i
    j k l

...there are complications when additional elements need to be spliced back into the parent expression:

(a b c
    (d e f
        (g h i))
    j k l)

A simple but valid approach would be to make use of the single-element rule again and put each tail element on a separate line:

a b c
    d e f
        g h i
    j
    k
    l

But we can also reuse the splice-line control character to this end:

a b c
    d e f
        g h i
    \ j k l

Left-Hand Nesting

When using infix notation, conditional blocks or functions producing functions, expressions arise that nest at the head level rather than the tail:

((((a b)
    c d)
        e f)
            g h)

While this expression tree is easy to describe in coated notation, pure naked expressions will need to make use of line comment characters and optional splice-line characters to trade parentheses for additional indentation:

;removing these
    ;comments is
        ;a syntax error
            a b
            \ c d
        \ e f
    \ g h

Once again, the first-class token nature of ; is put to use in order to be able to start left-hand nesting expressions.

A more complex tree which also requires splicing elements back into the parent expression can be realized with the same combo of line comment and splice-line control character:

; coated
(a
    ((b
        (c d)) e)
    f g
    (h i))

; naked
a
    ;
        b
            c d
        e
    \ f g
    h i

While this example demonstrates the versatile usefulness of splice-line control and line comments as empty symbols, less seasoned users may prefer to express similar trees in partial coated notation instead.

Block Comments

While all comments are recorded at parser stage, they are stripped before macro expansion stage. In addition to ; single line comments, None recognizes and strips a special kind of multi-line comment.

A list beginning with a symbol that starts with a ### (triple hash) describes a block comment. Block comments have to remain syntactically consistent. Here are some examples for valid block comments:

; block comments in coated notation
(###this comment
    will be removed)
(###
    ; commenting out whole sections
    (function ()
        true)
    (function ()
        false))

; block comments in naked notation
###this comment
    will be removed

###
    ; commenting out whole sections
    function ()
        true
    function ()
        false

The Dynamic Language

TODO

Variables

Blocks

Conditionals

Iterators

Stream Processing

Scopes

Working with Numbers

Working with Strings

Working with Tables

Working with AST Lists

Infix Notation

Dot Notation

Number Formats

  • 0x
  • 0b

Unpacking

  • multiple lua return arguments
  • var-unpack
  • function arguments

Exception Handling

Types

Lua Compatibility

  • _G

Debugging

Assertions

Exceptions

Tracebacks

The Core Library

Intrinsic Operators

AST Operations

Converting Types

Lua Modules

  • math
  • io
  • os
  • string
  • ffi

Working with Strings

Working with Tables

Macro Programming

Pattern Matching

Debugging

Infix Macros

Symbol Prefix Macros

List Hooks

Symbol Hooks

Meta-Evaluation

Conditional Translation

The Static Language

Functions

Variables

Types

Function Types

Structs

Conditionals

Loops

Constants

Iterators

Globals

Escapes

C Compatibility

Pointers

Static Macros

Defer

None Language Reference

Built-in Functions

These functions are loaded into the global namespace before core.n is executed.

function ( type object )
function ( generate-symbol )
function ( generate-anchor [ level ])
function ( expect-symbol symbol )
function ( expect-list list )
function ( expect-list-count list , min-count [, max-count ])
function ( table-new ... )
function ( table-apply function , table )
function ( table-call function [, argument , ... ])
function ( table-get table , key , ... )
function ( table-setkey table , key , value )
function ( loop-pred step )

Built-in Symbols

var true
var false
var null
var globals

Core Macros

These macros are all defined in core.n and become available before the execution of any user script.

macro ( syntax-global macro-name , function-expression )
macro ( __syntax-trace expression )
macro ( syntax-alias-global new-macro-name , existing-macro-name )
macro ( syntax macro-name , ... , function-expression )
macro ( syntax-alias new-macro-name , existing-macro-name )
macro ( do expression , ... )
macro ( var variable-name [, init-expression ])
macro ( if conditional-expression , then-expression [, else-expression ])
macro ( break )
macro ( locals )
macro ( quote expression )
macro ( do-splice expression , ... )
macro ( del variable-name )
macro ( meta-eval expression , ... )
macro ( meta-do expression , ... )
macro ( loop variable-name , ( start , stop [, step ]), expression , ... , )
macro ( while conditional-expression , loop-expression , ... )
macro ( function ([ parameter-name , | ( $ parameter-name , ... ), ... , ]) expression , ... , )
macro ( function-global ([ parameter-name , ... ]), expression , ... , )
macro ( var-global variable-name , init-expression )
macro ( __dot expression , name )
macro ( __dotset expression , name , | ( name , value ))
macro ( __member-call expression ( name [, argument , ... ]))
macro ( __method-call expression ( name [, argument , ... ]))
macro ( __hashset expression ( key , value ))
macro ( syntax-rules ( pattern , template ), ... , )
macro ( syntax-table table-expression )
macro ( __and lhs-expression , rhs-expression )
macro ( __or lhs-expression , rhs-expression )
macro ( - [ lhs-expression , ] rhs-expression )
macro ( / [ lhs-expression , ] rhs-expression )
macro ( // lhs-expression , rhs-expression )
macro ( __hashsetdefault expression ( key , default-value ))
macro ( = variable-expression , [ ... , ] value-expression )
macro ( and lhs-expression , rhs-expression [, ... ])
macro ( or lhs-expression , rhs-expression [, ... ])
macro ( | lhs-expression , rhs-expression [, ... ])
macro ( & lhs-expression , rhs-expression [, ... ])
macro ( ^ lhs-expression , rhs-expression [, ... ])
macro ( << lhs-expression , rhs-expression [, ... ])
macro ( >> lhs-expression , rhs-expression [, ... ])
macro ( + lhs-expression , | , table-expression [, rhs-expression , ... ])
macro ( * lhs-expression , rhs-expression [, ... ])
macro ( .. lhs-expression , [ ... , ] rhs-expression )
macro ( min lhs-expression , | , table-expression [, rhs-expression , ... ])
macro ( max lhs-expression , | , table-expression [, rhs-expression , ... ])
macro ( . expression , name [, ... ])
macro ( -> expression ( name [, argument , ... ])[, ... ])
macro ( --> expression ( name [, argument , ... ])[, ... ])
macro ( .= expression , name , | ( name , value )[, ... ])
macro ( #= expression ( key , value )[, ... ])
macro ( =# expression ( key , default-value )[, ... ])
macro ( syntax-infix-rules precedence , associativity , macro-name )
macro ( syntax-infix-alias-global macro-name , rule )
macro ( syntax-infix-alias macro-name , rule )
infix-macro ( variable-name , = value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-name , := init-expression )
Precedence:50
Associativity:<
infix-macro ( lhs-expression , or rhs-expression )
Precedence:100
Associativity:>
infix-macro ( lhs-expression , and rhs-expression )
Precedence:200
Associativity:>
infix-macro ( lhs-expression , | rhs-expression )
Precedence:240
Associativity:>
infix-macro ( lhs-expression , ^ rhs-expression )
Precedence:250
Associativity:>
infix-macro ( lhs-expression , & rhs-expression )
Precedence:260
Associativity:>
infix-macro ( lhs-expression , < rhs-expression )
Precedence:300
Associativity:>
infix-macro ( lhs-expression , > rhs-expression )
Precedence:300
Associativity:>
infix-macro ( lhs-expression , <= rhs-expression )
Precedence:300
Associativity:>
infix-macro ( lhs-expression , >= rhs-expression )
Precedence:300
Associativity:>
infix-macro ( lhs-expression , != rhs-expression )
Precedence:300
Associativity:>
infix-macro ( lhs-expression , == rhs-expression )
Precedence:300
Associativity:>
infix-macro ( lhs-expression , is rhs-expression )
Precedence:300
Associativity:>
infix-macro ( lhs-expression , .. rhs-expression )
Precedence:400
Associativity:<
infix-macro ( lhs-expression , << rhs-expression )
Precedence:450
Associativity:>
infix-macro ( lhs-expression , >> rhs-expression )
Precedence:450
Associativity:>
infix-macro ( lhs-expression , - rhs-expression )
Precedence:500
Associativity:>
infix-macro ( lhs-expression , + rhs-expression )
Precedence:500
Associativity:>
infix-macro ( lhs-expression , % rhs-expression )
Precedence:600
Associativity:>
infix-macro ( lhs-expression , / rhs-expression )
Precedence:600
Associativity:>
infix-macro ( lhs-expression , * rhs-expression )
Precedence:600
Associativity:>
infix-macro ( lhs-expression , ** rhs-expression )
Precedence:700
Associativity:<
infix-macro ( lhs-expression , . rhs-expression )
Precedence:800
Associativity:>
infix-macro ( expression ->( name [, argument , ... ]))
Precedence:800
Associativity:>
infix-macro ( expression -->( name [, argument , ... ]))
Precedence:800
Associativity:>
infix-macro ( expression #( key , value ))
Precedence:800
Associativity:>
infix-macro ( expression , .= name , | ( name , value ))
Precedence:800
Associativity:>
infix-macro ( expression #=( key , value ))
Precedence:800
Associativity:>
infix-macro ( expression =#( key , default-value ))
Precedence:800
Associativity:>
macro ( backquote expression )
macro ( unquote expression )
macro ( unquote-splice list-expression )
macro ( assert expression [, string-expression ])
macro ( assert-error expression , string-expression )
macro ( cond ( conditional-expression , case-expression , ... ), ... , [( else else-expression )])
macro ( switch ( literal-expression , case-expression , ... ), ... , [( else else-expression )])
macro ( do-if conditional-expression , expression , ... )
macro ( table-untupled ( function-expression [, argument-expression , ... ]))
macro ( import-from table-expression , | , module-name , symbol , | , index , | ( name , symbol ))
macro ( var-unpack table-expression , variable-name , ... )
macro ( foreach variable-name| , ( variable-name , ... ), iterator-expression , loop-exression , ... , )
macro ( ast-list-each variable-name| , ( variable-name , ... ), iterator-expression , loop-exression , ... , )
macro ( table-each variable-name| , ( variable-name , ... ), iterator-expression , loop-exression , ... , )
macro ( table-loop variable-name , ( start , stop [, step ]), loop-expression , ... , )
macro ( table-do expression , ... )
macro ( class name , | , name-expression , [ : baseclass-expression , ] expression , ... )
macro ( class-global name , | , name-expression , [ : baseclass-expression , ] expression , ... )
macro ( method [ name , ]([ argument-expression , ... ]), expression , ... , )
macro ( ++ variable-expression )
macro ( -- variable-expression )
macro ( += variable-expression , value-expression )
macro ( -= variable-expression , value-expression )
macro ( *= variable-expression , value-expression )
macro ( /= variable-expression , value-expression )
macro ( %= variable-expression , value-expression )
macro ( &= variable-expression , value-expression )
macro ( |= variable-expression , value-expression )
macro ( ^= variable-expression , value-expression )
macro ( <<= variable-expression , value-expression )
macro ( >>= variable-expression , value-expression )
macro ( ..= variable-expression , value-expression )
infix-macro ( variable-expression , += value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , -= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , *= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , /= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , %= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , &= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , |= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , ^= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , <<= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , >>= value-expression )
Precedence:50
Associativity:<
infix-macro ( variable-expression , ..= value-expression )
Precedence:50
Associativity:<
macro ( for ( init-expression , predicate-expression , increment-expression ), loop-expression , ... , )
macro ( postfix variable-expression , operator )
symbol-prefix 0x, hexadecimal-number,
symbol-prefix 0bbinary-number,
macro ( try try-expression , except err , catch-expression )
macro ( using module-name )
macro ( $ [ value , | ( key , := value ), | , ( var key , value ), ... , ])
macro ( syntax-export table-expression )
macro ( syntax-import name-string )
macro ( syntax-import-replace name-string )
macro ( syntax-if conditional-expression , then-expression [, else-expression ])
macro ( syntax-ifvar variable-name , then-expression [, else-expression ])
macro ( main-module? )
macro ( syntax-quote syntax-expression )
macro ( syntax-expand syntax-expression )
macro ( syntax-join syntax-expression )
macro ( syntax-concat syntax-expression , ... )
macro ( syntax-each variable-name , ( value , ... ), template , )
macro ( syntax-string expression )
macro ( ast-list-unpack list-expression , pattern )

Global Functions

These global functions are defined or imported in core.n and become available before any user script.

function ( print [ argument , ... ])
function ( dprint [ argument , ... ])
function ( syntax-globals )
function ( syntax-symbol-prefix-globals )
function ( __assert value , error-message )
function ( ast-list [ object , ... ])
function ( ast-tag anchor , list )
function ( ast-string symbol )
function ( ast-repr object )
function ( ast-list? object )
function ( ast-symbol? object )
function ( ast-string? object )
function ( ast-number? object )
function ( ast-atom? object )
function ( ast-typeof object )
function ( ast-format list [, opts ])
function ( ast-pattern-keys context , pattern )
function ( ast-syntax-match context , pattern , list )
function ( ast-apply-template context , template )
function ( ast-expand-infix list , infix-table )
function ( ast-wrap-compiler-call function , list , ... )
function ( __add a , b )
function ( __sub a , b )
function ( __mul a , b )
function ( __div a , b )
function ( __floordiv a , b )
function ( __mod a , b )
function ( __pow a , b )
function ( __concat a , b )
function ( __le a , b )
function ( __lt a , b )
function ( __ge a , b )
function ( __gt a , b )
function ( __eq a , b )
function ( __ne a , b )
function ( __is a , b )
function ( __unm x )
function ( __not x )
function ( len x )
function ( __band a , b )
function ( __bor a , b )
function ( __bnot x )
function ( __bxor a , b )
function ( __bswap a , b )
function ( __shl a , b )
function ( __shr a , b )
function ( __rol a , b )
function ( __ror a , b )
function ( __min a , b )
function ( __max a , b )
function ( table [ object , ... ])
function ( require module-name )
function ( __select n , ... )
function ( tobit number )
function ( tohex number )
function ( xpcall function , error-function )
function ( error message )
function ( tostring object )
function ( tonumber object )
function ( __pairs table )
function ( __ipairs table )
function ( __next table [, index ])
function ( rawset table , key , value )
function ( rawget table , key )
function ( % a , b )
function ( pow a , b )
function ( not x )
function ( ~ x )
function ( == a , b )
function ( != a , b )
function ( < a , b )
function ( <= a , b )
function ( > a , b )
function ( >= a , b )
function ( is a , b )
function ( ast-list-prepend list , object , ... )
function ( ast-list-append list , object , ... )
function ( ast-list-slice list , start [, end ])
function ( ast-list-concat a , b )
function ( ast-concat a , b )
function ( trace ast-object )
function ( __call-method table , name [, argument , ... ])
function ( syntax-rules-factory list )
function ( binary-op-chainer-ltr op-name )
function ( binary-op-chainer-rtl op-name )
function ( unary-table-or-chainer-op chainer , op-name )
function ( compound-assign-op op-name )
function ( tupled ... )
function ( table-tupled table )
function ( ipairs table , start )
function ( pairs table )
function ( iter iterable )
function ( map iterable , function )
function ( filter iterable , predicate )
function ( zip iterable-a , iterable-b )
function ( explode iterable )
function ( reduce iterable , function , init-value )
function ( null? object )
function ( cdata? object )
function ( table? object )
function ( function? object )
function ( userdata? object )
function ( number? object )
function ( string? object )
function ( boolean? object )
function ( empty? object )
function ( class? object )
function ( instance? object , class )
function ( super? superclass , class )
function ( ast-expand-symbol-prefix list , syntax-table )
function ( set-syntax-symbol-prefix syntax-table , prefix-name , function )
function ( ast-parse-dot ast-object )
function ( hook-symbol-lookup scope-table , table )
function ( $.insert table , [ index , ] value )
function ( $.remove table [, index ])
function ( $.len table )
function ( $.sort table , compare-function )
function ( $.concat table [, sep [, i [, j ]]])
function ( $.copy table )
function ( $.extend table [, other-table , ... ])
function ( $.update table , other-table )
function ( $.keys table )
function ( $.values table )
function ( $.setmeta table , metatable )
function ( $.sethiddenmeta table , metatable )
function ( $.meta table )
function ( $.set table )
function ( __syntax-export package-name , content , init )
function ( __syntax-import package-name , env , replace )
function ( listrepr object )
function ( repr object )
function ( help object )

Global Objects

var ast
var Exception
var package
var MethodType
var math
var io
var os
var string
var ffi

Special Forms

None’s 16 special forms and 3 special macros are the barebone building blocks from which the rest of the language is bootstrapped. Only these objects and a handful of global functions are available before the core library is imported.

As such, they are only of interest to users seeking to completely replace the default namespace or override default behavior, and play no role in day to day usage of None.

By design, special forms do not use the macro system to expand their arguments; it is only later that they are overriden by expanding macros. A special form expects all nested expressions to be literals, symbols or special forms.

special ( __call special-function-expression [, special-argument-expression , ... ])

Evaluates a function.

Parameters:
  • special-function-expression – An expression that evaluates to a callable object.
  • special-argument-expression – Zero or more expressions that evaluate to the arguments passed to the function to be evaluated.
Returns:

The return value of the evaluated function.

special ( __var variable-name , special-init-expression )

Declares and initialize a new variable that becomes accessible to subsequent expressions in the active scope. Redeclaring a variable with the same name in the active scope is a syntax error.

Parameters:
  • variable-name (symbol) – The name of the variable to be defined.
  • special-init-expression – An expression that evaluates to the value to be assigned to the variable name.
Returns:

the value of special-init-expression.

special ( __set special-variable-expression , special-value-expression )

Assigns a value to a variable or a table key.

Parameters:
  • special-variable-expression – The name of the variable to be changed, a __key expression, or a global name.
  • special-value-expression – An expression that evaluates to the value to be assigned.
Returns:

the value of special-value-expression.

special ( __key special-table-expression , special-key-expression )

Retrieves a value stored in a table at a given key.

Parameters:
  • special-table-expression (table) – An expression that evaluates to the table to be searched for special-key-expression.
  • special-key-expression – An expression that evaluates to the key under which the value is stored. Must not be null.
Returns:

the value of the key or null if missing.

special ( __do special-expression , ... )

Evaluates a list of expressions in a new scope. Variables declared using __var are only valid until __do returns.

Parameters:
  • special-expression – Zero or more expressions to be evaluated. Only the last expression’s value will be returned. Literals and symbols not last in the list will be ignored.
Returns:

the value of the last expression argument.

special ( __do-splice special-expression , ... )

Evaluates a list of expressions in the existing scope. __do-splice is only safe to use within the scope created by __function or __do.

Parameters:
  • special-expression – Zero or more expressions to be evaluated. Only the last expression’s value will be returned. Literals and symbols not last in the list will be ignored.
Returns:

the value of the last expression argument.

special ( __function ([ parameter-name , ... ]), special-expression , )

Constructs an unnamed first-order function with the given parameters and a single expression to be evaluated. The function can be instantiated using __call. Variables declared using __var within the scope of the function are only valid until the function has been evaluated.

Parameters:
  • parameter-name – Zero or more parameter names that bind arguments passed by the caller to the function’s top level scope. The names are accessible as variables for the duration of special-expression.
  • special-expression – An expression that will be evaluated when the function is applied to a list of arguments using __call.
Returns:

a new function object.

special ( __if special-condition-expression , special-then-expression , special-else-expression )

Conditionally evaluates two expressions based on the value of a third.

Parameters:
  • special-condition-expression – An expression whose value selects the subsequent expression to be evaluated. A value of null or false is interpreted as logical false and causes special-else-expression to be evaluated. Otherwise, logical true is assumed and special-then-expression is evaluated.
  • special-then-expression – The expression to be evaluated if special-condition-expression evaluates to logical true.
  • special-else-expression – The expression to be evaluated if special-condition-expression evaluates to logical false.
Returns:

the value of the selected branch expression.

special ( __while special-condition-expression , special-expression )

Repeatedly evaluate an expression until an exit condition is reached. The loop can also be exited using __break.

Parameters:
  • special-condition-expression – An expression to be evaluated at the beginning of each loop. A value of null or false is interpreted as logical false and causes the loop to abort. Otherwise, logical true is assumed, special-expression is evaluated and the loop repeats.
  • special-expression – An expression to be evaluated at the end of each loop. Calling __break anywhere within the loop’s scope aborts the loop prematurely.
Returns:

null

special ( __break )

Untimely abort a __while loop. Calling __break outside of __while is a syntax error.

special ( __scope )

Constructs a new table mapping each variable name in the active scope to its value.

Returns:the new scope table.
special ( __del variable-name )

Deletes a variable in the active scope previously declared by __var.

Returns:null
special ( __global variable-name [, table-name ])

Allows global variable look-ups for a specified name for the lifetime of the active scope.

Parameters:
  • table-name – If specified, the name of an alternative table to use for the lookup.
Returns:

null

special ( __quote special-expression )

Constructs an AST object from an expression instead of evaluating it.

Parameters:
  • special-expression – The expression to be quoted.
Returns:

an AST object representing the expression.

special ( __nop )

Contemplates the futility of existence.

Returns:null
special ( __pragma pragma-option [, special-expression , ... ])

Influences compiler behavior to aid with language debugging. Internally used and subject to change.

special ( __unpack special-table-expression )

Splices elements of a table array into function arguments. Only valid when used as an argument to __call.

Special Macros

Special macros are defined before the runtime environment is bootstrapped. The runtime environment then provides its own implementation for completeness.

macro ( __meta-eval expression , ... )

Evaluates a list of expressions within a new compiler context in a new top level scope that runs before the remainder of the source file has been translated. This can be used to patch the compiler’s environment with new macros and syntax handlers allowing the compiler to successfully translate the rest of the file.

The value returned by the last expression is spliced in place of the call to __meta-eval and is expected to be a valid AST object, including null.

macro ( __do expression , ... )

This is the expanding form of __do, applying the built-in syntax expander on every argument and returning the final, escaped special form.

macro ( __escape expression )

When the syntax expander encounters this expression, the __escape part is removed and the remainder returned unaltered. This functionality can be used to terminate syntax expansion.

This is a pseudo-macro that has been hardcoded into the macro expansion routine and can not be overridden.

These macros are defined at the beginning of the runtime bootstrapping process and add macro expansion and optional parameters to the special forms. Each macro returns an expanded and escaped version of itself.

macro ( __if conditional-expression , then-expression [, else-expression ])
macro ( __while conditional-expression , loop-expression )
macro ( __break )
macro ( __set-scope table-expression )
macro ( __var variable-name [, init-expression ])
macro ( __key table-expression , key-expression )
macro ( __set variable-expression , value-expression )
macro ( __function ([ parameter-name , ... ]), expression , )
macro ( __unpack table-expression )
macro ( __call function-expression [, argument-expression , ... ])
macro ( __do-splice expression , ... )
macro ( __quote special-expression )

Static Language Reference

Types

static-type void
static-type int
static-type uint
static-type bool
static-type double
static-type float
static-type int8
static-type int16
static-type int32
static-type int64
static-type uint8
static-type uint16
static-type uint32
static-type uint64
static-type opaque
static-type rawstring

Symbols

var NULL
var static-ast
var static-compile-settings
var epsilon-float
var epsilon-double

Macros

infix-macro ( return-type <-([ argument-type , ... ]))
Precedence:800
Associativity:>
macro ( struct name , expression , ... )
Parameters:
  • name – if symbolic, a declaration in the current scope, otherwise an expression expected to resolve to a string.
macro ( <- return-type ([ argument-type , ... ]))
macro ( offsetof type , name )
macro ( & x )
macro ( static-quote expression )
macro ( const [ name , ] : type , init , ... )
macro ( static [ name , ] : type [, init , ... ])
macro ( static [ name , ]([ argument , ... ]) : , type , expression , ... , )
macro ( static name , ( * ) static-function , ... , )
macro ( static-macro function )
macro ( static-macro [ name , ]([ argument , ... ]), expression , ... , )
macro ( static-intrinsic function )
macro ( static-intrinsic [ name , ]([ argument , ... ]), expression , ... , )

Struct Syntax Macros

symbol-prefix &symbol,
infix-macro ( name , : type )
Precedence:50
Associativity:<
infix-macro ( return-type <--([ argument-type , ... ]))
Precedence:800
Associativity:>
macro ( union expression , ... )
macro ( metamethod name , ([ arguments , ... ]) : , type , expression , ... , )
macro ( macro-metamethod name , ([ arguments , ... ]), expression , ... , )
macro ( method name , ([ arguments , ... ]) : , type , expression , ... , )
macro ( method name , ( * ) expression , ... , )
macro ( field name , type )
macro ( using field-definition )

Static Symbol Prefix Macros

static-symbol-prefix &, symbol,
static-symbol-prefix *symbol,

Static Macros

static-macro ( escape expression )
static-macro ( cloop variable-name , ( start , stop , step ), expression , ... , )
static-macro ( alias-cast type , expression )

Functions

function ( arrayof object , ... )
function ( vectorof object , ... )
function ( string-array string , ... )
function ( byte-offset count )
function ( overload function , ... )
function ( static-global type , init )
function ( static-symbol type , name )
function ( static-type? object )
function ( static-list? object )
function ( static-rawlist? object )
function ( static-function? object )
function ( static-function-definition? object )
function ( static-constant? object )
function ( static-macro? object )
function ( static-quote? object )
function ( static-symbol? object )
function ( static-newlist [ argument , ... ])
function ( static-new type [, init , ... ])
function ( static-constant object )
function ( static-offsetof struct , name )
function ( static-build filename , [ filetype , ] functiontable [, arguments , target ])
function ( c-require filename [, compiler-options ])
function ( c-define c-source-string [, compiler-options ])
function ( static-list-insert list , [ index , ] element )
function ( static-ast? object )
function ( static-trace object )
function ( void? object )
function ( static-functype argument-list , return-type )
function ( static-struct name , field-list )
function ( static-field name , type )
function ( tuple [ type , ... ])
function ( vector type , count )
function ( ^& type )
function ( cast type , object )
function ( static-typeof object )
function ( sizeof object )
function ( static-macro-fallback macro-function , lua-function )
function ( float== a , b )

AST Node Constructors

function ( static-arrayof type , expression-list )
function ( static-vectorof type , expression-list )
function ( static-tuple expression-list )
function ( static-sizeof-op expression )
function ( static-op return-type , op-name , argument-list )
function ( static-defer expression )
function ( static-call function [, argument , ... ])
function ( static-cast type , argument-list )
function ( static-method-call expression , name , argument-list )
function ( static-do statement-list )
function ( static-do-splice statement-list )
function ( static-for symbol , start , stop , step , statement-list )
function ( static-while expression , statement-list )
function ( static-repeat-until expression , statement-list )
function ( static-break )
function ( static-var symbol , expression )
function ( static-return expression )
function ( static-ref expression )
function ( static-deref expression )
function ( static-if expression , then-statement-list , else-statement-list )
function ( static-ifexpr expression , then-expression , else-expression )
function ( static-select expression , true-expression , false-expression )
function ( static-in statement-list , expression-list )
function ( static-assign lhs-expression , rhs-expression )
function ( static-subscript expression , name )
function ( static-member expression , name )
function ( static-argument functype , index , name )
function ( static-function argument-list , functype , statement-list [, name [, filename ]])

Special Forms

Indices and tables