2022/12/27
Table of contents
Nim is a programming language and while I was browsing reddit, someone suggested it in the comments as an alternative to Python because the syntax was similar so I decided to check it out.
According to Nims website the description is:
Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula.
Efficiency is one of Nims priorities.
One of the controversial features of Nim is the style-insensitive for variables, functions and type names. This is the first time I see a programming language with style-insensitive and doesn’t feel right. This is a valid nim file that compiles and runs without errors.
|
|
This feature can be disabled so you can program just like any other language with the flag --styleCheck
by default this option is off, but you can set it with hint
which will compile the program but output a hint message on the variables look the same or error
in which the program won’t compile if you have variables that are similar but not the same.
$ nim --styleCheck:error c vars.nim
vars.nim(3, 8) Error: 'fOOBAR' should be: 'foobar' [let declared in vars.nim(1, 5)]
In nim you have different types of variables and the compiler can infer the type of the variable based on the value making it a loosely typed language.
The let
type of variables are inmutable that means that once defined its value can’t be changed and can’t be redefined, meaning:
|
|
$ nim -r c letvars.nim
letvars.nim(6, 1) Error: 'x' cannot be assigned to
And if we change in line 6 to let x = 2
we get the following error
$ nim -r c letvars.nim
letvars.nim(6, 5) Error: redefinition of 'x'; previous declaration here: typevars.nim(3, 5)
This type of variable is mutable, meaning the value assigned to a variable can be changed later.
|
|
$ nim -r c varvars.nim
The value of x is 1
The new value of x is 2
FInally we have constants, this like it name says are constant are inmutable. The difference with the let
type of variable is that const
are evaluated at compile time while let expressions are evaluated at run time. So if you know and won’t change the value then const
should be used.
|
|
$ nim -r c constvars.nim
The value of x is 1
One of basic data structures commonly used in Python are lists. Similarly NIm provides 2 data structures like lists which I’ll explain their characteristics
This type of data structure behave similarly like lists in Python. You can create a sequence and add or remove elements from the sequence, the size is dynamic. Though you can’t mix different types within a list like in python where you can have ints and strings.
|
|
In languages like C arrays once they have been initialized their size can’t be easily modified, so if you define an array of 10 elements then to add another element you have to either create a new array of size 11 and include the new element or deal manually with memory, though there is a reason rust is becoming popular because it enforces memory safety which is not easy to deal with.
In Nim arrays behave similarly like they do in C, they have a static size and once initialized they can’t be changed in size.
One of the features of arrays in Nim is that it checks for access out of bounds at compile time unlike C which will throw an error at run time
|
|
Nim code, like it was mentioned in the first paragraphs, can be compiled by the nim compiler into an executable, the way it does it is by turning the nim code into C code and then uses a C compiler to turn it into an executable.
For example, lets say we have a file called hello.nim
with the following code
|
|
To compile it we run $ nim c hello.nim
and we get an executable hello
. The generated C files will be stored in $HOME/.cache/nim/hello_d/
and if we check the files it generated in that directory you should see this:
$ ls .cache/nim/hello_d/
hello.json
@mhello.nim.c
@mhello.nim.c.o
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@sstd@sprivate@sdigitsutils.nim.c
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@sstd@sprivate@sdigitsutils.nim.c.o
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@ssystem.nim.c
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@ssystem.nim.c.o
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@ssystem@sdollars.nim.c
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@ssystem@sdollars.nim.c.o
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@ssystem@sio.nim.c
@m..@s..@s.choosenim@stoolchains@snim-1.6.10@slib@ssystem@sio.nim.c.o
The hello.json
file is generated and used by the nim compiler and holds the information to compile the program with a C compiler, in this case GCC here is the output (I replaced the full home path with $HOME):
|
|
The file @mhello.nim.c
is the one that has contains the string “Hello, World!”
By default nim compiles in “debug mode” which like it name says it turns on certain checks and when it crashes it gives you a traceback of where in the code it failed. If you turn release mode on by passing the flag -d:release
to the compiler then it will turn off checks (which might speed up your program) and won’t show a traceback when it fails.
For example, lets say we have this program, it has a function that takes a sequence and given a sequence a number it will echo the given index + 1 of that sequence
|
|
$ nim c fruit.nim
26651 lines; 0.260s; 31.629MiB peakmem; proj: fruit.nim; out: fruit [SuccessX]
$ ./fruit
fruit.nim(9) fruit
fruit.nim(4) printFruits
~/.choosenim/toolchains/nim-1.6.10/lib/system/fatal.nim(54) sysFatal
Error: unhandled exception: index 5 not in 0 .. 2 [IndexDefect]
$ nim -d:release c fruit.nim
26651 lines; 0.248s; 31.645MiB peakmem; proj: fruit.nim; out: fruit [SuccessX]
$ ./fruit
fatal.nim(54) sysFatal
Error: unhandled exception: index 5 not in 0 .. 2 [IndexDefect]
As you can see debug mode shows the traceback, first the fruit.nim(9)
which is the first line that calls the function printFruits
and then shows the line and the name of the function where it failed fruit.nim(4) printFruits
. In release mode it simply states the error that it tried to access index 5 when it only goes from 0 to 2 but not where.
Nim looks like a very promising language, similar syntax to Python but compiles to C with tools like gcc, which makes it portable.
Although the language is stable (on version 1.x.x) there are changes and discussions being made for a version 2.0.
I’d keep an eye on Nim and check it out again once they release version 2.0.