1 คะแนน โดย GN⁺ 11 시간 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • let-go เป็นภาษาถิ่นของ Clojure ที่เขียนด้วย Go มีทั้งคอมไพเลอร์เป็นไบต์โค้ดและสแตก VM ทำงานได้เป็น ไบนารีเดี่ยวขนาดประมาณ 10MB โดยไม่ต้องพึ่ง JVM
  • การเริ่มทำงานแบบ cold start อยู่ที่ประมาณ 7ms และระบุความเข้ากันได้กับ Clojure ตาม jank-lang Clojure test suite ว่า ผ่าน 4696 / 4921 assertions (95.4%)
  • ผู้เขียนใช้งานกับ CLI, สคริปต์ และเว็บเซิร์ฟเวอร์ อีกทั้งยังสร้าง daemonless container runtime บน let-go และสามารถคอมไพล์เป็นไบนารีแบบ standalone หรือหน้าเว็บ WASM แบบ self-contained ได้
  • เป้าหมายคือรองรับความสามารถของ Clojure จำนวนมาก เช่น persistent data structures, lazy seqs, transducers, protocols, records, multimethods, core.async, BigInts รวมถึงมี interop แบบสองทางกับฟังก์ชัน·struct·channel ของ Go
  • ไม่ใช่ drop-in replacement ของ JVM Clojure และไม่โหลด JAR ดังนั้นโปรเจ็กต์จริงที่มีการพึ่งพาไลบรารีอาจต้องมีการปรับแก้
  • บนเบนช์มาร์ก Apple M1 Pro ระบุว่ามีขนาดไบนารี 10MB, เวลาเริ่มต้น 6.7ms, หน่วยความจำขณะ idle 13.5MB ซึ่งชี้ให้เห็นความได้เปรียบด้านหน่วยรันที่เล็กกว่าเมื่อเทียบกับ Babashka, Joker, go-joker, gloat และ Clojure JVM
  • สำหรับงานคำนวณเชิงตัวเลขขนาดใหญ่ go-joker ที่มี WASM JIT หรือ JVM ที่ HotSpot วอร์มแล้วจะทำได้ดีกว่า ขณะที่ let-go ให้ผลใกล้เคียง Babashka ในเบนช์มาร์กอัลกอริทึมส่วนใหญ่ และสรุปว่าเร็วกว่า upstream Joker มากกว่า 10 เท่า
  • เนมสเปซมาตรฐานประกอบด้วย clojure.core, clojure.string, clojure.set, clojure.edn, clojure.test, clojure.core.async, io, http, json, transit, os, System, syscall, pods เป็นต้น
  • สามารถโหลด Babashka pods ได้ จึงใช้งานระบบนิเวศของ pod สำหรับ SQLite, AWS, Docker, file watching ฯลฯ ได้ และแชร์ ~/.babashka/pods/ ร่วมกับ bb
  • ข้อจำกัดที่ทราบแล้วรวมถึงยังไม่รองรับ Refs / STM, Agents, hierarchies, reader tagged literals, deftype, reify, clojure.spec, alter-var-root, subseq / rsubseq และยังไม่มีการตรวจจับ int64 overflow แบบอัตโนมัติ
  • ความแตกต่างด้านพฤติกรรมคือบล็อก go ไม่ได้เป็น IOC state machine แต่เป็น goroutine จริง, regex ใช้ re2 ของ Go แทน Java regex และระบบตัวเลขประกอบด้วย int64 + float64 + BigInt
  • การติดตั้งทำได้ผ่าน Homebrew สำหรับ macOS/Linux, Releases สำหรับ Linux·macOS·Windows บน amd64/arm64 หรือใช้ go install github.com/nooga/let-go@latest บน Go 1.22+
  • lg รองรับ REPL, การ eval expression และการรันไฟล์ รวมถึงการคอมไพล์เป็นไบต์โค้ด .lgb, การ bundle เป็น executable แบบ standalone และการสร้างเว็บแอป WASM
  • เอาต์พุต WASM ประกอบด้วย index.html แบบ self-contained ที่รวม WASM inline ขนาดประมาณ 6MB gzipped และ service worker โดยเมื่อใช้เนมสเปซ term จะมีเทอร์มินัลอีมูเลชันที่อิงกับ xterm.js
  • เซิร์ฟเวอร์ nREPL ในตัวทำงานร่วมกับ CIDER, Calva, Conjure และในโปรแกรม Go สามารถฝัง let-go เป็นชั้นสคริปต์ผ่าน pkg/api เพื่อส่งค่า·ฟังก์ชัน·struct·channel ของ Go เข้าไปยัง VM ได้

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

 
ความคิดเห็นจาก Hacker News
  • ดีเลย! ช่วงนี้ผมลองทำการทดลองเอาไวยากรณ์แบบ Lisp มาครอบบน semantics ของ Go ดูด้วย: https://codeberg.org/veqq/Joe
    ถ้าเป็นสายตระกูล Clojure ที่ไม่มี JVM, Janet ก็ดีมากจริงๆ และผมก็ใช้งานในโปรดักชันอยู่พักหนึ่งแล้ว: https://janet-lang.org/
    ถ้าอยากได้ Lua VM และไลบรารี ก็มี Fennel ด้วย

    • Joe ดูดีเลยนะ ส่วน Janet ผมยังไม่ได้ลองใช้เอง แต่รู้สึกว่ามันเป็นภาษาที่ไปใน ทิศทางของตัวเอง มากกว่าจะพยายามเดินตาม Clojure
  • ลอง Wasm browser REPL นี้ดูก็ดี: https://gloathub.org/repl/
    Gloat เป็นเครื่องมืออัตโนมัติสำหรับ Glojure AOT
    เมื่อฤดูร้อนที่ผ่านมา ผมทำให้ Glojure AOT เป็นไปได้ร่วมกับ James Hamlin และตั้งแต่นั้นมาก็พัฒนาต่อเนื่องอยู่ กำลังทำงานร่วมกับ marcingas(nooga) ด้วยเพื่อให้ Gloat/Glojure/let-go ทำงานร่วมกันได้อย่างราบรื่น

  • น่าทึ่งที่มันรันบน Plan 9 ได้
    ถ้า Go กลายเป็นภาษาชั้นหนึ่งบน 9front หรือก็คือเป็นภาษาที่มีมาให้ในระบบเลยก็คงเจ๋งมาก
    ผมกำลังเล่นกับโซเชียลเน็ตเวิร์กสำหรับ Plan 9 อยู่: https://youtube.com/watch?v=q6qVnlCjcAI&si=MBCeM0QdA0WsKAe7
    ทั้งหมดเขียนด้วย rc และ awk แต่ก็มีบางจุดที่รู้สึกว่าน่าจะดีถ้ามี Go หรือ Clojure แทรกอยู่บ้าง

    • ชอบเดโม 9social นะ ถึงผมจะไม่ได้เป็นผู้ใช้ Plan 9 โดยตรง แต่ก็ได้แรงบันดาลใจจาก แนวทางแบบ Plan 9 อยู่เสมอ
    • ผมเริ่มปล่อย ไบนารี amd64 และ arm 32-bit สำหรับ Plan 9 ใน GitHub releases แล้ว
      amd64 ทดสอบบน 9front แล้ว และดูเหมือนว่าทุกอย่างจะทำงานได้ดี แม้ CLI จะยังไม่ค่อยมีความเป็น Plan 9 เท่าไร แต่สักวันก็อยากพอร์ตให้เนทีฟกว่านี้
  • ตอนนี้มี Clojure สำเนียง Go อยู่หลายตัวแล้ว สิ่งที่ผมอยากรู้ที่สุดคือฝั่งไหนที่ โฮสต์บน Go อย่างสมบูรณ์ และให้ระดับการทำงานร่วมกันได้เทียบเท่ากับที่ JVM Clojure มีกับ Java
    อยากให้ของที่ผมทำใน Go เอาไปใช้ได้ และใน Clojure ก็ใช้ Go ได้ด้วย รวมถึงทำโปรเจกต์แบบผสมกันได้ อีกอย่างนอกจากเรื่อง interop แล้ว ก็อยากเห็นรายละเอียดที่สรุปว่ามีอะไรที่เหมือนและต่างกันอย่างไร

    • Gloat/Glojure น่าจะมีเรื่องเล่าที่ดีที่สุดในด้านรันไทม์แบบโฮสต์ เพราะมี Go source AOT pipeline ที่ทำให้ตอนคอมไพล์สามารถดึงอะไรก็ได้จาก Go เข้ามา
      ส่วน let-go สามารถส่งผ่านค่า Go แบบไป-กลับได้ทุกชนิด รวมถึง struct, function และ channel แต่ยังไม่สามารถดึงไลบรารี Go แบบใดก็ได้เข้ามาใช้ตรงๆ โดยไม่ต้องห่อหุ้ม ไลบรารีพวกนั้นต้องถูก build ไว้ในรันไทม์ก่อน
  • ขอทักเล็กน้อยว่าใน README บอกว่า cold start 7ms แต่ไม่กี่บรรทัดถัดมาดันบอก 6ms สงสัยยิ่งอ่าน README ก็ยิ่งเร็วขึ้นมั้ง

    • แก้แล้ว บนเครื่องผมมันอยู่ราว 6~7ms และค่ามัธยฐานดูเหมือนจะประมาณ 6.5ms
  • นี่คือ Clojure port แบบที่ผมตามหาอยู่เสมอ
    เพราะผมมองว่า core library และ channel abstraction ของ Go เป็น API พื้นฐานที่เรียบง่ายและดีกว่า และก็น่าจะเข้ากันได้ดีกับ API สาย core.async ด้วย แถมยังตอบโจทย์ความอยากได้ไบนารีเดี่ยวขนาดใหญ่ด้วย
    ขอบคุณสำหรับงานนี้ ถ้าความหลงใหลใหม่ที่ผมมีต่อ C++26 ซาลงหน่อย จะกลับมาดูอีกแน่นอน
    อีกอย่าง ผมก็ไม่รู้ว่าทำไม Glojure ถึงไม่เคยอยู่ในเรดาร์ของผมเลย และมันก็ดูเป็นโปรเจกต์ที่ยอดเยี่ยมเหมือนกัน

    • ผมเคยคิดไอเดียทำ DSL สไตล์ PHP ยุคเก่า ที่ใช้รันไทม์และแพ็กเกจของ Go อยู่ข้างใต้
      ที่เรียกว่า PHP ยุคเก่า เพราะเดิมที PHP ใกล้เคียงกับการเป็น DSL ที่เน้นเว็บมากกว่า เดี๋ยวนี้ไม่ค่อยเป็นแบบนั้นแล้ว ภาษาแบ็กเอนด์ที่เขียนง่ายคล้าย PHP แต่มีพลังของ Go อยู่ด้านหลังน่าจะน่าสนใจ และ Clojure ก็เป็นตัวเลือกที่ยอดเยี่ยม
    • ถ้าภายหลังได้ลองใช้จริง รบกวนช่วยเปิด issue สักหนึ่งหรือสองอันด้วยก็ดีนะ
  • อีกทางเลือกคือ Joker ด้วย: https://joker-lang.org
    มันยอดเยี่ยมมากจริงๆ และผมคิดว่ามัน ถูกประเมินต่ำไปมาก

    • สิ่งที่ผมชอบมากใน Joker คือเรื่อง การห่อหุ้มไลบรารี Go ทำได้ลื่นไหลมาก ดูเหมือนจะรองรับทุกอย่างที่ Go มีให้
      แต่สำหรับ let-go ผมไม่อยากใส่อะไรเพิ่มมากเกินไป ผมชอบที่มันยังอยู่ภายใน 10MB ได้
  • อยากให้ชื่อภาษาดีกว่าแค่ “lets-go” หน่อย “clogo” เป็นไง?

    • การตั้งชื่อมันยาก แต่ผมชอบ let-go นะ มันเป็น มุกคำซ้อนหลายชั้น
      (let [...] (go ...))
      มันทำให้ใช้ let ใน Go ได้!
      ส่วน Clogo สำหรับผมถือว่า no-go ถ้ามีชื่ออื่นที่ดีกว่านี้ก็ยินดีพิจารณา
  • ถ้าส่ง PR ไปที่ https://github.com/chr15m/awesome-clojure-likes จะยินดีมาก