4 poin oleh GN⁺ 2024-04-25 | 1 komentar | Bagikan ke WhatsApp
  • Piet adalah bahasa pemrograman esoterik yang dibuat agar kode tampak seperti lukisan abstrak, dan dinamai dari Piet Mondrian, pelopor seni abstrak geometris
  • Program berupa grafik yang dibuat dari 20 warna yang dikenali, dan runner berpindah di antara blok warna sambil menafsirkan perubahan warna sebagai perintah
  • Semua data hanya berupa bilangan bulat dan disimpan dalam stack; ukuran blok warna adalah nilai, tetapi tidak otomatis masuk ke stack tanpa perintah push
  • Kontrol alur ditentukan oleh Direction Pointer dan Codel Chooser, serta aturan blok hitam, tepi, dan blok putih; sebagian perilaku dapat berbeda antar-implementasi
  • Ada ekosistem contoh dan tool eksternal, tetapi tidak ada interpreter resmi yang otoritatif; penanganan error dan interpretasi warna non-standar juga tetap bergantung pada implementasi

Ide dasar Piet

  • Piet adalah bahasa pemrograman yang kode programnya tampak seperti seni abstrak
  • Namanya diambil dari Piet Mondrian, pelopor seni abstrak geometris
  • Awalnya ingin memakai nama Mondrian, tetapi karena sudah ada bahasa skrip dengan nama yang sama, digunakanlah nama Piet
  • Setelah spesifikasi ditulis, komunitas kecil terbentuk dan terus membuat program, interpreter, IDE, dan compiler
  • Tidak ada interpreter resmi yang otoritatif, dan implementasi yang tersedia dapat menafsirkan spesifikasi sedikit berbeda
  • Beberapa penjelasan spesifikasi telah ditambahkan, tetapi sebagian implementasi lama mungkin tidak mengikutinya

Warna dan unit kode

  • Piet menggunakan total 20 warna
    • 18 warna termasuk dalam siklus hue dan siklus kecerahan
    • Putih dan hitam tidak termasuk dalam kedua siklus tersebut
  • Siklus hue berurutan red -> yellow -> green -> cyan -> blue -> magenta -> red
  • Siklus kecerahan berurutan light -> normal -> dark -> light
    • light juga dianggap satu tingkat lebih gelap daripada dark, dan sebaliknya juga berlaku
  • Warna non-standar seperti oranye atau cokelat dapat digunakan, tetapi efeknya bergantung pada implementasi
    • Dalam kasus paling sederhana, warna non-standar diperlakukan seperti putih
    • Kemungkinan lain, warna tersebut dapat diperlakukan seperti hitam

Codel dan blok warna

  • Kode Piet adalah grafik yang tersusun dari warna-warna yang dapat dikenali
  • Karena setiap piksel kode memiliki makna secara bahasa, pada program yang diperbesar agar mudah dilihat, satu piksel dalam kode disebut codel
  • Unit eksekusi dasarnya adalah blok warna
    • Blok warna adalah area tempat codel dengan warna yang sama tersambung secara atas-bawah-kiri-kanan
    • Blok yang hanya bersentuhan secara diagonal tidak dianggap tersambung
    • Blok warna dapat berbentuk apa pun, dan dapat memiliki lubang berwarna lain di dalamnya
    • Lubang internal bukan bagian dari blok tersebut

Stack dan representasi nilai

  • Piet menyimpan semua nilai data dalam stack
  • Nilai data hanya berupa bilangan bulat
    • Tergantung perintah, nilai dapat dimasukkan atau dikeluarkan sebagai nilai karakter Unicode
  • Secara konsep, stack memiliki kedalaman tak terbatas, tetapi implementasi dapat menetapkan ukuran stack maksimum yang terbatas
  • Jika overflow terjadi pada stack terbatas, itu adalah error runtime, dan penanganannya bergantung pada implementasi
  • Blok warna selain hitam dan putih merepresentasikan nilai bilangan bulat yang sama dengan jumlah codel dalam blok tersebut
    • Bilangan bulat yang tidak positif tidak dapat direpresentasikan secara langsung
    • Namun dapat dibuat melalui operator
    • Nilai blok warna tidak otomatis di-push ke stack; diperlukan perintah push eksplisit
  • Ukuran bilangan bulat juga secara konsep tak terbatas, tetapi implementasi dapat menetapkan ukuran bilangan bulat maksimum yang terbatas
    • Overflow bilangan bulat adalah error runtime, dan penanganannya bergantung pada implementasi

