2 คะแนน โดย GN⁺ 2024-11-29 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Janet for Mortals เป็นหนังสือออนไลน์ฟรีเกี่ยวกับภาษาโปรแกรม Janet แต่บทความย้อนมองนี้โฟกัสที่กระบวนการสร้างหนังสือเชิงเทคนิคทั้งชุด มากกว่าตัวหนังสือเอง รวมถึงเว็บ REPL และโปรเจ็กต์ตัวอย่างต่างๆ
  • งานทั้งหมดใช้เวลา 20 สัปดาห์ นานกว่าที่คาดไว้สำหรับการเขียนล้วนๆ ที่ 12 สัปดาห์ เพราะมีงานเสริมอย่างเว็บไซต์, C++ binding, เดโมบนเบราว์เซอร์, ตัวแยกพารามิเตอร์ CLI และเครื่องมือทดสอบเพิ่มเข้ามา
  • เว็บไซต์หนังสือมี REPL ในตัวที่ใช้ CodeMirror และไวยากรณ์ Lezer พร้อมระบบเติมคำอัตโนมัติที่ตรวจสอบสภาพแวดล้อม Janet ผ่าน WebAssembly และ (report) จะบันทึกฟีดแบ็กลง SQLite
  • cmd, judge, to do, และ Toodle.Studio ถูกใช้เป็นกรณีตัวอย่างพื้นฐานที่แสดงให้เห็นว่า Janet ใช้ได้กับ งานสคริปต์, เครื่องมือ CLI, การทดสอบ, การรันในเบราว์เซอร์ และการทำงานร่วมกับ JavaScript
  • หลังเปิดตัวไม่นาน เพียงส่งไปที่ Hacker News และ Lobsters ก็มีผู้เยี่ยมชมไม่ซ้ำ 30,025 คนในวันศุกร์, 9,568 คนในวันเสาร์, และ 3,777 คนในวันอาทิตย์ แต่คาดว่ามีเพียง 387 IP ที่อ่านเกิน 5 บทขึ้นไป

ขอบเขตของหนังสือและปริมาณงานจริง

  • Janet for Mortals เป็นหนังสือออนไลน์ฟรีเกี่ยวกับภาษาโปรแกรม Janet
  • ระยะเวลาการผลิตทั้งหมดคือ 20 สัปดาห์ หากนับจากเวลาว่าง
    • ตอนแรกคาดไว้ 12 สัปดาห์ และถ้าดูเฉพาะเวลาเขียนต้นฉบับภาษาอังกฤษจริงๆ ก็ไม่ได้คลาดเคลื่อนไปมาก
    • แต่กำหนดการจริงรวมโปรเจ็กต์โค้ดรอบๆ หนังสืออยู่มาก
  • ความยาวสุดท้ายอยู่ที่ ร้อยแก้วภาษาอังกฤษ 44,000 คำ ไม่นับโค้ดตัวอย่าง
    • หนังสือ The Great Gatsby ที่ยกมาเปรียบเทียบมี 47,000 คำ
    • สั้นกว่าชุดบทความเกี่ยวกับ Nix ก่อนหน้านี้ไม่ถึงครึ่ง
  • ตลอด 5 เดือนนั้น นอกจากหนังสือแล้วยังทำสิ่งต่อไปนี้ไปพร้อมกัน
    • เว็บไซต์หนังสือ
    • jimmy: binding สำหรับไลบรารีโครงสร้างข้อมูลแบบคงอยู่ถาวรของ C++
    • Toodle.Studio: playground แบบโต้ตอบสำหรับ turtle graphics
    • cmd: ไลบรารีแยกพารามิเตอร์บรรทัดคำสั่ง
    • judge: เฟรมเวิร์กทดสอบแบบ inline snapshot
    • to do: ตัวจัดการรายการสิ่งที่ต้องทำบนบรรทัดคำสั่ง

