Giriş: dil değerlendirme kriterleri ve dil tasarımına etkiler
Programlama dillerini neden incelediğimiz, uygulama alanları, readability/writability/reliability/cost kriterleri, orthogonality, tasarım ödünleşimleri, von Neumann mimarisinin etkisi ve dil kategorileri.
Bu ders bir dili öğretmez; dilleri karşılaştırmayı öğretir. Neden bir dil bir özelliği şöyle tasarlamış, başka bir dil böyle? Bunu soran biri yeni bir dili hızlı öğrenir, doğru dili seçer ve kullandığı dilin özelliklerini daha bilinçli kullanır. İlk hafta dilleri tartmak için kullanacağımız ölçütleri kurar. Vizede kısa cevaplı sorular olarak gelir: “Bu özellik hangi kriteri etkiler?”, “Orthogonality nedir, C’den örnek ver.”
Altın kurallar:
- Dört kriter: readability, writability, reliability, cost.
- Readability’yi etkileyen her şey writability ve reliability’yi de etkiler.
- Orthogonality = kuralın istisnası yok.
- Dil tasarımı bir dizi ödünleşimdir (trade-off); bir kriter kazanılırken diğeri kaybedilir.
Neden programlama dilleri?
- Fikirleri ifade etme gücü: düşünebildiğin yapılar bildiğin dilin yapılarıyla sınırlıdır. Başka dillerin yapılarını bilen biri, onları kendi dilinde de taklit edebilir.
- Doğru dili seçmek: sadece bir dil bilen her probleme o dille bakar.
- Yeni dilleri öğrenmek kolaylaşır: kavramlar (binding, scope, parametre geçirme) dilden dile taşınır.
- Uygulamayı anlamak: bir özelliğin nasıl uygulandığını bilmek, onu verimli kullanmayı sağlar (özyinelemenin maliyeti gibi).
- Bilinen dili daha iyi kullanmak ve bilişimin genel gelişimini anlamak.
Uygulama alanları (programming domains)
| Alan | İhtiyaç | Diller |
|---|---|---|
| Bilimsel (scientific) | Floating-point hesap, diziler, verim | Fortran |
| İş (business) | Rapor, ondalık sayılar, karakter verisi | COBOL |
| Yapay zekâ | Sembol işleme, bağlı listeler | LISP, Prolog |
| Sistem programlama | Verim, donanıma erişim | C |
| Web | Markup, betik, dinamik içerik | HTML, JavaScript, PHP |
Değerlendirme kriterleri
Readability (okunabilirlik)
Programın okunup anlaşılabilme kolaylığı. Bakım maliyetinin büyük kısmı burada belirlenir.
- Simplicity: az sayıda temel yapı. İki düşmanı var: feature multiplicity (aynı işi yapmanın birden çok yolu) ve kötü kullanılan operator overloading (
+ile çıkarma yapan bir kullanıcı tanımlı operatör).
int count = 0;
count = count + 1;
count += 1;
count++;
++count;
System.out.println(count);
4
Dört farklı yazım, aynı iş. Assembly ise tersinden aşırı basittir: yapı az, ama program uzun ve okunmaz.
- Orthogonality: görece az sayıda ilkel yapı, görece az sayıda yolla birleştirilebilir ve her olası birleşim geçerli ve anlamlıdır. C’de eksiklikler: fonksiyon struct döndürebilir ama dizi döndüremez; parametreler değerle geçer, diziler hariç; struct üyesi void dışında her tip olabilir ama dizi elemanı void ya da fonksiyon olamaz. Fazlası da zarar: ALGOL 68’deki patlayan kombinasyonlar.
- Data types: yeterli tip desteği. Boolean tip yoksa
timeOut = 1yazılır;timeOut = trueçok daha açıktır. - Syntax design: özel kelimeler ve bileşik ifadelerin sonu.
end ifveend loop(Ada) bir}’den daha çok bilgi verir. Biçim anlamı yansıtmalı: aynı kelimenin bağlama göre farklı anlamı olmamalı (C’destatic’in iki anlamı gibi).
Writability (yazılabilirlik)
Bir alanda program yazmanın kolaylığı. Readability’yi etkileyenlere ek olarak:
- Support for abstraction: karmaşık yapıları ayrıntıları gizleyerek tanımlayıp kullanabilmek. Process abstraction (alt program), data abstraction (ağaç düğümü için bir sınıf; Fortran 77’de bunun yerine paralel tam sayı dizileri gerekirdi).
- Expressivity: işi kısa ve uygun yoldan ifade edebilmek.
count++ifadesicount = count + 1’den,fordöngüsü eşdeğerwhile’dan yazması kolay.
Reliability (güvenilirlik)
Programın her koşulda belirtimine uygun çalışması.
- Type checking: tip hatalarını, tercihen derleme zamanında yakalamak. Çalışma zamanı kontrolü pahalı, derleme zamanı kontrolü ucuz.
- Exception handling: çalışma zamanı hatalarını yakalayıp düzeltici işlem yapabilmek.
- Aliasing: aynı hücreye iki isim. Kısıtlanması güvenilirliği artırır.
int[] a = {1, 2};
int[] b = a;
b[0] = 9;
System.out.println(a[0]);
9
- Readability ve writability de güvenilirliği etkiler: doğal olmayan yollarla yazılan programın hatalı olma ihtimali yüksektir.
Cost (maliyet)
Programcı eğitimi, program yazma, derleme, çalıştırma, dil uygulama sistemi (ücretsiz derleyici Java’nın yayılmasına yardım etti), düşük güvenilirliğin bedeli (kritik sistemde bir hata) ve bakım. Büyük sistemlerde en büyük kalem bakımdır.
Özet tablo
| Özellik | Readability | Writability | Reliability |
|---|---|---|---|
| Simplicity | ✔ | ✔ | ✔ |
| Orthogonality | ✔ | ✔ | ✔ |
| Data types | ✔ | ✔ | ✔ |
| Syntax design | ✔ | ✔ | ✔ |
| Support for abstraction | ✔ | ✔ | |
| Expressivity | ✔ | ✔ | |
| Type checking | ✔ | ||
| Exception handling | ✔ | ||
| Restricted aliasing | ✔ |
Diğer kriterler: portability (bir uygulamadan diğerine taşınabilirlik), generality (geniş uygulama alanı), well-definedness (resmi tanımın eksiksizliği).
Tasarım ödünleşimleri
| Ödünleşim | Örnek |
|---|---|
| Reliability vs cost of execution | Java her dizi indisini kontrol eder: güvenli ama yavaş. C etmez |
| Readability vs writability | APL: çok güçlü operatörler, kısa programlar, ama okunması çok zor |
| Writability vs reliability | C++ pointer’ları: esnek ve güçlü, ama güvensiz |
int[] big = new int[3];
try { big[3] = 1; } catch (ArrayIndexOutOfBoundsException e) { System.out.println("checked"); }
checked
Dil tasarımına etkiler
Bilgisayar mimarisi
Bugünkü bilgisayarların çoğu von Neumann mimarisindedir: veri ve program aynı bellekte, işlemci ayrı. Komutlar ve veri işlemciye bellekten taşınır, sonuçlar geri yazılır. Bu mimari imperative dilleri doğurdu:
- Değişkenler bellek hücrelerini modeller.
- Atama verinin bellek ile işlemci arasında taşınmasını modeller.
- Iteration bu mimaride verimlidir (komutlar ardışık hücrelerde); özyineleme daha pahalıdır.
İşlemci komutları bellekten çok daha hızlı çalıştırabildiği için, bellek ile işlemci arasındaki bağlantının hızı sistemi sınırlar: von Neumann bottleneck.
Programlama metodolojileri
| Dönem | Odak | Dil özellikleri |
|---|---|---|
| 1950’ler ve 60’ların başı | Basit uygulamalar, makine verimi | |
| 60’ların sonu | İnsan verimi; readability, daha iyi kontrol yapıları | Yapısal programlama, top-down tasarım |
| 70’lerin sonu | Process-oriented’den data-oriented’a | Data abstraction |
| 80’lerin ortası | Nesne yönelimli | Data abstraction + inheritance + polymorphism |
Dil kategorileri
| Kategori | Fikir | Örnek |
|---|---|---|
| Imperative | Değişken, atama, iterasyon | C, Java, Perl, JavaScript |
| Functional | Hesaplama, fonksiyonları parametrelere uygulamak | LISP, Scheme, ML, F# |
| Logic | Kural tabanlı; kuralların sırası belirtilmez | Prolog |
| Markup/programming hybrid | Markup dilini programlama yapılarıyla genişletmek | JSTL, XSLT |
Nesne yönelimli diller ayrı bir kategori değil, imperative dillerin uzantısı olarak görülür; scripting diller (Perl, Python, Ruby) ve görsel diller (.NET) de imperative ailede.
Sık yapılan hatalar
| Yanlış | Doğrusu |
|---|---|
| Aliasing readability’yi etkiler | Tablodaki yeri reliability |
| Orthogonality = çok özellik | Az yapı, istisnasız birleşim |
| Daha fazla orthogonality hep iyi | ALGOL 68: karmaşıklık |
| Type checking writability’yi etkiler | Tablodaki yeri reliability |
| Maliyetin büyüğü derleme | Genelde bakım |
| Von Neumann bottleneck = yavaş işlemci | Bellek-işlemci bağlantısı |
| OOP ayrı bir paradigma, imperative değil | Çoğunlukla imperative üstüne kurulu |
| Feature multiplicity writability’yi bozar | Asıl zarar readability/simplicity |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
Which language evaluation criterion is mainly harmed by aliasing (two names for the same memory cell)?
Cevabı göster
Bir değişken başka bir isim üzerinden değiştirilebiliyorsa, programcı bunu fark etmeyebilir ve program beklenmedik davranır. Aliasing tablosunda sadece reliability sütununda yer alır. Çoğu dil pointer ve reference yüzünden aliasing'e izin verir; kısıtlanmış aliasing güvenilirliği artırır.
What is printed in Java, and which criterion does this design weaken?
int count = 0;
count = count + 1;
count += 1;
count++;
++count;
System.out.println(count);Cevabı göster
Dört satır da aynı işi yapar: count'u 1 artırır, sonuç 4. Aynı işlemi yapmanın birden çok yolu olmasına feature multiplicity denir. Okuyan kişi hepsini tanımak zorunda; dil daha az basit (simplicity) ve daha zor okunur olur.
Define orthogonality and give one example of a lack of orthogonality in C.
Cevabı göster
Ortogonal bir dilde kuralların istisnası yoktur. C'de: fonksiyon struct döndürebilir ama dizi döndüremez; parametreler değerle geçer, diziler hariç (dizi adresi geçer); struct üyesi void dışında her tip olabilir. Her istisna öğrenilmesi gereken ek bir kural.
Java checks every array index at run time. Which two criteria are traded off by this decision?
Cevabı göster
İndis kontrolü sınır dışı erişimleri yakalar (reliability artar), ama her dizi erişimine ek bir karşılaştırma ekler (çalışma maliyeti artar). C kontrol etmez: hızlıdır ama taşma sessizce başka belleği bozar. Dil tasarımı bu tür ödünleşimlerle (trade-off) doludur.
What is printed in Java?
int[] a = {1, 2};
int[] b = a;
b[0] = 9;
System.out.println(a[0]);Cevabı göster
b = a diziyi kopyalamaz; aynı diziye ikinci bir isim yaratır (alias). b üzerinden yapılan değişiklik a'dan görünür. Okuyan kişi a[0]'ın değiştiğini a'ya bakarak anlayamaz; aliasing'in reliability'yi neden düşürdüğünün küçük bir örneği.
What is the von Neumann bottleneck?
Cevabı göster
Von Neumann mimarisinde komutlar ve veri aynı bellekte, işlemci ayrı durur. Her komut ve her operand bu bağlantıdan geçmek zorunda. Bağlantı, işlemcinin komut çalıştırma hızından yavaş olduğu için sistemin hızını sınırlar.
Which three features of imperative languages come directly from the von Neumann architecture?
Cevabı göster
Değişken bellek hücresini, atama verinin bellekten işlemciye gidip sonucun geri yazılmasını modeller. Komutlar ardışık hücrelerde durduğu için tekrar (iteration) hızlıdır; özyineleme bu mimaride daha pahalıdır. C, Java, Python bu yüzden imperative dillerdir.
Classify each language by category: C, Scheme, Prolog, Java, XSLT.
Cevabı göster
Imperative: değişken, atama, döngü. Functional: hesaplama fonksiyon uygulamasıyla. Logic: kural tabanlı, sonuç mantıksal çıkarımla. OOP diller çoğunlukla imperative dillerin üstüne kurulur. XSLT ve JSTL gibi markup tabanlı diller de sınırlı programlama yapıları içerir.
According to the standard table, which language characteristics affect writability and reliability but not readability?
Cevabı göster
Simplicity, orthogonality, data types ve syntax design üç kriteri de etkiler. Support for abstraction ve expressivity yazmayı ve güvenilirliği etkiler. Type checking, exception handling ve restricted aliasing sadece reliability'yi etkiler.
Of the cost components of a programming language (training, writing, compiling, executing, implementation system, poor reliability, maintenance), which is usually the largest for large software systems?
Cevabı göster
Büyük sistemlerde bakım maliyeti geliştirme maliyetinin birkaç katı olabilir. Bakım büyük ölçüde okunabilirliğe bağlıdır, çünkü bakımı genelde kodu ilk yazan kişi yapmaz. Bu yüzden readability en önemli kriterlerden biri sayılır.
Why can too much orthogonality also be a problem? Give the classic example language.
Cevabı göster
ALGOL 68'de neredeyse her yapı her yerde kullanılabilir (örneğin bir if bir atamanın sol tarafında olabilir). Kombinasyonlar patlar, dil öğrenmesi ve okunması zor hale gelir; ayrıca yazım hataları başka geçerli bir anlama düşüp yakalanmayabilir. Fonksiyonel diller ise ortogonallik ile basitliği iyi dengeler.
Name the three fundamental features of object-oriented languages, and the programming methodology era that led to them.
Cevabı göster
1950-60'larda verimlilik, 1970'lerde yapısal programlama ve yukarıdan aşağı tasarım, 1970'lerin sonunda veri yönelimli tasarım (soyut veri tipleri) öne çıktı. 1980'lerde OOP: veri soyutlama + kalıtım + dinamik bağlama. Metodolojiler dilleri şekillendirir.
Doğrulama: Feature multiplicity, aliasing ve dizi sınır kontrolü örnekleri JDK ile çalıştırıldı (java verify/SEN2001/W01.java). Kriter-özellik tablosu ve tanımlar kavramsal; ders kitabının standart sınıflandırmasıyla karşılaştırıldı.