As regards implicit dereferencing, the compiler, when looking for the field "a" has to detect that "p" is a reference or a pointer, check if the referenced type is an object or a tuple and that it contains a field "a" and if this is OK generate the code for dereferencing. I don’t see that as stylistic. Other languages will detect an error as "p" has not the right type.
As regards the varargs, that Python has more information at runtime than Nim, I agree. But, the expansion has to be done at compile time, not at runtime and Python lacks information about the expected argument type. When you write `def f(x):`, you don’t give the compiler a clue about the type of the elements of "x" which may be a list, an int, an dict and so on. So, if I call it with a list (without the "*"), the compiler cannot do the expansion as it doesn’t know what is expected (and to complicate things, contrary to Nim, the varargs need not to be of the same type). And your example with `printStuff(@[lines]` is wrong. If you want to pass a list of strings as a whole to a varargs, you have to declare the procedure to accept a sequence of strings, not a string. "printStuff" has been declared to accept a `varargs[string]` not a `varargs[seq[string]]`, so, when writing `printStuff(lines)` there is no way you can get a unique argument "lines" as it has not the expected type "string". But this works: proc printStuff(x: varargs[seq[string]]) = for element in x: echo element let lines = @["abc", "def"] printStuff(lines) Run Comparing Nim and Python is frequently a bad idea as the languages are fundamentally different. Python has done things a way which is logical for a dynamically typed language. And Nim does the things another way which is consistent with its nature.