26
votes

I've recently decided to learn Elixir. Coming from a C++/Java/JavaScript background I've been having a lot of trouble grasping the basics. This might sound stupid but how would return statements work in Elixir? I've looked around and it seems as though it's just the last line of a function i.e.

def Hello do 
  "Hello World!"
end

Would this function return "Hello World!", is there another way to do a return? Also, how would you return early? in JavaScript we could write something like this to find if an array has a certain value in it:

function foo(a){
   for(var i = 0;i<a.length;i++){
      if(a[i] == "22"){
         return true;
      }
   }
   return false;
}

How would that work in Elixir?

2
Here is another example on how to return early: elixir-examples.github.io/examples/return-earlyBrandon
@Brandon, thanks man, so in that example if "some_condition" is false it'll output the value that "do_something()" outputs?Joe Thomas
It's not a dumb question at all. It's really hard to get accustomed to the notion of every function returning the last value calculated when one is used to imperative languages. Stick with it--once you get used to the idea of every function returning a value you'll find that your functions will become much more cohesive.Onorio Catenacci
@wateriswet that's correct, it will return the value of do_something()Brandon
Possible duplicate of Return statement in ElixirDennis

2 Answers

23
votes

Elixir has no 'break out' keyword that would be equivalent to the 'return' keyword in other languages.

Typically what you would do is re-structure your code so the last statement executed is the return value.

Below is an idiomatic way in elixir to perform the equivalent of your code test, assuming you meant 'a' as something that behaves kind of array like in your initial example:

def is_there_a_22(a) do
  Enum.any?(a, fn(item) -> item == "22" end.)
end

What's actually going on here is we're restructuring our thinking a little bit. Instead of the procedural approach, where we'd search through the array and return early if we find what we were looking for, we're going to ask what you are really after in the code snippet: "Does this array have a 22 anywhere?"

We are then going to use the elixir Enum library to run through the array for us, and provide the any? function with a test which will tell us if anything matches the criteria we cared about.

While this is a case that is easily solved with enumeration, I think it's possible the heart of your question applies more to things such as the 'bouncer pattern' used in procedural methods. For example, if I meet certain criteria in a method, return right away. A good example of this would be a method that returns false if the thing you're going to do work on is null:

function is_my_property_true(obj) {
  if (obj == null) {
    return false;
  }
  // .....lots of code....
  return some_result_from_obj;
}

The only way to really accomplish this in elixir is to put the guard up front and factor out a method:

def test_property_val_from_obj(obj) do
  # ...a bunch of code about to get the property
  # want and see if it is true
end

def is_my_property_true(obj) do
   case obj do
     nil -> false
     _ -> test_property_value_from_obj(obj)
   end
end

tl;dr - No there isn't an equivalent - you need to structure your code accordingly. On the flip side, this tends to keep your methods small - and your intent clear.

6
votes

You are correct in that last expression is always returned. Even more - there are no statements in the language - just expressions. Every construct has a value - if, case, etc. There is also no early return. This may seem limiting, but you quickly get used to it.

A normal way to solve your example with Elixir would be to use a higher order function:

def foo(list) do
  Enum.any?(list, fn x -> x == "22" end)
end