How to understand compiled Elixir Erlang function names -


in exprof, elixir function names printed out assume erlang names, after compilation. 1 example

enum.reduce/3 

which printed

'elixir.enum':'-reduce/3-lists^foldl/2-0-'/3 

how parse string? -lists^foldl/2-0- part come from? why there multiple /3? why names - prefixed? ^ mean? why 2-0-?

how parse string?

'elixir.enum':'-reduce/3-lists^foldl/2-0-'/3 function reference syntax in erlang referring function named -reduce/3-lists^foldl/2-0- in module elixir.enum, arity 3, similar &enum."-reduce/3-lists^foldl/2-0-"/3 in elixir.

where -lists^foldl/2-0- part come from?

the -$fn/$arity-$something-$count- name returned erlang in stacktraces (and apparently profiling output) anonymous function defined inside $fn/$arity. normally, see -main/0-fun-0-, i.e. $something == "fun", example, this:

defmodule foo   def main     try       (fn -> raise("foo") end).()     rescue       _ -> io.inspect system.stacktrace     end   end end 

prints:

[{foo, :"-main/0-fun-0-", 0, [file: 'foo.ex', line: 4]},  {foo, :main, 0, [file: 'foo.ex', line: 4]},  {:erl_eval, :do_apply, 6, [file: 'erl_eval.erl', line: 670]},  {:elixir, :erl_eval, 3, [file: 'src/elixir.erl', line: 223]},  {:elixir, :eval_forms, 4, [file: 'src/elixir.erl', line: 211]},  {code, :eval_string, 3, [file: 'lib/code.ex', line: 168]},  {kernel.cli, :wrapper, 1, [file: 'lib/kernel/cli.ex', line: 437]},  {enum, :"-map/2-lists^map/1-0-", 2, [file: 'lib/enum.ex', line: 1184]}] 

it's you're less see -fun- ones in elixir's default error messages because they're normalized, anonymous fn/0 in foo.main/0 in case (this why printed stacktrace above calling system.stacktrace/0 explicitly).

so lists^foldl/2 come from? that's generated sys_core_fold_lists, module called sys_core_fold modules defining inline_list_funcs compile attribute (the enum module in elixir does that), "inlines high order lists functions lists module". inlining gives name "lists^foldl/2" anonymous function instead of being "fun".

here's simple demo:

defmodule fold   @compile :inline_list_funcs    def main     sum([1, 2, 3])   end    def sum(list)     :lists.foldl(fn a, b -> raise "foo" end, 0, list)   end end  fold.main 

with @compile :inline_list_funcs, output is:

** (runtimeerror) foo     fold.exs:9: anonymous fn/2 in fold.sum/1     fold.exs:9: fold."-sum/1-lists^foldl/2-0-"/3     (elixir) lib/code.ex:363: code.require_file/2 

and without it, output is:

** (runtimeerror) foo     fold.exs:9: anonymous fn/2 in fold.sum/1     (stdlib) lists.erl:1263: :lists.foldl/3     (elixir) lib/code.ex:363: code.require_file/2 

with attribute, don't have stacktrace entry lists module, though we're explicitly calling :lists:foldl.

why there multiple /3?

that seems side effect of erlang including arity of current function when naming anonymous function.

why names - prefixed?

explained above.

what ^ mean?

it's name sys_core_fold_lists:call/4 chose.

why 2-0-?

2 comes sys_core_fold_lists:call/4. 0 referred "count" in exception.format_mfa/3 i'm not sure means.


Comments