Avoiding name collisions with function and constructor parameters

A pattern I’ve seen used in some of the tutorials is to append ‘0’ to the parameters’ names to avoid conflicting with member variables’ names. For example, in the constructors I declared here, I had to mangle the parameter names to allow assignment to the member variable. I’d rather use the names I intend, keeping my external interface clean, possibly adding something like self. or this. to the member variable to distinguish when necessary, as is done in other languages.

Can I never have a constructor or function parameter with the same name as a member variable? There must be some way to solve this with scoping to help keep my code clean and readable. I’m not a fan of the “just append 0 when there would be a collision with a member variable” pattern.

But the issue here extends further than just member variable collisions. In the tutorial code linked above, there shouldn’t even be the need to mangle the parameter names in that case:

actor Contact {
  type Entry = {
    name: Text;
    ...
  };

  public func insert(name0: Text ...): async () {
    let newEntry : Entry = {
      name = name0;
      ...
    };
  };
}

name isn’t even a member variable of the Contact class that the insert function lives in. It’s a variable of a random type that could be defined anywhere. I would expect the compiler to be smart enough to be able to figure this out:

public func insert(name: Text) {
    let newEntry : Entry = {
        name = name;
    };
};

But instead I get a somewhat nonsensical error unless I change the name to avoid the collision: type error, cannot infer type of forward variable name

What say you, Motoko fans? How can I keep my code, especially the external interface, clean and readable while avoiding this type of name collision?

Are you using the latest dfx? I believe your last example works in dfx 0.6.16 or 0.6.17

1 Like