← Previous · All Episodes · Next →
Programlama Dillerinin Gücü ve Lisp'in Yeniden Yükselişi (Revenge of the Nerds) Episode 120

Programlama Dillerinin Gücü ve Lisp'in Yeniden Yükselişi (Revenge of the Nerds)

· 43:52

|
"Paul Graham'ın 2002'de yazdığı bu makale, programlama dillerinin farklı güçlere sahip olduğunu ve bu farkın önemini vurguluyor. Graham, dillerin gücünün, yazılımı oluşturmak için gereken kod miktarını azalttığını ve bu nedenle daha güçlü bir dilin, yazılımın daha hızlı yazılmasını sağladığını belirtiyor. Ayrıca, yazılım geliştirme sürecinde dil seçiminin, yöneticiler tarafından genellikle göz ardı edildiğini ve bu durumun, daha güçlü ve etkili bir dil kullanarak rekabet avantajı sağlama fırsatını kaçırdığını ifade ediyor. Graham, en güçlü dilin Lisp olduğunu ve diğer dillerin Lisp'e yaklaştığını ancak hala eksik olduklarını savunuyor. Bu makale, yazılım geliştirme ve dil seçimi konusunda derin bir bakış açısı sunuyor.

---

# Programlama Dillerinin Gücü ve Lisp'in Yeniden Yükselişi (Revenge of the Nerds)

Mayıs 2002

Hedefimiz C++ programcılarıydı, ancak çoğunu Lisp'e doğru yarı yolda bıraktık. 

- Java dili belirtimlerinin ortak yazarı Guy Steele

Yazılım dünyasında, sivri zekalı akademisyenlerle, eşit derecede güçlü olan sivri saçlı patronlar arasında bir mücadele var. Sivri saçlı patron kim mi? Evet, o çizgi film karakteri. Ama teknoloji dünyasında, bu karakter sadece bir çizgi film kahramanı değil, aynı zamanda birçok şirketin gerçek bir patronunu da temsil ediyor.

Sivri saçlı patron, tek başına oldukça yaygın olan ancak birlikte nadiren görülen iki özelliği bir arada bulunduruyor: (a) teknoloji hakkında hiçbir şey bilmiyor olması ve (b) hakkında hiçbir şey bilmediği bu konuda çok güçlü görüşlere sahip olması.

Diyelim ki bir yazılım yazmanız gerekiyor. Sivri saçlı patronunuz bu yazılımın nasıl işlemesi gerektiğini bilmiyor, programlama dillerini birbirinden ayırt edemiyor. Ama hangi dilde yazmanız gerektiğini biliyor. Evet, tam tahmin ettiğiniz gibi. Sizin Java'da yazmanızı istiyor.

Neden böyle düşünüyor diye merak ediyor olabilirsiniz. Gelin, sivri saçlı patronun kafasına bir göz atalım. İç sesi şöyle diyor: Java bir standart. Kesinlikle öyledir, çünkü sürekli gazetelerde okuyorum. Eğer bir şey standartsa, kullanmakla hata yapmış olmam. Bu da demek oluyor ki, her zaman çok sayıda Java programcısı olacak. Yani, şu an benimle çalışan programcılar işi bırakırsa, ki nedensiz bir şekilde hep bırakıyorlar, yerlerine başkasını getirmek kolay olacak.

Peki, bu pek de mantıksız gelmiyor mu? Ancak bu düşüncenin tamamı, aslında dile getirilmeyen bir varsayıma dayanıyor ve bu varsayımın doğru olmadığı ortaya çıkıyor. Sivri saçlı patron, tüm programlama dillerinin hemen hemen aynı olduğuna inanıyor. Eğer bu doğru olsaydı, o zaman patronun bu düşüncesi tam isabet olurdu. Eğer diller gerçekten birbirine eşitse, tabii ki, herkesin kullandığı dili kullanın.

Ama tabii ki tüm diller birbirine eşit değil ve ben bunu size, diller arasındaki farklara girme gereği bile duymadan kanıtlayabilirim. Diyelim ki 1992'de sivri saçlı patronunuza hangi dilde yazılım yapılması gerektiğini sordunuz. O, bugün olduğu gibi, hiç tereddüt etmeden 'Yazılımlar C++ dilinde yazılmalı' derdi. Ama eğer tüm diller birbirine eşitse, sivri saçlı patronun görüşü neden değişsin ki? Hatta bir adım daha ileri gidelim, Java'nın geliştiricileri neden yeni bir dil yaratmak için uğraşsınlar ki?

Yeni bir dil yaratıyorsanız, muhtemelen bunun sebebi, bu dili insanların zaten kullandığından bir şekilde daha iyi bulmanızdır. Aslında, Gosling, Java'nın ilk beyaz kağıdında, Java'nın C++'daki bazı sorunları çözmek üzere tasarlandığını belirtiyor. İşte burada durum netleşiyor: tüm diller birbirine eşit değil. Eğer patronun kafasındaki düşünce sürecini takip eder ve bu süreci Java'ya, oradan da Java'nın geçmişine kadar izlerseniz, sonunda başladığınız varsayımı çürüten bir fikre ulaşırsınız.

Peki, kim haklı? James Gosling mi, yoksa beyaz yakalı patron mu? Hiç şaşırtıcı olmayan bir şekilde, Gosling haklı. Bazı diller, belirli problemler konusunda diğerlerinden daha iyidir. İşte bu durum da bazı ilginç soruları beraberinde getiriyor. Java, belirli sorunlar için C++'dan daha iyi olacak şekilde tasarlandı. Peki hangi sorunlar bu? Java ne zaman daha iyi, C++ ne zaman daha üstün? Ya da belki de her ikisinden de daha iyi olan başka diller olduğu durumlar var mıdır?

Bu soruyu bir kez düşünmeye başladığınızda, gerçekten de büyük bir karmaşanın içine dalmış oluyorsunuz. Eğer sivri saçlı patron, sorunu tüm karmaşıklığı içerisinde düşünmek zorunda kalırsa, kafası karışıp patlar resmen. Tüm dilleri birbirine eşit olarak görürse, yapması gereken tek şey, en çok ivme kazananı seçmektir. Bu, teknolojiden çok moda meselesi olduğu için, bilgisi olmasa bile muhtemelen doğru cevabı bulabilir.Ancak dillerin birbirinden farklı olduğunu düşünmeye başlarsanız, birdenbire iki problemi birden çözmek zorunda kalırsınız. İlk olarak, çözmeniz gereken problem için önde gelen yirmi dili değerlendirmeniz ve hangisinin daha uygun olduğuna karar vermeniz gerekir. İkincisi ise, her bir dil için programcı, kütüphane vb. bulma ihtimalini hesaplamalıdır. Eğer kapının diğer tarafında bu tür bir durum varsa, sivri saçlı patronun kapıyı açmak istememesi hiç de şaşırtıcı değil.

