I believe the following code examples are all identically equivalent.
I don't see a place in the spec that would cause me to think that any
of these code examples would fail to compile yet the first two fail
and the last two work. I would also suggest that the first two
(especially the first) are far better in terms of being able to reason
about one's code because it doesn't require one to put a small
submodule/structure which is only meant to be meaningful in the
context of the parent module/structure into an independent file or
define it prior to its parent owning module. I know that modules are
technically flat (which is why v4 works) and that we're really just
talking about something that kinda resembles a namespace but it
doesn't change my impression that these are still equivalent code.

Can anyone tell me where in the language specification would make me
understand why these first two fail?
Also, is there any reason we can't support the first version of this code?

Version 1:
file demo.ex
defmodule Demo do

    defmodule Demo.Embed do
        defstruct local: 0
    end

    defstruct name: "", embed: %Embed{}
end

scherrey@(none) ~/develop/elixir/demo $ mix compile

== 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

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.

Version 2:
file demo.ex
defmodule Demo do

    alias Demo.Embed

    defstruct name: "", embed: %Embed{}
end


defmodule Demo.Embed do
    defstruct local: 0
end

scherrey@(none) ~/develop/elixir/demo $ mix compile

== Compilation error on file lib/demo.ex ==
** (CompileError) lib/demo.ex:5: Demo.Embed.__struct__/0 is undefined,
cannot expand struct Demo.Embed
    (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

Version 3:
file demo.ex
defmodule Demo do

    alias Demo.Embed

    defstruct name: "", embed: %Embed{}
end

file embed.ex
defmodule Demo.Embed do
    defstruct local: 0
end

This compiles and works.

Version 4:
file demo.ex
defmodule Demo.Embed do
    defstruct local: 0
end

defmodule Demo do

    alias Demo.Embed

    defstruct name: "", embed: %Embed{}
end

This compiles and works.

I find this quite counter intuitive. Am I missing something obvious?

thanx,

  -- Ben Scherrey

-- 
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/CACo3ShgwQ5V1bkRQ7_C4A5Kc7y2OGONE%2Bs6wVh7no1rhwzDn3A%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to