If you could change one thing in Elixir language, what you would change?



Ok, so it make sense.
Thank u for answer


I’ll check it out, thanks!


This might go against the grain, but I’d love some OOP. I suppose in Elixir this is done through “processes”. Still trying to wrap my head around functional. I’ve found a hybrid approach provides much more flexibility.

Should I be looking at processes for this? I’ve been able to simplify a great deal through functional approaches.

That plus static typing (though we are 25% of the way there through dialyzer). Sadly, doesn’t look like either will make an appearance due to nature of underlying architecture.



This is a good read to help wrap your head around the concepts of modeling with processes.


Appreciate it!


It might be valuable to discover what elements you feel you are missing out on - for example:

  • mutable vs immutable
  • shared vs not shared
  • designing flow of control vs flow of data (values)
  • etc.

There are already some topics around that explore the differences and nuances. Like:

  1. improve the REPL with a few things:

It would be nice for history to persist between invocations.
It would be nice for multiline invocations to be up-arrowable (if you’re curious to how amazing this is, try julialang).
It would be nice to be able to define functions in the REPL scope without having to define a module (I know, this is nigh impossible).

  1. etc:

Can I make a module compile-time only? We can currently do this with packages using runtime: false, but not on a module-by-module basis.


You might add to your .bash_profile…

export ERL_AFLAGS="-kernel shell_history enabled"


What you mean by that? What would you expect out of such module? You can define module that will contain only macros, so effectively it will end mostly empty in production, mix help compile.app mention option :modules but I do not know if this is respected anyway by the compiler it is.


This is actually not impossible, it just depends on what the shell interpreter decides to do. For example the Erlang shell has a simple way that if you have a module :user_defaults then you can call these functions without a module prefix. Yes, I know, a module but it is on the way. The LFE repl allows you the define both local functions and macros without a module.


Sometimes it’s useful for macros to call functions which are then unit tested.


:modules option seems like it’s what i want, but it’s somewhat poorly documented:

.app files also expect other options like :modules
and :vsn

is all it says. Is there another place where I can find what it does or should I just chase the code?


The :modules option won’t make modules disappear or make them compile-time only. It exists only for catalog purposes and to check for module conflicts when building a release, it doesn’t affect runtime. So AFAIK there is no reason to change it and it is better to let Mix fill it in. :slight_smile:


If you want to have test-only modules then add new path to the :elixirc_paths (commonly used path is test/support) and define such modules there, or if this is for testing then you can define such module within your test module, ex.:

defmodule MyTest do
  use ExUnit.Case

  defmodule Foo do
    use MyMod

  test "Foo module has function foo/0" do
    assert function_exported?(Foo, :foo, 0)


no, that doesn’t help. Here’s what I’m doing:

defmodule MyMacros do
   defmacro mymacro(foo) do
   def ast_transform(foo) do
      <calls other functions>

I don’t need ast_transform (and friends) at runtime. It’s compile-time only. I might want to unit test ast-transform, because it’s rather complicated.


When I first started learning elixir it felt inconvinient not to have a ternary operator
foo = bar ? buz : buzzz
and to type

foo = if bar do

instead. I got accustomed to it as well as to calling captured functions with a period sign between function variable name and arguments but…

recently started learning Dart (thanks to Flutter) and found there besides of ternary operator such goodies:
var foo ??= 'bar';
which means "if foo is not null then do nothing, else set it to ‘bar’ "
var foo = bar?? : buz;
which means “set foo to bar if it’s not null else set it to buz”
var foo = bar?.buz;
which means “if bar is not null then foo is equal to buz property of bar”

I think this brevity adds to Dart’s expressiveness. I know that question mark and colon are really busy in Elixir, I’m just missing for some consice substitution for ternary operator.


I’m not a fan of those operators in dart, and if they are idiomatic, maybe its even a reason to not start with it?

I like the expliciteness of foo = if foo == nil, do: 'bar', else: foo. Even my son might grok whats going on here (after he had the first couple of english lessons). He probably wont understand var foo ??= 'bar'; without having explicitely learned dart…


Oh, and break operator for breaking loops. Last time I had to do it like in here: https://gist.github.com/lerencao/bd6f3ddf3fb468a7e52ae31f2f07f995
I just remember my surprise not to have it in Elixir from the box…


Enum.reduce_while? Explicit recursion?

Stop yelling the l world and start using recursion and higher order functions!


Huh? You can break from a loop just fine:

iex(1)> defmodule Blah do
...(1)>   def bloop(i) do
...(1)>     if i < 10 do
...(1)>       0
...(1)>     else
...(1)>       i + bloop(i-1)
...(1)>     end
...(1)>   end
...(1)> end
{:module, Blah,
 <<70, 79, 82, 49, 0, 0, 4, 224, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 128,
   0, 0, 0, 15, 11, 69, 108, 105, 120, 105, 114, 46, 66, 108, 97, 104, 8, 95,
   95, 105, 110, 102, 111, 95, 95, 7, 99, ...>>, {:bloop, 1}}
iex(2)> Blah.bloop(15)

Remember, in a pure functional world loops are just recursive calls, to ‘break’ out you just return instead of continuing the recursion. :slight_smile:

Hmm, so:

foo = foo || "bar"
foo = foo && bar || buz
foo = bar && bar.buz

Though you didn’t say what the last one does when bar is null, guessing it sets foo to null since expressions have to return something, so I did the same.

That dart syntax I’m not a fan of, that’s getting into operator overload there… >.>