English3000
First impressions of Elixir's core
Per Imagining Elixir 2.0 - #14 by English3000, I have decided to fork Elixir.
Additionally, I am writing gists as I go, documenting my thought process…
This is the first.
TL;DR
eexshould be extracted to its own package because a basic Mix project doesn’t use templatesex_unitshould be extracted too, but automatically included inmix.exs
Most Liked
josevalim
Easily in which sense? Have you tried to move them out? It is not just a matter of moving a file from a directory to the other.
For example, could inspect be a separate library? Sure, it could. But if we do so, how would Elixir core, which cannot depend on any external package, do something as simple as:
def some_function(other) do
raise ArgumentError, "expected an integer, got #{inspect(other)}"
end
The best we would be able to do is say “expected an integer, got something else” or we would have to reimplement the inspect functionality by hand.
What if you move a GenServer out? Then how would we implement the functionality in Elixir that relies on GenServers today?
So the answer why a lot of those things are in core is because building a reasonably useful application without them, including Elixir itself, would be very hard. Removing them is not easy because it means you would have to implement some good chunks of them to implement Elixir’s core itself. As others said, without ex_unit we couldn’t even write tests for core.
So what about mix and eex? They are in Elixir because although they are not needed in Elixir itself, they are needed for Elixir developers. You want to start a new project? Well, you need mix. You want to compile a project? Well, you need mix as well. But they are not required, to the point those are typically stripped out when running your software in production. In fact, if you want to ditch Mix and maintain your whole project with a Makefile, you can do it (and what’s how we did it before Mix).
This leaves us with Logger and IEx. We probably wouldn’t have a Logger in Elixir if Erlang/OTP didn’t have a Logger. But Erlang/OTP does ship with a Logger, as part of its kernel/stdlib, and if we didn’t have a Logger in Elixir, then it means you would get error reports and log messages with everything as Erlang terms. So Logger is needed at least as a translation layer. Same thing for IEx. It comes as part of Erlang/OTP’s kernel/stdlib, so providing a shell that understands Elixir is quite reasonable and relatively low effort. If we didn’t have one in Erlang/OTP, maybe we wouldn’t have one in Elixir too (although I would consider IEx to be an essential development tool).
So you can think of this as an onion. Inside core, we have a bunch things that are essential for writing software and often they are dependent on each other. For example, if Enum depends on GenServer and GenServer depends on Enum, how can you compile them in the first place? This is common in all programming languages that are mostly implemented in terms of themselves, which is why such languages need to find a way to bootstrap themselves. Some languages even require a previous version of the language in order to compile the new version. If you don’t want this, then the alternative is to write your core in another language.
Then on top of this core, we have another layer with applications which are necessary for developers to bootstrap their own applications and run them in production with good user experience. That implies a build tool, interactive elixir, properly formatted log messages, etc. At this point, it is much easier to organize those parts into applications because the “core” is ready. We can use almost all conveniences any Elixir developer would, except by the build tool itself.
Then the third layer is the one provided by Hex (which is not part of core) and the community.
If you really want to take the idea of a minimal core to the extreme, you can try this: in your next project, you can only use Kernel.SpecialForms. Nothing more. You will see that, in order to get anything meaningful done, you will have to reimplement a good chunk of Elixir’s core.
josevalim
So every time this discussion comes out I have to remind everyone that for cannot be implemented using regular constructs because it relies on some VM optimizations that only work if we emit the proper Erlang abstract code. with also has some particular scoping rules that would be hard to implement as efficiently without being a special form but I want to submit a PR to Erlang/OTP for that.
NobbZ
First misconception… eex is a general purpose templating enging that directly embeds elixir code into the template, rather than using a DSL.
Because they are different (OTP) applications. This way you can compile and run your project without having to include mix and eex, just because elixir uses them…
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









