Skip to content
gingerBill edited this page Sep 26, 2022 · 34 revisions

Odin vs Jai

Time of writing: June 2022 (previously November 2021, February 2020)

Commentary

Jonathan Blow's language talk was a minor inspiration, and thus his language Jai, of which Ginger Bill is quite open about. One of the main reasons people compare the two languages is purely regarding the similarity of the declaration syntax. From a semantic standpoint, the programming languages are quite different (Jai being very C++ like, and Odin being more Pascal/Go like). It is regularly asked about it which is why the minor table below was produced for people to understand the differences at a glance.

The declaration syntax is similar to Jai's but Blow didn't invent it, and in fact took it from Sean Barrett. And with a little research, you can find that it was Rob Pike who first invented that syntax back in the early '90s for Newsqueak and Limbo.

Some of the similarities that Odin and Jai hold are not unique to either and can be found in earlier languages. using is a good example of this in that Ginger Bill was originally going to have with from Pascal, but seeing how Jon applied that idea to "live variables" was pretty clever. And the uninitialized value --- syntax is copied from Jai but it turned out to be a life saver because it was reused as the declaration syntax for (foreign) procedures without a body. The declaration syntax of Odin was changed for a week to a more conventional proc main() syntax because it was thought the problem was unsolvable until it was realized this token could be used for that purpose. Hypothetically if Odin was to change its declaration syntax to a more qualifier-focused, it could be made to look more like Go or Rust in its declaration syntax without changing the AST layout whatsoever, and many of the comparisons to Jai would completely disappear.

Other than that, Odin and Jai are very different languages with very different philosophies behind them.

Similarities:

Differences:

Odin Jai
Publicly Available Private Beta Only (Currently)
Arbitrary Compile Time Execution
Compile Time AST modification (Outdated video: https://www.youtube.com/watch?v=59lKAlb6cRg)
Strong Typed with virtually no implicit conversions Many implicit conversions similar to C++
Pascal-family Type System C-family Type System
Modula/Go style directory-based package system File-based library system
Discriminated union type
bit_set
cstring *u8 (not semantically equivalent because it is not denoting a string type nor is it stating the value is NUL terminated)
distinct type declarations
Built-in map type (User-level type)
Slicing notation like Python/Go [lo:hi] Use of pointer arithmetic and wrapper procedures
where clauses for procedure and record types #modify metaprogramming
switch statements which allow for multiple cases, ranges, and any/union types if cond=={ case x:
Explicit parameter declaration with for val, idx in array{} Implicit parameter declaration with for array { val, idx := it, it_index; },
as well as explicit for val, index : array {}
Extensive constant system which "just works" reducing the need for implicit conversions Basic constant system which can be extended with the compile time execution features
rune type for Unicode Codepoints s32 (signed 32-bit integer) (No default character type)
Unicode identifiers ASCII identifiers (currently)
Array programming Available explicitly through operator overloading
matrix type Available explicitly through operator overloading
Operator overloading
Explicit procedure overloading Implicit procedure overloading (Implicit Poylmorphism)
Zero is initialized Default struct fields
Built-in complex and quaternion types (User-level type)
rawptr *void
ptr: ^int; i := ptr^; x := &i; ptr: *int; i := <<ptr; x:= *i;
p: [^]int; q := p[i:] (multi-pointers) p: *int; q := p + 1; (pointer arithmetic)
proc(T) -> U (T) -> U (to see proof of the ambiguity: https://gist.github.com/gingerBill/27aec0cd434f2be58d024dccef6e8d13)
proc(a, b: int, c: string) (a: int, b: int, c: string)
#soa data types (User-level type through metaprogramming and operator overloading) (Video: https://www.youtube.com/watch?v=zgoqZtu15kI)
Enumerated arrays
Iterators through procedures Iterators through macros
Ranged Fields for array compounds literals
Implicit Selector Expressions .A Implicit Selector Expressions .A (originally did not)
#partial switch #complete if cond == {
Hygenic Macros
#run_and_insert