multiple modules in one file

1,421 views
Skip to first unread message

Joe Armstrong

unread,
May 24, 2013, 4:07:47 PM5/24/13
to elixir-l...@googlegroups.com
Foo.ex is as follows
----

defmodule One do

   def xx(a) do
       Two.double(a)   
   end

end

defmodule Two do
   def double(x) do
       2*x
   end
end
-----

> elixirc Foo.ex

produces two files Elixir.One.beam and Elixir.Two.beam

and NOT Elixir.Foo.beam as I had expected

This is a real shame - it would be really nice to distribute applications in one file
and not zillions of small files - when I distribute an entire application the users should
only see one file not many small files

/Joe

Yurii Rashkovskii

unread,
May 24, 2013, 4:12:22 PM5/24/13
to elixir-l...@googlegroups.com
Joe, unlike in Erlang, Elixir does not equate files to modules, hence the result you're getting.



/Joe

--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

José Valim

unread,
May 24, 2013, 4:23:24 PM5/24/13
to elixir-l...@googlegroups.com
To extend Yurii's response, an Elixir file does not represent a module but it contains a "script" to generate one or many modules. For each module you define, you get a beam. That's why you can also write stuff like:

if some_condition? do
  defmodule ThisModule do
    # sip
  end
else
  defmodule AnotherModule do
    # sip
  end
end

The same happens with function definitions inside modules. They don't have a rigid form as in Erlang:

defmodule SomeExample do
  if System.get_env("DEBUG") do
    # generate some functions specific for debug
  end
end

This provides a more natural form of definition than special preprocessors like ifdef. You simply use the same if/case/receive and friends you would inside your functions.

To distribute a project as one single file, there are many approaches coming from OTP as you are aware like escripts, archives, etc.


José Valim
Skype: jv.ptec
Founder and Lead Developer

Joe Armstrong

unread,
May 24, 2013, 4:33:21 PM5/24/13
to elixir-l...@googlegroups.com


On Friday, 24 May 2013 22:12:22 UTC+2, Yurii Rashkovskii wrote:
Joe, unlike in Erlang, Elixir does not equate files to modules, hence the result you're getting.



Right - but it breaks the principle of least astonishment and doesn't play nicely with
traditional makefiles etc,

/Joe

Yurii Rashkovskii

unread,
May 24, 2013, 4:36:30 PM5/24/13
to elixir-l...@googlegroups.com
Lets not even start with the least astonishment, we all know how least astonishing Erlang is to begin with.

I could not possibly imagine a single file with two module definitions to map logically into one module (that would definitely be astonishing!).

I am not even sure what's your proposal is about, anyway... pack two modules into one? always do an escript? an ez?

José Valim

unread,
May 24, 2013, 4:43:59 PM5/24/13
to elixir-l...@googlegroups.com
> Right - but it breaks the principle of least astonishment and doesn't play nicely with traditional makefiles etc,

The least astonishment to whom? It changes from person to person, depending on their background. It is impossible to design a language that is not going to break this principle for any particular group of people. Even if Elixir was just a command line calculator using binary operators, those used with Reverse Polish Notation would still be astonished...

However, you are right. It does break makefiles and but that's hardly a concern in Elixir. In Elixir, a developer will use the Mix tool (in the same scope as rebar) to manage their projects and files.  It also compiles files in parallel and, more importantly, it also automatically solves dependencies in between the files. Having macros means that modules are going to depend on each other at compilation time and all those dependencies would have to be properly sorted in any Makefile attempt.


José Valim
Skype: jv.ptec
Founder and Lead Developer


Joe Armstrong

unread,
May 24, 2013, 5:11:56 PM5/24/13
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br


On Friday, 24 May 2013 22:43:59 UTC+2, José Valim wrote:
> Right - but it breaks the principle of least astonishment and doesn't play nicely with traditional makefiles etc,

The least astonishment to whom? It changes from person to person, depending on their background. It is impossible to design a language that is not going to break this principle for any particular group of people. Even if Elixir was just a command line calculator using binary operators, those used with Reverse Polish Notation would still be astonished...

For me - I'm astonished :-)
 

However, you are right. It does break makefiles and but that's hardly a concern in Elixir. In Elixir, a developer will use the Mix tool (in the same scope as rebar) to manage their projects and files.  It also compiles files in parallel and, more importantly, it also automatically solves dependencies in between the files. Having macros means that modules are going to depend on each other at compilation time and all those dependencies would have to be properly sorted in any Makefile attempt.

I don't know about mix - what is it? - I typically build things using
erlang, c, bash scripts node.js, javascript etc. Makefiles are pretty universal and language neural
(ie equally bad at all languages)

Large numbers of languages use the principle OneSource x Compile = One OutputFile with
a different file extension.

One input file -> many outputfiles with many different names rather surprises me.

Id actually like no input files and no output files (like smalltalk) bit that's a different
discussion.

Devin Torres

unread,
May 24, 2013, 5:20:22 PM5/24/13
to elixir-l...@googlegroups.com, José Valim
Joe--

Mix is our build tool that comes with Elixir (http://elixir-lang.org/getting_started/mix/1.html). It's really pretty awesome. I still use Makefiles, but they just call out to mix tasks.

José Valim

unread,
May 24, 2013, 5:49:04 PM5/24/13
to elixir-l...@googlegroups.com
For me - I'm astonished :-)

Ha! :)
 
I don't know about mix - what is it? 

The easiest explanation for an Erlanger is that it is our rebar equivalent. :) You will find mix in the same path you have the elixir executable. So if elixir is in your path, mix will be too. Give it a try:

    mix new new_project
    cd new_project
    mix help

You may want to try `mix compile` and `mix test` straight away. Notice it will build the app file and everything. :)

That's more like a flow an Elixir developer will go through. They will create a new project with mix that already sets up the test framework and everything. So it is more likely that we will use the test framework itself (because it is more robust, has great reporting, etc) than matches in the module definition.

Although being able to call functions in the module body would bring other benefits too... like module body meta-programming... I just wish we could implement it in way that wouldn't rely on eval. :S
Reply all
Reply to author
Forward
0 new messages