Uygulama yöntemleri ve dillerin evrimi
Compilation, pure interpretation ve hybrid uygulama; derleyicinin fazları, linker ve preprocessor, JIT; programlama ortamları ve Fortran'dan Java'ya dillerin evriminde sınavda sorulan kilometre taşları.
Bir dili yazmak bir şey, onu bir bilgisayarda çalıştırmak başka bir şey. Bu sayfa iki konuyu kapsar: dillerin nasıl uygulandığı (compilation, interpretation, hybrid) ve dillerin evriminden sınavda sorulan kilometre taşları. Vizede kısa cevaplı ve eşleştirme soruları olarak çıkar; az emekle alınan puanlar.
Altın kurallar:
- Compilation: yavaş çeviri, hızlı çalışma. Interpretation: çeviri yok, yavaş çalışma.
- Hybrid = ara dile derle + yorumla. JIT bunu hızlandırır.
- Preprocessor metinsel değiştirme yapar, hesaplamaz.
- Tarihte “ilk”leri bil: Fortran ilk derlenen dil, ALGOL 60 ilk BNF, SIMULA 67 ilk sınıf, LISP ilk fonksiyonel.
Uygulama yöntemleri
Bilgisayarın donanımı sadece makine dilini çalıştırır. Yüksek seviyeli bir dil üç yolla çalıştırılabilir.
Compilation
Kaynak program bir kez makine diline çevrilir, sonra doğrudan çalışır. Çeviri yavaş, çalışma hızlı. C, C++, COBOL, Ada.
kaynak program
│ lexical analyzer karakterler → lexical units (lexeme)
▼
lexical units
│ syntax analyzer → parse trees
▼
parse trees
│ intermediate code generator ve semantic analyzer
▼
ara kod ──(optimizasyon, isteğe bağlı)
│ code generator
▼
makine dili ── linker (+ kütüphane ve sistem kodu) ──► load module ──► çalışır
symbol table: tüm fazlara kullanıcı tanımlı isimlerin tip ve niteliklerini sağlar
- Lexical analyzer: karakterleri identifier, özel kelime, operatör, noktalama gibi birimlere toplar; yorumları atlar.
- Syntax analyzer: bu birimlerden parse tree kurar.
- Semantic analyzer: tip hataları gibi sözdiziminin yakalayamadığı hataları kontrol eder; ara kod üretir.
- Optimization: programı küçültür ya da hızlandırır (genelde ara kod üzerinde).
- Code generator: makine kodunu üretir.
- Linker: kullanıcı programını sistem ve kütüphane programlarıyla bağlar; çıktı load module (executable image).
Bir program çalışırken komutlar bellekten işlemciye taşınır; bu bağlantı genelde işlemciden yavaştır ve hızı sınırlar (von Neumann bottleneck).
Pure interpretation
Çeviri yok. Bir yorumlayıcı (interpreter) program, kaynak programı ifade ifade okuyup çalıştırır; yazılımla taklit edilmiş bir sanal makine gibi.
- Artı: hata mesajı doğrudan kaynak satırına ve değişkene işaret eder; debug kolay.
- Eksi: 10 ila 100 kat yavaş. Darboğaz, her ifadenin her çalıştırılışta yeniden decode edilmesi. Ayrıca kaynak program ve symbol table çalışırken bellekte durur.
- Örnekler: erken JavaScript ve PHP, LISP’in ilk sürümleri, APL. Web betik dilleriyle geri döndü.
Hybrid implementation
Kaynak program, yorumlanması kolay bir ara dile derlenir; ara dil yorumlanır. Saf yorumlamadan hızlı, çünkü kaynak ifadeler sadece bir kez decode edilir.
- Perl: önce hataları yakalamak için kısmen derlenir.
- Java: kaynak → bytecode → JVM (Java Virtual Machine) yorumlar. Bytecode taşınabilir: JVM’i olan her makinede çalışır.
Just-in-time
JIT derleyici, bir alt program ilk çağrıldığında onun ara kodunu makine koduna çevirir ve saklar; sonraki çağrılar makine kodunu kullanır. Java ve .NET dilleri (C#) böyle çalışır. Sonuç: taşınabilir ara kod + derlenmiş kodun hızı.
| Yöntem | Çeviri | Çalışma hızı | Örnek |
|---|---|---|---|
| Compilation | Bir kez, yavaş | En hızlı | C, C++, COBOL |
| Pure interpretation | Yok | 10-100x yavaş | Erken JavaScript, PHP |
| Hybrid | Ara dile | Arada | Perl, erken Java |
| JIT | Ara dil + çalışırken makine koduna | Derlenmişe yakın | Java, C# |
Preprocessor
Programı derlemeden hemen önce işleyen bir programdır. Başka dosyaları ekler (#include), makroları açar (#define). Değiştirme metinseldir; ifade hesaplanmaz ve öncelik kuralları açılımdan sonra uygulanır.
#define SQ(x) x*x
#define SQP(x) ((x)*(x))
#define DOUBLE(x) x+x
SQ(2+3) /* 2+3*2+3 */
SQP(2+3) /* ((2+3)*(2+3)) */
10 * DOUBLE(3) /* 10 * 3+3 */
11
25
33
TUZAK · makro fonksiyon değildir.
SQ(2+3)25 değil 11 verir, çünkü argüman hesaplanmadan metin olarak yapıştırılır. Parametreleri ve tüm gövdeyi parantez içine al.
Programlama ortamları
Yazılım geliştirmede kullanılan araçlar topluluğu: dosya sistemi, editör, linker, derleyici, debugger. UNIX eski bir ortam; Eclipse, NetBeans, Microsoft Visual Studio .NET entegre (IDE) örnekleri.
Dillerin evrimi: sınavda sorulanlar
| Yıl | Dil | Neden önemli? |
|---|---|---|
| 1945 | Plankalkül (Zuse) | İlk yüksek seviyeli dil tasarımı; uygulanmadı |
| 1957 | Fortran I (Backus, IBM) | İlk yaygın derlenen yüksek seviyeli dil; derlenmiş kodun verimli olabileceğini gösterdi |
| 1958 | LISP (McCarthy) | İlk fonksiyonel dil; liste işleme, garbage collection; yapay zekâ |
| 1958-60 | ALGOL 58 / ALGOL 60 | Makineden bağımsız; BNF ile tanımlanan ilk dil; blok yapısı, özyineleme, pass-by-value ve pass-by-name |
| 1960 | COBOL | İş uygulamaları; kayıtlar (record), ondalık aritmetik, okunur İngilizce benzeri sözdizimi |
| 1964 | BASIC | Zaman paylaşımlı, öğrenmesi kolay |
| 1964 | PL/I | Bilimsel + iş; ilk istisna yönetimi ve eşzamanlılık denemeleri; çok karmaşık |
| 1967 | SIMULA 67 | Sınıflar ve nesneler; veri soyutlamanın temeli |
| 1971 | Pascal (Wirth) | Öğretim için; yapısal programlama |
| 1972 | C | Sistem programlama (UNIX); güçlü operatörler, zayıf tip kontrolü |
| 1972 | Prolog | Mantık programlama |
| 1980 | Smalltalk-80 | İlk tam OOP: her şey nesne, mesaj gönderme; grafik arayüz |
| 1983 | Ada | ABD Savunma Bakanlığı; paketler, istisna yönetimi, generic’ler, task’lar |
| 1985 | C++ | C + sınıflar, çoklu kalıtım, operator overloading, template |
| 1995 | Java | C++ temelli, daha basit ve güvenli: pointer yok, garbage collection, applet’ler, bytecode |
| 2000 | C# | .NET; Java ve C++ fikirleri, delegate, property |
Betik diller: Perl (1987, metin işleme), JavaScript (1995, tarayıcı), PHP (1995, sunucu), Python (1991), Ruby (1996, her şey nesne). Fonksiyonel: Scheme (1975, LISP’in küçük lehçesi), ML (statik tip, type inference), Haskell (saf ve lazy).
İPUCU · “ilk” soruları. İlk derlenen: Fortran. İlk BNF: ALGOL 60. İlk sınıf: SIMULA 67. İlk tam OOP: Smalltalk. İlk fonksiyonel ve garbage collection: LISP. Mantık: Prolog. İş: COBOL. Bu yedi eşleşme bu bölümün puanlarının çoğunu getirir.
Sık yapılan hatalar
| Yanlış | Doğrusu |
|---|---|
| Yorumlama yavaş çünkü makine komutu yavaş | Her ifade her seferinde decode edilir |
| Java saf yorumlanır | Bytecode + JVM (hybrid), bugün JIT |
| JIT tüm programı başta derler | Alt programı ilk çağrıda derler ve saklar |
| Optimizasyon zorunlu faz | İsteğe bağlı |
| Linker kaynak kodu derler | Derlenmiş parçaları kütüphanelerle bağlar |
SQ(2+3) = 25 | x*x makrosuyla 11 |
| İlk BNF Fortran’da | ALGOL 60 (ALGOL 58 için kullanıldı) |
| İlk OOP dili Smalltalk | Sınıflar SIMULA 67’de; ilk tam OOP Smalltalk |
Kendini test et
Sınavdaki gibi İngilizce sorular. Önce kâğıt kalemle çöz, sonra cevabı aç.
Put the phases of a compiler in order: code generation, syntax analysis, lexical analysis, semantic analysis / intermediate code generation, optimization (optional).
Cevabı göster
Lexer karakterleri lexeme'lere toplar. Parser bunlardan parse tree kurar. Semantic analyzer tip hatalarını kontrol eder ve ara kod (intermediate code) üretir. İsteğe bağlı optimizasyon programı küçültür ya da hızlandırır. Code generator makine kodunu üretir. Symbol table tüm fazlara hizmet eder.
Which compiler phase turns the characters of the source program into lexical units, and which builds parse trees?
Cevabı göster
Lexical units: identifier, özel kelime, operatör, noktalama. Lexer yorumları ve boşlukları atlar. Syntax analyzer (parser) lexical unit'lerden programın sözdizimsel yapısını gösteren parse tree'leri kurar.
Why is pure interpretation typically 10 to 100 times slower than running compiled code?
Cevabı göster
Yorumlayıcı kaynak ifadeyi her çalıştırışta yeniden çözümlemek zorunda; bir döngüde aynı satır binlerce kez çözümlenir. Darboğaz ifadenin decode edilmesidir, makine komutlarının kendisi değil. Ayrıca kaynak program ve symbol table çalışırken bellekte durur. Artısı: hata mesajları kaynak satırına işaret eder, debug kolaydır.
Classify the implementation method: (a) C and COBOL; (b) early JavaScript and PHP; (c) Perl and early Java.
Cevabı göster
Compilation: kaynak bir kez makine diline çevrilir, çalışma hızlı. Pure interpretation: çeviri yok, yorumlayıcı kaynağı doğrudan çalıştırır. Hybrid: kaynak, yorumlanması kolay bir ara dile (Java bytecode) çevrilir, sonra bu ara dil yorumlanır (JVM).
What does a just-in-time (JIT) compiler do?
Cevabı göster
JIT, hybrid sistemin yavaşlığını giderir: program ara dile derlenir; bir alt program ilk kez çağrıldığında onun ara kodu makine koduna çevrilir ve saklanır, sonraki çağrılar doğrudan makine kodunu çalıştırır. Java ve .NET dilleri bu yolla çalışır. Yani JIT aslında gecikmeli bir derleyicidir.
With the C macro #define SQ(x) x*x, what is the value of SQ(2+3)? How should the macro be written?
Cevabı göster
Preprocessor derlemeden önce metinsel değiştirme yapar, ifadeyi hesaplamaz. SQ(2+3) → 2+3*2+3; çarpma önce: 2 + 6 + 3 = 11. Parantezli tanımla ((2+3)*(2+3)) = 25 olur.
With #define DOUBLE(x) x+x, what is the value of 10 * DOUBLE(3)?
Cevabı göster
Açılım: 10 * 3+3. Önce çarpma: 30 + 3 = 33 (beklenen 60 değil). Makronun tüm gövdesi de parantez içinde olmalı: #define DOUBLE(x) ((x)+(x)).
What does a linker do?
Cevabı göster
Kullanıcı programı genelde başka programlara (işletim sistemi rutinleri, kütüphane fonksiyonları) ihtiyaç duyar. Linker bunları bağlayıp tek bir çalıştırılabilir dosya (load module) üretir. Kütüphane çağrısının fonksiyonun koduna bağlanması bu yüzden link time'da olur.
Name the language: (a) the first widely used compiled high-level language (1957); (b) the first language described with BNF; (c) the language that introduced classes (1967); (d) designed for business data processing.
Cevabı göster
Fortran (John Backus, IBM 704) derlenmiş kodun hızlı olabileceğini kanıtladı. ALGOL 60 BNF ile tanımlandı ve blok yapısı, özyineleme, pass-by-value/name getirdi. SIMULA 67 simülasyon için sınıfları ve nesneleri getirdi. COBOL (1960) iş uygulamaları için kayıtlar ve ondalık sayılar.
Which language introduced list processing and garbage collection, and which was the first purely object-oriented language?
Cevabı göster
LISP (1958, John McCarthy) yapay zekâ için tasarlandı: tek veri yapısı liste, hesaplama fonksiyon uygulaması, kullanılmayan bellek otomatik toplanır. Smalltalk (Xerox PARC, Smalltalk-80) her şeyin nesne olduğu ve hesaplamanın mesaj göndermeyle yapıldığı ilk tam OOP dili; grafik pencere arayüzünü de tanıttı.
Order these chronologically: Java, Prolog, Fortran I, SIMULA 67, Smalltalk-80.
Cevabı göster
Fortran I 1957, SIMULA 67 1967, Prolog 1972, Smalltalk-80 1980, Java 1995. Sınavda yıl ezberi değil sıra ve "hangi fikir ilk nerede?" sorulur.
Which language was designed for the U.S. Department of Defense and is known for packages, exception handling, generic units and tasks (concurrency)?
Cevabı göster
Ada (1983) çok büyük bir tasarım sürecinin ürünü: paketlerle veri soyutlama, ayrıntılı istisna yönetimi, generic program birimleri, task'larla eşzamanlılık. Ada 95 OOP desteği ekledi. Karmaşıklığı ve derleyici maliyeti yayılmasını sınırladı.
Doğrulama: Preprocessor makro soruları, makro gövdesi metinsel olarak açılıp ortaya çıkan ifade node ile hesaplanarak doğrulandı (verify/SEN2001/01.mjs); C derleyicisi kurulu olmadığı için gerçek cpp çalıştırılmadı. Faz sıraları ve yıllar kavramsal/tarihsel bilgi; ders kitabının standart anlatımıyla karşılaştırıldı.