1 คะแนน โดย GN⁺ 24 일 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • โครงสร้างของ CSS ที่ใช้ selector และกฎ เพื่อเลือกชุดเป้าหมายและนำคุณสมบัติไปใช้ มีความคล้ายคลึงในเชิงรูปแบบกับ Datalog ที่ทำงานด้วยเซตและกฎ
  • การผสาน selector อย่าง div.awesome สร้าง จุดตัด และใน Datalog ก็เกิด join ที่คล้ายกันผ่านการใช้ตัวแปรเดิมซ้ำ
  • CSS ปัจจุบันไม่สามารถนำผลลัพธ์ของ computed style กลับมาใช้เป็นเงื่อนไขการเลือกได้ จึงยากที่จะเขียน การสืบค้นแบบส่งผ่านเชิงเวียนเกิด หรือการแพร่กระจายซ้ำของสถานะที่ได้มาโดยตรง
  • Datalog ใช้ กฎแบบเวียนเกิด และ การประเมินแบบจุดตรึง เพื่อขยายความสัมพันธ์ไปเรื่อย ๆ จนไม่มีข้อเท็จจริงใหม่เกิดขึ้น และด้วยคุณสมบัติความเป็นโมโนโทนิกจึงสามารถจบการคำนวณได้ภายในขอบเขตที่มีจำกัด
  • CSS จริงมีฟีเจอร์อย่าง Container Queries ที่อ่านข้อมูลจากบรรพบุรุษได้ แต่เลือกแนวทางที่ป้องกัน feedback loop และวงจร และยังคงเปิดช่องให้ไวยากรณ์แบบ CSS ไปประยุกต์กับภาษาสืบค้นแบบเวียนเกิดได้

โครงสร้างที่คล้ายกันของ CSS และ Datalog

  • CSS มีโครงสร้างแบบ เลือกชุดเป้าหมาย และ ใช้กฎกับเป้าหมายที่ถูกเลือก
    • "Things" เช่นองค์ประกอบ HTML มีอยู่ก่อน แล้ว selector จะชี้ไปยังเซตที่มีคุณสมบัติร่วมกัน
    • สามารถอธิบายเซตด้วย selector อย่าง div, #child, .awesome, [data-custom-attribute="foo"]
    • สามารถรวม selector แบบ div.awesome เพื่อสร้าง จุดตัด ได้
  • กฎของ CSS ผูก selector เข้ากับ declaration เพื่อกำหนดคุณสมบัติอย่าง color หรือ font-size ให้กับองค์ประกอบที่เลือก
    • แต่คุณสมบัติเหล่านี้ส่วนใหญ่เป็นการเปลี่ยน สถานะภายนอกภาษา และไม่สามารถนำผลลัพธ์นั้นกลับมาเป็นเงื่อนไขของ selector ได้
    • รูปแบบอย่าง div[color=red] ที่สืบค้นผลลัพธ์ของ style ย้อนกลับ เบราว์เซอร์จะไม่ยอมรับ
  • Datalog ก็ทำงานในลักษณะคล้ายกันด้วย ชุดข้อเท็จจริง และ การอนุมานตามกฎ
    • อะตอมและความสัมพันธ์อย่าง parent(alice, bob) เป็นหน่วยพื้นฐาน
    • ใช้ตัวแปร X, Y เพื่อเลือกชุดรายการที่ตรงเงื่อนไข
    • เมื่อนำตัวแปรเดียวกันมาใช้ซ้ำเพื่อเชื่อมเงื่อนไข ก็จะเกิด join ที่คล้ายกับการรวม selector ของ CSS
  • โครงสร้าง head(X, Y) :- body1(X, Z), body2(Z, Y) มีรูปแบบคล้ายกฎของ CSS เพียงแต่ทิศทางกลับกัน
    • selector ของ CSS ใกล้เคียงกับ body ของ Datalog ส่วน declaration ใกล้เคียงกับ head
    • div.awesome { color: red; } จับคู่ได้กับ color(X, red) :- div(X), class(X, awesome).

