Skip to content

Instantly share code, notes, and snippets.

@oleganza
Last active August 21, 2019 22:03
Show Gist options
  • Save oleganza/b8f353a44cf59973cf8f5434f1d21a2e to your computer and use it in GitHub Desktop.
Save oleganza/b8f353a44cf59973cf8f5434f1d21a2e to your computer and use it in GitHub Desktop.

Rust Script

A scripting variant of the Rust language: syntactic sugar for runtime memory ownership rules and other dynamic features, with none of the static ones.

The goal is to have a good complimentary language that's easier to write and tinker with, while interoperating with Rust easily.

"Rust learned from Ruby. What if Ruby learned from Rust?"

File extension

example.rustscript

Conventions

Same braces and indentation, CamelCase for constants, snake_case for variables and functions, etc.

Concepts

Type system

There are types that are both structs and traits.

The language is optimized for simplicity and safety. Performance optimizations are delegated to Rust (e.g. if you want an array of integers of specific width - use Rust).

Method dispatch is dynamic, but at type granularity, via a chosen and checked trait cast. Function declarations required to specify traits. Trait cast is done automatically per declared trait in the arguments list, but can be re-cast to any other trait. Cast fails if the object itself, or none of its types implement the trait.

In the function declaraton, the types are resolved within the function's scope:

fn function(x: T) -> U {
    x.method()
}

is equivalent to

fn function(x: Any) -> Any {
    // TBD: lookup T in the current scope-tree
    x.as(T).method()
}
function(x).as(U)

The recipient gets the reference to an object associated with a specific type reference.

Runtime object model

Everything is an object with slots.

Each slot has attributes:

  • public / private
  • borrowed / mut-borrowed / owned

Memory ownership

Same rules as for RefCell: a scope can have ownership of a value, a mutable reference to a value, or an immutable reference to a value.

Unlike Rust, but more like Ruby, the syntax is defaulting to immutable references. The move or mutable referencing needs to be explicitly specified.

// Rust           
fn foo(x: T);        // x.as(T)
fn foo(x: &T);       // x.borrow(T)
fn foo(x: &mut T);   // x.borrow_mut(T)

Shared references (RC) are created via .share method on Shared.new(obj).

Thread safety

By default, non-thread-safe Rc/Weak are used for performance. Type Mutex produces thread-safe references.

Basic types

Any - a type that has as coercion method.

I64 - a signed 64-bit integer type.

U64 - an unsigned 64-bit integer type.

Float - a double-precision floating point type.

Vec - array of other types.

Map - key-value dictionary of other types.

String - utf8 string.

...

Enums

TBD: Runtime-based matching.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment