Solidity provides useful builtin function modifiers view
and pure
which provide configurable compiler checking against modifying and reading contract state. This compiler checking is a boon for security practices. For example, the checks-effects-interactions pattern benefits from compiler assurance that checks do not modify state.
Why not make similar compiler guarantees available in-line at the statement and block level?
contract InlineDemo {
uint someState;
function foo() public view returns (uint) {
return someState;
}
function bar() public pure returns (uint) {
return 0x123;
}
function fizz() public view {
require(someState == 5, 'not pure');
view foo(); // error: the function is already
// declared view
}
function buzz() public {
someState = 9;
}
function bang() public returns (uint) {
return someState;
}
function someFn() public {
pure uint a = bar(); // passes
view uint b = bar(); // passes - pure is stronger than view
view uint c = bang(); // warning: bang does not modify state,
// but it not *marked* view
pure uint d = someState; // error: reads state
uint e = someState; // OK, someFn is not pure
someState = c * e; // OK, but I should stop before stack too deep...
// Similar for blocks:
view { // error - state is modified in the block
someState = x;
}
}
}
This change could reduce cognitive load for readers (auditors) of contract code, which in turn improves accuracy of the reader’s mental model of the code. Instead of context-switches between the function-under-examination and the signatures of called subroutines (potentially in several different files), the reader can have immediate certainty that this or that entire block of code applies no effects, interactions, etc.
(ps - apologies for the earlier deleted post. Muscle memory for new-line tricked me into posting work-in-progress)