Skip to content

Commit 46ced5b

Browse files
committed
first full jai guide pass
1 parent b62ae5f commit 46ced5b

1 file changed

Lines changed: 86 additions & 153 deletions

File tree

content/posts/jai-guide.md

Lines changed: 86 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ d: ***int = *c;
182182
e: int = d.*.*.*; // dereference in a chain
183183
```
184184

185-
## Headers
185+
## Modules And Imports
186186

187187
Jai has no header files. Code organization is handled by `#import` and `#load` instead.
188188
There is no need for `#include` or header guards in Jai, because multiple `#load` calls dont cause duplicate symbols inclusion.
@@ -279,23 +279,23 @@ result := action(1, 2);
279279

280280
## Casting
281281

282-
The jai syntax is similar to c in this regard, in c it would be `(T)value` while in jai its `cast(T) value`, it only adds the cast word and an extra space.
282+
The jai syntax is similar to c in this regard, in c it would be `(T)value` while in jai its `cast(T)value`, it only adds the cast word.
283283
Jai is strict about casts. Implicit widening is allowed, but narrowing requires an explicit cast.
284284

285285
Example:
286286
```jai
287287
a: u32 = 50000;
288-
b: u16 = cast(u16) a;
288+
b: u16 = cast(u16)a;
289289
```
290290

291291
For truncation or unchecked casts, use the `trunc` or `no_check` flags.
292-
Also Jai uses comma-separated “attributes” like this: `operation,modifier1,modifier2(type) value`:
292+
Jai uses comma-separated “attributes” like this: `operation,modifier1,modifier2(type)value`:
293293
```jai
294-
b = cast,trunc(u16) a;
295-
b = cast,no_check(u16) a;
294+
b = cast,trunc(u16)a;
295+
b = cast,no_check(u16)a;
296296
```
297297

298-
Use `xx` when you want the compiler to infer the target type:
298+
Use `xx` when you want the compiler to infer the target type to cast to:
299299
```jai
300300
b = xx a;
301301
```
@@ -304,7 +304,7 @@ b = xx a;
304304

305305
Jai supports operator overloading for many operators: `+`, `-`, `*`, `/`, `%`, `==`, `!=`, `<<`, `>>`, `[]`, and more.
306306

307-
Jai syntax follows this rule: `operator + :: implementation`, where `+` can be any other operator. Unlike C, Jai needs spaces around the operator symbol.
307+
Jai syntax follows this rule: `operator + :: implementation`, where `+` can be any other operator.
308308

