JAI

Impressions

  • (2025-08-04)

  • Closed beta.

  • Bad aspects of syntax :

    • The need for ;  is a bit annoying, maybe.

    • #char  looks ugly, but maybe I didn’t understand its purpose correctly.

    • I don’t like pos := Vector2.{40, 40}; , the need for .  is strange.

    • The way pointers are used is odd, doing deref with something.* .

      • Not necessarily bad, maybe, but it feels like you’re accessing it as a property of the variable.

  • Okay aspects of syntax :

    • a: [..]int  is better than [dynamic]  in Odin, I think, maybe.

    • I don’t fully understand how it works, but the existence of default values for structs and enums is nice.

  • Feels like just another layer of abstractions over how things work, without clarity in programming.

    • Aliases in imports are not mandatory.

    • Strange libraries that don’t expose the core of how things work.

      • "Simp" used to create windows.

      • "Input" for inputs.

      • Etc.

    • Still, it feels redundant. There are already libraries that do exactly what these do, like GLFW, etc.

    • Doesn’t seem to solve any problem.

  • I don’t have many opinions on meta-language.

  • Overall :

    • Feels unprepared and maybe unpolished.

    • Tho, I have some expectations about the language, so who knows, in the future the language might be ok.

About

Example
// imports without aliasing
#import "Basic";
#import "GL";
#import "Math";
#import "Window_Creation";

// imports with aliasing
Input :: #import "Input";
Simp  :: #import "Simp";
Windows :: #import "Windows";

// comment

main :: () {
    run := true;
    player_pos := Vector2.{40, 40};

    prev_time := seconds_since_init();

    while run {
        cur_time := seconds_since_init();
        dt := cast(float)(cur_time - prev_time);
        prev_time = cur_time;

        for Input.events_this_frame {
            if it.type == .QUIT {
                run = false;
            }

            SPEED :: 200;

            if it.type == {
                case .KEYBOARD;  // very weird to use ; here.
                    if it.key_pressed && it.key_code == #char "A" {  // so much indentation.
                        player_pos.x -= SPEED * dt;
                    }
                    if it.key_pressed && it.key_code == #char "D" {
                        player_pos.x += SPEED * dt;
                    }
            }
        }
    }
}

Build

jai main.jai

Types

a: float = 2;
b := 4.2;

HEY :: 8;

HELLO : float : 8;

Key :: enum {
    Up;
    Down;
    Left;
    Right;
}

Event_Type :: enum {
    UNINIT     :: 0;
    KEYBOARD   :: 1;
    TEXT_INPUT :: 2;
    //etc
    DRAG       :: 6;
    //etc
}


Key_Current_State :: enum_flags u32 {
    NONE  :: 0x0;
    DOWN  :: 0x1;
    START :: 0x4;
    END   :: 0x8;
}

My_Struct :: struct {
    shift_pressed := false;
}

Buller :: struct {
    pos: Vector2;
}

Meta programming

#if OS != .WINDOWS {
    #add_context input_handler: struct {};
}

Control flow

a: [..]int;
    // resizable array (dynamic array)
for 1..10 array_add(*a, it);