As I understand the let keyword introduces an immutable variable, so you can't change it after initialization.
So for example
let x = @[1,2,3]
x[0] = 5
wouldn't work.
Yesterday I discovered the library neo, which can be used to create matrices and vectors. But there are some weird behaviors with the let keyword.
let
mm = ones(2, 2)
var
mb = mm[0..<2, 0..<2] # shares memory
mb[1,1] = 0.8
mm is created as immutable matrix which contains only ones. So it shouldn't be possible to change values in this matrix. When I'm trying to change a value of mm for example with mm[0,0] = 2 it doesn't work, which is expected.
But then 2 questions. First, the mb variable creates a slice of the matrix and is declared as var. A slice in this library creates a reference to the underlying array. Tho I'm able to change values of the original immutable matrix. Shouldn't it be impossible to change a value of an immutable variable, even if I create an immutable reference to it?
Then second question. The library contains two methods to get a row or a column of the matrix:
let
mr = mm.row(0) # shares memory
mc = mm.column(0) # shares memory
mr[0] = 2
mc[1] = 3
The variables mr and mc are immutable and they share the memory of an immutable matrix. And I'm still able to change their values.
After executing this code and printing mm it results into [[2, 1, 3, 0.8]].
Can someone explain this behavior to me?
If a ref/ptr is declared with let, then the pointer/reference is itself immutable (meaning it cannot point to somewhere else), however the variable it points to is still mutable, as the variable pointed to is not a part of the let variable.
let p: ptr int = nil
var a: int
p = addr(a) # Error: 'p' cannot be assigned to
Pointers are inconsistent with seq just like int (many values) is "inconsistent" with bool (only two values). An inconsistency usually goes beyond "I connected two different things in my head and they are different, ergo inconsistent". There is also var openArray (mutable, not appendable).
Also, while var implies mutable it also implies a hidden pointer which explains all of its behavior. With the correct description of things, things are much easier to understand and "consistent".
the reason is, because other parts of the object aren't stored on the heap (length and depending on the runtime also capacity iirc). Another reason is that seqs behave exactly like regular non heap objects in that they have copy instead of reference semantics.
So the internal pointer of a seq is in this context more like an implementation detail.
why do I need a var seq (hidden pointer to a variable on the stack) in order to change its items?
You don't, var openArray does what you're asking for.