Tüm programlama dillerinin eşit olduğuna inanmanın dezavantajı, bu durumun aslında doğru olmaması. Ancak avantajı, hayatınızı çok daha basit hale getirmesi. Ve bence bu fikrin bu kadar yaygın olmasının ana sebebi bu. Gerçekten de _rahat_ bir fikir.

Biliyoruz ki Java oldukça iyi bir dil çünkü o yeni ve popüler bir programlama dili. Ama gerçekten öyle mi? Eğer programlama dilleri dünyasına biraz mesafeden bakarsanız, Java'nın son trend olduğunu düşünebilirsiniz. (Yeterince uzaktan bakınca, sadece Sun'ın devasa ve parıldayan reklam panosunu görebilirsiniz.) Ancak bu dünyaya biraz daha yakından bakarsanız, 'popülerliğin' de kendi içinde dereceleri olduğunu anlarsınız. Hacker altkültüründe, Java'dan çok daha popüler olan Perl adında başka bir dil var. Örneğin, Slashdot sitesi Perl ile hazırlanıyor. Orada Java Sunucu Sayfaları'nı kullanan birini bulmanız pek mümkün olmaz. Ama Python adında, kullanıcıları genellikle Perl'yi küçümseyen, daha yeni bir dil var ve daha birçok dil [sahneye çıkmak için] (accgen.html) bekliyor.

Bu dilleri, Java, Perl ve Python'ı sıralı bir şekilde incelediğinizde, ilginç bir desen göze çarpıyor. Tabii ki, eğer bir Lisp programcısıysanız bu deseni fark edersiniz. Her bir dil, bir öncekine göre Lisp'e daha çok benziyor. Python, birçok Lisp programcısının bile yanlış olarak kabul ettiği özellikleri bile kopyalıyor. Basit Lisp programlarını neredeyse satır satır Python'a çevirebilirsiniz. İşte 2002 yılındayız ve programlama dilleri neredeyse 1958'deki Lisp seviyesine yetişmek üzere.

**Matematikle Yetişmek**

Demek istediğim, Lisp aslında ilk kez 1958'de John McCarthy tarafından keşfedildi ve bugünün popüler programlama dilleri ancak şimdi o dönemde McCarthy'nin geliştirdiği fikirleri yakalamaya başlıyor.

Peki bu nasıl mümkün olabilir ki? Bilgisayar teknolojisi sürekli hızla değişen bir alan değil mi? Yani, 1958'de bilgisayarlar, bir kol saatinin işlem gücüne sahip olan ve buzdolabı büyüklüğündeki dev makinelerdi. Bu kadar eski bir teknolojinin hala önemli olması, hatta en son teknolojilere üstünlük sağlaması nasıl mümkün olabilir?

Size nasıl olduğunu anlatayım. Aslında, başlangıçta Lisp bir programlama dili olarak tasarlanmamıştı, en azından bugün bildiğimiz anlamda değil. Programlama dili dediğimizde, bunu bir bilgisayara ne yapması gerektiğini söylemek için kullanılan bir araç olarak anlarız. McCarthy sonunda bu tarz bir programlama dili geliştirmeyi planladı elbette, ama bugün bildiğimiz Lisp, aslında McCarthy'nin bir teorik deney sırasında geliştirdiği, Turing Makinesine daha kullanışlı bir alternatif oluşturmayı hedefleyen bir şeye dayanıyor. McCarthy'nin sonradan söylediği gibi,

Lisp'in Turing makinelerinden daha düzgün olduğunu göstermenin başka bir yolu, evrensel bir Lisp fonksiyonu oluşturmak ve bunun, evrensel bir Turing makinesinin tasvirinden daha anlaşılır ve kısa olduğunu belirtmektir. İşte bu Lisp fonksiyonu '_eval_' idi. Bu fonksiyon, bir Lisp ifadesinin değerini hesaplıyor. '_eval_'ı yazmak için Lisp fonksiyonlarını Lisp verisi olarak temsil eden bir notasyon bulmak gerekiyordu. Bu notasyon, makale için özel olarak tasarlandı ve pratikte Lisp programlarına döküm yapmak amacıyla kullanılacağı hiç düşünülmedi.

Sonrasında neler mi oldu? 1958'in sonlarında, McCarthy'nin yüksek lisans öğrencilerinden biri olan Steve Russell, bu 'eval' tanımını inceledi ve eğer bunu makine diline çevirebilirse, sonuçta bir Lisp yorumlayıcısı çıkacağını anladı.

Bu, o dönemde büyük bir şok olmuştu.Hadi bir zaman makinesine binip 1950'lerin başına gidelim ve John McCarthy'nin Lisp'i yaratma hikayesine tanık olalım. McCarthy, Lisp'i yaratma fikrini ilk kez duyduğunda, bunun sadece bir teori olduğunu düşünmüştü. Ama sonra Steve Russell, ""Bu _eval_'ı programlamaya ne dersin?"" dedi ve McCarthy'nin düşünceleri değişti. McCarthy, _eval_'ın hesaplama için değil, okuma için tasarlandığını söyledi. Ama Russell durmadı, _eval_'ı IBM 704'ün makine diline çevirdi, hataları düzeltti ve bunun bir Lisp yorumlayıcısı olduğunu ilan etti. Ve işte o an, Lisp bugünkü haliyle karşımıza çıktı...

Bu hikaye, bir teorinin nasıl gerçek bir programlama diline dönüştüğünü gösteriyor. McCarthy'nin teorik çalışması, beklediğinden daha güçlü bir dil haline geldi. Ve bu, 1950'lerin dili olmasına rağmen, hala kullanılıyor olmasının nedenlerinden biri.

Lisp'in neden eskimediğini anlamak için, onun bir teknoloji değil, matematik olduğunu bilmek önemlidir. Matematik asla eskimez, değil mi? Lisp'i karşılaştıracağımız şey, 1950'lerin teknolojisi değil, örneğin 1960'ta bulunan ve hala en hızlı genel amaçlı sıralama algoritması olan Quicksort olmalı.

