İngilizce Kaynaklar


Diğer




D Diline Genel Bakış

Not: Bu bir D1 karşılaştırmasıdır. Modern D'nin başka farklılıkları da var.

Bu bölümde D'nin ilginç ve önemli olanaklarından bazılarını bulabilirsiniz. Bu listenin kaynağı Digital Mars'ın sitesindeki D tanıtım sayfasıdır.

Sınıflar

D'de nesne yönelimli programlamanın temelini sınıflar oluşturuyor. Bu konuda C++'dan oldukça köklü farkları var: Arayüz [interface] türetirken çoklu kalıtım, ama gerçekleştirme [implementation] türetirken tekli kalıtım... Bütün sıradüzenin en tepesinde Object temel arayüzü bulunuyor. Nesneler C ve C++'nın tersine referans olarak oluşturuluyorlar.

İşleç yükleme [operator overloading]

İşleç yükleme konusunda aslında bir fark yok: Başka nesne yönelimli dillerde olduğu gibi D'de de işleçler her tür için özel olarak tanımlanabiliyor.

Modüller

Her kaynak dosya, içerisinde bulunduğu klasöre göre bir modülün parçası olarak kabul ediliyor. Bildirimleri derleyiciye tanıtmak için #include etmek yerine, modüller import ediliyorlar. Böylelikle ne başlık dosyalarına gerek kalıyor ne de programcılığın özüyle ilgisi olmayan #ifndef ve #pragma once gibi çözümlere...

Bildirimler gereksiz

C'de ve C++'da anahtar kelimeler dışındaki bütün isimlerin önceden bildirilmiş olmaları gerekir. printf bile <stdio.h> başlığı eklenmeden kullanılamaz. (Aslında bazı derleyiciler buna izin verirler ama standart değildir.) Bu yüzden programcılar sürekli olarak .h başlık dosyaları ile .c kod dosyalarını uyumlu tutmaya çabalarlar. Bu hem hataya açık hem de gereksiz bir külfettir. D'de ise bu iş derleyicinin görevidir:

import std.stdio;

void main()
{
    ismi_henüz_görülmemiş_bir_fonksiyon();
}

void ismi_henüz_görülmemiş_bir_fonksiyon()
{
    auto nesne = new İsmiHenüzGörülmemişBirSınıf;
    nesne.selam_ver();
}

class İsmiHenüzGörülmemişBirSınıf
{
    void selam_ver()
    {
        writeln("Merhaba!");
    }
}
Şablonlar [templates]

Ne kadar güçlü olsalar da; C++'nın şablonları hem büyük uzmanlık gerektirir, hem de kullanımları bazı durumlarda çok sorunludur. C++ şablonlarının en büyük uzmanlarından birisi Andrei Alexandrescu'dur. Kendisi şablonlarla tasarımlarının ötesinde işler becermiş ve bunları Modern C++ Design kitabında tanıttığı Loki kütüphanesinde göstermiştir. C++'da gördüğü eksiklikleri D'ye taşımış ve şablonları D'de çok daha kullanışlı bir hale getirmiştir.

Çağrışımlı diziler [associative arrays]

Başka dillerde de bulunan ve C++'da std::map ile sunulan çağrışımlı diziler D'de dilin iç olanaklarına dahil ve hızlı eşleme tablosu [hash table] olarak gerçekleştirilmişler.

Gerçek anlamda typedef'ler

C'de ve C++'da typedef yeni tür oluşturmaz, olan bir türe daha kullanışlı bir isim verir. D'de ise yeni bir tür oluşur. Sonuçta,

typedef int ÖğrenciNumarası;

ile oluşturulan ÖğrenciNumarası türü ile onun temel aldığı int farklıdırlar. Örneğin fonksiyonlar bu türler için ayrı ayrı yüklenebilirler:

int yazdır(int sayı);
int yazdır(ÖğrenciNumarası öğrenci);
Belgeleme

