Bridges

Two kinds of starting point. The Language Bridges are for programmers who already know another language and want to write JaiScript. The Code Migrations are for C++ code that already uses a library JaiScript replaces, and wants to move onto JaiScript's equivalent.

Language Bridges

Each bridge sets a language beside JaiScript idiom by idiom, then lists the places where a habit from it gets a different answer, each with a sample that shows what JaiScript does, and ends with a complete program written the way that audience would write it. Every code sample was executed on both backends (tree-walking interpreter and bytecode VM); the output shown beneath each example is the real, verified output.

Run a sample by saving it as try.jai and running jaiscript try.jai with the standalone runner (Hello & Basics has the two-minute setup). The static checker is always on, and strict, so a typed mistake it can see stops the load before anything runs.

After a bridge, the Language Guide covers every rule in depth, starting from the same place each bridge points to first: Value Semantics & References.

  1. From JavaScript

    var, function, template strings and ?. carry over, with let, arrow functions, ??, do ... while and the array helpers (map, reduce, find, ...). Assignment copies arrays and objects, == compares contents and never converts, 7 / 2 is 3, lambdas name what they capture.

  2. From C++

    Value classes, references, destructors, operators and capture lists mean what they mean in C++. No pointers or templates, a narrow const; a defined evaluation order, checked overflow, no slicing, and a switch that never falls through.

  3. From C#

    Classes, override, statics and yield look familiar, but a class is a value type: new makes the shared reference. var is dynamic and auto is C#'s var; properties are accessor methods, and coroutines replace async.

Code Migrations

Each migration maps a C++ library's types and calls to their JaiScript spelling, converts real code from one to the other, and then covers the behavior that changes, where a straight translation compiles and gives another result. The C++ on these pages was compiled against the libraries it names, and the JaiScript samples ran on both backends.

  1. From Cereal

    Cereal's archives, names, save/load splits, versions, polymorphic registration and pointer identity mapped to JaiScript's archives, a converted save game, the JAI_PROPERTY route that deletes the serialize functions, both libraries in one function during the transition, converting existing files once, and the Boost.Serialization spellings of all of it.

  2. From Boost.Signals2

    signal, connection, scoped_connection, track, blocks and combiners mapped to jai::signal; a class converted; and what behaves differently: the private emitter, a handle that is the connection, connecting and disconnecting during an emit, the per-signal lock. Notes for Qt and sigslot code.

  3. From ChaiScript Bindings

    fun, user_type, constructor, base_class, modules, globals, eval and eval_error mapped to the engine and dynamic_binder, from a real host's binding block; then the script habits that change: containers copy, interpolation uses backticks, integers are 64-bit and checked.

  4. From sol2 (Lua) Bindings

    new_usertype, constructors, property, overload, bases, meta functions, tables and protected calls mapped to the engine and dynamic_binder, from a real host's binding block; then the Lua habits that change: tables become values, indexes start at 0, / truncates between integers, 0 is false.

  5. From Squirrel Bindings

    The stack-based C API (sq_newclosure, sq_newclass with type tags, sq_call, sq_getlasterror) mapped to the engine and dynamic_binder, from a real host's binding block; then the Squirrel habits that change: instances, arrays and tables copy, the empty string is false, generators become coroutines.

  6. From pybind11 and Boost.Python

    class_, init, def_readwrite, def_property, overload_cast, holders, error_already_set and calls into Python mapped to dynamic_binder and the engine, a class converted from both libraries, and what has no counterpart: keyword arguments, trampolines, the GIL.

  7. From nlohmann::json

    NLOHMANN_DEFINE_TYPE_*, dump and get<T> mapped to the archives, the record format they write, and loose documents moved to script, where from_json gives maps and arrays and to_json writes plain JSON.

  8. From Qt Properties, RTTR and refl-cpp

    Q_PROPERTY, RTTR registration and REFL_AUTO mapped to JAI_PROPERTY: declaring, walking, reading and writing by name, NOTIFY as an observable property, script access, and what has no counterpart: metadata, compile-time iteration, dynamic properties.

  9. From Lua Coroutines and C++20 Schedulers

    coroutine.create, yield, resume and status, and C++20 promise types and schedulers, mapped to coroutine functions with next(), next(n) and done(); a patrol converted three ways, hosting handles from C++, budgets and hot reload.