Imagining Elixir 2.0


1 Like

You should be realistic – the core maintainers aren’t going to hard-fork their own language core and then maintain two copies. I agree with your sentiment overall – and it has been said by people much smarter than all of us here that a perfect software is achieved when you cannot take away anything more.

But in real life we cannot be gods and sometimes we have to maintain past mistakes – or simply a baggage we no longer need but others do.

The way to go about it isn’t to divide the community – which is what will happen if your proposal to remove some functions is implemented. The way to go is invest in good educational materials that can show some of Elixir’s gotchas right from the start (like using Erlang modules for a number of scenarios instead of emulating the functionality in Elixir and/or including wrappers in your app).


The “variations” part doesn’t seem like a good example - fetch vs get isn’t the greatest API, but smashing them together and then control-coupling to an option list isn’t great either.

Re: “where cruft and redundancies have been removed for better performance” in the conclusion - is there any research measuring the performance impact of having unused functions in Elixir? There’s definitely an impact in client-side-Javascript-land, but that’s a very different environment.


It’s as simple as publishing a new release.

Unless you’re saying :ecto, "~> 3.0" and :ecto_sql have somehow “divided” the community??

A great example that already exists in Elixir is IO.inspect/2-3

It’s very powerful and very convenient.

To your point, right now I need to remember the distinction between two functions, as captured by somewhat arbitrary naming.

An options list is more explicit and more powerful. If I ever want to change my code, I just add an option instead of having to use a whole new function.

Think about it.

Re: cruft and performance, I’m referring to compile time.

That’s a big part of how Elixir is able to announce it’s faster with each release.

List/String.myers_difference are not in the core out of pure luck, but because it’s needed by the core itself. It currently is used by the ExUnit diffing mechanisms to give you the really amazing diffs in errors. So they simply couldn’t be in some external package and it’s nice that they are kept public so other people can benefit from the efforts of having it in the core.


I’m confused. You said it’s used in ExUnit. I’m not necessarily saying that’s the right home for it, but…

Let’s look to another example: Erlang.

When you start a project in Erlang, instead of just getting :elixir by default, you get 3, IIRC.

One could argue that Erlang’s packages are too modular… and I’d agree with that!

But by the same token, I’d say Elixir’s core has some things that could be revised.

Now if 1.8 truly is the slowdown point, fine. It’s small enough.

But again, Valim’s whole argument for not adding new functions to say ExUnit (such as 2 that I proposed) is the notion that Elixir should be extensible.

At the end of the day, I think there’s a double-standard: the Core Team adds things even when the separation of concerns is poor or unexplained. And when I worked off of that, suggesting 2 macros, I get this line about extensibility.

The irony is I agreed with Valim’s point in principle, so I’m confused by the resistance here when I apply this same principle to the core itself… :man_shrugging:

Putting anything in the language core is a permanent commitment.

There are two things at play: What happened until now and what happens in the future.

I’m sure there’s stuff in the core, which could be removed. Though I’d expect all those to be deprecated and simply to not be removed because of not having breaking changes. All the rest therefore is there to have the elixir version we have today. That version is what José said is what he and the core team is happy about and what they refer to as essentially feature complete. Afaik any additional features following up should only be added if they really can’t be done in an external package (e.g. see the discussion about private modules) or otherwise greatly benefit from being in the core. It’s probably not their intention for people to now go and see what can be split out of current elixir, because it could’ve been an external package. Doing that would make it a different elixir to what we have today. Also a good stdlib is not a minimal one, but one, which is just right. Enough to get people up to speed, small enough to not feel bloated for a good amount of usecases (like embedded work will always fight for a few MB less) and powerful enough to not have people miss more or less essential functionality. Maintaining balance is the hard part here.


I’m confused where you disagree with me.

I’m saying the same point.

I’ll just say this: I think the core lacks order.

And while I don’t have the power to deactivate posting, please know that my intention was not a debate but rather a discussion.

And I am genuinely disheartened by the response :frowning_face:

You will find this is a very controversial statement. I’d say people who create and maintain languages are likely to disagree.

Nothing much to be disheartened about, do you have some sort of a huge blocker working with Elixir?

Again, were it up to me, I would have closed this, as it is a debate not a discussion. But given the debate continues, I must continue making my case.

Elixir lacks order in that there is no objective criterion for what does or doesn’t go in the core.

Rather, it is stated:

The Elixir team focuses on language features that:

  1. are necessary for developing the language itself
  2. bring important concepts/features to the community in a way its effect can only be maximized or leveraged by making it part of the language

