/fixlang

Primary LanguageRustOtherNOASSERTION

Fix-lang: Fix Programming Language

Overview

Fix is a functional programming language focused on ease of learning and use. We hope it will grow to a language that is recommended as "your first functional programming language".

You can try Fix in fixlang playground.

Features:

  • Familiar syntax.
    • The syntax of Fix is more similar to languages such as C++ or Rust than to other functional languages such as Haskell. Even if you have never learned a functional language, you will be able to learn Fix quickly.
  • Simplicity.
    • We try to keep the specifications of Fix simple and small so that it is easily learned and understood.
  • Safety and efficiency.
    • For modern languages, memory / thread safety is a natural requirement. An outstanding language with this characteristic is Rust. Rust introduces "lifetime", "mutable references" and "borrowing rules" to achieve it, but these language features complicate the type system and put a burden on a programmer. Since Fix focuses on simplicity and ease, we go another way: Fix manages lifetime and mutability of values by reference counting.
    • Fix uses reference counter for judging mutability. For example, suppose that you are trying to make a new array by modifying an old one, like let arr2 = arr1.set(i, v);. If the reference counter of arr1 is one at the call of set(i, v), Fix just mutates arr1 and call the result as arr2, avoiding cloning the array. This optimization enables you to implement an algorithm which needs to mutate an array in O(1) without relying something like "ST monad".
    • Of course, Fix uses reference counter for garbage collection. This ensures that values that are no longer needed are immediately released, and that no invalid memory access occurs. Moreover, Fix's syntax ensures that no circular reference is made, so Fix is free from memory leak.

Example code:

module Main;

// Prints n-th value of Fibonacci sequence in O(n).
main : IO ();
main = (
    let n = 30;
    let arr = Array::fill(n+1, 0);
    let arr = arr.set(0, 0);
    let arr = arr.set(1, 1);
    let arr = loop((2, arr), |(idx, arr)|
        if idx == arr.get_size {
            break $ arr
        } else {
            let x = arr.@(idx-1);
            let y = arr.@(idx-2);
            let arr = arr.set(idx, x+y);
            continue $ (idx+1, arr)
        }
    );
    println $ arr.@(n).to_string // 832040 for n = 30
);

Run in playground

Planned features

  • Multi parameter traits and associated type synonyms (if they are truely necessary).

Examples

Install (macOS / Linux, WSL)

Install pre-built binary

Go to Releases, download pre-built binary and install it to somewhere you like.

Bulid from source

  • Install Rust.
  • Install llvm12.0.1. It is recommended to use llvmemv.
    • In macOS, llvmenv installs llvm to "~/Library/Application Support/llvmenv/12.0.1", but llvm-sys currently doesn't understand path with a whitespace correctly, so you need to copy/move "12.0.1" directory to another path.
  • Set LLVM_SYS_120_PREFIX variable to the directory to which llvm installed.
  • git clone https://github.com/tttmmmyyyy/fixlang.git && cd fixlang.
  • cargo install --locked --path .. Then the compiler command fix will be installed to ~/.cargo/bin.

Use Docker image

Thanks to pt9999, docker image is available!

Usage

  • You can run the source file (with extension ".fix") by fix run -f {source-files}.
  • If you want to build executable binary, run fix build -f {source-files}..
  • For more details, see fix help, fix build --help or fix run --help.
  • For debugging, see this section in Document.md.
  • We provide syntax highlight plugin for VSCode. See this repo.

Document

Discord

https://discord.gg/ad4GakEA7R