Alur eksekusi

  • Interpreter memulai eksekusi dari blok warna yang mencakup codel kiri atas program
  • Selama eksekusi, dua status dipertahankan
    • Direction Pointer(DP): awalnya menunjuk ke kanan, dan menunjuk salah satu dari kanan, kiri, bawah, atau atas
    • Codel Chooser(CC): awalnya menunjuk ke kiri, dan menunjuk salah satu dari kiri atau kanan
  • Target perpindahan berikutnya ditentukan oleh batas blok warna saat ini serta kombinasi DP dan CC
    • Cari sisi terjauh dari blok warna saat ini pada arah DP
    • Dari sisi itu, pilih codel terjauh pada arah CC relatif terhadap arah gerak DP
    • Dari codel tersebut, pindah ke blok warna yang berisi codel tepat berikutnya pada arah DP
  • Proses ini diulang hingga kondisi terminasi tercapai, lalu program selesai

Blok hitam, tepi, dan blok putih

  • Blok warna hitam dan tepi program berperan sebagai penghalang yang menghentikan alur eksekusi
  • Jika interpreter mencoba berpindah ke blok hitam atau keluar melewati tepi, ia berhenti dan mengganti CC
  • Jika percobaan kedua juga gagal, DP diputar satu langkah searah jarum jam
  • Jika setelah bergantian mengubah CC dan DP sebanyak total 8 percobaan masih tidak dapat keluar dari blok warna saat ini, program berakhir
  • Perpindahan blok putih

    • Blok warna putih adalah area bebas yang dilalui interpreter tanpa hambatan
    • Saat berpindah dari blok warna ke area putih, interpreter bergerak lurus pada arah DP hingga mencapai blok warna yang bukan putih
    • Saat berpindah melewati blok putih ke warna baru, tidak ada perintah yang dijalankan
    • Karena sifat ini, blok putih berguna untuk membuat loop karena dapat mengubah warna saat ini tanpa menjalankan perintah
    • Perpindahan blok putih tidak menggunakan prosedur pemilihan pintu keluar dari blok warna non-putih, melainkan hanya melakukan gerak lurus
  • Saat terhalang di blok putih

    • Jika saat bergerak lurus melewati blok putih interpreter bertemu blok hitam atau tepi, hal itu dianggap sebagai terkena batasan
    • Dalam kasus ini CC diganti, tetapi karena posisi yang ingin dituju tidak berubah, DP segera diputar satu langkah searah jarum jam
    • Setelah itu, dari codel putih saat ini, interpreter kembali bergerak lurus pada arah DP baru
    • Setiap kali menemui batasan di dalam blok putih, pergantian CC dan rotasi DP diulangi
    • Jika masuk ke blok warna, eksekusi berlanjut; jika mulai menelusuri kembali jalur di dalam blok putih, berarti tidak ada jalan keluar dan eksekusi berakhir

Sistem perintah

  • Perintah Piet ditentukan oleh perubahan warna saat berpindah dari satu blok warna ke blok warna berikutnya
  • Perintah ditentukan oleh berapa langkah perpindahan dalam siklus hue dan berapa langkah perpindahan dalam siklus kecerahan
  • Pada transisi warna yang dilakukan melalui blok putih, tidak ada perintah yang dijalankan
  • Perintah stack dan aritmetika

    • push: memasukkan nilai blok warna yang baru saja ditinggalkan ke stack
    • pop: mengambil dan membuang nilai teratas stack
    • add: menjumlahkan dua nilai teratas dan memasukkan hasilnya kembali ke stack
    • subtract: memasukkan ke stack hasil pengurangan nilai kedua oleh nilai teratas
    • multiply: mengalikan dua nilai teratas
    • divide: melakukan pembagian bilangan bulat pada nilai kedua dengan nilai teratas
    • Pembagian dengan 0 adalah error yang bergantung pada implementasi; cara yang disarankan adalah mengabaikan perintah
    • mod: memasukkan ke stack sisa bagi dari nilai kedua dibagi nilai teratas
    • Hasilnya memiliki tanda yang sama dengan pembagi, yaitu nilai teratas stack
    • Jika nilai teratas 0, itu adalah error pembagian dengan 0; cara yang disarankan adalah mengabaikan perintah
    • mod untuk dividen negatif sama dengan floored division yang dijelaskan dalam modulus operation di Wikipedia
  • Perintah perbandingan, pointer, dan I/O

    • not: mengubah nilai teratas stack menjadi 0 jika bukan 0, atau menjadi 1 jika 0
    • greater: memasukkan 1 ke stack jika nilai kedua lebih besar daripada nilai teratas, jika tidak 0
    • pointer: mengambil nilai teratas stack dan memutar DP searah jarum jam sebanyak nilai tersebut
    • Jika negatif, diputar berlawanan arah jarum jam
    • switch: mengambil nilai teratas stack dan mengganti CC sebanyak nilai tersebut
    • Jika negatif, diganti sebanyak nilai absolutnya
    • duplicate: memasukkan salinan nilai teratas stack ke stack
    • roll: mengambil dua nilai teratas dan memutar sebagian stack yang tersisa sesuai kedalaman dan jumlah yang ditentukan
    • Jika kedalaman negatif, itu adalah error dan perintah diabaikan
    • roll yang melebihi kedalaman stack maksimum yang bergantung pada implementasi adalah error yang bergantung pada implementasi, dan disarankan agar perintah diabaikan
    • in: membaca angka atau karakter dari STDIN dan memasukkannya ke stack
    • Jika tidak ada input, atau pada input bilangan bulat tidak mendapatkan bilangan bulat, itu adalah error dan perintah diabaikan
    • out: mengeluarkan nilai teratas stack ke STDOUT sebagai angka atau karakter
    • Operasi yang tidak dapat dilakukan karena nilai stack tidak mencukupi akan diabaikan dan eksekusi lanjut ke perintah berikutnya