เว็บไซต์และ REPL ในตัว

  • องค์ประกอบหลักของเว็บไซต์ Janet for Mortals คือ REPL ในตัว
    • ผู้ใช้สามารถกดปุ่ม Escape เพื่อเปิด REPL ได้ทุกเมื่อ
    • REPL ถูกตรึงไว้ด้านล่างของหน้า จึงไม่บังเนื้อหาหลักมากนัก
  • ตัวแก้ไขใช้ CodeMirror
    • โดยปกติ CodeMirror ไม่รองรับ Janet
    • จึงใช้ต่อยอดจากงานรองรับภาษา Janet ที่เคยทำไว้ตอนทำ Bauble
    • ไวยากรณ์ Janet อย่างสตริงแบบ multi`backtick`quoted ซึ่งไม่สำคัญใน Bauble DSL กลับจำเป็นสำหรับหนังสือ
  • ระหว่างเสริมไวยากรณ์ Lezer ที่ CodeMirror ใช้ ก็ได้นำไวยากรณ์เดียวกันกลับมาใช้กับ syntax highlighting ของโค้ดในหนังสือด้วย
    • ไม่พบ static site generator ที่รู้จักตัวไหนรองรับการไฮไลต์โค้ด Janet
    • ตอนแรกหนังสือเป็นขาวดำ แต่ภายหลังก็เพิ่มสีเพื่อให้ไวยากรณ์ Janet ที่ไม่คุ้นตาดูเข้าถึงง่ายขึ้น
  • static site generator ถูกเขียนขึ้นเองโดยใช้ redo
    • แกนหลักของตัวสร้างเขียนด้วย JavaScript จึงสามารถเชื่อม Lezer grammar เข้าไปได้
    • โครงสร้างโดยรวมค่อนข้างเปราะบางและยึดโยงกันด้วย shell
  • Remark ถูกใช้ทั้งในการ parse ต้นฉบับหนังสือและใน REPL ฝั่งไคลเอนต์
    • มีการเพิ่มส่วนขยายเล็กๆ เพื่อใส่ป้ายกำกับให้ code block
    • docstring ของไลบรารีมาตรฐาน Janet เขียนเป็น Markdown จึงเรนเดอร์เป็น HTML แบบทันทีในระบบเติมคำอัตโนมัติของ REPL

การเติมคำอัตโนมัติและฟีดแบ็กทางเดียว

  • ระบบเติมคำอัตโนมัติของ REPL ถูกให้ความสำคัญมาก เพราะผู้อ่านจำนวนมากเพิ่งรู้จัก Janet เป็นครั้งแรก
    • ตอนเริ่ม REPL จะตรวจสอบสภาพแวดล้อม Janet แบบไดนามิกผ่าน WebAssembly
    • แม้ผู้ใช้จะนิยามสัญลักษณ์ใหม่พร้อม docstring แต่ผลการเติมคำอัตโนมัติจะไม่แสดงสิ่งนั้น
    • แม้จะสามารถสร้างข้อมูลเติมคำอัตโนมัติใหม่ทุกครั้งหลังรันคำสั่งได้ แต่ตัดสินใจว่าไม่คุ้มกับความซับซ้อน
  • ฟังก์ชัน (report) รับสตริงแล้วส่ง POST ไปยังเว็บเซิร์ฟเวอร์อย่างง่าย ซึ่งเซิร์ฟเวอร์จะบันทึกลงฐานข้อมูล SQLite
    • แนวคิดคล้ายกล่องคอมเมนต์ แต่จุดเด่นคือส่งได้ตรงจาก REPL
    • ฟีเจอร์นี้ช่วยให้ได้อ่านฟีดแบ็กและแก้ข้อผิดพลาดหลายจุด
    • ไม่มีการทำระบบตอบกลับไว้
  • backend ของ report ไม่ได้เขียนด้วย Janet แต่เป็นแอปพลิเคชัน Haskell ขนาดเล็ก
    • หน้าที่มีเพียงรับคำขอ POST แล้วบันทึกลง SQLite
  • เว็บเซิร์ฟเวอร์ไม่ได้สร้างด้วย Janet
    • มองว่าความปลอดภัยคือองค์ประกอบสำคัญที่สุดของเว็บเซิร์ฟเวอร์
    • และยังไม่มั่นใจว่า Janet กับไลบรารี HTTP ของ Janet ผ่านการพิสูจน์มากพอจะเปิดรับอินเทอร์เน็ตโดยตรง

jimmy: การทดลองด้านการทำงานร่วมกับ C++

  • jimmy คือ binding ของ Janet สำหรับ immer
    • immer เป็นไลบรารีโครงสร้างข้อมูลแบบคงอยู่ถาวร
  • binding นี้ยังไม่เสร็จสมบูรณ์ และมีแนวโน้มว่าจะยังไม่ถูกทำต่อจนกว่าจะมีงานที่ต้องใช้จริง
  • ถึงอย่างนั้นก็ถือว่าประสบความสำเร็จในฐานะตัวอย่างที่แสดงวิธีให้ Janet ทำงานร่วมกับโค้ด C++

Toodle.Studio และ Janet ในเบราว์เซอร์

  • Bauble เป็น playground ศิลปะขนาดเล็กที่เคยทำไว้ก่อนหน้านี้ และเป็นประสบการณ์แรกของการฝัง Janet ลงในเบราว์เซอร์
    • ตอนนั้นแทบไม่มีข้อมูลอ้างอิงเรื่องการ embed Janet
    • และต้องใช้ทั้ง WebAssembly, Emscripten และ TypeScript ในเบราว์เซอร์ จึงมีความยากสูง
  • ผลลัพธ์สุดท้ายของ Bauble คือเว็บไซต์ที่ลอจิกของแอปพลิเคชันเขียนด้วย Janet
    • แม้ UI จะใช้ JavaScript มาก แต่ลอจิกหลักอยู่ที่ Janet
  • หนึ่งในแรงจูงใจสำคัญของการเขียนหนังสือคืออยากทำให้เทคนิคการใช้ Janet ในเบราว์เซอร์เข้าถึงได้มากขึ้น
  • ในหนังสือจึงเลือกทำ Toodle.Studio เป็นตัวอย่างแทน Bauble
    • Bauble แทบไม่มี state และใกล้เคียงกับฟังก์ชันบริสุทธิ์ที่แปลงสตริงเป็นสตริง จึงค่อนข้างง่ายในแง่มุมของการทำงานร่วมกัน
    • Toodle.Studio เป็น fork ของ Bauble อย่างชัดเจน แต่มีการทำงานร่วมระหว่าง JavaScript กับ Janet ที่ซับซ้อนกว่า
  • Toodle.Studio มีองค์ประกอบทางเทคนิคที่เหมาะจะเป็นตัวอย่างในหนังสือมากกว่า
    • ต้องรันโปรแกรม Janet ที่ทำงานนานแบบ asynchronous ตามช่วงเวลา
    • โค้ด JavaScript ต้องถืออ้างอิงหลายตัวไปยังค่า Janet ตัวเดียวกัน จึงต้องคำนึงถึง การจัดการหน่วยความจำ
    • ต้องส่งโครงสร้างข้อมูลซ้อนกันที่ซับซ้อนไปมาระหว่าง Janet ผ่าน C++
  • โลโก้ของ Toodle.Studio คือเต่าแอนิเมชันที่สร้างด้วย Bauble
    • เดิมมีฟีดแบ็กว่าเป็นเดโม turtle graphics แต่ไม่มีเต่า จึงเพิ่มเข้าไป
    • และทำให้ดวงตาของมันมองตามเมาส์ได้

cmd: ตัวแยกอาร์กิวเมนต์ CLI สำหรับ Janet

  • cmd เป็นไลบรารีแยกพารามิเตอร์บรรทัดคำสั่ง
    • ในหนังสือมีพูดถึงเพียงราวสามย่อหน้า แต่จำเป็นเพื่อแสดงให้ชัดว่า Janet เป็นภาษาสำหรับ งานสคริปต์ ที่ดี
  • cmd ได้รับอิทธิพลอย่างมากจาก Core.Command ของ OCaml
    • มองว่า Core.Command เป็นไลบรารีแยกอาร์กิวเมนต์บรรทัดคำสั่งที่ดีที่สุดเท่าที่เคยใช้มา
    • จึงพยายามถ่ายทอดประสบการณ์นั้นมาสู่ Janet
  • cmd อาจยังไม่ดีเท่า Core.Command
    • เพราะเมื่อมี type แล้ว ทุกอย่างจะง่ายขึ้นมาก
    • แต่ก็ยังมีฟีเจอร์ 95% ของสิ่งที่เห็นว่าสำคัญ และด้วยรูปแบบที่กระชับจึงใช้งานกับสคริปต์ ad-hoc ได้สะดวกกว่า
  • ตอนนี้ยังไม่มีฟีเจอร์สร้างฟังก์ชัน Bash autocomplete
    • ขณะที่ Core.Command สร้างสิ่งนี้ได้อัตโนมัติ
    • API ของ cmd ถูกออกแบบไว้ให้เพิ่มความสามารถนี้ในภายหลังได้

