Skip to content

Class Archetypes#

Code Example

Runnable Example in Jac and JacLib

# Archetypes - All 5 types: class, obj, node, edge, walker

# Class with init constructor (Python-style with explicit self)
# Note: No 'has' declarations - init creates instance variables directly
class ClassicAnimal {
    def init(self: ClassicAnimal, species: str, age: int, name: str = "Unnamed") {
        self.species = species;
        self.age = age;
        self.name = name;
    }

    def describe(self: ClassicAnimal) { print(f"{self.name} is a {self.age} year old {self.species}"); }
}

# Object archetype with has declarations (implicit self in methods)
obj Animal {
    has species: str = "Unknown";
    has age: int = 0;
    def make_sound { print(f"{self.species} makes a sound"); }
}

# Object archetype (implicit self in methods)
obj Domesticated {
    has owner: str = "None";
    has trained: bool = False;
    def train {  # No self parameter - it's implicit in obj
        self.trained = True;
        print(f"Training {self.owner}'s pet");
    }
}

obj Mammal { has warm_blooded: bool = True; }

# Node with multiple inheritance
node Pet(Animal, Domesticated, Mammal) {
    has name: str = "Unnamed";
    has favorite_toy: str = "ball";
    def play { print(f"{self.name} plays with {self.favorite_toy}"); }

    can greet_person with Person entry {
        print(f"  {self.name} wags tail at {visitor.name}");
    }
}

# Edge with public access modifier and method
edge :pub Relationship {
    has strength: int = 5;
    has since: int = 2020;
    def strengthen {
        self.strength += 1;
        print(f"Relationship strengthened to {self.strength}");
    }
}

# Edge with walker ability
edge Ownership {
    has duration_years: int = 0;
    can track with OwnershipWalker entry {
        print(f"  Edge: Ownership duration = {self.duration_years} years");
        self.duration_years += 1;
    }
}

# Walker with inheritance chain (Person -> Caretaker -> Veterinarian)
walker Person(Animal) {
    has name: str = "Person";
    has visited_count: int = 0;
    can greet with `root entry {
        print(f"{self.name}: Starting walk from root");
        visit [-->];
    }
    can visit_pet with Pet entry {
        self.visited_count += 1;
        print(f"{self.name} visits {here.name}");
        visit [-->];
    }
}

walker Caretaker(Person) {
    has care_quality: int = 10;
    can care_for with Pet entry {
        print(f"{self.name} cares for {here.name} (quality: {self.care_quality})");
        visit [-->];
    }
}

walker Veterinarian(Caretaker) {
    has specialty: str = "general";
    can examine with Pet entry {
        print(f"Dr. {self.name} ({self.specialty}) examines {here.name}");
        visit [-->];
    }
}

# Async walker
async walker AsyncInspector {
    has inspected: list = [];
    async can inspect with `root entry {
        print("AsyncInspector: starting");
        visit [-->];
    }
    async can check with Pet entry {
        self.inspected.append(here.name);
        print(f"  Async checking: {here.name}");
        visit [-->];
    }
}

# Access modifiers: private, public, protected
obj :priv PrivateConfig { has secret_key: str = "hidden"; }
obj :pub PublicAPI { has version: str = "1.0"; }
obj :protect ProtectedResource { has resource_id: int = 0; }

# Forward declarations
node AnimalNode;
walker SpecializedWalker;
edge SpecialEdge;

# Implementation blocks for forward declarations
impl AnimalNode {
    has animal_type: str = "wild";
    has habitat: str = "forest";
    def describe { print(f"AnimalNode: {self.animal_type} in {self.habitat}"); }
}

impl SpecializedWalker {
    has specialization: str = "research";
    can process with AnimalNode entry {
        print(f"SpecializedWalker ({self.specialization}): Processing node");
        disengage;
    }
}

impl SpecialEdge {
    has edge_weight: float = 1.0;
    def get_weight -> float { return self.edge_weight; }
}

# Decorators on archetypes
def print_bases(cls: type) -> type {
    print(f"Archetype {cls.__name__} bases: {[c.__name__ for c in cls.__bases__]}");
    return cls;
}

def track_creation(cls: type) -> type {
    print(f"Created archetype: {cls.__name__}");
    return cls;
}