These are heuristics. The core team determines what belongs and what doesn’t. Extensibility can be cited to avoid going in one direction while reason #2 can be cited to do so.

The problem, from an open-source standpoint, is that there is no system to consider new ideas (in my experience, just hostility). As a result, might is “right”.

I mean, so be it–Valim has done a generally great job.

It’s just frustrating…

I’ve already made the distinctions in my article from an organizational standpoint.

In terms of documentation, currently functions are arbitrarily put in alphabetical order. Again, I’ve already written this before, but just for visibility–the benefit is ordering is predictable; the downside is it is cluttered. Were an additional level of granularity to be added (like how modules themselves aren’t ordered completely alphabetically, but rather alphabetically within logically arranged groups–or like in Kernel where there is a second dropdown for guards), that would provide users the best of both worlds.

Last, in my experience, the codebase itself in certain places could be refactored for concision and clarity. Part of this is the scope of my article, and the other part is an experience I had trying to contribute to :ex_doc which isn’t part of the core.

Whatever the case, whatever the reasons, it doesn’t really matter. The great thing about tech is even if a bunch of people don’t like the sound of one’s idea… one can simply build it.

For those of you who are interested in what I have in mind, please feel free to check out my gists.

Those are two very distinct examples.

The reason we added String.myers_difference is because we use it for ExUnit diffing. If we didn’t have ExUnit diffing, we wouldn’t have String.myers_difference. Originally the diffing algorithms were inside ExUnit exclusively but some developers asked them to be extracted. Since the feature was already in core, it made sense to be extracted. However, if it wasn’t on core and somebody asked to add String.myers_difference, then we likely wouldn’t have accepted it.

So there is a whole history of how things evolved and how myers_difference plays an important role in one of ExUnit’s most important usability features.

With that said, there is no denial that deciding what is worth enough to get into core is decided by the core team. There are heuristics in place. Those heuristics were created exactly because before there was nothing and the community asked us to write down our decision process for guidance. It is completely natural for us to refine the process as the language and the community matures. I am also completely aware that we won’t make everybody happy.

In fact, the whole point of saying “Elixir is slowing down” is exactly to signal to everyone that proposals most likely won’t be accepted. The most relevant features have already made into core. Sure, we may miss some excellent features as part of core by taking such stance, but there is no perfect system.

Look, I completely understand it is frustrating to work on something and have proposals rejected. I am also an open source contributor. I also get this end of the stick.

Heck, this happens even on Elixir itself. You can find examples here on the forum of proposals that I have put dozens of hours into it, describing the rationale, the pros and cons, answered questions from the community, and they were ultimately “rejected by the community”. Either because the proposal really wasn’t as good as I thought or because I could not get my point across.

Ultimately, if you believe that there is a double standard, there is nothing I can do about it, but my conscience is clear that communication regarding Elixir’s future improved steadily and that we are doing our best to apply our heuristics consistently. In fact, even you cited an example of a feature that was built by the core team (ExUnitProperties) and it was decided to not be part of language either. It is a case extremely similar to yours and the outcomes have been the same, roughly around the same time period.

Somebody (usually myself) needs to “say no”, which means I will get flack from time to time and is, honestly, quite exhausting, but that’s the best system I can think of.


The difference though is that none of the options given to IO.inspect/2-3 change its return type. We generally avoid having an option change the return type because it makes the code harder to understand.

For example, if we were to merge get, fetch and fetch! into something, the following call Map.something(map, key, opts) could return {:ok, value} | value | :error | no_return. This can have a negative impact in static analysis tools like diaylzer, which may now have to work with this broad return type, and even affect features in editors, such as the typespecs autocompletion found in VS Code Elixir.

Sorry but it is unclear how the suggestions above would impact compile time and how it relates to the “Elixir is faster” announcements. Can you please expand? If there are ways we can compile libraries and applications faster, I would love to hear.


@josevalim have the Core team considered changing or improving the syntax for pattern matches on and construction of maps?

One of the changes I would love to see is ability to only having to specify the name of the key and get a variable of the same name:

%{ name, age } = my_map

or only specify the variable names and get keys using the same names:

name = “Jose”
my_map = %{ name }

This is similar to how clojure does it and especially newer js syntax.

This has been requested a multitude of times and rejected every time. See also:

1 Like

I tried to get that added to elixir, but there was a lot of opposition. Proposal: Add field puns/map shorthand to Elixir

I don’t see that changing. I think the best option at this point would be to implement %/2 in Elixir instead of a Kernel.SpecialForm, so that you could at least do that with structs.