# Conditional return

**URL:** <https://forum.crystal-lang.org/t/conditional-return/6663>\
**Category:** Crystal Contrib\
**Created:** [March 4, 2024, 12:23am UTC](https://forum.crystal-lang.org/t/conditional-return/6663 "2024-03-04T00:23:15Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![self](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/self/32/2421_2.png) [@self](https://forum.crystal-lang.org/u/self)\
**Post date:** [March 4, 2024, 12:23am UTC](https://forum.crystal-lang.org/t/conditional-return/6663/1 "2024-03-04T00:23:15Z")

</div>

What do you think about a conditional `return` statement?  
(Let’s call it “`return?`”)

Sometimes I find myself writing code like:

```crystal
result = some_loooooooooooooooooooooooooooooong_expression
return result if result
result = some_other_loooooooooooooooooooooooooooooong_expression
return result if result
return nil

```

I could write that like so, but I don’t really like multiple `return` statements in a method to be that far to the right because they can easily be overlooked:

```crystal
(result = some_loooooooooooooooooooooooooooooong_expression) && return result
(result = some_other_loooooooooooooooooooooooooooooong_expression) && return result
return nil

```

Not a fan either:

```crystal
return some_loooooooooooooooooooooooooooooong_expression ||
  some_other_loooooooooooooooooooooooooooooong_expression ||
  nil

```

So how about:

```crystal
return? some_loooooooooooooooooooooooooooooong_expression
return? some_other_loooooooooooooooooooooooooooooong_expression
return nil

```

with `return?` being something like:

```crystal
macro return?(expr)
  result = ({{expr}})
  return result if result
end

```

Is the forum the right place for questions like these or should it go directly into a discussion in an issue on GitHub?

---

<div class="post-metadata">

**Author:** ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)\
**Post date:** [March 4, 2024, 12:30am UTC](https://forum.crystal-lang.org/t/conditional-return/6663/2 "2024-03-04T00:30:08Z")

</div>

What’s wrong with your first example? Could also write it like:

```crystal
def some_method
  if result = some_loooooooooooooooooooooooooooooong_expression
    return result
  end

  if result = some_other_loooooooooooooooooooooooooooooong_expression
    return result
  end

  nil
end

```

Otherwise, it’s my 2 cents that if you really want to have this macro for your own code/projects that’s fine, but I’m not sure it’s worth having in the stdlib…

But yes, the forums are a good starting point until there is something actionable that is worth creating an issue for.

---

<div class="post-metadata">

**Author:** ![HertzDevil](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/hertzdevil/32/1023_2.png) [@HertzDevil](https://forum.crystal-lang.org/u/HertzDevil)\
**Post date:** [March 4, 2024, 12:36am UTC](https://forum.crystal-lang.org/t/conditional-return/6663/3 "2024-03-04T00:36:01Z")

</div>

There’s also:

```crystal
return unless result = some_loooooooooooooooooooooooooooooong_expression

```

And note that oftentimes `nil` is the only possible falsey value so you could write `return` instead of `return result`.

---

<div class="post-metadata">

**Author:** ![self](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/self/32/2421_2.png) [@self](https://forum.crystal-lang.org/u/self)\
**Post date:** [March 4, 2024, 12:51am UTC](https://forum.crystal-lang.org/t/conditional-return/6663/4 "2024-03-04T00:51:19Z")

</div>

I actually want to return the result value, so if I’m not mistaken that would be:

```cr
return result if result = some_long_expression

```

But what I get is:

> Error: undefined method ‘result’ …  
> If you declared ‘result’ in a suffix if, declare it in a regular if for this to work.

So that would be:

```cr
result = nil
return result if result = some_long_expression
return result if result = some_other_long_expression

```

Still need to think about whether I like that. 🙂

---

<div class="post-metadata">

**Author:** ![ysbaddaden](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/ysbaddaden/32/2252_2.png) [@ysbaddaden](https://forum.crystal-lang.org/u/ysbaddaden)\
**Post date:** [March 4, 2024, 3:09pm UTC](https://forum.crystal-lang.org/t/conditional-return/6663/5 "2024-03-04T15:09:40Z")

</div>

What about using this opportunity to refactor your code?

```auto
def execute?
  operation || second_operation
end

private def operation
  some_loooooooooooooooooooooooooooooong_expression
end

private def second_operation
  some_other_loooooooooooooooooooooooooooooong_expression
end

```

The compiled result will be identical (the operation methods should be inlined) and given that `#operation` and `#second_operation` are given explicit, self explanatory, names, this might be nicer to read.

---

<div class="post-metadata">

**Author:** ![zw963](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/zw963/32/1623_2.png) [@zw963](https://forum.crystal-lang.org/u/zw963)\
**Post date:** [March 4, 2024, 4:26pm UTC](https://forum.crystal-lang.org/t/conditional-return/6663/6 "2024-03-04T16:26:37Z")

</div>

```crystal
return? some_loooooooooooooooooooooooooooooong_expression
return? some_other_loooooooooooooooooooooooooooooong_expression
return

```

I think the above is a very good solution, better than else.

is there any other programming language have this?

---

<div class="post-metadata">

**Author:** ![Xen](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/xen/32/2288_2.png) [@Xen](https://forum.crystal-lang.org/u/Xen)\
**Post date:** [March 4, 2024, 9:35pm UTC](https://forum.crystal-lang.org/t/conditional-return/6663/7 "2024-03-04T21:35:34Z")

</div>

> [@ysbaddaden](#):
>
> What about using this opportunity to refactor your code?

Indeed. I’ve grown a habit of trying to avoid explicit returns when writing Crystal, I quite like having the return value be the last evaluated line of the function.

Secondly, I try to avoid long expressions for readability. I believe the cost of using a few extra local variables is so minute as to be irrelevant.
