# Use ⟹ instead of &&?

**URL:** <https://discourse.julialang.org/t/use-instead-of/120729>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [September 30, 2024, 4:29pm UTC](https://discourse.julialang.org/t/use-instead-of/120729 "2024-09-30T16:29:46Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Sariel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sariel/32/212345_2.png) [@Sariel](https://discourse.julialang.org/u/Sariel)\
**Post date:** [September 30, 2024, 4:29pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/1 "2024-09-30T16:29:46Z")

</div>

I find the && notation a bit weird for shortening ifs - it works, but it feels like a hack. A nicer format might be:

(condition) ⟹ do\_something

It would be cool if there is a way to already define \implies to do so, but I guess there is the point of not using notation that nobody else does…

---

<div class="post-metadata">

**Author:** ![zdenek\_hurak](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zdenek_hurak/32/53118_2.png) [@zdenek\_hurak](https://discourse.julialang.org/u/zdenek_hurak)\
**Post date:** [September 30, 2024, 5:05pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/2 "2024-09-30T17:05:58Z")

</div>

Hi Sariel, welcome to the community. I used to struggle with accepting the code like `x && println("OK")` too (where `x` is either `true` or `false`). But the [section](https://docs.julialang.org/en/v1/manual/control-flow/#Short-Circuit-Evaluation) in the manual explains it nicely, I guess. I am now at peace with the notation. In fact, it then also makes perfect sense to write `x || println("OK")` instead of `!x && println("OK")`.

---

<div class="post-metadata">

**Author:** ![Sariel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sariel/32/212345_2.png) [@Sariel](https://discourse.julialang.org/u/Sariel)\
**Post date:** [September 30, 2024, 5:27pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/3 "2024-09-30T17:27:08Z")

</div>

I got used to it, but it feels like a lost opportunity for clarity ;).

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [September 30, 2024, 5:35pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/4 "2024-09-30T17:35:27Z")

</div>

I mostly avoid `&&` and `||` in package code, because it decreases the granularity of code coverage. And of error message location info in general. Related issue:

> <https://github.com/JuliaLang/julia/issues/53090>
>
> \`a.jl\`:
> 
> \`\`\`julia
> 1 +
> 2 +
> 3 +
> error() +
> 5
> \`\`\`
> 
> \`b.jl\`:
> 
> \`\`\`julia
> 1 …+ 2 + 3 + 4 + error() + 5
> \`\`\`
> 
> REPL session:
> 
> \`\`\`julia-repl
> julia\> include("a.jl") # It'd be nice to get a more accurate line number here, i.e., "4" instead of "1"
> ERROR: LoadError: 
> Stacktrace:
> \[1\] error()
> @ Base ./error.jl:44
> \[2\] top-level scope
> @ /tmp/asdoi98uz/a.jl:1
> \[3\] include(fname::String)
> @ Main ./sysimg.jl:38
> \[4\] top-level scope
> @ REPL\[1\]:1
> in expression starting at /tmp/asdoi98uz/a.jl:1
> 
> julia\> include("b.jl") # It'd be nice to get a column number range here for the offending call, \`error()\`
> ERROR: LoadError: 
> Stacktrace:
> \[1\] error()
> @ Base ./error.jl:44
> \[2\] top-level scope
> @ /tmp/asdoi98uz/b.jl:1
> \[3\] include(fname::String)
> @ Main ./sysimg.jl:38
> \[4\] top-level scope
> @ REPL\[2\]:1
> in expression starting at /tmp/asdoi98uz/b.jl:1
> 
> julia\> versioninfo()
> Julia Version 1.11.0-DEV.1389
> Commit ecc14ca3888 (2024-01-27 15:45 UTC)
> Build Info:
> Official https://julialang.org/ release
> Platform Info:
> OS: Linux (x86\_64-linux-gnu)
> CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
> WORD\_SIZE: 64
> LLVM: libLLVM-16.0.6 (ORCJIT, znver2)
> Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
> \`\`\`
> 
> 
> Related issues: #33735, #38531, #50834

---

<div class="post-metadata">

**Author:** ![eldee](https://avatars.discourse-cdn.com/v4/letter/e/b5a626/32.png) [@eldee](https://discourse.julialang.org/u/eldee)\
**Post date:** [September 30, 2024, 5:43pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/5 "2024-09-30T17:43:30Z")

</div>

> [@Sariel](#):
>
> It would be cool if there is a way to already define \implies to do so

You could always write a macro to replace `⟹` by `&&`. E.g.

```julia-repl
julia> macro ⟹(expr)
           replace_implies_call_with_short_circuiting_and!(expr)
           return expr
       end;

julia> function replace_implies_call_with_short_circuiting_and!(expr)
           if expr.head === :call && expr.args[1] === :⟹
               expr.head = :&&
               popfirst!(expr.args)
               for a in expr.args
                   a isa Expr && replace_implies_call_with_short_circuiting_and!(a)
               end
           end
       end;

julia> @⟹ true ⟹ println("Will print");
Will print

julia> @⟹ false ⟹ println("Won't print");

```

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [September 30, 2024, 8:01pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/6 "2024-09-30T20:01:52Z")

</div>

Logically `x ⟹ y` is `!x || y` and could thus be used to the desired effect. Unfortunately, short-circuiting requires delayed evaluation which requires macros in Julia and infix macros cannot be defined. A combination of `⟹` and a macro could be used:

```julia
⟹(x, y) = !x || y()
macro dø(x); :(() -> $(esc(x))) end

```

```julia-repl
julia> true ⟹ @dø error(:ha)
ERROR: ha

julia> false ⟹ @dø error(:ha)
true

```

---

<div class="post-metadata">

**Author:** ![littlelib](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/littlelib/32/209324_2.png) [@littlelib](https://discourse.julialang.org/u/littlelib)\
**Post date:** [September 30, 2024, 10:05pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/7 "2024-09-30T22:05:10Z")

</div>

I thought that [Match.jl](https://github.com/JuliaServices/Match.jl) might be what you want, but then I realized it might be an overkill for your situation, where you’re most likely trying to make a one-liner code.  
Although you can make an one-liner code using Match.jl, it will error if the condition is not met since you can’t exhaust all the possible conditions, and that won’t be something you’d want.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [September 30, 2024, 11:26pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/8 "2024-09-30T23:26:07Z")

</div>

It does feel like a hack because `&&` is primarily a boolean AND. This notation `=>` makes more sense for a conditional, but I’d rather not add more syntax when the typical `if (condition) do_something end` already works and makes as much sense. Then again, I am biased because I prefer `if end` one-liners over `&&` to begin with.

It’s also worth pointing out that short-circuiting semantics are not strict like other arithmetic operators (which act only after all inputs are evaluated), so they are formally control flow as well, which is why they are used as such in many languages for over half a century. A few dynamically typed languages, like Julia, lean into it by conditionally returning the 2nd expression, which may not be boolean. This is also a reason I personally prefer `if end`; on the occasion I assign the value of a conditional statement, I intend a potentially stable type from the branches or `nothing`, not a particular value of the condition depending on the operator.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [October 1, 2024, 1:10am UTC](https://discourse.julialang.org/t/use-instead-of/120729/9 "2024-10-01T01:10:13Z")

</div>

> [@Sariel](#):
>
> it works, but it feels like a hack

Couldn’t agree more. Makes code less readable. Would be happy to never see it again.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [October 1, 2024, 1:22am UTC](https://discourse.julialang.org/t/use-instead-of/120729/10 "2024-10-01T01:22:31Z")

</div>

I have an feature request (that would be breaking, and shouldn’t be seriously considered for a very long time) for [backwards-looking macros](https://github.com/JuliaLang/julia/issues/47895). This seems like a scenario where they might be useful.

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [October 1, 2024, 2:15am UTC](https://discourse.julialang.org/t/use-instead-of/120729/11 "2024-10-01T02:15:09Z")

</div>

Related github issue for one-line `if` statements:

> <https://github.com/JuliaLang/julia/issues/16389>
>
> In various discussions, it has been suggested to allow syntax like:
> 
> \`\`\` julia
> i…f x then y
> \`\`\`
> 
> As a short-form "if" statement and as an alternative to the common:
> 
> \`\`\` julia
> x && y
> \`\`\`
> 
> syntax which leverages the short-circuiting \`&&\` operator for conditionally executing \`y\` (with \`y\` often containing other side effects and not necessarily returning a \`Bool\`).
> 
> The main advantages to this \`if-then\` construct being: more legible code, relying less on abusing \`&&\`, and formally including an "if" statement form that doesn't require an \`end\` keyword.
> 
> It occurred to me the other day, that this syntax would also provide a convenient means for implementing #550, which would look like:
> 
> \`\`\` julia
> A = \[if x % 2 == 0 then f(x) for x in 1:10\]
> \`\`\`
> 
> Relying on the fact that \`if-then\` doesn't require an \`end\` keyword, which we would probably need in some form anyway even if we went with python-style guards:
> 
> \`\`\` python
> A = \[f(x) for x in range(10) if x % 2 == 0\]
> \`\`\`
> 
> To be clear, the Julia guard syntax would essentially be doing a rewrite from:
> 
> \`\`\` julia
> A = \[if x % 2 == 0 then f(x) for x in 1:10\]
> \`\`\`
> 
> to
> 
> \`\`\` julia
> A = \[Filter(x-\>x % 2 == 0, f(x) for x in 1:10)\]
> \`\`\`
> 
> Also as a clarifying note, this would be allowing the guard syntax at the \_generator\_ level as opposed to just the \_comprehension\_ level (which matches what python allows as well).

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [October 1, 2024, 3:42am UTC](https://discourse.julialang.org/t/use-instead-of/120729/12 "2024-10-01T03:42:49Z")

</div>

I don’t like the lack of mandatory `end` or some other block delimiter. It’d be fine if it were restricted to a binary operation, but the conversation naturally involved `else` (which has historically been the case), and that runs into the long-solved dangling else problem:

```julia
if a then if b then x else y
could be
if a then (if b then x) else y # y depends on a
or 
if a then (if b then x else y) # y depends on b

```

Julia’s `end`-less syntax must actually disambiguate that example with `||` vs `?:` for `if-then` vs `if-then-else` respectively, but I go through a similar struggle for:

```julia
a, b, x, y = true, false, "hello", "world"
a ? b : z ? x : y
#=
Is it
(a ? b : z) ? x : y
or
a ? b : (z ? x : y)
=#

```

I struggle with the precedence of binary operators as is, I can’t see it’s the latter, whether intuitively or with the operator precedence table on hand. Granted, the equivalent `if a b elseif z x else y end` statement is hard to read, but at least I can tell where the branches are.

PS you can fake `then` right now with `if a #=then=# b end`. If that seems a tad long, there’s the even shorter `if (a) b end` or `if a; b end` to explicitly divide the condition and branch.

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [October 1, 2024, 6:00pm UTC](https://discourse.julialang.org/t/use-instead-of/120729/13 "2024-10-01T18:00:03Z")

</div>

Have come to like

```julia
condition || error

```

which runs through if the condition holds true and reads like `condition ORELSE error`.
