Komentar Hofstadter tentang Lisp (1983)
(gist.github.com/jackrusher)- Tulisan Douglas Hofstadter tahun 1983 memperkenalkan Lisp, yang banyak digunakan dalam riset AI, sebagai bahasa yang elegan dan fleksibel yang dibangun di atas kernel matematis kecil
- Interaktivitas Lisp tampak dalam read-eval-print loop: ketika pengguna memasukkan ekspresi, interpreter membacanya, mengevaluasinya, mencetak hasilnya, lalu menunggu input berikutnya
- Objek Lisp tersusun terutama dari atom dan list, sementara nil memiliki posisi khusus sebagai list kosong sekaligus atom
quote,eval,car,cdr,cons,setq,set,lambda,def,condmemungkinkan kode dan data diperlakukan sebagai struktur list yang sama, sehingga fungsi baru dapat dibuat secara bertahap- Komposisi fungsi, ekspresi kondisional, efek samping dan gaya applicative, serta pemikiran rekursif dirangkai lewat contoh; fungsi
powerdi bagian akhir dan analogi “porpuquine” mengisyaratkan rekursi ala Lisp
Riset AI dan posisi Lisp
- AI pada tahun 1983 adalah bidang riset yang berupaya mengimplementasikan perilaku seperti fleksibilitas, akal sehat, wawasan, kreativitas, kesadaran diri, dan humor pada komputer
- Di Amerika Serikat ada sekitar 2.000 orang yang terlibat secara profesional dalam AI, dan di luar negeri ada peneliti dalam jumlah yang kurang lebih serupa
- Para peneliti AI sangat terpecah soal jalur terbaik menuju AI, tetapi dalam pilihan bahasa pemrograman mereka hampir secara umum memakai Lisp
- Nama Lisp berasal dari “list processing”, dan bukan akronim penuh
- Daya tarik Lisp terletak pada sifatnya sebagai bahasa yang “crisp” dan “elegant”
- Sementara banyak bahasa memuat banyak fitur arbitrer, beberapa bahasa seperti Lisp dan Algol tersusun di sekitar kernel yang terasa alami, seperti cabang matematika
- Kernel Lisp memiliki “crystalline purity”, dan kemurnian ini berkontribusi bukan hanya pada rasa estetis tetapi juga pada fleksibilitas
Dari logika matematika ke bahasa pemrosesan list
- Akar mendalam Lisp berada dalam logika matematika
- Gagasan yang ditinggalkan Thoralf Skolem, Kurt Godel, dan Alonzo Church dalam logika pada 1920–1930-an kelak masuk ke dalam Lisp
- Pemrograman komputer yang sesungguhnya dimulai pada 1940-an, dan bahasa tingkat tinggi seperti Lisp muncul pada 1950-an
- Bahasa pemrosesan list pertama bukan Lisp, melainkan IPL(Information Processing Language)
- IPL dikembangkan pada pertengahan 1950-an oleh Herbert Simon, Allen Newell, dan J. C. Shaw
- John McCarthy menciptakan bahasa pemrosesan list aljabar bernama Lisp pada 1956–1958 berdasarkan gagasan-gagasan yang sudah ada
- Lisp dengan cepat menyebar di kalangan peneliti muda di sekitar MIT Artificial Intelligence Project
- Bahasa ini diimplementasikan pada IBM 704 dan menyebar ke kelompok-kelompok AI lain
- Berbagai dialek muncul, tetapi semuanya berbagi kernel pusat yang elegan
Lisp yang interaktif dan REPL
- Berbeda dari banyak bahasa tingkat tinggi lain, Lisp disajikan sebagai bahasa interaktif
- Pengguna menjalankan Lisp di terminal, melihat prompt, lalu memasukkan ekspresi
- Contoh: jika memasukkan
(plus 2 2),4dicetak dan prompt baru muncul
- Contoh: jika memasukkan
- Operasi inti interpreter Lisp adalah read-eval-print loop
- Membaca ekspresi
- Mengevaluasi ekspresi
- Mencetak nilai yang sesuai
- Memberi tahu bahwa ia siap membaca ekspresi berikutnya
- Berkat struktur ini, pengguna dapat memasukkan “keinginan” satu per satu dan langsung memeriksa hasilnya
- Dalam banyak bahasa non-interaktif, seluruh program harus ditulis dan dijalankan terlebih dahulu, sehingga banyak tahap harus saling pas dengan sempurna, dan perbaikan kesalahan pun tidak langsung serta mahal
- Lisp memungkinkan pengembangan dan debugging bertahap dengan menjalankan ekspresi satu demi satu
Notasi Polish dan tanda kurung
- Ekspresi aritmetika Lisp memakai notasi Polish, dengan operator diletakkan sebelum operand
- Contoh:
(times (plus 6 3) (difference 6 3))dievaluasi menjadi 27
- Contoh:
- Notasi ini dibuat sebelum era komputer oleh logikawan Polandia Jan Lukasiewicz
- Ekspresi Lisp banyak mengandung tanda kurung
- Ekspresi panjang sering berakhir dengan beberapa tanda kurung penutup
- Awalnya terasa membebani, tetapi setelah terbiasa, struktur logikanya terlihat intuitif
- Contoh-contoh disajikan dalam bentuk pretty printing yang menampilkan struktur lewat indentasi
Atom, list, nil
- Inti Lisp adalah struktur yang dapat dimanipulasi, dan semua program bekerja dengan membuat, mengubah, dan menghancurkan struktur
- Struktur ada dua jenis
- Atom: objek dasar yang tidak dapat dibagi lagi
- List: struktur berisi beberapa elemen dalam urutan tertentu
- Semua objek Lisp adalah atom atau list, dengan satu pengecualian yaitu nil
- nil adalah atom sekaligus list
- nil merepresentasikan list kosong
()dannilbermakna sama, tetapi nil lebih sering digunakan
- Elemen list bisa berupa atom maupun list
- Contoh:
(zonk blee strill (croak flonk))adalah list berisi empat elemen, dan elemen terakhirnya adalah list lain berisi dua elemen
- Contoh:
- Kalimat Lisp sendiri juga berupa list
(plus 2 2)juga sebuah list- Interpreter Lisp dapat memanipulasi list dan atom untuk membuat dan mengevaluasi “perintah” baru
Nilai, quote, eval
- Atom dapat memiliki nilai
- Atom angka memiliki dirinya sendiri sebagai nilai permanen
- Nilai nil adalah nil
- t juga atom khusus yang memiliki dirinya sendiri sebagai nilai permanen
setqmenetapkan nilai pada atom(setq pie 4)membuat nilaipiemenjadi 4(setq pie (plus 2 2))juga membuat nilaipiemenjadi 4
- Nilai atom tidak hanya bisa berupa angka, tetapi juga objek Lisp apa pun
- Bisa atom, bisa juga list
- quote mencegah evaluasi dan membuat list atau atom diperlakukan apa adanya sebagai data
(setq pie (plus 2 2))mengevaluasi ekspresi di dalamnya dan menyimpan 4 kepie(setq pi '(plus 2 2))menyimpan list(plus 2 2)itu sendiri kepi
evalmengevaluasi kembali ekspresi yang tersimpan sebagai nilai- Jika nilai
piadalah(plus 2 2), maka(eval pi)mengembalikan 4 - Interpreter biasanya hanya mengevaluasi satu tingkat, tetapi dengan
evalkita dapat meminta evaluasi tambahan
- Jika nilai
car, cdr, cons
- Semua list yang bukan nil memiliki setidaknya satu elemen, dan elemen pertamanya disebut car
- car dari
(eval pi)adalaheval - car dari
(plus 2 2)adalahplus
- car dari
- car tidak harus berupa nama fungsi
- car dari
((1)(2 2) (3 3 3))adalah(1)
- car dari
- List yang tersisa setelah car dihapus disebut cdr
- cdr dari
(a b c d)adalah(b c d) - Lalu menyusut menjadi
(c d),(d), dan nil
- cdr dari
- Nil tidak memiliki car maupun cdr, dan mengambil car atau cdr darinya semestinya menghasilkan error
consmembuat list baru dengan menempelkan car baru di depan list yang sudah ada- Ketika
xadalah(cake cookie),(cons 'pie x)membuat(pie cake cookie) - Dalam proses ini,
xyang lama tidak berubah
- Ketika
- Hasilnya berbeda tergantung ada tidaknya quote
- Jika nilai
pieadalah 4,(cons pie x)mengembalikan(4 cake cookie) (cons 'pie x)menempelkan nama atompieitu sendiri di depan
- Jika nilai
Perbedaan setq dan set
- Interpreter Lisp tidak selalu mengevaluasi argumen, dan
setqadalah pengecualian yang representatif - Argumen pertama
setqtidak dievaluasi dan diperlakukan apa adanya sebagai nama variabel- Huruf q pada
setqberarti quote, sehingga argumen pertama diperlakukan seolah-olah dikutip
- Huruf q pada
setmirip dengansetq, tetapi argumen pertamanya juga dievaluasi- Ketika nilai x adalah k,
(set x 7)tidak mengubah x, melainkan mengubah nilai k menjadi 7
- Ketika nilai x adalah k,
- Urutan berikut disajikan sebagai contoh
(setq a 'b)(setq b 'c)(setq c 'a)(set a c)(set c b)
- Setelah eksekusi ini, nilai a, b, dan c masing-masing semuanya menjadi
a setjarang digunakan, dan kebingungan semacam ini juga tidak sering terjadi
Definisi fungsi dan lambda
- Kekuatan besar pemrograman terletak pada kemampuan mendefinisikan operasi majemuk baru dari operasi yang sudah ada, lalu mengulanginya untuk membangun repertoar operasi yang lebih kompleks
- Dalam Lisp, fungsi baru didefinisikan dari fungsi-fungsi yang sudah diketahui
racadalah contoh fungsi yang mengembalikan elemen terakhir dari sebuah list- Untuk mendapatkan elemen terakhir, balik list lalu ambil car-nya
- Definisi:
(def rac (lambda (lyst) (car (reverse lyst))))
(lyst)setelahlambdamenunjukkan parameter fungsi, yaitu variabel dummy- Setelah didefinisikan dengan
def,racmenjadi fungsi yang dapat digunakan seperticar(rac '(your brains))mengembalikanbrains
- Fungsi
readers-digest-condensed-versionmembuat list pendek yang hanya berisi elemen pertama dan terakhir dari sebuah list panjang- Jika seluruh Finnegans Wake karya James Joyce diperlakukan sebagai list kata, muncul contoh yang menghasilkan
(riverrun the)
- Jika seluruh Finnegans Wake karya James Joyce diperlakukan sebagai list kata, muncul contoh yang menghasilkan
- Operasi kebalikan bernama
rejoyceadalah fungsi imajiner yang menghasilkan novel dengan awal dan akhir yang ditentukan oleh dua kata, dan penulisannya ditinggalkan sebagai latihan bagi pembaca
Nilai balik, efek samping, gaya applicative
- Sebagian orang memandang dua tujuan berikut sebagai hal yang diinginkan dan mungkin dalam Lisp serta bahasa terkait
- Semua kalimat mengembalikan nilai
- Efek sebuah kalimat terjadi hanya melalui nilai baliknya
- Dialek Lisp yang dibahas dalam tulisan ini memenuhi syarat pertama, tetapi tidak selalu memenuhi syarat kedua
(reverse x)tidak mengubah x itu sendiri, melainkan membuat dan mengembalikan list baru yang sama dengan x tetapi urutannya dibalik- Ini sama seperti
(plus 2 2)tidak mengubah nilai 2
- Ini sama seperti
consjuga mengembalikan list baru tanpa mengubah list yang sudah ada- Sebaliknya,
setqadalah contoh perintah yang meninggalkan efek samping dengan mengubah binding variabel- Selain perubahan binding variabel, efek samping juga dapat mencakup input/output
- Pendukung pemrograman applicative lebih menyukai cara fungsi menghitung dan meneruskan nilai tanpa efek samping
- Dalam gaya ini, binding yang diperbolehkan adalah lambda binding yang muncul sementara selama pemanggilan fungsi
- Setelah perhitungan fungsi selesai, binding variabel dummy menghilang
- Narator tulisan ini memandang gaya applicative sebagai sesuatu yang elegan, tetapi tidak praktis untuk membuat program besar bergaya AI
- Dalam pemrograman applicative yang ketat,
defpun menjadi kasus ekstrem yang tidak diperbolehkan karena menyimpan definisi fungsi permanen di memori
Ekspresi kondisional cond dan keputusan
- Agar Lisp dapat melakukan hal yang lebih menarik, ia harus mampu mengambil keputusan berdasarkan apa yang terjadi di tengah proses, dan untuk itu diperlukan ekspresi kondisional
- Contoh:
(cond ((eq x 1) 'land) ((eq x 2) 'sea))- Jika x adalah 1, hasilnya
land - Jika x adalah 2, hasilnya
sea - Selain itu, mengembalikan nil
- Jika x adalah 1, hasilnya
eqadalah fungsi Lisp yang mengembalikantjika nilai kedua argumennya sama, danniljika berbeda- Pernyataan
conddimulai dengan nama fungsiconddan memiliki beberapa klausa- Setiap klausa adalah list 2 elemen yang terdiri dari kondisi dan hasil
- Kondisi diperiksa berurutan; ketika ditemukan kondisi pertama yang mengembalikan nilai bukan nil, hasil yang sesuai dievaluasi dan dikembalikan sebagai nilai seluruh
cond - Klausa berikutnya tidak diperiksa
- Jika klausa catch-all dengan kondisi
tdiletakkan di akhir, hasil default dapat dikembalikan alih-alih nil- Contoh yang disajikan adalah
condyang mengembalikanairjika kondisi land dan sea sama-sama gagal
- Contoh yang disajikan adalah
Pangkat dan struktur rekursif
- Di bagian akhir tulisan muncul definisi fungsi dengan pola yang jelas
squareadalahk * kcubeadalahk * square(k)4th-poweradalahk * cube(k)- Dan seterusnya dengan cara yang sama
- Pertanyaan yang diajukan adalah apakah fungsi dua parameter
poweryang mencakup seluruh pola ini sekaligus dapat didefinisikan(power 9 3)adalah 729(power 7 4)harus mengembalikan 2.401
- Semua alat yang diperlukan telah disajikan dalam teks, dan ini menuntut kecerdikan pembaca
- Kisah Glazunkian porpuquine di bagian akhir memperlakukan struktur rekursif seperti sebuah fabel
- Duri porpuquine adalah porpuquine yang lebih kecil
- Di Outer Glazunkia selalu ada 9 duri, sedangkan di Inner Glazunkia selalu ada 7 duri
- Porpuquine berukuran 0 inci tidak memiliki duri, sehingga menghentikan regresi tak berhingga
- “buying power” atau “power” hewan ini dikaitkan dengan jumlah hidung porpuquine kecil berukuran 0 inci yang terkandung di dalamnya, dan tulisan ditutup dengan analogi yang tersambung ke masalah
powersebelumnya
Konteks pemuatan ulang teks asli
- Bagian awal Gist menjelaskan bahwa tulisan ini adalah pengantar Lisp oleh Douglas Hofstadter yang ditemui dalam edisi lama Scientific American dari pertengahan 1980-an
- Contoh-contohnya masih dapat dijalankan di Emacs jika memasang beberapa alias
plus→+quotient→/times→*difference→-
- Bagian akhir menyarankan bahwa jika pembaca menikmati panduan Lisp khas Hofstadter ini, mereka dapat melihat tulisan serupa lainnya dalam bukunya Metamagical Themas
1 komentar
Komentar Hacker News
Nama fungsi
"oval"dan"snot"di contoh sempat membingungkan, lalu beberapa detik kemudian saya sadar bahwa keduanya adalah salah ketik dari"eval"dan"snoc"Kode aslinya seharusnya dibaca seperti
(cond ((eq (eval pi) pie) (eval (snoc pie pi))) (t (eval (snoc (rac pi) pi))))Setelah mengunduh dan memeriksa artikel Scientific American aslinya dari https://www.jstor.org/stable/24968822, ternyata
oval/snotmemang salah ketik darieval/snoc"oval"dan"snot"memang salah ketik dari"eval"dan"snoc"Dan
snoctampaknya adalahconsyang dibalik, sedangkanracadalahcaryang dibalikTulisan ini kembali menunjukkan bahwa salah satu penyebab utama Lisp kurang populer adalah cara Lisp dijelaskan
Tulisan-tulisan tentang Lisp seperti ini sama sekali tidak memberi tahu saya semasa kecil hal-hal yang benar-benar bisa dipakai, juga tidak menunjukkan seberapa jauh pekerjaan X menjadi lebih mudah dibanding assembly/C/Pascal
Kalau saya yang menulis sekarang, saya akan menunjukkan, “Pemeriksa ejaan yang butuh 7 bulan dalam assembly? Di Lisp pada mikrokomputer dengan memori bank-switched itu nyaris sepele, dan garbage collection pun bisa dibuat menentukan bahkan pada CPU yang buruk”
Begitu banyak tulisan dan buku ajar Lisp hanya mengulang soal list, rekursi, dan AI tanpa menunjukkan cara melakukan hal yang berguna, sampai terasa seperti membuang waktu memrogram dengan pinset, butir beras, dan lem
Di majalah Byte yang pertama kali saya lihat saat kecil, ada kode Lisp untuk diferensiasi simbolik dan penyederhanaan aljabar; meski sulit diikuti, tetap terasa ada sesuatu yang memikat
Rasanya itu tidak mungkin lebih mudah dalam Basic, dan belakangan saya sadar kodenya juga bukan contoh yang sangat bagus, tetapi saya baru benar-benar jatuh hati pada Lisp setelah bertemu XLisp di PC akhir 80-an dan SICP
Saya sangat menyukai gaya menulis Hofstadter. Ia menangkap dengan baik perasaan saat menemukan Lisp
Saya anak yang belajar pemrograman pada 80-an, dan di awal SMA serta kuliah saya sudah sedikit mencoba BASIC, Fortran, Pascal, dan COBOL; ada perbedaannya, tetapi pada dasarnya mereka punya kesamaan
Lalu kelas ilmu komputer pertama di UC Berkeley diajarkan dengan Scheme, sebuah dialek Lisp, dan itu benar-benar mengejutkan
Seperti kata Hofstadter, rasanya paling dekat dengan matematika, sangat mengingatkan pada banyak kelas teori matematika, dan itu adalah bahasa pertama yang saya anggap indah
Saya sangat menyukai kutipan, “Lisp dan Algol dibangun di sekitar inti alami yang menyerupai cabang matematika. Di inti Lisp ada kemurnian kristalin yang bukan hanya menarik secara estetis, tetapi juga membuatnya jauh lebih fleksibel daripada kebanyakan bahasa”
Bahkan dari sudut pandang seseorang yang ingin menjadi ahli topologi aljabar, Scheme lebih mirip ekspresi yang elegan dan minimal dari gaya pemrograman yang menyebar ke bahasa-bahasa bertipe dinamis dengan garbage collection
Ia terasa seperti “teori” dalam arti tampak lengkap, dan jika seseorang memikirkan cara menyelesaikan masalah di Scheme lalu memindahkannya ke bahasa dinamis lain, orang itu masih bisa mencapai solusi yang elegan
Scheme adalah bahasa yang menyederhanakan dan merapikan Lisp tradisional saat itu, misalnya lewat lexical scope dan satu namespace untuk fungsi serta variabel
Pada tahun 1983, bidang ini sudah berjalan sekitar 20 tahun, tetapi masih membicarakan AI yang memrogram komputer agar punya “fleksibilitas, akal sehat, wawasan, kreativitas, kesadaran diri, humor”
Daftar ini cukup lucu karena terbaca seperti daftar hal-hal yang benar-benar buruk dilakukan LLM
Meski begitu, setidaknya sekarang sudah ada kemajuan yang tidak nol ke arah itu
Mungkin bahkan lebih, tetapi kalau saya mengatakannya begitu, rasanya agak aneh bahkan bagi saya sendiri
Meski banyak hal masih belum membuahkan hasil, tetap menarik untuk dibaca
Dua tulisan pendamping yang disebut bersama artikel ini dimuat sebagai bab 17~19 dalam buku Hofstadter Metamagical Themas, bersama artikel lain dari seri yang sama di Scientific American
[0]: https://www.goodreads.com/book/show/181239.Metamagical_Thema...
Judul bukunya berasal dari judul seri yang merupakan anagram dari “Mathematical Games”, kolom yang ditulis Martin Gardner di Scientific American, lalu dilanjutkan oleh Hofstadter
Tulisan itu mengatakan bahwa menerapkan
carataucdrpadanilseharusnya menghasilkan error seperti membagi dengan nol, tetapi di Lisp modern sering kali sudah tidak demikian lagiDalam Lisp asli yang didefinisikan John McCarthy,
CARdanCDRmemang tidak didefinisikan untukNIL: <https://dl.acm.org/doi/pdf/10.1145/367177.367199>Namun Common Lisp dan Emacs Lisp mendefinisikan
(car nil)dan(cdr nil)sebagainil: <https://www.lispworks.com/documentation/HyperSpec/Body/f_car...>, <https://www.gnu.org/software/emacs/manual/html_node/elisp/Li...>Di
LISP 2156,(status lispversion)mengembalikan/2156, dan(car nil)serta(cdr nil)sama-sama mengembalikanNILcardancdrjustru menjadi bagian intiOperasi paling dasar dan paling terkenal dari “List Processor” ternyata tidak dibuat untuk bekerja pada list, melainkan pada cons, elemen representasi mesin tertentu yang dipakai Lisp saat membangun struktur data
cons juga tidak selalu ditafsirkan sebagai list, dan list yang sangat penting sebagai kasus dasar fungsi rekursif pada list bahkan tidak direpresentasikan sebagai cons
Bahkan setelah 60 tahun, sebagian besar program Lisp masih dipenuhi operasi cons, dan mungkin nama yang lebih tepat adalah “Cons Processor”
Ini mengingatkan bahwa Lisp lahir pada masa ketika bahasa dan implementasi harus saling terkait erat, sehingga pencapaian membangun bahasa komputer di atas logika matematika terasa makin mengagumkan
CARatauCDRdarinilakan menghasilkan errorcar/cdrpadaniladalah error, jadi bagi pemula seperti saya, kodenya terasa cukup tidak ergonomisMeski begitu, saya tetap lebih menyukai Guile Scheme dibanding Common Lisp, jadi agak disayangkan
niltanpa error lalu mengembalikannillagiSQL juga terlintas, dan secara pribadi saya menganggap itu pilihan yang kurang baik, jadi kalau belum ada istilah lain saya ingin menyebutnya “bleeding nils/NULLs”
Terutama jika
niltidak sama denganfalsedalam perbandingan boolean, itu terasa lebih buruk lagiDi Ruby dan Elixir,
nildiperlakukan sepertifalse, dan Elixir membedakanandyang hanya menerima boolean murni dengan&&yang memperlakukannilsebagaifalseDesain seperti ini awalnya memang bisa membuat kode tampak rapi, tetapi
nilyang sebenarnya merupakan error penanganan bisa baru muncul di bagian yang sama sekali berbeda setelah beberapa lapis call stack, sehingga debugging jauh lebih sulitSaya sudah tahu informasi Lisp dalam tulisan ini, tetapi tetap membacanya dengan senang. Gaya bahasa Hofstadter memang sangat memikat
Terutama leluconnya saat ia membuat
rejoyce, operasi kebalikan darireaders-digest-condensed-version, sehingga jika menjalankan(rejoyce 'Stately 'Yes), peri Lisp akan menghasilkan seluruh Ulysses seperti yang kira-kira akan ditulis James Joyce, dari awalMemang butuh waktu, tetapi kita akhirnya sampai juga ke titik itu, dan meskipun AI tahun 2024 tidak persis sama dengan yang ia bayangkan pada 1983, mereproduksi teks dari seed pendek adalah jenis tugas yang sangat cocok untuk AI saat ini
Lisp masih dianggap sebagai bahasa utama yang mampu menampung konsep strange loop yang dibahas Hofstadter
Lisp memang bukan satu-satunya bahasa yang homoikonik, tetapi di antara bahasa yang benar-benar bisa dipakai orang, Lisp termasuk yang terbesar yang
eval-nya tidak menerima string yang harus diparseSaya tidak suka ketika orang menyamakan Lisp dengan pemrograman fungsional secara keseluruhan
Bukannya saya membenci pemrograman fungsional, tetapi sifat simbolik Lisp jauh lebih menarik, dan selalu terasa menyenangkan bahwa bahasa ini juga sangat mudah dipakai untuk membuat kode yang digerakkan oleh bagian
(go tag), sehingga pemrograman bergaya GOTO pun sangat mudah dilakukanDengan XSLT dan XML, metaprogramming yang menghasilkan XSLT alih-alih menulis langsung kode berulang cukup banyak digunakan
Hanya saja, sintaksnya merupakan masalah yang bahkan lebih besar daripada sintaks Lisp
Tidak mudah membuat bahasa yang sintaksnya enak dipakai sehari-hari sekaligus tidak terlalu berat untuk diperlakukan sebagai abstract syntax tree, dan Lisp adalah salah satu dari sedikit contoh yang relatif berhasil
functoolsdi Python: https://docs.python.org/3/library/functools.htmlSaya sedang membangun AGI simbolik tanpa Lisp, dan ingin mendengar petunjuk dari para ahli
Sejauh yang saya pahami, fitur di Python itu mencakup fungsi seperti
filter(),map(),reduce()yang menerapkan fungsi lain ke iterable, wrapper seperti@singledispatchyang merutekan pemanggilan, fungsi seperti@cachedanpartial()yang memberi kemudahan untuk kontrol alur atau performa, serta kemampuan membungkus fungsi secara arbitrer sepertiwraps()Sebagian besar hal ini tampak seperti fitur kenyamanan untuk memanggil fungsi dengan cara yang tidak biasa, dan rasanya belum sampai ke tingkat pujian terhadap Lisp yang memperlakukan “introspeksi diri” sebagai perhatian kelas satu
Saya ingin tahu apa sebenarnya yang Lisp sediakan yang tidak ada pada fitur-fitur di atas
Mereka memakai Lisp sebagai sarana menyampaikan konsep, dan konsep itu biasanya berputar di sekitar rekursi fungsional
Scheme dan budaya di sekitarnya juga berperan
Scheme memang bukan semata-mata bahasa fungsional, tetapi dibandingkan keluarga Lisp sebelumnya ia lebih menekankan pemrograman murni, bahasa dasarnya menyediakan struktur tail recursion alih-alih struktur iterasi, dan menuntut implementasinya melakukan optimisasi tail call
Bahkan di Common Lisp,
defaliasbisa didefinisikan sebagai makro dan dipakai sepertidefaliasdi Emacs: https://stackoverflow.com/questions/24252539/defining-aliase...Saya menyukai tulisan Hofstadter tentang Lisp yang dimuat di Metamagical Themas, dan pernah memindahkan serta merapikan kode dari artikel penutup serial itu agar cocok untuk Clojure dalam kelompok belajar di tempat kerja
[1] http://johnj.com/posts/oodles/