Quali linguaggi di programmazione supportano gli operatori come cittadini di prima classe? [chiuso]

1

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.

    
posta Jordan Mack 12.05.2016 - 08:50
fonte

3 risposte

12

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.

    
risposta data 12.05.2016 - 10:11
fonte
6

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 +)
    
  • Common Lisp :

    (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 +)
    
  • Lua : ottieni l'attributo __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 +
    
risposta data 13.05.2016 - 01:09
fonte
2

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.

    
risposta data 12.05.2016 - 09:15
fonte

Leggi altre domande sui tag