- Inti Lisp bukan pada sintaks kurungnya, melainkan pada cara berpikir untuk memperluas bahasa agar sesuai dengan masalah, dan nilainya baru benar-benar terlihat setelah memahami REPL, package, symbol, condition, hingga restart
- Berkat homoiconicity, di mana kode dan data sama-sama direpresentasikan sebagai list, macro dapat memperlakukan kode seperti data sebelum evaluasi untuk membuat struktur kontrol baru dan abstraksi sintaks
- Bahkan
while yang tidak ada di Common Lisp bisa ditambahkan dengan defmacro, tetapi jika ditiru dengan fungsi, argumen akan langsung dievaluasi sehingga body menjadi nilai, bukan kode
- Pengembangan Lisp lebih dekat ke pengembangan berbasis REPL, di mana kode terus dievaluasi ke proses yang sedang berjalan sehingga fungsi, macro, dan variabel dapat didefinisikan ulang sambil mengembangkan program tanpa henti
- Ketika ekstensibilitas bahasa digabungkan dengan sistem live, kita bisa membuat perangkat lunak yang dapat diperluas dengan mengekspos DSL internal kepada pengguna, seperti pada AutoLISP dan Emacs
Rasa pemrograman berbeda yang dituntut Lisp
- Programmer yang pertama kali menemui Lisp sering merasa asing dengan sintaks yang penuh kurung, indentasi yang khas, dan cara
format menentukan keluaran standar lewat argumen pertamanya
- Untuk menguasai Lisp, tidak cukup hanya membaca kode; kita juga perlu menangani package dan symbol, membuat proyek, mengimpor library, REPL, condition, hingga restart
- Perubahan yang lebih besar muncul pada cara menyusun algoritme
- Lisp memungkinkan hal-hal yang sulit dilakukan di bahasa lain, dan bentuk algoritmenya pun ikut berubah
- Alurnya berlanjut ke pola memperbesar bahasa terlebih dahulu agar cocok dengan masalah, lalu menulis program dengan bahasa yang sudah diperluas itu
- Paradoks Blub adalah konsep yang menjelaskan mengapa programmer yang hanya pernah memakai bahasa yang kurang kuat sulit mengenali keunggulan Lisp
Bahasa yang dapat diperluas
- Lisp dapat memperluas dirinya sendiri, dan para ahli Lisp menyebutnya sebagai programmable programming language
- Alat utamanya adalah
macro
- Tidak berhenti pada penghapusan kode berulang seperti macro di C, Rust, atau Swift
- Macro Lisp dapat membuat komponen baru yang menjadi bagian dari bahasa itu sendiri
- Common Lisp tidak memiliki operator dasar
while, tetapi bisa ditambahkan sendiri dengan defmacro
(defmacro while (condition &body body)
`(loop while ,condition do
(progn ,@body)))
- Macro
while ini menjalankan beberapa perintah dalam body selama condition bernilai benar
loop adalah macro untuk menulis perulangan yang kompleks
progn menjalankan beberapa ekspresi secara berurutan dan mengembalikan hasil dari ekspresi terakhir
- Hasilnya, kita bisa memakai bentuk
(while ...) alih-alih (loop while ... do (progn ...)), sehingga kode lebih singkat dan strukturnya mirip while di C
Perbedaan krusial antara macro dan fungsi
- Jika perilaku yang sama dibuat sebagai fungsi
fake-while, hasilnya gagal
(defun fake-while (condition body)
(loop while condition do
(funcall body)))
- Dalam pemanggilan
fake-while, argumen dievaluasi lebih dulu
condition menjadi nilai benar t
(print counter) di dalam progn dijalankan, lalu (decf counter) mengembalikan 2
body menjadi nilai 2, bukan blok kode
- Setelah itu
funcall mengharapkan fungsi, tetapi menerima 2, sehingga muncul type error seperti The value 2 is not of type FUNCTION
- Sebaliknya, macro
while tidak langsung mengevaluasi condition dan body, melainkan mempertahankannya
- Hasil ekspansinya bisa diperiksa dengan
macroexpand-1
- Compiler menerima kode dalam bentuk hasil ekspansi
(LOOP WHILE ... DO (PROGN ...))
- Berbeda dari fungsi, macro tidak mengevaluasi argumen lebih dulu dan memperlakukannya sebagai data murni, sehingga transformasi seperti ini menjadi mungkin
List, s-expression, homoiconicity
- Program Lisp tersusun dari rangkaian symbolic expression, yaitu s-expression
- s-expression terbagi menjadi dua jenis
- atom: unit data seperti angka, string, dan symbol
- list: koleksi yang berisi atom atau list lain
- Nama Lisp berasal dari LISt Processing, dan perintah yang menyusun program juga direpresentasikan sebagai list
- Di Lisp, list adalah struktur data utama sekaligus cara menulis kode
- Sifat bahwa kode dan data sama-sama direpresentasikan sebagai list disebut homoiconicity
- List yang sama,
(+ 1 2), dapat berperilaku berbeda tergantung apakah ia dievaluasi atau tidak
(+ 1 2) dievaluasi sebagai kode dan mengembalikan 3
'(+ 1 2) tidak dievaluasi dan dikembalikan apa adanya sebagai list data
- Lisp menggunakan Polish notation, menempatkan nama fungsi sebagai elemen pertama list lalu diikuti argumen
- Karena batas antara kode dan data tipis, macro bisa mentransformasikan source code dan memungkinkan pembuatan program yang menulis program
Abstraksi kode yang dibuat macro
- Dengan memperluas bahasa, kita bisa membuat komponen baru yang lebih ekspresif untuk area program tertentu
- Boilerplate yang berulang dapat diganti dengan macro kustom untuk mengurangi kode dan menghemat waktu
- Kita bisa membuat struktur kontrol baru untuk mengatur akses resource dan evaluasi form
- Macro menghasilkan kode, meningkatkan performa, dan menyediakan abstraksi sintaks yang menyembunyikan kode kompleks dan rawan error
Lisp sebagai sistem live
- Lisp diperlakukan bukan sekadar sebagai bahasa pemrograman, melainkan sebagai sistem live yang sedang berjalan
- Dalam banyak bahasa umum, alurnya adalah menulis kode di editor, lalu mengompilasi dan menjalankannya untuk diamati, diuji, dan di-debug
- Di Lisp, kita biasanya memulai proses Lisp terlebih dahulu, terhubung ke REPL, lalu memuat proyek ke dalam proses tersebut
- REPL adalah singkatan dari Read-Eval-Print Loop, yaitu lingkungan interaktif untuk mengevaluasi kode dan langsung melihat hasilnya
- Ia berfungsi sebagai jendela untuk mengintip proses Lisp yang sedang menjalankan program saat ini
- Developer Lisp terus mengevaluasi kode di dalam proses yang sedang berjalan dan langsung memeriksa hasilnya lewat REPL
- menguji fungsi individual
- menjalankan query database
- memeriksa variabel
- melakukan debugging juga bisa lewat REPL
- Proses Lisp tidak perlu dihentikan dan bisa tetap hidup selama berminggu-minggu
- Fungsi, macro, dan variabel terus didefinisikan dan didefinisikan ulang di memori internal, yaitu environment, dan alur ini disebut pengembangan berbasis REPL
Hot reloading di Lisp
- Di frontend web, pengalaman hot reload untuk kode JavaScript lewat penyimpanan file atau refresh halaman sudah umum
- Hot reloading pada umumnya bergantung pada alat dan teknik terpisah seperti pemantauan file, kompilasi ulang modul yang berubah, dan injeksi perubahan lewat WebSocket
- Tidak semua stack perangkat lunak menyediakan tingkat hot reloading yang sama
- beberapa framework backend memerlukan kompilasi ulang
- lingkungan pengembangan desktop dan mobile bervariasi
- bahasa tingkat rendah memerlukan kompilasi penuh setiap kali
- Di Lisp, hot reloading bukan alat terpisah, melainkan konsekuensi alami dari evaluasi kode di lingkungan live
- ketika symbol didefinisikan ulang, fungsi, data, dan macro semuanya memakai definisi baru
- kebutuhan untuk berhenti lalu kompilasi, menjalankan tes secara terpisah, atau memakai debugger khusus menjadi berkurang
- Pemrograman Lisp lebih mirip mengembangkan program secara evolusioner daripada sekadar merakitnya
Perangkat lunak yang dapat diperluas
- Ekstensibilitas bahasa dan sistem live membuat Lisp sangat cocok untuk membangun perangkat lunak yang dapat diperluas
- Program desktop pada umumnya diperluas lewat plugin atau bahasa scripting
- developer harus merancang dan memelihara sistem ekstensi
- pengguna harus mempelajari API tertentu untuk menulis plugin atau ekstensi
- Di Lisp, macro mendorong pembungkusan perilaku agar mudah dipakai ulang, dan secara alami mengarah pada penulisan DSL
- Untuk membuat perangkat lunak dapat diperluas, cukup biarkan pengguna memakai DSL internal yang kita bangun
- Dalam contoh server CMS, macro
html untuk menghasilkan halaman web sisi server dapat diekspos kepada pengguna
- pengguna tetap bisa memakai variabel Lisp, perulangan
dolist, dan pemformatan string format secara langsung bersama itu
- tidak perlu mempelajari sintaks terpisah seperti
{{ user_name }} atau {% for %} seperti pada bahasa template tradisional
- DSL ini mewarisi kemampuan conditional Lisp, rekursi, higher-order function, dan debugging bertahap lewat REPL apa adanya
- Dalam contoh perangkat lunak grafik matematika, DSL untuk rumus dan gambar dapat diekspos sehingga pengguna bisa menggambar kurva dan titik dengan kode singkat
Contoh nyata dan posisi Lisp
- AutoCAD menggunakan AutoLISP untuk otomatisasi tugas berulang dan pembuatan geometri yang kompleks
- Emacs adalah editor teks yang sangat dapat diperluas karena sebagian besar diimplementasikan dengan dialek Lisp miliknya sendiri
- pembaca PDF
- browser web
- klien email
- pembaca RSS
- terminal multiplexer
- klien Git
- pemutar musik
- klien chat
- spreadsheet
- klien IRC
- bahkan ada contoh yang meluas hingga pengelola jendela desktop
- R. M. Stallman menilai Lisp sebagai bahasa yang membantu memahami makna bahasa pemrograman yang kuat dan elegan
- Harapan bahwa suatu hari Lisp akan dipakai luas seperti bahasa default tidak terwujud, dan tampaknya kecil kemungkinan itu akan terjadi ke depan
- Meski begitu, Lisp telah bertahan sejak 1960-an dan menjadi bahasa pemrograman aktif tertua kedua setelah Fortran
- Nilai Lisp tidak datang dari satu fitur terpisah seperti ekstensibilitas, lingkungan interaktif, atau REPL, melainkan dari kombinasi semuanya
1 komentar
Pendapat Hacker News
Pemrograman berdiri di atas ketegangan antara sisi terang dan sisi gelap
Sisi terang berusaha mencegah programmer melakukan kesalahan: menghapus
goto, menambahkan tipe statis, dan membuat bug tidak bisa diekspresikanSisi gelap memberi kekuatan kepada programmer: macro, operator overloading, kode yang memodifikasi dirinya sendiri, sampai regex multi-baris pun dibiarkan sebebas mungkin
Menariknya, Lisp jelas berada di sisi gelap karena programmer bisa melakukan apa saja, tetapi tetap dihormati juga oleh programmer sisi terang. Mungkin karena kesederhanaan bahasanya terasa Platonis dan nyaris mustahil tercemar, atau mungkin karena Lisp begitu murni sehingga seperti dewa yang melahirkan semesta pemrograman dan merangkul kedua sisi sekaligus
Kita tidak bisa memilih siapa yang akan bekerja bersama, dan tingkat kemampuan dalam tim juga tidak bisa dipilih. Ketika rekan yang kurang berpengalaman membuat kesalahan, makin permisif bahasanya makin besar dampak akibatnya
Karena itu code review jadi perlu, tetapi akibatnya programmer yang berpengalaman berubah menjadi pengajar. Sebagian waktu yang dipakai untuk meningkatkan kemampuan programmer lain terasa terbuang karena programmer bisa masuk dan keluar kapan saja. AI mungkin bisa mengubah dinamika ini
Pada akhirnya yang penting adalah mempertahankan tim kecil yang terampil, tetapi politik perusahaan membuatnya tidak mudah. Misalnya, sering muncul dorongan untuk menambah developer demi mempertimbangkan bus factor atau mempercepat jadwal rilis
Sistem dengan keandalan tinggi juga ditulis dengan Erlang, yang kalau dilihat sambil memicingkan mata bisa dianggap sebagai dialek Lisp lainnya. Ada juga versi berbasis S-expression bernama LFE, yaitu Erlang bergaya Lisp
Inti keandalan Erlang bukan pada pencegahan kesalahan yang luar biasa ketat, melainkan pada pemulihan dari kesalahan. Klasifikasi terang/gelap itu sendiri cukup menarik
Meski tidak ada tipe statis dan macro bisa menjadi kekacauan, baseline cara berpikir deklaratif dan fungsional jauh lebih kuat, sehingga titik awal untuk memikirkan dan menalar program dengan jelas menjadi lebih baik
Pembagian terang/gelap tampak terlalu menyederhanakan. Keseimbangan bahasa pemrograman adalah topik yang sangat kompleks dan menarik
Setelah bereksperimen selama bertahun-tahun dengan banyak bahasa, pada akhirnya ini soal konteks penggunaan, selera pribadi, dan tujuan. Tidak ada yang namanya “bahasa pemrograman terbaik sepanjang masa”, dan juga tidak ada “yang terbaik untuk pemrograman sisi terang” atau “yang terbaik untuk pemrograman sisi gelap”
Dalam seni lukis pun tidak ada sisi terang/sisi gelap seperti itu. Jelas ada lukisan yang lebih agung, tetapi tidak ada “lukisan terbaik” yang akan dianggap paling indah oleh semua orang dibanding semua lukisan lain
https://en.wikipedia.org/wiki/Malbolge
https://en.wikipedia.org/wiki/Clean_(programming_language)
https://en.wikipedia.org/wiki/K_(programming_language)
Dalam beberapa bulan terakhir muncul editor dan alat baru yang luar biasa, jadi sayang kalau terlewat
Mine adalah aplikasi unduhan tunggal yang menyediakan semua yang dibutuhkan untuk merasakan alur pengembangan interaktif dan inkremental, termasuk hot reloading dan debugging seketika. Ini untuk CL dan Coalton
https://coalton-lang.github.io/20260424-mine/
OLIVE adalah plugin buatan tangan untuk VSCode, dan ICL adalah REPL baru untuk terminal dan browser dengan fitur tingkat lanjut. Sebagai bonus, ada juga kernel JupyterLite berbasis JSCL sehingga berjalan 100% di browser
Semuanya bisa dilihat di sini: https://lispcookbook.github.io/cl-cookbook/editor-support.ht...
mine. Ada tautannya?Sepertinya ada bug syntax highlighting di situs webnya. Potongan kode yang disisipkan di artikel tampil hitam, dan teks aslinya baru terlihat kalau dipilih dengan mouse
Bug yang sama terlihat di Chrome desktop dan Safari di iPad
Solusi sementara adalah membuka salah satu elemen kode di debugger browser lalu menambahkan
color: whitepada style:not(pre) > codeAda banyak tulisan yang memuja kelebihan Lisp. Saya juga ingin melihat tulisan yang mengkritik dengan tenang Lisp, ide-idenya, dan posisinya dalam ekosistem bahasa.
Tulisan seperti ini, atau tulisan PG yang dirujuk di sini, pada akhirnya terasa dekat dengan “yang paham ya paham”. Saya memahami daya tariknya, dan juga memahami klaim yang dibuat tulisan ini secara eksplisit maupun implisit.
Pemrograman komputer sudah cukup matang selama 60 tahun terakhir. Saya ingin melihat lebih banyak tulisan yang memuat telaah yang lebih mendalam.
Kekurangan kedua adalah ia bisa menghabiskan waktu orang-orang yang cukup kompeten selama bertahun-tahun, tetapi hasilnya tidak membenarkan waktu yang diinvestasikan itu. Sesuatu seperti Python juga sudah memadai. Saya merasa akan lebih baik jika sebagian besar waktu yang saya habiskan untuk Lisp dipakai untuk hal lain.
Clojure, Clojurescript, Clojure-Dart, Fennel, Jade, Jank, Jolt, Coalton adalah bahasa-bahasa yang relatif baru dan masih terus berkembang sekarang. Itu baru yang langsung terlintas, dan masih ada jauh lebih banyak lagi.
Dalam satu makna, Lisp bukan bahasa pemrograman melainkan sebuah gagasan. Ia telah memengaruhi hampir semua bahasa pemrograman yang kita pakai saat ini dan masih terus begitu. Sulit untuk mengkritik sebuah gagasan “dengan tenang”; itu mirip seperti mengkritik teori grup. Namun, kelebihan dan kekurangan dari implementasi tertentu atas gagasan itu tetap bisa dibahas.
async/awaityang distandardisasi. Standarnya tidak pernah diperbarui sejak 1995, jadi kemungkinan besar itu juga tidak akan terjadi ke depan.Bagi sebagian orang, ia terasa menarik secara mental. Saya ingin membandingkannya dengan genre musik yang benar-benar niche. Orang yang menyukainya sedikit, tetapi mereka menyukainya dengan sangat intens. Ini seperti Stockhausen-nya dunia pemrograman.
Pada dasarnya ini adalah fandom. Fandom yang bertahan sangat lama secara mengejutkan, tetapi tidak pernah benar-benar menembus arus utama, dan kecil kemungkinan akan begitu ke depannya. Sekarang posisinya malah lebih buruk. Jika Anda dipersenjatai dengan LLM dan tidak terlalu peduli pada kode itu sendiri, mengapa repot-repot menyuruhnya menulis dalam Lisp?
Saya sudah terlalu lama memakai Lisp sampai-sampai tidak lagi benar-benar mensyukuri fitur-fiturnya. Lalu ketika melihat orang-orang merusak diri mereka sendiri di bahasa yang populer dan secara ekonomi kurang berisiko, dengan rasa kaget dan ngeri, saya tiba-tiba kembali merasakan nilai Lisp.
Di lapangan komersial, bahasa khusus domain adalah antipola. Seseorang membuat bahasa khusus domain yang dokumentasinya minim dan hanya dia yang memahaminya, lalu pergi.
Programmer yang datang belakangan harus bersusah payah menguraikan bahasa aneh itu. Hampir selalu lebih baik memakai struktur dan fitur bahasa standar. Kode lebih sering dibaca daripada ditulis.
Yang sebenarnya ditolak kemungkinan besar adalah kurangnya transparansi referensial. Secara adil, ini juga menjadi masalah di banyak bahasa, termasuk Lisp.
Contoh yang bagus adalah makro
LOOPdi Common Lisp itu sendiri. Jika cara pemakaian seseorang sulit dipahami, Anda bisa meminta Lisp untuk memperluasnya menjadi pemanggilan dasar non-LOOPyang lebih verbose, dan sama sekali tidak perlu memahamiLOOP. Bahkan, Anda bisa mengganti formLOOPitu dengan kode hasil ekspansinya.Ini merupakan perbedaan kunci dari kebanyakan bahasa lain, di mana kode bahasa khusus domain pada praktiknya adalah struktur data yang kemudian diinterpretasikan.
Lisps memang punya hal-hal yang sangat kuat dan unik, tetapi saya berharap tulisan seperti ini tidak terus-menerus memasukkan REPL dan hot reloading.
REPL sudah lama menjadi syarat dasar di bahasa interpreter, bahkan di sebagian bahasa kompilasi. Hot reloading juga tidak unik, dan tidak terlalu luas dipakai secara khusus. Karena harus menangani state dan patch, ada alasan mengapa mereset semuanya demi mempermudah penalaran dianggap sebagai praktik terbaik.
Itu membuat pengembangan menjadi jauh lebih interaktif dibanding bahasa interpreter lain.
Tentu saja tidak sempurna. Tetapi untuk jenis perubahan yang dilakukan saat mengiterasi pengalaman pengguna, itu bekerja sangat baik.
Namun, patut ditekankan bahwa cukup banyak bagian tingkat lanjut dari hot reloading sudah ditangani di Common Lisp. Hal yang sama berlaku untuk REPL, yang lebih sering dipakai bukan sebagai tempat mengetik langsung, melainkan sebagai antarmuka yang sangat kuat tempat image yang sedang berjalan dan alat saling berinteraksi.
Meski begitu, saya setuju bahwa keberadaan hal-hal ini saja tidak membuatnya terlalu istimewa pada masa kini.
Jika definisi kelas diganti lewat reload tetapi instance lama masih tersisa, apa yang harus dilakukan? Dialek Common Lisp punya jawaban yang berguna untuk pertanyaan seperti ini, tetapi tidak setiap Lisp yang Anda temui pasti demikian.
Bash juga mendukung hot reloading. Saya pernah mengembangkan modul yang diperbarui di tempat dengan
sourceseperti berikut.$ . /path/to/script.shKegunaannya memang terbatas, tetapi jika Anda memulai dari sudut pandang bahwa Anda akan sering memakainya, batasan itu mulai menghilang cukup cepat.
Secara pribadi saya sudah melewati tahap-tahap seperti ini. Saya pernah memakai Common Lisp, Forth, dan Haskell, dan membaca 『On Lisp』 serta 『Let Over Lambda』 dengan senang hati
Sekarang saya menganggap bahasa pemrograman terbaik adalah Triage Calculus karya Barry Jay. Ini lebih dekat ke logika kombinator atau kalkulus lambda tak bertipe
Namun berbeda dari kalkulus lambda, Triage Calculus memiliki kutipan bawaan dan introspeksi yang mirip dengan
CARdanCDRdi Lisp, sehingga pemeriksaan tipe bisa ditambahkan dengan mudah. Jadi di TC, jika Anda hanya membuat abstraksi yang benar, Anda bisa memiliki sintaks apa pun yang Anda inginkan. Ini benar-benar bahasa pemrograman pamungkasTC menunjukkan bahwa pembedaan antara fitur bahasa dan sintaks di satu sisi, serta definisi fungsi/API di pustaka standar atau kode pengguna di sisi lain, adalah dikotomi palsu. Setiap kali Anda menulis kode yang dimaksudkan untuk dipakai ulang, Anda sedang menambahkan sesuatu ke bahasa. Semua itu bisa diekspresikan sebagai suatu term dalam TC
Semua perdebatan tentang sintaks hanyalah soal kebiasaan. Hanya saja, satu fitur sintaks yang benar-benar saya inginkan di TC adalah abstraksi
let over lambda, karena menyusun kombinator dengan tangan agak merepotkanTulisan yang bagus
Dulu saya berpikir bahwa suatu hari semua orang akan memakai Lisp, dan kalau alat serta pustaka yang hebat sudah tersedia, semuanya akan menjadi luar biasa. Bahkan rencana saya setelah pensiun adalah membuat pustaka berkualitas tinggi untuk bahasa Lisp demi mempercepat proses itu
Apakah kebangkitan AI akan mengakhiri mimpi ini? Apakah sekali lagi kita menyelesaikan masalah dengan menambahkan lebih banyak tetek bengek? Apakah alih-alih menulis kode dalam bahasa pemrograman terbaik yang mungkin untuk AI supercerdas, kita malah hanya akan menyebarkan banyak kode Python dan terus memaksakannya sampai berhasil?
Saya tidak tahu apakah ini penting. Saya hanya menginginkan dunia yang punya keanggunan
“Jean-Marie Hullot, saat bekerja di INRIA, membuat ‘SOS Interface’ untuk Macintosh yang ditulis dalam Lisp, dan itu adalah ‘interface builder’ modern pertama”
https://denninginstitute.com/itcore/userinterface/GUIHistory...
Saya jadi bertanya-tanya bagaimana jadinya kalau ini menjadi produk Mac arus utama, alih-alih berpindah ke NeXT dan dipakai bersama Objective-C
LISP sangat cocok untuk saya. Dalam kelas bahasa komparatif di kampus, hanya saya yang menyelesaikan semua tugas LISP, dan belajar LISP juga sangat membantu saya saat menggunakan TeX
Yang saya inginkan adalah toolkit GUI native atau lintas platform yang lumayan dan open source, serta cara mudah untuk mendistribusikan proyek sebagai kode hasil kompilasi yang bisa dijalankan secara mandiri
Manusia bisa mengekspresikan ide yang bagus dengan keduanya. Lebih baik menganggap bahasa sebagai alat. Impact drill tidak lebih unggul daripada bor putar biasa. Saat membuat dek, impact drill mungkin lebih cocok, tetapi keduanya sama-sama bisa menyelesaikan pekerjaan
Saya kira ini akan menjadi https://web.archive.org/web/20120106121645/http://wiki.alu.o...
Ini mengingatkan saya pada masa-masa mengikuti comp.lang.lisp. Rasanya seperti drama tersendiri. Bukan hanya sihir pemrograman, tetapi juga banyak tokoh yang kuat karakternya dan berbagai kejadian