Nel caso di Java, è perché volevano che fosse eseguito su molte architetture diverse (ricorda che le sue radici erano per un sistema embedded). In base a ciò, hanno pensato che sarebbe stato meglio fornire un livello intermedio (la VM) in modo che il codice java potesse essere scritto per il livello, quindi non sarebbe necessario fornire implementazioni diverse per ciascuna piattaforma. Invece il layer verrebbe costruito per ogni piattaforma.
Quando Microsoft ha iniziato a creare .NET, la sua era così strongmente progettata per essere Java (in effetti utilizzava gran parte del vecchio codice J ++ che avevano già, e il capo progettista era il tipo che ha lavorato alla loro implementazione Java) quindi comprensibile hanno mantenuto il più piccolo possibile al fine di produrre qualcosa di più veloce. Penso che abbiano anche ipotizzato che avrebbero potuto fare più ottimizzazioni nel JIT in fase di runtime, quindi non sarebbe stato molto più lento.
Perché non hanno un compilatore nativo per ora è discutibile. Probabilmente hanno deciso che non è necessario, il codice .NET ha semplicemente la VM installata insieme alla libreria di runtime, quindi far sì che generi codice "puro" nativo sarebbe una perdita di tempo per loro.
Confronta questo con Mono che però genera codice nativo.
Penso che i ragazzi che hanno creato D and Go non volessero limitarsi a usare la tecnologia Microsoft (comprensibile), e forse solo perché a loro piace creare un nuovo linguaggio (ci sono già abbastanza lingue, ne sono appena 2 nuove! !).