Closed axic closed 8 years ago
What about
/// @requires-solidity >= 0.1.7
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?
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.
A non-present compiler version for a source file could trigger an error starting from some specific version.
/// @requires-solidity >= 0.1.7
This is basically a natspec comment used for deducing compiler warnings/errors?
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).
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.
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:
require {this, that} >= 10.0.1
not look unique with @ or function-call-like parentheses@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.
@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.?
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.
@chriseth which part of this is not implemented yet?
Starting from version 0.4.0, source files have to specify which compiler version they are targeting, to prevent breaking changes from going unnoticed:
The string can be any npm-style semver version match expression (including the
||
operator).