For example in front of this:
@static if v"0.2" <= VERSION < v"0.3-"
# do something specific to 0.2 release series
end
Is the @static necessary?
For example in front of this:
@static if v"0.2" <= VERSION < v"0.3-"
# do something specific to 0.2 release series
end
Is the @static necessary?
In addition to @DVNold's answer, here's a bit more explanation...
First, the difference between the two:
if in global scope the condition and whatever branch is selected are both evaluated when that code is run;@static if evaluates the condition when the code is parsed (during macro expansion) and is replaced with the code for whichever branch the condition selects — no if is left after macro expansion.In top-level global scope, there's not much difference between these two since evaluation happens only once, right after the code is parsed, macro expanded and lowered. There are, however, some situations where you can't syntactically put an if expression. A good example is if you want the presence or absence of a field in a structure to be conditional on something:
have_baz_field = rand(Bool)
struct Foo
bar::Int
@static if have_baz_field
baz::Int
end
end
Here are two different evaluations of this code:
julia> have_baz_field = rand(Bool)
false
julia> struct Foo
bar::Int
@static if have_baz_field
baz::Int
end
end
julia> fieldnames(Foo)
(:bar,)
julia> have_baz_field = rand(Bool)
true
julia> struct Foo
bar::Int
@static if have_baz_field
baz::Int
end
end
julia> fieldnames(Foo)
(:bar, :baz)
Of course, randomly having a field or not isn't very useful; in practice, you'd want to have a more meaningful condition for whether to have the field or not, probably something based on the platform you're on when trying to match the layout of a C struct.
In local scope, there's more difference between if and @static if since the code can be evaluated many times whereas it is parsed only once. Since the condition is evaluated at parse time in the global scope where the expression appears, the @static if form cannot access any local variables since they don't exist when the macro is being expanded. On the other hand, if the condition of a non-static if is based only on global constants, there's a strong chance that the compiler can predict the value of the condition, so there still may not be any effective difference since the compiler will eliminate all code but the taken branch anyway. However, if you want to make sure that this happens at parse / compile time, then you can use @static if to force it.
Hopefully that clarifies the difference. In short, you rarely need @static if because it's usually equivalent in top-level scope and even in local scope, in situations where you can use @static if the compiler will probably already do the equivalent anyway. There are a few situations where @static if is required in a global scope because a branch is not syntactically allowed. In local scope, it usually isn't necessary, but may be desirable to be really sure that the condition is not evaluated at run time. In most code, you don't need @static if. In the example given in the question, for example, I would personally just use if and omit the @static since the expression appears at the top level and the condition is only evaluated once either way.
Yes, in some contexts if statements are not allowed, but macros are, or you can't, for example, define a struct in an if statement. Inside functions it might often not be necessary, but sometimes you want to be absolutely sure that the if statement gets eliminated.