DEV Community

Sophia Brandt
Sophia Brandt

Posted on • Originally published at rockyourcode.com on

TIL: Objects in Nim

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")
Enter fullscreen mode Exit fullscreen mode

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"}
Enter fullscreen mode Exit fullscreen mode

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")
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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
}
Enter fullscreen mode Exit fullscreen mode

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)}
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

Reason 3:

type student = {taughtBy: teacher}
and teacher = {students: list(student)};
Enter fullscreen mode Exit fullscreen mode

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.

Further Reading


  1. https://nim-lang.org/docs/tut1.html#advanced-types-objects 

  2. https://nim-lang.org/docs/tut1.html#advanced-types-reference-and-pointer-types 

  3. https://reasonml.github.io/docs/en/more-on-type#mutually-recursive-types 

Top comments (4)

Collapse
 
idkjs profile image
Alain

So what is NIM about? A teaching language? I didn't find an answer in the top 10 results on DuckDuckGo! I guess the question is, what drew you to it?

Collapse
 
sophiabrandt profile image
Sophia Brandt

It's a systems programming language. The syntax is very similar to Python, but it's statically compiled to stand-alone binary (per default C.).
Thus, it's pretty fast.

I was thinking about learning Rust, but there are a few things that speak against Rust (for me):

  • big language (lots of stuff to learn just from the standard library)
  • memory management via borrow checkers (hard to learn, I assume)
  • verbose syntax

What I like about Nim:

  • white-space syntax
  • over 10 years old (a very small core team, but the language isn't going anywhere)
  • statically compiled to a stand-alone binary
  • "modern" language features: iterators, async/await
  • macro system (the language itself is not that big, but you can extend it yourself with templates, and write your own DSL)
  • garbage collected (the team works on a way of managing memory manually)
Collapse
 
idkjs profile image
Alain

Have you found any good example repos you were able to refer to?

Thread Thread
 
sophiabrandt profile image
Sophia Brandt

I have the book "Nim in Action", here's the code for the projects:
github.com/dom96/nim-in-action-code