@print_bases
@track_creation
node DecoratedNode(Pet) { has special_attr: str = "decorated"; }

# Walker for edge abilities
walker OwnershipWalker {
    can start with `root entry {
        print("OwnershipWalker: tracking ownership edges");
        visit [-->];
    }
    can visit_node with Pet entry {
        print(f"  At pet: {here.name}");
        visit [edge -->];
    }
}

# ===== Tests =====
with entry {
    print("=== 1. Basic Archetypes ===");

    print("\n--- Class with Init Constructor (Python-style explicit self) ---");
    classic = ClassicAnimal("Cat", 3, "Whiskers");
    classic.describe();
    classic2 = ClassicAnimal("Bird", 1);
    classic2.describe();

    print("\n--- Object with Has Declarations (implicit self) ---");
    # Demonstrate that obj has variables are instance variables (not class variables)
    animal1 = Animal();
    animal2 = Animal();
    print(f"Before assignment - animal1.species: {animal1.species}, animal2.species: {animal2.species}");

    # Assigning to obj instance variable
    animal1.species = "Dog";
    print(f"After animal1.species = 'Dog' - animal1.species: {animal1.species}, animal2.species: {animal2.species}");
    print("Note: Each obj instance has its own copy of the variable");
    animal1.make_sound();

    dom = Domesticated();
    dom.owner = "Alice";
    dom.trained = True;
    print(f"Owner: {dom.owner}, Trained: {dom.trained}");

    print("\n=== 2. Multiple Inheritance ===");
    pet1 = Pet();
    pet1.name = "Buddy";
    pet1.species = "Dog";
    pet1.owner = "Bob";
    pet1.play();
    pet1.train();
    print(f"Warm blooded: {pet1.warm_blooded}");

    print("\n=== 3. Edge Methods ===");
    rel = Relationship();
    rel.strength = 8;
    rel.strengthen();

    print("\n=== 4. Walker Inheritance ===");
    pet2 = Pet();
    pet2.name = "Max";
    pet2.species = "Cat";
    root ++> pet1 ++> pet2;

    person = Person();
    person.name = "Alice";
    person.species = "Human";
    root spawn person;
    print(f"Alice visited {person.visited_count} pets");

    vet = Veterinarian();
    vet.name = "Dr.Smith";
    vet.specialty = "canine";
    vet.species = "Human";
    root spawn vet;

    print("\n=== 5. Edge Abilities ===");
    owner = Pet();
    owner.name = "Owner";
    owned = Pet();
    owned.name = "Owned";
    root ++> owner +>: Ownership(duration_years=3) :+> owned;
    root spawn OwnershipWalker();

    print("\n=== 6. Access Modifiers ===");
    print(f"Private: {PrivateConfig().secret_key}, Public: {PublicAPI().version}, Protected: {ProtectedResource().resource_id}");

    print("\n=== 7. Forward Declarations ===");
    animal_node = AnimalNode();
    animal_node.animal_type = "lion";
    animal_node.describe();
    print(f"Edge weight: {SpecialEdge().get_weight()}");

    root ++> animal_node;
    spec = SpecializedWalker();
    spec.specialization = "wildlife";
    animal_node spawn spec;

    print("\n=== 8. Decorators ===");
    decorated = DecoratedNode();
    decorated.name = "Deco";
    print(f"Decorated: {decorated.special_attr}");

    print("\n✓ All features demonstrated!");
}
# Archetypes - All 5 types: class, obj, node, edge, walker

# Class with init constructor (Python-style with explicit self)
# Note: No 'has' declarations - init creates instance variables directly
class ClassicAnimal {
    def init(self: ClassicAnimal, species: str, age: int, name: str = "Unnamed") {
        self.species = species;
        self.age = age;
        self.name = name;
    }

    def describe(self: ClassicAnimal) { print(f"{self.name} is a {self.age} year old {self.species}"); }
}

# Object archetype with has declarations (implicit self in methods)
obj Animal {
    has species: str = "Unknown";
    has age: int = 0;
    def make_sound { print(f"{self.species} makes a sound"); }
}

# Object archetype (implicit self in methods)
obj Domesticated {
    has owner: str = "None";
    has trained: bool = False;
    def train {  # No self parameter - it's implicit in obj
        self.trained = True;
        print(f"Training {self.owner}'s pet");
    }
}

obj Mammal { has warm_blooded: bool = True; }

# Node with multiple inheritance
node Pet(Animal, Domesticated, Mammal) {
    has name: str = "Unnamed";
    has favorite_toy: str = "ball";
    def play { print(f"{self.name} plays with {self.favorite_toy}"); }

    can greet_person with Person entry {
        print(f"  {self.name} wags tail at {visitor.name}");
    }
}

# Edge with public access modifier and method
edge :pub Relationship {
    has strength: int = 5;
    has since: int = 2020;
    def strengthen {
        self.strength += 1;
        print(f"Relationship strengthened to {self.strength}");
    }
}

# Edge with walker ability
edge Ownership {
    has duration_years: int = 0;
    can track with OwnershipWalker entry {
        print(f"  Edge: Ownership duration = {self.duration_years} years");
        self.duration_years += 1;
    }
}

# Walker with inheritance chain (Person -> Caretaker -> Veterinarian)
walker Person(Animal) {
    has name: str = "Person";
    has visited_count: int = 0;
    can greet with `root entry {
        print(f"{self.name}: Starting walk from root");
        visit [-->];
    }
    can visit_pet with Pet entry {
        self.visited_count += 1;
        print(f"{self.name} visits {here.name}");
        visit [-->];
    }
}

