1 poin oleh GN⁺ 2024-06-10 | 2 komentar | Bagikan ke WhatsApp
  • Startup yang baru saja mengaktifkan monetisasi mengalami gangguan pembayaran langganan, tetapi karena tidak bisa direproduksi secara internal, identifikasi penyebabnya tertunda selama 5 hari
  • Gangguan bermula saat format konversi Prisma/TypeScript→Python/SQLAlchemy buatan ChatGPT disalin, lalu string ID yang di-hardcode masuk sebagai nilai default alih-alih fungsi pembuat UUID
  • Karena arsitekturnya terdiri dari 8 task AWS ECS dan masing-masing 5 instance, pengguna bisa bertemu salah satu dari maksimal 40 pool ID unik, sehingga pada siang hari masalahnya tertutupi oleh deploy yang sering
  • Saat malam deploy berhenti, satu ID pada tiap server habis terpakai, dan setelah itu upaya langganan baru gagal karena tabrakan unique ID
  • Dengan 50 keluhan per hari, selama 5 hari, dan biaya langganan $40 per bulan, kerugiannya diperkirakan mencapai $10,000 per bulan; ketiadaan testing, logging, alerting, dan praktik menyalin kode memperbesar dampak insiden

Gangguan langganan yang muncul tepat setelah monetisasi

  • Startup tersebut pertama kali mengaktifkan monetisasi pada bulan Mei dan mendapatkan pelanggan pertama dalam 1 jam setelah peluncuran
  • Keesokan paginya, Gmail sudah dipenuhi lebih dari 40 keluhan pengguna
    • Pengguna tidak bisa menyelesaikan langganan
    • Saat menekan tombol langganan, muncul spinner loading tanpa henti
  • Mereka membuat akun baru dan mencoba memeriksa sendiri, tetapi di lingkungan internal langganan tetap berjalan normal sehingga penyebabnya tidak bisa direproduksi
  • Pada jam kerja hampir tidak ada keluhan, dan gangguan terutama menumpuk pada malam hari

Implementasi monetisasi di bawah tekanan waktu

  • Mei adalah saat batch YC S23 dimulai, dan tim belum yakin arah mana yang paling tepat setelah peluncuran
  • Dalton, group partner YC, menyarankan agar pelanggan berbayar dijadikan metrik penentu arah, dan harga bulanan yang dipikirkan dinaikkan dua kali lipat
  • Harga akhirnya ditetapkan menjadi $40 per bulan
  • Proyek awalnya full-stack NextJS, tetapi sebelum dan sesudah pekerjaan monetisasi mereka sedang memindahkan sistem ke Python/FastAPI
    • Mereka memanfaatkan ChatGPT selama proses migrasi
    • Integrasi Stripe juga sudah selesai
  • Selama 5 hari berikutnya, waktu tidur berkurang drastis dan mereka harus menangani 30–50 email keluhan setiap hari

Format konversi model buatan ChatGPT

  • Dalam proses migrasi backend, model database dipindahkan dari Prisma/TypeScript ke Python/SQLAlchemy
  • Karena konversi model terasa membosankan dan ChatGPT dinilai melakukannya dengan baik, mereka menggunakannya untuk hampir seluruh migrasi
  • Kode yang dihasilkan disalin-tempel lalu dicek apakah berjalan, dan karena tampak normal di production, proses itu diteruskan
  • Saat itu, penyisipan database masih ditangani oleh Next API, dan backend Python hanya membaca database
  • Ketika fitur langganan diimplementasikan, untuk pertama kalinya mereka mulai menyisipkan record DB dari Python
    • Model SQLAlchemy baru dibuat sendiri, tetapi format buatan ChatGPT dari model lama disalin apa adanya
    • Masalah yang sama masuk ke metode pembuatan ID di semua model

Penyebab sebenarnya dan mengapa tidak terlihat di siang hari

  • Kesalahan intinya adalah memberikan satu string ID yang di-hardcode, bukan memberikan fungsi atau lambda yang menghasilkan UUID
  • Jika satu pengguna di instance backend tertentu berhasil menyelesaikan langganan dengan ID itu, maka upaya langganan berikutnya pada instance yang sama akan memicu tabrakan ID unik
  • Konfigurasi backend membuat masalah ini tersembunyi lebih lama
    • Mereka menjalankan 8 task ECS di AWS
    • Setiap task menjalankan 5 instance backend
    • Pengguna berpotensi mencapai salah satu dari 40 ID berbeda
  • Pada siang hari mereka langsung commit ke branch main 10–20 kali per hari, dan setiap kali itu memicu deploy backend baru
    • Setiap deploy menciptakan 40 ID baru yang bisa dipakai pelanggan
  • Pada malam hari, commit dan deploy berhenti sehingga satu ID pada tiap server cepat habis terpakai
    • Awalnya ada hampir 40 server yang masih bisa menerima langganan, tetapi seiring waktu jumlah itu turun mendekati 0