1950'lerden bugüne kalan başka bir dil daha var, Fortran. Ama bu dil, Lisp'in tam tersi bir yaklaşımı temsil ediyor. Lisp, aslında bir teoriyken beklenmedik bir şekilde programlama diline dönüştü. Ama Fortran, tamamen programlama dili olması amacıyla ve bilinçli bir şekilde geliştirildi. Ancak bugün perspektifimizle baktığımızda, Fortran'ı çok düşük seviye bir dil olarak değerlendiririz.

1956'da ortaya çıkan Fortran I, bugünkü Fortran dilinden oldukça farklıydı. Fortran I, aslında matematikle donatılmış bir montaj dilinden farksızdı. Hatta bazı yönlerden daha yeni montaj dilleri, Fortran I'dan daha gelişmişti; örneğin, sadece dallanmalar vardı, alt rutinler yoktu. Günümüzdeki Fortran, Fortran I'a kıyasla belki de Lisp'e daha yakın hale geldi.

Lisp ve Fortran, biri matematik diğeri makine mimarisi kökenli olmak üzere iki ayrı evrimsel ağacın gövdeleriydi. Bu iki ağaç o günden beri birbirine doğru yaklaşıyor. Lisp güçlü bir başlangıç yaptı ve sonraki yirmi yıl boyunca hızlandı. Öte yandan, ana akım diller hızlı bir başlangıç yaptı ve sonraki kırk yıl boyunca yavaşça güçlendi. Şimdi, en gelişmiş olanları hemen hemen Lisp kadar güçlü. Ancak, hala eksik olan birkaç şey var...

**Lisp'i Farklı Kılan Şey**

İlk kez ortaya çıktığında, Lisp tam dokuz yeni fikri bir araya getiriyordu. Bu fikirlerden bazıları şimdi o kadar yaygın ki, onları göz ardı ediyoruz, bazıları ise sadece daha ileri seviye dillerde görülüyor ve iki tanesi hala yalnızca Lisp'e özgü. Bu dokuz fikir, genel kabul görmelerinin sırasına göre şunlardır:

1. Koşullu ifadeler. Koşullu ifade, bir 'eğer-sonra-değilse' yapısını ifade eder. Bugün onları hepimiz tabii ki kabul ediyoruz, ancak Fortran I'da böyle bir özellik yoktu. Sadece, temel makine talimatına dayalı bir koşullu git-goto- mekanizması vardı.

2. Fonksiyon tipi. Lisp dilinde, fonksiyonlar da tıpkı tam sayılar veya metinler gibi bir veri tipidir. Kendi özgün gösterimleri vardır, değişkenlere atabilir, argüman olarak iletebilir ve daha pek çok şey yapabilirsiniz.

3. Özyineleme. İlk özyinelemeyi destekleyen programlama dili Lisp'ti.

4. Dinamik tiplemeler. Lisp'teki tüm değişkenler aslında işaretçi görevi görür. Değişkenlerin değil, değerlerin türleri vardır ve değişkenlerin atanması ya da bağlanması, işaret ettikleri değil, işaretçilerin kendisinin kopyalanması demektir.

5. Çöp toplama.

6. İfadelerin oluşturduğu programlar. Lisp programları, her biri bir değer döndüren ifadelerden oluşan ağaçlardır. Bu, ifadeler ve deyimler arasında ayrım yapan Fortran ve sonraki dillerin çoğunun aksinedir.

Fortran I'de ifadeleri iç içe kullanamadığınız için bu ayrımın olması doğaldı. Matematik işlemleri için ifadelere ihtiyaç duyarken, bir değer döndüren başka bir şey oluşturmanın bir anlamı yoktu çünkü o değeri bekleyen bir şey olamazdı.

Blok yapıdaki dillerin belirmesiyle bu sınırlama son buldu. Ancak bu durum çoktan çözülmesi gereken bir sorundu. İfadeler ve cümleler arasındaki ayrım çoktan yerleşmişti. Bu ayrım Fortran'dan Algol'e, oradan da tüm alt dillerine aktarıldı.

7. Bir sembol türü var.Semboller, aslında birer işaretçi olan metinlere yönlendiren birer hash tablosu. Yani, her bir karakteri tek tek karşılaştırmak yerine, işaretçinin kendisini karşılaştırarak eşitliği kontrol edebilirsiniz. Bu, kodlama dünyasında oldukça kullanışlı bir araç.

8. Sembol ve sabitlerin ağaçlarından oluşan bir kodlama notasyonu. Bu, bir dilin temel yapı taşlarını oluşturan sembollerin ve sabitlerin ağaç yapısını ifade eder.

9. Tüm dil, her daim orada. Okuma, derleme ve çalışma zamanı arasında net bir ayrım yok. Kodu okurken derleme veya çalıştırma işlemi yapabilirsiniz, derleme esnasında kodu okuyabilir veya çalıştırabilirsiniz ve çalışma zamanında da kodu okuyabilir veya derleyebilirsiniz. Bu, dilin dinamik ve esnek yapısını gösteren bir örnek.

Kodları okuma zamanında çalıştırma, kullanıcıların Lisp'in sözdizimini yeniden programlamalarına olanak sağlar. Derleme zamanında çalışan kodlar, makroların temelini oluşturur. Derleme işleminin çalışma zamanında yapılması, Lisp'in Emacs gibi programlara bir eklenti dili olarak eklenmesine imkan verir. Çalışma zamanında okuma ise, programların s-ifadeleri kullanarak iletişim kurabilmesini sağlar. Bu kavram yakın zamanda XML olarak yeniden keşfedildi.

Lisp ilk ortaya çıktığında, bu fikirler 1950'lerin sonunda kullanılan donanım tarafından belirlenen standart programlama uygulamalarından oldukça uzaktı. Ancak zamanla, bir dizi popüler dilin içinde yer aldığı varsayılan dil, yavaş yavaş Lisp'e yaklaştı. 1'den 5'e kadar olan fikirler artık oldukça yaygın. 6 numaralı fikir ana akımda yer almaya başladı. Python'da 7 numaralı fikirin bir formu var, ancak bunun için belirli bir sözdizimi gibi görünmüyor.

