Una funzione di ordine superiore è una funzione che accetta un'altra funzione come argomento. Una funzione di ordine superiore ben nota è map
, che esegue un'azione su ciascun elemento di una raccolta, ad esempio:
-- Haskell
map (\x -> 2 * x) [1, 2, 3, 4, 5] -- => [2, 4, 6, 8, 10]
Le funzioni di ordine superiore richiedono che tu possa passare una funzione come valore di prima classe, così come puoi passare attorno a numeri, stringhe o altri oggetti. Questo viene fatto non rendendo affatto speciali le funzioni (cioè sono solo oggetti ordinari con sintassi speciale per crearli), o fornendo una sintassi speciale per ottenere un riferimento a una funzione. Potrebbe anche esserci una sintassi per le funzioni anonime (lambda), ma questo non è strettamente necessario per avere funzioni di ordine più elevate.
Nei linguaggi orientati agli oggetti, è interessante notare che oggetti e chiusure sono equivalenti tra loro. In effetti, molti linguaggi rappresentano funzioni di prima classe come un oggetto con un metodo chiamato apply()
o simile. Ancor prima che Java ottenesse lambda, le funzioni di prima classe potevano essere implementate molto verbalmente passando gli oggetti in giro e le classi anonime erano molto simili ai lambda attuali. Il Pattern di comando è essenzialmente una codifica di funzioni di prima classe in un contesto OOP. Quindi qualsiasi linguaggio OOP può avere funzioni di ordine superiore, ma le funzioni di prima classe tendono a implicare una quantità irragionevole di cerimonia.
Le lingue con TO GO calcolati sono anche equivalenti a (in realtà, anche più potenti di) funzioni di prima classe. Mentre tali linguaggi tendono a mancare di molte garanzie del sistema di tipo e rendono facile la scrittura di un oscuro codice di spaghetti, potrebbero essere considerati anche come funzioni di prima classe.
-
C : ha funzioni di puntatori (cioè funzioni di prima classe) e supporta anche funzioni di ordine superiore. Tuttavia, non ha chiusure.
-
Java : esegue OOP e pertanto supporta il modello di comando. Aveva anche classi anonime per un po ', che è una specie di lambda. Con Java 8, ha ottenuto lambdas e sintassi reali per passare metodi come oggetti ordinari. Le chiusure sono limitate.
-
C ++ : ha tutto ciò che C ha, oltre al Command Pattern dovuto a OOP. Ha ottenuto varie forme di lambda nella revisione C ++ 11. Le chiusure sono esplicite e limitate dallo schema di gestione della memoria.
-
Python : è un linguaggio OOP, ma ha anche un numero di influenze Lisp (il Lisp è il linguaggio di programmazione funzionale originale). Le funzioni sono solo oggetti con sintassi di fantasia. L'operatore di chiamata di funzione viene effettivamente tradotto in una chiamata di metodo, il che significa che anche gli oggetti definiti dall'utente possono essere utilizzati come una funzione. Esiste anche una forma di funzioni anonime (espressioni lambda), ma sono ridicolmente limitate. Tutte le funzioni sono chiusure, ma a volte devono essere esplicite a causa delle regole di scoping di Python.
-
JavaScript : è la stessa storia di Python, tranne per il fatto che manca il sovraccarico dell'operatore e non impone restrizioni a lambda. Le chiusure funzionano come previsto.
-
Perl : supporta paradigmi sia orientati agli oggetti che funzionali. È possibile ottenere un riferimento a una funzione denominata come
$code_ref = \&function_name
e chiamare tali riferimenti come $code_ref->(@arguments)
, che equivale a function_name(@arguments)
. Le chiamate ai metodi possono essere eseguite da un nome di runtime, in modo che $object->method()
sia uguale a $name = "method"; $object->$name()
. La risoluzione del metodo può essere eseguita per produrre un riferimento al codice come $code_ref = $object->can("method")
. Sono supportate funzioni anonime: $code_ref = sub { ... }
. Inoltre, l'operatore di chiamata di funzione può essere sovraccaricato per gli oggetti. Tutte le funzioni sono chiusure.
Non posso commentare C #, PHP e i vari dialetti BASIC.