>
> I believe the following code examples are all identically equivalent.
>
Well, the compiler is explicitly telling you that they are not. :)
There are two concepts to understand in the examples you posted: one of
aliasing and the other one is about compile time expansion. In particular,
remember that structs are expanded at compilation time.
> Version 1:
> defmodule Demo do
> defmodule Demo.Embed do
> defstruct local: 0
> end
>
> defstruct name: "", embed: %Embed{}
> end
>
In this example, you are actually defining a struct named Demo.Demo.Embed.
In this case, when you try to expand %Embed{}, it doesn't see an Embed
alias and then it tries to expand the "root" Embed which does not exist.
That's *not* the error message you reported though. So I am assuming you
mixed something up either when copying the code or the error message.
If we fix the code:
defmodule Demo do
> defmodule Embed do
> defstruct local: 0
> end
>
> defstruct name: "", embed: %Embed{}
> end
>
Then the error is the one you reported:
== Compilation error on file lib/demo.ex ==
> ** (CompileError) lib/demo.ex:7: cannot access struct Demo.Embed, the
> struct was not yet defined or the struct is being accessed in the same
> context that defines it
> (elixir) src/elixir_map.erl:58: :elixir_map.translate_struct/4
> (stdlib) lists.erl:1353: :lists.mapfoldl/3
> (stdlib) lists.erl:1354: :lists.mapfoldl/3
>
And then:
This: "the struct is being accessed in the same context that defines
> it" is a pretty big hint but I disagree with it. By time line 7 is
> being compiled the Embed struct is already fully defined.
>
The compiler is correct, regardless of how much you disagree with it. :)
Remember that structs are expanded at compile time so when you try to
expand %Embed{}, the defmodule macro was also expanded but the module
contents was not yet executed/defined.
You can effectively think of your code as running twice: one goes through
all the source, doing all the compiler time work, then when you execute it
does another pass, running all of the expanded code.
Version 2 will fail since you can't use a struct before you defined it. The
next two examples are correct.
--
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/CAGnRm4JF6BK1MkZ_bOUuXH33ranJrWnJGo6KV9wLwPKy%2BTcfTQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.