Fuzion Logo
flang.dev — The Fuzion Language Portal
JavaScript seems to be disabled. Functionality is limited.

Standard Library Design

The standard library has to provide basic data types like integers, floats, strings, array, lists, maps, etc. Parts of the library need to be known to the Fuzion front end to provide syntactic sugar and some even to the back end for an efficient implementation.

Mutability

The standard library should provide immutable and mutable features, while the default should be immutable.

Iterators

To iterate over a collection, one could use integer indices (as in a for loop), an iterator instance (as in a Java iterating for loop), a stream or a (lazy) list. Only a list uses immutable instances:

Collection Initialization

Fuzion should have syntactic sugar for the creation of arrays, lists and maps with pre-defined values. These values could be compile-time constants or run-time variables.

Arrays

in Java: var arr = new int[] {1, 2, 3, 4};

in Rust: let arr:[i32;4] = [1, 2, 3, 4];

in F#: let arr = [| 1; 2; 3; 4; 5; 6 |]

in Python: arr = array.array('i', [1, 2, 3, 4])

In Fuzion: using brackets [] appears syntactically close to indexing using brackets, so this might be best. The array type could be inferred from the elements or the target of the assignment. The result should be an immutable array:

arr := [1, 2, 3, 4];

Lists

in Java: var l = Arrays.asList(1, 2, 4, 5);

in Rust: let l = vec![1, 2, 3, 4];

in Python: l = [1, 2, 3, 4]

in Go: l := []int{1, 2, 3, 4}

in Lua: l := {1, 2, 3, 4}

In Fuzion: If an array is one possible implementation of a list, the array syntax can be used:

l := [1, 2, 3, 4];

Maps

in Java:

import java.util.HashMap;
import java.util.Map;
Map x = new HashMap<>();
x.put("one", 1);
x.put("two", 2);

in Rust:

use std::collections::HashMap;
let x: HashMap<&str, i32> = [
    ("one", 1),
    ("two", 2),
].iter().cloned().collect();

in Python:

x = {"one" : 1, "two" : 2}

in Go:

x := map[string]int {"one": 1, "two": 2}

in Lua:

x = {one = 1, two = 2}

In Fuzion: Hash map are inherently non-deterministic with an awful worst-case performance. So, hash maps should only be used if perfect hashing is possible at compile time. Otherwise, a tree map could be used if a total order is defined for the keys. The map type should be given explicitly unless perfect hashing or a tree map is possible.

Tuple syntax could be used to declare an array that is then used to create a map.

map := TreeMapFromArray([("one", 1), ("two", 2)]);

Arrays

TBW

Lists

A list in Fuzion should be much like a list in Lisp: a list should either be empty or consists of a head element and a list tail.

Need to decide how to represent an empty list: An empty list could either be nil as follows

  list<T> : choice <nil | node<T>> { }
  node<T> (T head; list<T> tail) { }

or a list whose head element is nil.

  list (head Option head; tail Option>) { }

Using nil for an empty list seems cleaner, but it should be possible to add list-specific inner features that handle the empty list case, e.g., a size feature that returns 0 for an empty list:

  list<T> : choice <nil | node<T>>
  {
  size => size(0);
  private size(s i32) => match list.this
  {
    nil       => s,
    n node => n.tail.size(s+1)  // tail recursion
  };
  node<T> (T head; list<T> tail) { }

Using the first variant with nil being a valid empty list seems the way to go.