การสืบค้นแบบเวียนเกิดที่ CSS ทำไม่ได้

  • เงื่อนไขที่ต้องการให้ทุกองค์ประกอบที่โฟกัสอยู่ภายใต้ data-theme="dark" ได้รับสไตล์แบบกลับสี แต่หยุดเมื่อเจอ data-theme="light" ระหว่างทาง จำเป็นต้องใช้ การสืบค้นแบบส่งผ่าน
    • ใน CSS จริงสามารถจัดการได้บางส่วนด้วยกฎอย่าง [data-theme="dark"] :focus และ [data-theme="dark"] [data-theme="light"] :focus
    • เมื่อระดับการซ้อนเพิ่มขึ้น ก็ต้องเพิ่มกฎต่อไปเรื่อย ๆ และยากที่จะอธิบายความสัมพันธ์แบบเวียนเกิดโดยตรง
  • เงื่อนไขที่ต้องการจริง ๆ คือการตัดสินแบบเวียนเกิดว่าองค์ประกอบนั้นเป็น effectively-dark หรือไม่
    • ถ้าตัวมันเองมี data-theme="dark" ก็จะเป็น effectively-dark
    • ลูกที่อยู่ใต้บรรพบุรุษที่ effectively-dark ก็จะเป็น effectively-dark ด้วย ถ้าไม่มี data-theme="light" คั่นอยู่
    • จากนั้นจึงต้องใช้สไตล์กับ .effectively-dark :focus ตามสถานะนี้
  • ในไวยากรณ์ CSSLog สมมุติ กฎสามารถ เพิ่มสถานะที่อนุมานได้ ด้วยรูปแบบอย่าง class: +effectively-dark
    • .effectively-dark > :not([data-theme="light"]) จะส่งต่อสถานะไปยังลูก
    • กฎต้องถูก ทำซ้ำแบบเวียนเกิด จนกว่าจะถึงสถานะเป้าหมาย
  • การแพร่กระจายแบบเวียนเกิดลักษณะนี้แสดงออกได้ยากใน CSS ปัจจุบัน
    • ช่วงท้ายบทความมีวิธีเลียนแบบบางส่วนที่คล้ายกัน แต่ไม่ใช่วิธีทั่วไปที่ใช้หลักการเดียวกัน

การเวียนเกิดและจุดตรึงใน Datalog

  • Datalog ทำงานโดย อนุมานข้อเท็จจริงใหม่ จากข้อเท็จจริงเดิม และรองรับการเวียนเกิดเป็นพื้นฐาน
    • ancestor(X, Y) :- parent(X, Y).
    • ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).
  • กฎ ancestor จะขยายความสัมพันธ์บรรพบุรุษตามลำดับขั้นจากความสัมพันธ์พ่อแม่
    • จาก parent(alice, bob) จะได้ ancestor(alice, bob) ก่อน
    • จากนั้นเส้นทางอย่าง alice -> bob -> carol, alice -> bob -> dave ก็ถูกอนุมานเพิ่ม
  • การคำนวณนี้ดำเนินไปจนสุดได้ด้วย การประเมินแบบจุดตรึง โดยไม่ต้องมีลูป for แบบชัดเจน
    • เริ่มต้นด้วยการใช้เฉพาะ base fact ที่ระบุไว้
    • นำ body ของทุกกฎไปแทนค่ากับชุดข้อเท็จจริงปัจจุบัน แล้วเพิ่ม head
    • หยุดเมื่อไม่มีข้อเท็จจริงใหม่เกิดขึ้นอีก
  • เหตุผลที่วิธีนี้จบได้อยู่ที่ ความเป็นโมโนโทนิก
    • มีแต่เพิ่มข้อเท็จจริง ไม่ได้ลบออก ชุดข้อเท็จจริงที่รู้จึงมีแต่จะใหญ่ขึ้น
    • ถ้าเริ่มจากชุดข้อเท็จจริงจำกัด จำนวนข้อเท็จจริงที่อนุมานได้ก็ถูกจำกัดแบบมีขอบเขต
    • ตรงกันข้าม ถ้าลบข้อเท็จจริงได้ ข้อสรุปก่อนหน้าอาจถูกพลิกกลับและทำให้ติดลูปไม่รู้จบ