Besarnya kerugian dan langkah setelahnya

  • Kerugian dihitung sebagai 50 emails/day x 5 days x $40/month dan diperkirakan mencapai $10,000 pendapatan bulanan yang hilang
    • Perhitungan ini hanya berdasarkan pengguna yang mengirim keluhan
  • Untuk menemukan penyebabnya dibutuhkan 5 hari, sangat banyak email, ratusan log Sentry, percakapan Discord yang panjang dengan engineer Stripe, dan peninjauan lima file inti
  • Setelah penyebab ditemukan, Adam segera mengunggah perbaikannya
  • Setelah itu mereka menambahkan unit/integration test yang kuat, alerting, dan logging
  • Insiden ini menunjukkan bahwa kesalahan manusia, testing yang kurang, penyalinan kode, dan push langsung ke main dapat membuat satu baris kecil berujung pada kehilangan pendapatan yang besar

2 komentar

 
znjadong 2024-06-11

Eh, kode yang dibuat otomatis oleh AI itu tentu harus ditinjau dulu, kenapa langsung dipakai begitu saja?

 
GN⁺ 2024-06-10
Opini Hacker News
  • Tidak adanya monitoring itulah yang membuat mereka kehilangan 10 ribu dolar. Aplikasi terus-menerus mengeluarkan exception database dalam jumlah besar, tetapi tidak ada yang menerima notifikasi
    Kalau ada notifikasi seperti itu, investigasinya akan selesai dalam 5 menit, bukan 5 hari. Jika sistem notifikasinya tidak diperbaiki, sebenarnya tidak ada yang benar-benar diperbaiki

    • Benar. Pesan log pasti menunjukkan bahwa ID tidak unik, dan itu akan jauh mengurangi waktu debugging
      Pemrograman itu mudah saat semuanya berjalan baik; bagian yang sulit adalah menangani masalah
    • Hal seperti ini makin sering terjadi. Perusahaan dan pendiri tidak memikirkan infrastruktur, karena percaya penyedia cloud pilihan mereka akan secara ajaib mengurus semuanya
      Begitu ada pelanggan berbayar yang masuk, dibutuhkan orang yang punya pengetahuan dan pengalaman untuk menangani logging, monitoring, notifikasi, keamanan, dan sebagainya. DevOps tidak boleh diperlakukan secara amatiran
    • Tidak adanya test juga buruk, dan memakai sesuatu buatan AI tanpa memeriksanya tiga kali juga berbahaya
      Namun bagian yang benar-benar gila adalah database tidak punya logging error dan notifikasi. Ini bukan kode legacy berusia 20 tahun, melainkan produk baru, dan juga bukan kode dari masa ketika error DB dipakai seperti validasi data
    • Deploy lalu langsung tidur terlihat sebagai sinyal bahaya di sini. Seharusnya deploy dilakukan sekitar pukul 9 pagi, lalu masalah dipantau selama jam kerja
    • Sepertinya ChatGPT tidak memberi tahu bahwa monitoring diperlukan
  • Artikel blog-nya menampilkan 404, jadi saya tinggalkan tautan Web Archive
    https://web.archive.org/web/20240610032818/https://asim.bear...
    Penulis menambahkan koreksi penting: praktik yang dilakukan di sini sangat buruk dan memalukan, dan setelah itu mereka menambahkan unit/integration test yang solid serta notifikasi/logging. Intinya, ini adalah kesalahan manusia, dan jika dilihat ke belakang jelas bisa dihindari
    Ia juga menambahkan bahwa kejadian ini terjadi dalam beberapa minggu awal perusahaan, di bawah tekanan waktu yang besar, dan meminta agar ini dilihat sebagai cerita lucu tentang bug yang secara unik bisa direproduksi di production

  • Kesalahannya langsung terlihat. Dengan tetap menghormati timnya, ini tidak terlalu berkaitan dengan ChatGPT, melainkan lebih karena mereka memakai model pemrograman yang belum cukup familier bagi tim
    Bahkan andaipun lolos code review, besar kemungkinan ini bisa tertangkap hanya dengan tool monitoring yang bisa disiapkan dalam 5 menit

    • Agar adil, kalau tidak secara khusus mencari bug ini, saya rasa saya juga tidak akan melihatnya. Tetap saja, benar bahwa dengan monitoring atau sekadar pengujian manual paling dasar pun ini akan langsung tertangkap
    • Sepertinya tim bahkan tidak bisa melakukan troubleshooting dasar dari log database atau log aplikasi. Ini kesalahan sederhana, dan saya khawatir apa yang akan terjadi jika muncul error sementara seperti penguncian implisit pada tabel
    • Ini bukan kesalahan polos; judulnya sengaja dibuat clickbait sekaligus untuk optimasi kata kunci. Judul itu mengisyaratkan seolah-olah ChatGPT yang melakukan kesalahan, demi memancing klik karena kecemasan
      Judul seperti “Kami membuat kesalahan pemrograman saat menggunakan LLM, dan karena tidak melakukan quality assurance, biayanya 10 ribu dolar” tidak akan memicu reaksi eksekutif seperti “Kalau ChatGPT mengacau, berapa eksposur kerugian kita?” Akan ada sangat banyak manajer tingkat menengah dan senior yang membagikan tulisan ini di LinkedIn
      LLM tidak bisa “melakukan kesalahan”. Ia tidak deterministik, tidak bernalar, tidak berpikir, dan tidak menjalankan logika. Ia adalah generator word salad yang sangat mewah berbasis probabilitas statistik, dan karena tidak ada jaminan bahwa keluarannya benar atau akurat, secara definisi istilah kesalahan juga tidak tepat
      Edit: setelah tulisan ini banyak di-downvote karena alasan yang jelas, peringkatnya tiba-tiba melonjak, yang tampaknya berarti moderator mem-boost-nya: https://hnrankings.info/40627558/
      Lucu bahwa tulisan clickbait yang menurut aturan seharusnya judulnya diubah justru di-boost oleh moderator. Selain itu, fakta bahwa penulisnya tampaknya berasal dari perusahaan Y Combinator tentu saja pasti hanya kebetulan belaka: https://news.ycombinator.com/item?id=40629998
    • Menariknya, pihak lain yang menemukan kesalahan ini adalah ChatGPT-4o. Chat yang berisi gambar tidak bisa dibagikan, tetapi ketika saya menempelkan gambar kode yang salah dan bertanya “apa yang bermasalah dari kode ini”, ia memberi tahu hal berikut
      Untuk pembuatan UUID pada primary key, seharusnya memakai callable uuid.uuid4 secara langsung, bukan str(uuid.uuid4()), dan SQLAlchemy akan memanggil fungsi itu saat membuat nilai. Untuk default tanggal, ia mengatakan server_default=text("(now())") mungkin tidak berjalan sesuai harapan sehingga sebaiknya memakai func.now(), juga meminta memastikan impor uuid dan text dari SQLAlchemy, serta menyarankan mempertimbangkan DateTime(timezone=True) untuk penanganan zona waktu
      Setelah itu ia mengusulkan kode perbaikan id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()), unique=True, nullable=False), dan penambahan lambda: di sini memperbaiki masalahnya
    • Jika pengalaman Python hampir tidak ada, saya bisa membayangkan uuid.uuid4() dianggap seperti definisi skema di Prisma atau semacamnya. Jadi bug ini sendiri tidak mengejutkan, dan saya pun bisa saja membuat kesalahan yang sama
      Tetap saja, satu kali kubectl logs seharusnya langsung menangkapnya. Selain itu, dari Next.js dan Prisma lalu pindah ke Python? Kenapa?
  • Kesalahan itu sendiri bisa dipahami. Bahkan tanpa ChatGPT, kode seperti ini tampaknya cukup mudah terlewat
    Namun saya tidak paham mengapa setelah kegagalan pertama ini tidak tertangkap. Apakah perusahaan ini tidak punya logging? Fakta bahwa backend mencoba memakai ulang UUID seharusnya langsung terlihat dari error-nya

    • Mereka bahkan tidak tahu ada error sampai pelanggan mengeluh. Seharusnya mereka tahu error apa yang terjadi sebelum pelanggan, dan logging, alert, atau bentuk monitoring apa pun akan membantu
    • Inilah masalah yang sebenarnya. Kalau ini proyek yang bergerak cepat, kemungkinan besar suatu saat akan ada bug produksi seperti ini lagi. Semoga saja lain kali tidak butuh 5 hari untuk mengidentifikasinya
    • Butuh 5 hari untuk memahami bug ini itu cukup gila
    • Kasus khusus seperti beberapa langganan Stripe memang sangat mungkin luput dari unit test umum. Seperti yang disebutkan dalam tulisan, mereproduksinya dengan acceptance test juga mungkin tidak mudah, dan fokus pada ChatGPT terasa agak berlebihan, baik dari penulis maupun orang lain
      Tidak jarang orang tidak sengaja mengoper string ke fungsi yang seharusnya menerima objek callable, bukan String. Kalau tidak memakai ORM, masalah spesifik ini mungkin bisa dihindari, meski itu mungkin hanya bias pribadi saya terhadap ORM. Bug serupa juga sangat mungkin terjadi dalam konteks selain database
      Orang-orang yang dengan yakin mengatakan pasti akan menangkap bug ini entah memang engineer yang jauh lebih hebat daripada saya, atau, lebih mungkin, agak salah menilai kemampuan diri sendiri
      Namun tidak adanya log, atau tidak melihat log, benar-benar sulit dipahami. Kalau memakai ECS, sepertinya exception Duplicate Key akan diteruskan ke CloudWatch tanpa konfigurasi khusus; saya penasaran apakah itu tidak terjadi, atau terjadi tetapi tidak ada yang memeriksa exception apa yang muncul semalaman
    • Karena kegagalan proses seperti ini, Amazon memiliki proses koreksi kesalahan, yaitu proses postmortem: https://aws.amazon.com/blogs/mt/why-you-should-develop-a-cor...
      Dalam situasi seperti ini, berguna untuk bertanya mengapa deteksinya terlambat dan mengapa diagnosisnya memakan waktu lama
  • Saya sudah beberapa kali melihat kesalahan yang sama di kode buatan manusia. Terutama di React / TypeScript / JavaScript, orang sering lupa menambahkan lambda
    Tulisan blog itu terasa tidak benar-benar menjelaskan akar masalahnya dan langsung menyalahkan ChatGPT. Kalau bekerja terburu-buru, lalu memasukkan commit berisi perubahan besar atau tanpa review rekan ke main, hal seperti ini memang terjadi
    Masalah sebenarnya adalah kalau kita terburu-buru, mengambil jalan pintas, serta tidak melakukan pengujian yang memadai dan code review oleh rekan, error akan muncul. Rasanya ini pasti langsung ketahuan kalau saja ada tes yang mencoba beberapa opsi pendaftaran

    • Model mental saya tentang ChatGPT adalah engineer junior yang tidak akan pernah dipromosikan. Orang seperti ini pada akhirnya akan dipecat, tetapi karena bisa mengetik sangat cepat tanpa batas, ia bisa berguna jika dipakai dengan sangat hati-hati
      Kalau orang seperti ini ditempatkan di dekat kode yang penting secara finansial, masalah serupa akan muncul, dan saya akan mempertanyakan penilaian orang yang memutuskan untuk men-deploy kode itu dengan hampir tanpa tes
    • Masalah seperti ini umum terjadi di banyak tempat. Misalnya, properti komponen di Vue bisa memiliki nilai default, tetapi kalau memakai objek atau array literal sebagai nilai default alih-alih fungsi yang mengembalikan objek atau array, itu bisa jadi bencana
      Mengejutkan bahwa tidak ada aturan lint untuk kasus ini
    • ChatGPT hanyalah faktor pengalih perhatian. Yang penting bukan siapa atau apa yang menghasilkan kode itu, melainkan apa yang dilakukan dengan kode tersebut
    • Strukturnya: kode ditulis oleh ChatGPT, di-push oleh ChatGPT, lalu setelah itu direview juga oleh ChatGPT. /s
      Semoga saja tidak begitu
  • Bagian “proyek aslinya full-stack NextJS, tetapi saya ingin lebih dulu memigrasikan semuanya ke Python/FastAPI” cukup membuka mata
    Saya tidak mengerti bagaimana startup yang belum punya pelanggan bisa membenarkan penulisan ulang

    • Saya berpikir sama sampai merasa mungkin saya yang gila. Saya pikir menulis ulang sedini ini tidak masuk akal, tetapi rasanya tidak ada yang menunjukkannya di komentar
      Terlepas dari ada atau tidaknya pelanggan, saya tidak mengerti mengapa pada tahap sedini ini melakukan perpindahan horizontal yang pada dasarnya dari Node ke Python. Kalau mereka sudah punya ratusan pelanggan dan ingin beralih ke sesuatu seperti Go, mungkin masih bisa sedikit dimengerti, meski tetap meragukan
    • Selain itu, mereka sedang menulis ulang dalam bahasa yang belum cukup mereka kuasai sampai-sampai bug yang tampak jelas pun tidak dikenali
    • Dalam kasus saya, kalau ini proyek nyata yang sedang saya kerjakan, alasannya bisa jadi karena C# adalah bahasa yang bagus dan runtime serta framework web-nya juga lumayan, tetapi memperlambat pengembangan dan titik-titik sakitnya terus menumpuk
      Misalnya, saya harus membuat banyak objek DTO, tetapi AutoMapper tidak berjalan dengan kombinasi versi dan konfigurasi proyek yang saya pakai, dan Entity Framework serta serialisasi/deserialisasi JSON juga lebih banyak menyakitkan daripada memberi manfaat
      Tentu ini bisa diselesaikan secara bertahap. Bisa dengan menggali dokumentasi dalam-dalam, mencampurnya dengan hack, meng-upgrade paket, dan menulis ulang konfigurasi. Namun sebagai manusia, rasanya ingin mengambil jeriken bensin metaforis, membakar semuanya, lalu membuat sistem kedua yang lebih baik. Tentu pada kenyataannya belum tentu lebih baik; biasanya hanya muncul titik sakit lain, dan mungkin juga tidak bisa melakukan semua hal yang dilakukan sistem pertama atau tidak melakukannya dengan benar
      Di tempat kerja pun, setiap melihat sistem legacy atau sistem yang merepotkan, dorongan yang sama muncul. Dibutuhkan usaha aktif dan terus-menerus untuk mengalahkan otak yang berteriak agar menulis ulang. Kadang penulisan ulang atau perubahan arsitektur seperti adopsi container memang berhasil, tetapi biasanya berakhir masuk ke kobaran api atau menjadi pekerjaan tanpa akhir
      Kecuali ada keyakinan tinggi bahwa itu akan meningkatkan operasi sistem atau developer experience bagi developer lain, untungnya saya tidak menyerah pada dorongan itu
    • Satu-satunya kegagalan ChatGPT dalam kejadian ini adalah karena kemampuannya, ia membuat penulisan ulang sebelum peluncuran terasa seperti hal yang masuk akal dan mudah untuk menghabiskan runway
  • ChatGPT justru pihak yang menghasilkan uang untuk aplikasi itu. Karena tanpa ChatGPT, mereka tidak punya kemampuan untuk mengimplementasikannya
    Kurangnya kemampuan untuk coding, debugging, logging, dan monitoring-lah yang membuat 10 ribu dolar melayang, dan dalam cerita ini efek bersih ChatGPT positif

    • Melihat proyek tim ini di github.com/reworkd langsung terlihat tingkat kematangan produk dan timnya. Ini pengembangan berbasis emoji
      Semua pesan commit berisi emoji. Monyet, pisang, roket, kembang api, dan entah apa lagi
    • Apalagi jika dilihat sebagai biaya 20 dolar per bulan
    • 10 ribu dolar itu uang receh. Elon mungkin kehilangan 500 miliar dolar karena kesalahan xAI yang muncul hari ini
      https://grook.ai/share?id=e269e88a7b1a71eff4f176c864b30161&x...
    • Sepertinya mereka memang punya kemampuan, karena implementasinya sudah ada
      Katanya awalnya full-stack NextJS, lalu saat memigrasikan backend ke Python/FastAPI, mereka menerjemahkan model database Prisma/Typescript ke Python/SQLAlchemy. Pekerjaan ini membosankan, dan karena menilai ChatGPT cukup bagus melakukannya, mereka memakainya untuk hampir seluruh migrasi
      Kalau sejak awal tidak ada ChatGPT, mereka mungkin tidak akan mencoba migrasi pendahuluan ini, jadi sulit menyebut efek bersihnya positif. Stack lama mungkin punya logging error yang lebih baik, mungkin juga tidak; dan karena kodenya ditulis sendiri, mereka mungkin lebih memahami strukturnya sehingga kebutuhan itu lebih kecil
      Keputusan untuk “menulis ulang semua kode untuk kedua kalinya” sebelum mengaktifkan monetisasi itu sendiri memang menarik
  • Ada kalimat, “Saya ingin terlebih dahulu mengatakan bahwa praktik di sini buruk dan bisa dihindari. Ini terjadi pada periode lain ketika ada tekanan waktu besar. Mohon baca dengan mempertimbangkan hal ini”
    Karena batasan seperti inilah langganan software terasa menakutkan

    • Saya sangat menghormati penulis karena mempublikasikan cerita ini, terutama karena menambahkan pengantar seperti itu. Mengetahui kesalahan apa yang dibuat orang lain sangat berguna, tetapi mempublikasikan kesalahan sendiri bisa cukup memalukan
    • Meski tidak suka langganan, dunia lama ketika kita membeli lisensi ratusan dolar per kursi pengguna juga bukan dunia yang hebat
    • Saya pernah menangani kode langganan legacy, dan itu bisa sangat berantakan
      Karena race condition, kami pernah menagih pengguna dua kali. Jadi setiap melihat timeout atau error yang berkaitan dengan uang, saya jadi paranoid sampai-sampai pertama-tama mengasumsikan pembayaran sudah terjadi lalu memeriksanya lagi nanti
    • Alternatifnya adalah menulis sendiri, tetapi itu membuat segala hal lain ikut terkena batasan
    • Melakukan penulisan ulang di tengah tekanan waktu yang “besar” juga tidak biasa
  • Kode yang ditulis dengan TypeScript dan Python, framework seperti Next.js, menjalankan masing-masing 5 instance untuk 8 task AWS, tapi pendapatannya hanya 40 dolar dan masa pengembangannya cuma beberapa minggu?
    Saya jadi bertanya-tanya sebenarnya apa yang terjadi. Mereka memperbaikinya dengan alasan kodenya berantakan karena keterbatasan waktu, tetapi yang lebih buruk adalah mereka justru menghabiskan waktu untuk refactoring lintas bahasa dan membangun sistem terdistribusi tanpa alasan jelas
    Ini adalah kompleksitas yang melukai diri sendiri, karena mereka mencoba menjuggling fitur dan kompleksitas teknis yang tidak masuk akal sekaligus. Entah apa yang mereka pikirkan
    Koreksi: Ini perusahaan YC musim panas 2023, tetapi bahkan pada musim panas 2024 produknya tampaknya masih berada di balik daftar tunggu. Mungkin karena sedang ditulis ulang dengan Rust

    • Karena mereka punya pendanaan awal 500 ribu dolar, ditambah 1,2 juta dolar lagi di atasnya, serta kredit AWS gratis untuk dibakar habis
  • Rasanya mereka bahkan belum pernah menulis total 1000 baris Python, tetapi berhasil menemukan masalahnya dengan tepat
    Python punya cacat karena gagal menyalin strategi evaluasi Common Lisp dengan benar. Jika ada argumen seperti foo=obj.whatever() pada ekspresi nilai default untuk argumen fungsi opsional, obj.whatever() dievaluasi saat definisi fungsi diproses, bukan saat fungsi dipanggil
    Saya curiga itu sengaja dibuat begitu demi efisiensi. Python juga punya cacat lain: tidak ada sintaks literal sejati untuk objek umum seperti list. [1, 2, 3] bukan literal, melainkan lebih mirip konstruktor, dan setiap kali dievaluasi harus membuat list baru lalu mengisinya dengan nilai
    Perancangnya mungkin tidak ingin parameter seperti list=[] membuat list kosong baru setiap kali argumen dihilangkan. Di Lisp, '(1 2 3) dan '() adalah literal sejati dan menunjuk ke objek yang sama setiap kali direferensikan. Programmer bisa memilih apakah akan memakai (list 1 2 3) atau '(1 2 3) sebagai ekspresi nilai default
    Yang pertama membuat objek mutable baru setiap kali seperti [1, 2, 3], sedangkan yang kedua hampir pasti mengembalikan objek yang sama dan tidak dapat dimodifikasi secara andal serta portabel. Bahasa populer modern sudah memiliki sebagian besar fitur Lisp, jadi ini terasa seperti lelucon bahwa tidak ada ruginya

    • Pernyataannya sendiri benar, tetapi yang terjadi dalam tulisan blog itu bukan itu. Masalahnya ada di dalam definisi class, bukan definisi fungsi
    • Pernyataan bahwa pada foo=obj.whatever(), obj.whatever() dievaluasi saat definisi fungsi diproses, bukan saat fungsi dipanggil, rasanya tidak mungkin benar
      Kalau .whatever() bergantung pada state internal yang berubah setelah inisialisasi objek, lalu apa yang terjadi?