Anonymous functions, the dot, and parameters

The main reason is that Elixir is a lisp-2 language - this means that variables and functions “occupy” different name spaces, so calling a function in the functions namespace and calling a function in the variables namespace has to work differently. Most languages are lisp-1 (which means that variables and functions are in the same namespace). Some other lisp-2 languages are Ruby, Common Lisp and Perl.

Being lisp-2 means that this code is valid:

def foo(arg), do: arg

def bar() do
  foo = 1
  foo(foo)
end

I.e. we can define a variable with the same name as local function and there is no shadowing occurring. This doesn’t work in lisp-1 languages, for example in Python:

>>> def foo(arg):
...   return arg
>>> foo(1)
1
>>> foo = 1
>>> foo(foo)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable

It also doesn’t matter if the language is statically typed, for example in C:

int foo(int a) {
    return a;
}

int main() {
    int foo = 1;
    return foo(foo);
}

Fails to compile with:

test.c:7:15: error: called object type 'int' is not a function or function pointer
    return foo(foo);
           ~~~^
1 error generated.

Neither choice is better or worse, it’s a design decision like many when constructing a language - each with it’s own trade-offs. It also has little to do with optional parenthesis. While yes, it’s true that optional parenthesis make it harder, this is not the main reason. This choice was dictated primarily by semantics of the language and not syntax.

21 Likes