Conditional return

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

Sometimes I find myself writing code like:

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:

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

Not a fan either:

return some_loooooooooooooooooooooooooooooong_expression ||
  some_other_loooooooooooooooooooooooooooooong_expression ||
  nil

So how about:

return? some_loooooooooooooooooooooooooooooong_expression
return? some_other_loooooooooooooooooooooooooooooong_expression
return  nil

with return? being something like:

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?

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

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.

1 Like

There’s also:

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.

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

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:

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. :slight_smile:

What about using this opportunity to refactor your code?

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.

7 Likes
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?

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.