Hacker News new | ask | show | jobs
by Araq 4188 days ago
You cannot do these things easily currently since the assignment operator cannot be overloaded. There are ways around it, you can "fix" the broken builtin assignment with a TR macro, but since TR macros MUST not change semantics (you can disable them on a global level and code shall continue to work!) this is a bad idea.
1 comments

How about doing something like:

    type refCounted[T] =
      val: T
      refs: int

    proc `v=`(var x:refCounted[T], var y:refCounted[T]) =
      inc(y.refs)
      dec(x.refs)
      if x.refs <= 0: destroy(x.val)
      x.val = y.val

    # use let so x and y cannot be assigned    
    let x, y = refCounted[string]

    # instead use x.v to assign and manage refs properly.
    x.v = y
    
using "let" would make sure all assignments happen through a blessed method (such as the ".v" assignment I defined above).

But to actually make it work, I would need to decrease reference on going-out-of-scope (as there a way to do that? maybe a python "with" style enter exit macro?).

And to make it easy to work with, there would need to be a way to pre- "incref" an argument before it is passed as an argument, and "decref" it after the function call return. I can probably write a macro that rewrites every function call with a refCounted arg so that it increfs() on the way in, decrefs() on the way out; or maybe have that macro on the callees instead.

Guess I'll have to try the different approaches and see what works and how efficiently.

I think that should be

    type refCounted[T] = object
      val: T
      refs: int
You could try a destructor for the object: http://nim-lang.org/manual.html#destructors