Given the following module definition:
defmodule MyMod do
def fun_1 do
0
end
def fun_2 do
fon_1 + 1
end
end
…Elixir provides a nice compile-time error informing me that MyMod.fon_1/1 does not exist:
** (CompileError) test/foo_test.exs:7: undefined function fon_1/0
(stdlib) lists.erl:1337: :lists.foreach/2
(stdlib) erl_eval.erl:669: :erl_eval.do_apply/6
(stdlib) erl_eval.erl:122: :erl_eval.exprs/5
But if I call an undefined remote function:
defmodule MyMod do
def fun_1 do
0
end
def fun_2 do
MyMod.fon_1 + 1
end
end
…then Elixir does not provide a compile-time error. Instead, a runtime error is raised when fun_2 is called:
** (UndefinedFunctionError) undefined function MyMod.fon_1/0
stacktrace:
MyMod.fon_1()
test/foo_test.exs:7: MyMod.fun_2/0
test/foo_test.exs:15
Is there anything preventing Elixir from providing a compile-time error in this case? Obviously, if a remote function call is made using a module variable (e.g. var.foo()) the compiler can’t statically know what functions var exports. But if the remote function call is made on a static alias, it seems like the compiler should be able to figure it out.
Thanks,
Mron
--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CADUxQmtuLSokWRJA0prd9bnguSepcYL6fyFWcTA%3Dw%2BntNYn88A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CADUxQmtuLSokWRJA0prd9bnguSepcYL6fyFWcTA%3Dw%2BntNYn88A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.
But maybe my search-fu is just week (I searched on "remote function").
Anyway, the issue with this feature is exactly the same that appeared during the defmodulep discussion: the only way to know if a function exists in another module is by compiling that module and today the compiler does not work under such assumptions.
The best option to provide such features in the short-term is by doing a post-compilation check. Post-compilation checks could also detect circular dependencies which we would need to deprecate if we want to have such features at compile time in the future.
It seems like mix compiles libraries in topological order (based on declared dependency relationships) so for modules provided by a dependency (or by Elixir itself) could it provide this?
It's not clear to me why we have to deprecate circular module dependencies to support this feature as a post-compilation check.
This scheme would allow circular module dependencies as we have now, assuming the post-compilation step does not run until the entire project has finished compilation. Circular project dependencies would not be allowed but from what I understand, they are already not allowed.
Any reason such an approach wouldn't work with the existing compiler?