# \`ifelse\` query

**URL:** https://discourse.julialang.org/t/ifelse-query/121466
**Category:** General Usage
**Created:** [October 18, 2024, 6:29pm UTC](https://discourse.julialang.org/t/ifelse-query/121466 "2024-10-18T18:29:10Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![Sushrut\_Deshpande](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sushrut_deshpande/32/52754_2.png) [@Sushrut\_Deshpande](https://discourse.julialang.org/u/Sushrut_Deshpande)
#### Post date: [October 18, 2024, 6:29pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/1 "2024-10-18T18:29:10Z")

</div>

Hello,  
I have the following code

```julia
function test(x,y)
   ifelse(x>y,return x, throw(error("err")))
end

```

For me the function is always returning error. This does not make sense to me as for `test(2,1)` it should return 2.

This is only happening when error is thrown. Otherwise for numerical outputs there is no problem.

---

<div class="post-metadata">

### Author: ![jakobjpeters](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobjpeters/32/207797_2.png) [@jakobjpeters](https://discourse.julialang.org/u/jakobjpeters)
#### Post date: [October 18, 2024, 6:32pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/2 "2024-10-18T18:32:28Z")

</div>

Compare how your example is parsed with wrapping the return in parentheses.

```julia-repl
julia> :(function test(x,y)
          ifelse(x>y,return x, throw(error("err")))
       end)
:(function test(x, y)
      #= REPL[9]:1 =#
      #= REPL[9]:2 =#
      ifelse(x > y, return (x, throw(error("err"))))
  end)

julia> :(function test(x,y)
          ifelse(x>y,(return x), throw(error("err")))
       end)
:(function test(x, y)
      #= REPL[8]:1 =#
      #= REPL[8]:2 =#
      ifelse(x > y, return x, throw(error("err")))
  end)

```

---

<div class="post-metadata">

### Author: ![Sushrut\_Deshpande](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sushrut_deshpande/32/52754_2.png) [@Sushrut\_Deshpande](https://discourse.julialang.org/u/Sushrut_Deshpande)
#### Post date: [October 18, 2024, 6:34pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/3 "2024-10-18T18:34:25Z")

</div>

Ah I see. I wasn’t aware of the parsing.

---

<div class="post-metadata">

### Author: ![jakobjpeters](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobjpeters/32/207797_2.png) [@jakobjpeters](https://discourse.julialang.org/u/jakobjpeters)
#### Post date: [October 18, 2024, 6:35pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/4 "2024-10-18T18:35:29Z")

</div>

Even though this function is similar to the `if` statement syntax, you probably don’t want a `return` statement within a function call.

---

<div class="post-metadata">

### Author: ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)
#### Post date: [October 18, 2024, 6:55pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/5 "2024-10-18T18:55:53Z")

</div>

Just to add to the explanation of @jakobjpeters about the `return` statement:  
Another issue is the use of `ifelse` itself.

From the docstring (EDIT: I removed the irrelevant parts of the docstring to reduce noise):

```julia
  ifelse(condition::Bool, x, y)

  [...] This differs from ? or if in that it is an ordinary function, so all the arguments are evaluated
  first. [...]

```

So the `error` will always be thrown, no matter what:

```julia-repl
julia> ifelse(true, 1, error("2"))
ERROR: 2
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] top-level scope
   @ REPL[17]:1

```

---

<div class="post-metadata">

### Author: ![Sushrut\_Deshpande](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sushrut_deshpande/32/52754_2.png) [@Sushrut\_Deshpande](https://discourse.julialang.org/u/Sushrut_Deshpande)
#### Post date: [October 18, 2024, 7:41pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/6 "2024-10-18T19:41:54Z")

</div>

Yes indeed. I figured that out as well. But then the question becomes is there a safe way to throw error statements?

---

<div class="post-metadata">

### Author: ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)
#### Post date: [October 18, 2024, 7:51pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/7 "2024-10-18T19:51:53Z")

</div>

What do you mean by safe?

You can just use a regular `if` statement:

```julia
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)

```julia
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.)

---

<div class="post-metadata">

### Author: ![Sushrut\_Deshpande](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sushrut_deshpande/32/52754_2.png) [@Sushrut\_Deshpande](https://discourse.julialang.org/u/Sushrut_Deshpande)
#### Post date: [October 18, 2024, 7:54pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/8 "2024-10-18T19:54:13Z")

</div>

I see your point. Thanks!!

---

<div class="post-metadata">

### Author: ![kevbonham](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevbonham/32/216165_2.png) [@kevbonham](https://discourse.julialang.org/u/kevbonham)
#### Post date: [October 19, 2024, 11:22am UTC](https://discourse.julialang.org/t/ifelse-query/121466/9 "2024-10-19T11:22:55Z")

</div>

Just to add one more possibility…

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

```julia
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) &&...`

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [October 19, 2024, 2:26pm UTC](https://discourse.julialang.org/t/ifelse-query/121466/10 "2024-10-19T14:26:20Z")

</div>

`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

```julia
julia> macro macro_ifelse(condExpr, trueExpr, falseExpr) :($condExpr ? $trueExpr : $falseExpr) end
julia> @macro_ifelse(1<2, 1, throw("oops"))
1

```

But that would be a mere shorthand for a ternary / if-else:

```julia
julia> Base.@macroexpand @macro_ifelse(1<2, 1, throw("oops"))
:(if 1 < 2
      1
  else
      Main.throw("oops")
  end)

```

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`.
