Programlama Dilleri
Programlama dillerini sözdizimi ve semantikten tür sistemlerine, çalışma zamanı ve bellek modellerinden eşzamanlılık, fonksiyonel/nesne yönelimli paradigmalara ve güncel C, C++, Java 27, C# 14, Python 3.14, Rust, Go, Kotlin, ECMAScript ve WebAssembly çizgisine kadar karşılaştırmalı ele alan ders notu.
Programlama dilleri dersi, çok sayıda dilin sözdizimini art arda ezberleme dersi değildir. Amaç; bir dilin hangi soyutlamaları sunduğunu, bu soyutlamaların hangi çalışma zamanı ve güvenlik maliyetlerini doğurduğunu, farklı paradigmalardaki tasarım kararlarının programın doğrulanabilirliğini ve bakımını nasıl etkilediğini anlayabilmektir.
Bir dil seçimi yalnız popülerlik kararı değildir. Çalışma zamanı modeli, tür sistemi, bellek güvenliği, eşzamanlılık, FFI/ABI gereksinimi, gerçek zaman kısıtları, geliştirme araçları ve uzun vadeli standartlaşma projenin risk profilini değiştirir. Klasik dil kuramı, güncel dil ve çalışma zamanı örnekleriyle birlikte değerlendirildiğinde tasarım tercihleri daha görünür hâle gelir.
1. Neden programlama dilleri çalışılır?
Birden çok dili kavramsal düzeyde bilmek üç önemli kazanım sağlar:
- aynı problemi farklı soyutlama maliyetleriyle modelleyebilmek,
- yeni dili yalnız sözdizimi değil mevcut kavramların yeni kombinasyonu olarak öğrenmek,
- proje gereksinimine göre dil/çalışma zamanı ödünleşim'larını daha bilinçli değerlendirmek.
Örneğin async/await, pattern matching veya generics farklı dillerde farklı sözdizimine sahip olabilir; asıl önemli olan bunların tür sistemi, allocation ve control-flow üzerinde hangi semantiği kurduğudur.
2. Dil değerlendirme ölçütleri
Klasik değerlendirme eksenleri okunabilirlik, yazılabilirlik, güvenilirlik ve toplam maliyettir. Güncel kritik sistemlerde bunlara şu boyutları eklemek gerekir:
- type ve bellek güvenliği,
- deterministik davranış ve worst-case latency,
- concurrency modeli,
- FFI/ABI ve platform erişimi,
- build/reproducibility,
- toolchain ve static analysis olgunluğu,
- standardizasyon ve backward compatibility,
- dağıtım footprint ve startup,
- library/supply-chain yüzeyi.
Bir kriter diğerini otomatik olarak üstün kılmaz. Daha güçlü safety kontrolleri derleme süresini artırabilir; daha dinamik yapı geliştirme hızını artırırken bazı hataları çalışma zamanı'a bırakabilir.
3. Dil tasarımı bir ödünleşim problemidir
Programlama dili, "en fazla özellik" yarışması değildir. Tasarım kararları birbirini etkiler:
implicit conversion <-> convenience / ambiguity
manual memory <-> control / safety burden
dynamic typing <-> flexibility / earlier error detection
GC <-> simpler ownership / pause + throughput cost
reflection <-> dynamism / analyzability + AOT costİyi bir dil tasarımı hedef domain'in önceliklerini görünür hale getirir. Sistem programlama, veri analizi ve UI scripting aynı optimum noktaya sahip değildir.
4. Sözdizimi, statik semantik ve dinamik semantik
Sözdizimi bir programın biçimsel olarak hangi token ve yapılardan oluşabileceğini tanımlar. Statik semantik, parse edilmiş program üzerinde çalışma öncesi uygulanabilen kurallardır: type checking, isim çözümleme veya kesin atama buna örnektir. Dinamik semantik ise program yürütülürken yapıların ne anlama geldiğini tanımlar.
Şu kod sözdizimsel olarak geçerli olabilir fakat type sistemi tarafından reddedilebilir:
int count = "forty-two"Buna karşılık sıfıra bölme veya null dereference gibi bazı problemler dil ve analiz düzeyine göre ancak çalışırken ortaya çıkabilir.
5. Grammar: BNF ve EBNF
Bir dilin context-free sözdizimi BNF/EBNF üretimleriyle açıklanabilir:
expression = term { ("+" | "-") term } ;
term = factor { ("*" | "/") factor } ;
factor = number | "(" expression ")" ;Bu grammar çarpma/bölmenin toplama/çıkarmadan daha sıkı bağlanmasını doğrudan yapı üzerinden ifade eder. Grammar, type kuralları veya çalışma zamanı davranışı açıklamaz; onlar ayrı semantik katmanlardır.
6. Sözcüksel çözümleyici ve ayrıştırıcı ayrımı
Sözcüksel çözümleyici kaynak metni identifier, literal, keyword ve operator gibi token'lara ayırır. Ayrıştırıcı bu token dizisini grammar'a göre syntax tree'ye dönüştürür.
source -> characters -> tokens -> AST -> semantic analysis -> IR/codeModern ayrıştırıcı pipeline'larında hata recovery, source span ve incremental parsing IDE deneyimi açısından en az "geçerli programı parse etmek" kadar önemlidir.
7. Ayrıştırıcı yaklaşımları
Recursive-descent, LL/LR ailesi ve ayrıştırıcı generator yaklaşımları farklı grammar sınıfları ve geliştirme araçları maliyetleri sunar. Küçük DSL için elle yazılan recursive-descent ayrıştırıcı okunabilir olabilir; büyük dilde generated ayrıştırıcı veya PEG gibi başka modeller tercih edilebilir.
Ayrıştırıcı seçimi yalnız hız kararı değildir. Hata mesajının kalitesi, incremental parse, ambiguity ve grammar bakım maliyeti de değerlendirilir.
8. İsim, bağlama ve yaşam süresi
Bir name'in neye bağlandığı ve bu bağlama'in ne zaman oluşturulduğu dilin temel semantiğidir.
name -> entity
entity -> storage/value/function/type/moduleStatic bağlama compile/link zamanında belirlenebilir. Dynamic dispatch gibi bazı bağlama'ler çalışma zamanı'da seçilir.
Kapsam, ismin kaynak kodda görünür olduğu alanı; yaşam süresi ise bağlı nesnenin çalışma zamanında var olduğu süreyi ifade eder. Bunlar aynı kavram değildir. Closure dış kapsam'daki değişkenin yaşam süresi'ını lexical bloktan daha uzun hale getirebilir.
9. Lexical ve dynamic kapsam
Çoğu modern genel amaçlı dil lexical kapsam kullanır: isim çözümleme kaynak kodun statik iç içe yapısına göre yapılır.
Dynamic kapsam ise çağrı zincirine göre isim arar ve local reasoning'i zorlaştırır. Bazı özel DSL veya configuration sistemlerinde benzer dinamik bağlam davranışları görülebilir.
Lexical kapsam derleyici optimizasyonu, refactoring ve static analysis için daha öngörülebilir bir temel sunar.
10. Değer, referans ve kimlik
Bir dilde x = y ifadesi "değeri kopyala", "referansı kopyala", "move et" veya başka bir semantic olabilir.
C'de struct assignment değer kopyalayabilir. Java'da object variable'ı referans değerini taşır. Rust'ta bazı değerlerin assignment'ı ownership move eder. C++'ta copy/move constructor ve overload'lar devreye girebilir.
Bu nedenle "pass by value" ifadesi, taşınan değerin pointer/reference olması halinde nesnenin de kopyalandığı anlamına gelmez.
11. Tür sistemi'in amacı
Tür sistemi, mümkün olmayan durumların bir kısmını program yürütülmeden veya kontrollü çalışma zamanı check ile engellemeye çalışır.
Type özellikleri farklı eksenlerde incelenebilir:
- static / dinamik türleme,
- nominal / structural typing,
- explicit / inferred types,
- strong / permissive conversions,
- nullable / non-null types,
- algebraic types,
- ownership/yaşam süresi types.
"Strongly typed" tek ve evrensel kesinlikte bir sınıflandırma değildir; hangi dönüşümlerin ve hangi hataların engellendiği açıkça belirtilmelidir.
12. Nominal ve structural typing
Nominal sistemde type uyumluluğu declaration identity ve açık ilişkilerle belirlenir. Java class/interface ve C# type ilişkileri büyük ölçüde nominaldir.
Structural sistemde bir değerin gereken üyeleri sağlaması yeterli olabilir. TypeScript bu yaklaşımı yaygın biçimde kullanır. Go interface satisfaction da açık implements declaration gerektirmeyen structural bir model sunar.
Structural typing adapter ihtiyacını azaltabilir; nominal typing domain sınırını ve intent'i daha belirgin hale getirebilir.
13. Primitive, product, sum ve optional types
Record/struct/tuple, birden çok alanın birlikte bulunduğu product type olarak düşünülebilir. Variant/discriminated union/enum-with-payload ise alternatiflerden yalnız birinin aktif olduğu sum type modelidir.
Result<T, E> = Ok(T) | Error(E)
Option<T> = Some(T) | NoneBu model hata ve eksik değeri null veya sentinel sayı yerine tür sistemi'e taşır. Rust Result/Option, Swift Optional ve fonksiyonel dillerdeki algebraic data type'lar bu fikrin pratik örnekleridir.
14. Null tasarım kararıdır
Null kolay bir "değer yok" işareti sunar fakat her reference'a sessizce eklenirse hata alanını büyütür. Modern diller bu sorunu farklı yollarla ele alır:
- Kotlin
TileT?'yi ayırır, - Swift optional kullanır,
- Rust
Option<T>kullanır, - C# nullable reference analysis sunar,
- Java
Optional<T>'ı belirli API senaryolarında library type olarak sunar.
Amaç null'u yasaklamak değil, absence durumunu sözleşmede görünür yapmaktır.
15. Unicode ve string semantiği
"Bir karakter bir byte'tır" varsayımı modern metin işlemede geçerli değildir. Unicode code point, UTF-8/UTF-16 code unit ve kullanıcı tarafından algılanan grapheme cluster farklı kavramlardır.
Bir dilde length fonksiyonunun byte, code unit, scalar value veya grapheme sayması API tasarımını etkiler. C/C++ byte-oriented string, Java/C# UTF-16 kökenli string ve Rust UTF-8 String farklı indexing kararları gösterir.
Metin algoritmaları storage encoding ile insan dilindeki karakter kavramını karıştırmamalıdır.
16. Conversion ve coercion
Explicit conversion programcı tercihidir; implicit coercion dilin otomatik dönüşümüdür. Otomatik dönüşüm kolaylık sağlarken precision kaybı veya overload ambiguity yaratabilir.
Kritik hesapta narrowing conversion açık olmalı ve range kontrolü düşünülmelidir. Para hesabında binary floating point ile decimal arithmetic seçimi tür sistemi'in domain doğruluğuna etkisine örnektir.
17. Generics ve parametric polymorphism
Generic yapı, algoritmayı belirli bir concrete type'a bağlamadan type-safe yeniden kullanımı sağlar.
function max<T: Ordered>(a: T, b: T) -> TImplementation stratejileri farklı olabilir: C++ template instantiation/monomorphization, Java type erasure, .NET reified generic üst veri/çalışma zamanı specialization ve Rust monomorphization farklı binary-size/çalışma zamanı ödünleşim'ları üretir.
Generic abstraction "sıfır maliyet" varsayımıyla değil dilin gerçek implementation modeliyle değerlendirilmelidir.
18. Ad-hoc, subtype ve parametric polymorphism
Polymorphism tek bir mekanizma değildir:
- ad-hoc: overload/operator overloading,
- subtype: interface/base type üzerinden dynamic dispatch,
- parametric: generic type parameter,
- coercion: değerin başka tipe dönüştürülmesi.
Bu ayrım API tasarımında önemlidir. Overload set büyüdükçe resolution karmaşıklaşabilir; dynamic dispatch çalışma zamanı indirection getirir; generic specialization binary büyütebilir.
19. Fonksiyonlar, closure ve higher-order yapı
Fonksiyon birinci sınıf değer olduğunda parameter olarak taşınabilir veya döndürülebilir. Closure, executable code ile lexical environment'ı birlikte tutar.
function counter() {
let value = 0;
return () => ++value;
}
const next = counter();
console.log(next());
console.log(next());value, outer call tamamlandıktan sonra da closure tarafından erişilebilir. Bu durum yaşam süresi ve allocation üzerinde etki oluşturabilir.
20. Parameter passing semantiği
Klasik modeller value, reference, result, value-result ve name gibi yöntemleri inceler. Modern dillerde pratik olarak value semantics, reference/pointer values, ref/out, borrow ve inout benzeri mekanizmalar görülür.
Aliasing, iki farklı erişim yolunun aynı mutable nesneye ulaşmasıdır. Aliasing arttıkça derleyici optimizasyonu ve local reasoning zorlaşır. Rust borrow checker bu sınıf problemi type/yaşam süresi kurallarıyla kısıtlamaya çalışır.
21. Evaluation order ve side effect
Şu ifadenin güvenilir olması için dilin operand evaluation order kuralı bilinmelidir:
f(i++, i++)Evaluation order tanımsız, unspecified veya kesin olabilir. Side effect taşıyan expression'lar sıralama kuralına duyarlıdır.
Kritik kodda karmaşık expression yerine adımları açık statement'lara ayırmak dil farklarından ve refactoring sürprizlerinden korunmaya yardımcı olur.
22. Control flow ve pattern matching
Selection ve iteration temel yapılardır; modern diller pattern matching ile veri biçimi ve control-flow'u birleştirir.
match result {
Ok(value) => use(value),
Error(cause) => recover(cause)
}Exhaustiveness checking, tüm variant'ların ele alınmasını derleyici seviyesinde doğrulayabilir. Bu, yeni variant eklendiğinde sessiz default davranıştan daha güvenli olabilir.
23. Exception, Result ve effect yaklaşımı
Exception normal return yolundan ayrı stack unwinding mekanizması sunar. Bazı diller checked istisna, bazıları unchecked model kullanır; Rust gibi diller recoverable hata için Result tipini tercih eder.
Hata modelinin seçiminde şu sorular önemlidir:
- caller hatayı görmeye zorlanıyor mu?
- stack unwinding maliyeti nedir?
- resource cleanup garanti altında mı?
- hata type-safe mi yoksa string/code mu?
- API composition nasıl davranıyor?
Exception'ı rutin branch mekanizması yapmak hem maliyet hem okunabilirlik problemi oluşturabilir.
24. Resource management: GC, RAII ve ownership
Bellek yönetiminde üç yaygın yaklaşım birbirini tamamen dışlamaz:
- manual allocation/free,
- tracing çöp toplama,
- deterministic ownership/RAII.
C manual yaşam süresi kontrolü verir fakat use-after-free/double-free riskini programcıya bırakır. Java/C# tracing GC ile object heap'i yönetir fakat file/socket gibi dış kaynaklar için yine explicit close/dispose gerekir. C++ RAII destructor ömrünü lexical/object yaşam süresi ile bağlar. Rust ownership ve borrow kurallarıyla GC olmadan bellek güvenliği hedefler.
GC "bellek sızıntısı imkânsız" anlamına gelmez; erişilebilir fakat artık gereksiz nesne tutulabilir.
25. Stack, heap ve escape
Stack/heap ayrımı source-level type kategorisinden çok çalışma zamanı implementation konusudur. Escape analysis bir nesnenin local kapsam dışına çıkmadığını kanıtlayıp allocation'ı optimize edebilir.
Closure capture, interface boxing, async state machine veya reflection allocation davranışını değiştirebilir. Performans analizi dil sloganıyla değil derleyici/çalışma zamanı çıktısıyla yapılmalıdır.
26. Object-oriented model
OOP'nin temel mekanizmaları encapsulation, abstraction, inheritance ve dynamic dispatch çevresinde gelişmiştir. Ancak inheritance kod tekrarını azaltmak için otomatik ilk tercih değildir.
Composition, interface/protocol ve immutable value object çoğu domain'de daha gevşek coupling sağlar. Modern Java/C#/Kotlin/Swift gibi diller inheritance ile birlikte sealed type, record/data class ve pattern matching gibi başka modeling araçları da sunar.
27. Interface, trait ve protocol
Benzer amaç farklı dillerde farklı adlarla görünür:
- Java/C#: interface,
- Rust: trait,
- Swift: protocol,
- Go: interface.
Semantic fark önemlidir. Go interface structural olarak satisfaction görür; Rust trait generic constraint ve static/dynamic dispatch için kullanılabilir; Swift protocol associated type ve extension mekanizmalarıyla farklı abstraction imkânları sunar.
"Hepsi interface" demek bu çalışma zamanı farklarını gizler.
28. Modül, package ve namespace
Büyük sistemde type kadar compilation/dağıtım birimi de önemlidir. Module sistemi visibility, dependency graph ve initialization order'ı etkiler.
C/C++ header/module modeli, Java module/package, C# assembly/namespace, Go package/module, Rust crate/module ve JavaScript ES module aynı probleme farklı seviyelerde çözüm getirir.
Package manager, dil module sistemi ve OS shared library aynı kavram değildir.
29. Concurrency ile paralellik ayrımı
Concurrency birden çok işin ilerlemesini organize eder; paralellik bunların aynı anda farklı execution resource üzerinde çalışmasıdır.
Dil/çalışma zamanı modelleri:
- OS iş parçacığı + shared memory,
- user-mode task/fiber/virtual iş parçacığı,
- async event loop,
- actor/message passing,
- CSP/channel,
- data parallel primitives.
Model değişse de race, deadkilit, starvation, cancellation ve geri basınç problemleri kaybolmaz.
30. Memory model ve happens-before
Shared-memory dilde "iki iş parçacığı aynı değişkeni okur/yazar" problemi yalnız CPU önbellek meselesi değildir. Dil memory model'i hangi read/write yeniden sıralamalarının mümkün olduğunu ve synchronization'ın görünürlük garantisini tanımlar.
Atomic, volatile, kilit/mutex ve channel gibi primitive'ler birbirinin doğrudan eş anlamlısı değildir. Lock mutual exclusion sağlar; atomic belirli işlemin indivisible olmasını sağlayabilir; visibility/order garantisi dile göre değişir.
31. Async/await dil özelliği ne yapar?
async/await çoğu dilde continuation/state-machine modelini daha okunabilir yazmayı sağlar. Otomatik paralellik veya yeni iş parçacığı garantisi değildir.
I/O-bound yüksek concurrency için değerli olabilir. CPU-bound iş için scheduler/iş parçacığı pool/parallel primitive ayrıca seçilmelidir.
Cancellation ve timeout structured concurrency modelinin parçası yapılmadığında orphan task ve resource leak ortaya çıkabilir.
32. Fonksiyonel programlama
Functional yaklaşım first-class function, immutable data ve expression composition'ı öne çıkarır. Pure function aynı input için aynı output'u üretir ve gözlemlenebilir dış yan etki oluşturmaz.
Bu özellikler test ve concurrency reasoning'i kolaylaştırabilir. Gerçek uygulama I/O yaptığı için amaç "hiç side effect olmasın" değil, effect boundary'lerini görünür ve sınırlı tutmaktır.
Java Stream, C# LINQ, Kotlin collection operators veya JavaScript array higher-order metodları functional fikirleri imperative/OOP dillere taşır.
33. Logic ve declarative programming
Logic programming'de programcı işlem sırasından çok relation ve kuralları belirtir. Prolog klasik örnektir.
SQL de imperative kontrol akışından ziyade istenen sonucu tarif eden declarative bir dil örneğidir; query optimizer fiziksel execution planını seçer.
Declarative dil "performans düşünmeye gerek yok" anlamına gelmez. Abstraction altında optimizer ve evaluation modeli vardır.
34. Metaprogramming, macro ve reflection
Metaprogramming kodun kod veya program yapısı üzerinde çalışmasıdır. Preprocessor macro, hygienic macro, annotation processor, source generator, compile-time evaluation ve çalışma zamanı reflection farklı mekanizmalardır.
Çalışma zamanı reflection esneklik sağlarken startup, trimming/AOT ve static analysis maliyeti oluşturabilir. Compile-time generation daha fazla build karmaşıklığı karşılığında çalışma zamanı üst veri taramasını azaltabilir.
Textual macro ile AST/token-aware macro aynı güvenlik ve hygiene özelliklerine sahip değildir.
35. Derleyici, interpreter, JIT ve AOT
"Derlenen dil" ve "yorumlanan dil" ikili sınıflandırması modern çalışma zamanı'ları açıklamakta yetersizdir.
Java source -> bytecode -> JVM interpreter/JIT -> native code
C# source -> IL -> CLR JIT/AOT -> native code
C/C++ -> object -> linker -> native image
JavaScript -> parser/IR/interpreter/JIT -> native executionAOT startup ve dağıtım karakteristiğini değiştirir; JIT çalışma zamanı profile üzerinden adaptif optimizasyon yapabilir. Ödünleşim workload'a bağlıdır.
36. Intermediate representation ve optimizer
Derleyici genellikle source'tan doğrudan machine code üretmez. AST sonrası bir veya daha çok IR üzerinden type lowering, SSA, inlining, dead-code elimination, vectorization ve register allocation gibi aşamalar uygulanabilir.
IR, birden çok source dilinin ortak optimizer/backend kullanmasını mümkün kılar. LLVM IR bunun tanınmış örneklerinden biridir; JVM bytecode ve .NET IL ise aynı zamanda dağıtım/çalışma zamanı formatı rolü oynar.
37. ABI, FFI ve dil sınırı
İki dilin birbirini çağırabilmesi yalnız function adını bilmek değildir. Calling convention, symbol mangling, layout/alignment, ownership, istisna ve string representation uyumlu olmalıdır.
C ABI birçok ekosistemde ortak düşük seviye sınır olarak kullanılır. FFI sınırında safety garantileri zayıflayabilir; Rust unsafe, Java JNI/FFM veya .NET P/Invoke gibi mekanizmalar explicit boundary oluşturur.
Serialization kullanarak process boundary kurmak, aynı-process FFI'dan farklı latency ve failure semantics üretir.
38. WebAssembly bir hedef platformdur
W3C'nin 12 Ağustos 2026 tarihli WebAssembly Core Specification belgesi sürüm 3.0'ı tanımlar ve Candidate Recommendation Draft durumundadır. WebAssembly güvenli, taşınabilir ve düşük seviyeli bir kod biçimidir; C/C++, Rust ve başka diller için tarayıcı veya WASI hedefi olabilir.
Wasm bir kaynak dil değildir; derleyici hedefi ve çalışma zamanı modelidir. Çöp toplayıcılı diller, bileşen modeli veya konak API'leriyle kullanımda ek ABI ve birlikte çalışabilirlik kararları gerekir.
39. C ve C++: güncel standart çizgisi
2026 itibarıyla yayımlanmış ISO standartları C için ISO/IEC 9899:2024 ve C++ için ISO/IEC 14882:2024'tür.
C; açık memory layout, pointer ve düşük çalışma zamanı abstraction ile sistem/embedded alanında güçlüdür. Bu kontrol undefined behavior ve manual yaşam süresi sorumluluğunu da beraberinde getirir.
C++ RAII, templates, constexpr, concepts ve standard library ile zero-overhead abstraction hedefler; dilin büyük özellik alanı coding standard ve toolchain discipline gerektirir.
İlgili uygulama notları: C Programlama ve C++ Programlama.
40. Java: JVM ve managed çalışma zamanı
Java 27 güncel özellik sürümü, Java 25 ise uzun süreli destek (LTS) çizgisidir. Java source JVM bytecode'a derlenir; çalışma zamanı JIT/AOT ve çöp toplama tekniklerini kullanabilir.
Java'nın nominal static type sistemi, generics, records/sealed classes, pattern matching, virtual iş parçacığıs ve geniş library/çalışma zamanı ekosistemi modern dil tasarımının birçok konusunu aynı platformda gösterir.
Ayrıntılar için Java Programlama.
41. C# ve .NET
C# 14, .NET 10 üzerinde güncel dil sürümüdür. C#; nominal statik türleme, generics, delegates, LINQ, records, pattern matching, async/await, spans ve unsafe escape hatch'lerini aynı dilde birleştirir.
CLR IL, üst veri, JIT ve AOT seçenekleri type/çalışma zamanı tasarımını doğrudan görünür kılar.
Ayrıntılar için C# Programlama.
42. Python 3.14
Python 3.14.7, 3.14 serisinin güncel bakım sürümüdür. Python 3.14 serisi dinamik türleme, duck typing, first-class function, generator/coroutine ve geniş çalışma zamanı introspection modelini sürdürür. Python 3.14'te free-iş parçacığıed Python resmi destek kazanmıştır; bu gelişme "GIL her Python build'inin değişmez özelliğidir" gibi genellemeleri geçersiz kılar.
Dynamic typing ile type annotations farklı katmanlardır: annotation, interpreter'ın bütün type hatalarını otomatik engellemesi anlamına gelmez; static checker/geliştirme araçları ek bir analysis katmanıdır.
43. Rust 2024 Edition
Rust 1.98.1 güncel kararlı sürümdür; Rust 2024 Edition ise dilin sürümden bağımsız edition çizgisini belirtir. Rust'ın ayırt edici tasarımı ownership, borrowing ve yaşam süresi kurallarıyla tracing GC olmadan bellek güvenliği sağlamayı hedeflemesidir.
unsafe Rust, derleyici'ın bazı safety kanıtlarını programcıya devrettiği explicit boundary'dir; unsafe kullanılması tüm programın denetimsiz olduğu anlamına gelmez.
Rust'ın enum + pattern matching + Result modeli sum type ve explicit error handling için öğretici örnektir.
44. Go 1.27
Go 1.27 specification; strongly typed, garbage-collected ve explicit concurrency desteği olan genel amaçlı bir dil tanımlar. Go 1.27 generic methods desteğini de eklemiştir.
Goroutine ve channel, CSP-benzeri concurrency yaklaşımını pratikleştirir; bununla birlikte shared memory, mutex ve atomic primitive'ler de mevcuttur.
Go'nun küçük dil yüzeyi ve backward compatibility politikası dil karmaşıklığı ile ecosystem stability arasındaki farklı tasarım tercihine örnektir.
45. Kotlin 2.4 ve Swift
Kotlin 2.4.20 güncel 2.4 release line'ındadır ve JVM yanında JavaScript, WebAssembly ve Native hedeflerini destekler. Null safety, extension function, coroutine ve multiplatform modeli; kaynak dil ile target çalışma zamanı ayrımını görmek için güçlü örnektir.
Swift'in resmi Language Reference'ı protocol, value semantics, generics, optionals ve structured concurrency gibi özellikleri tanımlar. Swift yalnız iOS UI dili olarak değil, modern type-system ve ownership yönelimli tasarım kararları açısından incelenmelidir.
46. JavaScript / ECMAScript 2026
ECMAScript 2026, ECMA-262'nin 17. baskısıdır. JavaScript dinamik türleme, prototype-based object model, closure, event-loop ile bütünleşen promise/async model ve module sistemini bir arada gösterir.
JavaScript çalışma zamanı ile Web API aynı şey değildir. fetch, DOM ve localStorage tarayıcı platform API'leridir; ECMAScript dil standardının kendisi değildir. Node.js başka host API'leri sağlar.
47. Dil seçimi için pratik matris
Tek bir "en iyi dil" yerine gereksinimleri görünür yapın:
Kriter Sorulacak soru
--------------------- ---------------------------------------------
Latency p99/p999 ve worst-case sınırı var mı?
Memory safety unsafe/native sınır ne kadar geniş?
Runtime GC/JIT kabul edilebilir mi?
Startup/footprint kısa ömürlü process veya edge hedefi mi?
Concurrency thread, actor, async, channel hangisi doğal?
Interop mevcut C ABI/JVM/.NET/native koda bağlanacak mı?
Tooling static analysis, profiler, debugger yeterli mi?
Portability hangi OS/CPU/runtime hedefleniyor?
Team mevcut uzmanlık ve bakım süresi nedir?
Standardization dil/toolchain sürüm politikası ne kadar kararlı?Bu matris winner üretmez; ödünleşim'ların projeye göre açıkça belgelenmesini sağlar.
48. Kritik ve gerçek zamanlı sistemlerde dil semantiği
Kritik sistemde average throughput yeterli ölçüt değildir. Allocation, GC pause, hidden synchronization, istisna path, scheduler ve JIT warm-up tail latency'yi etkileyebilir.
Determinism gerekiyorsa:
- allocation stratejisini sınırla,
- bkiliting noktalarını görünür yap,
- concurrency primitive'lerini ölç,
- istisna/error path'i benchmark et,
- derleyici flags/çalışma zamanı sürümünü sabitle,
- undefined behavior ve data race'i static/dynamic analysis ile denetle,
- production benzeri workload kullan.
Dil seçimi bu operasyonel disiplinin yerine geçmez.
49. Güvenlik açısından dil seçimi
Memory-safe dil bütün güvenlik açıklarını çözmez; authorization, injection ve business logic hataları devam eder. Bununla birlikte bounds check, ownership, safe reference ve type-safe serialization belirli exploit sınıflarını azaltabilir.
Native FFI, unsafe, reflection, deserialization ve code generation safety sınırını tekrar açabilir. Threat model bu escape hatch'leri ayrıca işaretlemelidir.
Supply-chain riski çoğu zaman dilin kendisinden çok package ecosystem ve build pipeline'dan gelir.
50. İlgili dersler
Dil kuramını somut platformlarda görmek için C Programlama, C++ Programlama, Java Programlama ve C# Programlama birlikte okunabilir. Syntax/grammar tarafı için Otomatlar Kuramı ve Biçimsel Diller, çalışma zamanı/memory için İşletim Sistemleri, web host modeli için Web Programlama tamamlayıcıdır.
Dil seçimini çalışma modeliyle ilişkilendirmek
Bir programlama dilini yalnız sözdizimi üzerinden karşılaştırmak yanıltıcıdır. Aynı algoritma; bellek yönetimi, çağrı modeli, hata sözleşmesi, eşzamanlılık ilkelleri ve çalışma zamanı nedeniyle farklı dillerde farklı operasyonel özellikler gösterir. Dil seçimi bu nedenle "hangi dil daha hızlı?" sorusundan çok, hangi maliyetlerin görünür ve denetlenebilir olduğuyla ilgilidir.
Örneğin GC kullanan bir çalışma zamanı kısa ömürlü nesneler için geliştirici yükünü azaltabilir; fakat gecikme bütçesi çok sıkı bir sistemde allocation hızı ve duraklama dağılımı ayrıca ölçülmelidir. Sahiplik tabanlı bir model ise bazı yaşam süresi hatalarını derleme zamanına taşıyabilir; bunun karşılığında API tasarımı daha açık sahiplik kuralları ister.
Dil değerlendirmesinde yararlı bir matris şunları birlikte ele alır:
- tür güvenliği ve ifade gücü,
- hata ve iptal sözleşmesi,
- bellek sahipliği ve yaşam süresi,
- eşzamanlılık ve paralellik modeli,
- ABI/FFI ve ekosistem sınırı,
- derleme, JIT/AOT ve dağıtım modeli,
- tanılama, profil çıkarma ve test araçları.
Bu yaklaşım, dili "özellik listesi" olarak değil, yazılımın çalışma davranışını belirleyen bir mühendislik sistemi olarak okumayı sağlar.
Bir dil iddiasını teknik kanıta bağlamak
Bir dil özelliği değerlendirilirken üç kaynak birbirinden ayrılmalıdır: dil standardı veya resmi belirtim, gerçek çalışma zamanı/derleyici davranışı ve belirli bir iş yükünde yapılan ölçüm. “Dil bunu garanti eder” ifadesi ancak belirtim düzeyinde destekleniyorsa genellenebilir; tek bir derleyicide gözlenen davranış dil sözleşmesi yerine geçmez.
Performans karşılaştırmasında aynı algoritma, aynı veri kümesi, benzer optimizasyon düzeyi ve tekrar edilebilir ölçüm düzeni gerekir. Başlangıç süresi, ısınma, bellek ayırma ve G/Ç maliyeti ayrı raporlanır. Sonuçlar kullanılan sürüm, donanım ve çalışma zamanı ile birlikte anlam kazanır.
Bir dil seçimi değerlendirilirken teknik sınırlar da yazılmalıdır: gerçek zaman gereksinimi, ABI/FFI ihtiyacı, dağıtım modeli, hata toleransı, ekip yetkinliği ve bakım ömrü. Bu çerçeve, sözdizimi tercihini mühendislik kararından ayırır.
Kaynaklar
- Robert W. Sebesta, Concepts of Programming Languages, 12th Global Edition, Pearson, 2023. Bu kaynak yalnız kavramsal müfredat ve karşılaştırma eksenlerinin belirlenmesinde kullanılmıştır; metin ve örnekleri yeniden üretilmemiştir.
- ISO, ISO/IEC 9899:2024 — Programming languages — C. https://www.iso.org/standard/82075.html
- ISO, ISO/IEC 14882:2024 — Programming languages — C++. https://www.iso.org/standard/83626.html
- Oracle, Java SE Downloads and Release Information. https://www.oracle.com/java/technologies/downloads/
- Microsoft, C# Language Reference and What's new in C# 14. https://learn.microsoft.com/dotnet/csharp/
- Python Software Foundation, Python 3.14 documentation and releases. https://www.python.org/downloads/
- The Rust Project, The Rust Programming Language. https://doc.rust-lang.org/book/
- The Go Project, The Go Programming Language Specification. https://go.dev/ref/spec
- JetBrains, Kotlin 2.4 release documentation. https://kotlinlang.org/docs/releases.html
- Swift.org, The Swift Programming Language — Language Reference. https://www.swift.org/documentation/tspl/
- Ecma International, ECMA-262 — ECMAScript 2026. https://ecma-international.org/publications-and-standards/standards/ecma-262/
- W3C WebAssembly Working Group, WebAssembly Core Specification 3.0. https://www.w3.org/TR/wasm-core/