walker Caretaker(Person) {
    has care_quality: int = 10;
    can care_for with Pet entry {
        print(f"{self.name} cares for {here.name} (quality: {self.care_quality})");
        visit [-->];
    }
}

walker Veterinarian(Caretaker) {
    has specialty: str = "general";
    can examine with Pet entry {
        print(f"Dr. {self.name} ({self.specialty}) examines {here.name}");
        visit [-->];
    }
}

# Async walker
async walker AsyncInspector {
    has inspected: list = [];
    async can inspect with `root entry {
        print("AsyncInspector: starting");
        visit [-->];
    }
    async can check with Pet entry {
        self.inspected.append(here.name);
        print(f"  Async checking: {here.name}");
        visit [-->];
    }
}

# Access modifiers: private, public, protected
obj :priv PrivateConfig { has secret_key: str = "hidden"; }
obj :pub PublicAPI { has version: str = "1.0"; }
obj :protect ProtectedResource { has resource_id: int = 0; }

# Forward declarations
node AnimalNode;
walker SpecializedWalker;
edge SpecialEdge;

# Implementation blocks for forward declarations
impl AnimalNode {
    has animal_type: str = "wild";
    has habitat: str = "forest";
    def describe { print(f"AnimalNode: {self.animal_type} in {self.habitat}"); }
}

impl SpecializedWalker {
    has specialization: str = "research";
    can process with AnimalNode entry {
        print(f"SpecializedWalker ({self.specialization}): Processing node");
        disengage;
    }
}

impl SpecialEdge {
    has edge_weight: float = 1.0;
    def get_weight -> float { return self.edge_weight; }
}

# Decorators on archetypes
def print_bases(cls: type) -> type {
    print(f"Archetype {cls.__name__} bases: {[c.__name__ for c in cls.__bases__]}");
    return cls;
}

def track_creation(cls: type) -> type {
    print(f"Created archetype: {cls.__name__}");
    return cls;
}

@print_bases
@track_creation
node DecoratedNode(Pet) { has special_attr: str = "decorated"; }

# Walker for edge abilities
walker OwnershipWalker {
    can start with `root entry {
        print("OwnershipWalker: tracking ownership edges");
        visit [-->];
    }
    can visit_node with Pet entry {
        print(f"  At pet: {here.name}");
        visit [edge -->];
    }
}

