Skip to content

Instantly share code, notes, and snippets.

@sasa1977
Created February 4, 2013 09:45
Show Gist options
  • Save sasa1977/4705873 to your computer and use it in GitHub Desktop.
Save sasa1977/4705873 to your computer and use it in GitHub Desktop.
defmodule Lambda do
defmacro l(code) do
make_fun(arity(code), code)
end
defmacro l(arity, code) do
make_fun(arity, code)
end
defp make_fun(arity, code) do
quote do
fn(unquote_splicing(args(arity))) ->
unquote(code)
end
end
end
defp args(arity) do
Enum.map(0..arity, fn(arg) ->
{binary_to_atom("_#{arg}"), [], nil}
end) |> tl
end
defp arity(code), do: calc_arity(code, 0)
defp calc_arity({:l, _, _}, arity_acc), do: arity_acc
defp calc_arity(tuple, arity_acc) when is_tuple(tuple) do
calc_arity(tuple_to_list(tuple), arity_acc)
end
defp calc_arity(list, arity_acc) when is_list(list) do
List.foldl(list, arity_acc, fn(elem, arity_acc) -> calc_arity(elem, arity_acc) end)
end
defp calc_arity(identifier, arity_acc) when is_atom(identifier) do
calc_arity(atom_to_binary(identifier), arity_acc)
end
defp calc_arity("_" <> rest, arity_acc) do
case Regex.match?(%r/^\d+$/, rest) do
true -> max(arity_acc, binary_to_integer(rest))
false -> arity_acc
end
end
defp calc_arity(_, arity_acc), do: arity_acc
end
defrecord Rec, a: nil
defmodule Test do
import Lambda
def test_lambda do
Enum.map(1..5, l(Rec.new(a: _1))) |>
Enum.each(l(IO.puts _1.a))
Enum.each(1..3, l(1, IO.puts "Hi!"))
end
end
Test.test_lambda
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment