6 คะแนน โดย GN⁺ 2025-04-21 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ฟีเจอร์ comptime ของ Zig มอบ ความสามารถในการประเมินผลขณะคอมไพล์ที่ทรงพลังมาก แต่ก็ ถูกจำกัดไว้โดยเจตนา
  • เมื่อรันโค้ดในช่วงคอมไพล์ จะ ไม่สามารถเข้าถึงข้อมูลของโฮสต์ได้ ซึ่งเป็นการออกแบบที่เหมาะกับการครอสคอมไพล์
  • ไม่รองรับการสร้างโค้ดแบบไดนามิก, DSL, RTTI, I/O เป็นต้น แต่ใช้การทำโค้ดให้เฉพาะทางตามชนิดแบบชัดเจนแทน
  • RTTI สามารถทำขึ้นเองได้ โดยสามารถประกอบข้อมูลชนิดที่มีอยู่เฉพาะตอนคอมไพล์ใหม่ให้ใช้งานได้ในรันไทม์
  • สามารถสร้างชนิดใหม่ด้วย comptime ได้ แต่ขยาย API ไม่ได้ ไม่สามารถเพิ่มเมธอดที่ผู้ใช้กำหนดเองได้

สิ่งที่ comptime ของ Zig ไม่ได้ทำ

  • แม้ comptime ของ Zig จะมอบความสามารถทรงพลังอย่าง generics, conditional compilation, serialization, ORM และอื่น ๆ แต่ บางความสามารถก็ถูกจำกัดไว้อย่างชัดเจน
  • ข้อจำกัดเหล่านี้กลับทำให้การออกแบบของ Zig กระชับและคาดเดาได้มากขึ้น
  • เข้าถึงข้อมูลโฮสต์ไม่ได้ (No Host Leakage)

    • โค้ด comptime จะ ทำงานโดยยึดตามแพลตฟอร์มเป้าหมาย ไม่ใช่ระบบที่ใช้รันโค้ดนั้น
    • ใน Zig ระหว่างคอมไพล์ ไม่สามารถใช้ข้อมูลอย่าง endian ของระบบโฮสต์, ขนาดพอยน์เตอร์ ฯลฯ ได้
    • จุดประสงค์คือเพื่อ รับประกันความปลอดภัยสำหรับการครอสคอมไพล์
    • ในโค้ดตัวอย่าง ผลลัพธ์ไบต์ของตัวเลขรูปแบบ BF16 จะแตกต่างกันตามแพลตฟอร์มเป้าหมาย
  • ไม่มีการสร้างโค้ดจากสตริง (No #eval)

    • Zig ไม่ได้มีความสามารถในการ สร้างโค้ดแบบไดนามิก เหมือน #include ของ C, mixin ของภาษา D หรือ macro ของ Rust
    • แต่รองรับ partial evaluation ที่อิงกับอาร์กิวเมนต์ comptime
    • หากอาร์กิวเมนต์บางตัวทราบได้ตั้งแต่ตอนคอมไพล์ ก็จะเหลือเฉพาะสาขานั้นไว้ ทำให้ ปรับแต่งโค้ดให้เหมาะสมได้
  • ขยายไวยากรณ์ DSL ไม่ได้ (No DSLs)

    • ใน Zig ไม่มีความสามารถในการ สร้างไวยากรณ์ (syntax) ที่ผู้ใช้กำหนดเอง แบบ Lisp หรือ Rust
    • ข้อมูลทั้งหมดจะถูกส่งผ่านในรูปของ ค่า (value) ตามไวยากรณ์ของ Zig เท่านั้น
    • DSL แบบจำกัดอย่างฟอร์แมตสตริง (printf) สามารถทำได้ ผ่านสตริง comptime เท่านั้น
  • ไม่มีข้อมูลชนิดในรันไทม์ (No RTTI)

    • Zig อาจทำงานได้คล้ายภาษาไดนามิกอย่าง Python แต่ ข้อมูลชนิดจะมีอยู่เฉพาะใน comptime เท่านั้น
    • หากต้องการให้ใช้ได้ในรันไทม์ ต้อง นิยามโครงสร้าง RTTI เองและจัดการผ่านพอยน์เตอร์
    • ตัวอย่าง: นิยามโครงสร้าง RTTI ที่เก็บชื่อฟิลด์และข้อมูล offset ของ struct แล้วเข้าถึงฟิลด์ผ่านพอยน์เตอร์
  • สร้าง API ใหม่ไม่ได้ (No New API)

    • ใน Zig แม้จะสร้างชนิดใหม่ด้วย comptime ได้ แต่ ไม่สามารถเพิ่มเมธอดให้ชนิดนั้นได้
    • จึงไม่สามารถขยาย API ได้เหมือน derive macro ของ Rust
    • เมื่อต้องทำ JSON serialization จะไม่สามารถเพิ่มเมธอด .to_json() ได้ และต้อง ทำผ่านการส่ง type argument ให้ฟังก์ชันส่วนกลางแทน
  • ไม่มี IO ขณะคอมไพล์ (No IO)

    • comptime ของ Zig ห้ามเข้าถึงทรัพยากรภายนอก เช่น file system, network, database
    • ผลคือ มีความสามารถในการทำซ้ำได้สูงขึ้น ปลอดภัยขึ้น และใช้แคชได้ดีขึ้น
    • หากต้องใช้ IO ให้ใช้ระบบ build อย่าง build.zig เพื่อ สร้างโค้ด Zig ล่วงหน้าแล้ว import เข้ามา
  • สรุป: El Disco (สมดุลระหว่างนามธรรมกับความเรียบง่าย)

    • Zig มอบความสามารถด้าน metaprogramming ที่ทรงพลัง แต่ก็รักษาความคาดเดาได้ผ่านการออกแบบที่จำกัดอย่างมาก
    • ด้วยข้อจำกัดเหล่านี้ comptime ของ Zig จึง ยังคงมีความเป็นภาคปฏิบัติและเข้าใจได้ง่าย
    • แม้ไม่มีนามธรรมที่ซับซ้อน ก็ยังมีประโยชน์ต่อการใช้งานจริง และ ทำงานได้ชัดเจนตามความสามารถที่ประกาศไว้เท่านั้น

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

 
GN⁺ 2025-04-21
ความคิดเห็นบน Hacker News
  • comptime ของ Zig มีคุณลักษณะที่โดดเด่น

    • ใช้ทดแทนความสามารถหลากหลายอย่างจากภาษาอื่นได้
    • เข้าใจได้ง่ายเพราะมีความโปร่งใสเชิงอ้างอิง
    • มอบความสามารถอันทรงพลังผ่านการ introspection
    • เปิดทางให้เขียนโค้ดที่เรียบง่ายแต่ทรงพลังในแบบที่ต่างจาก Lisp
    • ภาษาที่มีดีไซน์และแนวทางใหม่เช่นนี้หาได้ไม่บ่อย
  • ข้อเสียและแนวทางแก้ของ comptime ใน Zig

    • สร้างโค้ดผ่าน zig build แล้วคอมไพล์ด้วยการ @import
    • ให้เสรีภาพมากขึ้นและเวลาในการรันแบบไม่จำกัด แต่ยังไม่มีอิสระในการสร้างชนิดข้อมูลของ Zig เป็นค่าในคอมไพล์ปัจจุบัน
    • คล้ายกับประสบการณ์ในอดีตที่เชื่อม Perl และ Tcl เข้ากับ C
    • ท่าทีวิพากษ์วิจารณ์ตัวเองของชุมชน Zig บางครั้งก็น่าประหลาดใจ
  • วลีภาษาสเปนที่อ้างจากเรื่องสั้นของ Borges เกี่ยวข้องกับเทพเจ้านอร์ส

  • ความยืดหยุ่นของ comptime

    • เมื่อจำเป็นต้องใช้ข้อมูลชนิดข้อมูลระหว่างทำงาน สามารถเพิ่มไว้ในพารามิเตอร์ของฟังก์ชันได้
    • หากไม่สามารถส่งชนิดข้อมูลได้ในบางสถานการณ์ ก็จำเป็นต้องแก้ปัญหาที่ระดับการออกแบบ
  • จุดเด่นที่ทำให้ comptime ของ Zig เป็นที่รู้จัก

    • รองรับความสามารถหลากหลาย เช่น generics, conditional compilation, subtyping, serialization, ORM เป็นต้น
    • ภาษาอื่นก็มีความสามารถคล้ายกันด้านการประเมินผลตอนคอมไพล์
  • บล็อกโพสต์ที่ให้ความรู้

    • อธิบายความแตกต่างระหว่าง comptime for และ inline for
    • เวอร์ชัน inline จะรู้ความยาวได้เฉพาะใน comptime เท่านั้น
  • ความเห็นเชิงบวกต่อภาษาและเครื่องมือของ Zig

    • อยากให้มี safe mode แบบ Rust
    • ไปไกลกว่า C/C++ มากแล้ว
    • ประทับใจคอมไพเลอร์ของ Zig อย่างมาก
  • ประเด็นที่น่าสนใจเกี่ยวกับ comptime ของ Zig

    • ความสามารถในการแทนชนิดข้อมูลเป็นค่าได้ในช่วงคอมไพล์
    • ทำให้เข้าใกล้ภาษาไดนามิกหรือ runtime reflection ได้โดยไม่มี runtime overhead
  • ความสับสนเกี่ยวกับการรันโค้ดในช่วงคอมไพล์

    • สงสัยว่าโค้ดที่ทำงานตอนคอมไพล์นั้นรันบนเครื่องโฮสต์ในเครื่องจริงหรือไม่
    • อยากรู้ว่าทำไม Zig ถึงซ่อนแพลตฟอร์มโฮสต์ไว้
    • มีความเห็นเชิงบวกต่อความสามารถ cross-compile ของ Zig