Forum: D Programlama Dili RSS
Çalışma zamanı çok şekilliliği ve derleme zamanı çok şekilliliği
acehreli (Moderatör) #1
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Çalışma zamanı çok şekilliliği ve derleme zamanı çok şekilliliği
Kusura bakmayın; çok hızlı ve karmaşık yazdım. :/

Geçende Mengü'yle şablonların gerekliliği konusunda bir şeyler konuşmuştuk.

Ben şablonların "Derleme zamanı çok şekilliliği" özelliklerine "Ayrıntılı Şablonlar" dersinde değinmiştim: http://ddili.org/ders/d/sablonlar_ayrintili.html

Walter Bright da geçende arayüzlerle şablonların kısa bir karşılaştırmasını verdi:

  http://www.digitalmars.com/webnews/newsgroups.…?art_grou…

Oradan biraz genişleterek ve anladığım şekilde aktarıyorum:

Arayüzler çalışma zamanı çok şekilliliği olanaklarıdır. Özellikle şu konularda kullanışlıdırlar:

1. çalışma zamanında davranış değişiklikleri. Örneğin PiştiOyuncusu sınıfının Taktik diye bir arayüz türünden bir üyesi bulunabilir.

Bu üyenin gösterdiği asıl nesne, örneğin en başta ValeyleHemenAlmaTaktiği olabilir. Sonra, çalışma zamanında, bilgisayarın karşısındaki insan oyuncunun ne kadar akıllı oynadığına bağlı olarak, taktik değiştirilebilir:

taktik = new ValeyiPiştiOlasılığıİçinSaklayanTaktik;

Yani, arayüzün arkasındaki asıl nesne çalışma zamanında değişebilir.

2. Gerçekleştirme gizlemesi: arayüzler, asıl nesnenin her zaman için gizli kalmasını da sağlayabilir. Yazdığımız kütüphane her zaman için Arşiv isminde bir arayüz sunabilir. Asıl arşiv nesnesinin ne olduğunu kütüphanenin kullanıcıların bilmeleri hiç gerekmez. Kütüphanenin bir sonraki sürümünde bambaşka bir arşivleme gerçekleştirmesi kullanılabilir ve kütüphaneden yararlanan kodların bundan haberleri bile olmaz.

3. arayüz kullanan kodlar binary kütüphaneler haline getirilebilirler (paylaşımlı (shared, yani .so veya .dll) veya statik (static, yani .a veya .lib) olarak) Çünkü, arayüz kullanan işlevden yalnızca bir tane derlenir, kütüphanenin içine yerleşir ve bütün programlar onunla bağlanabilir.

4. Çalışma zamanı çok şekilliliği Java/C# türü kodlamayı desteklerler. Yanılmıyorsam, Mengü'nün şablonlara gereğini sorgulaması bu tür programlama nedeniyleydi.

Çünkü örneğin kendisini dizgi olarak sunması beklenen bir sınıfın o işlevi sunan bir arayüzden, örneğin Object'ten türemesi şart koşulabilir. Object'ten kalıtımla edinilen toString'in o tür için tanımlaması, nesnelerin dizgi olarak ifadeleri için yeterlidir.

5. Çalışma zamanı çok şekilliliğinde programın derlenmiş hali daha küçük olur. Çünkü arayüz kullanan işlevden yalnızca bir tane derlenir.

6. Kullanıcı arayüzleri için, örneğin görsel programlama için son derece uygun programlama araçlarıdır.


Derleme zamanı çok şekilliliği, şablonlar tarafından sağlanır:

1. Şablon, her şablon parametre kullanımı için farklı olarak üretilir ve derlenir. Örneğin parantezliYazdır!int ve parantezliYazdır!long kullanımları için parantezliYazdır şablonundan int ve long için iki tane üretilir ve derlenir. Bin tür kullanılsa, bin tane... :)

