Potrei sbagliarmi dal momento che nessuno lo ha menzionato, ma avevo anche l'impressione che la ragione di ciò sia anche l'eredità rubina di poter chiamare funzioni senza parentesi.
Arity è ovviamente coinvolto, ma lascialo da parte per un po 'e usa le funzioni senza argomenti. In un linguaggio come javascript in cui le parentesi sono obbligatorie, è facile fare la differenza tra passare una funzione come argomento e chiamare la funzione. Lo chiami solo quando usi le parentesi.
my_function // argument
(function() {}) // argument
my_function() // function is called
(function() {})() // function is called
Come puoi vedere, nominarlo o meno non fa una grande differenza. Ma elisir e ruby ti consentono di chiamare funzioni senza parentesi. Questa è una scelta di design che mi piace personalmente ma ha questo effetto collaterale che non puoi usare solo il nome senza le parentesi perché potrebbe significare che vuoi chiamare la funzione. Questo è ciò che &
serve. Se lasci arity appart per un secondo, anteporre il nome della tua funzione &
significa che vuoi esplicitamente usare questa funzione come argomento, non ciò che questa funzione restituisce.
Ora la funzione anonima è leggermente diversa in quanto viene utilizzata principalmente come argomento. Ancora una volta questa è una scelta progettuale, ma il razionale dietro è che è principalmente usata da iteratori di funzioni che prendono le funzioni come argomenti. Quindi ovviamente non è necessario utilizzarlo &
perché sono già considerati argomenti per impostazione predefinita. È il loro scopo.
Ora l'ultimo problema è che a volte devi chiamarli nel tuo codice, perché non sono sempre usati con un tipo di funzione iteratore, o potresti codificare tu stesso un iteratore. Per la piccola storia, poiché ruby è orientato agli oggetti, il modo principale per farlo è stato quello di utilizzare il call
metodo sull'oggetto. In questo modo, è possibile mantenere coerente il comportamento delle parentesi non obbligatorie.
my_lambda.call
my_lambda.call()
my_lambda_with_arguments.call :h2g2, 42
my_lambda_with_arguments.call(:h2g2, 42)
Ora qualcuno ha trovato una scorciatoia che in pratica sembra un metodo senza nome.
my_lambda.()
my_lambda_with_arguments.(:h2g2, 42)
Ancora una volta, questa è una scelta di design. Ora elisir non è orientato agli oggetti e quindi chiama di sicuro non usare il primo modulo. Non posso parlare per José ma sembra che la seconda forma sia stata usata nell'elisir perché sembra ancora una chiamata di funzione con un carattere in più. È abbastanza vicino a una chiamata di funzione.
Non ho pensato a tutti i pro e contro, ma sembra che in entrambe le lingue potresti cavartela con le parentesi solo se rendi obbligatorie le parentesi per le funzioni anonime. Sembra che sia:
Parentesi obbligatorie VS Notazione leggermente diversa
In entrambi i casi fai un'eccezione perché fai in modo che entrambi si comportino diversamente. Poiché c'è una differenza, potresti anche renderlo ovvio e scegliere la diversa notazione. Le parentesi obbligatorie sembrerebbero naturali nella maggior parte dei casi, ma molto confuse quando le cose non vanno come previsto.
Ecco qui. Ora questa potrebbe non essere la migliore spiegazione al mondo perché ho semplificato la maggior parte dei dettagli. Inoltre, la maggior parte sono scelte progettuali e ho cercato di dare una ragione per loro senza giudicarle. Adoro l'elisir, adoro il rubino, mi piacciono le chiamate di funzione senza parentesi, ma come te, trovo le conseguenze abbastanza fuorvianti di tanto in tanto.
E nell'elisir, è proprio questo punto in più, mentre nel rubino hai dei blocchi sopra questo. I blocchi sono fantastici e sono sorpreso di quanto tu possa fare con solo i blocchi, ma funzionano solo quando hai bisogno di una sola funzione anonima che è l'ultimo argomento. Quindi, poiché dovresti essere in grado di gestire altri scenari, ecco che arriva l'intero metodo / lambda / proc / block confusion.
Comunque ... questo è fuori portata.