9 releases

Uses old Rust 2015

0.1.8 May 8, 2023
0.1.7 Mar 3, 2023
0.1.5 Feb 22, 2023

#188 in Programming languages

35 downloads per month

MIT license

1MB
7K SLoC

Oters

Oters (Oxidized Temporal Reactive Streams) is a functional reactive programming language designed for intuitively building GUIs based on Patrick Bahr's type system.

Documentation for the language can be found here.


Features

  • Type Inference - Types are fully inferred such that you never have to explicitly write a type.
  • Interpreted - While the language is interpreted, static type checking ensures that your program is safe before running.
  • Imports Rust Code - Can import Rust functions into your Oters code with a single macro.
  • No space or time leakages - The size and computation of the program stays constant after initiation.

Dependencies

Oters relies on the macroquad crate for its GUI functionality. This crate requires certain system dependencies. Specifically on Linux:

# ubuntu system dependencies
apt install pkg-config libx11-dev libxi-dev libgl1-mesa-dev libasound2-dev

# fedora system dependencies
dnf install libX11-devel libXi-devel mesa-libGL-devel alsa-lib-devel

# arch linux system dependencies
 pacman -S pkg-config libx11 libxi mesa-libgl alsa-lib

Usage

Oters works as a Rust library and so must be included into your Rust project like any other dependency:

[dependencies]
oters = "0.1.2"

Running an Oters file requires a single macro call in your main function:

fn main() {
    let config = oters::WindowConfig {
        title: "My Oters App".to_string(),
        dimensions: (800, 600),
        resizable: true,
        fullscreen: false,
        icon: None,
    };
    oters::run!(vec!["./examples/demo/demo.otrs".to_string()], config,);
}

Note that files passed to the run! macro must be in order of dependency. So if you have two files main.otrs and logic.otrs, and the former relies on the latter, then logic.otrs must come before main.otrs in the Vec.

And importing a Rust function into Oters, is also done through a single macro call:

#[export_oters]
fn print_message(s: String) {
    println!("This message is being printed from a Rust function: \n{s}");
}
// Can now call the function print_message from your Oters file

Examples

A token example taken from examples/demo/demo.otrs:

use std::stream::const
use std::stream::head
use gui::widget::*
use gui::color::*
use gui::shape::*

let ui = gui::frame ((100,50), (250, 100))

let (btn_id, btn_stream) = button ui (100, 50) (const "Click me!")

let counter = {
  let aux = fn n -> {
    let delta = if head btn_stream then 1 else 0;
    (n + delta) << @(aux (n + delta))
  };
  aux 0
}
let counter_string = std::int_to_string (head counter) << @counter_string

let (lab_id, lab_stream) = label ui (100, 50) counter_string 

let (grp_id, grp_stream) = hgroup 
  ui 
  (250,100) 
  (const [btn_id, lab_id]) 
  (Alignment::Top)

let _ = gui::attach_root (ui, grp_id)

let circle_color = 
  (if head counter % 3 == 0 then 
    red
  else if head counter %3 == 1 then
    green
  else 
    blue) << @circle_color

let circle = (draw_shape (Shape::Circle((200,200), 30, head circle_color))) << @circle

Dependencies

~28MB
~378K SLoC