small medium large xlarge

Dave_gnome_head_isolated_pragsmall
15 Jul 2013, 03:42
Dave Thomas (396 posts)
  • Write a macro called myunless that implements the standard unless functionality. You’re allowed to use the regular if expresssion in it.
Generic-user-small
08 Dec 2014, 10:50
Tim Rozmajzl (3 posts)
defmodule My do

  defmacro unless(condition, _do_block = [do: expression]) do
    _unless(condition, expression)
  end

  defmacro unless(condition, expression) do
    _unless(condition, expression)
  end

  defp _unless(condition, expression) do
    quote do
      if !unquote(condition), do: unquote(expression)
    end
  end

end
Generic-user-small
19 Jan 2015, 17:40
Pierre Sugar (57 posts)
defmodule My do
  defmacro unlezz(condition, clauses) do
    do_clause   = Keyword.get(clauses, :do, nil)
    else_clause = Keyword.get(clauses, :else, nil)

    quote do
      case unquote(condition) do
        val when val in [false, nil] -> unquote(do_clause)
        _                            -> unquote(else_clause)
      end
    end
  end
end

defmodule TestUnlezz do
  require My
  import  My

  unlezz 1 == 1 do
    IO.puts ">: 1 != 1"
  else
    IO.puts ">: 1 == 1"
  end

  unlezz 2 == 3 do
    IO.puts ">: 2 != 3"
  else
    IO.puts ">: 2 == 3"
  end
end
N657160017_3588_pragsmall
06 Jul 2016, 21:46
Alvise Susmel (9 posts)

Sincerely, I don’t like this unquote inside the quote block. I prefer to use Code.eval_quoted to evaluate the condition. Dave, what do you think ? I think is less complicated than the one in your example “macros/myif.ex”


defmodule My do defmacro myunless(condition,clauses) do {result, _} = Code.eval_quoted(condition) case !result do true -> clauses[:do] false -> clauses[:else] end end end

defmodule Test do import My

myunless 0 < 1 do
    IO.puts "myunless: true"
else
    IO.puts "myunless: false"
end end ---
20160310-gunnar_pragsmall
26 Jul 2016, 03:34
Felipe Juarez Murillo (9 posts)

As the exercise saids: “You’re allowed to use the regular if expression in it.”

defmodule MyMacro do

  defmacro myunless(condition, clauses) do
    do_clause   = Keyword.get(clauses, :do, nil)
    else_clause = Keyword.get(clauses, :else, nil)

    quote do
      if unquote(condition) do
        unquote(else_clause)
      else
        unquote(do_clause)
      end
    end
  end
end

defmodule TestMacro do
  require MyMacro

  MyMacro.myunless true do
    IO.puts("This will never be seen")
  else
    IO.puts("This will be seen")
  end
end
Generic-user-small
03 Feb 2018, 16:20
Christophe GAREYTE (1 post)

This one “mirrors” Dave’s original if macro and destructures clauses using pattern matching

defmacro unless(condition, do: do_clause, else: else_clause) do
    quote do
      case unquote(condition) do
        val when val in [false, nil] -> unquote(do_clause)
        _ -> unquote(else_clause)
      end
    end
  end
You must be logged in to comment