3 คะแนน โดย GN⁺ 2024-09-23 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Hy 1.0.0 ซึ่งเป็นภาษาถิ่น Lisp ที่ฝังอยู่ใน Python ได้รับการปล่อยออกมาแล้ว หลังผ่านการพัฒนาเป็นระยะ ๆ และการใช้งานจริงมาประมาณ 12 ปี
  • ใน Hy 1.x การเปลี่ยนแปลงที่ทำให้ ความเข้ากันได้เสียหาย ในองค์ประกอบภาษาที่มีเอกสารกำกับ จะนำไปสู่การเพิ่มหมายเลขเวอร์ชัน major โดยยกเว้นกรณีการยุติการรองรับเวอร์ชัน Python ที่นักพัฒนา CPython ไม่รองรับแล้ว
  • จุดเน้นต่อจากนี้จะอยู่ที่การแก้ บั๊ก ใหม่ ๆ การเพิ่มความเข้ากันได้กับ Python เวอร์ชันใหม่ และการ รองรับฟีเจอร์ใหม่ของ Python ในแบบที่ไม่ทำให้โค้ด Hy 1.x.y เดิมเสียหาย
  • ผู้ใช้รายหนึ่งยกตัวอย่างการใช้มาโคร Hy เพื่อลดรูปการประกาศ SQLAlchemy ORM ให้อยู่ในรูป defmodel และอธิบายว่าเพราะเป็นการขยายมาโคร จึง ไม่มีค่าใช้จ่ายเพิ่มเติมตอนรันไทม์
  • การทำงานโดยตรงบน MicroPython ดูจะยากเพราะมีเพียงส่วนย่อยของไลบรารีมาตรฐาน แต่การแปลงด้วย hy2py บน CPython แล้วใช้เฉพาะโครงสร้างที่ MicroPython รองรับอาจเป็นไปได้

การปล่อย Hy 1.0.0

  • Hy 1.0.0 ได้รับการปล่อยออกมาแล้ว
    • Hy เป็น ภาษาถิ่น Lisp ที่ฝังอยู่ใน Python
    • ก่อนมาถึงรีลีสนี้ มีการพัฒนาเป็นระยะ ๆ และมีการใช้งานจริงจำนวนมากมาเกือบ 12 ปี
  • บทแนะนำและเอกสารมีให้ที่ Hylang.org
  • ประวัติเวอร์ชันดูได้ใน NEWS file
  • ยังมีลิงก์ไปยังบทความเกี่ยวกับรีลีสที่จริงจังน้อยกว่าอย่าง HYPE POST ด้วย

นโยบายความเข้ากันได้ของ 1.x

  • ต่อจากนี้ breaking change ในส่วนของภาษาที่มีเอกสารกำกับ จะเพิ่มหมายเลขเวอร์ชัน major
  • ข้อยกเว้นคือกรณียุติการรองรับเวอร์ชัน Python ที่นักพัฒนา CPython ไม่รองรับแล้ว
  • มีการระบุเจตนาว่าจะไม่ให้การเพิ่มเวอร์ชัน major เกิดขึ้นบ่อย
  • จุดเน้นของงานต่อจากนี้อยู่ที่
    • การแก้ บั๊ก ที่เกิดขึ้นใหม่
    • การเพิ่มความเข้ากันได้กับ Python เวอร์ชันใหม่
    • การรองรับฟีเจอร์ใหม่ของ Python ในแบบที่ไม่ทำให้โค้ดที่ทำงานได้ใน Hy 1.x.y รุ่นก่อนเสียหาย

ตัวอย่างการใช้มาโคร Hy: DSL โมเดล SQLAlchemy

  • ผู้ใช้รายหนึ่งอธิบายว่ากำลังสร้าง ORM และเว็บเฟรมเวิร์กแบบอะซิงโครนัสด้วย Hy โดยทั้งสองอย่างใช้ไลบรารีเดิมที่มีอยู่ และส่วนใหญ่ประกอบขึ้นด้วย มาโคร
  • มีการนำเสนอตัวอย่างการเขียนประกาศโมเดลจาก SQLAlchemy ORM Quick Start Guide ให้สั้นลงด้วยมาโคร defmodel ของ Hy
    • เขียนโมเดล User, Address และการประกาศความสัมพันธ์ในรูป S-expression ของ Hy
    • defmodel เป็นมาโครที่ขยายเป็นโค้ด SQLAlchemy จึงไม่มี ค่าใช้จ่ายเพิ่มเติมตอนรันไทม์
  • ผู้ใช้ระบุว่าการที่ภายในของ Hy และ API มีเสถียรภาพเป็นสิ่งจำเป็นสำหรับงานลักษณะนี้

