Perché le espressioni lambda / closures sono arrivate così tardi in C ++?

3

Stavo leggendo un ottimo articolo di Bjarne Stroustrup in cui espone alcuni miti del C ++. Guardo il codice che focalizza la mia attenzione, perché non saprei che C ++ supporta questo tipo di espressioni. Sto parlando di espressioni lambda o chiusure.

void do_my_sort(vector<double>& v)
{
  sort(v,[](double x, double y) { return x>y; });  // sort v in decreasing order
}

Lavoravo con C # e JavaScript per diversi anni, più recentemente con Java e Objective C e trovo questa funzionalità linguistica molto potente e utile. Attualmente sto facendo alcuni lavori in Smalltalk e, nessuna sorpresa ... le chiusure ci sono anche ...

Quindi mi stavo chiedendo, perché questa funzione linguistica è arrivata così tardi in C ++ (2011)?

    
posta Agustin Meriles 23.12.2014 - 21:05
fonte

5 risposte

9

Compilatori deboli, ampio ambito, punti deboli della libreria esistenti e interazioni di libreria potenzialmente negative.

In primo luogo, è stato molto difficile per le implementazioni supportare tutto il C ++ 98, e si sono verificati solo molti anni dopo la spedizione dello standard. Aggiungere ancora più funzionalità avrebbe solo peggiorato la situazione. C # non ha questo problema perché C # 1.0 / 2.0 è molto facile da implementare in confronto. Il fatto è che anche ora gli strumenti C ++ sono molto indietro rispetto agli strumenti per questi altri linguaggi, perché C ++ è una tale puttana da gestire.

In secondo luogo, i lambda C ++ devono occuparsi di molti dettagli aggiuntivi. Ad esempio, la durata degli oggetti catturati è qualcosa che C # / JS non devono prendere in considerazione.

In terzo luogo, dirò che c'erano pochi esempi di API in cui Lambda sarebbe stato veramente utile. Ad esempio, lo STL originale ha fatto molto con gli oggetti funzione. Tuttavia, poiché non è possibile comporre o pigiare gli algoritmi, e gli iteratori fanno schifo, aggiungendo lambdas non sarebbero stati inseriti in LINQ. Affrontare davvero questi problemi e rendere gli algoritmi C ++ alla pari avrebbe richiesto molto più lavoro rispetto ai lambda, molti dei quali ancora non sono stati fatti. Rispetto alla scrittura di iteratori e allocatori personalizzati del tempo, e concatenando insieme algoritmi sul posto in contenitori a mano, l'uso di un struct struct non locale non era poi così male.

Infine, non è chiaro se le tecniche di libreria come i modelli di espressioni possano completamente ovviare alla necessità di una funzionalità linguistica. Si scopre che non possono, ma ci sono altre funzionalità linguistiche (non-placement new , delete e le loro versioni di array, matrici native) che ora non sono solo completamente ridondanti in C ++ 11, ma che prendono seriamente in considerazione dannoso. Ripetere questi errori è indesiderabile. È meglio fare ricorso a funzionalità linguistiche solo se sai che una libreria non può gestirle.

    
risposta data 24.12.2014 - 00:13
fonte
16

C ++ aveva oggetti funzione dal 1983 in poi; hanno preso / si prende cura di molti esempi in cui le persone ora usano lambda (e usano lambda in altre lingue). In effetti, un lambda C ++ è probabilmente meglio compreso come notazione semplificata per definire e utilizzare immediatamente un oggetto funzione.

    
risposta data 24.12.2014 - 15:17
fonte
5

Ciò che una chiusura fa, in sostanza, è astratta nel corso della vita delle variabili.

Gestione della memoria manuale OTOH, richiede al programmatore di essere consapevole della durata delle variabili. Ma come puoi essere consapevole di qualcosa che è astratto da te?

Le chiusure sono fondamentalmente incompatibili con la gestione manuale della memoria. La riconciliazione tra i due è molto difficile, e la comunità C ++ ha fatto il miglior lavoro possibile, ma in realtà è possibile ancora ottenere errori (o forse anche UB? non conosco il C ++.) usando chiusure che catturano variabili che vengono poi liberate.

