function test(x,y)
if x>y
return x
else
error("err")
end
end
(Note that throw(error("...")) doesn’t really work, because throw and error do the same thing, except that throw takes a specific instance of an Exception, whereas error just takes some string. There will be no difference whether you leave the outer throw() away or not, because the inner error will already have thrown an exception.)
or if it should be shorter (but arguably less readable)
function test(x,y)
return x>y ? x : error("err")
end
(Note that x > y ? return x : error("err") doesn’t work again because of the parsing – It would work as x > y ? (return x) : error("err") though.)
I personally like to use short-circuiting for this kind of check. Stylistically, it feels more like an aside (“just to be sure…”), rather than part of the program logic.
In this case
function test(x,y)
x > y || error("err")
return x
end
Or (again just personal preference) because I like testing affirmatively for the pathological case, x <= y && error("err") or !(x > y) &&...
ifelse behaves the same as myIfelse(cond, trueval, falseval) = (cond ? trueval : falseval). The main difference is that there is extra machinery to encourage the compiler to emit conditional move (e.g. CMOV) instructions. This is intended for settings where you either want to get SIMD or where you know that cond is hard to predict, i.e. where you have a pretty precise picture of the native code and uarch-state you want.
So, since ifelse is a function, the caller must evaluate the arguments before the call, and the side-effects (like returning or throwing an exception) happen before the ifelse even runs.
Your expected behavior could be achieved by
What this also tells you is that there is no difference between c ? a : b and if c a else b end: Both are parsed into the same expression and are just as equivalent as 1000 and 1_000.