Hello! I'm new to Nim but I didn't find easy answers to these questions in the docs so I'm looking for some clarification.
As I understand it, the auto type is basically an alias for creating generic procs, and
proc foo(a:auto,b:auto)
is equivalent to
proc foo(a,b:auto)
(aka every auto parameter gets its own T and there's no way to specify that a and b are the same T without writing out a generic proc).
Would it be syntactically ambiguous to allow "implicit" autos? E.g.,
proc foo(a,b:)
would be syntactic sugar for
proc foo(a,b:auto)
and
proc foo(a:,b:int)
would be sugar for
proc foo(a:auto,b:int)
(I'd have the same question about return types, in that case.)
It also wasn't clear to me whether generic/auto parameters can reference properties that aren't present for every T, or whether they could be passed as parameters to procs expecting a more specific type than T. The docs say that auto parameters do not yet "infer the parameters' types from the body", so do all generic/auto parameters need to be handled in a completely generic manner? Or does the compiler not do any type validation until the generic proc is called (and thereby instantiated)?
Nim's concept type, as I understand it, is essentially a form of statically-checked duck-typing (which I've never seen before and am really impressed with, by the way), which means the compiler is capable of verifying whether a type meets some arbitrary assertions. So then would it also be capable of, for lack of a better term, "implicit concept types for generics?" I.e., if I wrote
proc foo(var a:auto) =
a.x += 1
would the compiler accept this and essentially treat a as a member of
type T = concept var a
a.x += int
? If so we must be very close to allowing syntactic parity with Python in a statically-typed language and that is very cool.Would it be syntactically ambiguous to allow "implicit" autos?
It used to be like this proc foo(a, b) But Araq removed implicit parameters, so I don't think they will return.
Or does the compiler not do any type validation until the generic proc is called (and thereby instantiated
That's the case. It depends type by type.
So then would it also be capable of, for lack of a better term, "implicit concept types for generics?"
As long as the requirements are satisfied, yes:
type T = concept var a
a.x += int
proc foo(a: var auto): bool =
a.x += 1
a is T
var a = (x: 5, y: 5)
var b = (x: 5.3, y: 5)
echo foo(a) # true
echo foo(b) # false
Thanks for the responses!
a form of statically-checked duck-typing...for lack of a better term
I guess the formal term is "structural typing"?
I believe that this does actually qualify as duck typing. The saying "if it walks like a duck and quacks like a duck, then it's a duck" refers to a form of generic or type agnostic code where a type is usable based on its functionality. Aka, the types int and float have a +=(_: int) and as such they are valid for use in the proc with auto.
Structural typing means that types are interchangeable if their definitions are equal. In Nim this happens with tuples. If tuples have the same elements (by number and type), they are synonyms and interchangeable.
The above is an example of duck typing.
Here's some structural typing:
type
Vec = tuple [x, y, z: float]
Color = tuple [r, g, b: float]
proc interpolate(vecOrColor: Vec; weight: float): Vec =
# mix color or vector values
let a = Vec(1.0, 1.0, 1.0)
interpolate(a) # works
let b = Color(r: 1.0, g: 2.0, b: 3.0)
interpolate(b) # also works
(Hopefully I have the correct syntax there, I'm not somewhere with the compiler) :)