Which of the following two options do you prefer for a one-line if-then syntax?
bool && expr
if bool then expr
0 voters
Related Github issue:
Which of the following two options do you prefer for a one-line if-then syntax?
bool && expr
if bool then expr
0 voters
Related Github issue:
Typo FYI: if bool then expr end
(you missed end
)
Oh I guess you didnāt mean that, and I totally missed the then
. IMO it would be too weird to allow if
without end
, though an optional then
could be nice
To remove the need for end
how about Perlās
expr unless bool
or Pythonās
expr if bool
Not a fan, since this seems to imply that expr
is evaluated first.
I think a āfamiliar vs unfamiliarā poll is usually going to give the āfamiliarā answer.
The problem with a && b
is that inconsistent with Juliaās normal rules: it looks like an operator expression but it isnāt: itās control-flow syntax. That b
might not be evaluated is the point of this syntax (vs just using &
). IMO special syntax should look like special syntax to avoid misleading readers.
How about scheme/racketās
(when bool expr)
or
(unless bool expr)
without the parens, of course.
ā¦
What looks like special syntax? Words? The same we use as variable names? &&
and ||
are adopted by many languages working this exact way and are far better to identify and write into text than and
and or
.
Reserved keywords are special syntax for meta-level programming (except for true
and false
, which are special cased).
This is the list of reserved keywords in Julia:
baremodule, begin, break, catch, const, continue, do, else, elseif, end, export, false, finally, for, function, global, if, import, let, local, macro, module, quote, return, struct, true, try, using, while
. Those keywords are not allowed to be used as variable names.
To be more evidently syntax, these could have been prefixed with @
such as in @for
but this may have been considered too noisy.
Exactly my point. The syntax for meta-level programming is just a list of exceptions for the open list of identifiers. I believe it is much more misleading for a novice that an word that could be a variable/function/type/etc name is actually special, and that the only way to know this is knowing the whole list of exceptions. So I do not entirely buy the point that a solution using keywords is better. Finally, in
is already an exception to complementary idea that operators are restricted to non-letter symbols.
For simplicity Iād remove the in
/isa
exceptions to the infix operator policy rather than using the existence of some exceptions to justify others.
Thereās already if a b end
and a && b
. Unless you are suggesting disallowing the latter (how?) the only possibility is to add a third version to the others, that may or may not supplant them (probably not.)
Just to chime in with an opinion.
I donāt always understand the obsession of writing āshorter codeā, when most of the work is often having to read it multiple times.
To me, if bool then expr is much clearer than bool && expr.
Code readability is often times a good reason to not improve a package by 5% speed, so I would argue the same is the case here, that increasing the length of the statement to make the code easier to re-read is preferred.
Kind regards
Yes I am in favor of removing a && b
, a || b
in Julia 2.0. Julia has if
expressions (rather than statements), which removes the need for such special cases.
The same applies to a ? b : c
.
It would be nice to have block delimiters shorter than end
, but thatās a broader issue.
if bool expr end
is seldom used, because itās even harder to read than bool && expr
. I view if bool expr end
as more of an artifact of how Julia parsing works than as an actual feature of the language.
a && b
is certainly not going anywhere, because we still need it for regular old boolean comparison. The fact that &&
short-circuits is merely a performance optimization. One of the things I donāt like about bool && expr
is that it is taking a performance optimization and turning it into semantics.
The other thing I donāt like about bool && expr
is that it is hard to read. Itās not a matter of getting used to itāIāve seen it plenty of times and I still think itās harder to read than
if bool then expr
.
Iāll note that if bool then expr
is not quite as easy to read without syntax highlighting as it would be with syntax highlighting. Maybe itās easier to read with real code, like this:
if isempty(x) then error("oops.")
Hereās an example with syntax highlighting (from a different language, Elm)
(Elm is a pure functional language, so if ... then
statements must include an else
.)
I should have specified I favor getting rid of the symbols for short-circuiting control rather than getting rid of boolean operators. Though āØ ā§
express boolean operations more clearly IMO.
As a side note, AFAIU this work-reducing optimization can sometimes reduce throughput by putting more pressure on the branch predictor. If compute units are available then both branches can be computed simultaneously without extra cost which is helpful if the branch isnāt well predicted.
I strongly dispute this claim. The introduction of ||
and &&
in The C programming language of K&R just says:
The || operator groups left-to-right. It returns 1 if either of its operands compare unequal to zero, and 0 otherwise. Unlike |, || guarantees left-to-right evaluation: the first operand is evaluated, including all side effects; if it is unequal to 0, the value of the expression is 1.
The wikipedia page on short-circuit evaluation says nothing on this. I have a hard time believing that for combining simple relational operators (<
, >
, ==
, and !=
) over primitive data, &&
and ||
(which may incur in a jump) are more lightweight than |
and &
(the simplest possible operations to project in a circuit).
On the contrary, &&
and ||
short-circuiting behavior are absolutely about semantics. You can see in the K&R quote, they gave a guarantee. If the whole point of &&
and ||
was not to be short-circuiting they would not even have a reason to exist, because in C any integer greater than zero counts as true, together with > 0
you could have used |
and &
as replacements without loss of anything besides the short circuiting behavior.
&&
and ||
make much easier write code like i <= n && a[i] != x
, or s.tag == X && s.union_value
, or basically any other condition in which the second expression would lead to an access memory violation or undefined behavior if the first expression did not guarantee that it would not. Lots of code rely on this behavior, and I do not believe this is an accident but the original intent of the short-circuiting &&
and ||
.
I had the same experience with the unless
and when
of Ruby, I always though they were harder to understand than &&
and ||
. This is anecdotal evidence. Your experience is not universal. But I would argue that &&
and ||
have the advantage that you just need to think about the truth table and you remember what they are supposed to be doing. Also anecdotal but not having English as my first language I do have much more love for symbols than words in English, which will are often already sufficiently overloaded just for someone trying to learn English.
Because it is not an work-reducing optimization.
Wow. There will certainly be some strong opposition to that. This would be terrible. I use these all the time.
How will you write
if a && b || c
expr
end
?
I also love a ? b : c
.
Shorter code can be easier to read than longer code in many cases. This is an idiom you get quickly used to.
I just wrote this in one line for convenience. I actually meant
if bool
expr
end
While a good discussion is always fun, I think good to point out that this will never actually happen: PSA: Julia is not at that stage of development anymore
There will be a time when we start working on Julia 2.0, which will include some breaking changes, or we wouldnāt call it 2.0, we would just call it Julia 1.x for some value of x. At that point in time, we can consider breaking changes. But despite what it sounds like, this is not the time to make all the random changes that anyone might want to. Frankly, that time has passed for Julia and will never come again. There will probably be a few renamings of unfortunately named things. But thatās not what the 2.0 release is really about.
Your proposed changes would create such massive havoc throughout the ecosystem that probably more than 90% of code will stop working. There might not be any major packages left standing, and the reputation of the language would be devastated.
Removing &&
and ||
is basically impossible. The best you could do is introduce a more attractive alternative, and hope that it wins out over time. But so far I havenāt seen any alternatives I would use.
I agree with your point that shorter code can be easier to work with, but for me that has only been the case when:
The moment one has to handle a handover or look at the code a few months down the line, then I find that often I would have to write a lot of comments to remind me about the purpose of variables/functions.
Kind regards
I wonāt take a side here, but one limitation of the &&
syntax that I have encountered is when trying to assign default values in a function definition:
function foo(x::AbstractVector, m::Union{Nothing,Int}=nothing)
if m === nothing
m = length(x)
end
return sum(x[1:m])
end
works fine.
function bar(x::AbstractVector, m::Union{Nothing,Int}=nothing)
m === nothing && m = length(x)
return sum(x[1:m])
end
is an
ERROR: syntax: invalid assignment location "(m === nothing) && m" around REPL[1]:10
and rightly so! m = length(x)
returns length(x)
(an Int
), not a Bool
.
I guess if you really want a one-liner and donāt like if a b end
you can use the following:
function bar(x::AbstractVector, m::Union{Nothing,Int}=nothing)
m === nothing ? m = length(x) : nothing
return sum(x[1:m])
end
(Purists may prefer isnothing(m)
.)