The biggest thing I still don’t like about Nim is its imports:
import std/errorcodes
proc p(x: int) {.raises.} =
if x < 0:
raise ErrorCode.RangeError
use x
I can’t stand that there’s no direct connection between the thing you import and the names that wind up in your namespace.It needs to be this way so that UFCS works properly. Imagine if instead of "a,b".split(','), you had to write "a,b".(strutils.split)(',').
Nim imports are great. I would hate to qualify everything. It feels so bureaucratic when going back to other languages. They never cause me issues and largely transparent. Best feature.
You are free to import nil and type the fully qualified name.
There is a direct connection, you just don't have to bother with typing it. Same as type inference, the types are still there, you just don't have to specify them. If you have a collision in name and declaration then the compiler requires you to specify which version you wanted. And with language inspection tools (like LSP or other editor integration) you can easily figure out where something comes from if you need to. Most of the time though I find it fairly obvious when programming in Nim where something comes from, in your example it's trivial to see that the error code comes from the errorcodes module.
Oh, and as someone else pointed out you can also just `from std/errorcodes import nil` and then you _have_ to specify where things come from.