Skip to content

Base Module structure#

Code Example

Runnable Example in Jac and JacLib

"""Base module structure: Module and element docstrings, entry points.

This is the module-level docstring.
It describes the purpose of the entire module.
"""

# 1. Import statement
import math;

# 2. Global variable (using let as requested)
let global_value: int = 42;

# 3. Archetype (object)
obj MyObject {
    has value: int = 0;
}

# 4. Implementation
impl MyObject {
    def get_value -> int {
        return self.value;
    }
}

# 5. Semstring
sem MyObject.value = "A value stored in MyObject";

# 6. Ability (function)
def add(a: int, b: int) -> int {
    return a + b;
}

# 7. Free code (default entry point)
with entry {
    print("Default entry:", add(5, 8));
}

# 8. Free code (named entry point)
with entry:__main__ {
    print("Named entry:", add(1, 2));
}

# 9. Inline Python
::py::
def python_multiply(x, y):
    return x * y
::py::

# 10. Test
test basic_test {
    result = add(2, 3);
    assert result == 5;
}
"""Base module structure: Module and element docstrings, entry points.

This is the module-level docstring.
It describes the purpose of the entire module.
"""

# 1. Import statement
import math;

# 2. Global variable (using let as requested)
let global_value: int = 42;

# 3. Archetype (object)
obj MyObject {
    has value: int = 0;
}

# 4. Implementation
impl MyObject {
    def get_value -> int {
        return self.value;
    }
}

# 5. Semstring
sem MyObject.value = "A value stored in MyObject";

# 6. Ability (function)
def add(a: int, b: int) -> int {
    return a + b;
}

# 7. Free code (default entry point)
with entry {
    print("Default entry:", add(5, 8));
}

# 8. Free code (named entry point)
with entry:__main__ {
    print("Named entry:", add(1, 2));
}

# 9. Inline Python
::py::
def python_multiply(x, y):
    return x * y
::py::

# 10. Test
test basic_test {
    result = add(2, 3);
    assert result == 5;
}
"""Base module structure: Module and element docstrings, entry points.

This is the module-level docstring.
It describes the purpose of the entire module.
"""
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _jl
import math
global_value: int = 42

@_jl.sem('', {'value': 'A value stored in MyObject'})
class MyObject(_jl.Obj):
    value: int = 0

def add(a: int, b: int) -> int:
    return a + b
print('Default entry:', add(5, 8))
if __name__ == '__main__':
    print('Named entry:', add(1, 2))

def python_multiply(x, y):
    return x * y

@_jl.jac_test
def test_basic_test(_check) -> None:
    result = add(2, 3)
    _check.assertEqual(result, 5)
Jac Grammar Snippet
start: module

module: (toplevel_stmt (tl_stmt_with_doc | toplevel_stmt)*)?
       | STRING        (tl_stmt_with_doc | toplevel_stmt)*

tl_stmt_with_doc: STRING toplevel_stmt
toplevel_stmt: import_stmt
       | archetype
       | impl_def
       | sem_def
       | ability
       | global_var
       | free_code
       | py_code_block
       | test

Description

Jac modules organize code using top-level statements including imports, archetypes, implementations, globals, abilities, and entry points. This example demonstrates all top-level statement types.

Module-Level Docstrings

Lines 1-5 show the module docstring - a string literal at the very beginning of the file. This triple-quoted string documents what the entire module does. It appears before any code elements and is used by documentation tools.

Top-Level Statements Coverage

This module demonstrates all 9 top-level statement types from the grammar:

Statement Type Lines Example
Import 8 import math;
Global Variable 11 let global_value: int = 42;
Archetype 14-16 obj MyObject { ... }
Implementation 19-23 impl MyObject { ... }
Semstring 26 sem MyObject.value = "...";
Ability (Function) 29-31 def add(a: int, b: int) -> int { ... }
Free Code (Default Entry) 34-36 with entry { ... }
Free Code (Named Entry) 39-41 with entry:__main__ { ... }
Inline Python 44-47 ::py:: ... ::py::
Test 50-53 test basic_test { ... }

1. Import Statements (Line 8)

The import math; statement makes Python's math module available. Jac supports standard Python imports and Jac-specific imports using import from module { items } syntax.

2. Global Variables (Line 11)

let global_value: int = 42; declares a module-level variable using the let keyword. Global variables can have access modifiers (:priv, :pub, :protect) and type annotations.

3. Archetypes (Lines 14-16)

obj MyObject defines an object archetype with a value field. Jac has 5 archetype types: obj, class, node, edge, and walker.

Key distinction: obj vs class: - obj: All has fields are instance variables (each instance gets its own copy). Methods have implicit self - it doesn't appear in the parameter list (e.g., def init(param: str)). Compatible with spatial archetypes (node, edge, walker also use implicit self). - class: has fields with defaults become class variables (shared across instances). Methods require explicit self parameter with type annotation (e.g., def init(self: MyClass, param: str)).

See class_archetypes.md for detailed examples.

4. Implementations (Lines 19-23)

The impl MyObject block adds the get_value method to the MyObject archetype. Implementations allow forward declarations and deferred definitions, separating interface from implementation.

5. Semstrings (Line 26)

sem MyObject.value = "..." attaches semantic documentation to the value field. Semstrings guide LLM-based code generation and provide rich semantic context.

6. Abilities (Lines 29-31)

The def add function is a top-level ability that can be called throughout the module. Functions use type annotations and can be defined with def or can keywords.

7. Free Code - Entry Points (Lines 34-41)

Entry points execute when the module runs:

  • Default entry (with entry): Executes when the module runs
  • Named entry (with entry:__main__): Only executes when run directly (not when imported)

The default entry prints "Default entry: 13" by calling add(5, 8). The named entry prints "Named entry: 3" by calling add(1, 2).

8. Inline Python (Lines 44-47)

The ::py:: ... ::py:: block embeds pure Python code. This allows seamless Python interop - the python_multiply function can be called from Jac code.

9. Tests (Lines 50-53)

test basic_test defines a unit test that verifies add(2, 3) returns 5. Tests can be run with jac test command and use assertions to validate behavior.