1 คะแนน โดย GN⁺ 2026-01-09 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • หัวใจสำคัญของประสิทธิภาพการเขียนโปรแกรมคือ ระบบนิเวศของไลบรารีที่อุดมสมบูรณ์มากกว่าตัวภาษาเอง
  • เฟรมเวิร์กที่ ใช้ความสามารถขั้นสูงของภาษา อย่าง Ruby on Rails มอบประสิทธิภาพสูงได้แม้กับผู้ที่ไม่ใช่ผู้เชี่ยวชาญ
  • แต่เพราะ ข้อจำกัดเชิงโครงสร้างของภาษา จึงยากที่จะสร้างเฟรมเวิร์กระดับ Rails ด้วย Java หรือ C
  • การออกแบบภาษาเป็นตัวกำหนดโดยตรงถึงรูปแบบและความซับซ้อนของไลบรารีที่สามารถเขียนได้ และนี่คือเป้าหมายที่แท้จริงของวิวัฒนาการภาษา
  • ภาษา Stanza แสดงให้เห็นความสำคัญของการออกแบบภาษาที่ทำให้สามารถสร้างไลบรารีทรงพลังและใช้งานง่ายได้จากมุมมองนี้

ความสัมพันธ์ระหว่างภาษาโปรแกรมกับไลบรารี

  • ภาษาโปรแกรมส่วนใหญ่มีองค์ประกอบพื้นฐานคล้ายกัน เช่น ตัวแปร อาร์เรย์ ลูป และฟังก์ชัน
    • บางภาษามีความสามารถขั้นสูงอย่าง first-class functions หรือ coroutines แต่ผู้ใช้ที่ไม่ใช่ผู้เชี่ยวชาญมักไม่ได้ใช้งานสิ่งเหล่านี้มากนัก
  • สำหรับนักพัฒนาจำนวนมาก ปัจจัยที่ช่วยเพิ่มประสิทธิภาพคือ ไลบรารีมากกว่าตัวภาษา
    • ตัวอย่างเช่น Ruby on Rails ช่วยให้สร้างเว็บแอปพลิเคชันที่ทำงานกับฐานข้อมูลได้อย่างง่ายดาย
    • ด้วย Rails ผู้คนจึงมักชอบ เฟรมเวิร์กมากกว่าตัวภาษา Ruby เอง

ปฏิสัมพันธ์ระหว่าง Ruby on Rails กับความสามารถของภาษา

  • Rails ใช้ความสามารถหลากหลายของ Ruby เช่น metaprogramming, runtime evaluation, first-class functions, garbage collection
    • ตัวอย่าง: ActiveRecords ใช้ metaprogramming ส่วนระบบเทมเพลตใช้ runtime evaluation
    • การจัดการอีเวนต์ถูกทำผ่านการส่ง first-class functions เป็น callback
  • ใน Java หรือ C ความสามารถเหล่านี้มีไม่พอ จึง ไม่สามารถสร้างเฟรมเวิร์กระดับ Rails ได้
    • metaprogramming ของ Java ไม่ทรงพอสำหรับการสร้าง ActiveRecords
  • ดังนั้น Rails จึงเกิดขึ้นได้เพราะโครงสร้างของภาษา Ruby และ การออกแบบภาษาเป็นตัวกำหนดความเป็นไปได้ของไลบรารี

การออกแบบภาษากำหนดรูปแบบของไลบรารี

  • ภาษา C รองรับการนำกลับมาใช้ซ้ำผ่านเพียงการประกาศและเรียกใช้ฟังก์ชัน ทำให้ไลบรารีของ C ส่วนใหญ่อยู่ในรูปของ ชุดฟังก์ชัน
  • Ruby รองรับ first-class functions จึงสามารถเขียนว่า “เมื่อปุ่มถูกคลิกให้ทำงานนี้” ได้อย่างกระชับ
    • ในทางกลับกัน Java ต้อง นิยามคลาส handler ทำให้โค้ดซับซ้อนขึ้น
  • พลังในการแสดงออกของภาษาส่งผลโดยตรงต่อ โครงสร้างและความง่ายในการใช้งานของไลบรารี

ซอฟต์แวร์เชิงโต้ตอบและการมาของเฟรมเวิร์กที่ขยายได้

  • ในยุคคอมพิวติ้งแบบแบตช์ของทศวรรษ 1970 ไลบรารีที่เน้นฟังก์ชันก็เพียงพอแล้ว
  • แต่ในซอฟต์แวร์เชิงโต้ตอบสมัยใหม่ จำเป็นต้องมี ไลบรารีที่ขยายได้
    • ใน GUI หรือระบบที่ขับเคลื่อนด้วยอีเวนต์ จำเป็นต้องมีโครงสร้างแบบ “เมื่อผู้ใช้คลิก ให้รันโค้ดของฉัน”
  • Java และ C++ รองรับการขยายด้วย inheritance และ method overriding และโครงสร้างลักษณะนี้ก็พัฒนาไปเป็น เฟรมเวิร์ก