8. fikir, belki de tüm liste arasında en ilginç olanı. 8. ve 9. fikirler, Steve Russell'ın McCarthy'nin aslında hiç uygulanmasını düşünmediği bir şeyi hayata geçirmesi sonucu tamamen tesadüfen Lisp'in bir parçası oldu. Ancak bu iki fikir, hem Lisp'in tuhaf görünümünden hem de en belirgin özelliklerinden sorumlu. Lisp, garip bir sözdizimi olduğu için değil, aslında hiç sözdizimi olmaması nedeniyle tuhaf görünüyor. Programları, diğer dillerin ayrıştırıldığı zaman arka planda oluşan ayrıştırma ağaçlarındaki gibi ifade ediyorsunuz ve bu ağaçlar, listelerden oluşan Lisp veri yapılarını kullanıyor.

Dili kendi veri yapılarıyla ifade etmek, oldukça güçlü bir özellik haline gelir. 8 ve 9 numaralı fikirlerin birleşimi, program yazabilen programlar yaratabileceğinizi gösteriyor. Bu, ilk duyduğunuzda biraz tuhaf gelebilir, ama Lisp dilinde bu durum gayet normal. Bunu gerçekleştirmenin en yaygın yolu, genellikle _makro_ adı verilen bir özellik kullanmaktır.

Lisp'teki ""makro"" kelimesinin anlamı, diğer dillerdeki anlamından farklıdır. Lisp'teki bir makro, bir kısaltmadan yeni bir dilin derleyicisine kadar her şey olabilir. Eğer Lisp'i tam olarak anlamak ya da programlama becerilerinizi genişletmek istiyorsanız, makrolar hakkında daha fazla öğrenmeyi düşünmelisiniz.

Lisp anlamında makrolar, bildiğim kadarıyla, yalnızca Lisp'e özgü. Bunun bir sebebi, makroların olabilmesi için dilinizi muhtemelen Lisp kadar garip bir hale getirmeniz gerektiğidir. Ayrıca, bu son güç katkısını eklerseniz, artık yeni bir dil icat ettiğinizi iddia edemezsiniz, sadece Lisp'in yeni bir lehçesini yaratmış olursunuz.

Bunu daha çok şaka yollu söylüyorum ama gerçekten de bu tamamen doğru. Eğer car, cdr, cons, quote, cond, atom, eq ve bir de fonksiyonların listeler olarak ifade edildiği bir notasyonu içeren bir dil tanımlarsanız, o zaman Lisp'in tamamını bu öğelerle inşa edebilirsiniz. Aslında Lisp'i tanımlayan özellik de tam olarak budur: McCarthy, Lisp'in bu şekle bürünmesini sağlamak için bu öğeleri kullandı.

**Dillerin Önemli Olduğu Yer**

Diyelim ki Lisp, ana akım dillerin yavaşça yaklaştığı bir tür sınırı temsil ediyor. Peki, bu gerçekten yazılımınızı yazmak için onu kullanmanız gerektiği anlamına mı gelir? Daha az güçlü bir dil kullanarak ne kadar şey kaybediyorsunuz? Bazen yeniliklerin tam kenarında olmamak daha akıllıca olmaz mı? Ve bir dilin popülerliği bir bakıma kendi haklı çıkışını sağlamıyor mu?Bazen, sivri saçlı bir patronun, programcıların rahatça anlayabileceği bir dil kullanılmasını istemesi haklı olabilir. Programlama dili, her projede aynı derecede önemli olmayabilir. Genellikle, bir uygulama ne kadar karmaşık olursa, bir dilin gücünden o kadar fazla yararlanırsınız. Ancak çoğu proje o kadar da zorlu değildir. Çoğu zaman, programlama, küçük yapıştırıcı programlar yazmaktan ibarettir ve bu tür programlar için, aşina olduğunuz ve ihtiyacınız olan kütüphanelere sahip bir dili kullanabilirsiniz. Eğer tek yapmanız gereken bir Windows uygulamasından diğerine veri taşımaksa, tabii ki, Visual Basic kullanabilirsiniz.

Lisp'te de küçük yardımcı programlar yazabilirsiniz. Ben örneğin, bunu masaüstü hesap makinesi olarak kullanıyorum. Ancak, Lisp gibi dillerin en büyük avantajı, yoğun rekabetin olduğu alanlarda zor problemleri çözmek için karmaşık programlar yazmanız gerektiğinde kendini gösterir. Bunun güzel bir örneği, ITA Software'ın Orbitz'e lisansladığı havayolu ücret arama programıdır. Bu ekip, Travelocity ve Expedia gibi iki büyük ve piyasada çoktan yerini sağlamlaştırmış rakiplerin hakim olduğu bir pazara giriş yaptı ve onları teknoloji anlamında adeta yerle bir etti.

ITA'nın yazılımının çekirdeğinde, rakiplerinin çok ötesine geçen, 200.000 satır Common Lisp programı bulunuyor. Rakiplerinin büyük olasılıkla hala ana bilgisayar dönemi programlama tekniklerini kullandıklarına inanılıyor. (Elbette, ITA da bir anlamda ana bilgisayar dönemi bir programlama dili olan Lisp'i kullanıyor.) ITA'nın kodlarını hiç görmedim ama onların baş kod yazıcılarından birinin söylediğine göre, oldukça fazla makro kullanıyorlar ve bu durum beni hiç şaşırtmıyor.

**Merkezcil Kuvvetler**

Sözüm ona, yaygın olmayan teknolojileri kullanmanın hiçbir maliyeti yokmuş gibi bir şey söylemiyorum. Sivri saçlı patronun bu konuda endişelenmesi tamamen yanıltıcı değil. Ancak riskleri tam olarak anlamadığı için genellikle onları abartma eğiliminde olabiliyor.

Az kullanılan dilleri kullanmanın karşınıza çıkarabileceği üç sorun olduğunu düşünüyorum. Birincisi, yazdığınız programlar, diğer dillerde yazılan programlarla uyumlu çalışmayabilir. İkincisi, elinizde daha az sayıda kütüphane olabilir. Ve üçüncüsü, programcı bulmakta zorlanabilirsiniz.

Bu problemlerden her biri ne kadar ciddi? İlk faktörün önemi, tüm sistemi kontrol edip etmediğinize bağlı olarak değişir. Mesela, hatalı ve kapalı bir işletim sistemi üzerinde çalışacak bir yazılım yazıyorsanız (kimden bahsettiğimi söylemiyorum), uygulamanızı OS ile aynı dilde yazmanın avantajları olabilir. Ancak tüm sistemi kontrol ediyorsanız ve ITA'nın muhtemelen olduğu gibi tüm parçaların kaynak kodlarına sahipseniz, istediğiniz dili kullanabilirsiniz. Herhangi bir uyumsuzluk durumunda, bunu kendiniz halledebilirsiniz.

