| > So why can't Nim infer from `let b: uint = a` It "can", but it's a design decision not to by default because mixing `uint` and `int` is usually a bad idea. This is telling the compiler you want to add an `int` that represents (say) 63 bits of data with a +/- sign bit to a `uint` that doesn't have a sign bit. If `a = -1` then `b = uint(a)` leaves `b == 18446744073709551615`. Is that expected? Is it a bad idea? Yes. So, the explicit casting is "getting in your way" deliberately so you don't make these mistakes. If `a` is a `uint`, it can't be set to `-1`, and adding them is freely allowed. Incidentally `uint` shouldn't be used for other reasons too, for instance unsigned integers wrap around on overflow, whereas integers raise overflow errors. The freedom of mixing types like this are why languages like C have so many footguns. In short, explicit is better than implicit when data semantics are different. When the semantics are the same, like with two `int` values, there's no need to do this extra step. You could create a converter to automatically convert between these types, but you should know what you're doing; the compiler is trying to save you from surprises. For `int`/`float`, there is the lenientops module: https://nim-lang.org/docs/lenientops.html. This has to be deliberately imported so you're making a conscious choice to allow mixing these types. > don't you get tired of typing (and reading) `uint` twice in the latter setting? Well, no because I wouldn't be writing this code. This example is purely to show how the typing system lets you write pythonesque code with inferred typing for sensible things, and ensures you're explicit for less sensible things. For just `int`, there's no need to coerce types: var
a = 1
b = a + 2
intro = "My name is "
name = "Foo"
greeting = ""
b *= 10
# Error: type mismatch: can't concatenate a string with the `b` int.
# greeting = intro & name & " and I am " & b & " years old"
# The `$` operator converts the `b` int to a string.
greeting = intro & name & " and I am " & $b & " years old"
# If we wanted, we could allow this with a proc:
proc `&`(s: string, b: int): string = s & $b
# Now this works.
greeting = intro & name & " and I am " & b & " years old"
echo greeting # "My name is Foo and I am 30 years old"
# Normally, however, we'd probably be using the built in strformat.
# Incidentally, this is similar to the printf macro mentioned in the article.
import strformat
echo &"My name is {name} and I am {b} years old"
|
That said, Python's behavior (though correct to spec) is arguably worse:
With no complaints from mypy.