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.