A rusty dynamically typed scripting language

Overview

dyon

A rusty dynamically typed scripting language

Tutorial
Dyon-Interactive
Dyon Snippets
/r/dyon

Dyon script files end with .dyon.

To run Dyon script files from command line, type:

cargo install --example dyonrun dyon

Then, to run a script file you type:

dyonrun <file.dyon>

Editor-plugins

Dyon for Atom
Dyon for Vim
Dyon for Visual Studio Code

coding

List of features

Why the name Dyon?

Dyon is a hypothetical particle predicted by several grand unified theories in physics with both electrical and magnetic charge. See this Wikipedia article for more information.

The name Dyon fits because, just like the particle, there are things that are yet to be discovered about language design. However, this language was not born out of a grand new vision, but is the result of exploring and testing new ideas.

Motivation and goals

Sven Nilsen started this project in early 2016. The idea was to make a simple, but convenient scripting language that integrated well with Rust.

  • During the first week of coding, a way to do lifetime checking on function arguments was discovered
  • A different approach to code organization was explored by adding the ability to dynamically load modules
  • For nice error handling, added option, result and ? operator
  • To test the design of the language, created a demo for interactive coding
  • Mutability check to improve readability
  • Short For loop to improve readability and performance
  • Mathematical loops and Unicode symbols to improve readability
  • Go-like coroutines to add multi-thread support
  • 4D vectors with unpack and swizzle to make 2D and 3D programming easier
  • Html hex colors to make copying colors from image editors possible
  • Optional type system to help scaling a project
  • Ad-hoc types for extra type safety
  • Current objects to improve prototyping and tailored environments
  • Macros for easier embedding with Rust
  • Secrets to automatically derive meaning from mathematical loops
  • Closures that can be printed out, use current objects and grab from closure environment
  • Type safety for secrets, easy load/save of Dyon data
  • Link loop for easier and faster code generation and templates
  • In-types for easy cross thread communication

Main goals:

  • Integrate well with Rust
  • Flexible way of organizing code

Performance will be optimized for the cycle:

coding -> parsing -> running -> debugging -> coding

Sub goals:

  • Safety

Non-goals:

  • Rust equivalent performance
  • Replace Rust to build libraries
  • Interfacing with other languages than Rust

License

Licensed under either of

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you shall be dual licensed as above, without any additional terms or conditions.

