May 19, 2019
I think nim is great. I describe it to people as a faster Python that prevents typos. And I used to really like Python, now almost exclusively code in nim. But there is always something to improve.
Lets create a simple vector object:
type Vec2 = object
x, y: float32
We can then create this object by calling its type constructor:
let a = Vec2()
let c = Vec2(x: 1, y: 2)
I don’t want to be typing x: and y: all the time. I want something like this:
let b = Vec2(1, 2)
Error: attempting to call undeclared routine: ‘Vec2’
We can’t do this because we don’t have a function call that maps object parameters to function parameters. But we did!? we just needed to use x: and y: for some reason. Odd, but lets create it:
proc Vec2(x, y: float): Vec2 =
Vec2(x: x, y: y)
Error: redefinition of ‘Vec2’
Wait what I don’t want to redefine it! Compiler just said it was undeclared? I just want to declare a new variant, just like you can do with all the other functions! You know polymorphism… So because of this issue in nim, convention is to use newVec2… which is ugly to type but it works.
proc newVec2(x, y: float): Vec2 =
Vec2(x: x, y: y)
But wait nim has a new keyword? So sometimes you have to use the keyword sometimes you have to use a new as part of the name.
We declare Vec2 as a ref object — meaning object pointer this will make Vec2 always live on the heap and not copy it around all the time. (Which might be faster or slower depending on how you use them)
type Vec2 = ref object
x, y: float32
Our code really does not change if we continue to call the ref object’s default constructor:
proc newVec2(x, y: float): Vec2 =
return Vec2(x: x, y: y)
Why is there a new keyword at all? We only would need to use new if we don’t call the default constructor and created the object manually:
proc newVec2(x, y: float): Vec2 =
result = new(Vec2)
result.x = x
result.y = y
But we can just do it with default constructor:
result = Vec2()
The new is not needed at all!
Its odd that nim has both new convention and new keyword. I would just remove both these odd things!
I would make the default constructors polymorphic so that I could create my own variants and I would remove/deprecate the new keyword because you already can do this with the default constructor.
I would also create, if I was not lazy, a default constructor that takes all of the object members in order as parameters, you know … to be lazy.