1 poin oleh GN⁺ 9 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • Selector dan deklarasi CSS secara struktural berkaitan dengan Datalog karena keduanya memilih himpunan elemen yang sudah ada lalu menerapkan properti pada hasil tersebut
  • CSS biasa tidak mendukung perhitungan rekursif yang memakai hasil seleksi kembali sebagai kondisi seleksi, sehingga propagasi status seperti tema dark yang menurun ke turunan lalu berhenti di batas light tidak bisa diekspresikan secara langsung
  • Dalam CSSLog yang hipotetis, penambahan class yang memengaruhi pencocokan selector diizinkan, sehingga status turunan seperti .effectively-dark bisa dipropagasikan secara rekursif dan dihitung berulang sampai tidak ada hasil baru lagi
  • Perhitungan seperti ini dijelaskan lewat fixpoint dan monotonicity dalam Datalog; evaluasi berulang hanya bisa selesai secara hingga jika fakta tidak dihapus dan hanya ditambahkan
  • Container queries di CSS nyata juga bisa membaca status leluhur, tetapi tidak bisa meng-query status rekursif yang diturunkan, jadi meski CSS mendekati Datalog di titik tertentu, ia tetap tidak melampaui batas mesin rendering browser

Korespondensi dasar antara CSS dan Datalog

  • CSS mengandaikan adanya objek yang sudah ada, dan dalam konteks ini objek tersebut adalah elemen HTML
    • Elemen seperti h1, a, div sudah ada di luar CSS, dan CSS tidak mendeklarasikan elemen-elemen itu dari nol
    • Sebagai contoh, disebutkan elemen yang memiliki atribut seperti class, id, dan data-custom-attribute
  • Selector CSS menunjuk ke himpunan dengan kondisi bersama, dan target bisa dipersempit lewat nama tag, id, class, atau nilai atribut
    • Selector seperti div, #child, .awesome, [data-custom-attribute="foo"] muncul sebagai contoh
    • Target juga bisa diekspresikan lewat relasi posisi dalam hierarki dokumen, dan irisan pun bisa dibentuk lewat penggabungan selector
  • Selector gabungan seperti div.awesome melakukan irisan himpunan, dengan memilih hanya elemen yang sekaligus div dan .awesome
    • Konsep irisan ini nantinya menjadi kunci untuk dipadankan dengan join dalam Datalog
  • Aturan CSS mengikat selector dan deklarasi untuk menerapkan nilai properti pada himpunan yang dipilih
    • Pada contoh div.awesome { color: red; font-size: 24px }, color dan font-size diatur untuk elemen-elemen tersebut
    • Di browser, hasilnya dirender sebagai teks merah berukuran besar

Batasan CSS dan masalah query rekursif

  • CSS biasa kuat untuk mengubah properti di luar bahasa itu sendiri, tetapi hasil perubahan itu tidak bisa langsung dipakai lagi sebagai kondisi seleksi
    • Kita bisa mengatur warna elemen, tetapi contoh seperti div[color=red] yang menjadikan warna itu sendiri sebagai syarat selector akan ditolak browser
    • Aturan yang kembali menerapkan color: blue pada elemen dengan color: red menjadi tidak jelas maknanya
  • Contoh dark mode dalam design system diajukan sebagai masalah yang membutuhkan propagasi status transitif
    • Ingin menerapkan outline fokus putih ke semua elemen interaktif di dalam kartu dengan data-theme="dark"
    • Namun jika di tengah ada data-theme="light", propagasi harus berhenti di bawah titik itu
  • Di CSS nyata, hanya sebagian yang bisa ditangani dengan menambahkan pengecualian
    • Aturan dasar bisa dibuat dengan [data-theme="dark"] :focus { outline-color: white; }
    • Dan batas light bisa dipulihkan dengan [data-theme="dark"] [data-theme="light"] :focus { outline-color: black; }
    • Tetapi pendekatan ini menuntut penambahan aturan terus-menerus saat nested semakin dalam
  • Masalah ini membutuhkan definisi relasional rekursif, tetapi CSS tidak bisa mengekspresikannya
    • Diperlukan definisi seperti “effectively-dark jika dirinya sendiri dark, atau memiliki leluhur effectively-dark tanpa ada leluhur effectively-light di antaranya”
    • Teks aslinya menyebut ini sebagai recursive relational definition, dan menegaskan bahwa CSS tidak bisa menuliskannya

Sintaks hipotetis CSSLog

  • CSSLog diposisikan sebagai versi hipotetis yang tetap mempertahankan selector dan pengaturan properti seperti CSS biasa, tetapi juga bisa mengubah properti yang memengaruhi pencocokan selector
    • Dalam contoh, muncul sintaks seperti class: +bar untuk menambahkan class
    • Juga diasumsikan bentuk seperti +<div class="baz"> untuk membuat elemen anak baru
    • Penghapusan elemen hanya disebut “mungkin tidak boleh”, tanpa penjelasan lebih lanjut
  • Setelah aturan div.foo dijalankan, elemen yang sama bisa ikut cocok dengan div.bar, sehingga hasil eksekusi aturan memengaruhi pencocokan berikutnya
    • Pada titik ini, perhitungan tidak lagi selesai dengan satu kali penerapan maju, melainkan membutuhkan iterasi
  • Jika contoh dark mode dipindahkan ke CSSLog, propagasi rekursif class turunan menjadi mungkin
    • Dimulai dengan [data-theme="dark"] { class: +effectively-dark; }
    • Lalu dipropagasikan ke anak lewat .effectively-dark > :not([data-theme="light"]) { class: +effectively-dark; }
    • Dan style akhir diterapkan dengan .effectively-dark :focus { outline-color: white; }
  • Aturan kedua digambarkan menyebar secara rekursif sampai batas light, lalu berhenti saat status yang diinginkan sudah tercapai
    • Teks asli menyatakan bahwa perilaku seperti ini tidak bisa dilakukan oleh CSS saat ini, dan di bagian akhir kembali membahas beberapa jalan memutar yang mirip

Struktur Datalog dan kemiripannya dengan CSS

  • Dalam Datalog, objek disebut atom, dan menjadi ada pada saat pertama kali disebut
    • Nama seperti alice, bob bisa dipakai langsung tanpa deklarasi terpisah
    • Ada kalimat yang membandingkannya dengan :symbols di Ruby
  • Himpunan dan relasi direpresentasikan sebagai relation dan tuple
    • parent(alice, bob) menjadi satu tuple di dalam relasi parent
    • parent dijelaskan sebagai himpunan pasangan yang berarti “objek pertama adalah orang tua dari objek kedua”
  • Variabel dipakai untuk pencocokan query dan pemilihan himpunan
    • parent(bob, X) berarti semua X yang Bob menjadi orang tuanya
    • Dalam contoh ini, X dievaluasi menjadi carol dan dave
    • Secara konvensi, variabel ditulis dengan huruf besar, sedangkan atom dan relation dengan huruf kecil
  • Mengulang nama variabel yang sama akan menghasilkan join
    • mother(X, Y) :- parent(X, Y), woman(X). membentuk relasi ibu dari irisan himpunan parent dan himpunan woman
    • Teks menjelaskannya sebagai irisan antara “semua orang tua” dan “semua perempuan”
  • :- pada aturan Datalog dibaca sebagai if, yaitu ketika semua syarat di body kanan terpenuhi maka fakta di head kiri ditambahkan sebagai benar
    • Koma di body dibaca sebagai and
    • ancestor(X, Y) :- parent(X, Y). berarti jika X adalah orang tua Y, maka X adalah leluhur Y
  • CSS dan Datalog dibandingkan sebagai struktur serupa yang hanya dibalik bentuknya
    • color(X, red) :- div(X), class(X, awesome). berarti “warna X adalah red jika X adalah div dan memiliki class awesome”
    • Ini dipadankan secara semantik dengan CSS div.awesome { color: red; }
    • Teks aslinya merangkum bahwa selector adalah body, dan declaration adalah head

Rekursi dan fakta turunan

  • Dalam Datalog, melakukan sesuatu berarti menurunkan fakta baru
    • Sistem bekerja dengan menambahkan tuple baru ke relasi berdasarkan fakta yang sudah ada
  • Contoh ancestor diajukan sebagai bentuk khas aturan rekursif
    • ancestor(X, Y) :- parent(X, Y). menjadikan relasi orang tua langsung sebagai leluhur
    • ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y). memperluas ke atas dengan mengikuti relasi leluhur dari orang tua
  • Aturan kedua memuat rekursi referensi diri karena ancestor muncul sekaligus di head dan body
    • Dengan aturan ini, relasi leluhur tak langsung seperti alice -> bob -> carol dan alice -> bob -> dave bisa diturunkan
  • Hasil eksekusi contoh memperlihatkan lima fakta berikut
    • ancestor(alice, bob)
    • ancestor(bob, carol)
    • ancestor(bob, dave)
    • ancestor(alice, carol)
    • ancestor(alice, dave)
  • SQL juga tidak bisa melakukan perhitungan seperti ini sebelum WITH RECURSIVE, dan fitur itu disebut lahir karena kebutuhan komputasi rekursif
    • Namun teks aslinya menambahkan bahwa sintaks rekursif SQL dan maknanya tidak selalu menyatu baik dengan bagian-bagian lain
  • Datalog terus menghitung sampai semua hasil yang diperlukan muncul, tanpa perlu for loop eksplisit
    • Bagian berikutnya mengaitkan alasannya dengan fixpoint

Fixpoint dan monotonicity

  • Cascade pada CSS biasa digambarkan sebagai satu kali penerapan maju
    • Browser membaca aturan, menghitung kecocokan selector, menerapkan deklarasi, lalu selesai
    • Tidak ada feedback loop
  • Dalam CSSLog dan Datalog nyata, hasil suatu aturan bisa kembali memenuhi kondisi aturan lain
    • Sebuah aturan mengubah properti, properti itu membuat aturan lain aktif lagi, dan pada gilirannya bisa memengaruhi aturan pertama juga
  • Mesin Datalog naif mengulang penerapan aturan sampai tidak ada fakta baru yang muncul lagi
    • Dimulai dari base fact yang dinyatakan
    • Body semua aturan dicocokkan dengan himpunan fakta saat ini
    • Jika cocok, fakta head ditambahkan
    • Jika ada fakta baru, proses diulang; jika tidak ada, evaluasi berhenti
  • Titik berhenti ini disebut fixpoint
    • Yaitu keadaan ketika penerapan semua aturan sekali lagi tidak menghasilkan apa pun yang baru
  • Contoh ancestor diringkas dalam tiga putaran
    • Putaran pertama menambahkan tiga relasi leluhur langsung dari fakta parent
    • Putaran kedua menambahkan dua relasi leluhur tak langsung milik alice
    • Putaran ketiga tidak menghasilkan fakta baru, sehingga fixpoint tercapai
  • Alasan ia bisa berhenti adalah monotonicity
    • Karena fakta tidak pernah dihapus dan hanya ditambahkan, himpunan fakta yang diketahui hanya terus membesar
    • Dengan fakta awal yang terbatas dan kemungkinan turunan yang terbatas, proses akan berhenti setelah pekerjaan yang juga terbatas
  • Sebaliknya, jika penghapusan fakta diizinkan, hasil belakangan bisa membatalkan hasil sebelumnya, dan sifat ini pun rusak
    • Teks aslinya menyebut keadaan itu sebagai Infinite Loop Land, lalu mengaitkannya dengan alasan CSSLog lebih baik tidak mengizinkan penghapusan elemen
  • Dalam sistem terdistribusi pun, monotonicity disebut terkait dengan kemampuan memperoleh konsistensi tanpa koordinasi mahal dalam catatan kaki

Mengapa ini penting

  • Perbandingan CSS dan Datalog menyingkap struktur yang sama di bidang yang berbeda
    • Keduanya sama-sama punya objek, meng-query himpunan objek itu, lalu menerapkan sesuatu atau membentuk fakta baru dari hasilnya
  • Datalog dan Prolog sudah muncul sejak 1970-an dalam basis data relasional dan riset AI masa itu, lalu terus diciptakan ulang dalam berbagai bentuk
  • Terkandung pengamatan bahwa jika kita membangun sistem yang memiliki objek, bisa mendeskripsikan himpunan, dan bisa melakukan operasi pada objek tersebut, sistem itu akan cenderung berkonvergensi ke titik yang mirip
  • Ranah basis data dan logic programming serta ranah pengembangan web frontend tidak terlalu sering saling terhubung
    • Teks menambahkan harapan bahwa jika keduanya lebih sering bertemu, mungkin akan lahir sesuatu yang baru

Container Queries dan batas CSS nyata

  • Diskusi ini juga bersentuhan dengan fitur CSS nyata yaitu Container Queries
    • Kita bisa menerapkan style ke elemen saat ini berdasarkan style milik induk atau leluhur
    • Contoh yang diberikan adalah @container style(--theme: dark) { .card { background: royalblue; color: white; } }
  • Namun masalah transitive dark mode membutuhkan komputasi yang lebih kuat daripada sekadar melihat leluhur
    • Setiap elemen harus tahu apakah dirinya effectively dark
    • Status itu harus menyebar secara transitif ke keturunannya
    • Dan propagasi harus berhenti di batas data-theme="light"
  • Container queries tidak bisa membaca status turunan
    • Ia bisa membaca nilai custom property pada leluhur, tetapi tidak bisa meng-query status seperti effectively-dark yang sudah dihitung oleh aturan lain
    • Ia hanya bisa membaca status yang memang sudah ada di DOM, bukan hasil komputasi rekursif
  • Karena itu, query seperti “terapkan jika ada leluhur mana pun yang dark secara transitif, dan tidak ada leluhur light yang lebih dekat” memerlukan rekursi sehingga tidak bisa diimplementasikan
    • Teks aslinya menyatakan dengan tegas bahwa container queries tidak memiliki rekursi
  • Artikel tahun 2015 membahas latar belakang mengapa element queries terus gagal karena alasan yang serupa
    • Jika query diizinkan menanyakan lagi properti yang ia sendiri tetapkan, maka loop bahkan infinite loop bisa muncul
  • CSS Working Group diringkas sebagai pihak yang selama ini menyelesaikan masalah seperti ini lewat pembatasan arah aliran informasi
    • Keturunan boleh meng-query informasi leluhur, tetapi arah sebaliknya tidak diizinkan
    • Dengan begitu, keterhinggaan bisa dipertahankan tanpa semantik fixpoint
    • Informasi hanya merambat ke bawah pohon, dan strukturnya dijaga agar tidak memasukkan base fact baru
  • Teks aslinya menggambarkan alur ini sebagai CSS yang mendekati mesin Datalog tetapi sengaja tidak sampai ke sana
    • CSSLog berada di sisi yang mengizinkan siklus dan mengevaluasi sampai fixpoint
    • Sedangkan CSS nyata berhenti pada batas bahwa browser rendering engine bukanlah incremental relational database engine

Kemungkinan arah lain

  • Alih-alih memasukkan semantik Datalog ke browser, ada juga kemungkinan meletakkan sintaks CSS di atas Datalog
    • Sintaks Datalog seperti :-, titik, konvensi huruf besar-kecil, dan ketiadaan assignment bisa menjadi hambatan masuk bagi pengguna bahasa modern
  • CSS sudah memiliki sintaks yang secara langsung menangani struktur pohon
    • Ada combinator keturunan, anak, dan saudara sehingga relasi parent-child bisa diekspresikan secara alami
    • Dalam Datalog biasa, struktur seperti ini sering harus dienkodekan ke bentuk relasional dengan cara yang agak merepotkan
  • Ditekankan bahwa banyak data nyata memang berbentuk pohon
    • JSON
    • AST
    • filesystem
    • bagan organisasi
    • XML disebut sebagai contoh
  • Jika ada alat yang menggabungkan rekursi fixpoint, sintaks bergaya CSS, dan relasi parent-child implisit, maka query pohon rekursif bisa ditulis dengan notasi yang lebih familier
  • Menurut teks aslinya, sepertinya belum ada yang benar-benar membuat alat seperti itu
    • Tulisan ditutup dengan kalimat bahwa seseorang mungkin layak membuat sesuatu seperti “CSSLog” dengan nama yang lebih baik

Catatan kaki

  • Ada catatan kaki tentang penyederhanaan elemen HTML
    • Penulis mengantisipasi keberatan detail bahwa objek yang ditangani CSS tidak selalu seluruhnya elemen HTML, tetapi demi menyederhanakan penjelasan, teks utama memerlakukannya sebagai elemen HTML
  • Naive evaluation tidak efisien karena terus menghitung ulang fakta yang sudah diketahui
    • Sebagai perbaikan standar, disebut semi-naive evaluation
    • Intinya adalah pada setiap tahap hanya melihat fakta yang baru diturunkan
  • Ditambahkan pula bahwa infinite loop sendiri bukan hal asing dalam bahasa yang Turing-complete
    • Di JavaScript pun kita bisa menulis while true {}
    • Tetapi konteksnya adalah kita tentu tidak ingin sistem rendering browser berhenti selamanya hanya karena logika situs web yang membingungkan
  • Jalan memutar CSS lewat pewarisan custom property juga dibahas di catatan kaki
    • [data-theme="dark"] { --effective-theme: dark; }
    • [data-theme="light"] { --effective-theme: light; }
    • @container style(--effective-theme: dark) { :focus { outline-color: white; } }
    • Pendekatan ini umumnya bekerja untuk kasus khusus ini, tetapi pewarisan tidak sama dengan transitive closure yang sesungguhnya
    • Pada masalah yang lebih rumit, yang membutuhkan transitive closure di sepanjang rantai properti selain parent-child, pendekatan ini akan gagal