Ama o yüzden de işlevler çok hızlı olurlar. Çünkü arayüz kullanımında; farklı alt sınıfların farklı davranışları, işlev göstergeleri yoluyla sağlanmak zorundadır. Çalışma zamanı çok şekilliliğinde, nesnenin her üye işlevi için bir veya iki gösterge üzerinde ilerlemek gerekir.

2. Veriler için daha az yer kullanılır: Çalışma zamanı çok şekilliliğinde farklı türlerden nesnelerin farklı davranışları, geleneksel olarak vtable denen sanal işlev tabloları ile sağlanır. Her nesnenin en az bir adet böyle bir göstergesi vardır.

Derleme zamanı çok şekilliliğinde ise yapılar veya temel türler bile kullanılabilir. Öyle bir vtable göstergesi gerekmez. Bu açıdan, veri türlerinin uzunlukları ancak gerektiği kadar, olabildiğince küçük olur.

3. Şablonlar kodun daha güçlü olarak denetlenmesine olanak sağlarlar. Her şeyin derleme zamanında hallediliyor olması, derleme hataları ve uyarıları için daha çok fırsat verir.

Arayüzlerde ise, arayüzden türeyen her sınıf kullanılabildiği için, hangi sınıfın nesnesinin kullanıldığı çalışma zamanına kalmak zorundadır. O yüzden bazı alt sınıfların olası hataları ancak çalışma zamanında farkedilebilir.

Ali
acehreli (Moderatör) #2
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Digital Mars forumlarında arada bir Google Go dili ile ilgili konular açılıyor.

Birisi Go üzerine bir konuşmanın bağlantısını verdi ve "belki de Andrei yanılıyordur; belki de şablonları gerektirmeyen iyi ve esnek diller de tasarlanabiliyordur" dedi.

Alexandrescu, aynı tartışma içinde, Go'cuların dili tanıtırken dürüst olmadıklarını ve hep güzel taraflarını gösterdiklerini söyledi. Daha sonra, D'yi kendi kitabında dengeli olarak tanıttığını gösteren iki alıntı yaptı.

Birincisini aşağıdaki gibi çeviriyorum; ikincisini sonra vereceğim:

Çok az kitap çalışma zamanı çok şekilliliğini dengeli olarak tanıtır. Bazı kitaplar iyi taraflarını gösterirler, başka kitaplar iyi olmayan taraflarını... Ben The D Programming Language kitabımda bütün taraflarını göstermeye çalıştım:

====================
Sınıfların D'de referans türleri olmaları, nesne yönelimli olan başka bir çok dildekine benzer. Sınıf nesnelerinin referans türleri olmalarına ek olarak çöp toplayıcının bulunmasının hem iyi hem de kötü tarafları vardır. Bazıları şunlardır:

- Çok şekillilik: Referanslara bağlı kalınan programlamanın getirdiği dolaylama (indirection), çok şekilliliğe olanak sağlar. Türeme sonucunda aynı türden kabul edilmelerine rağmen nesneler farklı uzunlukta olabilirler; ama bütün referanslar aynı uzunluktadır. Erişim sağladıkları nesnelerin uzunluklarından bağımsız olarak referansların hep aynı uzunlukta olmaları, alt sınıf nesnelerinin üst sınıf nesneleri yerine kullanılabilmelerine olanak sağlar. Ayrıca, farklı türlerden olan nesnelerden oluşan diziler kullanılabilir. Eğer C++ kullanmışsanız, çok şekillilik için gösterge kullanılması gerektiğini ve unutulduğundaki sorunları biliyorsunuzdur.

