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;
}
Jac Grammar Snippet
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.