# ===== Tests =====
with entry {
    print("=== 1. Basic Archetypes ===");

    print("\n--- Class with Init Constructor (Python-style explicit self) ---");
    classic = ClassicAnimal("Cat", 3, "Whiskers");
    classic.describe();
    classic2 = ClassicAnimal("Bird", 1);
    classic2.describe();

    print("\n--- Object with Has Declarations (implicit self) ---");
    # Demonstrate that obj has variables are instance variables (not class variables)
    animal1 = Animal();
    animal2 = Animal();
    print(f"Before assignment - animal1.species: {animal1.species}, animal2.species: {animal2.species}");

    # Assigning to obj instance variable
    animal1.species = "Dog";
    print(f"After animal1.species = 'Dog' - animal1.species: {animal1.species}, animal2.species: {animal2.species}");
    print("Note: Each obj instance has its own copy of the variable");
    animal1.make_sound();

    dom = Domesticated();
    dom.owner = "Alice";
    dom.trained = True;
    print(f"Owner: {dom.owner}, Trained: {dom.trained}");

    print("\n=== 2. Multiple Inheritance ===");
    pet1 = Pet();
    pet1.name = "Buddy";
    pet1.species = "Dog";
    pet1.owner = "Bob";
    pet1.play();
    pet1.train();
    print(f"Warm blooded: {pet1.warm_blooded}");

    print("\n=== 3. Edge Methods ===");
    rel = Relationship();
    rel.strength = 8;
    rel.strengthen();

    print("\n=== 4. Walker Inheritance ===");
    pet2 = Pet();
    pet2.name = "Max";
    pet2.species = "Cat";
    root ++> pet1 ++> pet2;

    person = Person();
    person.name = "Alice";
    person.species = "Human";
    root spawn person;
    print(f"Alice visited {person.visited_count} pets");

    vet = Veterinarian();
    vet.name = "Dr.Smith";
    vet.specialty = "canine";
    vet.species = "Human";
    root spawn vet;

    print("\n=== 5. Edge Abilities ===");
    owner = Pet();
    owner.name = "Owner";
    owned = Pet();
    owned.name = "Owned";
    root ++> owner +>: Ownership(duration_years=3) :+> owned;
    root spawn OwnershipWalker();

    print("\n=== 6. Access Modifiers ===");
    print(f"Private: {PrivateConfig().secret_key}, Public: {PublicAPI().version}, Protected: {ProtectedResource().resource_id}");

    print("\n=== 7. Forward Declarations ===");
    animal_node = AnimalNode();
    animal_node.animal_type = "lion";
    animal_node.describe();
    print(f"Edge weight: {SpecialEdge().get_weight()}");

    root ++> animal_node;
    spec = SpecializedWalker();
    spec.specialization = "wildlife";
    animal_node spawn spec;

    print("\n=== 8. Decorators ===");
    decorated = DecoratedNode();
    decorated.name = "Deco";
    print(f"Decorated: {decorated.special_attr}");

    print("\n✓ All features demonstrated!");
}
from __future__ import annotations
from jaclang.runtimelib.builtin import *
from jaclang import JacMachineInterface as _jl

class ClassicAnimal:

    def __init__(self: ClassicAnimal, species: str, age: int, name: str='Unnamed') -> None:
        self.species = species
        self.age = age
        self.name = name

    def describe(self: ClassicAnimal) -> None:
        print(f'{self.name} is a {self.age} year old {self.species}')

class Animal(_jl.Obj):
    species: str = 'Unknown'
    age: int = 0

    def make_sound(self) -> None:
        print(f'{self.species} makes a sound')

class Domesticated(_jl.Obj):
    owner: str = 'None'
    trained: bool = False

    def train(self) -> None:
        self.trained = True
        print(f"Training {self.owner}'s pet")

class Mammal(_jl.Obj):
    warm_blooded: bool = True

class Pet(Animal, Domesticated, Mammal, _jl.Node):
    name: str = 'Unnamed'
    favorite_toy: str = 'ball'

    def play(self) -> None:
        print(f'{self.name} plays with {self.favorite_toy}')

    @_jl.entry
    def greet_person(self, visitor: Person) -> None:
        print(f'  {self.name} wags tail at {visitor.name}')

class Relationship(_jl.Edge):
    strength: int = 5
    since: int = 2020

    def strengthen(self) -> None:
        self.strength += 1
        print(f'Relationship strengthened to {self.strength}')

class Ownership(_jl.Edge):
    duration_years: int = 0

    @_jl.entry
    def track(self, visitor: OwnershipWalker) -> None:
        print(f'  Edge: Ownership duration = {self.duration_years} years')
        self.duration_years += 1