Sunucu tabanlı uygulamalar söz konusu olduğunda, en gelişmiş teknolojileri kullanabilirsiniz. Bence bu, Jonathan Erickson'un ""programlama dili rönesansı"" olarak tanımladığı durumun ana nedeni. İşte bu yüzden Perl ve Python gibi yeni diller hakkında konuşmalar duyuyoruz. Bu diller hakkında konuşuyoruz çünkü insanlar bu dilleri Windows uygulamaları yazmak yerine sunucularda kullanıyorlar. Ve yazılımın masaüstünden sunuculara kaydığı bir gelecekte (ki bu durumu Microsoft bile kabullenmeye başladı), ortalama teknolojileri kullanma baskısı da giderek azalacak.

Kütüphanelerin önemi de uygulamaya bağlıdır. Daha az karmaşık sorunlar söz konusu olduğunda, kütüphanelerin bulunabilirliği dilin doğal gücünden daha önemli olabilir. Ancak bu denge noktasını tam olarak belirlemek zor. Ancak şunu söyleyebiliriz ki, bu denge noktası, 'uygulama' olarak adlandıracağınız herhangi bir şeyden daha hızlı bir sürede gerçekleşir. Eğer bir şirket kendini yazılım işinde görüyorsa ve bir ürün olarak sunulacak bir uygulama yazıyorsa, bu işlem muhtemelen birkaç yazılımcıyı içerecek ve en az altı ay sürecektir.Bir projenin boyutu ne kadar büyük olursa, dil seçimi o kadar önemli hale gelir. Çünkü bu noktada, güçlü bir dilin avantajları, mevcut kütüphanelerin sunduğu kolaylıklardan daha ağır basmaya başlar.

Patronun üçüncü endişesi olan ""programcı bulma"" konusu, benim gözümde oldukça gereksiz bir endişe. Sonuçta, ne kadar çok hacker'a ihtiyacınız olabilir ki? Artık hepimiz biliyoruz ki, yazılım en iyi on kişiden az kişinin bulunduğu ekipler tarafından geliştirilir. Ve herhangi bir dilde bu ölçekte yazılımcıları işe almakta zorlanmamalısınız. Eğer on tane Lisp yazılımcısı bulamıyorsanız, belki de şirketiniz yazılım geliştirmek için yanlış bir şehirde konumlanmıştır.

Aslında, daha ileri seviye bir dil seçmek, ihtiyaç duyduğunuz ekibin boyutunu küçültme eğilimindedir. Çünkü (a) daha karmaşık bir dil kullandığınızda, muhtemelen bu kadar çok yazılımcıya ihtiyaç duymazsınız ve (b) daha ileri seviye dillerde çalışan yazılımcıların genellikle daha zeki olduğunu söyleyebiliriz.

Demek istediğim, ""standart"" olarak algılanan teknolojileri kullanmanız için yoğun bir baskı olmayacağı değil. Viaweb'de (şimdi Yahoo Store), Lisp dilini kullanarak hem yatırımcılarda hem de potansiyel alıcılarda hayret uyandırdık. Ancak aynı şekilde, ""endüstriyel"" sunucular olan Sun'ların yerine sıradan Intel kutularını kullanarak, Windows NT gibi gerçek bir ticari işletim sistemi yerine o dönemde çok bilinmeyen açık kaynaklı bir Unix türevi olan FreeBSD'yi tercih ederek ve artık kimse tarafından hatırlanmayan bir e-ticaret standardı olan SET'i görmezden gelerek de şaşkınlık yarattık.

Teknik kararları sizin yerinize 'takım elbise giyenlerin' vermesine asla izin veremezsiniz. Bizim Lisp kullandığımızı duyan potansiyel alıcılar biraz tedirgin oldu mu? Evet, biraz. Ama eğer biz Lisp kullanmasaydık, onların bizi satın almayı düşünmelerini sağlayacak yazılımı asla yazamazdık. Onların anormallik olarak gördüğü durum, aslında bir neden-sonuç ilişkisiydi.

Bir startup başlatıyorsanız, ürününüzü VC'ler veya olası alıcılara hitap etmek için tasarlamayın. _Ürününüzü kullanıcılara hitap edecek şekilde tasarlayın._ Kullanıcıları elde ederseniz, geri kalan her şey kendiliğinden gelir. Eğer bunu başaramazsanız, teknoloji seçimlerinizin ne kadar geleneksel veya rahatlatıcı olduğu kimseyi ilgilendirmez.

**Sıradan Olmanın Bedeli**

Daha az güçlü bir dil kullanmak ne kadar kaybettirir sizce? Bu konuda bir miktar bilgi mevcut aslında.

Muhtemelen gücün en rahat ölçüm yolu kod boyutudur. Üst düzey dillerin amacı, size daha büyük soyutlamalar sağlamaktır - sanki daha büyük tuğlalar veriyor gibi, böylece belirli bir büyüklükteki bir duvarı inşa etmek için çok fazla tuğlaya ihtiyaç duymazsınız. Dolayısıyla, dil ne kadar güçlü olursa, programınız da o kadar kısa olur (sadece karakter sayısı olarak değil, farklı elementler açısından da).

Daha güçlü bir dil nasıl daha kısa programlar yazmanızı sağlar? Eğer dil buna izin veriyorsa, kullanabileceğiniz bir teknik var: 'aşağıdan yukarıya programlama'. Bu yöntem ile uygulamanızı temel dilde yazmak yerine, temel dilin üzerine sizin programınızı yazmak için bir dil oluşturursunuz ve sonrasında bu yeni dilde programınızı yazarsınız. Bu şekilde birleştirilmiş kod, tüm programınızı temel dilde yazmış olsanızdan çok daha kısa olabilir - hatta çoğu sıkıştırma algoritması da bu mantıkla çalışır. Ayrıca 'aşağıdan yukarıya' programlar, birçok durumda dil katmanının hiç değişmemesi nedeniyle, değişikliklere de daha uyumlu olurlar.

