D (ohjelmointikieli)

D on Walter Brightin kehittämä moniparadigmainen oliopohjainen imperatiivinen ohjelmointikieli. Se on kehitetty C/C++:n pohjalta ja siinä on uudistettu monia C++:n ominaisuuksia. Lisäksi hyödyllisiksi havaittuja ominaisuuksia on lainattu muista kielistä.
Ominaisuudet.
D:n suunnittelussa on otettu huomioon C++:n käytössä vuosien aikana kertyneitä kokemuksia. D käyttää monia C++:n konsepteja ja laajentaa toiminnallisuutta toteuttamalla kielen tasolla tuottavuutta lisääviä ominaisuuksia, joita ovat esimerkiksi sopimuspohjainen ohjelmointi, yksikkötestaus, aidot ohjelmamoduulit, roskienkeruu, ensimmäisen luokan oliot, kehittyneet taulukko- ja assosiatiivinen taulukko-tietotyypit, sisäluokat ja -funktiot, sulkeumat ja uudelleen suunniteltu geneerinen ohjelmointi. D mahdollistaa C++:n lailla matalan tason ohjelmoinnin, jossa apuna voidaan käyttää kääntäjän assembleria. C++:n moniperintä on korvattu tavallisella yksinkertaisella perinnällä, rajapinnoilla ja mixineillä. D:n esittelyt, lauseet ja lausekkeet muistuttavat läheisesti C++:n vastaavia.
Yhteensopivuus muiden järjestelmien kanssa.
D tukee täydellisesti C-kielen ABI-rajapintaa (Application Binary Interface) sekä C:n tietotyyppejä ja mahdollistaa näin suoran pääsyn C-kieliseen ohjelmakoodiin ja kirjastoihin. C:n standardikirjasto on osa standardia D-kieltä. Koska D ei vielä ole standardoitu, tarkoitetaan tällä Digital Marsin referenssi-implementaatiota ja -spesifikaatiota.
C++:n ABI ei ole tuettu, mutta D-kielestä voidaan kutsua C-kielen ABI:n kautta C++-koodia, joka on kääritty C-kielisiin funktioihin. D kuitenkin tukee täysin C++-kielistä COM (Component Object Model) koodia.
Toteutukset.
Nykyiset D:n toteutukset kääntävät ohjelmat suoraan natiivikoodiksi. Tällä hetkellä merkittävimmät kääntäjät D:lle ovat Digital Marsin DMD sekä vapaa GDC.
DMD:n etuosa (selaaja, jäsennin) on julkaistu GNU GPL:n ja Artistic License:n alla. Toteutuksen tekijänoikeudet omistaa pääosin Digital Mars, muilta osin koodi on joko public domainia tai muun yhteensopivan vapaan lisenssin alla. Kääntäjä perustuu viralliseen D-spesifikaatioon, mutta on suljettua lähdekoodia ja tukee ainoastaan Windows- ja Linux/x86-alustoja.
Toinen merkittävä D-kääntäjä, GDC, yhdistää DMD:n etuosan GCC:tä käyttävään takaosaan. GDC toimii teoriassa kaikilla alustoilla, joilla GCC:kin, ja on lisäksi julkaistu vapaan GNU GPL -lisenssin alla. GDC on käytännön syistä ajoittain spesifikaation osalta jäljessä virallista kääntäjää. Linux-jakeluista ainakin Debian, Gentoo ja Ubuntu tarjoavat kääntäjää paketinhallintansa kautta.
D on yhä aktiivisen kehitystyön alla ja sen kääntäjistä julkaistaan säännöllisesti uusia versioita. Kääntäjän 1.0-haaraan ilmestyy lähinnä bugikorjauksia, mutta 2.0-haaraan myös epävakaita uusia toimintoja. Ehkä merkittävin muutos 2.0-versiossa on C++-kielen const-järjestelmän vastine. D 2.0 sisältänee ilmestyessään myös monia muita uusia ominaisuuksia, kuten aidot sulkeumat, paremman muistimallin monisäikeiselle ohjelmoinnille, suurehkon päivityksen standardikirjastoon ja monia pienempiä korjauksia.
Esimerkkejä.
Hei maailma.
Tämä esimerkki kirjoittaa ruudulle sanat "Hei maailma!" ja sen jälkeen komentorivin argumentit.
Jokaisen D-ohjelman suorittaminen alkaa main funktiosta, ja args
on merkkijonojen taulukko, jossa komentorivin argumentit ovat. Argumentit ovat valinnaisia.
Merkkijonoa kuvataan D:ssä tyypillä string. D 1.x:ssä string on alias merkkijonojen taulukolle(char[]), mutta 2.x estää merkkijonon muokkaamisen. Useiden merkkijonojen taulukko on vastaavasti string[].
import std.stdio; // tuo writefln()
int main(string[] args)
 writefln("Hei maailma!");
 foreach(indeksi, arvo; args)
 writefln("args[%d] = '%s'", indeksi, arvo);
 return 0;
foreach-lauseella voidaan käydä läpi mikä tahansa kokoelma. Vakiotietotyypit tarjoavat oletustoiminnallisuuden, mutta iterointi voidaan tarvittaessa erikoistaa määritellyissä luokissa. Lause päättelee indeksin ja arvon tyypit automaattisesti, mutta ne voidaan myös ilmoittaa.
Hajautustaulukot.
Esimerkki havainnollistaa hajautustaulujen käyttöä monimutkaisen tietorakenteen rakentamisessa.
import std.stdio; // tuo write[f]ln()
int main(string[] args)
 // Määritellään hajautustaulu, jossa arvoina on taulukoita merkkijonoista ja
 // avaimena merkkijono
 string[] [string] säiliö;
 // Lisätään säiliöön henkilöitä ja heille esineitä
 säiliö["Tuomikki"] ~= "puukko";
 säiliö["Airikka"] ~= "löylykauha";
 säiliö["Tuomikki"] ~= "puhelin";
 // Käydään läpi säiliön henkilöt
 foreach (string henkilö, string[] esineet; säiliö)
 kerro_montako_esinettä(henkilö, esineet);
 return 0; // ohjelma onnistui
void kerro_montako_esinettä(string henkilö, string[] esineet)
 writeln(henkilö, " kantaa ", esineet.length, " esinettä.");