Posso estar errado, já que ninguém o mencionou, mas também fiquei com a impressão de que a razão disso também é a herança ruby de poder chamar funções sem colchetes.
Arity está obviamente envolvido, mas vamos deixar isso de lado por um tempo e usar funções sem argumentos. Em uma linguagem como o javascript, onde os colchetes são obrigatórios, é fácil fazer a diferença entre passar uma função como argumento e chamar a função. Você chama apenas quando usa os colchetes.
my_function // argument
(function() {}) // argument
my_function() // function is called
(function() {})() // function is called
Como você pode ver, nomeá-lo ou não não faz uma grande diferença. Mas elixir e ruby permitem chamar funções sem os colchetes. Essa é uma opção de design que eu pessoalmente gosto, mas tem esse efeito colateral que você não pode usar apenas o nome sem os colchetes, pois pode significar que você deseja chamar a função. É para isso que &
serve. Se você deixar o arity appart por um segundo, acrescentar o nome da sua função &
significa que deseja explicitamente usar essa função como argumento, e não o que essa função retorna.
Agora, a função anônima é um pouco diferente, pois é usada principalmente como argumento. Novamente, essa é uma opção de design, mas o racional por trás disso é que ela é usada principalmente por iteradores, tipo de funções que aceitam funções como argumentos. Então, obviamente, você não precisa usá-lo &
porque eles já são considerados argumentos por padrão. É o propósito deles.
Agora, o último problema é que às vezes você precisa chamá-los em seu código, porque eles nem sempre são usados com um tipo de função de iterador ou você pode estar codificando um iterador. Para a pequena história, como o ruby é orientado a objetos, a principal maneira de fazer isso era usar o call
método no objeto. Dessa forma, você pode manter o comportamento dos colchetes não obrigatórios consistente.
my_lambda.call
my_lambda.call()
my_lambda_with_arguments.call :h2g2, 42
my_lambda_with_arguments.call(:h2g2, 42)
Agora, alguém criou um atalho que basicamente se parece com um método sem nome.
my_lambda.()
my_lambda_with_arguments.(:h2g2, 42)
Novamente, essa é uma escolha de design. Agora, o elixir não é orientado a objetos e, portanto, não deve usar o primeiro formulário com certeza. Não posso falar por José, mas parece que a segunda forma foi usada no elixir porque ainda parece uma chamada de função com um caractere extra. É perto o suficiente de uma chamada de função.
Eu não pensei em todos os prós e contras, mas parece que nos dois idiomas você pode se dar bem com os colchetes desde que os torne obrigatórios para funções anônimas. Parece que é:
Parênteses obrigatórios VS Notação ligeiramente diferente
Nos dois casos, você abre uma exceção porque os dois se comportam de maneira diferente. Como existe uma diferença, é melhor deixar óbvio e seguir a notação diferente. Os colchetes obrigatórios pareceriam naturais na maioria dos casos, mas muito confusos quando as coisas não saem conforme o planejado.
Aqui está. Agora, essa pode não ser a melhor explicação do mundo, porque simplifiquei a maioria dos detalhes. Também a maioria são escolhas de design e tentei dar uma razão para elas sem julgá-las. Eu amo elixir, eu amo rubi, gosto das chamadas de função sem colchetes, mas, como você, acho as consequências bastante errôneas de vez em quando.
E no elixir, é apenas esse ponto extra, enquanto no rubi você tem blocos em cima disso. Os blocos são incríveis e estou surpreso com o quanto você pode fazer com apenas blocos, mas eles só funcionam quando você precisa de apenas uma função anônima que é o último argumento. Então, como você deve lidar com outros cenários, aqui vem todo o método / lambda / proc / block confusion.
Enfim ... isso está fora de escopo.