การประกาศความสัมพันธ์และการถกเรื่อง Query DSL

  • ตัวอย่าง defmodel ถูกขยายไปยังรูปแบบความสัมพันธ์หลายแบบ
    • one-to-one: 1->1
    • many-to-many: *->* และ deflinktable
    • ฟิลด์ timestamp: :timestamp-create, :timestamp-update
  • หลังประกาศแล้ว อ็อบเจ็กต์จะเป็น อ็อบเจ็กต์ SQLAlchemy 2.0 ORM ทั่วไป ดังนั้นสามารถใช้ Hy เฉพาะส่วน DSL ของสคีมาฐานข้อมูล และใช้ Python กับส่วนที่เหลือได้
  • Query DSL ยังอยู่ระหว่างทำงาน และมีการกล่าวว่า fluent interface ไม่ค่อยเข้ากับ S-expression
  • ความเห็นหนึ่งเสนอให้ทำให้ syntactic order กับ semantic order ของ SQL ตรงกัน พร้อมลิงก์ไปยังงานของ Google Research เรื่อง SQL Has Problems. We Can Fix Them: Pipe Syntax In SQL
  • มีคำตอบว่าแนวทางอย่าง |> หรือการเลียนแบบ list comprehension อาจเป็นไปได้ แต่ดีไซน์สุดท้ายจะออกมาหลังจากทำแอปขนาดเล็กและวนรอบรีแฟกเตอร์ซ้ำ ๆ