- Güvenlik: Çoğumuz, çöp toplayıcıyı programcıyı bellek yönetimi derdinden kurtaran bir kodlama kolaylığı olarak görürüz. Ama, belki de şaşırtıcı olarak, çöp toplayıcının getirmiş olduğu sonsuz yaşam süreci gerçeği ve bellek güvenliği arasında çok sağlam bir ilişki vardır. Yaşam süreçlerinin sonsuz olabilmeleri, geçersiz referans sorununu ortadan kaldırır; yani zaten sonlanmış olan nesnelere erişim sağlayan referanslar bulunamaz. Burada, değer türleri kullanmanın da aynı derecede güvenli olabileceğine dikkat çekmek isterim (auto a2 = a1; yazıldığında a2'nin a1'in kopyası haline gelmesi). Ancak değer türleri kullanma yöntemi pek ilginç değildir; çünkü referans kavramı üzerine kurulu veri yapılarına izin vermez (liste, ağaç, graf, ve daha genel olarak, paylaşılan kaynaklar).

- Kaynak ayırma bedeli: Sınıf nesneleri genel olarak çöp toplayıcıya ait bellek bölgesinde bulunmak zorundadırlar. O bölgenin kullanılması, program yığıtından daha yavaştır ve daha fazla bellek kullanır. Günümüzde bu fark oldukça azalmıştır ama yine de bir bedeli vardır.

- Uzun mesafeli bağlantılar (long-range  coupling): Referanslar kullanmanın temel riski, aynı nesneye çok fazla yoldan erişim sağlanabilmesidir (aliasing). Aynı nesneye çok farklı ve hiç beklenmedik yerlerden farkında olunmadan erişim sağlanabilir. Aynı nesneye erişim sağlayan a1 ve a2 gibi iki referans, programın oldukça uzak noktalarında bulunuyor olabilirler. Ek olarak, aynı nesnenin daha da başka referansları bulunabilir. İlginç olarak, eğer nesne değişmez (immutable) bir nesne ise, sorun bütünüyle ortadan kalkar. Asıl güçlük, programda belirli bir bağlamdaki bir değişikliğin, başka bir bağlamdaki durumu da etkileyebiliyor olmasındadır. Bu sorunu gidermenin bir yolu, nesnelerin kopyala gibi bir üye işlev yardımıyla ve açıkça kopyalanmalarıdır. Bu yöntemin kötü tarafı, programcının dikkatini gerektirmesi ve "emin olunsun" diye gereğinden fazla kopyalanarak hız kaybedilmesidir.

Referans kavramını int gibi türlerdeki değer kavramıyla karşılaştırın. Değer türlerinin denklik açısından yararları vardır: denk olan nesneleri birbirlerinin yerlerine kullanabilirsiniz ve sonuç hep aynı olur. (Erişim sağladıkları nesneleri değiştiren referans türlerinde böyle bir mantık yürütülemez.) Değer türlerinin yararlarından olan hız da önemli bir konudur; ama eğer çok şekilliliğin dinamik esnekliği isteniyorsa, referans türleri şarttır. Bazı diller her iki yöntemi de barındırmaya çalışmış ve böylece "saf değil" olarak tanınmışlardır; saf olan nesne yönelimli diller ise bütünüyle referans türleri kullanırlar. D bu konuda açıkça saf değildir. Belirli bir türün nesne yönelimli olanaklarının bulunup bulunmayacağına tasarım aşamasında karar verilir; istendiğinde class, istenmediğinde struct kullanılır.

====================

Ali
acehreli (Moderatör) #3
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Alexandrescu'nun gösterdiği yukarıdaki yazı üzerine birisi de şöyle dedi: "evet ama bunlar programcının seçimi ile ilgili konular; dil tasarımcılarının seçimlerini göstermezler; belirli bir olanak istendiğinde diller arasında seçim yapmak gerekebilir."

Alexandrescu'nun kitabından alıntı içeren yanıtını çeviriyorum:

Kitap, dil tasarımı konularında dürüst tartışmalar da içeriyor; buna D'nin bilerek uzaklaştığı tasarımların yararlı tarafları da dahil. Örnek:

====================

{Ali'nin notu: Anlaşılan, bu metin find'ın bir işlev şablonu olarak tanımlandığı noktada başlıyor.}

