Perhaps I'm being dense but I don't see how your example relates to
mine. The only difference between my working code and non-working code
is that the working code has the sub-module defined prior to the
primary module. They're both fully closed at compile time in both
cases in that there is nothing more about the Demo.Embed struct to be
defined so references to it could be resolved at both compile and run
time.

Can you point me to where this issue of what is resolved at run time
vs compile time is documented?

I'm especially curious about your example code - is that legal elixir
and, if so, is my understanding correct that Foo.Bar is always
compiled but that its accessibility is still determined at run time?
This implies that you are supporting conditional compiling at run time
by allowing a different definition of Bar depending on the state of a
variable at run time. Is that correct?

thanx,

  -- Ben Scherrey


On Sun, Jul 17, 2016 at 9:04 PM, José Valim
<[email protected]> wrote:
>
>>
>>     Regarding #2 - Without a clearer understanding of the formal
>> specification of the language (ala #1) that tells me otherwise, I
>> still think (your corrected) Version #1 should be legal Elixir but
>> perhaps just requires a different mechanism for identifying when the
>> Module/Struct is fully defined. A two pass system could absolutely
>> still work this way.
>
>
> Since this seems to be the contention point, let's try to understand why
> this is the only possible way for this to work. Imagine you have this code:
>
> variable = System.get_env("DEFINE_BAR")
>
> defmodule Foo do
>
>   if variable in ~w(1 true) do
>
>     defmodule Bar do
>
>     end
>
>   end
>
> end
>
>
> If the module Bar was defined during compilation, Bar would be *always*
> defined, because compilation does not know the value of the variable nor it
> would evaluate the if (since it depends on runtime values). Code that is
> expanded, is always expanded, even if inside a conditional. If the module
> was defined during expansion then the module would always be defined.
>
> In other words, a struct expansion that happens at compile time, cannot
> depend on values that are in the same context and will be defined only at
> runtime. That's the same reason why you can't invoke a function in the same
> context you define it. The reason why multiple modules work is because we
> first expand both modules and then we execute them.
>
> While I personally think this behaviour is documented (because the two
> passes compilation is documented as part of the macro system as well as the
> fact that structs are expanded during compile time), I would agree it may
> take a while to build the intuition around it and we could very likely
> benefit from more examples and discussions.
>
>
> José Valim
> www.plataformatec.com.br
> Skype: jv.ptec
> Founder and Director of R&D
>
> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4Jc6%2BF_6ggP8gLAFVvvjtuvc74RBbd2MaOsZH%2Bc_y3gpg%40mail.gmail.com.
>
> For more options, visit https://groups.google.com/d/optout.

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/elixir-lang-core/CACo3Shghy4C380zoSF%3Dc_bbtjWvUHhdkDnwFS1HX2mg_s8LDYg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to