Friday, 22 June 2007

Erlang Macro Oddness


I found a little oddity with Erlang macros while I was writing version 2 of the Weighted Slope One algorithm. It seems that passing a multi-statement anonymous function as a parameter into a macro confuses the compiler.

For example, this code works:

-module(macro_oddness).
-export([start/0]).
-define(A_MACRO(FunAnon), apply(FunAnon, [])).

start() ->
?A_MACRO(
fun() ->
io:format("Single-element function works fine.~n")
end).


But this code produces a compile-time error:
-module(macro_oddness).
-export([start/0]).
-define(A_MACRO(FunAnon), apply(FunAnon, [])).

start() -> ?A_MACRO(
fun() ->
io:format("Multiple-element function "),
io:format("does not compile.~n")
end).


An "argument mismatch for macro ''A_MACRO''" error, to be precise.

Interestingly, multiple statements in a begin..end block seem to be okay:

-module(macro_oddness).
-export([start/0]).
-define(A_MACRO(FunAnon), apply(FunAnon, [])).

start() -> ?A_MACRO(
fun() ->
begin
io:format("Multiple-element function "),
io:format("with a begin..end block is okay.~n")
end
end).


Something to keep an eye out for.

2 comments:

  1. And do you know the reason of such behaviour?

    ReplyDelete
  2. Qrilka: I am guessing that the Erlang preprocessor is not flagging the 'fun' keyword as the beginning of a block of code that ends with the 'end' keyword, and instead ends the first statement at the comma (the usual statement terminator).

    The first argument would then be taken as 'fun() -> io:format(...)' and the second as 'io:format(...) end', which would cause the single-argument A_MACRO macro to choke during expansion.

    ReplyDelete

Obligatory legal stuff

Unless otherwise noted, all code appearing on this blog is released into the public domain and provided "as-is", without any warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall the author(s) be liable for any claim, damages, or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software.