The stuff in base/osutils.jl that implements
@osx? 1 : 2
strikes me as a bit too cute. It took me a minute screwing around with the syntax to figure out what was even going on with this macro. Cute as the resulting usage may be, this strikes me as an abuse of syntax. If we do keep it, the documentation needs to be improved to include how you actually call these things and ideally, it would tell you the same information when you inevitably use it incorrectly.
Also, why does the implementation do syntax structure checking at run-time? That should be done during macro expansion.
cc: @vtjnash, @loladiro, @johnmyleswhite (people who touched this file).
It is using a macro to write the bodies of the macros. _os_test could be a function instead.
Ah, I see. Yes, that's a bit confusing.
The thing I really don't like about this "fake ternary" syntax punning is how brittle it is:
julia> @osx? 1 : 2
1
julia> @osx? 1:2
1
julia> @osx? 1 :2
ERROR: wrong number of arguments
julia> @osx? 1: 2
1
julia> @osx?1:2
1
julia> @osx? 1:2
1
julia> @osx?1 :2
ERROR: wrong number of arguments
julia> @osx?1: 2
1
julia> @osx?1 : 2
1
julia> @osx?
ERROR: wrong number of arguments
julia> @osx ? 1 : 2
1
julia> @osx ?1:2
1
julia> @osx ?
ERROR: wrong number of arguments
julia> @osx ? 1 :
ERROR: wrong number of arguments
julia> @osx ? 1
ERROR: assertion failed: :(isa(ex,Expr))
Most of these syntax variations work for actual ternary operator expressions but half of them fail here because this isn't really a ternary operator even though it's supposed to look like one.
A couple of alternative options:
@system osx ? 1 : 2.@osx ? 1 : 2 => true ? 1 : 2; just rely on compiler to specialize on the boolean literal to avoid overhead.@osx 1 2 and @osx 1 is equivalent to @osx_only 1, which we can deprecate.I lean towards the last option myself, since it's the simplest and reduces the number of things in base.
+1 for combining them into one set of macros
Other than a better error message for that last expression (or allow it), I don't see how the rest are valid -- they look to me like incomplete expressions.
No kidding they're incomplete. The point is that the REPL doesn't let me finish the input because it has no idea what it's parsing.
In other words, this "syntax" is absurdly sensitive to whitespace 鈥撀爄n particular line breaks confuse the hell out of it.
Perhaps
@os windows ? 1 : 2
And
@os windows 3
Parentheses and begin/end are always helpful for the compiler -- and reviewer -- when you want to split over a newline.
You're missing the point that this _looks_ like a ternary operator聽so the user expects it to behave like one syntactically 鈥撀燽ut it isn't one at all and doesn't behave like one syntactically at all and instead breaks in all sorts of ways that ternary operators don't. If you just stop trying to make it look cute and make it what it is 鈥撀爄ndividual expressions passed to a macro 鈥撀爐hen all the confusion goes away. Yes, it looks slightly less pretty, but it's much more usable.
@os windows ? 1 : 2 does parse the macro argument like a normal ternary operator.
Yes, that's why I proposed it since it actually _has_ the syntax it looks like it has. And that does reduce all of these things to a single macro which is rather nice.
A few more issues with this, for the record.
? is mandatory. In v0.3
julia> @osx? print("A"):print("B")
A
In v0.4
julia> @osx?print("!"):print("B")
ERROR: wrong number of arguments
julia> @osx? print("A"):print("B")
A
julia> function f()
println(1)
println(2)
@osx?print("Y"):print("N")
end
ERROR: wrong number of arguments
OT: the parser is fine with this expression, the error happens later when starting to evaluate it.
I said this in a different issue but can't find it right now, this fake ternary would be better replaced by a conditional macro @if or @cond for the cases where this os-dependent code selection has to happen at parse time.
+1 to @if
@vtjnash also suggests the possibility of a @static modifier, so we could do @static if - or something similar to force parse-time evaluation of a pure condition
Most helpful comment
@vtjnash also suggests the possibility of a
@staticmodifier, so we could do@static if- or something similar to force parse-time evaluation of a pure condition