Maybe this is not possible, or I'm missing something. Given the following example:
converter floatToInt(f: float): int = f.int # allow conversion
type Point[T] = object
x: T
y: T
proc point[T](x, y: T): Point[T] =
return Point[T](x: x, y: y)
# this works
var a = point(1, 1) # int
var b = point(2.1, 2.2) # float
echo typedesc a, a
echo typedesc b, b
# this works
a = point[int](b.x, b.y)
# this doesn't
a = point(b.x, b.y)
# ideally I want to do this
# a = point(b)
Assuming for simplicity that T will be only int or float.
The proc point(x, y) above accepts int or float, without the need to specify the type. Here the result is based on the type of the arguments. How can I write a proc that will take a Point object and return another Point, based on the type of the variable it's assigned to?
So a Point[T] would be converted to a Point[U], where T can be any type (int or float), and U is the type of the variable the result is assigned to. Which could also be any type, possibly even the same type.
Implicitly converting between int and float is as dangrous as letting your children driving a car without letting them go to driving school. Nim doesn't implicitly convert them for safety. I think if you really need converting between int and float, it should be done explicitly so that you can easily find a bug when you get it.
For example:
type Point[T] = object
x: T
y: T
proc point[T](x, y: T): Point[T] =
return Point[T](x: x, y: y)
proc ConvertPoint[T](RetType: typedesc; x, y: T): Point[RetType] =
Point[RetType](x: RetType(x), y: RetType(y))
proc ConvertPoint[T, U](dest: var Point[T]; x, y: U) =
dest.x = T(x)
dest.y = T(y)
var
intP = point(1, 2)
floatP = point(3.1, 4.2)
intP = ConvertPoint(int, floatP.x, floatP.y)
echo intP
intP = point(0, 0)
ConvertPoint(intP, floatP.x, floatP.y)
echo intP
It's just an example. Think of Point as pixel position on a screen. So float to int is acceptable. But thanks for the example. What I was after was something like this:
proc point[T, U](dest: var Point[T]; pt: Point[U]) =
dest.x = T(pt.x)
dest.y = T(pt.y)
I tried it with Point[U] as return value, but got an error: "can't instanciate U"
So now I can use it like this:
var b = point(2.1, 2.2) # float
var c: Point[int]
c.point(b)
Now how to turn that into?
c = point(b)
:-)Ok, I found a solution. Seems converter is selected based on the type of the result. So I can define it like this:
converter toPointInt*[T](pt: Point[T]): Point[int] =
result.x = int(pt.x)
result.y = int(pt.y)
converter toPointFloat*[T](pt: Point[T]): Point[float] =
result.x = float(pt.x)
result.y = float(pt.y)
And then just call
c = b
https://play.nim-lang.org/#ix=3IJX
Maybe it's not good practice, but useful to hide the details in certain situations and to avoid clutter.