Beta Release 0.1.9
This release brings major syntax changes, optional semicolons, OVM-WASM support for MacOS, and a host of bugfixes in the compiler and the standard library.
Major Syntax Changes
New Keywords
In this version of Onyx there are two new keywords: in
and as
.
They both exist to clean up the syntax of existing constructs in Onyx.
For Loops
For for
loops, Onyx now uses the following syntax to avoid the confusion of the :
.
for value in iterable {
// body
}
This is a small change, but it is much more readable and beginner-friendly. It also enables a very useful feature of for-loop that is new in this version: indexed for-loops.
For-loop can now have an optional second variable that is the index of the loop.
This variable is an i32
by default, but that can be changed using : TYPE
after the variable.
Note that only integer types are currently supported.
Also worthy of note, is that you can now explicitly type the loop iterator, and you will get a compile error if it is typed wrong.
arr := .["A", "list", "of", "strings"];
for value: str, index: i32 in arr {
// body
}
// Or more succinctly
for value, index in arr {
// body
}
Case Statement Captures
For case
statements with captures, Onyx now uses the following syntax. The old syntax was meant to parallel the for-loop syntax, and since that changed, I felt this needed to change as well.
switch some_union {
case .SomeVariant as some_value {
// body
}
// Capture by pointer
case .AnotherVariant as &another_value {
// body
}
}
Interfaces
Interfaces also got some touch ups this version.
Interface parameters now look like normal procedure or structure parameters, and can be of any type, so long as their value is compile-time known.
To specify that you want a value of a certain type in an interface body, simply use the as
keyword.
CanAdd :: interface (T: type_expr) {
t as T;
{ t + t } -> T;
}
add :: (x, y: $T) -> T where CanAdd(T) {
return x + y;
}
Optional Semicolons
As an experimental feature, you can now opt in to optional-semicolons.
To do so, simply pass the --feature optional-semicolons
flag to enable optional-semicolons across an entire project.
Or, simply place the following line at the top of any Onyx file to enable optional-semicolons in that file.
This line must be the first line of code.
//+optional-semicolons
Optional semicolons are implemented in a very straight forward way. Whenever the lexical analyzer encounters a newline, it looks at the last token it procedure and if it is one of the following, it implicitly inserts a semicolon.
A symbol (foo, __bar) | break |
continue |
fallthrough |
return |
A string literal | A character literal | A boolean literal | An integer literal | A float literal |
--- |
? |
) |
} |
] |
There are some rough cases that I have come across with some of the code I have written that make for a slightly rough transition, but largely I am enjoying writing Onyx without semicolons. I believe this will be the default in a future release.
Converting Old Code
If you have old Onyx code that you want to convert to the new syntax, you can use these two POSIX shell commands to convert all for loops and case statements. It is a good idea to make a backup of all Onyx files in your project before running these commands. I personal used these commands on all Onyx projects I am currently working on and they worked flawlessly, but your mileage may vary.
$ find -name '*.onyx' -exec sed -ri 's/(\s+)for([^a-zA-Z0-9_][^:]*)\s*:/\1for\2 in/g' {} \;
$ find -name '*.onyx' -exec sed -ri 's/(\s+)case\s*([^:]*)\s*:\s*\.([a-zA-Z0-9_]+)/\1case .\3 as \2/g' {} \;
There is not a conversion for interfaces, but those are much less common so they should not take too long to migrate.
OVM-WASM support on MacOS
Thanks to community contributions, Onyx's custom WebAssembly runtime called OVM-WASM now has support on MacOS. OVM-WASM was created to allow for debugging of Onyx programs, which is now possible on MacOS. Simply install the newest version of Onyx, and use the newest version of the Visual Studio Code extension for Onyx to enable debugging support.
Array Programming
Thanks to more community contributions, Onyx now has support for basic array programming.
This means that small arrays of 4 elements or less have special operator overloads for +
, -
, and *
, as well as special accessors for their elements.
To see how potentially useful this is, consider this code snippet.
// Vector2 is just an alias for an array of 2 integers
Vector2 :: [2] i32
main :: () {
v: Vector2;
v.x = 10; // Here you can use `.x` and `.y` to
v.y = 20; // directly set the first and second elements
w := v * 2;
println(w);
}
Miscellaneous Improvements
Tree-shaking
Onyx now performs a simple tree-shaking algorithm to reduce the output binary size substantially. It does this by removing code and data that is proven to be impossible to reach. This was rather simple to do in the Onyx compiler, since there is no partial compilation. Everything that could end up in the binary must pass through all stages of the compiler.
There is one caveat to note though. In order to make this as effective as possible, the methods
field in the Type_Info_Union
and Type_Info_Struct
structures is now left empty by default. This is because there are many cases where including it would mean that you could access a procedure dynamically through the type information. This hurt the performance of the tree-shaking algorithm and meant that very little was removed. To fix this, a flag was added to the compiler that you can pass if you want method information for your type. Simply pass --generate-method-info
when running or building.
while defer
Another small syntax change that I am experimenting with is an alternative way to do bottom-test loops (do {} while (...)
in C). The old-syntax was while #bottom_test condition { ... }
, but in this version you can also use the following.
i := 10;
while defer i < 10 {
println(i);
}
This code would print "10", because the actual condition (i < 10
) is not checked until after the body of the loop, hence the defer
keyword.
Updating
To update to the newest version of Onyx simply use the same install script found on the homepage. It will automatically detect your previous install and will override it with the new version.
$ sh <(curl https://get.onyxlang.io -sSfL)
Full Changelog
Additions
- OVM-Wasm support on MacOS (thanks to @judah-caruso).
- This enables debugging support when on MacOS.
- Available from installer.
.*
as a postfix alternative to*
.where
clauses can contain arbitrary boolean expressions (thanks to @judah-caruso).- Small arrays (4 or fewer elements) have special accessors for their components.
- Tree-shaking is performed prior to code generation, reducing binary size drastically in some cases.
- Operation overloads for
+
,-
and*
for small arrays. where defer
as a cleaner alternative towhere #bottom_test
-
Added procedures to core library
core.intrinsics.wasm.memory_equal
core.iter.counter
core.iter.sum
core.iter.fold1
make(List(T))
core.list.from_array
core.list.pop_begin_opt
core.list.pop_end_opt
core.list.empty
core.conv.parse
core.conv.parse_with_allocator
core.encoding.json.encode_string_opt
core.encoding.json.as_any
overload
Removals
- Compiler test cases are no longer shipped with tool-chain.
Changes
-
Due to tree shaking, the
methods
member ofType_Info_Struct
andType_Info_Union
is not populated by default anymore.- Use the
--generate-method-info
CLI flag to add this information back in.
- Use the
- Due to
as
being a keyword now,cptr.as
was renamed tocptr.as_unsafe
.
Bugfixes
-
Error reporting in many cases saw a lot of improvements.
- Especially with polymorphic procedures, l-values, and code blocks.
- Implementation of
core.array.remove
.
Contributors
- @judah-caruso (10 pull requests)
- @stagas (2 pull requests)
- @magnetenstad (1 pull request)
- @jtakakura (1 pull request)
- @hatappo (1 pull request)
- @Syuparn (1 pull request)
- @benstt (1 pull request)