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