Blank Operator - send results to nil

Hi everyone,

This is a pedantic question, but i think improves readability of code. Solidity don’t have a blank operator, resulting in function calls with multi returns in something like:

(, , , , uint256 returnValue) = function();

Proposed change

Use the same blank operator as other languages (like Go)

( _, _, _, _, uint256 returnValue) = function();

I don’t think the _ operator is used in the current solidity implementation.

What do you think about this style?

(/* value1 */, /* value2 */, /* value3 */, /* value4 */, uint256 returnValue) = function();

I personally never use the _ variable even in languages that offer it because it hides the name of the things that get returned (I prefer to know what I’m ignoring).

I don’t think the _ operator is used in the current solidity implementation.

It is. It’s used to represent the place in a modifier where function body will be inserted. This change would make them a bit more tricky (and less readable IMO):

contract C {
    modifier m {
        _ = foo();
        (_, _) = bar();
        _;
    }
}
1 Like

Is I forgot about the modifiers…

I focus on the underscore just because Golang. Could be another character.

contract C {
    modifier m {
        _ = foo(); // only use the blank operator in attribution. This case should be syntactical corrected but should not be used.
        (_, _) = bar();  // the same
        _;
    }
}

please take a look:

playground

Yeah, something else might work. What would you propose?

By the way, one language where I wished I had this is C++. Currently destructuring expressions like for (auto const& [a, b]: someMap) don’t let you skip any of the components. Fortunately ranges-v3 solves this problem for map by introducing keys and values views, and the library is going to be a part of the stdlib in C++20.

I think that the main benefit of _ in other languages is that it’s the only way to skip a particular component of a tuple. In Solidity you can do that already so adding _ would just be a cosmetic change. But anyway, I’d be very interested to hear how others feel about this. Getting some real feedback is always good.

I like the idea of using the _ is very intuitive. But the question of modifiers is very pertinent.

Personal opinion I don’t like the idea of decorator of functions “as is” of today. When reading code we end up always going up and down. I can be wrong but is more about a question of sugar that in the end is not particular useful in the context of writing smart contracts (small, concise and understandable). Using _ in modifier to simbolize the execution of the function is something is strange.

@cameel what do you think about this:

modifier: to signal the continuation of execution use the keyword : continue/break; (like loops).
reassign the _ to nil as discussed previous.

Cheers

I’m not sure I understand how it would work. You mean that

modifier m {
    continue;
}

would be equivalent to what is now this

modifier m {
    _;
}

?

What would this code mean then?

modifier m {
    for (uint i; i < 10; ++i) {
        continue;
    }
}

The more I have to use multiple returns values, the more I think we really need to create a more pleasant way to read it.

Agree on that syntax. It’s way more better than empty lists of commas. To prevent syntax from conflicting with modifier’s placeholder, I’d suggest to update placeholder syntax. I think modifier’s syntax should be more specific and close to code block, e.g:

contract Contract {
  modifier mod() {
    {...} /* or */ {***}
  }
}

For me such syntax looks more logical.

1 Like