ความเป็นไปได้กับ MicroPython และกระแสตอบรับต่อรีลีส

  • มีคำถามว่าสามารถทำงานบน MicroPython แทน CPython ได้หรือไม่
  • คำตอบมีแนวโน้มว่า การทำงานโดยตรงดูจะยาก เพราะ MicroPython มีเพียงส่วนย่อยขนาดเล็กของไลบรารีมาตรฐาน Python
  • อย่างไรก็ตาม หากใช้ hy2py บน CPython เพื่อแปลงเป็นโค้ด Python แล้วจำกัดให้อยู่ในโครงสร้างที่ MicroPython รองรับ ก็อาจสามารถรันผลลัพธ์ได้
  • พบว่าจำนวนผู้เยี่ยมชมไม่ซ้ำรายวันของเว็บเซิร์ฟเวอร์ที่โฮสต์ Hylang.org เพิ่มขึ้นอย่างมากในวันปล่อยรีลีส

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

 
GN⁺ 2024-09-23
ความคิดเห็นจาก Hacker News
  • ตอนแรกค่อนข้างเข้าใจยากว่า Hy แปลงเป็น Python จริง ๆ อย่างไร และก็ไม่แน่ใจด้วยซ้ำว่ามันถูกคอมไพล์หรืออินเทอร์พรีต
    สุดท้ายไปเจอคำอธิบายใน Wikipedia ว่า “Hy เป็น Lisp dialect ที่ออกแบบมาให้แปลง s-expression ไปเป็น abstract syntax tree (AST) ของ Python เพื่อให้ทำงานร่วมกับ Python ได้” และดูจากโค้ดบน GitHub แล้ว ตัวคอมไพเลอร์ก็น่าจะเขียนด้วย Python เช่นกัน: https://github.com/hylang/hy/blob/master/hy/compiler.py
    ถ้าในเว็บหลักอธิบายว่าเป็น “Lisp dialect ที่คอมไพล์ไปเป็น Python AST” แทน “Lisp dialect ที่ฝังอยู่ใน Python” ก็น่าจะชัดเจนกว่า เพราะการฝัง Lisp ทำได้หลายแบบ เช่น ติดอินเทอร์พรีเตอร์เข้าไป, คอมไพล์เป็น Python bytecode, หรือแปลงเป็นซอร์สโค้ด Python ซึ่งแต่ละแบบก็มีข้อแลกเปลี่ยนต่างกันมาก

    • ใน README/หน้า GitHub ก็มีเขียนไว้แล้วว่า “Hy เป็น Lisp dialect ที่ฝังอยู่ใน Python และแปลงโค้ด Lisp ไปเป็น อ็อบเจ็กต์ Python AST ทำให้คุณใช้โลกของ Python ในรูปแบบ Lisp ได้”
    • ใช่ ตัวคอมไพเลอร์นี้เขียนด้วย Python และ Hy ไม่ได้ self-hosting
      โดยปกติซอร์สโค้ด Hy จะกลายเป็นอ็อบเจ็กต์ Python AST แล้วให้ Python คอมไพล์และรันมันต่อ แต่ก็สามารถแปลงอ็อบเจ็กต์ Python AST ให้กลับเป็นข้อความซอร์ส Python ได้เช่นกัน และยังทำงานข้ามกันได้ทั้งใช้ Python จาก Hy หรือใช้ Hy จาก Python: https://hylang.org/hy/doc/v1.0.0/interop
    • คำว่า “ฝัง” หมายถึงการที่สามารถผสม Python กับ Hy ในโปรเจกต์เดียวกันและ เรียกหากันได้สองทาง
      สุดท้ายทั้งหมดก็กลายเป็น Python bytecode เลยทำงานได้ดี
    • ในงานเปิดตัว Hy เดิมก็พูดชัดเจนว่า Lisp ถูก คอมไพล์เป็น Python bytecode แล้วจึงฝังเข้าไป
      ดูได้ราวนาที 16:25 ของวิดีโอนี้: https://m.youtube.com/watch?v=1vui-LupKJI
  • ตลอดหลายปีที่ Hy เติบโตขึ้น ดูเหมือนว่ามันไม่ได้สะสม syntax sugar และกรณีพิเศษเพื่อให้ Lispy มากขึ้นและ Pythony น้อยลง แต่กลับเข้าใกล้การเป็น ชั้นนามธรรมทางไวยากรณ์แบบบาง ๆ ของชุดความสามารถใน Python มากกว่า
    หรือพูดอีกแบบคือไปโฟกัสที่แก่นซึ่งเลียนแบบด้วยวิธีอื่นได้ยาก โดยเฉพาะ macro ตัวอย่างล่าสุดคือ match ก็เป็น match แบบเนทีฟของ Python ตรง ๆ และไม่มี polyfill สำหรับเวอร์ชันก่อน Python 3.10 สมัยก่อน foo? เคยเป็นกรณีพิเศษที่ถูก mangling ไปเป็น is_foo แต่ก็ถูกถอดออกแล้ว, hy.eval ก็ถูกปรับให้ใกล้กับ eval ของ Python มากขึ้น, และยูทิลิตีที่ไม่ใช่แก่นหลักแต่มีไว้ก็ดีอย่าง unless ก็มักถูกย้ายไปอยู่ในแพ็กเกจ Hyrule
    ตอนแรกมันดูสวนทางกับสัญชาตญาณ แต่ข้อดีสำคัญคือช่วยลดเส้นโค้งการเรียนรู้เวลาย้ายจาก Python มา Hy และทำให้โต้ตอบกับแพ็กเกจ Python ได้สอดคล้องง่ายขึ้น อาจเป็นไปได้ด้วยว่าเหตุผลหนึ่งคือเพื่อให้บำรุงรักษาภาษาได้ง่ายขึ้น และถ้าจำไม่ผิด แค่ let อย่างเดียวก็เหมือนจะลองทำกันราวสี่ครั้งกว่าจะลงตัว

    • พอถึงจุดหนึ่งก็ได้ตระหนักว่า ถ้าลดความแตกต่างที่ไม่จำเป็นจาก Python ลง ทั้งการดูแลภาษาและการใช้งานก็จะลื่นไหลขึ้นมาก
      เวลาผมเขียนโค้ด Hy ผมก็เปิดเอกสาร Python หรือเอกสารของไลบรารี Python ภายนอกบ่อยกว่าเอกสาร Hy มาก รู้สึกว่ามีหลายจุดที่ Python ควรถูกปรับปรุง แต่ฟีเจอร์เก่า ๆ อย่างการอนุญาตให้เขียน True เป็น true เพื่อเอาใจ Clojure นั้นจริง ๆ แล้วก็เป็นแค่ความซับซ้อนที่ไม่จำเป็น
  • HYPE POST ดีมากจริง ๆ ในฐานะคนทำซอฟต์แวร์องค์กร ต้องบอกว่า มุกเสียดสี เฉียบมาก
    https://github.com/hylang/hy/discussions/2609

  • ในที่สุดก็ออกสักที แบบนี้คงได้ไปเก็บงาน https://github.com/rcarmo/sushy ต่อ
    ผมค่อย ๆ แตะมันมาเป็นปี ๆ แต่ทุกครั้งที่อัปเกรด Hy ก็มักมีบางส่วนของไวยากรณ์พัง หรือไม่ก็มีฟีเจอร์ย้ายเข้าออกแพ็กเกจ Hyrule ทำให้ลำบาก
    อนึ่ง Hy ทำงานได้ค่อนข้างดีใน https://holzschu.github.io/a-Shell_iOS บน iPad ด้วย เพียงแต่ syntax highlighting ของ vim/neovim ต้องตามให้ทันรีลีส 0.29+ และ async
    ที่ผ่านมาผมก็ลอง Fennel กับ Guile มาเหมือนกัน แต่การเข้าถึงไลบรารีและ ecosystem ของ Python ยังดูดีกว่า และด้วย async ก็ทำงานด้าน API ได้อย่างมีประสิทธิภาพด้วย ใน Scheme หลายตัว การจัดการ HTTPS พร้อมการ reuse socket และควบคุม header แบบละเอียดก็ยังยุ่งยากอยู่มาก เลยรู้สึกว่าการใช้ aiohttp ดีกว่ามาก

  • ถ้าเทียบกับจุดเริ่มต้นเรียบง่ายในวันแรก ๆ มันมาไกลมากจริง ๆ
    ผมเคยดู lightning talk ที่ PyCon ซึ่งเป็นครั้งแรกที่ Hy ถูกนำเสนอให้โลกเห็น และไม่นานหลังจากนั้นก็ได้เจอ Paul แล้วเริ่มมีส่วนร่วมกับ Hy เวอร์ชันแรก ๆ ผมดูแล kwargs สไตล์ Common Lisp, งานภายในบางส่วน, และไลบรารีหนึ่งหรือสองตัว
    ความขี้เล่น นั้นมีประโยชน์ โดยเฉพาะในแง่ของการรักษาแพสชันไว้ ผมชอบที่แฮกเกอร์ยังเป็นแฮกเกอร์ได้ และไม่จำเป็นที่ทุกอย่างต้องเป็นเรื่องธุรกิจ แม้ผมจะไม่ได้เกี่ยวข้องมาหลายปีแล้ว แต่ก็รู้สึกดีที่เห็นโปรเจกต์ยังเดินหน้าต่อ และนี่เป็นหมุดหมายที่ยอดเยี่ยมจริง ๆ

  • ถ้าเป็นแฟน Clojure ก็ยังมี Basilisp ซึ่งเป็น Lisp dialect ที่ใกล้เคียงกับ Clojure มากกว่าและรองรับ Python 3.8+ ด้วย
    https://github.com/basilisp-lang/basilisp

  • แม้จะไม่ใช่ Lisp แต่ถ้ามองว่าเป็นภาษาการเขียนโปรแกรมเชิงฟังก์ชันที่ transpile ไปเป็น Python แล้ว Coconut ก็น่าสนใจเช่นกัน: https://coconut-lang.org/
    อยากรู้ประสบการณ์จากคนที่เคยใช้ Hy หรือ Coconut จริง ๆ มาก

    • เมื่อหลายปีก่อนเคยลองใช้ Coconut นิดหน่อย และตอนนั้นรู้สึกว่าคอมไพเลอร์ยังไม่ฉลาดพอที่จะมีประโยชน์จริง
      ด้านบนของโค้ดที่สร้างขึ้นจะมีฟังก์ชันช่วยแบบ hardcode ติดมาจำนวนมาก และโปรแกรมก็ช้ากว่าการเขียนเนื้อหาเดียวกันด้วย Python แบบธรรมดามาก
      ในทางกลับกัน Hy สร้างโค้ดที่ค่อนข้างใกล้กับโค้ด Python ที่คนอาจเขียนด้วยมือ ยกเว้นเรื่องชั้นทางอ้อมเล็กน้อยที่เกิดจากการจัดการสโคปของ let หรือความต่างบางอย่างรอบ ๆ ค่าที่คืนกลับมา ทั้งนี้ Coconut ก็ผ่านมานานแล้ว อาจจะดีขึ้นก็ได้
  • ยินดีด้วย มีสองอย่างที่สงสัย: รองรับ การพัฒนาแบบ REPL-driven ไหม เช่น มี condition system หรือ breakloop อะไรแบบนั้นหรือเปล่า
    อีกอย่างคือมี distribution แบบ standalone ไหม เพราะการแจกจ่าย Python เองก็ค่อนข้างยุ่งยาก ดังนั้นในอุดมคติแล้วถ้าสามารถแจกจ่ายเป็นไบนารี Hy ไฟล์เดียวที่รวม dependency ทั้งหมดไว้ได้ก็น่าจะดี จะเป็น static link หรือไฟล์ zip ที่แตกไปยังไดเรกทอรีชั่วคราวก็ได้

    • แม้จะไม่ใช่ distribution แบบ standalone แต่สามารถเข้า Hy REPL ได้ด้วย uvx hy@1.0.0
      ถ้ารัน echo '(print "hi hn")' > hi.hy แล้วตามด้วย uvx hy@1.0.0 hi.hy ก็จะพิมพ์ "hi hn" ออกมา
      https://docs.astral.sh/uv/guides/tools/#running-tools
      และ uv ก็สามารถติดตั้งและจัดการเวอร์ชัน Python ได้ด้วย
    • ไม่ค่อยแน่ใจว่า breakloop คืออะไร Hy ใช้ ระบบข้อยกเว้น ของ Python ซึ่งใกล้กับระบบข้อยกเว้นแบบดั้งเดิมมากกว่าระบบ condition ของ Common Lisp
      ไม่มี distribution แบบ standalone
    • มีข้อมูลที่เกี่ยวข้องอยู่ในเอกสาร REPL: https://hylang.org/hy/doc/v1.0.0/repl
      ถ้าต้องการดีบักโค้ดแบบโต้ตอบ สามารถใส่ (.run (hy.REPL :locals {#\* (globals) #\* (locals)})) ลงในโค้ดที่ต้องการดีบักได้ และใน Python ก็ใช้ได้ในลักษณะ import hy; hy.REPL(locals = {\*globals(), \*locals()}).run()
      แต่เช่นเดียวกับ code.interact() ต่อให้เปลี่ยนตัวแปร local ภายใน REPL ก็จะไม่กระจายกลับไปยังสโคปเดิม
    • เคยทำอะไรที่ใกล้เคียงกับข้อ 2 ด้วย py2app และการแฮ็กอย่างระมัดระวัง
      สามารถคอมไพล์ทุกอย่างเป็น bytecode แล้วใช้ เครื่องมือแจกจ่ายแบบไฟล์เดียว ของ Python ได้
    • Hy รองรับชุดความสามารถเดียวกับที่ Python รองรับ การดีบักแบบทีละขั้นดั้งเดิมหรือการดีบักหลังเกิดเหตุทำได้ค่อนข้างดี และ CPython ก็มี internal hook ขั้นสูงอีกหลายอย่าง
      แต่ไม่มี condition system หรือ handlers/restarts
  • ชอบส่วนที่จริงจังน้อย ๆ มาก อยากให้โปรเจกต์เขียนโปรแกรมอื่น ๆ เปิดรับ ความขี้เล่น มากกว่านี้
    บางทีนั่นอาจเป็นวิธีที่ดีที่สุดในการให้เกียรติขนบของ Python ก็ได้

    • เมื่อหลายปีก่อน ได้เอาองค์ประกอบขี้เล่นออกจาก Hy และเอกสารไปเยอะพอสมควร เพราะมันทำให้เสียสมาธิและทำให้ข้อความทดสอบล้มเหลวดูหนวกหู
      แต่พอถึงจุดหนึ่งก็รู้สึกว่าไปไกลเกินไป เลยช่วงหลัง ๆ พยายามใส่ความขี้เล่นกลับเข้ามาอีกเล็กน้อย
  • ใช้ Hy แบบเป็นครั้งคราวมาเรื่อย ๆ และตอนที่พยายามสร้าง transformer ก็ได้ปล่อย https://github.com/kunalb/orphism ที่เขียนด้วย Hy ออกมาด้วย
    ดูเหมือนว่าจะถึงเวลาหยิบมันกลับมาลองรันอย่างจริงจังอีกครั้งแล้ว