ฉากหลังของการออกแบบ Stanza และข้อจำกัดของภาษา

  • แรงจูงใจในการออกแบบ Stanza เริ่มจากความยากในการ เขียนไลบรารีสำหรับการเขียนโปรแกรมเกมที่ใช้งานง่าย ใน Java
    • ใน Java ต้องแสดง concurrency ด้วย state machine
    • ส่วน Scheme รองรับ continuation จึงทำให้สร้างสิ่งนี้ได้อย่างเป็นธรรมชาติกว่า
  • แต่ Scheme ไม่รองรับการตรวจสอบชนิดแบบสแตติก จึง มีประสิทธิภาพในการดีบักต่ำ
    • ปัจจุบัน ภาษาส่วนใหญ่ยังไม่สามารถ ขยายระบบชนิดผ่านไลบรารี ได้
  • Stanza มี ระบบชนิดแบบเลือกใช้, garbage collection, ระบบอ็อบเจ็กต์แบบ multimethod-based
    • แต่ก็ยังไม่สามารถเขียนระบบอ็อบเจ็กต์แบบกำหนดเองขึ้นใหม่ได้

เป้าหมายของภาษาและทิศทางการวิจัย

  • เป้าหมายของภาษาโปรแกรมเอนกประสงค์คือ รองรับการสร้างไลบรารีที่ทรงพลังและใช้งานง่าย
    • ยิ่งภาษาทรงพลังมากเท่าไร การใช้งานไลบรารีก็ยิ่งกระชับมากขึ้นเท่านั้น
  • เมื่อโค้ดใช้ไลบรารีที่ออกแบบมาอย่างดี มันจะ อ่านได้เป็นธรรมชาติราวกับประโยคที่ใช้สั่งงานเพื่อนร่วมงาน
  • งานวิจัยอย่าง Racket, Shen และ meta object protocol กำลังสำรวจ ระบบชนิดและระบบอ็อบเจ็กต์ที่ขยายได้
  • ท้ายที่สุด ภาษาแต่ละภาษาถูกจำแนกได้จาก “ใช้ไลบรารีแบบใดได้ และแบบใดใช้ไม่ได้
  • เบื้องหลังไลบรารีที่งดงามคือ งานวิจัยและความพยายามด้านการออกแบบภาษาที่สั่งสมมาหลายทศวรรษ

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

 
GN⁺ 2026-01-09
ความเห็นจาก Hacker News
  • ตัวอย่างที่ดีที่สุดคือ Prolog มักถูกเรียกว่าเป็นภาษาตัวแทนของการเขียนโปรแกรมเชิงตรรกะ แต่จริง ๆ แล้วแทบจะเป็นเพียง ชุดของอัลกอริทึมหลายแบบ และสามารถนำไปทำเป็นไลบรารีของแต่ละภาษาได้ แค่มีรูปแบบไวยากรณ์ของ Prolog ให้สอดคล้องกับไวยากรณ์ของแต่ละภาษาก็น่าจะเพียงพอ

    • แก่นของ Prolog ไม่ใช่อัลกอริทึม แต่คือวิธี ประกาศกฎเชิงตรรกะแบบประกาศเจตนา ตัวอย่างเช่น ถ้านิยามกฎว่า “ปู่ย่าตายายคือพ่อแม่ของพ่อแม่” ก็สามารถใช้กฎนี้เพื่อหาความสัมพันธ์ปู่ย่าตายาย หรือย้อนกลับไปอนุมานความสัมพันธ์พ่อแม่ได้ด้วย การ อนุมานได้สองทิศทาง แบบนี้คือเสน่ห์ของ Prolog แน่นอนว่าถ้าจะเลียนแบบความสามารถนี้ในภาษาทั่วไป ก็ต้องใช้โค้ดที่ไม่มีผลข้างเคียงและมี DSL ที่ถูกจำกัดไว้ แต่ในเมื่อยังสามารถเรียกข้ามภาษากันได้แบบ PyTorch หรือ TensorFlow ที่รัน CUDA จาก Python โครงสร้างที่ไม่ยึดติดกับภาษาใดภาษาหนึ่งก็น่าจะทำได้เหมือนกัน
    • ไวยากรณ์ของ Prolog เป็นส่วนย่อยของ ตรรกะอันดับหนึ่ง (First Order Logic) โดยตัวแปรจะไม่ถูกกำหนดค่าแบบตายตัว แต่จะค้นหาไปบนเซตของค่าที่เป็นไปได้จนกว่าจะเจอเงื่อนไขที่สอดคล้องกัน เอนจินของ Prolog ทำงานมากกว่าแค่การเรียกไลบรารีธรรมดา — เช่น การแทนปริภูมิคำตอบแบบบีบอัด, การทำงานขนาน, การตัดกิ่งอัตโนมัติ เป็นต้น เพราะอย่างนั้นโดยทั่วไปจึงมักเอา Prolog ไปไว้เป็นบริการ backend หรือผสานเข้าด้วยวิธีสร้างโค้ด Prolog มีพลังมากเป็นพิเศษในงาน การวางแผน, การแก้ constraint, การพิสูจน์ทฤษฎีบท, การทดสอบเชิงจัดหมู่, การทำโมเดลราคา ดังนั้นผมจึงคิดว่ามันคงฝืนเกินไปถ้าจะมอง Prolog เป็นแค่ “ภาษาที่พอแทนได้ด้วยไลบรารี”
    • ถ้าคิดตามตรรกะเดียวกัน ก็อาจบอกได้ว่าความสามารถแบบ object-oriented เองก็ลอกเลียนด้วย closure ได้ จึงไม่จำเป็นต้องมีในภาษาก็ได้ แต่ พลังการแสดงออกที่มาจากไวยากรณ์ที่ชัดเจน ก็มีข้อดีของมัน
    • ถ้าจะทำ relational programming แบบ Prolog เป็นไลบรารี ภาษานั้นต้อง รองรับการจัดการ symbol และตัวแปรในฐานะ first-class object Lisp ตระกูลต่าง ๆ ยังพอทำได้บ้าง แต่ในภาษาทั่วไป usability จะตกลงไปมาก ตอนคุยกับ Bob Harper เขาพูดว่า “ก็สร้างภาษาใหม่ไปเลยสิ” ซึ่งฟังดูมีเหตุผลมากทีเดียว
    • ผมอยากเรียนรู้ Prolog แต่หาสื่อระดับ กลาง ๆ ระหว่างบทสอนเริ่มต้นกับตัวอย่างขั้นสูง ได้ยาก ผมกำลังลองแก้ปริศนา Sudoku แบบดัดแปลงด้วย Prolog แต่ตัวอย่างที่มีอยู่มักถูกปรับแต่งมาอย่างมากจนยากจะเรียนรู้การนิยามความสัมพันธ์แบบทั่วไป โดยเฉพาะผมอยากรู้ว่าจะทำโมเดลกรณีที่กฎบางข้ออาจผิดได้อย่างไร ตอนนี้กำลังดู ตัวอย่าง Sudoku ของ SWI-Prolog อยู่
  • เมื่อ 10 ปีก่อนผมเป็นแฟน Scala มาก แนวคิด “Scalable Language” ที่สามารถสร้าง DSL ภายใน type system ได้เป็นอะไรที่ดึงดูดมาก แต่พอ community เริ่มใช้มันเหมือน Haskell บน JVM ผมก็หมดความสนใจ ทุกวันนี้ผมคาดหวังว่าเทคโนโลยีอย่าง WASM หรือ Graal จะช่วยให้การเลือกภาษายืดหยุ่นขึ้น หลายกรณีใช้ JS ก็พอแล้ว แต่ก็ดีที่เวลาจำเป็นยังมีตัวเลือกให้ใช้ภาษาระดับล่างอย่าง Rust ได้

    • ผมก็คิดว่าปัญหาใหญ่ที่สุดของ Scala คือ การใช้ DSL มากเกินไป ไม่ใช่แค่ตัวภาษา แต่รวมถึง test framework ต่าง ๆ ด้วย จนให้ความรู้สึกว่าต้องเรียนภาษาใหม่ซ้อนเข้าไปอีก แน่นอนว่าการเขียน Hadoop MapReduce ได้ในบรรทัดเดียวมันน่าประทับใจ แต่สำหรับงานส่วนใหญ่ก็มากเกินจำเป็น แถมนักพัฒนา Scala หลายคนก็ไม่ชอบเขียน “โค้ดน่าเบื่อ” ผมเห็นหลายครั้งที่คนพยายามโชว์ของ แล้วทิ้งนรกแห่งการบำรุงรักษาไว้ให้คนอื่น
    • ไม่ใช่ว่าทั้ง community ของ Scala จะมุ่งไปทาง Haskell กันหมด มีแค่ พ่อมดสาย type บางส่วนเท่านั้นที่เป็นแบบนั้น Scala เองก็ยอดเยี่ยมมากถ้าใช้เป็นแค่ “Java ที่ดีกว่า” คุณได้ข้อดีของแนวคิด functional แบบไม่ต้องแบกรับภาระมากเกินไป
    • เดิมที Haskell ก็ถูกใช้บ่อยเป็น ภาษาสำหรับสร้าง DSL อยู่แล้ว Haxl ของ Meta หรือ TidalCycles ซึ่งเป็น DSL สำหรับดนตรีก็เป็นตัวอย่างที่ดี เพียงแต่ไลบรารีที่อิงกับ higher-kinded type มักมีปัญหา performance หนัก และซับซ้อนเกินความจำเป็น
    • เคยลอง Clojure(Script) ไหม? ตามสไตล์ภาษา Lisp มันทำ bottom-up programming โดยค่อย ๆ ขยายภาษาให้เหมาะกับปัญหาได้ Paul Graham ก็เน้นแนวทางนี้ไว้ใน On Lisp และขอแนะนำบรรยาย Bottom Up vs Top Down Design in Clojure ด้วย
    • ผมเพิ่งเริ่มเรียน Scala ไม่นานนี้ และชอบมันมากแม้ในแง่ functional programming ผมคิดว่ามันเป็นภาษาอเนกประสงค์พอจะใช้ได้หลายแบบนอกจากการสร้าง DSL เลยอยากรู้ว่าคุณรู้สึกว่า Scala ยังขาดอะไรอยู่ไหม
  • ถ้ามี ภาษาสคริปต์แบบมี type ที่เอามาแทน bash ได้ก็คงดี ผมลองเขียนสคริปต์ parser JSON ง่าย ๆ ด้วย Elixir แล้วรู้สึกว่าใช้ได้เลย

    • เคยลอง Nushell ไหม? งานที่เมื่อก่อนต้องใช้ “ภาษาจริงจัง” ตอนนี้ทำเป็น one-liner ได้ เช่น เขียน pipeline สำหรับจัดเรียงรายชื่อไฟล์แล้วแสดงผลเป็น JSON ได้ง่ายมาก
    • จริง ๆ แล้วถ้าใช้ shebang ก็เขียนสคริปต์ได้หลายภาษา เช่น C#, Java, Go ทำได้ทั้งหมด และถ้าใช้ Scriptisto ก็ทำ shebang script ได้แทบทุกภาษา
    • OCaml ก็ใช้แบบสคริปต์ได้เช่นกัน รันตรง ๆ ด้วย #!/usr/bin/env ocaml ได้เลย เพียงแต่ยังไม่มีความสามารถติดตั้ง dependency ภายนอกอัตโนมัติจากไฟล์เดียว
    • ใน Go ก็มี ทริก สำหรับเลียนแบบ shebang ด้วย ดูการพูดคุยที่เกี่ยวข้องได้ ที่นี่
    • สำหรับงานสคริปต์ประจำวัน Python หรือ PowerShell ก็เป็นตัวเลือกที่ดี
  • ภาษาและไลบรารี ไม่ได้เป็นสิ่งที่排斥กัน ไลบรารีบางตัวทำงานแทบไม่ต่างจากภาษา และในทางกลับกัน ภาษาบางภาษาก็ถูกออกแบบมาเพื่อไลบรารีเฉพาะด้วย เช่น Julia เป็นตัวอย่างที่บาลานซ์ระหว่างประสิทธิภาพกับความสะดวกในการใช้งานได้ดี คุณสามารถเขียนโค้ดประสิทธิภาพสูงด้วย Julia โดยตรง และได้ประโยชน์จาก การคอมไพล์แบบ type-specialized ระดับ JIT เพื่อให้รันได้อย่างเหมาะสม แม้โมเดลภายนอกจะดูเป็นแค่การเรียกฟังก์ชันธรรมดา แต่ภายในซับซ้อนและชาญฉลาดมาก

    • ใช่เลย สุดท้ายประเด็นหลักก็คือ เราต้องมีทั้งภาษาและไลบรารี
  • Raku ถูกออกแบบให้เป็นโครงสร้างที่เชื่อมหลายภาษาย่อย (slang) เข้าด้วยกัน เช่น regex, PEG, quoting ฯลฯ ถูกจัดการเป็นมินิภาษาของตัวเอง และใช้ Slangify เพื่อเพิ่ม DSL ของตัวเองได้ง่าย

    • แต่ส่วนตัวผมไม่ชอบ ไวยากรณ์ที่วาง type ไว้หลังชื่อตัวแปร เลยไม่ค่อยชอบ Raku
  • ครั้งหนึ่งมีนักพัฒนาอาวุโสคนหนึ่งพูดว่า “ถ้าเห็น Rails ในเรซูเม่ก็โยนทิ้งทันที” มันยิ่งทำให้รู้สึกว่า การตัดสินคนจากภาษา เป็นเรื่องโง่แค่ไหน

    • การที่ Rails กำลังมาและ J2EE กำลังถอย เกิดขึ้นพร้อมกันไม่ใช่เรื่องบังเอิญ Rails แสดงให้เห็น backend code ที่เรียบง่ายและมีแนวทางชัดเจน และอิทธิพลนั้นก็ทำให้เฟรมเวิร์ก Java อย่าง DropWizard, Javalin, Spring Boot เกิดขึ้นตามมา
    • อยากรู้จริง ๆ ว่า tech stack ของ senior คนนั้นคืออะไร
    • ถึงขั้นอยากไปขอรับของจากถังขยะของเพื่อนร่วมงานคนนั้นเลย หานักพัฒนา Rails ดี ๆ ยากนะ ผมเองก็มี ประสบการณ์ RoR และยังชอบมันอยู่
    • แน่นอนว่าถ้าคุณกำลังหานักพัฒนา Java การคัดเรซูเม่ Rails ทิ้งก็อาจมีประสิทธิภาพกว่า
    • เกณฑ์ในการประเมินคนสุดท้ายแล้วก็ขึ้นอยู่กับ ความเข้ากันได้กับวัฒนธรรมองค์กร และ สไตล์การทำงานร่วมกัน ไม่มีวิธีกรองที่สมบูรณ์แบบหรอก
  • ท้ายที่สุดแล้ว ภาษาหรือไลบรารีก็คือ เครื่องมือสื่อสารทั้งกับเครื่องและกับคน เครื่องสื่อสารผ่านบิตและแรงดันไฟฟ้า ส่วนคนสื่อสารผ่าน เจตนาและแนวคิด เพราะฉะนั้นถ้าภาษาหรือไลบรารีช่วยให้คนสื่อสารได้ชัดและเร็วพอ จะเป็นภาษาหรือไลบรารีก็ไม่สำคัญ Rails หรือ Stanza ก็เหมือนกัน ถ้ามันเหมาะกับจุดประสงค์และทีมเข้าใจได้ง่าย นั่นก็คือคำตอบที่ถูกต้อง

  • ผมมองว่า “ไลบรารีก็คือภาษาสุดท้ายในสายโซ่” ตัวอย่างเช่น Ruby on Rails คือภาษาสำหรับเว็บเซอร์วิสที่ยอดเยี่ยมซึ่งอยู่บนฐานของ Ruby Ruby และ Rails พัฒนาร่วมกันเพื่อเกื้อหนุนกันเอง สุดท้ายแล้วผมคิดว่า การเขียนโปรแกรมคือกระบวนการแปลภาษาต่อเนื่องหลายชั้น

    • C# และ ASP.NET Core ก็เติบโตมาด้วยกันในลักษณะคล้ายกัน ทั้งไวยากรณ์ที่เป็นมิตรกับผู้ใช้และการปรับแต่งระดับระบบเกิดขึ้นพร้อมกัน
  • คำพูดที่ว่า “ยิ่งภาษาทรงพลังเท่าไร การใช้ไลบรารีก็ยิ่งง่ายขึ้น” นั้นจริง สมัยก่อน Java ทำเฟรมเวิร์กอย่าง Express ได้ยาก

    • ผมไม่รู้ว่า Express คืออะไร แต่คิดว่า Java กลายเป็นภาษาองค์กรได้ก็เพราะ ความสามารถในการใช้ไลบรารี
    • ASP.NET Core minimal API ของ C# เป็นตัวอย่างที่แทบจะทำ Express ออกมาตรง ๆ เลย เรื่องแบบนี้จะเกิดขึ้นได้ก็เมื่อภาษาและเฟรมเวิร์กพัฒนาไปด้วยกัน
    • ใน Java เองก็มีเฟรมเวิร์กคล้าย Express อย่าง Javalin ปัญหาคือ community ไม่ได้ต้องการความเรียบง่าย
  • ถ้าเป็นเว็บเฟรมเวิร์กสำหรับภาษา C ก็มี PHP ไงล่ะ ;)

    • นั่นฟังดูเหมือน มุกที่ขยายความหมายของคำว่าไลบรารีกว้างเกินไป