--
← Back to blog
Entities, Contracts, and OOP in NSL

Entities, Contracts, and OOP in NSL

Entities

NSL uses entity instead of class. Entities support constructors, methods, inheritance, and visibility modifiers.

entity Animal
    :: init(self, name, sound) ->
        self.name = name
        self.sound = sound

    :: speak(self) ->
        print(f"{self.name} says {self.sound}")

let dog = Animal("Rex", "woof")
dog.speak()  # "Rex says woof"

Inheritance

entity Dog from Animal
    :: init(self, name, breed) ->
        self.name = name
        self.sound = "woof"
        self.breed = breed

    :: fetch(self, item) ->
        print(f"{self.name} fetches the {item}!")

let d = Dog("Rex", "Labrador")
d.speak()        # inherited: "Rex says woof"
d.fetch("ball")  # "Rex fetches the ball!"

Visibility Modifiers

Control access to entity members:

entity Account
    exposed balance = 0       # public (default)
    hidden _password = ""     # private
    guarded _internal = null  # protected (subclasses only)

    :: init(self, initial) ->
        self.balance = initial

    exposed :: deposit(self, amount) ->
        self.balance += amount

    hidden :: _validate(self) ->
        return self.balance >= 0

Class Methods

Shared methods belong to the entity, not instances:

entity Counter
    shared count = 0

    shared :: increment() ->
        Counter.count += 1

    shared :: get_count() ->
        return Counter.count

Counter.increment()
Counter.increment()
print(Counter.get_count())  # 2

Contracts (Interfaces)

Define method signatures that entities must implement:

contract Drawable
    :: draw(self) ->
    :: area(self) ->

entity Circle implements Drawable
    :: init(self, radius) ->
        self.radius = radius

    :: draw(self) ->
        print(f"Drawing circle with radius {self.radius}")

    :: area(self) ->
        return 3.14159 * self.radius ** 2

Choices (Enums)

choices Color
    Red
    Green
    Blue
    Custom(r, g, b)

let c = Color.Red
let custom = Color.Custom(255, 128, 0)

Domains (Namespaces)

Group related functions and types:

domain physics
    const G = 9.81

    :: kinetic_energy(mass, velocity) ->
        return 0.5 * mass * velocity ** 2

    :: potential_energy(mass, height) ->
        return mass * G * height

let ke = physics.kinetic_energy(10, 5)

Type Aliases

type Point = {x: float, y: float}
type Callback = fn(int) -> bool

Operator Overloading

entity Vector
    :: init(self, x, y) ->
        self.x = x
        self.y = y

operator +(a: Vector, b: Vector)
    return Vector(a.x + b.x, a.y + b.y)

let v = Vector(1, 2) + Vector(3, 4)
print(f"({v.x}, {v.y})")  # (4, 6)

With Statement (Context Manager)

with open_connection("db://localhost") as conn do
    conn.query("SELECT * FROM users")
    # conn is automatically closed after this block
All Posts