Kaynak kodlar geleneksel olarak; JavaDoc, Doxygen, vs. gibi araçlarla açıklama satırlarında belgelenir. Örneğin fonksiyon parametrelerinin ve dönüş değerlerinin ne anlama geldikleri ve nasıl kullanıldıkları, fonksiyonların başlarındaki /** ve */ ile belirlenen açıklama bölümlerine yazılırlar. D'de belgeleme işi de derleyicinin görevidir; ayrıca program kullanmaya gerek yoktur. Dahası, belgeleme salt kod ile sınırlı değildir; okumakta olduğunuz bu sayfalar bile Ddoc ile oluşturulmuşlardır.

Kapsam fonksiyonları

Fonksiyonlar başka fonksiyonların içinde tanımlanabilirler.

Fonksiyon sabitleri [function literals]

Fonksiyonlar kullanıldıkları ifadeler içinde isimsiz olarak tanımlanabilirler. [Not: Fonksiyonlar zaten sabit oldukları halde burada literalstring literal'a benzeterek sabit olarak çeviriyorum.]

// Burada üçüncü parametre bir fonksiyon sabiti
foo(3, 10, (int sayı){ return sayı * sayı; } );

// Parametre almayan bir fonksiyon sabiti
bar(3, 10, { return 5; } );
Kapamalar [closures]

Kapsam fonksiyonlarına ve sınıf üye fonksiyonlarına kapama ([delegate] de denir) olarak referans verebiliriz. Bu özellik türden bağımsız programlamayı kolaylaştırır ve daha güvenli hale getirir.

Parametre türleri

Parametreler kullanımlarına göre açıkça giriş, çıkış, veya giriş-çıkış olarak belirtilebilirler. C++'da parametrelerin kullanımları biraz anlaşmaya bağlıdır: giriş parametreleri değer olarak veya const referans olarak geçirilirler; çıkış ve giriş-çıkış parametreleri ise işaretçi veya referans olarak geçirilirler. Bu konu D'de açıktır.

Diziler

C dizilerinin C++'ya da taşınmış olan bir çok sorunu vardır:

D, dizilerin bu sorunlarını çözer.

Dizgiler [strings]

Dizgiler programlama dilinden tam destek almayı gerektirecek kadar yaygın ve yararlı veri yapılarıdır. Modern dillerde olduğu gibi D'de de dizgiler C ve C++'dan farklı olarak doğrudan destek görürler.

Otomatik bellek yönetimi

D'de bellek yönetimi çöp toplamalıdır [garbage collected]. Bellek yönetimi konusundaki gözlemler, çöp toplama olanağının program geliştirmeyi çok çabuklaştırdığını ve çok daha kolaylaştırdığını gösteriyor. Ortaya çıkan program da çoğu durumda daha hızlı çalışıyor.

Elle bellek yönetimi

D çöp toplamalı olsa da, new ve delete işleçleri her sınıf için ayrı olarak yüklenebilir.

RAII

Resource Acquisition Is Initialization'ın kısaltması olan RAII, kaynakların bozucu fonksiyonlarda geri verilmesi yöntemidir. Hata atılan durumlarda bile kaynak sızıntılarını önler. D RAII'yi çöp toplamadan ayrı olarak ve ona ek olarak destekler.

Etkin yapılar

C'deki struct gibi alt düzey yapılar D'de de desteklenir. Bunlar hem C fonksiyonlarıyla etkileşmek için, hem de etkin veri yapıları oluşturmak için yararlıdırlar.

Makine dili [assembly]

C'de ve C++'da olduğu gibi, D'de de gereken özel durumlarda doğrudan makine dilinde kod yazılabilir.

Sözleşmeli programlama [contract programming]

Eiffel dilinin yaratıcısı Bertrand Meyer tarafından icat edilen sözleşmeli programlama, kodun doğruluğunu sağlama konusunda çok güçlü bir yöntemdir. Sözleşmeli programlama D'de fonksiyon giriş ve çıkış koşulları [precondition ve postcondition], sınıf değişmezleri, ve assert'lerden oluşur.

Örneğin alan_ üyesinin değerinin her zaman için sıfırdan büyük olması beklenen bir Üçgen sınıfında bu değişmezlik kavramı invariant sözcüğü ile şöyle ifade edilebilir:

class Üçgen
{
    double alan_;
    /* ... */

    invariant()
    {
        /* Üçgen'in her üye fonksiyonunun her işletilişinden
         * sonra bu koşul denetlenecektir.  */
        assert(alan_ > 0.0);
    }
}
Birim testleri [unit tests]

Birim testleri başka dillerde dilin dışında düzeneklerle halledilirler. Örneğin C++ için CppUnit, unittest++, vs. gibi bir birim test düzeneği genellikle make veya benzeri oluşturma sisteminin parçası olacak şekilde ayarlanırlar ve asıl programın dışında olarak çalıştırılırlar.

D birim testleri biraz daha ileri götürmüş ve dil olanağı haline getirmiştir. Testler örneğin sınıflara eklenirler, ve istenirse program başlamadan önce otomatik olarak çalıştırılırlar. Böylece sınıfların değişmezlik koşullarındaki tutarsızlıklar birim testleri tarafından en kısa sürede farkedilmiş olurlar.

Hata ayıklama [debug] olanakları

D'de hata ayıklama olanakları dilin parçasıdır. Hata ayıklayıcı kodlar makrolara gerek bırakmadan, derleyici düzeyinde etkin hale getirilebilirler. Böylece programın hem hata ayıklama sürümü [debug], hem de asıl sürümü [release] aynı kod tarafından oluşturulabilir.

Hata atma [exceptions]

D, try-catch'den daha yararlı olduğu görülen try-catch-finally modelini kullanır. Böylece küçük kaynak temizlikleri için bile C++'da olduğu gibi ayrıca sınıf yazmak gerekmemiş olur.

Çoklu iş parçacıkları [multi-threads]

D bu konuya dil düzeyinde çözüm getirir. Sınıf ve fonksiyon düzeyinde koruma sağlar. Örneğin synchronized olarak belirtilen fonksiyonların tek bir anda yalnızca tek bir iş parçacığı tarafından işletilmeleri dil tarafından sağlanır.

synchronized int fonksiyon()
{
    /* Bu kod belirli bir anda tek bir iş parçacığı
     * tarafından işletilir */
}
Sağlam kodlama yöntemleri

D, kod doğruluğunu ve güvenliğini arttıran bazı olanaklar getirir:

Derleme zamanı denetimleri
Çalışma zamanı denetimleri
İşleç öncelikleri

Bu konudaki sürprizleri ve hataları engellemek için D C'deki işleç önceliklerini kullanır.

C fonksiyonlarına doğrudan destek

D'ni C'ninkilere bire bir karşılık gelen veri yapıları da destekleridiği için, C kütüphane fonksiyonları hiçbir dönüşüm gerekmeden doğrudan çağrılabilirler.

Bütün C türlerine destek

C'deki struct'lar, union'lar, enum'lar, işaretçiler, C99'un getirdiği bütün türler desteklenir. Hatta struct üyelerinin bellek sıralanma düzenleri [alignment] bile belirlenebilir.

İşletim sistemi hataları

D'nin hata yakalama düzeneği işletim sistemi tarafından atılan hatalarla da uyumludur.

Araç programlarla uyumluluk

D standart program parçası [object file] formatında kod üretir. Bu sayede; hata ayıklayıcı, bağlayıcı, vs. mevcut araç programların D programları ile kullanılmaları da sağlanmış olur.

Kod sürümleri

D, bir program kodundan birden fazla sürüm üretilmesine destek verir. Böylelikle #if/#endif gibi yöntemlere gerek kalmamış olur.

Emekliye ayrılan kod

Çeşitli nedenlerle artık kullanılmaması gereken kodlar eski oldukları şeklinde işaretlenebilirler ve böylece yeni kodlarda kullanılmaları önlenebilir ama gerekirse eski programlarda kullanılmalarına izin verilebilir.