Map device name in runtime to save some typing #366

Merged
merged 1 commit into from Jun 15, 2012

Conversation

Projects
None yet
3 participants
Member

alco commented Jun 14, 2012

Here's my take on the issue #318. I ran into a compiler crash when placing the defmacrop part at the bottom of the module.

elixir/lib/io.ex:114: macro map_dev/1 is unused
error: {'__MAIN__.CompileError','__exception__',
                                <<"function map_dev/1 undefined">>,
                                <<"/Users/alco/Documents/git/elixir/lib/io.ex">>,
                                19}
stacktrace: [{io,'__info__',[macros],[]},
             {elixir_dispatch,get_optional_macros,1,
                              [{file,"src/elixir_dispatch.erl"},{line,225}]},
             {elixir_dispatch,expand_require,8,
                              [{file,"src/elixir_dispatch.erl"},{line,135}]},
             {elixir_dispatch,dispatch_require,6,
                              [{file,"src/elixir_dispatch.erl"},{line,83}]},
             {lists,mapfoldl,3,[{file,"lists.erl"},{line,1278}]},
             {elixir_clauses,assigns_block,6,
                             [{file,"src/elixir_clauses.erl"},{line,44}]},
             {elixir_def,translate_definition,7,
                         [{file,"src/elixir_def.erl"},{line,165}]},
             {elixir_def,store_definition,8{"init terminating in do_boot",1}
,
                         [{file,"src/elixir_def.erl"},{line,81}]}]

Also, I tried to make a wrapper for def to streamline the mapping experience, but got stuck with unquoting and concatenating module refs. Not sure if it's of any use:

  defmacrop ErlIO(fun, dev, args) do
    quote do
      Erlang.io.unquote(fun) unquote(map_dev(dev)), unquote_splicing(args)
    end
  end

This pull request passes (merged 0872515 into c79caec).

Owner

josevalim commented Jun 15, 2012

This looks great, thanks. Is there really a need to be a macro? Just wondering.

And yes, a macro must be defined before it is used. :) The error message was ugly just because you were compiling elixir itself, you would get a nice pretty-printed message otherwise.

Owner

josevalim commented Jun 15, 2012

Regarding the def wrapper you had in mind, you would have to use apply:

defmacrop ErlIO(fun, dev, args) do
  quote do
    apply Erlang.io, unquote(fun), [unquote(map_dev(dev)), unquote_splicing(args)]
  end
end

@josevalim josevalim added a commit that referenced this pull request Jun 15, 2012

@josevalim josevalim Merge pull request #366 from alco/map_dev
Map device name in runtime to save some typing
fb07d5e

@josevalim josevalim merged commit fb07d5e into elixir-lang:master Jun 15, 2012

Member

alco commented Jun 15, 2012

This looks great, thanks. Is there really a need to be a macro? Just wondering.

The macro is saving us one function call, although it's more a matter of preference.

Regarding the def wrapper you had in mind, you would have to use apply:

That's sad, I thought I would be able to do alias concatenation at compile time.

Owner

josevalim commented Jun 15, 2012

@alco apply is a smart macro and actually does it at compile time, so no worries. :)

Member

alco commented Jun 15, 2012

@josevalim Oh, sorry. I thought you were talking about Erlang's apply. Thanks for the info :)

Owner

josevalim commented Jun 15, 2012

Yeah, we simply wrap erlang's apply. They may also optimize it too, for example, apply(lists, flatten, [[1,2,3]]) may be the same as lists:flatten([1,2,3]), never benchmarked to be sure though.

Member

alco commented Jun 15, 2012

@josevalim They have a note here:

Note: If the number of arguments are known at compile-time, the call is better written as Module:Function(Arg1, Arg2, ..., ArgN).

I understand it as a statement that apply does some work at runtime to support variable-length lists of arguments.

Owner

josevalim commented Jun 15, 2012

Interesting. They could optimize it, it is funny they don't. Elixir optimizes it exactly if the list of arguments is known at compile-time (which is the case above).

alco deleted the alco:map_dev branch May 16, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment