3 poin oleh GN⁺ 2025-11-04 | 1 komentar | Bagikan ke WhatsApp
  • Catatan yang menganalisis kode C interpreter bahasa K sepanjang 50 baris buatan Arthur Whitney sambil menafsirkan gaya pemrogramannya yang unik
  • Kode tersebut memuat banyak struktur eksperimental yang berbeda dari kode C pada umumnya, seperti sintaks padat berbasis makro, ekstensi C nonstandar, dan penggunaan argumen implisit
  • Penulis menafsirkan sendiri makna tiap makro dan fungsi sambil menelusuri filosofi bahasa keluarga APL serta kelebihan dan kekurangan kepadatan kode
  • Sebagai kelebihan, penulis menyoroti panjang yang singkat dan daya susun yang tinggi, sementara kekurangannya adalah sintaks nonstandar dan menurunnya keterbacaan
  • Pada akhirnya, kode ini dinilai sebagai contoh yang menunjukkan pentingnya cara berpikir menulis kode setelah sepenuhnya memahami masalah, bukan sekadar “cara menulis dengan singkat”

Arthur Whitney dan kodenya

  • Arthur Whitney adalah ilmuwan komputer yang merancang bahasa A, K, Q serta basis data kdb, Shakti
    • kdb adalah basis data deret waktu berkecepatan sangat tinggi yang digunakan di sektor finansial, sedangkan Shakti adalah versi yang lebih cepat dan dirancang untuk menangani dataset berskala 1 triliun baris
  • Bahasa-bahasanya adalah bahasa berbasis array yang sangat dipengaruhi APL, dengan penekanan pada keringkasan dan daya ekspresi matematis
  • Fokus tulisan ini bukan pada aplikasi finansialnya, melainkan pada analisis gaya unik kode C yang ditulis Whitney

Struktur interpreter K 50 baris

  • Repositori publik ksimple memuat interpreter C sekitar 50 baris yang ditulis Whitney hanya dalam beberapa hari
  • Inti kodenya terdiri dari dua berkas, a.h dan a.c, dengan ciri khas pemendekan definisi fungsi melalui makro dan struktur yang memperlakukan pointer seperti integer
  • Melalui sintaks typedef char*s,c;, s didefinisikan sebagai pointer string dan c sebagai tipe karakter
  • s Q=(s)128; adalah contoh pointer yang digunakan seperti integer, dan di seluruh kode Q dipakai sebagai nilai khusus yang menandakan status error
  • Banyak dipakai sintaks ekstensi GCC seperti statement expression berbentuk ({e;}) dan operator ?:
Iklan

Makna makro dan fungsi utama

  • #define _(e...) ({e;}) : makro yang membungkus beberapa pernyataan menjadi satu ekspresi
  • #define i(n,e) : bentuk ringkas perulangan, menuliskan loop for dalam satu baris
  • #define Q(e) dan sejenisnya adalah makro penanganan error, sedangkan Qr, Qd, Qz masing-masing mengembalikan error rank, domain, dan not-yet-implemented
  • Makro _s, _i, f, F menyederhanakan deklarasi fungsi dan secara implisit memakai argumen x, a
  • ax, ix, nx dan lainnya adalah makro untuk pemeriksaan tipe data dan pengindeksan, dengan ax menentukan apakah “x adalah atom”
  • f(w,write(1,ax?&x:x,ax?1:strlen(x));x) adalah fungsi output: jika atom maka dicetak sebagai karakter, jika vektor maka sebagai string

Cara kerja interpreter

  • Fungsi m(x) melakukan alokasi memori dan pembuatan pointer yang memuat informasi panjang, dengan panjang maksimum vektor 255 byte
  • Makro g(a,v) menyatukan penanganan operasi atom/vektor, dan fungsi seperti not, sub, At, _A didefinisikan berdasarkan makro ini
  • Makro G(f,o) melakukan pembuatan otomatis fungsi operator biner, mendukung operasi seperti <, ==, +, *, &, |
  • cat, rev, cnt, Tak adalah fungsi manipulasi vektor, dan rev membuat indeks terbalik dengan memakai fungsi ind
  • Fungsi e() adalah evaluator rekursif yang membaca string dari kanan ke kiri untuk menangani variabel satu karakter, angka, dan operator
  • main() berbentuk loop REPL yang menerima input, mengevaluasinya dengan e(), lalu mencetak hasilnya

Penilaian terhadap gaya kode

  • Kelebihan
    • Himpunan operasi primitif yang ringkas dan tersusun dari makro yang dapat dikombinasikan
    • Karena panjang kode yang pendek, seluruh logika bisa dilihat sekaligus tanpa perlu scroll
    • Ekspresi berkepadatan tinggi memampatkan struktur logis kode
  • Kekurangan
    • Penanganan tipe yang tidak bermakna secara semantik karena char* diperlakukan seperti integer
    • Keterbacaan menurun akibat penggunaan langsung kode ASCII, operator ternary yang rumit, dan sintaks nonstandar
    • Argumen implisit dan nama variabel yang pendek membuat niat kode sulit dipahami
  • Unsur netral
    • Sintaks khusus GCC (?:, statement expression) menarik, tetapi mengurangi portabilitas
    • Penggunaan argumen implisit berguna pada kode kecil, tetapi bisa menimbulkan kebingungan pada kode besar
    • Nama yang pendek efisien setelah terbiasa, tetapi lemah dalam menyampaikan makna
    Iklan

Kesimpulan dan pelajaran

  • Kode ini bukan sekadar soal “cara menulis dengan singkat”, melainkan menunjukkan cara berpikir menulis kode setelah masalah dipahami sepenuhnya
  • Kode Whitney adalah bentuk pemindahan model matematis yang sudah selesai ke dalam kode, yaitu “hasil mengekspresikan pikiran ke dalam kode”
  • Penulis merefleksikan kebiasaannya selama ini yang cenderung menyelesaikan masalah di dalam kode,
    dan ke depan menekankan pentingnya pemodelan konseptual dan penataan pikiran sebelum menulis kode
  • Pada akhirnya, eksperimen ini dirangkum sebagai pengalaman untuk melatih kemampuan membaca kode dan menelusuri keseimbangan antara kepadatan kode dan kejernihan berpikir

Ide eksperimen lanjutan

  • Usulan latihan memperluas interpreter:
    • Dukungan vektor floating-point
    • Penanganan elemen lebih dari 255 buah
    • Angka dan nama variabel multikarakter
    • Literal array dan pengabaian spasi
    • Penambahan manajemen memori dan fitur penanda error
    • Menyelesaikan fungsi yang belum diimplementasikan
  • Perluasan semacam ini dapat menjadi eksperimen untuk mengembangkan gaya kode ala Whitney menjadi bahasa yang benar-benar dapat dipakai sambil tetap mempertahankan ciri khasnya

1 komentar

 
GN⁺ 2025-11-04
Opini Hacker News
  • Makro dalam kode ini dibuat untuk memadatkan operasi yang umum Saya membaca J Incunabulum terlebih dahulu sebelum melihat kode ini, dan bagi programmer yang terbiasa dengan C, mulai membaca dari tengah bisa membuat definisi makro di awal terasa membingungkan Karena makro-makro itu saling bertumpuk satu sama lain, kodenya cepat menaiki tangga abstraksi Saya terutama menyukai makro Iterate (i), karena ia merangkum loop yang bertele-tele menjadi satu huruf Alasan kode sepadat ini sulit dibaca adalah karena ia membuat begitu banyak abstraksi hanya dalam puluhan baris lalu langsung memakainya Jadi harus dibaca pelan-pelan, satu karakter demi satu karakter Sebagai orang yang pernah bekerja di codebase besar yang terdiri dari ratusan file tipis, kepadatan ekstrem seperti ini justru terasa menyegarkan

    • Saya juga punya kesan serupa saat membaca Incunabulum, tetapi ketika nama variabel saya ganti dengan emoji, kodenya jadi jauh lebih mudah dipahami Seperti yang terlihat pada gambar kode versi emoji, sebagian masalahnya bukan cuma kepadatan informasi, tetapi juga bentuk tulisan (orthography) Bahasa modern biasanya tidak mengizinkan simbol atau emoji dalam identifier, padahal kalau pembedaan visual seperti itu memungkinkan, keterbacaannya akan jauh lebih baik Selain itu, kebanyakan editor memakai syntax highlighting per jenis sintaks, tetapi pewarnaan berbasis token (setiap identifier punya warna unik) sering kali lebih berguna Contohnya adalah “hashed syntax highlighting” di Sublime Text Setelah diubah seperti ini, struktur kodenya langsung terlihat jelas
    • Sepertinya para developer justru menyukai codebase yang besar sekali Saya suka struktur yang bisa langsung dicari dengan grep *.[ch] tanpa subdirektori Proyek Java terutama sulit dicari karena ada terlalu banyak file kecil dengan isi yang minim Memang lebih baik kalau ada IDE, tapi saya tidak memakainya Whitney pernah berkata dalam wawancara bahwa ia ingin semua kodenya muat dalam satu halaman, dan “IDE”-nya adalah Windows console dan Notepad
  • Untuk memahami kode C Arthur Whitney, pertama-tama kita perlu mempelajari bahasa keluarga APL Kalau tidak, ini hanya akan terlihat seperti gaya C yang aneh Whitney sedang mencoba memakai C seperti APL Gaya tanpa spasi, nama satu huruf, dan fungsi satu baris juga sama di APL Ini mirip seperti programmer Pascal yang menulis sesuatu seperti #define begin {, tetapi Whitney jauh lebih orisinal dari itu

    • Bahkan dari sudut pandang pengguna APL, ini tetap terlihat aneh Bahasa K buatan Whitney memang memakai gaya seperti ini, tetapi fungsi satu baris tidak mungkin dilakukan dalam APL tradisional Makro, operator ternary, atau nama variabel implisit juga tidak ada di APL Inti dari APL adalah operasi array yang immutable, dan gaya C Whitney berbeda dari filosofi itu
    • Menanggapi komentar “ini seperti programmer Pascal yang pindah ke C lalu menulis #define begin {”, ada yang bercanda, “ah, seperti Stephen Bourne ya”
    • Awalnya ini tampak seperti bahasa fungsional, tetapi tak lama kemudian malah mengingatkan pada horor preprocessor C
    • Padahal di bagian pembuka tulisan sudah dijelaskan bahwa “C milik Whitney terinspirasi dari APL” Ini sindiran bahwa terlalu banyak komentar yang hanya merangkum isi tulisan
    • Mempelajari J juga tampaknya ide yang bagus J lebih mudah diakses daripada APL karena memakai simbol yang bisa diketik dengan keyboard biasa
  • Saat mencari Shakti, saya melihat tautan Wikipedia diarahkan ke k.nyc, dan di halaman itu hanya ada satu huruf ‘k’ Setelah melihat source-nya, memang cuma ada `k

` Ini terasa seperti minimalisme ala Whitney versi HTML — semua yang tidak perlu dibuang, lalu sisanya dibiarkan ditangani compiler secara implisit

  • k

  • Tulisan blog ini adalah analisis yang sangat bagus, terlepas dari bagaimana kita menilai gaya coding Whitney Untuk tulisan yang kabarnya dibuat hanya dalam 8 jam, isinya cukup mendalam, dan bagian kesimpulannya sangat mengesankan Tautan teks asli

  • Ini mengingatkan pada upaya Stephen Bourne untuk membuat C terasa seperti Algol Kalau melihat contoh mac.h dan contoh expand.c, nuansanya terasa mirip

  • Di setiap bidang selalu ada yang disebut “best practice”, tetapi itu hanya benar-benar cocok untuk kasus rata-rata Dalam situasi tertentu, justru pendekatan sebaliknya bisa lebih baik Pada akhirnya, kebijaksanaan kolektif layak dijadikan default, tetapi begitu mulai berpikir sendiri, celah-celahnya akan mulai terlihat

    • Karena itu saya tidak suka istilah “best practice” Sebenarnya itu cuma kompromi tingkat rata-rata Itu adalah pertukaran: mengorbankan efisiensi dan performa demi kemudahan pemeliharaan dan konsistensi
    • Membuat produk yang bagus dan keterbacaan codebase atau kurva belajar adalah hal yang terpisah Kalau yang satu baik, bukan berarti yang lain otomatis ikut baik
  • Senang melihat sudut pandang yang seimbang tanpa bersikap agresif terhadap kode tersebut Menyenangkan untuk dibaca, dan saya ingin membacanya lagi nanti

  • Saya penasaran apakah gaya coding seperti ini merupakan paradigma tertentu Saya hampir tidak pernah melihat kode seperti ini di proyek nyata, kecuali pengecualian seperti “business card ray tracer” Source code untuk bahasa J buatan Whitney juga memiliki gaya yang sangat terkompresi serupa

    • Ya, ini adalah gaya coding khas Whitney Ia memakainya secara konsisten dalam interpreter bahasa array buatannya, dan terkenal karena bisa memuat seluruh implementasi hanya dalam beberapa halaman Ada juga tautan komentar meta yang mengumpulkan diskusi HN terkait
    • Menanggapi “saya belum pernah melihat kode seperti ini di dunia nyata”, ada yang menjawab, “berarti Anda beruntung” Ini bukan lagi C, melainkan semacam DSL internal baru yang dibangun di atas C C di sini hanyalah target kompilasi pertama
    • Ini mirip dengan bahasa keluarga APL seperti J dan K Mereka memakai simbol non-ASCII, dan dapat memuat sangat banyak informasi dalam satu halaman berkat kepadatan yang ekstrem Setelah terbiasa, ada juga keuntungan berupa berkurangnya lapisan abstraksi
    • Ada juga video terkait co-dfns yang dibuat dengan pendekatan serupa Memang bukan C, tetapi ditulis dengan gaya padat yang mirip
    • Ada yang bercanda menyebut ini “OCC (Obfuscated C Code)”
  • Jika melihat definisi makro berikut

    #define _(e...) ({e;})
    #define x(a,e...) _(s x=a;e)
    #define $(a,b) if(a)b;else
    #define i(n,e) {int $n=n;int i=0;for(;i