Non so molto di D, ma molti, molti programmatori di C ++ che conosco non mi piacciono molto, e personalmente devo essere d'accordo: non mi piace l'aspetto di D e non ne prenderò uno più vicino.
Per capire perché D non sta guadagnando più trazione, devi iniziare capendo cosa attira le persone al C ++. In una parola, il motivo numero uno è il controllo. Quando programmi in C ++, hai il controllo completo sul tuo programma. Vuoi sostituire la libreria standard? Puoi. Vuoi eseguire cast di puntatori non sicuri? Puoi. Vuoi violare la correttezza const? Puoi. Vuoi sostituire l'allocatore di memoria? Puoi. Vuoi copiare la memoria grezza senza tener conto del tipo? Se vuoi davvero. Vuoi ereditare da più implementazioni? È il tuo funerale. Diavolo, puoi persino ottenere librerie di raccolta rifiuti, come il collezionista Boehm. Quindi hai problemi come le prestazioni, che seguono da vicino il controllo: più controllo ha un programmatore, più può ottimizzare il suo programma.
Ecco alcune cose che ho visto quando ho fatto una piccola ricerca e ho parlato con un paio di persone che l'hanno provato:
Gerarchia di tipi unificata. Gli utenti C ++ usano l'ereditarietà molto raramente, la maggior parte dei programmatori C ++ preferisce la composizione e i tipi dovrebbero essere collegati tramite ereditarietà solo se c'è una ragione molto valida per farlo. Il concetto di oggetto viola fortemente questo principio collegando ogni tipo. Inoltre, sta violando uno dei principi di base del C ++: usi solo ciò che desideri. Non avere la scelta di ereditare da Object, e i costi che ne derivano, sono fortemente contrari a ciò che C ++ rappresenta come linguaggio in termini di controllo del programmatore sul suo programma.
Ho sentito parlare di problemi con funzioni e delegati. Apparentemente, D ha sia funzioni che delegati come tipi di funzioni richiamabili di runtime, e non sono uguali ma sono intercambiabili o ... qualcosa? Il mio amico ha avuto alcuni problemi con loro. Questo è sicuramente un downgrade dal C ++, che ha appena fatto std::function
e il gioco è fatto.
Quindi hai compatibilità. D non è particolarmente compatibile con C ++. Voglio dire, nessun linguaggio è compatibile con C ++, ammettiamolo, tranne C ++ / CLI che è una specie di imbroglio, ma come barriera all'ingresso, deve essere menzionato.
Quindi, ci sono altre cose. Ad esempio, basta leggere la voce di Wikipedia.
import std.metastrings;
pragma(msg, Format!("7! = %s", fact_7));
pragma(msg, Format!("9! = %s", fact_9));
printf
è una delle funzioni più sicure mai inventate, nella stessa famiglia di grossi problemi come quelli gets
della vecchia libreria C Standard. Se lo cerchi su Stack Overflow, troverai molte, molte domande relative al suo uso improprio. Fondamentalmente, printf
è una violazione di DRY- stai dando il tipo nella stringa di formato e poi lo dai di nuovo quando gli dai un argomento. Una violazione di DRY in cui se si sbaglia, allora accadono cose molto brutte, se si cambia un typedef da un numero intero a 16 bit in uno a 32 bit. Inoltre, non è affatto estensibile, immagina cosa accadrebbe se tutti inventassero i propri identificatori di formato. Gli iostreams del C ++ possono essere lenti e la loro scelta dell'operatore potrebbe non essere la migliore, e la loro interfaccia potrebbe usare il lavoro, ma sono fondamentalmente garantiti per essere sicuri, e DRY non viene violato e possono essere prontamente estesi. Questo non è qualcosa di cui si possa dire printf
.
Nessuna eredità multipla. Questo non è molto il modo C ++. I programmatori C ++ si aspettano di avere il controllo completo sul proprio programma e il linguaggio che impone ciò da cui non è possibile ereditare costituisce una violazione di tale principio. Inoltre, rende l'ereditarietà (ancora più) fragile, perché se si modifica un tipo da un'interfaccia a una classe perché si desidera fornire un'implementazione predefinita o qualcosa del genere, improvvisamente tutto il codice dell'utente viene interrotto. Non è una buona cosa.
Un altro esempio è string
e wstring
. In C ++ è già abbastanza doloroso const char*
doverli convertire tra di loro, e questa libreria supporta Unicode, e questa vecchia libreria C usa solo e deve scrivere versioni diverse della stessa funzione a seconda del tipo di argomento stringa che si desidera. In particolare, le intestazioni di Windows, ad esempio, hanno alcune macro estremamente irritanti per far fronte al problema che spesso può interferire con il tuo codice. L'aggiunta dstring
al mix non farà che peggiorare le cose, poiché ora invece di due tipi di stringa, devi gestirne tre. Avere più di un tipo di stringa aumenterà i problemi di manutenzione e introdurrà un codice ripetitivo relativo alle stringhe.
Scott Meyers scrive:
D è un linguaggio di programmazione creato per aiutare i programmatori ad affrontare le sfide dello sviluppo di software moderno. Lo fa promuovendo moduli interconnessi attraverso interfacce precise, una federazione di paradigmi di programmazione strettamente integrati, isolamento dei thread forzato dal linguaggio, sicurezza di tipo modulare, un modello di memoria efficiente e altro ancora.
L'isolamento del thread forzato dal linguaggio non è un vantaggio. I programmatori C ++ si aspettano il pieno controllo dei loro programmi e il linguaggio che impone qualcosa non è assolutamente quello che il medico ha ordinato.
Parlerò anche della manipolazione di stringhe in fase di compilazione. D ha la capacità di interpretare il codice D in fase di compilazione. Questo non è un vantaggio. Considera gli enormi mal di testa causati dal preprocessore relativamente limitato di C, ben noto a tutti i programmatori veterani C ++, e poi immagina quanto gravemente questa funzionalità verrà abusata. La capacità di creare codice D in fase di compilazione è eccezionale, ma dovrebbe essere semantica , non sintattica.
Inoltre, puoi aspettarti un certo riflesso. D ha la garbage collection, che i programmatori C ++ assoceranno a linguaggi come Java e C # che si oppongono abbastanza direttamente ad esso nelle filosofie, e le somiglianze sintattiche ne faranno pensare anche a loro. Questo non è necessariamente oggettivamente giustificabile, ma è qualcosa che certamente dovrebbe essere notato.
Fondamentalmente, non offre così tanto che i programmatori C ++ non possono già fare. Forse è più facile scrivere un metaprogramma fattoriale in D, ma può già scrivere metaprograms fattoriali in C ++. Forse in D puoi scrivere un ray-tracer in fase di compilazione, ma nessuno vuole farlo comunque. Rispetto alle violazioni fondamentali della filosofia C ++, ciò che puoi fare in D non è particolarmente notevole.
Anche se queste cose sono solo problemi in superficie, allora sono abbastanza sicuro che il fatto che in superficie D non assomigli affatto al C ++ è probabilmente una buona ragione per cui molti programmatori C ++ non stanno migrando verso D. Forse D ha bisogno di fare un lavoro migliore pubblicizzando se stesso.