There was a discussion about this pattern in Julia on the mailing list recently:
...
flag = true
...
flag && (x = rand(2,2))
...
I very much see the need for something short and sweet in these cases (rather than a long if ... etc), but this particular syntax strikes me as pretty opaque to new users. I've also seen things like
...
flag = true
...
flag && error("Error")
...
Which again is super useful for e.g. argument error checking, but somehow to me looks like a misuse of &&.
Couldn't ? without a : work in these cases? I.e. the following syntax:
...
flag = true
...
flag ? x = rand(2,2)
...
and
flag = true
...
flag ? error("error")
...
Essentially ? would just be a shorthand notation for an if.
Great!
What would
Y = flag ? x = 1 : 4
Mean?
Same thing it means today? Sorry, I guess I'm not getting your point :)
Some might think you are assigning a range.
flag ? x = (1:4)
Good point. On the other hand, is it really much worse than what is currently happening? At least I had to try out what
flag ? 1:2:3
actually does. It just seems that one needs to know the rule for how ranges and ?: interact in any case, right?
Another option could be to use ?? for this. In any case, the flat && something notation seems like a hack to me with a potential for a cleaner syntax.
I could see keywords and = &&
and or = ||
being useful in this situation (although I've gotten used to and now love how concise using &&
and ||
is).
I don't know that I really understand the motivation. Do you not like the way &&
looks? Or do you not find it very readable? Short-circuit evaluation is pretty standard across many languages, although not many use it idiomatically for control flow. Are there any languages that allow you to omit the colon of a ternary conditional operator? There's a GNU C extension that lets you omit the true branch expression… but that's different.
If you're after a more readable alternative, I'd go for more verbose and standard instead of less. One suggestion a while ago was to introduce the then
keyword for this, e.g., if flag then x = rand(2,2)
. I really like the way that reads, personally, but an if without an end would make editor code folding support a bit tougher.
The disadvantage here would be that it requires one more language keyword. I don't think it'd be too terrible to deprecate, but it's not a decision to be taken lightly. The same would be true for and
and or
.
I think short-circuit evaluation is one of those things that is super natural to programmers but to most non-programmers it really looks weird to do control flow via that trick. I think code could be more easily understood if there was some way to do one-line if...then... semantic with a more obvious syntax than short-circuit evaluation. The if flag then
thing would also work. If that debate is still ongoing maybe this issue should be folded in (I just tried to search for it but the search terms "if then" is not ideal ;)
It was a julia-users discussion thread. Also related is the and
/or
issue: #5238.
Would a || b ? return c
do something different from a || b && return c
? I found myself writing the latter today, which behaved differently than I meant it to; if a
is true, the return condition is never evaluated.
That's a good point; ?
has lower precedence than &&
and ||
, which makes it better for "guarding" a return or assignment.
I actually like the idea of allowing ?
without :
. Currently it is a syntax error, so it should be simple to support without breaking much.
I'm kind of shocked that you like this. It is currently fine to put the colon on the next line in a ternary operator expression. While I think that's uncommon, it will potentially break code. I guess we can do that though.
I don't believe that is true:
> (julia-parse "true ? b
: c")
error: colon expected in "?" expression
#0 (error ("colon expected in \"?\" expression"))
Well, what do you know. I guess I never tried that. Then this syntax is actually available. If we're going to start doing things with ?
can I lobby for also letting d[k] ?= ex
mean what get!(()->ex, d, k)
currently means, but without actually having to create the thunk?
I just stumbled upon the "colon on next line" thing and wanted to report it as a bug, because I'm used to be able to format the ternary that way in C/C++ and wanted to do it in Julia too:
α(t) = t < 1000 ? 0.5 - 0.46/1000* t
: t < 10000 ? 0.04 - 0.04/9000*(t-1000)
: 0
My current alternative looks slightly worse to me:
α(t) = t < 1000 ? 0.5 - 0.46/1000* t :
t < 10000 ? 0.04 - 0.04/9000*(t-1000) :
0
Mind you, this is a very minor complaint.
I would also expect it to be possible to have the :
on the next line and would be quite surprised for a ? b
by itself to mean if a; b; end
. If we're going to do that, then there have been several other less unusual suggestions put out there already, including b if a
and if a then b
on a single line.
I would also be in favor of if a then b
as the go to one-liner for conditionals. It's simple, clear, very readable and doesn't confuse anything else we're already using.
+1 for if a then b
Is there some new issue that tracks suggestions like if a then b
, or some other alternative? I didn't get the impression that there was overwhelming dislike for some solution to this in the discussion here, so not clear to me why this issue is being closed.
If we drop the leading 'if
, we would be able to do:
a then b
a else b
... both of which I think people will find perfectly clear / readable / obvious without explanation.
Thread here: https://discourse.julialang.org/t/proposal-then-else-syntax-to-replace-short-circuiting
I don't think that else
syntax is workable, since the following currently parses:
if 1 < 0
2 else 3
end
or more generally when writing conditional expressions on a single line, if 1 < 0 2 else 3 end
.
@p-i-: that's basically already how I read &&
and ||
in my head. To me the only real issue with &&
and ||
is precedence issues with assignment (i.e. x = y && z
vs x && y = z
).
Looking at the precedence table, I'm starting to think the Perl solution of having two different pairs of short-circuit operators for this is actually not so bad: &&
and ||
have higher precedence than arrows, conditionals or assignment (as they currently do) while and
and or
have lower precedence than assignment. However, we have the added complication of xor
, &
and |
(as well as .&
and .|
) so there's a lot of things to sort out. Basically, I think what we have now is not so bad.
Perhaps consider borrowing Ruby's post-fix conditionals? b if a
and b unless a
? I know opinions on this particular feature vary, but I've always found them extremely useful.
EDIT: Just to add...
&&
and||
have higher precedence than arrows, conditionals or assignment (as they currently do) whileand
andor
have lower precedence than assignment
Ruby shares these extra operators with Perl, and anecdotally they lead to far more confusion than benefit. Beginning developers will see these in Ruby and assume && === and
, which works...until it doesn't. Very little Ruby code uses and
and or
in practice (likely due to the post-fix conditionals being available and much more intention revealing).
Sorry to revisit this, but I was thinking about how some of this stuff is parsed.
In some contexts at least, I can make the Julia code
;
which returns nothing
. Given that lack of code is basically nothing
, I'm wondering if it would be natural that I could write some code like:
cond ? a : ;
cond ? : b
(Perhaps we could have shorter forms like cond ? a;
and cond ?: b
... these aren't really a very readable alternative to #16389 but do seem to extend the ternary to binary forms in a _somewhat_ consistent way)
Current behavior (v0.6 and v0.7):
julia> true ? 1 : ;
ERROR: syntax: unexpected ";"
julia> true ? : 1
ERROR: syntax: space not allowed after ":" used for quoting
Most helpful comment
I would also be in favor of
if a then b
as the go to one-liner for conditionals. It's simple, clear, very readable and doesn't confuse anything else we're already using.