class Person(Animal, _jl.Walker):
    name: str = 'Person'
    visited_count: int = 0

    @_jl.entry
    def greet(self, here: _jl.Root) -> None:
        print(f'{self.name}: Starting walk from root')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().visit()))

    @_jl.entry
    def visit_pet(self, here: Pet) -> None:
        self.visited_count += 1
        print(f'{self.name} visits {here.name}')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().visit()))

class Caretaker(Person, _jl.Walker):
    care_quality: int = 10

    @_jl.entry
    def care_for(self, here: Pet) -> None:
        print(f'{self.name} cares for {here.name} (quality: {self.care_quality})')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().visit()))

class Veterinarian(Caretaker, _jl.Walker):
    specialty: str = 'general'

    @_jl.entry
    def examine(self, here: Pet) -> None:
        print(f'Dr. {self.name} ({self.specialty}) examines {here.name}')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().visit()))

class AsyncInspector(_jl.Walker):
    __jac_async__ = True
    inspected: list = _jl.field(factory=lambda: [])

    @_jl.entry
    async def inspect(self, here: _jl.Root) -> None:
        print('AsyncInspector: starting')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().visit()))

    @_jl.entry
    async def check(self, here: Pet) -> None:
        self.inspected.append(here.name)
        print(f'  Async checking: {here.name}')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().visit()))

class PrivateConfig(_jl.Obj):
    secret_key: str = 'hidden'

class PublicAPI(_jl.Obj):
    version: str = '1.0'

class ProtectedResource(_jl.Obj):
    resource_id: int = 0

class AnimalNode(_jl.Node):
    animal_type: str = 'wild'
    habitat: str = 'forest'

    def describe(self) -> None:
        print(f'AnimalNode: {self.animal_type} in {self.habitat}')

class SpecializedWalker(_jl.Walker):
    specialization: str = 'research'

    @_jl.entry
    def process(self, visitor: AnimalNode) -> None:
        print(f'SpecializedWalker ({self.specialization}): Processing node')
        _jl.disengage(visitor)
        return

class SpecialEdge(_jl.Edge):
    edge_weight: float = 1.0

    def get_weight(self) -> float:
        return self.edge_weight

def print_bases(cls: type) -> type:
    print(f'Archetype {cls.__name__} bases: {[c.__name__ for c in cls.__bases__]}')
    return cls

def track_creation(cls: type) -> type:
    print(f'Created archetype: {cls.__name__}')
    return cls

@print_bases
@track_creation
class DecoratedNode(Pet, _jl.Node):
    special_attr: str = 'decorated'

class OwnershipWalker(_jl.Walker):

    @_jl.entry
    def start(self, here: _jl.Root) -> None:
        print('OwnershipWalker: tracking ownership edges')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().visit()))

    @_jl.entry
    def visit_node(self, here: Pet) -> None:
        print(f'  At pet: {here.name}')
        _jl.visit(self, _jl.refs(_jl.Path(here)._out().edge().visit()))
