3

Say I have a function, that's slightly verbose and is called with the same arguments each time, this function is also required a lot to do some setup before any other functions from that module can be called within its callback.

SomeMod.called_a_lot(‘xx’, fn(y) ->
  SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’)
end)

I imagine that I can wrap it like so:

defp easier_to_call(func) do
  SomeMod.called_a_lot(‘xx’, fn(y) -> func(y) end
end

then use it like so:

easier_to_call(fn(y) ->
  SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’)
end)

How does one actually do this in Elixir?

1
  • 1
    Your code looks fine; just change func(y) to func.(y) since it's an anonymous function. Commented May 9, 2017 at 19:09

4 Answers 4

3

Your syntax is just a bit off for calling anonymous functions. You will need to use

func.(y)

instead of

func(y)

since it is an anonymous function.

See the Elixir Crash Course for a brief example.

Sign up to request clarification or add additional context in comments.

Comments

2

I don't really understand what exactly you're asking, but I feel like the capture operator (&) is what you're looking for.

An example use would be:

easier_func = &SomeMod.called_a_lot(‘xx’, &1)

easier_func.(fn(_y) ->
  SomeMod.needs_called_a_lot_to_be_called_first(‘do_stuff’)
end)

With &1 being the first parameter in the anonymous function.

If you need a multiple arity anonymous function then you can do:

easy_reduce = &Enum.reduce(&1, 0, &2)

easy_reduce.([1,2,3,4], fn(x, acc) -> acc + x end) # => 10

Comments

1

Dogbert's comment is correct. But since you don't modify the arguments, you could just pass the function on without wrapping it in an anonymous function:

defp easier_to_call(func) do
  SomeMod.called_a_lot(‘xx’, func)
end

Comments

1

Just to show another approach: it might be achieved with macro, that calls the function to be called first and then calls the block:

defmodule Test do
  defmacro with_prepended(arg, do: block) do
    quote do
      IO.inspect(unquote(arg), label: "In function")
      prepended(unquote(arg))
      unquote(block)
    end
  end
end

defmodule Tester do
  require Test

  defp prepended(arg), do: IO.inspect(arg, label: "In prepended")

  def fun(arg) do
    Test.with_prepended(arg) do
      IO.puts "Actual code"
    end
  end
end

Tester.fun(42)

#⇒ In function: 42
#⇒ In prepended: 42
#⇒ Actual code

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.