309309
Example:
310310
```jai
@@ -336,202 +336,140 @@ operator * :: (a: Vector3, b: float) -> Vector3 #symmetric {
336336

337337
## Arrays / Lists
338338

339-
Static arrays:
340-
```jai
341-
arr : [4]int;
342-
arr[0] = 1;
343-
```
344-
345-
Dynamic arrays:
346-
```jai
347-
arr : [..]int;
348-
array_add(*arr, 1);
349-
```
339+
in jai a normal array is typed like ``[size]T``, and a slice like ``[]T``, and a dynamic array like ``[..]T``.
350340

351-
Static arrays expose `.count`:
352-
```jai
353-
print("count = %\n", arr.count);
354-
```
341+
unlike in c, arrays store their length in jai, you can get it by the `array.count` member.
355342

356-
Multi-dimensional arrays are nested:
357-
```jai
358-
matrix : [4][4]float;
359-
```
343+
you can get the memory adress of the first element in an array using the `array.data` member.
360344

361-
Dynamic arrays are similar to `std::vector` but use Jai’s allocator and context system.
345+
Both Static Arrays and Dynamic Arrays are autocasted to Array Views if the array view is a parameter. Because strings are array views with u8, both share the same definition.
362346

363-
## Array Pointer Decay
347+
Arrays in jai are simply a tiny struct that holds the size and location of where the array actually is in memory. so copying an array directly makes an array that points to the same data.
364348

365-
Jai static arrays do not decay to pointers the way C/C++ arrays do.
366-
Instead, an array has a `.data` field for its backing pointer.
349+
You can initialize arrays using the following syntax:
367350

368-
Example:
369351
```jai
370-
arr : [5]int;
371-
ptr : *int = arr.data;
352+
array: [4]float = float.[10.0, 20.0, 1.4, 10.0];
372353
```
373354

374-
If you need a view, use a separate array view or dynamic array type.
375-
376-
## Generics / Templates
377-
378-
Jai uses compile-time polymorphism with `$T` and `Type`.
379-
380-
Generic function:
355+
regular arrays:
381356
```jai
382-
foo :: (x: $T) {
383-
print("%\n", x);
384-
}
357+
// simple array
358+
array: [8]int; // create
359+
value: int = array[0]; // index
385360
```
386361

387-
Polymorphic struct:
362+
dynamic arrays:
388363
```jai
389-
Box :: struct(T: Type) {
390-
value: T;
391-
};
364+
// create dynamic array
365+
array: [..]int;
392366
393-
b : Box(int);
394-
b.value = 5;
395-
```
367+
// get length of dynamic array
368+
length: int = array.count;
396369
397-
You can constrain polymorphic types with `/` and `interface` syntax.
370+
// add to the dynamic array
371+
array_add(*array, 4);
398372
399-
## Strings
373+
// remove third element from the dynamic array
400374
401-
Jai strings are views over `u8`.
375+
// index the dynamic array
376+
value: int = array[0];
402377
403-
Examples:
404-
```jai
405-
s := "hello";
406-
print("%\n", s);
378+
// clear the dynamic array
379+
array_reset(*array);
407380
```
408381

409-
Common helpers include `join`, `split`, `equal`, `compare`, `contains`, `begins_with`, and `ends_with`.
410-
411-
`to_c_string` allocates a C-style string on the heap, and `c_style_strlen` computes its length.
412-
413-
## Immutables And Statics
414-
415-
Jai constants are created with `::`.
416-
417-
Example:
382+
slices (array views):
418383
```jai
419-
PI :: 3.141592;
420-
```
384+
arr: []int = int.[1,2,3,4,5]; // represents a view into the data that is contained in an array or a subsection of an array
421385
422-
There is no `readonly` or `constexpr` keyword in the same way as C++.
386+
```
423387

424-
File-local scope is expressed with `#scope_file`, while exported symbols use `#scope_export`.
388+
multi dimensional arrays:
389+
```jai
390+
array: [2][2]int; // creating a 2D static array
391+
array: [2][2][2]int; // creating a 3D static array
425392
426-
## Header Guards
393+
array: [2][2]int = int.[int.[1, 0], int.[0, 3]]; // initializing a 2D array
394+
array: [2][2]int = .[.[1, 0], .[0, 3]]; // initializing a 2D array with inferred type
427395
428-
Not applicable in Jai: there are no header files, so there is no need for header guards.
396+
value: int = array[0][0]; // indexing a 2D array
397+
```
429398

430-
## Optional Header Only Libraries
399+
## Array Pointer Decay
431400

432-
Not applicable in Jai either.
433-
Jai libraries are modules and source files, not header-only libraries.
401+
Jai static arrays do not decay to pointers the way C/C++ arrays do.
402+
Instead, an array has a `.data` field for its backing pointer.
434403

435-
## Preprocessor
404+
## Polymorphism (Generics)
436405

437-
Jai has compile-time directives rather than a traditional C preprocessor.
406+
In jai generics is called polymorphism.
438407

439-
Common directives:
440-
- `#import`
441-
- `#load`
442-
- `#if`, `#else`, `#elif`, `#endif`
443-
- `#exists`
444-
- `#run`
445-
- `#type`
446-
- `#add_context`
408+
Jai’s generics are compile-time polymorphism using `$T` and `Type` parameters.
447409

