Objects are basic blocks of a Nim Programming language and are similar to the type in typescripts.

It is used to create a new type by grouping existing data types.

Notes:

  • Contains a group of existing types
  • Default eligible to garbage collector when unreferenced
  • An object can be passed to a procedure using value, You can pass reference type for mutating an object while passing to procedure

Nim Objects

The object is a new type created using the type keyword.

type Employee = object
  id: int
  name: string

Employee object declared, Let’s create a variable for this object.

let emp1: Employee;

Another way to initialize the object using constructor syntax

var emp1 = Employee(id: 3 , name: "John" )
echo emp1

Output:

(id: 3, name: "John")

The object variable is stored in the stack.

Pass an object to the procedure in NIM

Here is an example of passing an object to the procedure in Nim. Procedure modifies an object. By default object is not modified,

You have to add ref to make it a reference type so that it mutates an object.

In the below procedure, pass a reference to an object instead of an object.

type Employee = ref object
  id: int
  name: string
  salary: int

proc addSalary(self: Employee): int =
  self.salary += 1000
  return self.salary

var emp = Employee(id:1, name: "john", salary: 2000)

echo addSalary(emp);

output:

3000

Nim Inheritance example

Inheritance is one of the oops concepts for reusing an object’s properties and methods. Nim supports Inheritance using type and of keywords.

  • Created a parent Object Shape which contains name and method print

  • Square and Rectangle extend Shape using ref object of Shape and overrides all methods behaviors.

  • Version of the method is to be decided on the type of an object.

  • An object checks whether extends the superclass using the of keyword

Here is an example

type Shape = ref object of RootObj
  name: string
method print(self: Shape): string {.base.} = "..."

type Square = ref object of Shape
method print(self: Square): string = "Square"

type Rectangle = ref object of Shape
method print(self: Rectangle): string = "Rectangle"

var shapes: seq[Shape] = @[]
shapes.add(Square(name: "square"))
shapes.add(Rectangle(name: "rectangle"))

for shape in shapes:
  echo shape.print()
  echo(shape of Square)
  echo(shape of Rectangle)
  echo(shape of Shape)

Output:

Square
true
false
true
Rectangle
false
true
true

Different types of Objects

  • Value type

It is a plain object similar to Struct in C and record type in Typescript. It allocates objects in stack memory Object equality is whether the same data exists or not

type Employee = object
  id: int
  name: string
  salary: int
  • Reference type

References types are stored under heap memory and not thread-safe and GC is automatic.

type Employee = ref object
  id: int
  name: string
  salary: int

Object equality for reference is pointing to the same object or not

  • Pointer type

Pointer objects are not automatically managed. The data is stored in a heap and stack.

type Employee = ptr object
  id: int
  name: string
  salary: int