Kod boyutu önemlidir, çünkü bir programı yazmak genellikle ne kadar süreceği, kodun ne kadar uzun olduğuna bağlıdır. Eğer başka bir dilde yazacağınız program üç kat daha uzun olacaksa, onu yazmak da üç kat daha uzun sürecektir. Ve ne yazık ki, daha fazla insan işe alarak bu durumu hızlandıramazsınız, çünkü belirli bir noktadan sonra yeni işe alımlar aslında net bir kayıp yaratır. Fred Brooks bu durumu ünlü kitabı ""Mitik Adam-Ayı""da anlatmıştı ve benim gözlemlerim de onun söylediklerini doğruluyor.

Peki, programlarınızı Lisp ile yazarsanız ne kadar kısa oluyor?Biraz teknik bir konuya değinelim mi? Örneğin, Lisp ve C dilleri arasındaki performans farkını duymuş muydunuz? Genellikle, Lisp'in C'ye göre 7-10 kat daha hızlı olduğunu söylerler. Ancak, 'New Architect' dergisindeki son bir makalede, ""bir Lisp kodunun 20 C kodunun yerini alabileceğini"" okuduğumu hatırlıyorum. Bu makalede ITA'nın başkanından alıntılar olduğunu düşünüyorum, yani bu bilgiye güvenebiliriz. ITA'nın yazılımı sadece Lisp değil, C ve C++ kodları da içeriyor, yani deneyimlerine dayanarak konuşuyorlar.

Ancak, bu kat sayıların sabit olmadığını düşünüyorum. Daha zorlu problemlerle karşılaştığınızda ve daha yetenekli programcılarınız olduğunda, bu kat sayıların artacağını tahmin ediyorum. Gerçek bir hacker, daha iyi araçlardan daha fazla verim alabilir.

Eğer bu verileri bir grafik üzerinde düşünürsek, ITA ile rekabet etmek ve yazılımınızı C dilinde yazmayı seçerseniz, onlar sizden tam yirmi kat daha hızlı yazılım geliştirebilirler. Eğer yeni bir özelliği geliştirmek için bir yılınızı harcarsanız, onlar bunu ancak üç haftada kopyalayabilirler. Ancak, eğer onlar yepyeni bir şey geliştirmek için sadece üç ay harcarsa, sizin bu özelliği kendi yazılımınıza eklemeniz tam _beş yıl_ alır.

Ve biliyor musunuz ne? Bu aslında en iyi senaryo. Kod-boyut oranlarından bahsettiğinizde, aslında daha düşük seviye bir dilde programı yazabileceğinizi varsayıyorsunuzdur. Fakat gerçek şu ki, bir programcının ne yapabileceği konusunda belirli sınırlar vardır. Daha düşük seviye bir dil ile zorlu bir problemi çözmeye çalışıyorsanız, bir noktada aklınızda aynı anda tutmanız gereken bilgilerin miktarı kontrolden çıkar.

Eğer ITA'nın hayali bir rakibinin, ITA'nın Lisp'te üç ayda yazabileceği bir şeyi beş yıl boyunca kopyalamak zorunda kalacağını söylüyorsam, bunun beş yılın sorunsuz geçtiği anlamına geldiğini belirtmek isterim. Ancak aslında, çoğu şirkette, beş yıl sürecek bir geliştirme projesi genellikle hiç tamamlanmaz.

Bu durumun aşırı olduğunu kabul ederim. ITA'nın hackerları gerçekten zeki gibi görünüyor ve C, oldukça teknik bir dil. Ama rekabetçi bir pazarda, iki ya da üçe bir oranındaki bir fark bile, her zaman geride olacağınızı garantiler.

**Bir Tarif**

Sivri saçlı patronun bile düşünmek istemeyeceği bir olasılıktan bahsediyoruz. Ve çoğu da düşünmüyor. Çünkü, ne de olsa, sivri saçlı patronun umrunda değil şirketin ne hale geldiği, yeter ki kimse bunun kendi hatası olduğunu kanıtlayamazsın. Kendi için en güvenli yol, sürünün göbeğinde sıkıca kalmaktır.

Büyük kuruluşlarda bu yaklaşıma ""sektörel en iyi uygulama"" denir. Asıl amaç, patronun sorumluluktan kaçmasına yardımcı olmaktır: Eğer patron ""sektörel en iyi uygulamayı"" seçer ve şirket zarar görürse, suçu üzerine alamazsınız. Çünkü aslında seçimini o yapmadı, sektör yaptı.

Bu terim, genelde muhasebe metodları gibi konuları tanımlamak için kullanılırdı. Anlamı kabaca, _tuhaf bir şey yapma_ demektir. Muhasebe alanında bu iyi bir fikir olabilir. ""Son teknoloji"" ve ""muhasebe"" kelimeleri bir arada pek hoş durmaz. Ama bu ölçütü teknolojik kararlara uyguladığınızda, yanlış sonuçlara ulaşabilirsiniz.

Teknolojinin çoğu zaman son teknoloji olması gerekiyor. Erann Gat'ın da vurguladığı gibi, programlama dillerinde ""endüstriyel en iyi uygulama"" aslında size en iyiyi değil, sadece ortalama bir performansı sunar. Daha agresif rakiplerinizden daha yavaş yazılım geliştirmenize sebep olan bir karar, ""en iyi uygulama"" ifadesini yanıltıcı hale getirir.

İşte burada sizinle çok değerli olduğunu düşündüğüm iki bilgiyi paylaşıyorum. Aslında bunları kendi deneyimlerimden öğrendim. Birincisi, dillerin gücü değişir. İkincisi, çoğu yönetici bu gerçeği göz ardı etmeye bayılır. İşte bu iki gerçek, para kazanmanın adeta bir tarifi gibidir. ITA, bu tarifin canlı bir örneği.Yazılım dünyasında başarılı olmak istiyorsanız, bazen zorlukları kabul etmek ve en güçlü dili kullanmak gerektiğini unutmayın. Ayrıca, rakiplerinizin 'sıradan' yöneticilerinin ortalama bir performansa geri dönmesini beklemek de önemli bir strateji olabilir. 

***

**Ek: Güç**

Programlama dillerinin nispi gücünü anlatan bir örnekleme yapmak istiyorum. Bir fonksiyon yazmak istiyoruz ve bu fonksiyon, birikimci - yani bir 'n' sayısı alıp, başka bir 'i' sayısı alarak 'n'yi 'i' kadar artıran bir fonksiyon - oluştursun.

(Burada kastettiğimiz _arttırma_, plus değil. Bir biriktirici, birikim yapmalıdır.)

