Git Product home page Git Product logo

mun's Introduction

Mun Mun

Build Status Crates.io docs main docs v0.4 MIT/Apache Join us on Discord codecov Lines of Code

Mun is a programming language empowering creation through iteration.

Features

  • Ahead of time compilation - Mun is compiled ahead of time (AOT), as opposed to being interpreted or compiled just in time (JIT). By detecting errors in the code during AOT compilation, an entire class of runtime errors is eliminated. This allows developers to stay within the comfort of their IDE instead of having to switch between the IDE and target application to debug runtime errors.

  • Statically typed - Mun resolves types at compilation time instead of at runtime, resulting in immediate feedback when writing code and opening the door for powerful refactoring tools.

  • First class hot-reloading - Every aspect of Mun is designed with hot reloading in mind. Hot reloading is the process of changing code and resources of a live application, removing the need to start, stop and recompile an application whenever a function or value is changed.

  • Performance - AOT compilation combined with static typing ensure that Mun is compiled to machine code that can be natively executed on any target platform. LLVM is used for compilation and optimization, guaranteeing the best possible performance. Hot reloading does introduce a slight runtime overhead, but it can be disabled for production builds to ensure the best possible runtime performance.

  • Cross compilation - The Mun compiler is able to compile to all supported target platforms from any supported compiler platform.

  • Powerful IDE integration - The Mun language and compiler framework are designed to support source code queries, allowing for powerful IDE integrations such as code completion and refactoring tools.

Example

fn fibonacci(n: i32) -> i32 {
    if n <= 1 {
        n
    } else {
        fibonacci(n - 1) + fibonacci(n - 2)
    }
}

// Comments: functions marked as `pub` can be called outside the module
pub fn main() {
    // Native support for bool, f32, f64, i8, u8, u128, i128, usize, isize, etc
    let is_true = true;
    let var = 0.5;

    // Type annotations are not required when a variable's type can be deduced
    let n = 3;

    let result = fibonacci(n);

    // Adding a suffix to a literal restricts its type
    let lit = 15u128;

    let foo = record();
    let bar = tuple();
    let baz = on_heap();
}

// Both record structs and tuple structs are supported
struct Record {
    n: i32,
}

// Struct definitions include whether they are allocated by a garbage collector
// (`gc`) and passed by reference, or passed by `value`. By default, a struct
// is garbage collected.
struct(value) Tuple(f32, f32);

struct(gc) GC(i32);

// The order of function definitions doesn't matter
fn record() -> Record {
    // Mun allows implicit returns
    Record { n: 7 }
}

fn tuple() -> Tuple {
    // Mun allows explicit returns
    return Tuple(3.14, -6.28);
}

fn on_heap() -> GC {
    GC(0)
}

Documentation

The Mun Programming Language Book is hosted on netlify.

Pre-Built Binaries

[NOTE] We do not provide support for milestone releases

[NOTE] None of the binaries are currently signed

Download pre-built binaries of milestone releases for macOS, Linux, and Windows (64-bit only).

Building from Source

Make sure you have the following dependencies installed on you machine:

Clone the source code, including all submodules:

git clone https://github.com/mun-lang/mun.git
git submodule update --init --recursive

Use cargo to build a release version

cargo build --release

Language server

Mun contains support for the lsp protocol, start the executable using:

mun language-server

Alternatively, you can install editor-specific extensions.

VS code

To run in Visual Studio Code. Use the following extension: VS code extension.

Vim/Neovim

Use a language server plugin (or built-in lsp support of neovim), for example using coc.nvim.

Paste the following config into your :CocConfig, replace the command, with the correct path to the mun executable.

  "languageserver": {
      "mun": {
          "command": "<path_to_mun>",
          "rootPatterns": ["mun.toml"],
          "trace.server": "verbose",
          "args": ["language-server"],
          "filetypes": ["mun"]
      }
  }

Note that, "trace.server": "verbose" is optional and helps with language server debugging.

Building Documentation

Building the book requires mdBook, ideally version 0.3.x. To install it, run:

$ cargo install mdbook --vers [version-num]

The Mun book uses a custom version of Highlight.js to enable highlighting of Mun code. The build version of Highlight.js is required by mdbook in the theme/ folder but it is not distributed with the source. Instead, it can be build by invoking the build script:

cd book
./ci/build-highlight-js

Every time you change something in the custom version of highlight.js you have to call the above script to ensure you locally use the latest version.

After generating the custom minified Highlight.js, to build the book, type:

$ mdbook build

The output will be in the book subdirectory. To view the book, open it in your web browser.

For local development use mdbook serve instead of mdbook build. This will start a local webserver on port 3000 that serves the book and rebuilds the content when changes are detected.

All of the above is also combined in a single shell script that can be invoked by simply running:

./ci/build

To test the rust source code in the book, run:

mdbook test -L path/to/target/debug/deps

For this to work, there can only be one libmun_runtime-{HASH}.rlib file in the provided library path.

License

The Mun Runtime is licensed under either of

at your option.

mun's People

Contributors

alexandrasp avatar baszalmstra avatar belagoesr avatar benediktwerner avatar dependabot[bot] avatar emigr2k1 avatar eopb avatar fominok avatar github-actions[bot] avatar jonatcln avatar legendiguess avatar mkhan45 avatar parasyte avatar radicalzephyr avatar sburris0 avatar sinato avatar tdejager avatar toyboot4e avatar vengarioth avatar virgilhuxley avatar wackbyte avatar wodann avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mun's Issues

Add int and float literal type inference

Currently, the compiler sees all integer literals as int and all float literals as float, which means that the following code:

fn add(x: u8): u8 {
    x + 1
}

fn main() {
    let four = add(3);
}

will produce the following error:

error: expected `u8`, found `int`
 --> test.mun:2:8
  |
2 |     x + 1
  |         ^
error: expected `u8`, found `int`
 --> test.mun:2:4
  |
2 |     x + 1
  |     ^^^^^
error: expected `u8`, found `int`
 --> test.mun:1:18
  |