Contoh dan tool

1 komentar

 
GN⁺ 2024-04-25
Komentar Hacker News
  • Program terakhir di halaman contoh benar-benar mengejutkan: katanya seseorang bernama Piet melihat sebuah karya seni yang mengingatkan pada bahasa Piet lalu mencoba menjalankannya
    Program itu berjalan, dan mungkin ini kasus pertama dalam sejarah ketika seorang seniman grafis secara kebetulan menggambar program komputer yang berfungsi
    https://www.dangermouse.net/esoteric/piet/samples.html
    https://gitlab.fabcity.hamburg/hofalab/piet-get-together

    • Jika syarat “berfungsi” dibuat cukup longgar, pernah ditunjukkan bahwa sebagian besar cipratan cat pada dasarnya sudah merupakan program Perl yang valid
      https://www.mcmillen.dev/sigbovik/
    • Piet J. sedang melihat karya seni di sebuah galeri kecil dan merasa karya itu mirip program Piet, sementara sang seniman mengatakan ia sama sekali tidak tahu bahasa tersebut
      Piet memotret karya itu, mengonversinya menjadi file gambar yang dirapikan dengan warna-warna yang mendekati palet Piet, lalu menjalankannya; ternyata benar-benar berjalan, dan kodenya adalah loop tak hingga yang membaca karakter ASCII lalu mencetak nilai angka ASCII-nya
      Ini benar-benar sulit dipercaya
    • Contoh yang menghitung π juga bagus
      Penjelasan “tentu saja, jika memakai program yang lebih besar, Anda bisa mendapatkan nilai yang lebih akurat” terasa seperti jenis lelucon yang baru pertama kali saya lihat
    • Sayangnya, itu bergantung pada perbedaan antara npiet dan spesifikasi Piet saat ini
      Menurut spesifikasi, interpreter harus mulai meluncur dari codel putih saat ini ke arah DP yang baru, lalu terus bergerak sampai masuk ke blok warna atau menemui batasan lain
      Namun interpreter npiet mengintip ke ruang kosong lalu memutar kembali ke posisi codel berwarna terakhir. Suatu hari saya ingin memasukkan perilaku itu sebagai opsi di lexer compiler Piet saya, tetapi belum sempat mengerjakannya
      Jika mengikuti spesifikasi, program itu menjadi loop sederhana yang tidak pernah berhenti, karena sudut ekstrem hampir semua blok bersebelahan dengan warna putih. Menulis program Piet yang kompleks untuk berbagai interpreter dan compiler cukup sulit, dan semuanya punya perbedaan interpretasi halus yang tidak terdokumentasi
      Saya rasa output backend Piet saya umumnya tidak terlalu bergantung pada interpreter, tetapi yang pernah saya telusuri detailnya hanya sekitar tiga atau empat interpreter lain
      https://github.com/boothby/repiet/
    • Saya penasaran seberapa besar kemungkinan gambar sederhana seperti ini, yaitu yang hanya terdiri dari beberapa blok persegi panjang besar, menjadi program yang valid
      Kalau melihat sekilas dokumentasinya, karena ada ketentuan bahwa “operasi yang tidak bisa dilakukan, seperti operasi yang tidak dapat mengambil nilai karena stack kekurangan nilai, cukup diabaikan dan eksekusi dilanjutkan ke perintah berikutnya”, rasanya semua gambar seperti ini mungkin bisa berjalan tanpa error
      Namun berapa banyak dari gambar acak semacam itu yang benar-benar melakukan sesuatu yang “bermakna” adalah persoalan lain
  • Piet memang eksperimen penting di antara bahasa pemrograman esoterik, tetapi menurut saya ia belum mencapai tujuan membuat program terlihat seperti lukisan Mondrian, kecuali developernya benar-benar sengaja melakukannya
    Akan lebih baik jika struktur bahasanya sendiri dirancang agar apa pun yang “ditulis” akan terlihat seperti lukisan Mondrian

    • Memang begitu, tetapi Mondrian pada dasarnya terutama memakai warna primer, jadi sepertinya akan cukup terbatas
  • Pertanyaan seperti ini selalu muncul di benak: seperti apa bentuk algoritma?
    Bisakah kita membuat sesuatu di dunia nyata yang mirip dengan yang ada dalam novel Herman Hesse, The Glass Bead Game? Judul aslinya adalah Magister Ludi
    Sebagai orang yang berorientasi visual, aku ingin percaya itu mungkin, dan memang pernah mencoba memakai alat semacam itu
    https://community.carbide3d.com/uploads/default/original/3X/5/b/5b0872a5666fec9b7bb6fd623c431de03263372d.jpeg
    Namun tanpa jawaban yang jelas atas pertanyaan di atas, alat-alat seperti ini selalu berisiko berakhir seperti berikut
    https://blueprintsfromhell.tumblr.com/
    https://scriptsofanotherdimension.tumblr.com/
    Menyeimbangkan daya ekspresi visual dan modularitas juga sulit, dan jika modularitas terlalu dipaksakan, kita terlalu mudah kembali ke dinding teks yang ingin dihindari

    • Kalau menulis Piet dengan tangan, ada keseruan tersendiri dalam mengeksplorasi “seperti apa bentuk algoritma”
      Sergei Lewis dan aku masing-masing membuat alat untuk menghasilkan kode Piet. Assembler milik Sergei menghasilkan kode yang jauh lebih enak dilihat daripada backend Piet milikku
      Yang benar-benar terlihat dari output compiler-ku hanyalah bahwa aku memakai trampoline dengan sangat malas
      http://www.toothycat.net/wiki/wiki.pl?MoonShadow/Piet
      https://github.com/boothby/repiet/
      https://en.wikipedia.org/wiki/Trampoline_(computing)
    • Aku percaya algoritma apa pun, bahkan konsep mental apa pun, punya hubungan 1:1 dengan representasi visual
      Ini gagasan yang kudapat saat membaca buku Steven Pinker: kata-kata abstrak bisa dipecah menjadi kata-kata yang lebih sederhana dan pada akhirnya menjelaskan suatu relasi spasial. Misalnya, “rekindle” bisa dilihat sebagai “membawa dua hal kembali bersama”
      Dengan cara serupa, for loop juga merupakan konsep mental “satu hal melewati banyak hal lain”, dan itu punya representasi visual seperti “100” -> “010” -> “001”
      Kalau begitu, aku penasaran apakah bisa dibuat bahasa yang mendefinisikan komponen-komponen seperti ini sebagai transformasi visual murni
    • Untuk program sederhana, kita juga bisa membayangkan mengimplementasikan mesin Turing dengan simbol berupa warna
  • Hal seperti ini cocok muncul di thriller kriminal: membuat tokoh utama atau para penyidik buntu, sampai seseorang sadar bahwa itu adalah kode
    Padahal kupikir cuma kode QR yang berguna

  • Seseorang membuat quine dengan Piet: http://mamememo.blogspot.com/2009/10/piet-quine.html?m=1
    Gambar di tulisan itu sudah rusak, tetapi salinannya ada di sini: https://codegolf.stackexchange.com/a/23255/103045

  • Momen ketika menemukan Piet adalah momen istimewa yang bercampur rasa takjub, bingung, dan kagum
    Dalam kasusku, itu terekam dalam percakapan ini di podcast ilmu komputer “The CS Primer Show” bersama temanku Oz: https://show.csprimer.com/episodes/e2-dont-let-a-gpt-have-all-the-fun

  • Di kampus ada kelas kecil tentang bahasa pemrograman esoterik
    Setiap orang harus memilih salah satu bahasa seperti Brainfuck atau Piet untuk dicoba-coba, dan aku memilih Piet serta cukup menikmatinya
    Sejujurnya aplikasi contoh kecil yang kubuat tidak terlalu bagus secara estetika, dan sepertinya untuk membuat karya seni dengan Piet, kita harus menjadi pakar Piet

  • Halaman contohnya bagus sekali
    Kita bisa melihat kanvasnya berevolusi menjadi semakin rumit dan enak dilihat
    https://www.dangermouse.net/esoteric/piet/samples.html

  • “light dianggap satu tingkat lebih gelap daripada dark”, cukup mendalam juga

  • Akan keren kalau bisa membuat autoencoder yang belajar menerima kode Python atau bahasa lain yang tidak terlalu esoterik lalu mengeluarkannya sebagai Piet
    Dengan begitu, mungkin juga bisa menghasilkan algoritma acak seperti Stable Diffusion