Common Lisp'de bu işlemi (defun foo (n) (lambda (i) (incf n i))) kodu ile yaparsınız ve Perl 5'te ise aynı işlemi sub foo { my ($n) = @_; sub {$n += shift} } kodu ile gerçekleştirirsiniz. Perl'deki versiyonun daha fazla ayrıntıya sahip olmasının sebebi, Perl'de parametrelerin elle çıkarılması gerekliliğidir.

Smalltalk'ta kod, Lisp'teki foo: n |s| s := n. ^[:i| s := s+i. ] kodundan biraz daha uzun oluyor. Çünkü genellikle leksik değişkenler çalışırken, bir parametreye doğrudan değer atayamazsınız. Bu sebeple yeni bir 's' değişkeni oluşturmanız gerekiyor.

Javascript'teki örnek biraz daha uzun çünkü Javascript, ifade ve komutlar arasındaki farkı korur. Bu yüzden değerleri geri döndürmek için net bir 'return' ifadesine ihtiyacınız var: function foo(n) { return function (i) { return n += i } } (Adil olmak adına, Perl de bu farkı korur, fakat tipik Perl tarzında 'return' ifadelerini es geçmenize izin verir.)

Lisp/Perl/Smalltalk/Javascript kodunu Python'a çevirmeye çalıştığınızda bazı kısıtlamalarla karşılaşırsınız. Python, leksik değişkenleri tam desteklemediği için n'nin değerini saklamak için bir veri yapısı oluşturmanız gerekir. Python'un fonksiyon veri türü olsa da, tek bir ifade dışında bir fonksiyonu temsil etmek için bir gösterim bulunmamaktadır. Bu yüzden, döndürmek için isimli bir fonksiyon oluşturmanız gerekiyor. Sonuç olarak aşağıdaki kodu elde edersiniz:

def foo(n):

  s = [n]

  def bar(i):

    s[0] += i

    return s[0]

  return bar

Python kullanıcıları, neden sadece

def foo(n):

  return lambda i: n += i

veya 

def foo(n):

  lambda i: n += i 

yazamadıklarını merak edebilirler. Benim tahminim, bir gün muhtemelen bunu yapabilecekler. (Eğer Python'un Lisp'e tamamen evrilmesini beklemek istemiyorlarsa, her zaman... şeklinde de düşünebilirler.)

Nesne yönelimli dillerde, bir closure'ı (yani, çevreleyen kapsamlarda tanımlanan değişkenlere atıfta bulunan bir fonksiyonu) bir dereceye kadar taklit edebilirsiniz. Bunun için, çevreleyen kapsamdaki her bir değişkeni temsil edecek bir alan ve bir metoda sahip bir sınıf tanımlarsınız. Bu, programcının, sözdizimsel kapsamı tam olarak destekleyen bir dilin derleyicisi tarafından yapılacak türden bir kod analizi yapmasını gerektirir. Ancak bu, bir değişkene birden fazla fonksiyonun atıfta bulunduğu durumlarda işe yaramaz. Ancak bu, bu gibi basit durumlar için genellikle yeterli olur.

Python konusunda deneyimli kişiler, bu kodların Python'da bu problemi çözmenin en uygun yolu olduğunda genelde hemfikir oluyorlar. Bu kodları burada paylaşıyorum çünkü Python'u savunanların, dilin yanıltıcı olduğunu öne sürmelerini istemem. Ancak her iki örnek de bana ilk versiyondan daha karmaşık geliyor. Aslında aynı işi yapıyorsunuz, birikimleri tutmak için ayrı bir yer oluşturuyorsunuz; sadece bir liste başı yerine bir nesnenin içindeki bir alan. Ve bu özel, ayrılmış alan isimlerinin kullanımı, özellikle __call__, biraz hile gibi görünüyor.

Perl ve Python arasındaki rekabette, Python geliştiricileri genellikle Python'un Perl'e kıyasla daha zarif bir alternatif olduğunu iddia ediyor. Ancak bu örnekte görüyoruz ki, gerçek zarafet aslında güçtür: Perl programı, dil bilgisi biraz daha çirkin olsa bile, daha sade (daha az elemanlı).

Peki ya diğer programlama dilleri? Bu konuşmada bahsi geçen Fortran, C, C++, Java ve Visual Basic gibi dillerde bu problemi çözüp çözemediğiniz konusunda net bir şey söylemek zor.Ken Anderson, aşağıdaki Java kodunun, belirli bir problemi çözmek için en iyi yaklaşım olduğunu söylüyor:

```java
public interface Inttoint { 
    public int call(int i); 


public static Inttoint foo(final int n) { 
    return new Inttoint() { 
        int s = n; 
        public int call(int i) { 
            s = s + i; 
            return s; 
        }
    }; 
}
```

Ancak, bu çözüm sadece tam sayılarla sınırlı olduğu için, tam anlamıyla istenilen çözüm olmaktan uzak. Java hakkında yaptığım birçok e-posta alışverişi sonucunda, benzer durumlarla karşılaştığımı söyleyebilirim. Bu tür bir polimorfik çözümün yazılmasının ya çok zor ya da imkansız olduğunu söyleyen birçok kişiyle karşılaştım. Eğer biri bunu başarabilirse, sonucu görmekten çok memnun olurum, ancak ben bu konuyu kapatmaya karar verdim.

Tabii ki, bu sorunu başka dillerde çözemezsiniz diye bir durum kesinlikle söz konusu değil. Tüm bu dillerin Turing'e eşdeğer olması, aslında herhangi bir programı hangi dilde isterseniz o dilde yazabileceğinizi gösteriyor. Peki, bunu nasıl yapardınız? İşin en uç noktasında, daha az güçlü bir dilde Lisp yorumlayıcısı yazarak bu mümkün olabilir.

Bu bir şaka gibi gelebilir, ancak bu durum büyük programlama projelerinde o kadar sık yaşanıyor ki, bu durumu tanımlamak için 'Greenspun'un Onuncu Kuralı' gibi bir isim bile var.

> Yeterince karmaşık bir C veya Fortran programı, genellikle Common Lisp'in yarısının hatalı, yavaş ve düzensiz bir uygulamasını barındırır.

Zor bir problemi çözerken, asıl mesele kullanacağınız dilin ne kadar güçlü olduğu değil, şu üç seçenekten hangisini yapacağınızdır: (a) güçlü bir dil kullanmak, (b) bir dil için yorumlayıcı yazmak, veya (c) bir dilin insan derleyicisi olmak. Python örneğinde bunun zaten başladığını görüyoruz. Burada, bir derleyicinin sözcüksel bir değişkeni uygularken üreteceği kodu adeta canlandırıyoruz.