print('=== 1. Basic Archetypes ===')
print('\n--- Class with Init Constructor (Python-style explicit self) ---')
classic = ClassicAnimal('Cat', 3, 'Whiskers')
classic.describe()
classic2 = ClassicAnimal('Bird', 1)
classic2.describe()
print('\n--- Object with Has Declarations (implicit self) ---')
animal1 = Animal()
animal2 = Animal()
print(f'Before assignment - animal1.species: {animal1.species}, animal2.species: {animal2.species}')
animal1.species = 'Dog'
print(f"After animal1.species = 'Dog' - animal1.species: {animal1.species}, animal2.species: {animal2.species}")
print('Note: Each obj instance has its own copy of the variable')
animal1.make_sound()
dom = Domesticated()
dom.owner = 'Alice'
dom.trained = True
print(f'Owner: {dom.owner}, Trained: {dom.trained}')
print('\n=== 2. Multiple Inheritance ===')
pet1 = Pet()
pet1.name = 'Buddy'
pet1.species = 'Dog'
pet1.owner = 'Bob'
pet1.play()
pet1.train()
print(f'Warm blooded: {pet1.warm_blooded}')
print('\n=== 3. Edge Methods ===')
rel = Relationship()
rel.strength = 8
rel.strengthen()
print('\n=== 4. Walker Inheritance ===')
pet2 = Pet()
pet2.name = 'Max'
pet2.species = 'Cat'
_jl.connect(left=_jl.connect(left=_jl.root(), right=pet1), right=pet2)
person = Person()
person.name = 'Alice'
person.species = 'Human'
_jl.spawn(_jl.root(), person)
print(f'Alice visited {person.visited_count} pets')
vet = Veterinarian()
vet.name = 'Dr.Smith'
vet.specialty = 'canine'
vet.species = 'Human'
_jl.spawn(_jl.root(), vet)
print('\n=== 5. Edge Abilities ===')
owner = Pet()
owner.name = 'Owner'
owned = Pet()
owned.name = 'Owned'
_jl.connect(left=_jl.connect(left=_jl.root(), right=owner), right=owned, edge=Ownership(duration_years=3))
_jl.spawn(_jl.root(), OwnershipWalker())
print('\n=== 6. Access Modifiers ===')
print(f'Private: {PrivateConfig().secret_key}, Public: {PublicAPI().version}, Protected: {ProtectedResource().resource_id}')
print('\n=== 7. Forward Declarations ===')
animal_node = AnimalNode()
animal_node.animal_type = 'lion'
animal_node.describe()
print(f'Edge weight: {SpecialEdge().get_weight()}')
_jl.connect(left=_jl.root(), right=animal_node)
spec = SpecializedWalker()
spec.specialization = 'wildlife'
_jl.spawn(animal_node, spec)
print('\n=== 8. Decorators ===')
decorated = DecoratedNode()
decorated.name = 'Deco'
print(f'Decorated: {decorated.special_attr}')
print('\n✓ All features demonstrated!')
Jac Grammar Snippet
archetype: decorators? KW_ASYNC? archetype_decl
         | enum

archetype_decl: arch_type access_tag? NAME inherited_archs? (member_block | SEMI)
decorators: (DECOR_OP atomic_chain)+
access_tag: COLON ( KW_PROT | KW_PUB | KW_PRIV )
inherited_archs: LPAREN (atomic_chain COMMA)* atomic_chain RPAREN


arch_type: KW_WALKER
          | KW_OBJECT
          | KW_EDGE
          | KW_NODE
          | KW_CLASS

Description

Archetypes are Jac's fundamental type declarations, providing five distinct keywords for building both traditional object-oriented and Object-Spatial programs.

The Five Archetype Types:

Type Purpose Spatial? Use Case
class Traditional OOP classes No Pure object-oriented programming without graph features
obj OOP objects compatible with spatial Hybrid Bridge between OOP and spatial programming
node Graph vertices Yes Data locations that can be connected and visited
edge Graph relationships Yes First-class connections with state and behavior
walker Mobile computation Yes Traversal logic that flows to data

Key Difference: class vs obj

The fundamental distinction between class and obj is their variable semantics:

  • class: Uses traditional Python class semantics. has variables with defaults become class variables initially, but can be shadowed by instance variables when assigned (e.g., self.species = "Dog"). Methods require explicit self parameter with type annotation (e.g., def init(self: MyClass, ...)).
  • obj: Uses Python dataclass semantics where all has variables automatically become instance variables with each instance having its own copy. Methods have implicit self - it doesn't appear in the parameter list.

This difference is critical when choosing between class and obj: - Use class when you need class variables (shared state), Python-style explicit self, and traditional class behavior - Use obj when you need guaranteed instance variables, implicit self, or compatibility with spatial archetypes (node, edge, walker also use implicit self)

Basic Archetype Declaration:

Lines 3-13 demonstrate a class archetype with custom init constructor (Python-style with explicit self). Note: There are no has declarations - the init method (lines 6-10) creates instance variables directly by assigning to self.species, self.age, and self.name. This shows that in class archetypes with custom init, you can create instance variables without pre-declaring them with has. All methods including init require explicit self with type annotation (e.g., self: ClassicAnimal). The describe method (line 12) also has the explicit self: ClassicAnimal parameter.

Lines 15-20 show an obj archetype with has declarations and implicit self. The has keyword declares attributes with type annotations and default values. In obj archetypes, all has variables are instance variables - each instance gets its own copy (as demonstrated in lines 176-186). Methods like make_sound (line 19) have implicit self - it doesn't appear in the parameter list but can be used in the method body.