Issues
  • Name collision with Dynamo BIM

    Name collision with Dynamo BIM

    Someone on reddit pointed out that Dynamo is already used by http://dynamobim.org/.

    discussion 
    opened by bvssvni 13
  • Make Hyper/HTTP support an optional feature

    Make Hyper/HTTP support an optional feature

    I would like to request you make Hyper/HTTP support an optional feature, as the language presents a good platform to use for a bunch of project ideas I have, but Hyper (thanks to OpenSSL), is difficult and unpredictable to build on Windows machines, and I think making it an optional feature would both allow for easy building on windows, and the ability to lock down a potential security hole in applications that don't need HTTP support, while also giving the developer the choice to use other HTTP libraries if they so wish (or even simply implement tighter controls on when/where HTTP is allowed).

    easy 
    opened by nicka101 9
  • Higher Order Operator Overloading

    Higher Order Operator Overloading

    Higher Order Operator Overloading (HOOO) is very important for higher order reasoning. For reference, see papers on path semantics notation https://github.com/advancedresearch/path_semantics/blob/master/sequences.md#notation

    By adding HOOO support to Dyon, it could open up a new functional programming paradigm. I suggest that HOOO should inline by default.

    Algebra With Closures

    The syntax for "algebra with closures":

    a := \(x: f64) = x + 1
    b := \(x: f64) = x + 2
    c := a + b
    

    This is the same as:

    a := \(x: f64) = x + 1
    b := \(x: f64) = x + 2
    c := \(x: f64) = {
        a := grab a
        b := grab b
        \a(x) + \b(x)
    }
    

    The above is inlined to this:

    a := \(x: f64) = x + 1
    b := \(x: f64) = x + 2
    c := \(x: f64) = (x + 1) + (x + 2)
    

    This is generalized for any binary and unary operator.

    draft discussion 
    opened by bvssvni 5
  • current object / dynamic scope

    current object / dynamic scope

    The 'current object' feature is interesting, I think it's the same as (or similar to) 'dynamic scope'? https://en.wikipedia.org/wiki/Scope_(computer_science)#Dynamic_scoping

    In lisp I think they have 'defvar ' for this;

    are there any differences, would you change the way you describe it?

    I think it's uncommon in modern languages because the shadowing is less predictable (its also hard to do efficiently), but having 'lexical scope' as the default and something else to make something dynamically scoped seems like the best of both worlds.

    The other suggestion I was going to make was to use a different syntax for it, because I remember the ~foo pointers rust used to have (not sure what though. maybe some keyword infront)

    discussion 
    opened by dobkeratops 5
  • Passing data between two functions called from rust

    Passing data between two functions called from rust

    I'm trying to use dyon as a scripting language for a fantasy console coded in rust. The console calls a init() function defined in the script, then for each frame a render() function is called. How can I pass a context from the init function to the render function ? Using current object doesn't work because render is not called directly by init itself but by the rust part. My idea was to return a context from the init function that the rust engine had to pass as parameter to the render function, but the type is unknown at compile time.

    opened by jice-nospam 5
  • Overhead of Secrets ?

    Overhead of Secrets ?

    Greetings,

    This is not a critical issue since said "overhead" is likely to be negligible, and Dyon is a scripting language anyway, so practical affordances are likely to matter most.

    The thing is, as a reader of the Dyon tutorial, I couldn't help but raise an eyebrow at the concept of "Secrets", for these reasons :

    • I'm hardly convinced by the use cases shown in the tutorial (i.e If I want to pair a bool with a string, I'd rather use a tuple or struct), but those demonstrated in #266 actually look cool and practical;
    • There has got to be some overhead, somewhere, if any bool or f64 is implicitly able to store extra info such as strings. Could it be that bools are actually 32-bit integers which point to string memory if they're not false ? (I don't actually think so, but it's the kind of question that comes to mind).

    IMO the tutorial could benefit from mentioning better, more concrete use cases for Secrets, and explaining how they're implemented under the hood.

    discussion 
    opened by yoanlcq 4
  • Any reason you can't publish the dyon theme for Atom on atom.io?

    Any reason you can't publish the dyon theme for Atom on atom.io?

    Atom has a default package management tool called apm. You can easily put the theme on Atom's official site (aka where it will not only get more downloads but will be easier for other users to receive updates from.) It's very easy to do: literally just go to the folder where it is downloaded, type apm login, and then apm publish patch (for bug fixes) and apm publish minor for minor releases.

    opened by qolop 4
  • Define some broad goals/use cases

    Define some broad goals/use cases

    Given it's place in the Piston project, I've been assuming that dynamo is intended to be used for game scripting. However, that's not explicitly mentioned anywhere and I don't want to spend time writing a proposal that turns out to be inappropriate for your vision of the language.

    If it is game scripting, what kind of level are you expecting it to be best at (keeping in mind that people will contort any language into any situation with enough effort)? Is it intended to be mainly used for large amounts of game logic, or for small bits of custom behaviour?

    I'd like to help with the language, but I don't really know anything about the language to do so.

    discussion 
    opened by Aatch 4
  • Redesign AST to use Vec<Expression>

    Redesign AST to use Vec

    ast::Expression is the most central node in the AST. Currently it uses a lot of Box. It might be that reserving some memory upfront and packing the nodes in a Vec will improve performance a bit.

    • [ ] Redesign to use usize and Vec<Expression>
    • [ ] Test performance before merging
    draft discussion 
    opened by bvssvni 4
  • Simple refinement types

    Simple refinement types

    Dyon is a rusty dynamically typed scripting language.

    What are simple refinement types?

    A simple refinement type system is an "extra layer" of types in addition to the normal type signature of functions. This is used to catch more errors before runtime.

    The extra layer contains special knowledge about the function or alternative semantics from how the function is used.

    Dyon supports ad-hoc types which lets you write e.g. Unknown bool instead of just bool. Simple refinement types in Dyon works seamlessly ad-hoc types.

    For example, one can use this to type check many-valued boolean logic:

    use std as std
    
    fn flip() -> Unknown bool {return if random() < 0.5 {false} else {true}}
    fn tr() -> True bool {return true}
    fn fa() -> False bool {return false}
    
    // Override `!` operator.
    fn not(a: bool) -> bool {return std::not(a)}
        // Use simple refinement types to add extra type information.
        (True bool) -> False bool
        (False bool) -> True bool
        (Unknown bool) -> Unknown bool
    
    fn check_tr(_: True bool) {}
    
    fn main() {
        a := flip()
        check_tr(!a)
    }
    

    The ad-hoc type Unknown bool is constructed by a coin-flip. If you invert a coin-flip, you don't know whether it is true or false, so it is still Unknown bool.

    Dyon detects an error in the code above:

    Type mismatch (#100):
    Expected `True bool`, found `Unknown bool`
    17,14:     check_tr(!a)
    17,14:              ^
    

    In this example, I used simple refinement types to reason about nondeterministic behavior of many-valued boolean logic. Instead of writing code explicitly as many-valued boolean logic, one can use ad-hoc types to lift the many-value logic to type level.

    Design

    For design, see https://github.com/PistonDevelopers/dyon/issues/636

    This PR adds support for simple refinement types in Dyon. This allows e.g. binary operators to be type checked as external functions.

    • Moved all unary and binary operations from runtime to the standard library (see https://github.com/PistonDevelopers/dyon/issues/635)
    • Make std namespace for standard external functions (see https://github.com/PistonDevelopers/dyon/issues/639)
    • Added lots of tests for type refinement
    • Added support for ad-hoc variables in refinement types (see https://github.com/PistonDevelopers/dyon/issues/645)
    • Added support for lazy invariants (see https://github.com/PistonDevelopers/dyon/issues/640)
    • Added check__in_string_imports (type checker knowledge, see https://github.com/PistonDevelopers/dyon/issues/646)
    • Added lazy invariant for unwrap_or

    Improvements in performance

    There is a 4.4% improvement in performance on the n-body benchmark for n=100_000. This is a longer run that is tested manually and measures performance on typical game-logic workloads.

    opened by bvssvni 3
  • Use numbers instead of strings in draw list (Dyon-Interactive)

    Use numbers instead of strings in draw list (Dyon-Interactive)

    Numbers are faster than strings.

    draft discussion 
    opened by bvssvni 0
  • Use Rust objects for images and textures in Dyon-Interactive

    Use Rust objects for images and textures in Dyon-Interactive

    Currently, these are stored in an array and referenced by id.

    draft discussion 
    opened by bvssvni 0
  • Sandbox Untrusted Code?

    Sandbox Untrusted Code?

    Hello! I'm a game developer and I'm considering using dyon in my current project. I was wondering if it has the ability to sandbox untrusted code, as I'd like to have user-created scripts running on clients, and it would obviously be an issue if those scripts could maliciously affect clients. Thank you in advance!

    opened by Aurailus 2
  • Global objects

    Global objects

    A global object is declared at module level with some fields:

    ~ foo { a: f64 }
    
    fn bar() foo {
        println(foo.a)
    }
    fn baz() mut foo {
        foo.a = 42
    }
    

    The global object is created automatically if it doesn't exist already. A global object outlives any other lifetime.

    The globals function returns a list of all global objects:

    fn main() {
        println(globals())
    }
    

    A global can be destroyed, but it will recreated when calling some function accessing it or using it:

    fn main() {
        foo() // Creates global object `foo_object`
        destroy("foo")
        foo() // Recreates global object `foo_object`
    }
    
    ~ foo_object {}
    fn foo() foo_object {}
    

    A global object can inherit from another global object:

    ~ rect { pos: [vec4], size: [vec4] }
    ~ button: rect { label: [str] }
    

    When a global object only contains arrays as members, one can use the for-in syntax:

    fn foo() mut button {
        for b in button {
             b.label = "click me!"
        }
    }
    

    Methods can be declared on global objects that can be used inside for-in syntax:

    ~ rect {
        pos: [vec4],
        size: [vec4],
        min() = pos
        max() = pos + size
    }
    
    fn foo() rect {
        for r in rect {
            println(r.max())
        }
    }
    

    Methods can also combine lists and scalar fields:

    ~ foo {
        a: f64,
        b: [f64],
        bar() = a + b
    }
    

    To insert a new item in a global object, one uses push syntax:

    ~ rect { pos: vec4, size: vec4 }
    
    fn main() {
        foo()
    }
    fn foo() mut rect {
        push rect { pos: (0, 0), size: (0, 0) }
    }
    

    The super function returns the inherited global object of a global object:

    fn super(global: str) -> opt[str] { ... }
    

    The methods function returns a list of methods and their types:

    fn methods(global: str) -> [{}] { ... }
    

    The glob function converts a global into an ordinary object (read-only):

    fn glob(global: str) -> opt[{}] { ... }
    
    draft discussion 
    opened by bvssvni 0
  • Pausing execution

    Pausing execution

    Is it possible in the Rust side to pause the Runtime execution? To have, for example, a function that delays execution without blocking any threads, returning context back to the original Rust caller?

    This would make for great use in game scripting when certain elements are known to have delays that can then, from the Rust end, be continued once time has expired without hogging any resources.

    In the example project, I've seen lots of normal flow functions:

    dyon_fn!{fn mouse_cursor_pos() -> Option<Vec4> {
        unsafe { Current::<Option<Event>>::new()
            .as_ref().expect(NO_EVENT).mouse_cursor_args().map(|pos| pos.into()) }
    }}
    

    However, what I'm after would be similar to a wait_for_keypress(x) function, where the Rust wrapper application handles the actual continuation once the key was pressed, without really blocking the cpu.

    opened by Velocity- 0
  • Dynamically overriding / reloading functions / modules

    Dynamically overriding / reloading functions / modules

    Would it be possible to somehow dynamically rewrite/replace a function or module at runtime, without having to write to a file explicitly? I can't find anything like that documented anywhere.

    My usecase would be to use this in something like a vim-style text-editor where you (even as the user) could re-write functions and add new behaviour to the application at runtime. For this, being able to actually freely override any module or even just function would be a massive addition to flexibility.

    opened by elkowar 2
  • Can you use async with dyon?

    Can you use async with dyon?

    Hello, nice project. I have one question: Can you use async with dyon?

    async fn hello_world() { println!("hello, world!"); }

    can you call this function from dyon?

    opened by onthegit 0
  • Rust object shorthand syntax in macros

    Rust object shorthand syntax in macros

    Dyon supports a shorthand syntax for Rust objects in the dyon_fn macro:

    dyon_fn{fn foo(a: #Foo) {
        ...
    }}
    
    • #Foo - by value (requires the Copy trait)
    • #&Foo - by reference
    • #&mut Foo by mutable reference

    One can also use #Foo as return type:

    dyon_fn{fn new_foo() -> #Foo { ... }}
    
    draft information 
    opened by bvssvni 0
  • no_std support

    no_std support

    I'm working on a no_std project and I'd love to use Dyon for scripting, but I can't easily use it without no_std support. I might implement the support myself and put in a pull request, but that won't happen any time soon.

    opened by alexbuzzbee 1
Releases(v0.36)
  • v0.36(Jun 16, 2018)

    This version adds a way to communicate between threads in Dyon.

    The design is very simple: Any loaded function can be turned into a channel. A new thread can subscribe to input data sent to a function, without having to communicate any new information with the other threads. One thread can listen in on the conversation after other threads have started. This allows reloading diagnostic tools at run-time without ever stopping the whole program. It also functions as a log feature: All data that is sent to a function can be recorded and analyzed later, which makes debugging of multiple threads easier. This can also be used in single-thread applications. The in-type uses Rust's std::sync::mpsc::Receiver which can also be used by external Rust functions.

    • in-types e.g. x := in foo to receive inputs when any thread calls foo
    • for msg in x { ... } loop (same for sum/prod/min/max/any/all/sift/link)
    • msg := next() for next message from in-type
    • msg := wait_next() for waiting for next message from in-type

    Single-thread example:

    fn log(a: f64) {}
    fn main() {
        xs := in log
        for i 10 {log(i)}
        println(sum x in xs {x[0]})
    }
    

    Multi-thread example:

    fn log(a: f64) {}
    fn finish() {}
    fn bar() -> bool {
        return = true
        for i 10 {log(i)}
        finish()
    }
    fn main() {
        xs := in log
        done := in finish
        _ := go bar()
        _ := wait_next(done)
        println(sum x in xs {x[0]})
    }
    
    Source code(tar.gz)
    Source code(zip)
  • v0.9(Sep 19, 2016)

  • v0.8(Jul 11, 2016)

    New features:

    • Infer range from loops
    • Packed loops
    • Secrets
    • Current objects (using hidden dynamical scope)
    • Ad-hoc types
    • Link type
    • Unpack and swizzle 4D vectors
    • vec2/vec3/vec4 un-loops
    • Closures
    • Grab expressions
    • Lazy || and &&
    • Lots of bug fixes
    • Better type inference
    Source code(tar.gz)
    Source code(zip)
Owner
PistonDevelopers
The Piston game engine organization for maintenance and research
PistonDevelopers
Rhai - An embedded scripting language for Rust.

Rhai - Embedded Scripting for Rust Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way to add scripti

Rhai - Embedded scripting language and engine for Rust 1.3k Nov 19, 2021
Scripting language focused on processing tabular data.

ogma Welcome to the ogma project! ogma is a scripting language focused on ergonomically and efficiently processing tabular data, with batteries includ

kdr-aus 45 Nov 18, 2021
A static, type inferred and embeddable language written in Rust.

gluon Gluon is a small, statically-typed, functional programming language designed for application embedding. Features Statically-typed - Static typin

null 2.4k Nov 30, 2021
Source code for the Mun language and runtime.

Mun Mun is a programming language empowering creation through iteration. Features Ahead of time compilation - Mun is compiled ahead of time (AOT), as

The Mun Programming Language 1.2k Nov 22, 2021
Implementation of Immix Mark-Region Garbage collector written in Rust Programming Language.

libimmixcons Implementation of Immix Mark-Region Garbage collector written in Rust Programming Language. Status This is mostly usable library. You can

playX 27 Oct 17, 2021
A computer programming language interpreter written in Rust

Ella lang Welcome to Ella lang! Ella lang is a computer programming language implemented in Rust.

Luke Chu 60 Oct 30, 2021
Oxide Programming Language

Oxide Programming Language Interpreted C-like language with a Rust influenced syntax. Latest release Example programs /// recursive function calls to

Arthur Kurbidaev 98 Nov 19, 2021
The hash programming language compiler

The Hash Programming language Run Using the command cargo run hash. This will compile, build and run the program in the current terminal/shell. Submit

Hash 6 Nov 21, 2021
Interpreted language developed in Rust

Xelis VM Xelis is an interpreted language developed in Rust. It supports constants, functions, while/for loops, arrays and structures. The syntax is s

null 4 Sep 11, 2021
Interactive interpreter for a statement-based proof-of-concept language.

nhotyp-lang Nhotyp is a conceptual language designed for ease of implementation during my tutoring in an introductive algorithmic course at Harbin Ins

Geoffrey Tang 6 Jun 19, 2021
🍖 ham, general purpose programming language

?? ham, a programming language made in rust status: alpha Goals Speed Security Comfort Example fn calc(value){ if value == 5 { return 0

Marc Espín 14 Nov 12, 2021
A small programming language created in an hour

Building a programming language in an hour This is the project I made while doing the Building a programming language in an hour video. You can run it

JT 30 Nov 15, 2021
The Loop programming language

Loop Language Documentation | Website A dynamic type-safe general purpose programming language Note: currently Loop is being re-written into Rust. Mea

LoopLanguage 16 Nov 24, 2021
Stackbased programming language

Rack is a stackbased programming language inspired by Forth, every operation push or pop on the stack. Because the language is stackbased and for a ve

Xavier Hamel 1 Oct 28, 2021
A dynamically typed, interpreted, stack-based language.

Stacc A dynamically typed, interpreted, stack-based language. How does it work? Each call-frame/scope has its own variables and stack, so you can get/

null 8 Nov 12, 2021
Lagoon is a dynamic, weakly-typed and minimal scripting language. 🏞

Lagoon is a dynamic, weakly-typed and minimal scripting language. It draws inspiration from a handful of modern languages including JavaScript, Rust and PHP.

Ryan Chandler 21 Oct 25, 2021
A game made for the Rusty Jam https://itch.io/jam/rusty-jam

Murder-User Dungeon Introduction Tony is a young man. Finally having its own apartment is a good thing! He will learn how to live by himself and how t

null 32 Nov 14, 2021
Dynamically get the suggested clusters in the data for unsupervised learning.

Python implementation of the Gap Statistic Purpose Dynamically identify the suggested number of clusters in a data-set using the gap statistic. Full e

Miles Granger 117 Nov 20, 2021
Dynamically invoke arbitrary unmanaged code.

DInvoke_rs Rust port of Dinvoke. DInvoke_rs may be used for many purposes such as PE parsing, dynamic exported functions resolution, dynamically loadi

Kurosh Dabbagh Escalante 41 Nov 19, 2021
This crate allows you to safely initialize Dynamically Sized Types (DST) using only safe Rust.

This crate allows you to safely initialize Dynamically Sized Types (DST) using only safe Rust.

Christofer Nolander 6 Oct 22, 2021
A dynamically prioritizable priority queue.

bheap A generic binary max heap implementation for implementing a dynamically prioritizable priority queue. This implementation uses a vector as the u

Arindam Das 4 Oct 20, 2021
Lisp dialect scripting and extension language for Rust programs

Ketos Ketos is a Lisp dialect functional programming language. The primary goal of Ketos is to serve as a scripting and extension language for program

Murarth 698 Nov 26, 2021
Rhai - An embedded scripting language for Rust.

Rhai - Embedded Scripting for Rust Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way to add scripti

Rhai - Embedded scripting language and engine for Rust 1.3k Nov 19, 2021
Orion lang is a lispy programming language that is strongly and statically typed.

Orion Orion is a lisp inspired statically typed programming language written in Rust Install To install orion you can either: Download binary from the

Wafelack 211 Nov 19, 2021
Rhai - An embedded scripting language for Rust.

Rhai is an embedded scripting language and evaluation engine for Rust that gives a safe and easy way to add scripting to any application.

Rhai - Embedded scripting language and engine for Rust 1.3k Nov 27, 2021
A scripting language that allows complex key remapping on Linux.

Map2 A scripting language that allows complex key remapping on Linux, written in Rust. All of the functionality related to interacting with graphical

Matt 78 Nov 29, 2021
Simple, extendable and embeddable scripting language.

duckscript duckscript SDK CLI Simple, extendable and embeddable scripting language. Overview Language Goals Installation Homebrew Binary Release Ducks

Sagie Gur-Ari 246 Nov 18, 2021
A shell scripting language

Slash The system level language for getting the job done. Detailed documentation is available on the Slash site Motivation Bash is an awesome shell, b

null 18 Jul 13, 2021
An interactive scripting language where you can read and modify code comments as if they were regular strings

An interactive scripting language where you can read and modify code comments as if they were regular strings. Add and view text-based visualizations and debugging information inside your source code file.

Sumeet Agarwal 10 Sep 1, 2021