Quali linguaggi di programmazione supportano gli operatori come cittadini di prima classe? es .: restituisce un operatore (+, -, =, ==, ecc.) da una funzione, o memorizza all'interno di una variabile.
Quali linguaggi di programmazione supportano gli operatori come cittadini di prima classe? es .: restituisce un operatore (+, -, =, ==, ecc.) da una funzione, o memorizza all'interno di una variabile.
In alcune lingue, gli operatori non sono molto speciali. Invece, sono semplicemente funzioni con nomi composti da simboli e spesso non usano la normale sintassi di chiamata della funzione.
Lisp: gli operatori sono solo funzioni normali. (+ 1 2)
aggiunge i suoi argomenti, (< 1 2 3)
controlla un ordine, .... Non ci sono operatori infissi. Non c'è nulla di speciale in questi nomi e puoi utilizzare tali operatori nelle funzioni di ordine superiore.
Scala: puoi invocare metodi senza paranti: foo.bar(baz)
e foo bar baz
sono equivalenti. Puoi anche usare i simboli per i nomi dei metodi. La precedenza di questi operatori è determinata dal primo carattere nell'operatore. Ad esempio, possiamo definire un metodo def +-+(x: SomeType)
e quindi richiamarlo come x +-+ y
.
Possiamo anche eseguire operazioni di ordine superiore con questi operatori, ma è importante notare che sono davvero metodi non funzioni libere. Se abbiamo una sequenza e vogliamo combinarla, non possiamo scrivere Seq(…).fold(defaultValue)(+-+)
ma dovremmo passare l'operatore come (_ +-+ _)
che è zucchero sintattico per ((a, b) -> a.+-+(b))
.
Haskell: gli operatori sono funzioni con nomi non alfabetici e un'associatività e precedenza. Possiamo dichiarare un nuovo operatore come infixr 0 &
, che dichiarerebbe un operatore di destra-associazione &
infisso con la prima possibile il più possibile. Possiamo in seguito definirlo come x & y = ...
o (&) x y = ...
. Non dobbiamo usarlo come operatore. Per usarlo come una funzione regolare, possiamo racchiuderlo tra parentesi. Quindi potrei passarlo a foldl
come foldl (&) default someList
. Altrimenti, la sintassi sarebbe ambigua. Possiamo anche utilizzare funzioni regolari come funzioni infissi, racchiudendo il nome tra apici inversi: ((&) 'foldl' default) someList
funzionerebbe anche.
C ++: gli operatori sono funzioni libere o metodi membri. Mentre per esempio l'aggiunta su tipi personalizzati può essere invocata come a + b
, potremmo anche usare operator+(a, b)
o a.operator+(b)
, a seconda che si tratti di una funzione libera. Possiamo anche ottenere i puntatori di funzione agli operatori definiti dall'utente. Tuttavia, questo non funziona per i tipi built-in poiché tali operatori non sono implementati come funzioni. L'equivalente di prima classe sarebbe il tipo nell'intestazione functional
, ad es. std::plus<T>
o std::logical_not<T>
. Per esempio. per capovolgere un vettore di booleani, potrei std::transform(xs.begin(), xs.end(), xs.begin(), std::logical_not<bool>())
.
Mentre alcuni di questi linguaggi fanno solo una differenza sintattica tra funzioni e operatori, qualsiasi lingua con funzioni di ordine superiore può effettivamente passare gli operatori in giro definendo una funzione additionWrapper(x, y) { return x + y }
, e quindi usando additionWrapper
come sostituto . Questo è l'approccio utilizzato da C ++ quando è necessario utilizzare funzioni di ordine superiore con operatori integrati.
So che le domande dell'elenco sono fuori tema qui e che non dovrei rispondere alle domande fuori tema, ma è così allettante! Quindi, qui ci sono un certo numero di lingue che riesco a pensare fuori dalla mia testa che supportano operatori di prima classe, o almeno qualcosa di simile:
Apricot :
(def plus +)
Arco :
(= plus +)
Clojure :
(def plus +)
(defvar *plus* #'+)
Dylan :
let plus = \+;
Elisir :
plus = &Kernel.+/2
F♯ :
let plus = (+)
GOO :
(def plus +)
Haskell :
let plus = (+)
Io :
plus := Number getSlot("+")
Ioke :
plus = Number Decimal cell(:+)
Julia :
plus = +
Lambra :
(set plus +)
LFE :
(set plus +)
__add
dal metatable, contiene la funzione da chiamare per +
operatore, ecc. . MISC :
plus: +
Newspeak : i metodi non sono oggetti / valori, ma puoi utilizzare il reflection per ottenere un MethodMirror
oggetto (Newspeak utilizza una riflessione stratificata basata su specchi) per un metodo:
plus ::= (platform mirrors ClassMirror reflecting: Integer) reflectee methodDictionary at: #+.
Nu :
(set plus +)
OCaml :
let plus = (+)
Oz :
Plus = Number.'+'
Perl6 :
my $plus = &infix:<+>
Pico :
plus : +
Pike :
mixed plus = '+
Python :
plus = int.__add__
REBOL :
plus: :+
R :
plus <- '+'
Ruby : i metodi non sono oggetti / valori, ma puoi usare il reflection per ottenere una% oggettoUnboundMethod
per un metodo (il metodo public_instance_method
su Module
restituisce un UnboundMethod
per il Symbol
che è stato passato in):
plus = Integer.public_instance_method(:+)
Scheme :
(define plus +)
Seph :
plus = Number Decimal get(:+)
Smalltalk : i metodi non sono oggetti / valori, ma puoi utilizzare il reflection per ottenere un CompiledMethod
oggetto per un metodo (il metodo >>
su Class
restituisce un CompiledMethod
per il Symbol
che è stato passato in):
plus := Number >> #+
ML standard :
val plus = op +
Credo che molti linguaggi funzionali trattino gli operatori in modo diverso rispetto a qualsiasi altra funzione.
Un esempio di tale linguaggio è Haskell, in cui gli operatori sono essenzialmente funzioni e possono essere passati come parametri ad altre funzioni.
Leggi altre domande sui tag programming-languages operators language-features