find'ın bu yeni tanımını gördüğünde derleyici ne yapabilir? Derleyici int[] kullanıldığı durumdan daha güç bir durumdadır çünkü bu sefer T'nin ne olduğu bilinmemektedir; T herhangi bir tür olabilir. Değişik türler bellekte değişik olarak saklanırlar, işlevlere değişik olarak geçirilirler, ve == işlecinin anlamı bile farklıdır. Bu güçlüğün üstesinden gelmeye çalışmak önemlidir; çünkü tür konusunda esneklik getiren şablon parametreleri, kod paylaşımı konusunda seçenekler sunarlar. Tür şablon parametreleri için kod üretme konusunda günümüzde iki temel yaklaşım vardır:

- Bağdaşık kod üretimi (homogeneous  translation): Bütün veri tek bir düzene indirgenir ve böylece find işlevinden her tür için kullanılacak olan tek adet derlenir.

- Değişik kod üretimi (heterogeneous  translation): find'ın değişik türlerle kullanılması (örneğin int, double, string) her tür için değişik kod üretilmesine neden olur.

{Ali'nin notu: Ben bunu "Ayrıntılı Şablonlar" dersinde "Kod şişmesi" başlığında anlatmıştım.}

Bağdaşık kod üretiminde, verinin find'a sunulabilmesi için, her tür veriye aynı şekilde erişilebilmesi gerekir. Değişik kod üretiminde ise, sanki birisi find'ı her tür için ayrı ayrı ve belirli bir kalıba uygun olarak yazıyor gibidir. Her iki yaklaşımın yararları ve zararları olduğu açıktır; ve bunlar ateşli dil tartışmalarının konuları arasındadırlar. Bağdaşık kod üretimi tek düzeliği, basitliği, ve kodun küçüklüğünü yeğler. Örneğin, geleneksel fonksiyonel dillerde her şey liste düzenindedir; veya çoğu geleneksel nesne yönelimli dilde her şey nesne olduğu için nesneler aynı arayüzle kullanılırlar. Bağdaşık kod üretiminin kötü taraflarının arasında esnek olmama, ifade gücü düşüklüğü, ve hız kaybı bulunur. Öte yandan, değişik kod üretimi; özellemeyi, ifade gücünü, ve üretilen kodun hızını ön plana çıkartır. Bunun bedeli; kod şişmesi, dilin karmaşıklaşması, ve garip bir derleme modelidir (değişik kod üretimine karşı kullanılan tezlerden birisi, onların aslında süslü makrolar olduklarıdır; makrolar C dilinden beri kötü olarak ünlenmiş oldukları için de bu oldukça kötü olarak algılanır).

Buradaki önemli bir ayrıntı, içerme ilişkisidir: değişik kod üretimi, bağdaşık kod üretimini içerir ("birden fazla" düzen, "tek" düzeni içerdiği için). Diğer konuları bir tarafa bırakacak olursak, bu gerçeğe dayanarak, değişik derlemenin bağdaşık derlemeden daha güçlü olduğu sonucunu çıkartırız. Değişik derleme yöntemine sahipseniz, gerektiğinde bağdaşık derleme de kullanabilirsiniz. Bunun tersi geçerli değildir. Tabii buna dayanarak değişik derlemenin bağdaşık derlemeden daha iyi olduğunu öne sürmek, konuyu fazlaca basite indirgemek olur.

D, değişik derleme yöntemini kullanır. Ek olarak, kapsama bağlı isim çözümleme (statically scoped symbol lookup) ve geciktirilmiş tür denetimi (deferred typechecking) de kullanır. D derleyicisi; find'ın genel tanımını ayrıştırır (parse) ve nerede tanımlandığını hatırlar, ama onun ilerideki bir zamanda çağrılmasına kadar hiçbir şey yapmaz. Derleyici find'ı ancak o zaman ve kullanılmakta olan T ile derler. İşlevin kullandığı isimler, işlevin tanımlandığı noktada çözümlenirler.
====================

Ali
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-19, 07:56:38 (UTC -08:00)