I was going to talk about this on IRC but I figured out a post would be more 
appropriate. This is also my first post on this forum so _hello, 
nim-community_.  I usually don't get involved in such stuff, but since Nim is 
running towards 1.0 and I have huge expectations for it, I'm making an effort. 

I'm a bit disappointed about ptr/ref constness and I wanted to talk about it. 
As far as I understand it, constness in nim is expressed using:

  * let variables
  * "non-var" proc parameters



As long as the variable is a "value-type" (an _object_ in nim-talk) the const 
guarantees applies. The problem is that when using a ref/ptr, the constness 
applies to the ptr and not the pointed object.

* * *

In C++ speak I have the feeling that:
    
    
    Object const* ptr; //pointer is mutable, pointed object is const
    //cannot be expressed in nim AFAIK
    

is far more usefull, and in general a stronger guarantee, than: 
    
    
    Object *const ptr; //pointer is const, pointed object is mutable
    //equivalent to let ptr/ref, and "non-var" ptr/ref parameters in nim
    

* * *

Now an example of why it weakens the guarantees while using nim:

Let say I create an int wrapper like this (obviously useless, but it's an 
example), and an associated proc that prints it, without modifying it. The 
second line of this proc is an error and is catched by the compiler.
    
    
    type IntBox = object
        i:int
    
    proc log(box:IntBox)=
        echo $box.i
        box.i = 2  # DOES NOT compile: box is not var, i'm not allowed to 
modify it.
        # Proc signature says it wont modify box: strong guarantee enforced at 
compile time.
    

I go further into development and discover that my IntBox instances should be 
shared between multiple locations. I need to allocate them on the heap, and 
thus make the following change in type declaration.

_Note that the semantic of my proc is unchanged: it shouldn't modify the box 
it's applied to._
    
    
    type IntBox = ref object
        i:int
    
    proc log(box:IntBox)=
        echo $box.i
        box.i = 2   # now it DOES compile, and proc is allowed to modify box!
        # Strong guarantee is gone :(
    

* * *

I'm not sure why things are that way and there's probably a good reason for it. 
I bet on consistency, as ptr/ref are values themselves, and it seems logical 
that constness applies to the same level than for other values.

But still, nim's design is about practicality more than consistency (am I 
wrong?), and here I think we loose a huge practical guarantee.

I'm not sure about the solution, but could we imagine that a ptr/ref constness 
expands to its pointed value? I'm still a newcomer in nim and might be 
mistaken, but I wanted to talk about it. 

Reply via email to