Allow for named parameters in constructor

Functions allow for named parameter. Is there any particular reason this wasn’t implemented for constructors?

function foo(uint256 bar, string memory baz) public {

}

function main() public {
  foo({baz: "wow", bar: 1 ether});
}

This is particularly useful when inheriting several contracts into a parent contract. Allows for more explicit constructor initializing.

for example:

abstract contract A {
  constructor(string memory _name, uint256 _age) {}
}

contract B is A {
  constructor()
    A({_age: 100, _name: "solidity"})
  {}
}
1 Like

It’s not specifically about the constructor, but more generally, about anything which comes before the function body. For example, the usage of a modifier:

contract C {
    modifier modi(uint x) {
        require(x > 0);
        _;
    }

    function func() public modi({x: 1}) {
    }
}

In order to prove that this is not about the constructor, consider the case of instantiating (deploying) a new contract onchain, which compiles successfully:

contract D {
    constructor(string memory _name, uint256 _age) {}
}

contract E  {
    D d;
    constructor() {
        d = new D({_age: 100, _name: "solidity"});
    }
}

Thank you for response. I’m still unclear from your examples if there is a reason this is not possible. I understand it is not current behavior.

My guess would be that they simply did not take it into account, or possibly that it is a little more technically complicated to support.

It’s ultimately nothing more than sugar-syntax, i.e., not something which poses any user limitation…

1 Like

It looks like an unintentional omission to me. I can’t think of any technical limitation preventing this. We also don’t seem to have any syntax tests covering this case and the grammar for modifier invocation does in fact include that possibility (but note that this grammar is intentionally pretty loose and only an approximation of our parser).

Looking into the code, it does not even seem to be hard to change. Might be a simple as replacing the call to parseFunctionCallListArguments() inside parseModifierInvocation() with a call to the more general parseFunctionCallArguments(), which does allow named arguments.

EDIT: Actually a bunch more changes, e.g. the ModifierInvocation AST node would have to be adjusted to store the argument names like FunctionCall node currently does. And then the AST we export for that node would have to change too, which would make it a breaking change. Then the codegen would have to take care to pull the arguments in the right order from the AST. Still looks quite doable though.

3 Likes

Your 1st paragraph implies that my 1st speculation was correct.
Your 3rd paragraph implies that my 2nd speculation was correct.

:slight_smile:

Thanks for confirming.