type
Tr = ref T
T = object of RootObj
r: T2r
T1r = ref T1
T1 = object of RootObj
a: int
T2r = ref T2
T2 = object of T1
b: int
converter c(t: Tr): T2r =
t.r
proc cp(t: Tr): T2r =
t.r
proc p(t: T1r) =
discard
var x: Tr = new(T)
x.r = new(T2)
p(x.r)
p(cp(x))
p(x)
Last line gives: t.nim(27, 2) Error: type mismatch: got (Tr) but expected one of: t.p(t: T1r)
So this is something which a converter can not handle?
We do something similar with the wxWidgets module we are working on (very slowly atm).
We basically wrap the external data with a Nim object and establish a finalizer for that (using new(result, myFinalizer))
To make it "reference" stuff we add fake references as "overhead" to the object. That way we can make "new" even consuming the references and free it themselves when the object gets destroyed. We could also GC_ref/GC_unref sometimes.
This allocates everything on the heap though and I am not positive if that whole concept will workout in the end. As from the experimental state it seems to work. The overhead cause by that seems to be neglect able for a GUI to me.
We use converters in that respect to automatically make the proxied object available to procs which expect the external type. For example the "ProxyObject" (Nim object) which encapsulates an "ExternalObject" (raw pointer) has something like that converter toExternalObject*(obj: ProxyObject): ExternalObject = obj.obj.
@OderWat
Yes, that is very similar to my idea concerning GTK. Indeed the benefit of GC support for GTK objects and encapsulation of GTK objects in real Nim objects is not really great, so I do not intent to write much code with big overhead for that. (For my current GTK3 wrapper, for example button_new() returns a button, but when I want to add it to a window I need the base type widget.) Some GTK wrapper, like the C++ gtkmm use very much additional code, I think that is not really justified for the few people who may be interested in GTK for Nim. For Go lang some people created a wrapper with GC support, https://blog.conformal.com/gotk3-gtk3-the-go-way/, but my impression is that not many people are using that one. Indeed, GTK works not bad without GC support, due to it reference counting. When coding in C we generally do not care much about memory allocation -- create a widget, add it to a parent window, and when the window is destroyed all memory is freed. But of course it is interesting to investigate how one can add GC support for external C libraries. I have not found nice examples yet -- someone announced to write a high level wrapper for libusb some months ago in the forum, but I think he gave up.
Generally, types need to be either equal, implicitly convertible to one another, or one the subtype of another to be assignment-compatible (the manual seem to be less than clear on that, but that's what I recall from digging into the compiler code).
The issue with allowing convertible and subtype relations to be mixed is that it means that type-checking suffers from combinatorial explosion (this is part of the reason why the Scala compiler can be so slow when lots of implicit conversions are enabled).