1 komentar

 
GN⁺ 9 jam lalu
Komentar Hacker News
  • Selector CSS jauh lebih mudah ditulis daripada XPath
    Baru-baru ini bahkan ada presentasi tentang API DOM baru di PHP yang memudahkan penanganan HTML dan selector CSS secara native. Dulu CSS harus dikonversi ke XPath
    [1] https://speakerdeck.com/keyvan/parsing-html-with-php-8-dot-4...
    Karena berkembang dengan fokus pada styling browser, agak disayangkan tidak ada fitur seperti pemilihan berdasarkan isi teks seperti di XPath
    Setahu saya dulu pernah ada usulan, tetapi tidak masuk ke spesifikasi karena bisa menimbulkan masalah performa dalam konteks rendering browser

    • LLM juga cukup mahir menangani selector CSS
      Saat membuat agen pengedit dokumen, saya menampilkan dokumen sebagai HTML lalu membiarkan LLM hanya menentukan CSS selector untuk menarik fragmen yang dibutuhkan ke dalam konteks, dan hasilnya bekerja nyaris seperti sihir
    • Di sisi klien, querySelector/querySelectorAll sudah digunakan sangat luas, jadi menyenangkan melihat itu kini masuk juga ke DOM baru di PHP
      Orang-orang bisa memakainya dengan cara yang sudah mereka kenal
  • Akan bagus kalau ada nama terpisah untuk membedakan sintaks CSS dan keseluruhan sistem seperti aturan, fungsi, dan unit yang didefinisikan CSSWG
    Ada cukup banyak potensi di sini, tetapi untuk membahas atau meneliti kasus penggunaan lain, sepertinya pada akhirnya kita harus mengaduk-aduk kode di GitHub yang memakai parser CSS untuk melihat hal-hal aneh apa yang dibuat orang
    Saya juga sedang mengutak-atik sesuatu yang mirip mesin template aneh, yang mencampurkan bahasa markup ringan berbasis node, selector CSS untuk menyatakan apa yang masuk ke template, dan sintaks mirip CSS untuk mengendalikan bagaimana potongan-potongan ini digabungkan

    • Menurut saya, di standar pemisahannya sudah cukup jelas
      https://www.w3.org/TR/selectors-3/
      Spesifikasi DOM juga merujuk ke sini
      https://dom.spec.whatwg.org/#selectors
      Jadi sebutan umum CSS selector memang sudah tepat, dan boleh juga hanya disebut selector
      Nama DOM selector mungkin terdengar lebih rapi, tetapi jika memikirkan selector yang dipakai di CSS statis atau di engine DOM lain di luar engine JS, seperti XML parser atau PHP DOM API, itu justru bisa lebih membingungkan
      Selain itu ada juga selector khusus seperti :hover atau ::target-text yang terikat langsung dengan rendering dan navigasi browser
      Namun, untuk subset sintaks query minimum yang kurang terikat ke browser atau CSS, akan berguna jika ada nama tersendiri
  • Ini mengingatkan saya pada https://github.com/braposo/graphql-css yang pernah saya lihat di konferensi dulu
    Itu proyek bercanda, tetapi saya suka karena menunjukkan dengan baik bahwa memindahkan pola ke konteks lain dan memakainya kembali bisa memungkinkan hal-hal yang tak terduga

    • Ini menarik
      Saya memang sedang mencoba membawa pola dari konteks berbeda seperti itu
      Meski kebanyakan mungkin tidak akan ke mana-mana, dari sudut pandang hacker ini cukup menarik
  • pyastgrep, seperti terlihat di https://pyastgrep.readthedocs.io/en/latest/, bisa memakai selector CSS untuk meng-query sintaks Python
    Default-nya adalah XPath, dan misalnya bisa seperti pyastgrep --css 'Call > func > Name#main'

    • Ini benar-benar bagus
      Hampir persis mengarah ke hal yang ingin saya tunjuk
  • Saya kurang paham skenario apa yang diselesaikan ini
    Saat ini pun parent bisa diubah secara kondisional berdasarkan child. Misalnya pre punya padding default 16px, dan jika child langsungnya adalah code, itu bisa dijadikan 0 dengan &:has(> code)

    • Sebenarnya ini pada awalnya lebih berangkat dari dua ide berbeda yang tampak mirip, lalu saya mendorong keterkaitan itu ke beberapa arah
      Jadi kesimpulannya lebih dekat ke "memakai sintaks mirip CSS di atas sistem mirip Datalog mungkin bisa membuat pekerjaan menangani data berbentuk tree terasa lebih akrab bagi lebih banyak engineer" daripada "memperbaiki keterbatasan CSS modern"
    • Yang dimaksud di sini bukan menyelesaikannya dengan satu kali perhitungan style, tetapi sintaks untuk memodifikasi data dasar itu sendiri dari target yang cocok dengan selector
      Artinya, pembicaraannya adalah tentang menambahkan elemen child atau atribut baru ke DOM
  • LLM saat ini cenderung tidak begitu bagus menangani CSS, jadi malah membuat saya ingin mencoba ini untuk melihat apakah LLM bisa bernalar lebih sederhana dengannya

  • Saya belum terlalu melihat kegunaan praktisnya, tapi tetap keren

  • Hmm... bukankah ini cuma JQ?

  • Saya cukup suka CSS sampai titik tertentu, tetapi saya tidak suka complexity creep yang makin parah
    Saya paham logika bahwa bahasa pemrograman menjadi lebih kuat daripada bahasa non-pemrograman, tetapi alih-alih terus memperbesar kerumitan HTML, CSS, dan JavaScript, rasanya lebih baik muncul sesuatu yang menggantikan semuanya
    Saya juga hampir tidak pernah memakai elemen baru HTML5 karena sebagian besar saya tidak paham kenapa itu diperlukan. Akhirnya saya menganggap banyak container hanyalah div dengan ID unik, dan saya bahkan berharap ada semacam alias untuk ID itu demi navigasi href internal
    Hal seperti [data-theme="dark"] [data-theme="light"] :focus { outline-color: black; } juga terasa butuh terlalu lama untuk dipahami di kepala, jadi tidak lagi terasa elegan dan sederhana
    Sebaliknya, h2 { color: red; } masih tetap sederhana
    Ekspresi seperti ancestor(X, Y) :- parent(X, Y). saja sudah membuat saya malas berpikir. :- itu sebenarnya apa, kelihatan seperti wajah tersenyum
    Saya berhenti membaca di @container style(--theme: dark) { .card { background: royalblue; color: white; } }
    Aneh rasanya melihat standar yang dulu bekerja baik makin lama justru seperti rusak

    • Maksud saya lebih dekat ke bukan menambahkan lebih banyak sintaks dan makna ke CSS, melainkan mencuri ide dari CSS lalu memanfaatkan kemiripannya dengan bahasa query logika/relasional untuk membuat sesuatu yang baru
      Misalnya [data-theme="dark"] [data-theme="light"] :focus { outline-color: black; } jika diurai ke pseudocode bergaya bahasa Inggris kurang lebih berarti, jika ada X dengan data-theme="dark" dan child Y dari X punya data-theme="light" serta sedang fokus, maka set outline-color Y menjadi black
      Jadi ini bisa ditulis dalam gaya Datalog sebagai outline-color(Y, black) if data-theme(X, "dark") and parent(X, Y) and data-theme(Y, "light") and focused(Y)
      Artinya :- diganti menjadi if, dan koma diganti menjadi and
      Lebih jauh lagi, ini bisa ditulis sebagai Y.outline_color := black if X.data-theme == dark and Y.parent == X and Y.data-theme == dark and Y.focused sehingga attr(X, val) tampak seperti syntactic sugar mirip UFCS semacam X.attr == val
      Jika ingin terlihat lebih seperti keluarga ALGOL, bisa juga menjadi forall Y { Y.outline_color := black if Y.data_theme == "dark" and Y.focused and Y.parent.data_theme == "light" }
      Di sini Y diperkenalkan secara eksplisit dan satu join dibuat implisit sehingga tampak lebih seperti pemrograman umum, tetapi pada praktiknya mesin Datalog yang akan menjalankan loop seperti ini secara efisien setiap kali dependensinya berubah`