1 | fn add(x: u8): u8 {
  |
error: expected `u8`, found `int`
 --> test.mun:6:19
  |
6 |     let four = add(3);
  |       

(a similar error occurs when f32 is used in place of u8)

Replace CStr::from_ptr(ptr).to_str() occurences with str::from_utf8_unchecked calls

Depends on #52.

Tests for incremental compilation

Our code has been setup to do incremental compilation but we notice that sometimes this breaks. However, we have no (or very little) tests to validate that we don't break this.

This issue touches that topic by implementing tests where possible to detect that incremental compilation still works.

Write test for C++ bindings

Currently, our C++ bindings have no tests to validate that they function as they should.

This issue is about adding those tests.

Test Mun examples in the book

The book contains a lot of useful Mun code examples. We incorporated the Mun book into the main repository to be able to test all these examples while we develop the language. This hopefully ensures that the book stays up to date with the features we develop.

However, currently, we are not yet testing all these examples. To do so we probably need to create a plugin for mdbook.

Good first issue process:

If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

Remove deprecated `Failure` crate

We use the Failure crate throughout the Mun codebase but it has been deprecated. It would be a good idea to replace it.

Suggested alternatives to use in places where we do use Failure (which is not really a lot) are:

  • anyhow as a replacement for failure::Error
  • displaydoc seems like a good replacement for #[derive(Fail)]
  • thiserror as a replacement for #[derive(Fail)]

Good first issue process:

If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

Implement compatibility checks between munlib and runtime

Problem

Currently, the runtime tries to load a *.munlib with the assumption that the ABI memory layout of the *.munlib matches its own ABI version. This can cause undefined behaviour when it tries to load a *.munlib with a different ABI version.

Solution

By including an ABI version in the *.munlib, the runtime can gracefully fail - reporting an error to the end user.

In the future - once we support backwards compatibility, we can even support loading of several different ABI versions using this functionality.

Tasks

  • add an integer ABI_VERSION constant to the mun_abi crate.
  • generate a get_version IR function
  • export the get_version function
  • in the runtime, call the get_version function and verify that the runtime's mun_abi::ABI_VERSION is compatible.
  • (bonus) add a constant with the get_version function name (and other API functions) to the mun_abi crate and use that constant in both the mun_codegen and mun_runtime crates - to avoid discrepancies.

Good first issue process:

If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

Casting of primitive types

We want to add the functionality to be able to cast from primitive types to other primitives through the use of the as keyword.

This should world:

pub fn test(a:i32) -> i64 {
    a as i64
}

[Discussion] as performs a bitcast, which avoids any security checks. Is this desirable or should we make it more difficult to write a bitcast?

[Discussion] Should we only allow as conversion if they are guaranteed to succeed? If not, a compile error will occur.

[Discussion] Should we allow fallible conversions and panic! if they fail (e.g. due to wrapping)?

Update to official inkwell crate

Currently, Mun uses LLVM 7.x.

It is beneficial for us to update to the latest LLVM but this requires some work to be compatible with the latest Inkwell.

Pass argument by reference

Similar to C#, we want to use the ref keyword in function signatures and function calls to signal that we are passing an argument by reference.

NOTE: Do not confuse the concept of passing by reference with the concept of reference types (i.e. struct(gc). The two concepts are not the same. A function parameter can be modified by ref regardless of whether it is a value type or a reference type.

To use a ref parameter, both the method definition and the calling method must explicitly use the ref keyword, as shown in the following example:

// `ref` implies that the arg is mutable
fn foo(ref arg: u32) {
  arg += 2;
}

fn main() {
  // A variable needs to be mutable (`mut`) in order to bind a `ref` to it
  let mut value = 4;
  foo(ref value);
  assert_eq!(value, 6);
}

As opposed to C# we will not introduce the out keyword, as people can already return anonymous tuples from a function.

[discussion 1] Is there a use case for using ref without actually editing the value it refers to? If so, we should add ref mut?

[discussion 2] If we do demand ref mut, should the function call site also use ref mut?

Edit: updated the proposal example to remove ref mut. After discussion with @baszalmstra, we don't think there are any use cases where you would not want to edit the ref binding.

Fix cryptic Option::unwrap() panic message during build

These should (probably) both compile:

// #1
extern fn extern_fn(a: float, b: float, c: float): float;

pub fn magic(): float {
    extern_fn(22.0, 23.0, 24.0)
}

// #2
extern fn extern_fn(a: float, b: float, c: float): float;

fn magic(): float {
    extern_fn(22.0, 23.0, 24.0)
}

But Mun panics here when building the second, saying:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', crates/mun_codegen/src/code_gen/symbols.rs:146:9

Fibonacci example doesn't compile because of ; in line 3

The semicolon in line 3 of this example prevents it from compiling:

pub fn fibonacci_n() -> i64 {
    let n = arg();
    fibonacci(n);
}

fn arg() -> i64 {
    5
}

fn fibonacci(n: i64) -> i64 {
    if n <= 1 {
        n
    } else {
        fibonacci(n - 1) + fibonacci(n - 2)
    }
}

P.S. sorry for reporting this in the wrong repo!

Export types from assemblies and store them in the runtime

We want to leave the ownership of the type information with the Garbage Collector so that memory can safely reference its type.

Assemblies will export the type information of types that are defined in them. Everywhere else types are referred to by their GUID. Which will be resolved in the runtime.

assembly type info

Add int and float literal type suffixes

This will add support for suffixing integer and float literals with their type.

Examples:

1i8
3.0f32
5i64
89u32
3543u8 <-- invalid!
1.0u8 <-- invalid!

Once #120 is implemented, spacing between the number and the type should also work, like 12_u32.

Implement slab allocator to store `ObjectInfo<T>`

The MarkSweep struct implements GcRuntime to facilitate garbage collection for Mun. Currently, the implementation is quite inefficient. One of the things that could be improved is to implement a slab allocator (or object pool) instead of randomly allocating memory through a Pin<Box<ObjectType<T>>>. The general idea of the allocator is to allocate large chunks of memory to store instances of ObjectType<T> in and reusing them when they are deallocated. We can use a slab allocator here because, unlike the memory the ObjectType<T> is pointing to, the size of an ObjectType<T> is always the same.

Currently, Mun is single-threaded, however, this will not be the case forever. Therefore it is important to take thread-safety into account when designing the allocator. But probably anything is better than the current implementation.

Good first issue process:

If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

feat: add type aliases

We want to introduce type aliases, as follows:

type Typename = OtherTypeName;

In large, this change builds on existing architecture, but it will require work in several places of our stack:

  • lexer: add the type keyword (src, example)
  • parsing: add parsing of type TypeName = OtherTypeName (example#1, example#2)
  • hir: add type aliases as type definition (src)
  • tests: add test for all of the above stages

Good first issue process:

If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

Make RuntimeBuilder agnostic to library extension

  • claim this issue (assign yourself or comment below)
  • setup repository on your local machine and make sure all tests pass (cargo test)
  • read our contributing guidelines
  • the Mun Runtime receives RuntimeOptions from the RuntimeBuilder in order to load a shared library. At the moment this library path is not platform agnostic (i.e. internally determines whether it is dealing with a *.so OR *.dll OR *.dylib file). This results in code like this (a contrived example):
    fn runtime_unix() -> Runtime {
        RuntimeBuilder::new("voxygen/src/anim/character/test.so")
            .spawn()
            .expect("Failed to spawn Runtime");
    }
    
    fn runtime_windows() -> Runtime {
        RuntimeBuilder::new("voxygen/src/anim/character/test.dll")
            .spawn()
            .expect("Failed to spawn Runtime");
    }
    Per @sonovice's submission, we want to instead generate libraries with a custom extension: *.munlib:
    fn runtime() -> Runtime {
        RuntimeBuilder::new("voxygen/src/anim/character/test.munlib")
            .spawn()
            .expect("Failed to spawn Runtime");
    }
    To implement this, you need to:
    • replace *.so / *.dll / *.dylib extensions with *.munlib in the Mun Compiler when writing to file
    • check that RuntimeBuilder::new is allowed to receive any path (both with and without extension)
  • start a Pull Request. Set description to closes #72. If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

Calling an extern function without a return type exits the function it is called in

Calling an extern fn without a return type seems to exit the function it is called in.

For example, the following code

// resources/script.mun
extern fn thing(n: int);
extern fn print(n: int) -> int;

pub fn main() {
    // 1st
    print(1);
    thing(5);

    // 2nd
    print(2);
    thing(78);
}

// src/main.rs
use mun_runtime::{invoke_fn, RuntimeBuilder};
use std::{cell::RefCell, rc::Rc};

extern "C" fn thing(n: i64) {
    // do some cool stuff
}

extern "C" fn print(n: i64) -> i64 {
    println!("{}", n);
    // return an int so that it doesn't fail
    0
}

fn main() {
    let runtime = Rc::new(RefCell::new({
        let mut runtime = RuntimeBuilder::new("resources/script.munlib");
        runtime.insert_fn("thing", thing as extern "C" fn(i64));
        runtime.insert_fn("print", print as extern "C" fn(i64) -> i64);
        runtime.spawn().unwrap()
    }));

    let _: Result<_, mun_runtime::InvokeErr0<'_, ()>> = invoke_fn!(runtime, "main");
}

will output only

1

and not 2.

Add hexadecimal, octal, and binary int literals

This will add support for hexadecimal, octal, and binary notation using the prefixes 0x, 0o, and 0b.
Like Rust, you should be able to use underscore spacing (as in #120) like 0xFF_FF, and it should be case-insensitive like 0xDeAdBeEf.

Design and implement heap-allocated variables

This issue requires some collaboration with the core contributors for language design

  • claim this issue (assign yourself or comment below)
  • setup repository on your local machine and make sure all tests pass (cargo test)
  • read our contributing guidelines
  • propose a language construct for heap-allocated variables (join Discord and post in the #development channel and comment below). For inspiration have a look at Rust's Box.
  • improve and conclude your language design based on feedback
  • implement heap-allocated variables
    • lexing
    • parsing
    • type checking
    • code generation
    • ABI
    • Hot reloading
  • start a Pull Request. Set description to closes #54. If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

WebAssembly support

Web creators being one of our target audiences, we set the goal:

Use the same Mun toolchain to build, test, and deploy content to the web using WebAssembly modules.

What is needed to achieve this goal?

  • Compile the mun_runtime for the wasm target
  • Test runtime-linking of *.munlib files in the browser
    • If impossible, add mun_compiler support for compiling LLVM IR to WebAssembly byte code - instead of machine code

Missing library `libtinfo.so.5` on Arch Linux

I downloaded the pre-built binary, followed the tutorial and executed mun build hello_fibonacci.mun. I got this error:

mun: error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory

It seems like I don't have the file libtinfo.so.5:

โฏ ls -l /usr/lib | grep libtinfo
-rw-r--r--   1 root root        24 13. Feb 09:08 libtinfo.so
lrwxrwxrwx   1 root root        16 13. Feb 09:08 libtinfo.so.6 -> libncursesw.so.6
Click here to see my system information
โฏ screenfetch

 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     ludwig@ludwig-pc
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     OS: Manjaro 20.0.1 Lysia
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     Kernel: x86_64 Linux 5.6.11-1-MANJARO
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     Uptime: 2h 29m
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ            โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     Packages: 1689
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     Shell: nu
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     Resolution: 3200x900
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     DE: KDE 5.69.0 / Plasma 5.18.5
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     WM: KWin
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     GTK Theme: Material-Black-Blueberry [GTK2/3]
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     Icon Theme: breeze-dark
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     Disk: 525G / 1,1T (54%)
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     CPU: AMD A8-7600 Radeon R7, 10 Compute Cores 4C+6G @ 4x 3.1GHz
 โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ  โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆ     GPU: AMD KAVERI (DRM 2.50.0, 5.6.11-1-MANJARO, LLVM 10.0.0)
                                  RAM: 4871MiB / 14925MiB

P.S. To see if there are other libraries missing, I copied libtinfo.so.6 to libtinfo.so.5. This produces another error:

mun: error while loading shared libraries: libffi.so.6: cannot open shared object file: No such file or directory

I have libffi.so.7.1.0 installed, but not libffi.so.6.


P.P.S I solved the problem by installing the following AUR packages:

  • ncurses5-compat-libs
  • libffi6

State of 0.1.0 Binaries?

After unpacking the linux binaries, the Fibonacci example cannot compile.

This is a known thing? Any chance of more uptodate snapshots?

Variable mutability

Similar to Rust, we want to use opt-in mutability; i.e. by default all variables are immutable. If you want to edit a variable, you need to declare it as with the mut keyword. E.g. this example should result in a compile error:

let foo = 5;
if condition() {
  foo += 1; // error: `foo` is not mutable
}

This code would be correct:

let mut foo = 5;
if condition() {
  foo += 1;
}

This construct extends to function arguments. E.g. if you want to make a function argument mutable:

fn foo(mut arg: u32) {
  arg += 1;
  // ...
}

Add binary signing

Currently, all released binaries are unsigned. We should modify the CI so that it also signs the binaries.

Garbage Collection

Currently, the Mun runtime defaults to a mark & sweep garbage collector (henceforth GC). This a relatively simple implementation of a GC, that serves as a good proof of concept. However, going foreword we need to mature our GC story.

Goals

  1. Benchmarking - The first step should be to create a benchmark suite that is used to avoid regression and guides high-level optimisations.
    image
    [discussion A] What metrics/use cases are important to benchmark?
  2. Constantly low overhead The Mun GC will have to run at interactive frame rate (30-60 Hz). As such it only has a minimal time budget to spend on GC - every frame.
  3. Rewrite the stack As Mun hot reloads state, data structures have to be mapped in memory. The current Mun GC is limited to rewriting all GC-allocated memory, but in the future we also want it to rewrite stack memory.
  4. Concurrency In the future, we want to implement some form of concurrency within the Mun runtime. As such, GC design discussions should sync up with Mun concurrency design discussions.

Book: Broken anchor-links because of HTML base-tag

All the anchor links in the book are broken because of the base tag that is inserted on every page.

When a base tag is present the anchor link will be relative to the base address instead of the current page so, for example, clicking on a heading on this page redirects to the index page.

I'm not sure why there even is a base tag in the first place but it seems to be added by this CI script according to the value from here.

The easiest fix would be to remove the base tag. I don't think there is a reason for it. Other rust books also don't use one and since mdBook pages are all on the root level stuff like CSS will still be loaded from the correct path.

why `->` before return type

i don't understand the use of this symbol.
it's totally unnecessary.

proposal: remove -> before return type

Project Management v0.1

To support multi-file Mun libraries, we need to come up with a project management system that allows users to easily setup, build, and tweak packages.

A Mun project will look as follows:
image

The main directory contains a src directory and mun.toml configuration file. All files in the src directory are automatically added to the build tree. This is different from Rust in that you cannot/do not have to write mod a in your source code.

A sub-module can be created by either:

  • adding a directory a with a mod.mun file; or
  • adding a a.mun file in the parent directory.

The above screenshot shows both of these examples for illustrative purposes.

To use a struct Foo, defined in src/a/b.mun, you can access it in the current file by writing: use a::b::Foo;.

By default, a type or function defined in a module is not accessible outside of its file and sub-modules. You can expand accessibility in three ways:

  • pub: accessible within the package and externally (incl. marshalling to the host language)
  • pub(package): accessible within the package
  • pub(super): accessible within parent module and its sub-modules

A mun.toml contains information about the package, similar to a Cargo.toml:

[package]
name="test"
version="0.2.0"
authors = ["Mun Team"]

Depends on

Improved by

Remaining issues moved to later milestones

Logo?

We currently don't really have a logo other than a cutout of the text on the website. It would be really awesome if we could design a proper logo for Mun that we could use all over the place.

Codegen Option::unwrap() panic during build

The following script:

fn do_the_things(n: int) -> int {
    n + 7
}

pub fn main() {
    do_the_things(3);
}

causes this panic:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', crates/mun_codegen/src/code_gen/symbols.rs:146:9

It compiles properly if do_the_things is pub.

It looks like it can't find the return type in the module for some reason.

After some error, compiler(in --watch mode) didn't go to newline in console

If try to mun build mun.lib --watch this code:

fn main(): float {
	0
}

Compiler output error and then will not go to newline for future outputs(yellow arrows on screenshot shows where console cursor right now)
image

So if after this we try to hotreload our code, we get that new errors log output wrong(with yellow line i drew the border between two compiler output):

image

Also here gif where i show this issue:
fg

Update to released version of mdBook 0.4.0

We are currently building mdbook from source on netlify. We do this because we need a feature from mdbook 0.4.0 (namely the head.hbs file). At the moment of writing 0.4.0 has not been released yet.

Building mdbook takes quite a while so we should revert to just downloading a release as soon as one is released for 0.4.0. We dont want to waste valuable netlify minutes. :)

Securely sharing Mun Libraries

The Mun Runtime's ability to securely plug-n-play Mun Libraries at runtime can be used for more than just hot reloading. It also makes it a good candidate for modding systems in games, or similar extensible systems in other domains.

Even though the Mun Runtime can give runtime-linking guarantees, a malicious entity could provide a Mun Library that executes any machine code. As such, we'll need to provide a way of verifying that a Mun Library can be trusted.

Possible options are:

[Option 1] Signing Mun Libraries
An online binary repository contains audited (and consequently signed) versions of Mun libraries. When runtime linking a Mun Library, the Mun Runtime verifies that the library is signed and wasn't modified.

This is a tried and tested method that is also used for other software and drivers. A downside about this approach is that some workload is required for the auditor of the binary repository.

[Option 2] Locally compiling Mun source
An interpreted language can guarantee safety by restricting execution to the available byte code. As Mun is compiled ahead of time, we can not do so at runtime. However, we can provide "security checks" at compile time by limiting the machine code that Mun can generate. Thus, if we compile Mun source on a local machine, the consequent Mun Library is guaranteed to only contain Mun-authorised function logic. (This model is similar to how cargo dependencies work.)

Note that it is still possible to add external functions, as the Mun Runtime allows the end user to insert extern "C" functions. This is however fully within the end users control.

[Option 3] ???
Please let us know if you have other ideas on how to securely share Mun Libraries between publishers.

`enum` type

Similar to Rust's enum, we want to introduce a strongly-typed enum.

Some important considerations:

  • Introduction of the enum type will also require introduction of pattern matching:
    • if let expression
      if let Enum::Variant = some_enum { .. } else { .. }
      
    • match expression
      match some_enum {
        Enum::VariantA => { .. },
        Enum::VariantB => { .. },
        _ => { .. }
      }
      
    • Variant decomposition
      if let Enum::Variant(a, true) = some_enum { .. } else { .. }
      
  • All variants need to be resolved

Replace automatic with manual generation of the Runtime bindings

  • claim this issue (assign yourself or comment below)
  • setup repository on your local machine and make sure all tests pass (cargo test)
  • read our contributing guidelines
  • inspect and remove build code for generating Runtime bindings
  • add tool to manually generate Runtime bindings
  • add test to check that a local bindings repository is up-to-date.
  • remove the crates/mun_runtime_capi/ffi submodule
  • start a Pull Request. Set description to closes #51. If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

Replace return type annotation `:` with `->`

We would benefit from staying close to Rust syntax, however, currently return type annotations are written like:

fn foo(): int {
}

we would like to replace this syntax with this:

fn foo() -> int {
}

to be closer to Rust.

Good first issue process:

If this is your first PR, welcome ๐ŸŽ‰ ๐Ÿ˜„

Error on invalid cyclic type definitions

When a value struct type directly or indirectly references itself this can cause an infinite recursion.

struct(value) Foo {
   a: Bar
}

struct(value) Bar {
   b:Foo
}

This is an example of an invalid construct because the two types reference each other. This is only a problem for value structs because GC structs are allocated on the heap.

We need to add a check and error to ensure this turns into a compiler error. Currently it doesn't error but will likely crash in LLVM.

Make GC API more generic

Currently Mun uses just type GarbageCollector = MarkSweep. It will be better to have trait GarbageCollector and implement it for GC impls.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.