judge: เฟรมเวิร์กทดสอบแบบ inline snapshot

  • judge เป็นหนึ่งในสิ่งแรกๆ ที่ทำด้วย Janet ในปี 2021
  • หลังจากเข้าใจ Janet มากขึ้น ก็ได้ เขียนใหม่ทั้งหมดตั้งแต่ต้น
    • API ใช้งานได้ดีขึ้น
    • implementation ก็เรียบง่ายขึ้นมากและแก้ไขเปลี่ยนแปลงได้ง่ายกว่าเดิม
  • ความต่างหลักระหว่าง Judge v1 กับ v2 คือที่อยู่ของเทสต์และ helper
    • เทสต์ไม่จำเป็นต้องอยู่แค่ในไดเรกทอรี test/ แต่ใส่ไว้ในไฟล์ซอร์สปกติได้ด้วย
    • มีการเพิ่ม helper test-macro และ test-stdout
  • ผู้เขียนบอกว่าแนวทางใน OCaml ที่สอดคล้องกับ test-stdout แทบเป็นวิธีเดียวที่ใช้เวลาต้องเขียนเทสต์ในงานจริง
    • OCaml ไม่มีวิธีเหมาะๆ สำหรับฝังข้อมูลตามอำเภอใจลงในซอร์สโค้ด จึงใช้แนวทางแปลงทุกอย่างเป็นสตริง
  • หลังหนังสือออก ก็ได้เพิ่มโหมด --interactive ให้ Judge

to do: เครื่องมือจัดการงานที่เขียนด้วย Janet แทน Bash

  • to do ถูกเลือกเป็นตัวอย่างในบทสคริปต์
    • เดิมเป็นเครื่องมือที่เคยทำด้วย Bash และเป็นเครื่องมือที่ไม่ใช่งานเล็กน้อย
    • implementation ฝั่ง Bash นั้นทรมานมาก
  • ส่วนที่ยากเป็นพิเศษใน Bash คือการ parse ข้อความและจัดการวันที่
    • การ parse ข้อความหลายบรรทัดด้วย Sed ไม่ใช่เรื่องสนุก
    • และการจัดการ date ให้ทำงานแบบเดียวกันทั้งบน macOS และ Linux แทบเป็นไปไม่ได้
  • ใน Janet ใช้ทั้ง PEG, sh, และ cmd เพื่อทำเครื่องมือที่มีฟีเจอร์มากกว่าเดิมได้เร็วกว่าเวอร์ชัน Bash
    • ตัวอย่างเช่นเพิ่มความสามารถเลือกหลายรายการด้วย fzf
    • ใน Bash การประกอบสตริงแบบ null-terminated เป็นเรื่องยาก
  • ในหนังสือกล่าวถึงเพียงเวอร์ชันที่ลดความซับซ้อนแล้ว
    • ไม่มีฟีเจอร์ตั้งเวลางานไว้ในอนาคต
    • ไม่มีแนวคิดเรื่อง “ข้าม” งาน
    • ฟีเจอร์หลักคือเพิ่มรายการและทำเครื่องหมายว่าเสร็จแล้ว
  • เมื่อนำไปใช้คู่กับ zsh-autoquoter ก็ถือว่าเป็นแอปที่มีประโยชน์เกินคาด