448-
Example:
410+
Generic function:
449411
```jai
450-
#if DEBUG {
451-
print("debug build\n");
412+
foo :: (x: $T) {
413+
print("%\n", x);
452414
}
453-
```
454-
455-
`#exists` lets you ask whether a symbol is available at compile time.
456415
457-
## Function Pointers
458-
459-
Function pointers are declared much like function types.
416+
foo(1);
417+
foo("hello");
418+
```
460419

461-
Example:
420+
Generic function with multiple types:
462421
```jai
463-
type_fn : (int, int) -> int;
464-
add :: (a: int, b: int) -> int { return a + b; }
465-
fn : type_fn = add;
466-
result := fn(1, 2);
422+
foo :: (a: $A, b: $B, c: $C) {
423+
// use a or b or c here
424+
}
467425
```
468426

469-
## Member Definition Outside The Class
470-
471-
Jai does not have separate class declarations and definitions.
472-
There is no equivalent to `ClassName::MethodName()` because Jai does not use C++-style classes.
473-
474-
## Member Initializer List
427+
Polymorphic structs:
428+
```jai
429+
Box :: struct(T: Type) {
430+
value: T;
431+
};
475432
476-
Jai has no constructor member initializer list.
477-
Structs are initialized directly, and fields are assigned via aggregate initialization or explicit assignment.
433+
b: Box(int);
434+
b.value = 5;
435+
print("type = %", a.T); // you can quiry the type of a stuct like this (prints out "type = int")
436+
```
478437

479-
## L-values And R-values
438+
Jai also supports type constraints such as `$T/SomeStruct` and `$T/interface SomeStruct`, which are similar to traits or interfaces.
480439

481-
Jai mostly treats named variables as addressable values and expressions as temporaries.
440+
## Interfaces / Traits
482441

483-
A variable like `x` is addressable, while `x + 1` is a temporary expression.
442+
todo
484443

485-
## Move Semantics
444+
You can constrain polymorphic types with `/` and `interface` syntax.
486445

487-
Jai does not have C++ move constructors or rvalue references.
488-
Ownership is explicit: either copy values, or use pointers and allocators.
446+
## Strings
489447

490-
Example:
491-
```jai
492-
value := big_data;
493-
copy := value; // copies the value if needed
494-
```
448+
todo
495449

496-
For large buffers, prefer pointers or custom allocator-based containers.
450+
Jai strings are are array views (slices) over `u8`, arrays are also not null terminated.
497451

498-
## Notes
452+
## Compile Time Directives (Preprocessor)
499453

500-
This guide matches the structure of the C++ reference guide, while explaining Jai’s equivalent concepts and the places where Jai intentionally diverges.
501-
Multi-dimensional arrays work too:
502-
```jai
503-
matrix : [4][4]float;
504-
```
454+
todo
505455

506-
## Polymorphism
456+
## Function Pointers / Function Types
507457

508-
Jai’s generics are compile-time polymorphism using `$T` and `Type` parameters.
458+
Function pointers are declared much like function types.
509459

510-
A simple polymorphic function:
460+
Example:
511461
```jai
512-
foo :: (x: $T) {
513-
print("%\n", x);
514-
}
462+
add :: (a: int, b: int) -> int { return a + b; }
515463
516-
foo(1);
517-
foo("hello");
518-
```
464+
function_type: (int,int)->int;
465+
function: function_type = add;
519466
520-
A polymorphic struct:
521-
```jai
522-
Box :: struct(T: Type) {
523-
value: T;
524-
};
467+
function: (int,int)->int = add; // also works
525468
526-
b : Box(int);
527-
b.value = 5;
469+
result := function(1, 2);
528470
```
529471

530-
Jai also supports type constraints such as `$T/SomeStruct` and `$T/interface SomeStruct`, which are similar to traits or interface-based matching.
531-
532-
## Modules and External Libraries
533-
534-
Jai uses modules instead of headers. You can import bundled modules with `#import` and local code with `#load`.
472+
## External Libraries / Interop
535473

536474
For external libraries, Jai can map foreign functions and dynamic libraries using `#library` and `#foreign` declarations.
537475

@@ -541,13 +479,8 @@ lz4 :: #library "liblz4";
541479
LZ4_compressBound :: (inputSize: s32) -> s32 #foreign lz4;
542480
```
543481

544-
Callback types use `#type` and `#c_call` for ABI compatibility.
545-
546482
## Summary
547483

548-
- Jai has explicit fixed-width types, plus `int` = `s64` and `float` = `float32`.
549484
- Jai has no C++ references; use pointers and `.*` dereference.
550-
- Heap allocation is explicit and usually performed by library helpers.
551485
- Jai does not use header files; it uses `#import` and `#load`.
552-
- Polymorphism is compile-time and uses `$T` and `Type`.
553-
- Jai’s initialization and constant syntax is different from C# / C++ but keeps the same concept of stack vs heap and value semantics.
486+
- Polymorphism is compile-time and uses `$T` and `Type`.

0 commit comments

Comments
 (0)