Beta Release 0.1.2
This release of Onyx brings a substantial new feature called tagged unions, and a collection of other small bugfixes.
Tagged Unions
Tagged unions are a big addition to the type system in Onyx, as they allow you to represent a new kind of type. They bring a number of safety and sanity features that Onyx had been lacking in its type system.
At their core, tagged unions store at most one type of data at a time, and know which type they are currently holding.
In order to use the data in the tagged union, you must do a switch statement, which guarantees that you can only access the data if it is of the correct type.
Let's look at a code example.
MultipleTypes :: union {
int: i32;
float: f32;
string: str;
}
main :: () {
value := MultipleTypes.{ string="Tagged unions are cool!" };
switch value {
case .int do println("It was an integer!");
case .float do println("It was a float!");
case .string do println("It was a string!");
}
}
This code will print It was a string!, because value currently holds the string variant.
This is specified with MultipleTypes.{ XXX = ... }; XXX must be one of the variants of MultipleTypes.
In order to access the data inside of the union, you can use a switch with a capture, like so.
main :: () {
value := MultipleTypes.{ string="Tagged unions are cool!" };
switch value {
case .int => int_value do printf("It was an integer: {}\n", int_value);
case .float => float_value do println("It was a float: {}\n", float_value);
// You can also use it by pointer by placing a '&' before the variable.
case .string => &str_value do println("It was a string: {}\n", *str_value);
}
}
You can also directly access the fields, like you would a structure. However, instead of getting the data directly, you get an Optional of the data. You then have to use the methods of the Optional type to access the data.
MultipleTypes :: union {
int: i32;
float: f32;
string: str;
}
main :: () {
v := MultipleTypes.{ float = 12.34 };
// Using Optional.unwrap to get the data.
// This will cause an exception if the union does not currently hold a 'float'.
float_value := v.float->unwrap();
println(float_value);
}
Tagged unions can also be polymorphic, just like structures. With this feature, this is how the Optional type is now defined.
Optional :: union (Value_Type: type_expr) {
None: void;
Some: Value_Type;
}
main :: () {
v := Optional(i32).{ Some = 123 };
switch v {
case .None {
println("No value :(");
}
case .Some => int_value {
printf("Int value: {}\n", int_value);
}
}
}
Full Changelog
Additions: * Tagged unions (uniontype) * String literals can have unicode code points. - '\uXXXX' for small code points (less than U+FFFF) - '\UXXXXXX' for large code points - Does not support UTF-16 surrogate pairs *iter.next_opt*memory.ptr_add*misc.any_memberRemovals: Changes: *optionalis now a tagged-union *resultis now a tagged-union *iter.singlecan take adisposefunction, which is called on close of the iterator, with the single value yielded. *io.write_escaped_strsupports escaping "\\" now. * In Javascript runtime, made__read_from_inputnot defined right away, so it can be overridden depending on the needs of the program. Bugfixes: *jsonencoder was wrongly not encoding strings when usingencodeon anany.