diff --git a/index.html b/index.html index 9a92103ae..1db34fc53 100644 --- a/index.html +++ b/index.html @@ -985,7 +985,7 @@

Cyber Docs

-
v0.4-dev 195-2fbe57c
+
v0.4-dev 226-6d3dca8
^topic @@ -1246,8 +1246,9 @@

Contextual keywords. ^topic

Literals. #

^topic @@ -1340,7 +1341,7 @@

Operator overloading. Zero values. #

Uninitialized type fields currently default to their zero values. However, this implicit behavior will be removed in the future in favor of a default value clause. Zero values must then be expressed using the reserved zero literal.

The following shows the zero values of builtin or created types:

-
TypeZero value
booleanfalse
int0
float0.0
String''
ArrayArray('')
List[]
MapMap{}
type SS{}
#host type SS.$zero()
dynamicint(0)
anyint(0)
?SOption(S).none
^topic +
TypeZero value
booleanfalse
int0
float0.0
String''
ArrayArray('')
List[]
MapMap{}
type SS{}
@host type SS.$zero()
dynint(0)
anyint(0)
?SOption[S].none
^topic

Type casting. #

The as keyword can be used to cast a value to a specific type. Casting lets the compiler know what the expected type is and does not perform any conversions.

If the compiler knows the cast will always fail at runtime, a compile error is returned instead.

@@ -1421,13 +1422,13 @@

