Nim being statically strongly typed, what is the justification for the auto type?
I have seen such a type in object-oriented languages like Eiffel with co-variant return type, but I can't find a justification for its use in Nim.
It is used only once in the compiler, in vmconv.nim:8: proc fromLit*(a: PNode, T: typedesc): auto and also once in the system library system.nim:821: proc new*(t: typedesc): auto, but I think that both procs could have been declared like proc new*[T](t: typedesc[T]): T.
A justification I could imagine is to shorten declarations. When types in a declaration are obviously non-ambiguous and the programmer delegates to the compiler to assign the correct types, because he does want to type shorter code. For instance, instead of writing
proc concat(x, y: seq[MyType]): seq[MyType] = x & y
a lasy coder would write
proc concat(x, y: seq[auto]): auto = x & y
to save a few keystrokes.
But I've encountered a piece of code where the compiler force me to use the auto type when I think I could not to.
type
Arb[N] = pointer
Bro[N: static int] = Arb[N]
proc getPointer[N: static int](s: string): Bro[N] =
unsafeAddr s
template foo(s: string; size: static uint): Arb[size] =
getPointer[size](s)
let a = foo("In foo", 10)
template bar(s: string; size: static uint): auto =
getPointer[size](s)
let b = bar("In bar", 10)
In that sample, if you replace the type declaration Arb[N] = pointer by Arb[N: static int] = pointer, foo does not compile with the error message cannot evaluate at compile time: size while bar still does. Is there a rational explanation for such behaviour? Does it justify having auto type?The auto keyword is used a few times in the rtree module, see
grep auto RTree/src/rtree.nim
proc center(r: Box): auto = #BoxCenter[r.len, type(r[0].a)] =
proc distance(c1, c2: BoxCenter): auto = # squared!
proc overlap(r1, r2: Box): auto =
proc area(r: Box): auto = #type(r[0].a) =
proc margin(r: Box): auto = #type(r[0].a) =
proc enlargement(r1, r2: Box): auto =
proc bestBinarySplit[M, D: Dim; RT, LT](d: array[TgsX * D, seq[LTGS[D, RT, LT]]]; m: int): auto =
proc rseq_nearest[D, RT](rs: RSeq; n: BoxCenter[D, RT]): auto =
I was not able to get it to compile without that time. But maybe the compiler has made some progress now, do you have suggestions for removing it?
Note: I tried removing some and quickly gave up.
Then all our serialization libraries at Status have a tremendous amount of bugs
I don't understand how this follows. So you heavily use auto, ok, no worries. My claim is that auto can "almost" always be avoided.