Hofstadter’in Lisp Üzerine Yorumu (1983)
(gist.github.com/jackrusher)- Douglas Hofstadter’in 1983 tarihli yazısı, yapay zeka araştırmalarında yaygın olarak kullanılan Lisp’i küçük bir matematiksel çekirdek üzerine kurulmuş zarif ve esnek bir dil olarak tanıtıyor
- Lisp’in etkileşimliliği read-eval-print loop içinde ortaya çıkar; kullanıcı bir ifade girdiğinde yorumlayıcı bunu okur, değerlendirir, çıktısını verir ve ardından bir sonraki girdiyi bekler
- Lisp nesneleri esas olarak atom ve liste etrafında kurulur;
nilise hem boş liste hem de atom olmasıyla istisnai bir konuma sahiptir quote,eval,car,cdr,cons,setq,set,lambda,def,cond; kod ile veriyi aynı liste yapısı içinde ele almayı mümkün kılar ve yeni işlevlerin kademeli olarak oluşturulmasına izin verir- İşlev bileşimi, koşul ifadeleri, yan etkiler ve applicative stil ile özyinelemeli düşünce örnekler üzerinden birbirine bağlanır; sondaki
powerişlevi ve “porpuquine” benzetmesi Lisp tarzı özyinelemeye işaret eder
Yapay zeka araştırmalarında Lisp’in yeri
- 1983 itibarıyla yapay zeka; esneklik, sağduyu, içgörü, yaratıcılık, öz farkındalık ve mizah gibi davranışları bilgisayarda gerçekleştirmeyi amaçlayan bir araştırma alanıydı
- ABD’de yapay zekayla profesyonel olarak ilgilenen yaklaşık 2 bin kişi vardı; yurtdışında da benzer ölçekte araştırmacı bulunuyordu
- Yapay zeka araştırmacıları, yapay zekaya giden en iyi yol konusunda ciddi biçimde ayrışmış olsalar da, programlama dili seçiminde neredeyse ortak biçimde Lisp kullanıyordu
- Lisp adı “list processing” ifadesinden gelir; tam anlamıyla bir kısaltma değildir
- Lisp’in çekiciliği, “crisp” ve “elegant” bir dil olmasında yatar
- Pek çok dil çok sayıda keyfi özelliği içine toplarken, Lisp ve Algol gibi bazı diller matematiğin bir dalı gibi doğal bir çekirdek etrafında kurulur
- Lisp’in çekirdeği “crystalline purity” taşır; bu saflık yalnızca estetik duyguya değil, esnekliğe de katkı sağlar
Matematiksel mantıktan liste işleme diline
- Lisp’in derin kökleri matematiksel mantık içindedir
- Thoralf Skolem, Kurt Godel ve Alonzo Church’ün 1920’ler ve 1930’larda mantığa bıraktığı fikirler daha sonra Lisp’e dahil edildi
- Asıl bilgisayar programlama 1940’larda başladı; Lisp gibi yüksek seviyeli diller ise 1950’lerde ortaya çıktı
- İlk liste işleme dili Lisp değil, IPL (Information Processing Language) idi
- IPL, 1950’lerin ortasında Herbert Simon, Allen Newell ve J. C. Shaw tarafından geliştirildi
- John McCarthy, 1956–1958 arasında mevcut fikirler üzerine kurulu cebirsel bir liste işleme dili olarak Lisp’i yarattı
- Lisp, MIT Artificial Intelligence Project çevresindeki genç araştırmacılar arasında hızla yayıldı
- IBM 704 üzerinde gerçeklendi ve diğer yapay zeka gruplarına da yayıldı
- Çeşitli lehçeleri ortaya çıktı ama zarif merkezî çekirdek ortak kaldı
Etkileşimli Lisp ve REPL
- Lisp, birçok diğer yüksek seviyeli dilden farklı olarak etkileşimli bir dil olarak sunulur
- Kullanıcı terminalde Lisp’i çalıştırır, istemi görür ve bir ifade girer
- Örnek:
(plus 2 2)girildiğinde4yazdırılır ve yeni bir istem görünür
- Örnek:
- Lisp yorumlayıcısının temel davranışı read-eval-print looptur
- İfadeyi okur
- İfadeyi değerlendirir
- Uygun değeri yazdırır
- Bir sonraki ifadeyi okumaya hazır olduğunu bildirir
- Bu yapı sayesinde kullanıcı “dileklerini” birer birer girip sonucu hemen görebilir
- Etkileşimli olmayan birçok dilde önce tüm programın yazılıp sonra çalıştırılması gerekir; bu da çok sayıda adımın kusursuz biçimde birbirine oturmasını gerektirir ve hata düzeltmeyi dolaylı, maliyetli bir sürece dönüştürür
- Lisp, ifadeleri teker teker çalıştırma yaklaşımıyla kademeli geliştirme ve hata ayıklama olanağı sağlar
Polish notation ve parantezler
- Lisp’in aritmetik ifadeleri, işlecin işlenenlerden önce geldiği Polish notation kullanır
- Örnek:
(times (plus 6 3) (difference 6 3))ifadesi 27 olarak değerlendirilir
- Örnek:
- Bu gösterim, Polonyalı mantıkçı Jan Lukasiewicz’in bilgisayarlardan önce geliştirdiği bir notasyondur
- Lisp ifadelerinde çok sayıda parantez bulunur
- Uzun ifadelerin birkaç kapanış paranteziyle bitmesi olağandır
- Başta göz korkutucu gelse de alışınca mantıksal yapı sezgisel biçimde görünür hale gelir
- Örnekler, yapıyı girintilerle görünür kılan pretty printing biçiminde verilir
Atomlar, listeler, nil
- Lisp’in özü, üzerinde işlem yapılabilen yapılardır; tüm programlar yapı kurarak, değiştirerek ve yok ederek çalışır
- Yapılar iki türdür
- Atom: daha fazla bölünemeyen temel nesne
- Liste: birden çok öğenin belirli bir sırada toplandığı yapı
- Tüm Lisp nesneleri ya atomdur ya da listedir; tek istisna **
nil**dirnilhem atomdur hem listedirnil, boş listeyi temsil eder()ilenilaynı anlama gelir, ama daha sıknilkullanılır
- Bir listenin öğeleri atom da olabilir, liste de olabilir
- Örnek:
(zonk blee strill (croak flonk))dört öğeli bir listedir; son öğe ayrıca iki öğeli başka bir listedir
- Örnek:
- Lisp cümlelerinin kendisi de listedir
(plus 2 2)de bir listedir- Lisp yorumlayıcısı listeleri ve atomları işleyerek yeni “komutlar” üretebilir ve değerlendirebilir
Değerler, quote, eval
- Atomlar bir değere sahip olabilir
- Sayı atomlarının kalıcı değeri kendileridir
nilin değerinildirtde kalıcı değeri kendisi olan özel bir atomdur
setq, bir atoma değer atar(setq pie 4)ifadesipiedeğerini 4 yapar(setq pie (plus 2 2))ifadesi depiedeğerini 4 yapar
- Bir atomun değeri yalnızca sayı değil, herhangi bir Lisp nesnesi olabilir
- Atom da olabilir, liste de olabilir
quote, değerlendirmeyi engeller ve bir liste ya da atomun doğrudan veri olarak ele alınmasını sağlar(setq pie (plus 2 2))içteki ifadeyi değerlendirippieiçine 4 koyar(setq pi '(plus 2 2))ise listenin kendisini, yani(plus 2 2)ifadesinipiiçine koyar
eval, değer olarak saklanmış ifadeyi yeniden değerlendirirpideğerinin(plus 2 2)olması durumunda(eval pi)4 döndürür- Yorumlayıcı normalde yalnızca bir adım değerlendirir;
evalile ek değerlendirme istenebilir
car, cdr, cons
nildışındaki her liste en az bir öğe içerir ve ilk öğesinecardenir(eval pi)ifadesinincarıevaldir(plus 2 2)ifadesinincarıplustır
car’ın mutlaka bir işlev adı olması gerekmez((1)(2 2) (3 3 3))ifadesinincarı(1)dir
carçıkarıldığında geride kalan listeyecdrdenir(a b c d)ifadesinincdrı(b c d)dir- Ardından
(c d),(d),nilolarak küçülür
niliçin necarnecdrvardır;carya dacdralınmaya çalışılırsa hata vermelidircons, mevcut bir listenin önüne yeni bircarekleyerek yeni bir liste oluştururxdeğeri(cake cookie)iken(cons 'pie x)ifadesi(pie cake cookie)üretir- Bu sırada mevcut
xdeğişmez
quotekullanılıp kullanılmamasına göre sonuç değişirpiedeğeri 4 ise(cons pie x)ifadesi(4 cake cookie)döndürür(cons 'pie x)ise atom adı olanpieyi başa ekler
setq ile set arasındaki fark
- Lisp yorumlayıcısı her zaman argümanları değerlendirmez;
setqbunun başlıca istisnalarından biridir setqiçindeki ilk argüman değerlendirilmez, doğrudan değişken adı olarak ele alınırsetqiçindekiq, quote anlamına gelir; yani ilk argüman sanki alıntılanmış gibi işlenir
set,setqya benzer ama ilk argümanı da değerlendirirxdeğerikiken(set x 7)ifadesixi değil,knın değerini 7 yapar
- Örnek olarak şu sıra verilir
(setq a 'b)(setq b 'c)(setq c 'a)(set a c)(set c b)
- Bunun ardından
a,b,cdeğerlerinin üçü deaolur setyaygın kullanılmaz; bu tür karışıklıklar da sık yaşanmaz
İşlev tanımı ve lambda
- Programlamanın büyük gücü, mevcut işlemlerden yeni bileşik işlemler tanımlamakta ve bunu tekrar ederek giderek daha karmaşık bir işlem repertuvarı oluşturmaktadır
- Lisp’te yeni işlevler, zaten bilinen işlevler kullanılarak tanımlanır
rac, bir listenin son öğesini döndüren örnek bir işlevdir- Son öğeyi almak için liste ters çevrilir ve ardından
caralınır - Tanım:
(def rac (lambda (lyst) (car (reverse lyst))))
- Son öğeyi almak için liste ters çevrilir ve ardından
lambdasonrasındaki(lyst), işlevin parametresini yani kukla değişkenini gösterirdefile tanımlandıktan sonrarac,cargibi kullanılabilen bir işlev haline gelir(rac '(your brains))ifadesibrainsdöndürür
readers-digest-condensed-versionadlı işlev, uzun bir listeden yalnızca ilk ve son öğeyi içeren kısa bir liste üretir- James Joyce’un Finnegans Wake eserinin tamamı bir sözcük listesi kabul edildiğinde
(riverrun the)sonucunun elde edildiği örneği verilir
- James Joyce’un Finnegans Wake eserinin tamamı bir sözcük listesi kabul edildiğinde
rejoyceadlı ters işlem ise başı ve sonu iki sözcükle belirlenmiş bir roman üreten hayalî bir işlevdir; yazımı okura alıştırma olarak bırakılır
Değer döndürme, yan etkiler, applicative stil
- Bazı insanlar Lisp ve ilgili dillerde iki hedefin hem arzu edilir hem de mümkün olduğunu düşünür
- Her cümle bir değer döndürmelidir
- Cümlelerin etkisi yalnızca döndürdükleri değerler aracılığıyla ortaya çıkmalıdır
- Yazıda ele alınan Lisp lehçeleri ilk koşulu sağlar ama ikinci koşulu zorunlu olarak sağlamaz
(reverse x),xin kendisini değiştirmez; onunla aynı ama sırası ters çevrilmiş yeni bir liste üretip döndürür- Bu,
(plus 2 2)ifadesinin 2’nin değerini değiştirmemesiyle aynı mantıktadır
- Bu,
consda mevcut listeyi değiştirmez, yeni bir liste döndürür- Buna karşılık
setq, değişken bağını değiştiren bir yan etki bırakan komut örneğidir- Yan etkiler, değişken bağlarının değişmesi dışında girdi/çıktıyı da içerebilir
- Applicative programlamayı savunanlar, yan etki olmadan işlevlerin değer hesaplayıp aktardığı yaklaşımı tercih eder
- Bu stilde izin verilen bağlar, işlev çağrısı sırasında geçici olarak oluşan lambda bindingdir
- İşlev hesabı tamamlandığında kukla değişkenin bağı kaybolur
- Yazının anlatıcısı applicative stili zarif bulsa da, büyük yapay zeka tarzı programlar kurarken pratik olmadığını düşünür
- Katı applicative programlamada, kalıcı işlev tanımını belleğe yazdığı için
defbile izin verilmeyen uç bir örnek sayılır
Koşul ifadesi cond ve karar verme
- Lisp’in daha ilginç işler yapabilmesi için ara aşamalarda olan bitene göre karar verebilmesi gerekir; bunun için koşul ifadesi gerekir
- Örnek:
(cond ((eq x 1) 'land) ((eq x 2) 'sea))x1 iselandx2 isesea- Bunların dışında
nildöndürür
eq, iki argümanın değeri aynıysat, farklıysanildöndüren bir Lisp işlevdircondifadesi,condadlı işlev adıyla başlar ve birden çok madde içerir- Her madde, koşul ve sonuçtan oluşan iki öğeli bir listedir
- Koşullar sırayla sınanır;
nildışında bir değer döndüren ilk koşul bulunduğunda, onun sonucu değerlendirilir ve tümcondifadesinin değeri olarak döndürülür - Sonraki maddeler artık sınanmaz
- Sona koşul olarak
tkonan bir catch-all madde eklenirse,nilyerine varsayılan sonuç döndürülebilir- Örnek olarak, hem land hem sea koşulları başarısız olursa
airdöndüren bircondverilir
- Örnek olarak, hem land hem sea koşulları başarısız olursa
Kuvvet ve özyinelemeli yapı
- Yazının sonunda belirgin bir örüntü taşıyan işlev tanımları gelir
square,k * kdircube,k * square(k)dir4th-power,k * cube(k)dir- Ve aynı biçimde devam eder
- Bu örüntünün tamamını bir kerede kapsayan iki parametreli
powerişlevinin tanımlanıp tanımlanamayacağı soru olarak ortaya konur(power 9 3)729 olmalıdır(power 7 4)ise 2,401 döndürmelidir
- Gerekli araçların tümü metin içinde verilmiştir; gerisi okurun zekasına bırakılır
- Sondaki Glazunkian porpuquine hikâyesi, özyinelemeli yapıyı alegorik biçimde ele alır
- Porpuquine’in dikenleri daha küçük porpuquine’lerdir
- Outer Glazunkia’da daima 9, Inner Glazunkia’da daima 7 diken bulunur
- 0 inçlik porpuquine’de diken olmadığı için sonsuz gerileme durur
- Bu hayvanın “buying power”ı ya da “power”ı, içinde yer alan küçük 0 inçlik porpuquine burunlarının sayısıyla ilişkilendirilir ve anlatı daha önce verilen
powerproblemiyle bağlantılı bir benzetmeyle sona erer
Orijinal metnin yeniden paylaşım bağlamı
- Gist’in baş kısmı, bu yazının Douglas Hofstadter’in 1980’lerin ortalarında Scientific American eski sayılarında rastlanan Lisp tanıtım yazısı olduğunu belirtir
- Örnekler, Emacs içinde birkaç takma ad kurulursa hâlâ çalıştırılabilir
plus→+quotient→/times→*difference→-
- Son bölüm, Hofstadter’in bu kendine özgü Lisp rehberinden hoşlananların, benzer yazıları Metamagical Themas kitabında da bulabileceğini söyler
1 yorum
Hacker News yorumları
Örnekteki
"oval"ve"snot"fonksiyon adları kafamı karıştırdı; birkaç saniye sonra bunların sırasıyla"eval"ve"snoc"yazım hataları olduğunu fark ettim.Asıl kod
(cond ((eq (eval pi) pie) (eval (snoc pie pi))) (t (eval (snoc (rac pi) pi))))şeklinde okunmalı.https://www.jstor.org/stable/24968822 adresinden özgün Scientific American yazısını indirip kontrol edince, gerçekten de
oval/snotıneval/snociçin yazım hatası olduğunu gördüm."oval"ve"snot", gerçekten"eval"ve"snoc"yazım hatası.Ayrıca
snoc, ters çevrilmişcons;racde ters çevrilmişcargibi görünüyor.Bu yazı, Lisp'in popülerliğinin zayıf kalmasının temel nedeninin Lisp'in anlatılma biçimi olduğunu yeniden gösteriyor.
Bu tür Lisp yazıları, çocukluğumdaki bana gerçekten kullanabileceğim hiçbir şey öğretmiyor; Assembly/C/Pascal vb. ile karşılaştırıldığında herhangi bir X işini ne kadar kolaylaştırdığını da göstermiyordu.
Şimdiki ben olsam, “Assembly ile 7 ay süren bir yazım denetleyici mi? Bank-switching bellek kullanan bir mikrobilgisayarda Lisp ile bu neredeyse önemsiz bir iş; çöp toplama da berbat bir CPU'da deterministik hâle getirilebilir” diye gösterirdim.
Sayısız Lisp yazısı ve ders kitabı sadece listeleri, özyinelemeyi ve yapay zekayı tekrarlayıp durdu; yararlı bir şeyin nasıl yapılacağını göstermediği için, cımbız, pirinç tanesi ve tutkalla program yazmışım gibi geçen zamana üzülüyorum.
Çocukken ilk gördüğüm Byte dergisinde, Lisp ile yazılmış sembolik türev alma ve cebirsel sadeleştirme kodu vardı; takip etmesi zordu ama bir şekilde çekici gelmişti.
Basic ile daha kolay olmasına imkân yoktu; sonradan o kodun çok da iyi olmadığını gördüm, ama 80'lerin sonlarında PC'de XLisp ve SICP ile tanıştıktan sonra Lisp'e gerçekten kapıldım.
Hofstadter'in yazı üslubunu gerçekten seviyorum. Lisp'i keşfettiğimde hissettiklerimi iyi yakalıyor.
80'lerde programlama öğrenen bir çocuktum; lise ve üniversitenin başlarında BASIC, Fortran, Pascal, COBOL'u zaten biraz denemiştim. Aralarında farklar vardı ama temelde ortak yanları bulunuyordu.
Fakat UC Berkeley'deki ilk bilgisayar bilimi dersim, bir Lisp lehçesi olan Scheme ile yürütüldü ve bu tamamen sarsıcıydı.
Hofstadter'in dediği gibi, matematiğe en yakın şey gibi hissettiriyordu; bana sık sık matematik kuramı derslerini hatırlatıyordu ve keşfettiğim ilk güzel dildi.
“Lisp ve Algol, matematiğin bir dalı gibi doğal bir çekirdek etrafında inşa edilmiştir. Lisp'in çekirdeğinde, yalnızca estetik duyguya hitap etmekle kalmayıp onu çoğu dilden çok daha esnek kılan kristal gibi bir saflık vardır” alıntısını özellikle sevmiştim.
Cebirsel topolog olmak istemiş biri olarak bile Scheme, dinamik tipler ve çöp toplama kullanan dillerin geneline yayılmış programlama stilinin zarif ve minimal bir ifadesine daha yakın.
Tamamlanmış gibi görünmesi ve Scheme ile bir problem çözme biçimini düşünüp sonra bunu başka dinamik tipli dillere taşıdığınızda da zarif çözümlere ulaşabilmeniz anlamında “teori” gibi hissettiriyor.
Scheme, o dönemin geleneksel Lisp'ine kıyasla leksik kapsam, fonksiyonlar ve değişkenler için tek ad alanı gibi yönlerde sadeleştirilmiş ve toparlanmış bir dildi.
1983, bu alanın başlamasından yaklaşık 20 yıl sonrasına denk geliyor; yazı ise bilgisayarları “esneklik, sağduyu, içgörü, yaratıcılık, öz farkındalık, mizah” sahibi olacak şekilde programlamaktan söz ediyor.
Bu listenin LLM'lerin gerçekten beceremediği şeylerin listesi gibi okunması epey ilginç.
Yine de en azından o yönde sıfır olmayan bir ilerleme kaydedilmiş sayılır.
Belki daha fazlasını bile gösterdiklerini hissediyorum; ama böyle söyleyince kulağıma bile biraz tuhaf geliyor.
Çoğu henüz sonuca dönüşmemiş olsa da okumaya değer derecede ilginç.
Bu yazıyla birlikte anılan iki eşlikçi yazı, Hofstadter'in Metamagical Themas kitabının 17-19. bölümlerinde yer alıyor; Scientific American'daki aynı dizide yayımlanan diğer yazılar da kitapta bulunuyor.
[0]: https://www.goodreads.com/book/show/181239.Metamagical_Thema...
Kitabın başlığı, Martin Gardner'ın Scientific American'da yazdığı “Mathematical Games”in anagramından gelen köşe başlığından türemiş; Hofstadter o köşeyi devralmıştı.
Yazıda
nilüzerinecarya dacdruygulanırsa, sıfıra bölme gibi hata vermesi gerektiği söyleniyor; ancak modern Lisp’te çoğu zaman artık böyle değilJohn McCarthy’nin tanımladığı özgün Lisp’te
CARveCDR,NILiçin tanımlı değildi: <https://dl.acm.org/doi/pdf/10.1145/367177.367199>Ancak Common Lisp ve Emacs Lisp,
(car nil)ile(cdr nil)ifadelerininilolarak tanımlar: <https://www.lispworks.com/documentation/HyperSpec/Body/f_car...>, <https://www.gnu.org/software/emacs/manual/html_node/elisp/Li...>LISP 2156içinde(status lispversion)/2156döndürdü;(car nil)ve(cdr nil)ise ikisi deNILdöndürdücarvecdrgibi son derece somut uygulama ayrıntılarının merkeze yerleşmiş olması şaşırtıcı“List Processor”ın en temel ve en ünlü operatörleri aslında listeler üzerinde değil, Lisp’in veri yapıları oluştururken kullandığı belirli bir makine temsili öğesi olan cons üzerinde çalışacak şekilde tasarlanmıştı
cons her zaman liste olarak yorumlanmaz; liste özyinelemeli fonksiyonların temel durumu olan çok önemli liste de cons ile temsil edilmez
60 yıl sonra bile Lisp programlarının çoğu cons işlemleriyle dolu ve belki de daha doğru ad “Cons Processor” olurdu
Bu, Lisp’in dil ile uygulamanın iç içe geçmek zorunda olduğu bir dönemde doğduğunu hatırlatıyor; bu yüzden bir bilgisayar dilini matematiksel mantığa dayandırma başarısı daha da şaşırtıcı geliyor
nilinCARya daCDRını almak hatadırnilincar/cdrı hata olduğu için, benim gibi yeni başlayanlara kod epey ergonomik olmayan bir his veriyorYine de Guile Scheme’i Common Lisp’e tercih ettiğim için bu durum üzücü
nile bir şey uygulandığında hata vermeden tekrarnildöndüren bu dil tasarımı tercihinin bir adı olup olmadığını merak ediyorumSQL de akla geliyor; kişisel olarak bunun iyi bir tercih olmadığını düşündüğümden, başka bir adı yoksa buna “bleeding nils/NULLs” demek isterim
Özellikle
nil, boolean karşılaştırmalardafalseile aynı değilse daha da kötüRuby ve Elixir’de
nil,falsegibi ele alınır; Elixir ise yalnızca saf boolean kabul edenandilenilifalsesayan&&operatörlerini ayrı ayrı sunarBu tür bir tasarım başta kodu temiz gösterebilir; ancak aslında hata olan, yanlış işlenmiş bir
nil, birçok çağrı yığınının ardından bambaşka bir yerde ortaya çıkıp hata ayıklamayı çok daha zorlaştırabilirBu yazıdaki Lisp bilgilerini zaten biliyordum ama yine de keyifle okudum. Hofstadter’ın dil tadı gerçekten çok çekici
Özellikle
readers-digest-condensed-versionın ters işlemi olanrejoyceu icat edip,(rejoyce 'Stately 'Yes)çalıştırıldığında Lisp perisinin James Joyce’un yazmış olabileceği Ulysses’in tamamını baştan ürettiği şakası hoşuma gittiBiraz zaman aldı ama sonunda o noktaya ulaştık sayılır; 2024’ün yapay zekası, onun 1983’te hayal ettiği şeyle tamamen aynı olmasa da, kısa bir tohumdan metni yeniden üretmek bugün yapay zekaya oldukça uygun bir iş
Lisp’in, Hofstadter’ın ele aldığı tuhaf döngü kavramını ifade edebilen başlıca dillerden biri olarak hâlâ yerini koruduğunu düşünüyorum
Lisp homoykonik olan tek dil değil, ama insanların gerçekten kullanmayı bildiği diller arasında
eval’in ayrıştırması gereken bir metin dizgesi almayan en büyük eksenlerden birine aitİnsanların Lisp’i doğrudan fonksiyonel programlamanın tamamıyla özdeşleştirmesinden hoşlanmıyorum
Fonksiyonel programlamadan hoşlanmıyor değilim, ama Lisp’in sembolik niteliği çok daha ilginç; ayrıca
(go tag)bölümleriyle çalışan kod üretip GOTO tarzı programlamayı da çok kolay yapabilmek bana bitmek bilmeyen bir eğlence gibi geliyorXSLT ve XML kullanarak, tekrarlı kodu elle yazmak yerine XSLT üreten türden metaprogramlama özellikleri epey yaygın kullanıldı
Ancak sözdizimi Lisp sözdiziminden de daha büyük bir sorundu
Hem gündelik kullanım için iyi bir sözdizimine sahip olan hem de soyut sözdizim ağacı olarak ele alınması fazla zahmetli olmayan bir dil yapmak kolay değil; Lisp bunun görece başarılı az sayıdaki örneğinden biri
functools’u ile pek yapılamayan derin düzeydeki homoykonik/sembolik destek gerçekten nedir merak ediyorum: https://docs.python.org/3/library/functools.htmlLisp olmadan sembolik AGI geliştiriyorum; uzmanlardan ipuçları duymak isterim
Python tarafında anladığım özellikler;
filter(),map(),reduce()gibi başka fonksiyonları yinelenebilir nesnelere uygulayan fonksiyonlar,@singledispatchgibi çağrıları yönlendiren sarmalayıcılar,@cachevepartial()gibi akış denetimi ya da performans kolaylığı sağlayan fonksiyonlar,wraps()gibi fonksiyonları keyfî biçimde sarmalama imkânı civarındaBunların çoğu, fonksiyonları alışılmadık şekillerde çağırmaya yarayan kolaylıklar gibi görünüyor ve “öz-yansıtma”yı birinci sınıf bir mesele gibi ele alan Lisp övgülerinin düzeyine ulaşmıyor sanki
Bu özelliklerde olmayan neyi Lisp’in gerçekten sağladığını bilmek istiyorum
Onlar Lisp’i kavram aktarma aracı olarak kullanıyor; bu kavramlar da genellikle fonksiyonel özyineleme etrafında dönüyor
Scheme ve çevresindeki kültürün de payı var
Scheme yalnızca fonksiyonel bir dil olmasa da önceki Lisp ailelerine göre saf programlamayı daha fazla vurgular; temel dil, yineleme yapıları yerine kuyruk özyineleme yapıları sunar ve uygulamalardan kuyruk çağrısı optimizasyonu ister
Common Lisp’te de
defaliasbir makro olarak tanımlanırsa Emacs’indefalias’ı gibi kullanılabilir: https://stackoverflow.com/questions/24252539/defining-aliase...Metamagical Themas’ta yer alan Hofstadter’ın Lisp yazısını sevmiştim; o serinin son yazısındaki kodu da iş yerindeki çalışma grubu için Clojure’a uyarlayıp düzenlemiştim
[1] http://johnj.com/posts/oodles/