งานโค้ดระหว่างการเขียนและการดูแลรักษา

  • จาก 20 สัปดาห์ของการทำหนังสือ เวลาที่ใช้เขียนโค้ดคิดเป็นเกือบครึ่งหนึ่ง
    • 8 สัปดาห์ เป็นงานโค้ด และในบางช่วงก็เขียนหนังสือกับเขียนโค้ดไปพร้อมกัน
  • ตอนแรกคาดว่าจะต้องแค่ปรับปรุง Judge และเขียนตัวแยกอาร์กิวเมนต์
    • แต่การทำตัวแยกอาร์กิวเมนต์ยากกว่าที่คิดมาก
    • และก็ไม่คาดว่า Bauble จะเรียบง่ายเกินไปจนต้องสร้าง playground ศิลปะใหม่อีกตัว
  • การเขียนจริงใช้ Markdown ใน Sublime Text
    • Sublime Text เป็นเอดิเตอร์ที่ชอบใช้สำหรับงานเขียนยาวๆ
  • ระหว่างเขียน มี Janet ออกรุ่นใหม่ 2 รุ่น
    • จึงต้องอัปเดตบทดีบักและ native module ให้สอดคล้องกับการเปลี่ยนแปลงของภาษา
    • มีแผนจะดูแลหนังสือให้ตามทัน Janet รุ่นล่าสุดต่อไป

กระแสตอบรับหลังเปิดตัวและระดับการอ่านจริง

  • การโปรโมตหนังสือมีเพียงการส่งไป Hacker News, ส่งไป Lobsters และทวีต
    • บน Hacker News หนังสืออยู่หน้าแรกตลอดทั้งวัน และขึ้นอันดับ 1 อยู่ช่วงหนึ่ง
  • จาก access log ของ Nginx จำนวนผู้เยี่ยมชมไม่ซ้ำมีดังนี้
    • วันศุกร์: 30,025 คน
    • วันเสาร์: 9,568 คน
    • วันอาทิตย์: 3,777 คน
  • ตัวเลขนี้น่าจะใกล้เคียงกับจำนวนคนที่กดลิงก์ มากกว่าจำนวนคนที่อ่านหนังสือจริง ซึ่งน้อยกว่านั้นมาก
  • เว็บไซต์ไม่มีระบบวิเคราะห์พฤติกรรมฝั่งไคลเอนต์
    • จึงประเมินคร่าวๆ ได้จาก access log เท่านั้น
  • ลำดับการเข้าชมแต่ละบทดูเหมือนจะมีอัตราคงอยู่ไม่ดีนัก
    • บทที่ 1 มีผู้เข้าชม 22% ของผู้ที่เข้าโฮมเพจ
    • บทที่ 2 มีผู้เข้าชม 20% ของผู้ที่เข้าบทที่ 1
    • บทที่ 3 มีผู้เข้าชม 69% ของผู้ที่เข้าบทที่ 2
    • บทที่ 4 “Pegular Expressions” และบทที่ 9 “Xenofunctions” มีผู้เข้าชมมากกว่าบทที่ 3
  • เมื่อสิ้นสุดสุดสัปดาห์แรกหลังเปิดตัว การประเมินที่ดีที่สุดของจำนวนผู้อ่านจริงคือ 387 คน
    • ใช้จำนวน IP ไม่ซ้ำที่โหลดบทที่แตกต่างกันตั้งแต่ 5 บทขึ้นไปเป็นเกณฑ์

ที่มาของชื่อและข้อจำกัดที่เห็นจากฟีดแบ็ก

  • ชื่อภาษา Janet มาจาก Janet สิ่งมีชีวิตอมตะใน The Good Place
    • ตัวละครนี้ช่วยเหล่า mortals ที่เดินทางในโลกหลังความตาย จึงเชื่อมโยงกับชื่อหนังสือด้วย
  • บทที่มีผู้เข้าชมน้อยที่สุดคือ “Testing and Debugging”
    • เป็นบทที่สามจากท้ายเล่ม
    • ผู้เขียนมองว่าสามบทสุดท้ายคือส่วนที่น่าสนใจที่สุดของหนังสือ
    • และวิธีทดสอบในบทนั้นเป็นหนึ่งในตัวเพิ่มประสิทธิภาพการทำงานที่สำคัญที่สุดในชีวิตวิศวกรของตน
  • ได้รับฟีดแบ็กผ่านฟังก์ชัน report ใน REPL ในตัวทั้งหมด 494 รายการ
    • จำนวนมากเป็นข้อความแนว “หนังสือดี” หรือข้อความทดสอบ
    • อีกหลายสิบรายการเป็นการแจ้งคำผิด ขอคำอธิบายเพิ่มเติม หรือคอมเมนต์ที่มีประโยชน์
  • ผู้ใช้บางคนส่งคำถามมาโดยไม่ทิ้งช่องทางติดต่อ และเพราะไม่มีฟังก์ชันตอบกลับจึงไม่สามารถตอบได้
    • ฟังก์ชัน report ถูกสร้างเป็นระบบฟีดแบ็กทางเดียวแบบดิบๆ มาก

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

 
GN⁺ 2024-11-29
ความคิดเห็นบน Hacker News
  • ของผู้เขียนคนเดียวกันอย่าง https://bauble.studio/ ก็พลาดไม่ได้เช่นกัน
    มันไม่ทำงานในเบราว์เซอร์บนคอมพิวเตอร์เก่าของผม แต่เวลาอ่านหนังสือที่ห้องสมุดแล้วอยากพัก ผมมักจะไปเล่นกับ bauble บนคอมพิวเตอร์ของห้องสมุดสักครึ่งชั่วโมง
    แค่ปรับตัวเลขไปมาก็สร้างกราฟิกได้มหาศาล และหวังว่า Janet จะอยู่ไปนาน ๆ

    • บน MacBook Pro M1 Max รุ่นปี 2021, MacOs 15.1.1 มันทำงานใน Chrome แต่ใน Firefox เกิดข้อผิดพลาดคอมไพล์ unknown symbol twist
      error: script:16:1: compile error: unknown symbol twist
      in evaluate [lib/evaluator.janet] on line 81, column 7
      in bauble-evaluator/evaluate [lib/init.janet] on line 8, column 12
  • การลองเปรียบเทียบ Janet กับ GNU Guile น่าสนใจ
    จุดแข็งดั้งเดิมของ Guile คือเป็นภาษาที่ทำให้นำไปใช้เคียงข้าง C ได้ง่าย แต่เพราะเป็นภาษาที่เก่าแล้ว จึงดูเหมือนยังรับแนวคิดสมัยใหม่อย่างการมี package manager เป็นส่วนหนึ่งของ toolchain ภาษาโดยค่าเริ่มต้นได้ไม่เต็มที่
    สิ่งที่ชอบใน Guile คือมันทุ่มเทมากในการอธิบายความเข้ากันได้กับ มาตรฐาน RNRS
    ไม่รู้ว่าในทางปฏิบัติ Janet มีความเป็น Scheme แค่ไหน แต่ก็สงสัยอยู่

    • Janet ไม่ได้เหมือน Scheme เลย
      มันใกล้เคียงกับการที่ใครสักคนสร้าง Clojure บน Lua มากกว่า
  • หนังสือคือ https://janet.guide/ และภาษาคือ https://janet-lang.org/

  • ผมชอบ แนวทางที่ใช้งานได้จริง ของหนังสือเล่มนี้ และนั่นเป็นเหตุผลใหญ่ที่ตอนนี้กำลังเรียนด้วยการแก้ Everybody Codes ด้วย Janet
    https://everybody.codes

  • สำนวนว่า “เต่าเป็นอุปมา” น่าเสียดายอยู่
    เต่าไม่ใช่อุปมา แต่เคยเป็นของจริง: http://classicacorn.computinghistory.org.uk/8bit_focus/logo/...
    แน่นอนว่ามันเข้ากับนิยามของอุปมาที่ว่า “สิ่งใดสิ่งหนึ่งที่แทนสิ่งอื่น เป็นสัญลักษณ์” แต่ฟังดูเหมือนมุกที่เข้าใจไอคอนบันทึกแบบฟลอปปีดิสก์ผิดว่าเป็นตู้เย็น
    เหมือนขาดบริบทไปว่าเมื่อก่อนเคยมี เต่าฮาร์ดแวร์ ที่สนุกและน่ารักจริง ๆ

    • สิ่งที่เห็นในหน้านั้นดูจะเรียกว่าเป็นเต่า “ของจริง” ได้ยากนะ
  • เห็นแค่ชื่อเรื่อง นึกว่าเป็นผู้ช่วย AI อีกตัวที่เอามาจาก Janet ใน The Good Place แต่กลายเป็นว่าจริง ๆ แล้วเป็นภาษาโปรแกรมมิง เลยประหลาดใจแบบดี ๆ
    ภาษา Janet ตั้งชื่อตาม Janet สิ่งมีชีวิตอมตะใน The Good Place ที่ช่วยมนุษย์นำทางชีวิตหลังความตาย ดังนั้นชื่อเรื่องจึงเป็นมุกที่ฉลาดและเข้ากันดี
    อีกอย่างที่คาดไม่ถึงคือมันให้ PEG (Parsing Expression Grammar) มาพร้อมกัน แทนที่จะมีแค่เอนจิน regular expression พื้นฐาน
    ผมหวังมาตลอดว่าถ้าภาษาไหนมีไลบรารี regular expression พื้นฐาน ก็ควรใส่ PEG ที่ดี ๆ มาด้วย

    • GNU Guile ก็มี ไลบรารี PEG ในไลบรารีมาตรฐาน
      ดู <https://www.gnu.org/software/guile/manual/html_node/PEG-Pars...>
    • โมดูล spork ของ Janet อยู่ในตำแหน่งคล้าย libc แบบหนึ่ง และมีซับโมดูล regular expression ด้วย จึงมีโอกาสสูงว่าจะติดตั้งอยู่แล้ว
      ผมรู้จัก PEG ครั้งแรกผ่าน Janet และชอบตรงที่มันทรงพลังและใช้ง่าย
      ผมแตะ regular expression มานิด ๆ หน่อย ๆ กว่า 20 ปีแล้ว แต่กลับเข้าใจ PEG ได้ดีกว่าภายในไม่กี่เดือน
      ในชุมชน Janet มีการอ้างอิงถึง The Good Place อยู่มาก และโมดูล third-party หลายตัวก็ตั้งชื่อตามตัวละคร
    • Elm ก็ใช้แนวทางคล้ายกัน
      elm/regex กับ elm/parser ไม่ได้ถูก built-in แต่ elm/regex แนะนำให้ใช้ elm/parser แทน
      ผมชอบที่มาของชื่อ แต่ถ้าเป็นภาษาที่ชื่อ Janet ก็ดูเหมือนมีหน้าที่ต้องให้ความสำคัญกับการควบคุมก่อนด้วย
  • ผมอ่านหนังสือแล้ว มันค่อนข้างน่าสนใจและมีอารมณ์ขี้เล่น ทำให้ การเรียน Janet สนุกขึ้นมาก
    แต่เอกสารของภาษายังขาดอยู่หลายด้าน
    ฟังก์ชันหรือคำสั่งมักถูกลิสต์ไว้เฉย ๆ โดยไม่มีตัวอย่างหรือคำอธิบาย หรือบางทีก็ขาดคำอธิบายว่ามันทำอะไร
    หลายครั้งผมหาฟีเจอร์ที่เห็นในหนังสือไม่เจอในเอกสาร และนั่นก็เป็นหนึ่งในเหตุผลที่ทำให้ผมหยุดเรียน ทั้งที่ชอบ Janet
    ผมชอบตรงที่มีค่าเริ่มต้นที่สมเหตุสมผลหลายอย่าง และมีส่วนที่คล้ายภาษากระแสหลักมากกว่าจะยึดติดกับธรรมเนียม Lisp เก่า ๆ
    สุดท้ายแล้วมันไม่ใช่ cons list ดังนั้นจริง ๆ ก็ไม่ใช่ Lisp แต่นั่นไม่เป็นไร
    ปัญหาคือภาษายังมีเอกสารไม่เพียงพอ

    • อยากรู้ว่ายังจำฟังก์ชันหรือคำสั่งที่ไม่ได้ถูกทำเอกสารไว้ได้ไหม
      ผมค่อนข้างมีส่วนร่วมในชุมชน Janet อยู่บ้าง ถ้ารู้ว่าตรงไหนขาด ก็อาจช่วย ปรับปรุงเอกสาร ได้
    • ผมมีประสบการณ์เหมือนกันเลย ยกเว้นแค่ว่าไม่ได้อ่านหนังสือ
      บ่อยครั้งมีแค่ signature ของฟังก์ชันโดยไม่มีคำอธิบายเพิ่มเติมเลย
      ผมเข้าใจว่าการทำเอกสารให้ครอบคลุมต้องใช้เวลาและแรงมาก แต่เรื่องแบบนี้เกิดขึ้นบ่อยเกินไป จนผมวางมันลงแล้วเริ่มมองหา Lisp ตัวอื่นที่คอมไพล์เป็นไบนารีได้
  • ผมปรับตัวกับ Janet ได้ไม่ค่อยดี แต่ก็ไม่รู้ว่าเป็นปัญหาของผมหรือเปล่า
    Lisp อีกตัวเดียวที่ผมเคยใช้มานานคือ Emacs Lisp และ Janet ก็คล้ายพอ แต่ต่างกันเล็ก ๆ น้อย ๆ จนทำให้ผมพลาดเรื่องจุกจิกอยู่เรื่อย ๆ
    ฟีเจอร์ PEG ดูน่าดึงดูดบนเอกสาร แต่ไวยากรณ์ใช้งานไม่สะดวกและชวนสับสน
    เอกสารครบในความหมายที่ว่ามีคำอธิบายของทุกฟังก์ชัน แต่ก็สั้นมาก ขาดตัวอย่างหรือข้อมูลการใช้งานที่เป็นประโยชน์
    ดูเหมือนฟีเจอร์พื้นฐานอย่างการ parse JSON ก็ไม่ได้รวมมาให้
    ถ้าภาษาที่ตั้งใจใช้เขียนสคริปต์เร็ว ๆ ทำให้ต้องเขียน parser สำหรับ JSON หรือ XML ก่อน งานนั้นก็ล้มเหลวไปแล้ว
    นั่นเป็นเรื่องเมื่อราว 4 ปีก่อน ระบบนิเวศอาจดีขึ้นแล้วก็ได้ และเกณฑ์ที่ผมใช้ประเมิน Janet ในฐานะภาษาสคริปต์อาจผิดเองก็ได้
    ถึงอย่างนั้นพอเห็นบทความนี้แล้วก็อยากลองติดตั้งใหม่อีกครั้ง

    • ของอย่าง JSON และ regular expression ถูกใส่ไว้ในโมดูล spork ซึ่งอยู่ในตำแหน่งคล้าย libc แบบหนึ่ง
      ภายในมีแนวโน้มแรงที่จะรักษาแกนหลักให้เบา
      หลายโปรเจกต์พึ่งพา spork ดังนั้นมีโอกาสสูงว่าจะถูกติดตั้งตั้งแต่ต้น
      เอกสารถือว่าใช้ได้ แต่เห็นด้วยว่ายังมีช่องว่างในด้านตัวอย่างเชิงปฏิบัติ
      ส่วนนี้ https://janetdocs.com กำลังช่วยเติมเต็ม โดยลิงก์ไปยัง “ตัวอย่างจากชุมชน” สำหรับแต่ละฟังก์ชัน
  • นอกเรื่องนิดหน่อย แต่บทความบล็อกอีกชิ้นของต้นฉบับทำให้ผมหันมาใช้ คีย์บอร์ดกลไกแบบแยกชิ้น
    ผมมีอาการปวดไหล่และข้อมือมาหลายปี และมันช่วยได้ จึงขอแนะนำอย่างยิ่งให้ลองดูบทความอื่น ๆ ของ Ian ด้วย

  • วิธีที่กด Esc ได้ทุกเมื่อเพื่อเปิด REPL ในตัว ที่ติดอยู่ด้านล่าง อาจไม่ใช่การตัดสินใจที่ดี
    เบราว์เซอร์มีคีย์ลัด Esc ตามค่าเริ่มต้นอยู่แล้ว และ Firefox จะออกจากโหมดเต็มหน้าจอเมื่อกด Esc