Container Queries และขอบเขตของ CSS จริง

  • Container Queries ใน CSS จริงสามารถใช้กฎโดยอิงจาก style ของบรรพบุรุษหรือคอนเทนเนอร์ได้
    • รองรับรูปแบบอย่าง @container style(--theme: dark) { .card { background: royalblue; color: white; } }
  • แต่ตัวอย่าง transitive dark mode ต้องการเงื่อนไขที่แรงกว่าการดูบรรพบุรุษแบบธรรมดา
    • แต่ละองค์ประกอบต้องรู้ว่าตัวเองเป็น effectively-dark หรือไม่
    • สถานะนั้นต้อง แพร่กระจายแบบส่งผ่าน ไปยังลูกหลานทั้งหมด
    • การแพร่กระจายต้องหยุดที่ขอบเขต data-theme="light"
  • Container Queries จัดการเงื่อนไขข้อที่สองไม่ได้
    • แม้อ่าน custom property ของบรรพบุรุษได้ แต่ไม่สามารถสืบค้น สถานะที่อนุมานได้ ซึ่งคำนวณโดยกฎอื่นไปแล้วซ้ำอีก
    • มองเห็นข้อมูลที่มีอยู่เดิมใน DOM ได้ แต่ไม่สามารถใช้ผลการคำนวณแบบเวียนเกิดมาเป็นเงื่อนไขของ selector ได้
  • บทความที่เกี่ยวข้อง ในปี 2015 ก็ชี้ว่า element queries ชนกับปัญหาเดียวกัน
    • ถ้าอนุญาตให้สืบค้นคุณสมบัติที่ตั้งค่าด้วย query ซ้ำได้ ความเสี่ยงของลูปและการวนไม่สิ้นสุดจะเพิ่มขึ้นมาก
  • CSS Working Group หลีกเลี่ยงปัญหานี้ด้วย การจำกัดทิศทางของการไหลของข้อมูล
    • อนุญาตให้ลูกหลานสืบค้นข้อมูลของบรรพบุรุษได้
    • แต่กัน feedback ทิศทางกลับหรือวงจรที่ย้อนมาสู่ style ของตัวเอง
    • จึงคงการคำนวณให้มีที่สิ้นสุดได้โดยไม่ต้องพึ่งความหมายเชิงจุดตรึง

ความเป็นไปได้ในการกลับด้านไวยากรณ์ CSS ให้เป็นภาษาสืบค้นแบบเวียนเกิด

  • แทนที่จะนำความหมายแบบ Datalog มาใส่ใน CSS ผู้เขียนเสนอว่าแนวทางใหม่ที่เป็นจริงได้มากกว่าคือ นำไวยากรณ์ CSS ไปวางทับบน Datalog
    • ไวยากรณ์อย่าง :-, จุดปิดท้าย, และอะตอมที่ไม่มี declaration ของ Datalog เป็นอุปสรรคต่อผู้ใช้ภาษาสมัยใหม่พอสมควร
    • CSS เองก็มีไวยากรณ์ selector ที่หลากหลายอยู่แล้วสำหรับจัดการโครงสร้างแบบต้นไม้
  • ผู้เขียนชี้ว่าข้อมูลจริงจำนวนมากมีลักษณะเป็น โครงสร้างต้นไม้
    • JSON
    • AST
    • ระบบไฟล์
    • ผังองค์กร
    • XML
  • ในโดเมนเหล่านี้ การผสานไวยากรณ์แบบ CSS ที่จัดการความสัมพันธ์พ่อแม่/ลูกโดยนัย เข้ากับ การเวียนเกิดแบบจุดตรึง อาจมีประโยชน์มาก
    • Datalog ทั่วไปมักต้องแปลงโครงสร้างต้นไม้มาเขียนใหม่ในรูปเชิงสัมพันธ์ ซึ่งยุ่งยาก
    • ถ้านำความรู้สึกแบบ selector ของ CSS มาใช้กับการสืบค้นแบบเวียนเกิดได้ตรง ๆ ก็อาจทำให้นักพัฒนาจำนวนมากเข้าถึงได้ง่ายขึ้น
  • เครื่องมือในรูปแบบนี้ยังไม่ปรากฏชัดนัก
    • ชื่อ "CSSLog" เป็นเพียงชื่อชั่วคราว และอาจมีภาษาอื่นที่ได้ชื่อดีกว่านี้
    • ยังมีพื้นที่ให้จัดการการสืบค้นต้นไม้แบบเวียนเกิดด้วยสัญกรณ์ที่คุ้นเคยกว่าเดิม

ประเด็นเสริมและลิงก์อ้างอิง

  • Datalog ถือกำเนิดขึ้นตั้งแต่ทศวรรษ 1970 ในบริบทของฐานข้อมูลเชิงสัมพันธ์และงานวิจัย AI ยุคนั้น ก่อนจะกลับมาได้รับความสนใจซ้ำในหลายรูปแบบ
  • รูปแบบการคำนวณจุดตรึงที่ง่ายที่สุดมักถูกแนะนำในชื่อ naive evaluation แต่สามารถไม่มีประสิทธิภาพเพราะคำนวณข้อเท็จจริงเดิมซ้ำทุกครั้ง
    • การปรับปรุงที่พบได้บ่อยคือ semi-naive evaluation ซึ่งใช้เฉพาะข้อเท็จจริงใหม่ที่เกิดขึ้นในแต่ละรอบ
  • ความเป็นโมโนโทนิกยังนำไปสู่คุณสมบัติที่เป็นประโยชน์ในระบบกระจายอีกด้วย
  • ยังมีวิธีเลียนแบบ transitive dark mode บางส่วนด้วยการสืบทอด custom property
    • [data-theme="dark"] { --effective-theme: dark; }
    • [data-theme="light"] { --effective-theme: light; }
    • @container style(--effective-theme: dark) { :focus { outline-color: white; } }
    • วิธีนี้ใช้แทนได้ค่อนข้างดีในกรณีเฉพาะนี้ แต่ไม่ได้ให้ transitive closure ที่แท้จริง ในภาพรวม

1 ความคิดเห็น

 
GN⁺ 24 일 전
ความคิดเห็นจาก Hacker News
  • CSS selector เขียนง่ายกว่า XPath มาก
    ไม่นานมานี้ยังมีการพูดถึงด้วยว่า DOM API ใหม่ของ PHP ทำให้จัดการ HTML และ CSS selector ได้แบบเนทีฟอย่างง่ายมาก แต่ก่อนต้องแปลง CSS ไปเป็น XPath
    [1] https://speakerdeck.com/keyvan/parsing-html-with-php-8-dot-4...
    แต่น่าเสียดายที่มันพัฒนามาโดยเน้นการจัดสไตล์บนเบราว์เซอร์ เลยไม่มีความสามารถอย่างการ เลือกตามเนื้อหาข้อความ แบบ XPath
    เท่าที่รู้เคยมีข้อเสนอมาก่อน แต่เข้า spec ไม่ได้เพราะอาจมีปัญหาด้านประสิทธิภาพในบริบทการเรนเดอร์ของเบราว์เซอร์

    • LLM ก็จัดการ CSS selector ได้ค่อนข้างดีเหมือนกัน
      ตอนทำเอเจนต์สำหรับแก้ไขเอกสาร ผมแสดงเอกสารเป็น HTML แล้วให้ LLM ระบุแค่ CSS selector เพื่อดึงชิ้นส่วนที่ต้องการเข้ามาเป็นคอนเท็กซ์ ซึ่งได้ผลดีแทบจะเหมือนเวทมนตร์
    • ฝั่งไคลเอนต์นั้น querySelector/querySelectorAll ถูกใช้อย่างแพร่หลายอยู่แล้ว เลยดีใจที่ DOM ใหม่ของ PHP มีสิ่งนี้เข้ามาด้วย
      คนสามารถใช้วิธีที่คุ้นเคยได้เหมือนเดิม
  • น่าจะดีถ้ามีชื่อที่ใช้เรียกแยกระหว่าง ไวยากรณ์ CSS กับระบบทั้งหมดของกฎ ฟังก์ชัน หน่วย ฯลฯ ที่ CSSWG นิยามไว้
    ฝั่งนี้ดูมีศักยภาพพอตัว แต่ถ้าจะคุยหรือค้นคว้าเคสการใช้งานอื่น ๆ สุดท้ายก็ดูเหมือนต้องไปคุ้ยโค้ดบน GitHub ที่มี CSS parser อยู่ เพื่อดูว่าคนกำลังสร้างของประหลาดอะไรบ้าง
    ผมเองก็กำลังลองจับของประหลาดคล้าย template engine ที่ผสมภาษามาร์กอัปแบบเบา ๆ ที่อิง node, CSS selector สำหรับบอกว่าอะไรจะเข้าไปในเทมเพลต, และไวยากรณ์คล้าย CSS สำหรับควบคุมว่าชิ้นส่วนเหล่านี้จะประกอบกันอย่างไร

    • ในมาตรฐาน ผมว่ามันแยกกันค่อนข้างชัดอยู่แล้ว
      https://www.w3.org/TR/selectors-3/
      และสเปก DOM ก็อ้างอิงสิ่งนี้
      https://dom.spec.whatwg.org/#selectors
      ดังนั้นคำเรียกรวมว่า CSS selector ก็ถูกต้องอยู่แล้ว หรือจะเรียกแค่ selector ก็ได้
      ชื่อ DOM selector อาจดูสะอาดตากว่า แต่ถ้าคิดถึง selector ที่ใช้ใน CSS แบบสแตติกหรือใน DOM engine อื่นนอก JS engine เช่น XML parser หรือ PHP DOM API ก็อาจยิ่งชวนสับสน
      อีกอย่างยังมี selector พิเศษอย่าง :hover หรือ ::target-text ที่ผูกตรงกับการเรนเดอร์และการนำทางของเบราว์เซอร์
      แต่ถ้าจะตั้งชื่อแยกให้กับ ส่วนย่อยขั้นต่ำของไวยากรณ์คิวรี ที่ผูกกับเบราว์เซอร์หรือ CSS น้อยกว่า ก็น่าจะมีประโยชน์
  • นึกถึง https://github.com/braposo/graphql-css ที่เคยเห็นในงานคอนเฟอเรนซ์เมื่อก่อน
    มันเป็นโปรเจ็กต์เล่น ๆ แต่ผมชอบที่มันแสดงให้เห็นได้ดีว่า การย้ายรูปแบบหนึ่งไปปลูกในอีกบริบทแล้วนำกลับมาใช้ใหม่ สามารถเปิดทางให้เกิดอะไรที่คาดไม่ถึงได้

    • อันนี้น่าสนใจดี
      ผมก็กำลังลองหยิบแพตเทิร์นจากต่างบริบทมาใช้ในแนวนี้พอดี
      ส่วนใหญ่คงไปไม่ไกลมาก แต่ในแง่ความเป็นแฮ็กเกอร์มันน่าสนใจไม่น้อย
  • pyastgrep อย่างที่เห็นใน https://pyastgrep.readthedocs.io/en/latest/ สามารถใช้ CSS selector เพื่อคิวรีไวยากรณ์ของ Python ได้
    ค่าเริ่มต้นคือ XPath เช่น pyastgrep --css 'Call > func > Name#main'

    • อันนี้ดีมากจริง ๆ
      มันเกือบตรงกับทิศทางที่ผมอยากชี้เลย
  • ผมยังไม่ค่อยเข้าใจว่ามันแก้สถานการณ์แบบไหน
    ตอนนี้ก็เปลี่ยนพาเรนต์แบบมีเงื่อนไขตามลูกได้อยู่แล้ว เช่น pre มี padding ปกติ 16px แต่ถ้ามีลูกโดยตรงเป็น code ก็ทำให้เป็น 0 ได้ด้วย &:has(> code)

    • จริง ๆ แล้วตอนแรกมันเริ่มจากการที่สองไอเดียคนละอย่างดูคล้ายกัน แล้วผมก็ลองผลักความเชื่อมโยงนั้นไปหลายทิศทางมากกว่า
      ข้อสรุปเลยไม่ใช่แนวว่า "ต้องแก้ข้อจำกัดของ CSS สมัยใหม่" แต่ใกล้เคียงกับว่า ถ้าเอา ไวยากรณ์คล้าย CSS ไปวางบน ระบบคล้าย Datalog มันอาจทำให้งานกับข้อมูลแบบต้นไม้ดูคุ้นมือสำหรับวิศวกรมากขึ้นไหม
    • สิ่งที่พูดถึงตรงนี้ไม่ใช่การแก้ด้วยการคำนวณสไตล์รอบเดียว แต่เป็นไวยากรณ์สำหรับ แก้ไขข้อมูลต้นทางเอง ของสิ่งที่แมตช์กับ selector
      พูดอีกแบบคือเป็นเรื่องของการเพิ่มองค์ประกอบลูกหรือแอตทริบิวต์ใหม่เข้าไปใน DOM
  • LLM ตอนนี้จริง ๆ แล้วไม่ได้เก่งเรื่อง CSS มากนัก เลยยิ่งอยากลองดูว่าถ้าทำแบบนี้แล้ว LLM จะให้เหตุผลได้ง่ายขึ้นไหม

  • นึกการใช้งานจริงไม่ค่อยออก แต่ก็ยังเท่อยู่ดี

  • อืม... ฟังดูเหมือนนี่คือ JQ เฉย ๆ หรือเปล่า

  • ผมชอบ CSS ในระดับหนึ่ง แต่ไม่ชอบที่มันมี ความซับซ้อนค่อย ๆ เพิ่มพอกพูน มากขึ้นเรื่อย ๆ
    ผมเข้าใจเหตุผลที่ว่าภาษาโปรแกรมย่อมทรงพลังกว่าภาษาที่ไม่ใช่ภาษาโปรแกรม แต่แทนที่จะทำให้ HTML·CSS·JavaScript ซับซ้อนขึ้นไปเรื่อย ๆ ผมกลับรู้สึกว่าน่าจะดีกว่าถ้ามีอะไรสักอย่างมาแทนทั้งก้อนนั้นไปเลย
    องค์ประกอบใหม่ ๆ ใน HTML5 ส่วนใหญ่ผมก็ยังไม่ค่อยเข้าใจว่าจำเป็นไปเพื่ออะไร เลยแทบไม่ใช้ สุดท้ายก็เริ่มคิดว่าคอนเทนเนอร์จำนวนมากก็เป็นแค่ div ที่มี ID เฉพาะเท่านั้น และถึงขั้นเคยอยากให้มี alias สำหรับ ID แบบนั้นไว้ใช้กับการนำทาง href ภายในหน้า
    อะไรอย่าง [data-theme="dark"] [data-theme="light"] :focus { outline-color: black; } ก็ใช้เวลาตีความในหัวนานเกินไป จนไม่รู้สึกว่ามันสวยงามและเรียบง่ายอีกต่อไป
    ในทางกลับกัน h2 { color: red; } ยังเรียบง่ายอยู่
    พอเป็นอะไรแบบ ancestor(X, Y) :- parent(X, Y). ก็ไม่อยากคิดต่อแล้ว :- นี่คืออะไรกัน ดูเหมือนหน้ายิ้ม
    ผมหยุดอ่านตั้งแต่ @container style(--theme: dark) { .card { background: royalblue; color: white; } }
    มันแปลกที่มาตรฐานซึ่งเคยทำงานได้ดี กลับดูเหมือนพังลงเรื่อย ๆ ตามเวลา

    • เจตนาของผมไม่ได้ไปทาง เพิ่มไวยากรณ์และความหมายให้ CSS แต่ใกล้เคียงกับการขโมยไอเดียจาก CSS มาใช้ประโยชน์จากความคล้ายกับภาษา query แบบตรรกะ/เชิงสัมพันธ์ เพื่อสร้าง สิ่งใหม่บางอย่าง มากกว่า
      ตัวอย่างเช่น [data-theme="dark"] [data-theme="light"] :focus { outline-color: black; } ถ้าคลี่เป็น pseudocode ภาษาอังกฤษ ก็จะใกล้เคียงกับว่า มี X ที่ data-theme="dark" และมีลูก Y ของมันที่ data-theme="light" และอยู่ในสถานะโฟกัส ก็ให้ outline-color ของ Y เป็น black
      ดังนั้นในสไตล์ Datalog ก็เขียนได้ประมาณ outline-color(Y, black) if data-theme(X, "dark") and parent(X, Y) and data-theme(Y, "light") and focused(Y)
      เท่ากับเปลี่ยน :- เป็น if และเปลี่ยนเครื่องหมายจุลภาคเป็น and
      ถัดไปยังอาจเขียนเป็น Y.outline_color := black if X.data-theme == dark and Y.parent == X and Y.data-theme == dark and Y.focused เพื่อให้ attr(X, val) ดูเป็น syntactic sugar คล้าย UFCS แบบ X.attr == val ได้ด้วย
      ถ้าอยากให้ดูเป็นสาย ALGOL มากขึ้น ก็อาจเป็น forall Y { Y.outline_color := black if Y.data_theme == "dark" and Y.focused and Y.parent.data_theme == "light" }
      ตรงนี้มีการประกาศ Y อย่างชัดเจนและทำให้ join หนึ่งตัวเป็นนัย เพื่อให้ดูเหมือนการเขียนโปรแกรมทั่วไปมากขึ้น แต่ในความเป็นจริงก็คือ Datalog engine จะคอยรันลูปแบบนี้อย่างมีประสิทธิภาพทุกครั้งที่ dependency เปลี่ยน