Bu uygulama sadece yaygın olmakla kalmıyor, aynı zamanda kurumsal bir hale de bürünüyor. Örneğin, nesne yönelimli programlama dünyasında ""kalıplar"" hakkında sıkça konuşulur. Bu kalıpların bazen, insanın bir derleyici gibi çalıştığı durumları (yani durum c'yi) gösteriyor olabileceğini düşünürüm. Programlarımda kalıplar gördüğümde, bu durumu bir problem belirtisi olarak algılarım. Bir programın tasarımı, sadece çözmesi gereken problemi yansıtmalıdır. Kodda var olan her türlü düzenlilik, bana göre, kullandığım soyutlamaların yeterince güçlü olmadığının bir işaretidir. Genellikle, yazmam gereken bir makronun ayrıntılarını elle çıkarttığımı gösterir.

#### Notlar

* IBM 704 işlemcisi, bir buzdolabı kadar büyük olmasına rağmen, ondan çok daha ağırdı. İşlemci tam 1428 kilogram ağırlığındaydı ve 4K RAM ise ayrı bir kutuda, tam 1814 kilogram ağırlığındaydı. Oysa ki, evlerimize sığabilen en büyük buzdolaplarından biri olan Sub-Zero 690 modeli, sadece 297 kilogram ağırlığında.

* Steve Russell, 1962'de tarihteki ilk dijital bilgisayar oyunu olan Spacewar'ı yazan kişi olarak da bilinir.

* Eğer teknik konularda pek bir bilgisi olmayan bir patronunuz varsa ve siz Lisp'te yazılım yapmak istiyorsanız, ona Lisp'in aslında XML olduğunu söyleyerek ikna edebilirsiniz.

* İşte diğer Lisp lehçelerinde akümülatör üreteci: Scheme'de: (define (foo n) (lambda (i) (set! n (+ n i)) n)) Goo'da: (df foo (n) (op incf n _))) Arc'da: (def foo (n) [++ n _]) şeklinde yazılır.

* Erann Gat'ın JPL'deki ""sektördeki en iyi uygulamalar"" üzerine olan hüzünlü hikayesi, bu genellikle yanlış kullanılan ifadeyi ele almam için bana ilham verdi.

* Peter Norvig, _Design Patterns_ kitabındaki 23 kalıptan 16'sının Lisp dilinde ""görünmez veya daha basit"" olduğunu keşfetti.

* Çeşitli diller hakkında sorularıma yanıt veren ve/veya bu yazının taslaklarını okuyan Ken Anderson, Trevor Blackwell, Erann Gat, Dan Giffin, Sarah Harlin, Jeremy Hylton, Robert Morris, Peter Norvig, Guy Steele ve Anton van Straaten gibi birçok kişiye teşekkürlerimi sunuyorum. Fakat belirtmek isterim ki, burada ifade edilen tüm görüşler tamamen bana aittir ve bu kişiler bu görüşlerden sorumlu tutulamazlar.

**İlgili:**

Bu konuşma hakkında birçok geri dönüş aldım. Bu, programlama dünyasında sıkça karşılaşılan bir durum ve çözüm yollarını anlamak, her birimizin daha iyi bir yazılımcı olmasına yardımcı olabilir. Bu konuda daha fazla bilgi edinmek isterseniz, aşağıdaki kaynaklara göz atabilirsiniz:

- [Greenspun'un Onuncu Kuralı](https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule)
- [Turing Makinesi](https://en.wikipedia.org/wiki/Turing_machine)
- [Lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language))Bu yüzden, tüm bu değerli yorumları inceleyebilmek ve tartışmaları sürdürebilmek için **Zeki Çocukların İntikamı** adlı bir sayfa oluşturdum. Bu sayfa, gelen her yoruma adeta bir yanıt niteliğinde. 

Bu konu, LL1 e-posta listesinde oldukça kapsamlı ve genellikle yararlı bir tartışma başlattı. Özellikle Anton van Straaten'in semantik sıkıştırma hakkındaki e-postasını incelemenizi öneririm. Gerçekten de düşündürücü ve bilgilendirici bir içerik.

LL1'deki bazı diğer e-postalar, dilin gücü üzerine yazdığım 'Öz, Güçtür' adlı yazımı daha da derinleştirmem için beni teşvik etti. Bu yüzden, bu konuda daha fazla bilgi edinmek isterseniz, bu yazıyı okumanızı tavsiye ederim.

Ayrıca, **Akümülatör Jeneratör Benchmark** uygulamalarının daha geniş bir kısmını kendi sayfalarında derledik. Bu sayede, bu konuda daha fazla bilgi edinmek isteyenler için kapsamlı bir kaynak sunmuş olduk.""""

---

İlişkili Konseptler: programlama dillerinin gücü, Lisp dili, programlama dili karşılaştırması, alttan yukarı programlama, programlama dili verimliliği, programlama dili kod boyutu, yazılım işi için programlama dili, programlamada endüstri en iyi uygulamaları, programlama dili rönesansı, programlama dillerinde güç ve zarafet, karmaşık programlar için programlama dili, programlama dilleri ve problem çözme, Lisp ve Python karşılaştırması, Lisp ve Java karşılaştırması, Lisp ve Perl karşılaştırması, Lisp ve C++ karşılaştırması, Lisp ve Fortran karşılaştırması, Lisp ve C karşılaştırması, Lisp ve Visual Basic karşılaştırması, rekabetçi pazar için programlama dili, karmaşık problemler için programlama dili, yenilikçi çözümler için programlama dili, son teknoloji için programlama dili, ileri uygulamalar için programlama dili, yüksek seviye görevler için programlama dili, yazılım geliştirme için programlama dili, yazılım endüstrisi için programlama dili, yazılım yenilikleri için programlama dili, yazılım rekabeti için programlama dili, yazılım verimliliği için programlama dili, yazılım gücü için programlama dili, yazılım karmaşıklığı için programlama dili, yazılım ilerlemesi için programlama dili, yazılım için son teknoloji programlama dili, yazılım için yüksek seviye programlama dili."

Subscribe

Listen to Yiğit Konur'un Okuma Listesi using one of many popular podcasting apps or directories.

Spotify Pocket Casts Amazon Music YouTube
← Previous · All Episodes · Next →