ethereum / solidity

Solidity, the Smart Contract Programming Language
https://soliditylang.org
GNU General Public License v3.0
23.3k stars 5.77k forks source link

Feature request: decorators for requiring a specific (minimum or maximum) version of Solidity #226

Closed axic closed 8 years ago

axic commented 8 years ago

Starting from version 0.4.0, source files have to specify which compiler version they are targeting, to prevent breaking changes from going unnoticed:

pragma solidity "^0.4.0";

The string can be any npm-style semver version match expression (including the || operator).

chriseth commented 8 years ago

What about

/// @requires-solidity >= 0.1.7
axic commented 8 years ago

As a short term solution I am happy with that.

Thinking long term: if macros become available, would there be macros there to conditionally enable code? If yes, how would be the version value available to them and would that make the above obsolete? Or having it as part of macros and as the above way wouldn't be considered a duplicate?

chriseth commented 8 years ago

We should use this together with breaking changes. I think the most common use-case would not be requires version >= 0.1.6 but rather requires version <= 0.1.6. If the source code uses a feature that is not present yet, it will not compile.

chriseth commented 8 years ago

A non-present compiler version for a source file could trigger an error starting from some specific version.

axic commented 8 years ago

/// @requires-solidity >= 0.1.7

This is basically a natspec comment used for deducing compiler warnings/errors?

chriseth commented 8 years ago

It is a special comment that creates a compiler error if the compiler version does not satisfy the condition. We can also make it a proper syntactic element (i.e. not a comment).

Smithgift commented 8 years ago

If this is a one-off thing, then I'd be OK with a comment. But if we're going to have macros in the future, I think this should be part of that system.

In, re: macros, it can be the scary road to doom (and unreadable code), but there's some use cases that could really use them. For example, compile-time constants that allow the user to chose which of a number of options (length of a channel's challenge period, for example) without having to store it in the storage, with associated costs.

blockzombie commented 8 years ago

Does @requires-solidity >= 0.1.7 mean a specific version of the language spec or of a compiler implementation?

Also, it's arguable that this pragma syntax should be harmonious with the import syntax. Why would their syntax be so different (e.g. @ prefix for a start)

The similarities include being file-scoped, modal etc. Typical pragmas hastily backported into languages include "use strict" which then often balloon out into all kinds of strict-about-this and strict-about-that variations.

Also, why limit these to compiler directives? Why not enable the same syntax to work for runtime pragma? Comment-based syntax would not be expected to impact generated code. I suggest not making a pragma syntax incompatible with the future possibility of runtime impacts. Note that these need not even be supported by all EVMs

I'm not saying any of this magic must be implemented, only that the syntax should:

chriseth commented 8 years ago

@blockzombie the current proposal (see description of this issue) is to provide semver-matching and not put it inside comments. If the language spec and compiler version start to diverge at some point, this refers to the language version.

I'm not so keen on using require for this because it is also a keyword in why3 and we might upgrade it to a proper language construct later.

So perhaps something like

pragma(solidity ^0.4.0)

would be best for now.

blockzombie commented 8 years ago

@chriseth thanks for your quick feedback.

I like the motivation and the feature and I'm a fan of semver. I also respect avoiding overloading require and pragma is a wonderfully exact replacement.

My burning question is why reuse parentheses such that it resembles a function call when you have syntax that causes modal, file-scoped changes to the meaning of the following code which use a syntax that has keyword with braces etc? (namely the syntax for import)

Would you consider it a design goal to make this change fit in more with the import syntax? I guess this would imply something closer to

pragma solidity ^0.4.0;

or

pragma { solidity ^0.4.0 };

or were you hoping that the function-call syntax would make older versions forward compatible by importing a pragma function etc.?

chriseth commented 8 years ago

The idea behind using parentheses was indeed forward-compatibility. For example, pragma can also be used to switch some features on or off, but I think

pragma solidity ^0.4.0;

also serves this goal. So the idea is:

A pragma starts with pragma, then an identifier and then just about any set of characters up until ;. The part between the identifier and the ; will be parsed as a string.

This would require less changes to the lexer if we just used

pragma solidity "^0.4.0";

which is a bit harder to type but still a better compromise, I would say.

axic commented 8 years ago

@chriseth which part of this is not implemented yet?