O, in altre parole: le chiusure estendono l'ambito dinamico delle variabili oltre il loro ambito lessicale, ma il fatto che lo scope dinamico e lo scope lessicale siano identici è la base fondamentale degli idiomi C ++ come RAII.

C ++ è stato AFAIK la prima lingua con gestione manuale della memoria a fare chiusure, quindi stavano facendo ricerche originali e la ricerca originale richiede tempo. Questo è il motivo principale per cui ci è voluto così tanto tempo. Stavano facendo questa ricerca in un comitato, che è il posto peggiore dove fare ricerca, che probabilmente ha prolungato ancora di più il processo, ma il motivo principale è che stavano facendo ricerche originali dure , non che loro stavano facendo così in un comitato.

    
risposta data 24.12.2014 - 01:36
fonte
3

Il C ++ non aveva uno standard ISO fino a dopo la sua creazione. Gran parte della sua vita iniziale era frammentata, con i compilatori che lavoravano in modo diverso al punto di essere a volte incompatibili con la fonte.

Il primo standard C ++ era C ++ 98, con aggiornamenti relativamente minori nello standard C ++ 03. L'obiettivo principale di questi standard era quello di prendere il "selvaggio west" del C ++ e portargli una parvenza di ordine. Una volta che la polvere si è risolta e gli sviluppatori hanno superato le modifiche, il comitato C ++ si concentrerà sulle nuove funzionalità.

Dallo stesso Bjarne Stroustrup (alcune parentesi vengono rimosse per brevità), Il linguaggio di programmazione C ++ (4a edizione) , sezione 1.4 .4 "Lo standard del 2011":

The current C++, C++11, known for years as C++0x, is the work of the members of WG21. The committee worked under increasingly onerous self-imposed processes and procedures. These processes probably led to a better (and more rigorous) specification, but they also limited innovation. An initial draft standard for public review was produced in 2009. The second ISO C++ standard was ratified by a 21-0 national vote in August 2011.

One reason for the long gap between the two standards is that most members of the committee (including me) were under the mistaken impression that the ISO rules required a "waiting period" after a standard was issued before working on new features. Consequently, serious work on new language features did not start until 2002.

Il C ++ non fu nemmeno standardizzato fino al 1998, e i prossimi anni furono impiegati per correggere gli errori nello standard (nuovo) esistente. Quindi il comitato si è seduto sulle sue mani per un paio di anni a causa di problemi procedurali che probabilmente non sarebbero stati necessari. Ci sono voluti sette anni dall'avvio iniziale a un documento pubblico, con molte discussioni e modifiche lungo la strada. Anche allora, ci sono voluti altri due anni prima che il documento fosse nella posizione di essere votato e ratificato.

Ciò significa che l'aggiunta di lambda e altre funzionalità linguistiche ha dovuto attendere la stabilizzazione dello status quo (1998/2003), quindi la politica e le procedure del processo hanno trascinato l'aggiunta di nuove funzionalità molto più a lungo di quanto fosse probabilmente necessario a (2011).

Un altro motivo per la mancanza di urgenza è che i functors possono fare quasi tutto ciò che un lambda può fare, sono solo più verbose. La lingua nel suo complesso non mancava molto oltre alla brevità dei lambda e alla loro capacità di legarsi a variabili locali. Tuttavia, anche questo può essere per lo più risolto aggirando i riferimenti nel functor.

    
risposta data 24.12.2014 - 01:12
fonte
-1

Qual è la differenza tra un funtore e un lambda? Il modo in cui il codice che scrivi sembra!

Un lambda è solo un funtore scritto in linea in modo da evitare un po 'di scia di piastra noiosa (sostituendolo con meno piastra di riscaldamento). Quindi, chiedendo perché C ++ non ha questa caratteristica manca il punto di ciò che è realmente la funzionalità. Quali funzionalità extra ottieni da un lamdba che non hai ricevuto da un functor?

Quindi, a parte una sintassi per le scorciatoie, non c'è nulla di nuovo da vedere qui. (e ricorda che la sintassi abbreviata è sbagliata, dai un'occhiata a qualche volta a perl e dimmi che accorciare le caratteristiche del linguaggio in modo che siano facili e veloci da digitare è una buona cosa :-))

    
risposta data 24.12.2014 - 15:33
fonte

Leggi altre domande sui tag