Lines 22-32 demonstrate another obj archetype (Domesticated), which also uses implicit self in methods. All has variables in obj are instance variables, making each object's attributes independent. Objects can be inherited by nodes for hybrid OOP/spatial designs.

Lines 23-31 show a node archetype with multiple inheritance from both Animal and Domesticated objects, plus Mammal. Nodes represent graph vertices and can define both methods and abilities. The can keyword (line 28) defines an ability that triggers automatically when a specific walker type visits.

Lines 34-41 demonstrate an edge archetype with the :pub access modifier, member variables, and a method. Edges are first-class relationships that carry state and behavior.

Lines 53-65 show a walker archetype inheriting from Animal. Walkers traverse graphs and execute node-specific abilities. Line 56 shows the special `root type for the entry ability.

Inheritance Patterns:

graph TD
    A[Animal] --> P[Person Walker]
    P --> C[Caretaker Walker]
    C --> V[Veterinarian Walker]

    A2[Animal] --> Pet[Pet Node]
    Dom[Domesticated] --> Pet
    Mam[Mammal] --> Pet

Lines 67-81 demonstrate walker inheritance chains. Veterinarian inherits from Caretaker, which inherits from Person, creating a three-level hierarchy. Each child accumulates all parent abilities plus its own.

Lines 23-31 show multiple inheritance where Pet combines three parent archetypes. When inheriting from both obj and class types, obj attributes become constructor parameters while class attributes must be set post-construction.

Access Modifiers:

Lines 98-100 demonstrate the three access levels using colon syntax: - :priv - Private to defining module - :pub - Publicly accessible - :protect - Protected to subclasses

Access modifiers appear after the archetype keyword and before the name.

Methods vs Abilities:

Feature Methods (def) Abilities (can)
Invocation Explicit call Automatic trigger on visit
Availability All archetypes Only node, edge, walker
Polymorphism Standard OOP Bidirectional (walker→node and node→walker)
Context self self, here, visitor

Line 7 shows a method definition - must be explicitly called like animal.make_sound().

Lines 28-30 show a node ability that triggers when a Person walker visits. Line 29 accesses the visiting walker via visitor.

Lines 46-49 show an edge ability triggered during edge traversal. Abilities enable event-driven spatial programming.

Bidirectional Polymorphism:

When a walker visits a node, both execute matching abilities: - Walker's abilities dispatch based on visited node type (lines 60-64) - Node's abilities dispatch based on visiting walker type (lines 28-30)

This creates rich interaction patterns where both parties respond to encounters.

Forward Declarations and Implementations:

Lines 103-105 show forward declarations - declaring archetype names without bodies. These enable: - Breaking circular dependencies - Organizing large codebases - Separating interface from implementation

Lines 108-125 provide implementations via impl blocks. Each impl block adds members, methods, and abilities to the forward-declared archetype.

Decorators:

Lines 128-140 demonstrate decorator usage. Decorators are Python functions that transform archetypes at definition time. Multiple decorators stack and apply bottom-up (line 140 applies track_creation first, then print_bases).

Async Walkers:

Lines 84-95 show async walker declaration. The async keyword enables concurrent operations: - Async walkers can have async abilities (line 86, 90) - Async abilities can use await for asynchronous operations - Useful for I/O-bound traversal logic

Spatial Integration:

Lines 184-204 demonstrate Object-Spatial Programming: - Line 184: Create graph structure with ++> (connect operator) - Line 189: Spawn walker at root with root spawn person - Line 203: Connect with typed edge using +>: EdgeType() :+> - Line 204: Spawn walker to trigger edge abilities

Spatial archetypes (node, edge, walker) enable computation that flows to data locations rather than data flowing to functions - a fundamental shift from traditional programming paradigms.

Execution Flow:

graph LR
    R[root] -->|spawn| W[Walker]
    W -->|visit| N1[Node1]
    N1 -->|trigger| A1[Node Ability]
    N1 -->|trigger| A2[Walker Ability]
    W -->|visit| N2[Node2]
    N2 -->|trigger| A3[Walker Ability]

When a walker spawns and visits nodes, abilities automatically trigger based on type matching, creating declarative traversal patterns.