Basic Types. #

  • Symbols.
  • any.
  • -
  • dynamic.
  • +
  • dyn.
  • ^top

    In Cyber, there are primitive types and object types. By default, primitives are copied around by value and don't need additional heap memory or reference counts.

    -

    Primitives include Booleans, Floats, Integers, Enums, Symbols, and Error Values.

    +

    Primitives include Booleans, Floats, Integers, Enums, Symbols, and Error Values.

    Object types include Lists, Tuples, Maps, Strings, Arrays, Objects, Lambdas, Fibers, Choices, Optionals, Pointers, and several internal object types.

    Booleans. #

    Booleans can be true or false. See type bool.

    @@ -1638,7 +1639,7 @@

    Lists. #

    ^topic

    Tuples. #

    -

    Incomplete: Tuples can only be created from #host funcs at the moment.

    +

    Incomplete: Tuples can only be created from @host funcs at the moment.

    ^topic

    Tables. #

    A Table is a versatile object that can have an arbitrary set of fields.

    @@ -1729,14 +1730,15 @@

    Map block. #

    ^topic

    Symbols. #

    -

    Symbol literals begin with ., followed by an identifier. They have their own global unique id.

    -
    var currency = .usd
    -print(currency == .usd)   -- 'true'
    -print int(currency)       -- '123' or some arbitrary id.
    +

    Symbol literals begin with symbol., followed by an identifier. +Each symbol has a global unique ID.

    +
    var currency = symbol.usd
    +print currency == .usd   --> true
    +print int(currency)      --> 
     
    ^topic

    any. #

    -

    Unlike dynamic, any is statically typed and performs type checks at compile-time. +

    Unlike dyn, any is statically typed and performs type checks at compile-time. any type can hold any value, but copying it to narrowed type destination will result in a compile error:

    func square(i int):
         return i * i
    @@ -1751,7 +1753,7 @@ 

    any. #

    print square(a as int)    --> 100
     
    ^topic -

    dynamic. #

    +

    dyn. #

    The dynamic type defers type checking to runtime. However, it also tracks its own recent type in order to surface errors at compile-time. See Dynamic Typing.

    ^topic

    Custom Types. #

    @@ -1844,7 +1846,7 @@

    Field visibility. #Default field values. #

    When a field is omitted in the record literal, it gets initialized to its zero value:

    var node Node = {value: 234}
    -print node.next       -- Prints "Option.none"
    +print node.next    --> Option.none
     
     type Student:
         name String
    @@ -1852,9 +1854,9 @@ 

    Default field values. +print s.age --> 0 +print s.gpa --> 0.0

    ^topic

    Circular references. #

    @@ -2031,17 +2033,17 @@

    Choices. #

    ^topic

    Initialize choice. #

    -

    If the payload is an object type, the choice can be initialized with a simplified record literal:

    -
    var s = Shape.rectangle{width: 10, height: 20}
    -
    -

    The general way to initialize a choice is to pass the payload as an argument:

    +

    The general way to initialize a choice is to invoke the initializer with the payload as the argument:

    var rect = Rectangle{width: 10, height: 20}
    -var s = Shape{rectangle: rect}
    +var s = Shape.rectangle(rect)
     
    -s = Shape{line: 20}
    +s = Shape.line(20)
    +
    +

    If the payload is a record-like type, the choice can be initialized with a record literal:

    +
    var s = Shape.rectangle{width: 10, height: 20}
     
    -

    A choice without a payload is initialized with an empty record literal:

    -
    var s = Shape.point{}
    +

    A choice without a payload is initialized like an enum member:

    +
    var s = Shape.point
     
    ^topic

    Choice switch. #

    @@ -2064,19 +2066,19 @@

    Choice switch. #Access choice. #

    A choice can be accessed by specifying the access operator .! before the tagged member name. This will either return the payload or panic at runtime: Planned Feature

    var s = Shape{line: 20}
    -print s.!line     -- Prints '20'
    +print s.!line     --> 20
     
    ^topic

    Optionals. #

    Optionals provide Null Safety by forcing values to be unwrapped before they can be used.

    The generic Option type is a choice type that either holds a none value or contains some value. The option template is defined as:

    -
    template(T type)
    +
    template[T type]
     type Option enum:
         case none
         case some #T
     

    A type prefixed with ? is the idiomatic way to create an option type. The following String optional types are equivalent:

    -
    Option(String)
    +
    Option[String]
     ?String
     
    ^topic @@ -2114,7 +2116,7 @@

    Unwrap or default. #

    ^topic

    Optional chaining. #

    -

    Given the last member's type T in a chain of ?. access operators, the chain's execution will either return Option(T).none on the first encounter of none or returns the last member as an Option(T).some: Planned Feature

    +

    Given the last member's type T in a chain of ?. access operators, the chain's execution will either return Option[T].none on the first encounter of none or returns the last member as an Option[T].some: Planned Feature

    print root?.a?.b?.c?.last
     
    ^topic @@ -2187,7 +2189,7 @@

    Union types. #

    ^topic

    Generic types. #

    Templates are used to specialize type declarations. Since template parameters only exist at compile-time, the # prefix is used to reference them in the template body:

    -
    template(T type)
    +
    template[T type]
     type MyContainer:
         id    int
         value #T
    @@ -2199,7 +2201,7 @@ 

    Generic types. #

    Expand type template. #

    When the template is invoked with compile-time argument(s), a specialized version of the type is generated.

    In this example, String can be used as an argument since it satisfies the type parameter constraint:

    -
    var a MyContainer(String) = {id: 123, value: 'abc'}
    +
    var a MyContainer[String] = {id: 123, value: 'abc'}
     print a.get()      -- Prints 'abc'
     

    Note that invoking the template again with the same argument(s) returns the same generated type. In other words, the generated type is always memoized from the input parameters.

    @@ -2414,7 +2416,11 @@

    Functions. #

  • Call block syntax.
  • -
  • Generic functions.
  • +
  • Generic functions. +
  • ^top

    In Cyber, there are first-class functions (or function values) and static functions.

    @@ -2434,7 +2440,7 @@

    Static functions. #-- Assigning to a local variable. var bar = dist -func squareDist(dist dynamic, size float) float: +func squareDist(dist dyn, size float) float: return dist(0.0, 0.0, size, size) -- Passing `dist` as an argument. @@ -2554,8 +2560,26 @@

    Call block syntax. #

    In the example above, the function foo is called with 4 arguments. The first argument 123 is included in the starting call expression. The second argument is a function value inside the call expression block. The third argument is mapped to the param param3. Finally, the fourth argument is a list that contains 234, bar(), and 'hello'.

    ^topic

    Generic functions. #

    -

    Planned Feature

    -
    ^topic +

    Templates are used to specialize function declarations. Since template parameters only exist at compile-time, the # prefix is used to reference them in the function declaration:

    +
    template[T type]
    +func add(a #T, b #T) #T:
    +    return a + b
    +
    +^topic +

    Expand function template. #

    +

    When the template is invoked with compile-time argument(s), a specialized version of the function is generated:

    +
    print add[int](1, 2)    --> 3
    +print add[float](1, 2)  --> 3.0
    +
    +

    Note that invoking the template again with the same argument(s) returns the same generated function. In other words, the generated function is always memoized from the input parameters.

    +^topic +

    Infer template function. #

    +

    When invoking template functions, it is possible to infer the template parameters from the call arguments. +In the following example, add[int] and add[float] are inferred from the function calls:

    +
    print add(1, 2)      --> 3
    +print add(1.0, 2.0)  --> 3.0
    +
    +^topic

    Modules. #

    @@ -2574,7 +2598,7 @@

    Modules. #

  • Symbol visibility.
  • Symbol alias.
  • Builtin modules.
  • -
  • module core
  • @@ -2739,12 +2763,12 @@

    Symbol alias. #

    Builtin modules. #

    Builtin modules are the bare minimum that comes with Cyber. The embeddable library contains these modules and nothing more. They include:

      -
    • core: Commonly used utilities.
    • -
    • cy: Cyber related functions.
    • -
    • math: Math constants and functions.
    • +
    • core: Commonly used utilities.
    • +
    • cy: Cyber related functions.
    • +
    • math: Math constants and functions.
    ^topic -

    module core #

    +

    mod core #

    The core module contains functions related to Cyber and common utilities. It is automatically imported into each script's namespace.

    Sample usage:

    -- `print` and `typeof` are available without imports.
    @@ -2772,7 +2796,7 @@ 

    module core #

    Returns whether a boxed value is the none case of a generic Option(T) type. This is temporary and may be removed in a future release.

    func must(val any) any

    If val is an error, panic(val) is invoked. Otherwise, val is returned.

    -

    func panic(err any) dynamic

    +

    func panic(err any) dyn

    Stop execution in the current fiber and starts unwinding the call stack. See Unexpected Errors.

    func performGC() Map

    Runs the garbage collector once to detect reference cycles and abandoned objects. Returns the statistics of the run in a map value.

    @@ -2795,7 +2819,7 @@

    type error #

    func sym() symbol

    Return the underlying symbol.

    func error.$call(val any) error

    -

    Create an error from an enum or symbol.

    +

    Create an error from symbol.

    ^topic

    type int #

    func $prefix~() int

    @@ -2841,25 +2865,25 @@

    type placeholder1 ^topic

    type placeholder2 #

    ^topic -

    type placeholder3 #

    +

    type taglit #

    ^topic -

    type dynamic #

    +

    type dyn #

    ^topic

    type any #

    ^topic

    type type #

    ^topic

    type List #

    -

    func $index(idx int) dynamic

    -

    func $index(range Range) List

    -

    func $setIndex(idx int, val any)

    +

    func $index(idx int) T

    +

    func $index(range Range) List[T]

    +

    func $setIndex(idx int, val T)

    func append(val any)

    Appends a value to the end of the list.

    -

    func appendAll(list List)

    +

    func appendAll(list List[T])

    Appends the elements of another list to the end of this list.

    -

    func insert(idx int, val any)

    +

    func insert(idx int, val T)

    Inserts a value at index idx.

    -

    func iterator() ListIterator

    +

    func iterator() ListIterator[T]

    Returns a new iterator over the list elements.

    func join(sep String) String

    Returns a new string that joins the elements with separator.

    @@ -2871,25 +2895,25 @@

    type List #

    Resizes the list to len elements. If the new size is bigger, none values are appended to the list. If the new size is smaller, elements at the end of the list are removed.

    func sort(lessFn any)

    Sorts the list with the given less function. If element a should be ordered before b, the function should return true otherwise false.

    -

    func List.fill(val any, n int) List

    +

    func List.fill(val T, n int) List[T]

    Creates a list with initial capacity of n and values set to val. If the value is an object, it is shallow copied n times.

    ^topic

    type ListIterator #

    -

    func next() ?any

    +

    func next() ?T

    ^topic

    type Tuple #

    func $index(idx int) any

    ^topic

    type Table #

    func $initPair(key String, value any)

    -

    func $get(name String) dynamic

    +

    func $get(name String) dyn

    func $set(name String, value any)

    -

    func $index(key any) dynamic

    +

    func $index(key any) dyn

    func $setIndex(key any, value any)

    ^topic

    type Map #

    func $initPair(key any, value any)

    -

    func $index(key any) any

    +

    func $index(key any) dyn

    func $setIndex(key any, val any)

    func contains(key any) bool

    Returns whether there is a value mapped to key.

    @@ -2938,11 +2962,11 @@

    type String #

    Returns the starting byte index for the rune index idx.

    func sliceAt(idx int) String

    Returns the UTF-8 rune starting at byte index idx as a string.

    -

    func $index(idx int) String

    +

    func $index(idx int) int

    Returns the rune at byte index idx. The replacement character (0xFFFD) is returned for an invalid UTF-8 rune.

    func $index(range Range) String

    Returns a slice into this string from a Range with start (inclusive) to end (exclusive) byte indexes.

    -

    func split(sep String) List

    +

    func split(sep String) List[String]

    Returns a list of UTF-8 strings split at occurrences of sep.

    func startsWith(prefix String) bool

    Returns whether the string starts with prefix.

    @@ -2992,7 +3016,7 @@

    type Array #

    func $index(idx int) int

    func $index(range Range) Array

    Returns a slice into this array from a Range with start (inclusive) to end (exclusive) indexes.

    -

    func split(sep Array) List

    +

    func split(sep Array) List[Array]

    Returns a list of arrays split at occurrences of sep.

    func startsWith(prefix Array) bool

    Returns whether the array starts with prefix.

    @@ -3043,7 +3067,7 @@

    type Box #

    type TccState #

    ^topic -

    module cy #

    +

    mod cy #

    The cy module contains functions related to the Cyber language.

    Sample usage:

    use cy
    @@ -3063,7 +3087,7 @@ 

    module cy #

    Encodes a value to CYON string.

    ^topic -

    module math #

    +

    mod math #

    The math module contains commonly used math constants and functions.

    Sample usage:

    use math
    @@ -3180,12 +3204,12 @@ 

    module math #

    Std modules. #

    Std modules come with Cyber's CLI. They include:

      -
    • cli: Related to the command line.
    • -
    • os: System level functions.
    • -
    • test: Utilities for testing.
    • +
    • cli: Related to the command line.
    • +
    • os: System level functions.
    • +
    • test: Utilities for testing.
    ^topic -

    module cli #

    +

    mod cli #

    The cli module contains functions related to the command line.

    Sample usage:

    use cli
    @@ -3199,7 +3223,7 @@ 

    module cli #

    Default implementation to read a line from the CLI for a REPL.

    ^topic -

    module os #

    +

    mod os #

    Cyber's os module contains system level functions. It's still undecided as to how much should be included here so it's incomplete. You can still access os and libc functions yourself using Cyber's FFI or embedding API.

    Sample usage:

    use os
    @@ -3226,8 +3250,8 @@ 

    module os #

    Default SIMD vector bit size.

    func access(path String, mode symbol)

    Attempts to access a file at the given path with the .read, .write, or .readWrite mode. Throws an error if unsuccessful.

    -

    func args() List

    -

    Returns the command line arguments in a List. Each argument is converted to a String.

    +

    func args() List[String]

    +

    Returns the command line arguments in a List[String].

    func cacheUrl(url String) String

    Returns the path of a locally cached file of url. If no such file exists locally, it's fetched from url.

    func copyFile(srcPath String, dstPath String)

    @@ -3242,7 +3266,7 @@

    module os #

    Returns the current working directory.

    func dirName(path String) ?String

    Returns the given path with its last component removed.

    -

    func execCmd(args List) Map

    +

    func execCmd(args List[String]) Map

    Runs a shell command and returns the stdout/stderr.

    func exePath() String

    Returns the current executable's path.

    @@ -3270,7 +3294,7 @@

    module os #

    Opens a directory at the given path. iterable indicates that the directory's entries can be iterated.

    func openFile(path String, mode symbol) File

    Opens a file at the given path with the .read, .write, or .readWrite mode.

    -

    func parseArgs(options List) Table

    +

    func parseArgs(options List[dyn]) Table

    Given expected ArgOptions, returns a Table of the options and a rest entry which contains the non-option arguments.

    func readAll() String

    Reads stdin to the EOF as a UTF-8 string. To return the bytes instead, use stdin.readAll().

    @@ -3329,7 +3353,7 @@

    type DirIterator ^topic

    type FFI #

    -

    func bindCallback(fn any, params List, ret symbol) ExternFunc

    +

    func bindCallback(fn any, params List[dyn], ret symbol) ExternFunc

    Creates an ExternFunc that contains a C function pointer with the given signature. The extern function is a wrapper that calls the provided user function. Once created, the extern function is retained and managed by the FFI context.

    func bindLib(path ?String) any

    Calls bindLib(path, [:]).

    @@ -3337,9 +3361,9 @@

    type FFI #

    Creates a handle to a dynamic library and functions declared from cfunc. By default, an anonymous object is returned with the C-functions binded as the object's methods. If config contains gen_table: true, a Table is returned instead with C-functions binded as function values.

    func bindObjPtr(obj any) pointer

    Returns a Cyber object's pointer. Operations on the pointer is unsafe, but it can be useful when passing it to C as an opaque pointer. The object is also retained and managed by the FFI context.

    -

    func cbind(mt metatype, fields List)

    +

    func cbind(mt metatype, fields List[dyn])

    Binds a Cyber type to a C struct.

    -

    func cfunc(name String, params List, ret any)

    +

    func cfunc(name String, params List[dyn], ret any)

    Declares a C function which will get binded to the library handle created from bindLib.

    func new(ctype symbol) pointer

    Allocates memory for a C struct or primitive with the given C type specifier. A pointer to the allocated memory is returned. Eventually this will return a cpointer instead which will be more idiomatic to use.

    @@ -3357,7 +3381,7 @@

    Map DirWalkEntry ^topic

    Table ArgOption #

    keysummary
    'name' -> StringThe name of the option to match excluding the hyphen prefix. eg. -path
    'type' -> metatype(String | float | boolean)Parse as given value type.
    'default' -> anyOptional: Default value if option is missing. none is used if this is not provided.
    ^topic -

    module test #

    +

    mod test #

    The test module contains utilities for testing.

    Sample usage:

    use t 'test'
    @@ -3369,8 +3393,7 @@ 

    module test #

    func assert(pred bool)

    Panics if pred is false.

    -

    func eq(a any, b any) bool

    -

    Returns whether two values are equal. Panics with error.AssertError if types or values do not match up.

    +

    func eq(a T, b T) bool

    func eqList(a any, b any) bool

    Returns true if two lists have the same size and the elements are equal as if eq was called on those corresponding elements.

    func eqNear(a any, b any) bool

    @@ -3438,7 +3461,7 @@

    Finalizer. #

    Once the object is released by ARC, the TCCState is also released which removes the JIT code from memory.

    ^topic

    Mappings. #

    -

    When using cfunc or cbind declarations, symbols are used to represent default type mappings from Cyber to C and back:

    +

    When using cfunc or cbind declarations, symbols are used to represent default type mappings from Cyber to C and back:

    Incomplete: This is not the final API for dynamically loading and interfacing with C libraries. The plan is to parse a subset of C headers to bind to Cyber types and functions.

    BindingCyberC
    .boolboolbool
    .charintint8_t, signed char
    .ucharintuint8_t, unsigned char
    .shortintint16_t, short
    .ushortintuint16_t, unsigned short
    .intintint32_t, int
    .uintintuint32_t, unsigned int
    .longintint64_t, long long
    .ulongintuint64_t, unsigned long long
    .usizeintsize_t, uintptr_t
    .floatfloatfloat
    .doublefloatdouble
    (1) .charPtrpointerchar*
    .voidPtrpointervoid*
    (2) type {S}type {S}struct
    1. Use os.cstr() and pointer.fromCstr() to convert between a Cyber string and a null terminated C string.
    2. @@ -3512,8 +3535,8 @@

      Error Handling. #

      • Semantic checks.
      • Stack trace.
      • @@ -3626,9 +3649,9 @@

        Value or error. #

        ^topic

        Semantic checks. #

        ^topic -

        throws specifier. #

        -

        The throws specifier ! indicates that a function contains a throwing expression that was not caught with try catch.

        -

        The specifier is attached to the function return type as a prefix:

        +

        Throws modifier. #

        +

        The throws modifier ! indicates that a function contains a throwing expression that was not caught with try catch.

        +

        The modifier is attached to the function return type as a prefix:

        func foo() !void:
             throw error.Failure
         
        @@ -3640,8 +3663,8 @@

        throws specifier. #

    ^topic -

    throws check. #

    -

    The compiler requires a throws specifier if the function contains an uncaught throwing expression: Planned Feature

    +

    Throws check. #

    +

    The compiler requires a throws modifier if the function contains an uncaught throwing expression: Planned Feature

    func foo(a int) int:
         if a == 10:
             throw error.Failure   --> CompileError.
    @@ -3649,7 +3672,7 @@ 

    throws check. #

    return a * 2 --> CompileError. Uncaught throwing expression. ---> `foo` requires the `!` throws specifier or +--> `foo` requires the `!` throws modifier or --> the expression must be caught with `try`.
    ^topic @@ -3841,12 +3864,13 @@

    Dynamic Typing. #

  • Dynamic functions.
  • Dynamic tables.
  • Custom tables.
  • +
  • Dynamic inference.
  • ^top

    Dynamic typing is supported with a less restrictive syntax. This can reduce the amount of friction when writing code, but it can also result in more runtime errors.

    In Cyber, the let keyword is used exclusively for dynamic declarations.

    Dynamic variables. #

    -

    Variables declared with let are implicitly given the dynamic type:

    +

    Variables declared with let are implicitly given the dyn type:

    let a = 123
     

    Typically a dynamic variable defers type checking to runtime, but if the compiler determines that an operation will always fail at runtime, a compile error is reported instead:

    @@ -3883,8 +3907,8 @@

    Runtime type checking. ^topic

    Dynamic functions. #

    Functions declared with let do not allow typed parameters or a return specifier. -All parameters are implicitly given the dynamic type.

    -

    The return specifier is also implicitly !dynamic which indicates that the function can throw an error. This is only relevant when typed code calls a dynamic function:

    +All parameters are implicitly given the dyn type.

    +

    The return specifier is also implicitly !dyn which indicates that the function can throw an error. This is only relevant when typed code calls a dynamic function:

    let foo(a, b, c):
         return a + b() + a[c]
     
    @@ -3930,6 +3954,13 @@

    Custom tables. #

    let v = Vec3{x: 1, y: 2, z: 3}
    ^topic +

    Dynamic inference. #

    +

    When the inference tag is used in a dynamic context, it will attempt to resolve its value at runtime. +In this example, the dynamic value a resolves to a String at runtime and invokes the typed method trim. +.left then infers to the correct value at runtime:

    +
    print str.trim(.left, ' ')
    +
    +^topic

    Metaprogramming. #

    @@ -3952,8 +3983,11 @@

    Metaprogramming. #

    • Reflection.
    • -
    • Directives.
    • -
    • Generics.
    • +
    • Attributes.
    • +
    • Generics. +
    • Macros.
    • Compile-time execution.
      • Builtin types.
      • @@ -4081,15 +4115,18 @@

        Reflection. #

        print bool -- 'type: bool' ^topic -

        Directives. #

        -

        Directives start with # and are used as modifiers.

        -

        #host

        -

        Modifier to bind a function, variable, or type to the host. See libcyber.

        +

        Attributes. #

        +

        Attributes start with @. They are used as declaration modifiers.

        +

        @host

        +

        Bind a function, variable, or type to the host. See libcyber.

        ^topic

        Generics. #

        Generics enables parametric polymorphism for types and functions. Compile-time arguments are passed to templates to generate specialized code. This facilitates developing container types and algorithms that operate on different types.

        See Custom Types / Generic types and Functions / Generic functions.

        ^topic +

        Template specialization. #

        +

        Planned Feature

        +
        ^topic

        Macros. #

        Planned Feature

        ^topic @@ -4196,7 +4233,7 @@

        Eval script. #

        } else { const char* report = clNewLastErrorReport(vm); printf("%s\n", report); - clFreeStrZ(report); + clFreeZ(report); }

        If a value is returned from the main block of the script, it's saved to the result value argument. @@ -4209,15 +4246,15 @@

        Module Loader. #

        bool modLoader(CLVM* vm, CLStr spec, CLModuleLoaderResult* out) {
             if (strncmp("my_mod", spec.buf, spec.len) == 0) {
                 out->src =
        -            "#host func add(a float, b float) float\n"
        -            "#host var .MyConstant float\n"
        -            "#host var .MyList     List\n"
        +            "@host func add(a float, b float) float\n"
        +            "@host var .MyConstant float\n"
        +            "@host var .MyList     List\n"
                     "\n"
        -            "#host\n"
        +            "@host\n"
                     "type MyCollection:\n"
        -            "    #host func asList() any"
        +            "    @host func asList() any"
                     "\n"
        -            "#host func MyCollection.new(a, b) MyCollection\n";
        +            "@host func MyCollection.new(a, b) MyCollection\n";
                 out->funcLoader = funcLoader;
                 out->varLoader = varLoader;
                 out->typeLoader = typeLoader;
        @@ -4240,7 +4277,7 @@ 

        Default module loader. clDefaultModuleLoader.

        ^topic

        Function loader. #

        -

        A function loader describes how to load a #host function when it's encountered by the compiler. +

        A function loader describes how to load a @host function when it's encountered by the compiler. The loader can bind functions and type methods:

        struct { char* n; CLFuncFn fn; } funcs[] = {
             {"add", add},
        @@ -4258,11 +4295,11 @@ 

        Function loader. #

        } }
        -

        This example uses the CLFuncInfo.idx of a #host function to index into an array and return a Host function pointer. The name is also compared to ensure it's binding to the correct pointer.

        +

        This example uses the CLFuncInfo.idx of a @host function to index into an array and return a Host function pointer. The name is also compared to ensure it's binding to the correct pointer.

        This is an efficient way to map Cyber functions to host functions. A different implementation might use a hash table to map the name of the function to it's pointer.

        ^topic

        Variable loader. #

        -

        A variable loader describes how to load a #host variable when it's encountered by the compiler:

        +

        A variable loader describes how to load a @host variable when it's encountered by the compiler:

        // C has limited static initializers (and objects require a vm instance) so initialize them in `main`.
         typedef struct { char* n; CLValue v; } NameValue;
         NameValue vars[2];
        @@ -4292,7 +4329,7 @@ 

        Variable loader. #

        This example uses the same technique as the function loader, but it can be much simpler. It doesn't matter how the mapping is done as long as the variable loader returns a CLValue.

        ^topic

        Type loader. #

        -

        A type loader describes how to load a #host type when it's encountered by the compiler:

        +

        A type loader describes how to load a @host type when it's encountered by the compiler:

        CLTypeId myCollectionId;
         
         bool typeLoader(CLVM* vm, CLTypeInfo info, CLTypeResult* out) {
        @@ -4862,13 +4899,13 @@ 

        AOT compiler. #

        return { keywords: { keyword: [ - 'template', 'func', 'module', 'for', 'coinit', 'coresume', 'coyield', 'use', + 'template', 'func', 'mod', 'for', 'coinit', 'coresume', 'coyield', 'use', 'return', 'if', 'else', 'as', 'while', 'var', 'let', 'dynobject', 'object', 'struct', 'with', 'caught', 'break', 'continue', 'switch', 'pass', 'or', 'and', 'not', 'is', 'error', 'throws', 'true', 'false', 'none', 'throw', 'try', 'catch', 'recover', 'enum', 'type', 'case' ], type: [ - 'float', 'String', 'Array', 'bool', 'any', 'int', 'List', 'Map', 'symbol', 'pointer', 'dynamic' + 'float', 'String', 'Array', 'bool', 'any', 'int', 'List', 'Map', 'symbol', 'pointer', 'dyn' ], }, contains: [