Ragioni per la rimozione dei tipi di funzione in Java 8

12

Ho cercato di capire perché il JDK 8 Lambda Expert Group (EG) ha deciso di non includere un nuovo tipo di funzione nel linguaggio di programmazione Java.

Passando sopra la mailing list ho trovato una discussione con la discussione sulla rimozione di tipi di funzioni .

Molte delle affermazioni sono ambigue per me, forse a causa della mancanza di contesto e, in alcuni casi, a causa delle mie conoscenze limitate sull'implementazione dei sistemi di tipi.

Tuttavia, ci sono un paio di domande che credo di poter formulare in modo sicuro in questo sito per aiutarmi a capire meglio che cosa intendessero.

So che potrei fare le domande nella mailing list, ma il thread è vecchio e tutte le decisioni sono già state fatte, quindi è probabile che verrò ignorato, soprattutto vedendo che questi ragazzi sono già in ritardo con i loro piani.

Nella sua risposta per supportare la rimozione dei tipi di funzione e approvare l'uso dei tipi SAM, Brian Goetz dice:

No reification. There was a long thread about how useful it would be for function types to be reified. Without reification, function types are hobbled.

Non sono riuscito a trovare il thread che menziona. Ora, posso capire che l'introduzione di un tipo di funzione strutturale può comportare alcune complicazioni nel sistema di tipo prevalentemente nominale di Java, ciò che non riesco a capire è come i tipi di SAM parametrizzati sono diversi in termini di reificazione.

Non sono entrambi soggetti agli stessi problemi di reificazione? Qualcuno capisce in che modo i tipi di funzione sono diversi dai tipi SAM parametrizzati in termini di reificazione?

In un altro commento Goetz dice:

There are two basic approaches to typing: nominal and structural. The identity of a nominal is based on its name; the identity of a structural type is based on what it is composed of (such as "tuple of int, int" or "function from int to float".) Most languages pick mostly nominal or mostly structural; there are not a lot of languages that successfully mix nominal and structural typing except "around the edges." Java is almost entirely nominal (with a few exceptions: arrays are a structural type, but at the bottom there is always a nominal element type; generics have a mix of nominal and structural too, and this is in fact part of the source of many of people's complaints about generics.) Grafting a structural type system (function types) onto Java's nominal type system means new complexity and edge cases. Is the benefit of function types worth this?

Quelli con esperienza nell'implementazione dei sistemi di tipi. Conoscete qualche esempio di queste complessità o casi limite che menziona qui?

Onestamente mi sento confuso da queste affermazioni quando considero che un linguaggio di programmazione come Scala, che è interamente basato sulla JVM, ha il supporto per tipi strutturali come funzioni e tuple, anche con i problemi di reificazione della piattaforma sottostante.

Non fraintendermi, non sto dicendo che un tipo di funzione dovrebbe essere migliore dei tipi SAM. Voglio solo capire perché hanno preso questa decisione.

    
posta edalorzo 11.01.2013 - 18:19
fonte

1 risposta

5

L'approccio SAM è in qualche modo simile a quello che Scala (e C ++ 11) fanno con le funzioni anonime (creato con l'operatore => di Scala o la sintassi []() (lambda) di C ++ 11).

La prima domanda a cui rispondere sul lato Java è se il tipo di ritorno di un'istruzione lambda sia un nuovo tipo di primitve, come int o byte , o un tipo di oggetto di qualche tipo. In Scala, ci sono non tipi primitivi - anche un intero è un oggetto di classe Int - e le funzioni non sono diverse, essendo oggetti di classe Function1 , Function2 , e così avanti, a seconda del numero di argomenti che la funzione richiede.

C ++ 11, ruby e python hanno analoghe espressioni lambda che restituiscono un oggetto che può essere richiamato in modo esplicito o implicito. L'oggetto restituito ha un metodo standard (come #call che può essere usato per chiamarlo come funzione. C ++ 11, per esempio, usa un tipo std::function che sovraccarica operator() in modo che le chiamate della chiamata dell'oggetto metodo anche guarda come le chiamate di funzione, testualmente.: -)

Dove la nuova proposta di Java diventa complicata sta nell'uso della tipizzazione strutturale per consentire l'assegnazione di un tale metodo a un altro oggetto, come un Comparator che ha un singolo metodo principale con un nome diverso . Mentre questo è concettualmente infido in qualche modo, fa significa che l'oggetto risultante può essere passato a funzioni esistenti che accettano un oggetto per rappresentare un callback, un comparatore e così via, e si aspettano di essere in grado chiamare un singolo metodo ben definito come #compare o #callback . Il trucco di C ++ di sovrascrivere operator() ha evitato accuratamente questo problema anche prima di C ++ 11, poiché tutte le opzioni di callback erano richiamabili nello stesso modo, e quindi l'STL non richiedeva alcun aggiustamento per consentire l'utilizzo di lambda C ++ 11 con sort e così via. Java, non avendo usato una denominazione standard per tali oggetti in passato (forse perché nessun trucco come l'overloading dell'operatore ha reso evidente un singolo approccio), non è così fortunato, quindi questo hack impedisce loro di dover cambiare un sacco di API esistenti .

    
risposta data 15.01.2013 - 20:33
fonte

Leggi altre domande sui tag