Objects in Nim use the type
constructor:
## Type Definition
type
MusicTrack = object
index: int
title: string
## (Mutable) Value
var summer = MusicTrack(index: 1, title: "Summer in the City")
That reminds me of Records in Reason:
/* Type definition */
type musicTrack = {index: int, title: string}
/* Value */
let summerInTheCity = {index: 1, title: "Summer in the City"}
In Nim, “An object is a value type, which means that when an object is assigned to a new variable all its components are copied as well.” 1
When you call the object constructor with var summer
, you create a mutable object on the stack.
type PersonRef = ref object
id: int
name: string
let tom = PersonRef(id: 1, name: "Tom")
tom
is a reference to an object allocated on the heap. tom
is immutable (via the let
keyword). You can’t change the tom
variable.
When you initialize tom
, Nim will create the object on the stack with binary zeroes. And although the let
keyword makes the variable immutable, you can change the values it is pointing at.
Thus, you can “assign” new values to tom
(id
of 1 and name
of “Tom”). You must do that when you define the new variable (let tom
). You can’t change it later.
const
variables work the same as let
, but must be computable at compile time. The main benefit is efficiency, as the compiler can optimize them.
In JavaScript, you might declare a new object literal with a const
keyword.
const myCar = {
make: "Toyota,
model: "Yaris",
year: 2005
}
const
means that you can’t declare a new variable with the same name myCar
.
This doesn’t work:
const myCar = {
make: "Toyota,
model: "Yaris",
year: 2005
}
const myCar = {
make: "Tesla"
model: "S",
year: 2018
}
But you can still change the values inside myCar
. The keywords inside the object point to the actual values. And you can change where you point them at.
const myCar = {
make: "Toyota,
model: "Yaris",
year: 2005
}
myCar.make = "Tesla"
myCar
> {make: "Tesla", model: "Yaris", year: 2008, features: Array(2)}
Now you have a Tesla instead of a Toyota!
Reference Types
For Nim:
References (similar to pointers in other programming languages) are a way to introduce many-to-one relationships. This means different references can point to and modify the same location in memory . 2
Now you can create mutually recursive types.
Nim:
type Student = ref object
taughtBy: ref Teacher
type Teacher = ref object
students: seq[Student]
Reason 3:
type student = {taughtBy: teacher}
and teacher = {students: list(student)};
If you pass a ref
object as an argument to a procedure (function), the procedure can modify it.
Nim encourages composition over inheritance for objects, but you can use inheritance and OOP patterns, see Object Oriented Programming.