Draft:Odin (programming language)
![]() | |
Paradigms | imperative, procedural |
---|---|
Designed by | Ginger Bill |
Typing discipline | Static, strong, inferred, structural, generic |
Platform | x86-64, ARM, WebAssembly |
OS | Cross-platform |
License | BSD-3 License |
Filename extensions | .odin |
Website | odin-lang |
Influenced by | |
Pascal, C, Go, Oberon-2, Newsqueak, Jai, GLSL[1] |
Odin is an imperative, general-purpose, statically typed, distinctly typed, compiled system programming language designed by Ginger Bill[2].
The language is designed for "high performance, modern systems, and built-in data-oriented data types", supports compile-time parametric polymorphism, runtime reflection, cross-compilation, manual memory management, array programming, and Structure of Arrays (SOA) data types.[3][4]
Example
package main
import "core:fmt"
main :: proc() {
program := "+ + * 😃 - /"
accumulator := 0
for token in program {
switch token {
case '+': accumulator += 1
case '-': accumulator -= 1
case '*': accumulator *= 2
case '/': accumulator /= 2
case '😃': accumulator *= accumulator
case: // Ignore everything else
}
}
fmt.printf("The program \"%s\" calculates the value %d\n",
program, accumulator)
}
Design
Odin is designed as being an alternative for the C programming language on "high performance, modern systems", with features like compile-time parametric polymorphism, array programming, and runtime reflection.
Syntax
Odin expects a UTF-8 encoded text file as its input. The file is required to have .odin extension. The declaration syntax is inspired by Newsqueak and Jai. Here's an example of some declarations:
// Variable declarations
x : int = 123
x : = 123
x := 123
x := int(123)
// Constant value declarations
X :: 123
X : : 123
Y : int : 123
Y :: int(123)
Z :: proc() {}
Z : proc() : proc() {} // Redundant type declaration
The semicolons are statement terminators and optional. Unlike Go, the Odin permits a newline in certain places where semicolon could otherwise be inserted, allowing programmer to have a higher selection of indentation styles, for example choosing to use Allman style:
// 1TBS/K&R Style
if cond {
} else {
}
// Allman Style
if cond
{
}
else // Odin allows else to be on the next line
{
}
Explicit procedure overloading
Odin has procedure overloading, but unlike C++ and Go the overloads have to be specified explicitly. Each overloaded is specified as a procedure with a distinct name. The overload is then specified explicitly by listing all the names of procedures that are being overloaded and giving the overload a new name.
bool_to_string :: proc(b: bool) -> string {...}
int_to_string :: proc(i: int) -> string {...}
to_string :: proc{bool_to_string, int_to_string}
In the example above the procedure to_string
can is an explicit overload of bool_to_string
and int_to_string
. If to_string
is called with bool
parameter, bool_to_string
will be called.
Array programming
Odin provides array programming feature. The arrays of numeric types can be added, subtracted, multiplied together, while the compiler will implicitly do the same operation value-by-value.
a := [3]f32{1, 2, 3}
b := [3]f32{5, 6, 7}
c := a * b
d := a + b
e := 1 + (c - d) / 2
fmt.printf("%.1f\n", e) // [0.5, 3.0, 6.5]
Using swizzle(array, indices..)
function, the elements of the array can be reordered in an arbitrary way. The indices specify the which element of the original array that is placed at a given spot in the new array. swizzle(a, 3, 2, 1)
will reorder elements of 3 dimensional array to be in backwards order. For arrays up to dimension 4, there is a shorter notation for swizzling, using combination of letter x, y, z, w in any order, akin to GLSL swizzling a.zyx
[5].
// Declaring type Vector to be the same as array of 3 f32's.
Vector3 :: [3]f32
// Cross product using swizzle function
cross :: proc(a, b: Vector3) -> Vector3 {
i := swizzle(a, 1, 2, 0) * swizzle(b, 2, 0, 1)
j := swizzle(a, 2, 0, 1) * swizzle(b, 1, 2, 0)
return i - j
}
// Cross product using shorter swizzle notation
cross_shorter :: proc(a, b: Vector3) -> Vector3 {
i := a.yzx * b.zxy
j := a.zxy * b.yzx
return i - j
}
Matrix support
A matrix
is a mathematical type built into Odin. It is a regular array of numbers, arranged in rows and columns. Odin's matrix support allows for matrix-array and matrix-matrix operations making it a Level 3 Basic Linear Algebra Subprograming language.
The following represents a :
a: matrix[2, 3]f32 // matrix that has 2 rows and 3 columns with an element type of f32
b: matrix[3, 2]f32 // matrix that has 3 rows and 2 columns with an element type of f32
v: [2]f32 // array that has 2 elements with an element type of f32
a = matrix[2, 3]f32{
1, 9, -13,
20, 5, -6,
}
b = matrix[3, 2]f32{
3, 5,
7, 9,
}
v = [2]f32{2, -4}
m := a * b // matrix-matrix multiplication
vp := m * v // matrix-array multiplication
The internal representation of a matrix
in Odin is stored in column-major format[6] while the matrix literals are written in standard (row-major like) order (e.g. matrix[2, 3]f32
is internally [3][2]f32
(with different a alignment requirement)). Column-major is used in order to utilize (SIMD) vector instructions effectively on modern hardware, if possible.
Comparisons with other languages
The syntax of Odin resembles Go's syntax with many adjustments.
Compared to C++, Odin:
- Removes UB from the language
- Removes text-based preprocessing stage
- Introduces strong typing
- Adds array programming and improves runtime reflection
- Has explicit function overloading[7]
Compared to Go, Odin:
- Has manual memory management
- Does not have interfaces
Notable software built with Odin
See also
External links
- ^ https://odin-lang.org/docs/faq/
- ^ https://www.youtube.com/watch?v=2YLA4ajby00
- ^ https://www.youtube.com/watch?v=iCqW_RepcW0
- ^ https://odin-lang.org/docs/overview/
- ^ https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling
- ^ https://odin-lang.org/docs/overview/#matrix-type
- ^ "Overview". odin-lang.org. Retrieved 2021-11-15.