ทำไมต้อง Clojure?
(gaiwan.co)- Clojure ไม่ใช่หนึ่งในภาษาโปรแกรมกระแสหลัก และอาจยังไม่คุ้นเคยสำหรับบางคน
- ข้อดีหลักของ Clojure
- ประสิทธิภาพการทำงานของนักพัฒนา : Clojure มีความเป็นอินเทอร์แอ็กทีฟ ลดงานที่ต้องทำซ้ำ และมอบสภาพแวดล้อมการพัฒนาที่มีประสิทธิภาพ ทำให้นักพัฒนาพึงพอใจและส่งมอบผลิตภัณฑ์ได้รวดเร็ว
- การบำรุงรักษาระยะยาว : ภาษาและอีโคซิสเต็มของ Clojure มีความสุกงอมและเสถียร สามารถสร้างระบบคุณภาพสูงพร้อมลดต้นทุนการบำรุงรักษาได้
- วัฒนธรรมที่ขับเคลื่อนด้วยแนวคิด : ชุมชน Clojure สำรวจแนวคิดจากทั้งอดีตและปัจจุบัน จากทั้งแวดวงวิชาการและอุตสาหกรรม เพื่อค้นหาวิธีพัฒนาซอฟต์แวร์ที่ดีกว่า มอบความท้าทายและโอกาสในการเรียนรู้ใหม่ ๆ ให้แก่นักพัฒนา
(hello 'clojure)
- Clojure เป็นหนึ่งในภาษาตระกูล Lisp ที่ถูกสร้างขึ้นมาตั้งแต่ยุคทศวรรษ 1950
- Lisp เริ่มต้นจากโมเดลเชิงทฤษฎี แต่ในการเขียนโปรแกรมจริงก็ให้ความงามเชิงแนวคิดในระดับสูง
- ไวยากรณ์ของโค้ดสอดคล้องกับโครงสร้างข้อมูลโดยตรง จึงมีข้อดีหลายอย่างเมื่อเทียบกับภาษาที่มีไวยากรณ์ซับซ้อน
- เคยถูกใช้เป็นภาษาหลักในช่วงกระแส AI ยุคแรก
- ภาษาตระกูล Lisp มักได้รับความนิยมเป็นระยะแล้วก็เงียบหายไป แต่ในช่วง 10 ปีที่ผ่านมา Clojure ได้รับความสนใจอย่างชัดเจน
- Clojure ทำงานอยู่บน JVM ของ Java และสะท้อนแนวคิดการเขียนโปรแกรมสมัยใหม่
- รองรับ โครงสร้างข้อมูลแบบ immutable อย่างแข็งแกร่ง
- ออกแบบมาโดยคำนึงถึง concurrency
- แม้จะเป็นชุมชนขนาดเล็กที่เติบโตขึ้นมาโดยไม่ได้รับแรงสนับสนุนจากบริษัทยักษ์ใหญ่ แต่มีคุณสมบัติด้านภาษาที่ทรงพลัง
- Clojure สามารถรันได้ในหลายสภาพแวดล้อม
- ClojureScript: แปลงเป็น JavaScript แล้วรัน
- ClojureCLR: รันบนสภาพแวดล้อม .NET
- Babashka: อินเทอร์พรีเตอร์สำหรับสคริปต์ที่รวดเร็วโดยอาศัย GraalVM
- Jank: รองรับการคอมไพล์แบบเนทีฟ
- เมื่อเรียนรู้ Clojure แล้ว ก็สามารถนำความรู้เดียวกันไปใช้ได้ในหลายสภาพแวดล้อม
แนวทางการพัฒนาแบบอินเทอร์แอ็กทีฟ
- การเขียนโปรแกรมคือกระบวนการทำซ้ำของ การเขียนโค้ดและการตรวจสอบ
- หากไม่มีฟีดแบ็ก ก็ยากจะมั่นใจได้ว่าโค้ดทำงานถูกต้องหรือไม่
- วิธีรับฟีดแบ็กโดยทั่วไป:
- การรันสคริปต์ซ้ำ ๆ
- การโต้ตอบกับ UI และการพิมพ์ log
- การใช้ unit test
- การใช้คอมไพเลอร์และเครื่องมือ static analysis
- ฟีดแบ็กที่รวดเร็วส่งผลอย่างมากต่อประสิทธิภาพการทำงานของนักพัฒนา
- ยิ่งฟีดแบ็กช้าลง เวลาที่ใช้ไปกับการดีบักก็ยิ่งเพิ่มขึ้น และเวลาสำหรับการเขียนโค้ดก็ยิ่งลดลง
- นอกจากวิธีฟีดแบ็กแบบเดิมแล้ว Clojure ยังมีแนวทาง interactive development
- แกนสำคัญคือการพัฒนาบนพื้นฐานของ REPL (Read-Eval-Print Loop)
- ก่อนเริ่มเขียนโค้ด นักพัฒนาจะรัน Clojure runtime แล้ว เชื่อมต่อกับเอดิเตอร์
- สามารถรันโค้ดทีละส่วนและรับฟีดแบ็กได้ทันที
- ด้วย โครงสร้างไวยากรณ์ที่สม่ำเสมอ ของ Lisp จึงสามารถรันได้อย่างอิสระตั้งแต่โค้ดชิ้นเล็ก ๆ ไปจนถึงบล็อกโค้ดขนาดใหญ่
- ต่างจาก REPL ทั่วไป Clojure สามารถ รันโค้ดเป็นส่วน ๆ ขณะเชื่อมต่อกับระบบที่กำลังทำงานอยู่ ได้
- วิธีนี้ให้ feedback loop ที่ทรงพลังกว่าแนวทางเดิมแบบ “เขียนโค้ด → รัน → ดีบัก” มาก
- สามารถ แก้ไขและดีบักโปรแกรมแบบเรียลไทม์
- ไม่ใช่แค่ REPL ธรรมดา แต่เป็น เครื่องมือปฏิสัมพันธ์ที่ทรงพลังซึ่งใช้ได้แม้ในสภาพแวดล้อม production
วัฒนธรรมที่ให้ความสำคัญกับเสถียรภาพ
- การเลือก Clojure ไม่ใช่แค่การได้เทคโนโลยีที่ทรงพลัง แต่ยังหมายถึงการเป็น สมาชิกของชุมชน ที่มีปรัชญาและหลักการเฉพาะตัว
- หากเพียงนำเทคโนโลยีมาใช้โดยไม่สื่อสารกับชุมชน ก็ยากจะสัมผัสคุณค่าที่แท้จริงของ Clojure
- ชุมชน Clojure ให้ความสำคัญกับ เสถียรภาพและ backward compatibility
- แกนหลักของภาษาถูกปรับปรุงและขยายอย่างต่อเนื่องโดย แทบไม่มี breaking change เลย
- อีโคซิสเต็มโอเพนซอร์สของ Clojure ก็ยึดถือปรัชญาเดียวกัน โดยลดการเปลี่ยนแปลงที่ไม่จำเป็น (churn) ให้น้อยที่สุด
- สิ่งนี้แตกต่างจากอีโคซิสเต็มของภาษาโปรแกรมสมัยใหม่ส่วนใหญ่
- ความสูญเปล่าของทรัพยากรจากการเปลี่ยนแปลงที่ไม่จำเป็นนั้นมีมูลค่าระดับหลายพันล้านดอลลาร์ทั่วโลก
- ใน Clojure การอัปเกรดไปยังภาษาและไลบรารีเวอร์ชันล่าสุดเป็นเรื่องที่เป็นธรรมชาติมาก
- ได้รับทั้งการแก้บั๊ก อัปเดตความปลอดภัย และปรับปรุงประสิทธิภาพ โดยไม่ต้องเขียน codebase ใหม่
- โค้ดเดิมที่อาจพังเมื่อมีเวอร์ชันใหม่ในภาษาอื่น มักยังใช้ได้เหมือนเดิมใน Clojure
- นักพัฒนาบางคนอาจสงสัยว่า “ถ้าไม่เปลี่ยน แล้วจะพัฒนาได้อย่างไร?”
- แต่ เสถียรภาพกับความหยุดนิ่ง (stagnation) ไม่ใช่เรื่องเดียวกัน
- Clojure พัฒนาโดย เพิ่มความสามารถใหม่และปรับปรุงสิ่งเดิมโดยไม่ทำลายของเดิม
- นักพัฒนาจึงสามารถใช้เครื่องมือที่ดีขึ้นอย่างต่อเนื่องได้โดยไม่ต้องแก้โค้ดที่ไม่จำเป็น
ระบบสารสนเทศและการแทนความรู้
- ในการพัฒนาเว็บและแอปพลิเคชันธุรกิจ หัวใจสำคัญคือ การรวบรวม เข้าถึง และประมวลผลข้อมูล
- แต่ภาษาโปรแกรมกระแสหลักจำนวนมากมักมี การออกแบบที่ไม่มีประสิทธิภาพ ในแง่ของการแทนและจัดการข้อมูล
- บังคับให้ใช้ โครงสร้างข้อมูลระดับล่าง จนเกิดความซับซ้อนที่ไม่จำเป็น
- ระบบชนิดข้อมูลแบบสแตติก มีความแข็งตัวมากเกินไป ทำให้จัดการข้อมูลอย่างยืดหยุ่นได้ยาก
- Clojure มี โครงสร้างข้อมูลเชิงฟังก์ชันและความสามารถในการจัดการข้อมูลที่ทรงพลัง มาให้โดยพื้นฐาน
- ในฐานะภาษาแบบ dynamic typing มันยึดตาม “Open World Assumption”
- ซึ่งเป็นแนวทางที่เพิ่มความสามารถในการขยายและความยืดหยุ่นของข้อมูลให้สูงสุด
- ได้รับอิทธิพลอย่างมากจาก RDF (เฟรมเวิร์กสำหรับการทำโมเดลข้อมูลของ Semantic Web)
- ตัวอย่างเด่นคือการทำงานร่วมกับกราฟดาต้าเบสอย่าง Datomic ได้อย่างลงตัว
- ใช้คีย์เวิร์ดที่มี namespace เพื่อ ให้ความหมายที่ไม่ขึ้นกับบริบท ได้
- ในฐานะภาษาแบบ dynamic typing มันยึดตาม “Open World Assumption”
- โครงสร้าง Clojure map ที่ใช้ namespace keyword สามารถถ่ายทอดความหมายได้ละเอียดกว่าการใช้ JSON แบบเรียบง่าย
- ขยายข้อมูลเพิ่มเติมได้ง่าย และ สามารถหลีกเลี่ยงการชนกันของชื่อพร้อมกับยังคงสื่อความหมายได้อย่างเป็นธรรมชาติ
ฟังก์ชันเล็กที่ประกอบกันได้และข้อมูลแบบ immutable
- ใน Clojure การเขียนโปรแกรมโดยยึด pure functions และ immutable data เป็นศูนย์กลางถือเป็นแนวปฏิบัติทั่วไป
- แม้จะสามารถเขียนโค้ดเชิงคำสั่งแบบ Java, Ruby หรือ C ได้ แต่ โค้ด Clojure ที่เป็นธรรมชาติ (idiomatic Clojure) นั้นแตกต่างมาก
- pure function: คืนผลลัพธ์จากค่าป้อนเข้าเท่านั้น และไม่เปลี่ยนแปลงสถานะภายนอก
- immutable data: มีความหมายบนฐานของ ค่า (value) ไม่ใช่ reference หรือ identity ของอ็อบเจ็กต์
- เพราะไม่ขึ้นกับสถานะภายนอก จึง ทำให้โค้ดคาดเดาได้สูง
- ไม่มีการแก้ไขตัวแปร global หรือ side effects ที่ไม่คาดคิด
- เพราะไม่มีความเสี่ยงที่ข้อมูลจะถูกเปลี่ยน จึง จัดการงานขนานและปัญหา concurrency ได้ง่าย
การจัดการ concurrency
- การประมวลผลสมัยใหม่ทำงานบนพื้นฐานของโปรเซสเซอร์แบบมัลติคอร์ และ concurrency เป็นองค์ประกอบที่ขาดไม่ได้
- เมื่อกฎของ Moore เข้าใกล้ขีดจำกัด การใช้ประโยชน์จากความขนาน จึงกลายเป็นกุญแจของการเพิ่มประสิทธิภาพ
- แต่เมื่อจัดการกับ mutable state ก็จำเป็นต้องรับมือกับปัญหาการซิงโครไนซ์และการควบคุมจังหวะเวลาที่ซับซ้อน
- Clojure เน้น immutability เพื่อแก้ปัญหา concurrency ตั้งแต่รากฐาน
- การจัดการหน่วยความจำที่เปลี่ยนแปลงได้ทำให้เกิดการพึ่งพาต่อเวลาและลำดับการทำงาน
- การแปลงข้อมูลแบบบริสุทธิ์ (data-in, data-out) สามารถรันแบบขนานได้อย่างปลอดภัยเสมอ
- Clojure ใช้ประโยชน์จากความสามารถด้าน concurrency ที่มีอยู่ใน JVM (
java.util.concurrent) พร้อมมอบ เครื่องมือเชิงนามธรรมระดับสูงกว่า- Atoms: รองรับการดำเนินการแบบอะตอมมิกด้วย CAS(Compare-and-Set) และการลองใหม่อัตโนมัติ
- Refs: ให้ความสามารถด้าน Software Transactional Memory (STM)
- Agents: ใช้แนวทางการอัปเดตแบบอะซิงโครนัส
- Futures: มอบอินเทอร์เฟซแบบ fork-and-join บน thread pool
- มีไลบรารี core.async
- รองรับแพตเทิร์น CSP (Communicating Sequential Processes) ที่คล้ายกับ goroutine ของ Go
- สามารถเปรียบเทียบได้กับ Actor model ของ Erlang/Elixir และ Akka ของ Scala
- แม้ไม่ใช้ความสามารถเชิงนามธรรมระดับสูงของ Clojure ก็ยังสามารถใช้ เทคนิคควบคุม concurrency ระดับล่างกว่า ได้
- รองรับ synchronized queue, atomic reference, lock, semaphore, thread pool หลายรูปแบบ และการจัดการเธรดด้วยตนเอง
- หากจำเป็นก็สามารถควบคุม concurrency อย่างละเอียดได้ แต่ในกรณีส่วนใหญ่ การใช้เครื่องมือเชิงนามธรรมจะปลอดภัยและมีประสิทธิภาพกว่า
การให้เหตุผลเฉพาะที่ (Local Reasoning)
- ความซับซ้อนของโค้ดที่มนุษย์สามารถพิจารณาได้ในคราวเดียวมีขีดจำกัด
- หากสถานะของโปรแกรมและการเปลี่ยนแปลงเกิดขึ้นในหลายจุด ก็จะทำให้เข้าใจและบำรุงรักษาโค้ดได้ยาก
- เหตุผลที่ Clojure ทำให้ local reasoning ง่ายขึ้น
- โค้ดที่มี pure function เป็นศูนย์กลาง
- สามารถเข้าใจการทำงานของฟังก์ชันได้อย่างสมบูรณ์จากค่าป้อนเข้าเพียงอย่างเดียว
- ไม่จำเป็นต้องพิจารณาสถานะภายนอกของฟังก์ชัน
- ความแตกต่างจากภาษาเชิงวัตถุ
- Clojure ลดการใช้ polymorphism ให้น้อยลง ทำให้ ตรวจสอบได้ง่ายว่าโค้ดถูกรันที่ไหน
- ในการเขียนโปรแกรมเชิงวัตถุ (OOP) มักเป็นลักษณะว่า “ทุกอย่างเกิดขึ้นที่อื่น” แต่ใน
Clojure เพียงติดตามฟังก์ชันที่นิยามไว้ใน namespace ก็พอ
- โค้ดที่มี pure function เป็นศูนย์กลาง
- ด้วย โครงสร้างไวยากรณ์ที่สม่ำเสมอ ของ Clojure การรีแฟกเตอร์โค้ดจึงทำได้ง่าย
- เนื่องจากใช้ immutable data และ pure function จึงมี side effect ที่ไม่คาดคิดน้อยเมื่อเปลี่ยนโค้ด
- แยกโค้ดเชิงคำสั่งให้น้อยที่สุดออกมาไว้ต่างหาก เพื่อ จัดองค์ประกอบโค้ดเชิงคำสั่งและโค้ดเชิงฟังก์ชันให้ทำงานร่วมกันอย่างลงตัว
การทดสอบที่ง่าย
- ในโค้ดที่ยึด pure function ของ Clojure เป็นหลัก สามารถทดสอบได้เพียง ใส่ค่าป้อนเข้าแล้วตรวจสอบค่าผลลัพธ์
- ไม่จำเป็นต้องมี การตั้งค่าสถานะเริ่มต้นที่ซับซ้อน การตั้งค่า mock object หรือการควบคุมเวลา เพื่อการทดสอบ
- ดังนั้น ความน่าเชื่อถือของการทดสอบจึงสูงขึ้น และมีความเป็น flaky น้อยลง
- รองรับเทคนิคทดสอบขั้นสูงอย่าง Property Based Testing (Generative Testing)
- สร้างค่าป้อนเข้าแบบสุ่มเพื่อค้นหากรณีที่ละเมิดคุณสมบัติเฉพาะหรือ invariant
- รองรับ เทคนิค shrinking ที่ช่วยค้นหากรณีล้มเหลวที่เล็กที่สุด
- แนวคิดนี้เริ่มต้นจาก Haskell และถูกนำไปใช้ในหลายภาษาผ่านเฟรมเวิร์กทดสอบที่อิง QuickCheck
- ใน Clojure แนวคิดนี้ยิ่งมีประสิทธิภาพมากขึ้นเมื่อทำงานร่วมกับ โครงสร้างข้อมูลแบบ immutable และแนวทางการพัฒนาแบบ REPL
ข้อดีของการจ้างนักพัฒนา Clojure
- โดยทั่วไปแล้วนักพัฒนา Clojure มีจำนวนน้อยกว่าเมื่อเทียบกับภาษายอดนิยมอย่าง JavaScript หรือ Python
- แต่ เมื่อมีนักพัฒนา Clojure น้อย บริษัทที่ใช้ Clojure ก็มีไม่มากเช่นกัน
- ดังนั้น สมดุลระหว่างอุปสงค์และอุปทานโดยรวมยังคงอยู่
- ในทางปฏิบัติ บริษัทที่ต้องการนักพัฒนา Clojure กับนักพัฒนาก็มักจับคู่กันได้เหมาะสม
- นักพัฒนา Clojure มักมีความสามารถในการแก้ปัญหาในระดับสูง
- แทนที่จะเรียนรู้เพียงเทคโนโลยีที่กำลังนิยม นักพัฒนากลุ่มนี้มักสนใจ สำรวจวิธีคิดและแนวคิดใหม่ ๆ
- บริษัทที่ใช้ Clojure หลายแห่งประเมินว่า แม้ผู้สมัครจะมีจำนวนน้อย แต่คุณภาพของนักพัฒนากลับสูง
- ตัวอย่าง: Nubank ได้ฝึกอบรมนักพัฒนาหลายร้อยคนในบราซิลให้ใช้ Clojure โดยตรง และสร้างกรณีศึกษาความสำเร็จขึ้นมา
- การหานักพัฒนา Clojure อาจไม่ง่าย แต่ หากเจอคนที่เหมาะสม ก็มีโอกาสสูงที่จะได้นักพัฒนาที่โดดเด่น
- แทนที่จะมองหาเพียงคนที่มีประสบการณ์กับภาษาโดยตรง การฝึกนักพัฒนาที่ มีความสามารถในการเรียนรู้สูง ก็เป็นทางเลือกที่ดี
- ตัวชุมชน Clojure เองก็มีลักษณะ ดึงดูดนักพัฒนาที่คิดลึกและแก้ปัญหาอย่างจริงจัง
trade-off และการปรับระดับ abstraction
- Clojure เป็น ภาษา high-level ที่มุ่งให้เขียนโค้ดได้กระชับและสื่อความหมายได้สูง
- ด้วยโครงสร้างข้อมูลเชิงฟังก์ชันแบบ immutable และ API จัดการข้อมูลที่ทรงพลัง จึงลดความซับซ้อนที่ไม่จำเป็นลงได้
- โครงสร้างข้อมูลของ Clojure ใช้ โครงสร้างต้นไม้ภายใน (Hash Array Mapped Trie) เพื่อรับประกัน immutability
- เมื่ออัปเดตจะเกิดการคัดลอกตามเส้นทาง (path copying) จึง อาจเพิ่มภาระให้ GC (garbage collection)
- ในกระบวนการทำ interop กับ Java อาจเกิด runtime reflection และ boxing/unboxing ได้
- สำหรับแอปพลิเคชันทั่วไป ต้นทุนเหล่านี้แทบเล็กน้อยจนมองข้ามได้ และข้อดีด้านประสิทธิภาพการพัฒนามีมากกว่า
- หากต้องการสมรรถนะสูง เช่น เอนจินกราฟิกแบบเรียลไทม์ การประมวลผลสัญญาณ หรือการคำนวณเชิงตัวเลข ก็ยัง ทำ optimization ระดับล่างได้
- ใน Clojure สามารถใช้ type hint เพื่อตัด reflection และเพิ่มประสิทธิภาพการคำนวณบน primitive type
- สามารถใช้ primitive array ที่ต่อเนื่องกัน เพื่ออาศัยประโยชน์จาก CPU cache
- สามารถใช้ไลบรารีเร่งความเร็วด้วย GPU ได้
- ภาษา high-level ส่วนใหญ่เมื่อต้องการประสิทธิภาพสำคัญ มักต้องพึ่ง native extension อย่าง C/Rust แต่
Clojure สามารถอาศัยการปรับแต่งของ JVM (JIT compilation) เพื่อแก้ปัญหาด้านประสิทธิภาพได้เป็นส่วนใหญ่- ด้วยการทำ profiling และ optimization เล็กน้อย ก็สามารถ ดันประสิทธิภาพของสิ่งอย่าง event loop ได้อย่างมาก
metaprogramming และ API ที่ขับเคลื่อนด้วยข้อมูล
- Clojure ในฐานะภาษาตระกูล Lisp มีจุดเด่นคือ สามารถปฏิบัติต่อโค้ดเหมือนข้อมูลได้
- คล้าย JSON แต่สามารถแทนโปรแกรมได้ใน โครงสร้างที่อ่านง่ายกว่า
- ใช้ฟอร์แมตข้อมูลชื่อ EDN(Extensible Data Notation) เพื่อให้การแทนข้อมูลคล้าย JSON
- Clojure มี ความสามารถในการแปลงตัวโค้ดเองด้วย macro
- อย่างไรก็ตาม ชุมชน Clojure มีวัฒนธรรมที่ จำกัดการใช้ macro อย่างระมัดระวัง
- เพราะ macro ดีบักยาก และอาจเข้ากันได้ไม่ดีกับเครื่องมือ static analysis
- สิ่งที่ได้รับความนิยมมากกว่าคือ แนวทางออกแบบ API แบบ data-driven
- เช่น HTTP routing, การสร้าง HTML/CSS, การตรวจสอบข้อมูล เป็นต้น
- แทนที่จะเรียกใช้ฟังก์ชันเฉพาะโดยตรง ก็ กำหนดพฤติกรรมผ่านโครงสร้างข้อมูล (map, vector)
- API ที่อิงข้อมูลสามารถจัดการแบบไดนามิกได้ และ บันทึกหรือแก้ไขการตั้งค่าผู้ใช้ได้ง่าย
- ด้วย API แบบ data-driven จึง สามารถปรับโครงสร้างระบบแบบไดนามิกได้ใน runtime
- ส่งผลให้ สร้างระบบจำลองที่ยืดหยุ่นสูง การจัดการค่าตั้งค่าแบบไดนามิก และ metaprogramming ได้ง่าย
Java interop และการใช้อีโคซิสเต็ม
- การพัฒนาแอปพลิเคชันสมัยใหม่คือ กระบวนการประกอบไลบรารีโอเพนซอร์สและ API จำนวนมหาศาลเข้าด้วยกัน
- เนื่องจาก Clojure รันบน JVM จึง ใช้แพ็กเกจ Java หลายล้านรายการบน Maven Central ได้
- สามารถเรียกใช้ไลบรารี Java ได้อย่างง่ายดายโดยไม่ต้องพึ่ง reflection
- Clojure มี โค้ดที่กระชับกว่า Java มาก และเหมาะกับ การเขียนโปรแกรมเชิงทดลองผ่าน REPL
- สามารถ สำรวจและประกอบ API ได้เร็วกว่ามากเมื่อเทียบกับ Java
- หากใช้ ClojureScript ก็สามารถใช้ JavaScript และอีโคซิสเต็ม NPM ได้ในลักษณะเดียวกัน
วัฒนธรรมที่ขับเคลื่อนด้วยแนวคิด
- ไม่ว่าจะใช้ภาษาใดก็สามารถสร้างโปรเจกต์ที่ประสบความสำเร็จได้ และในทางกลับกัน หากใช้อย่างไม่ถูกวิธี ก็ล้มเหลวได้กับทุกภาษา
- เครื่องมือที่ดีไม่ได้สร้างนักพัฒนาที่ดีโดยอัตโนมัติ
- Clojure มีจุดเริ่มต้นที่ยากและต้องลองผิดลองถูกในกระบวนการเรียนรู้ แต่สิ่งนี้ก็เปิดทางให้เกิดการคิดอย่างลึกซึ้ง
- บางโปรเจกต์ Clojure ยังคงมีรูปแบบการเขียนโค้ดแบบ Java หรือ Python ตกค้างอยู่ จึงใช้ศักยภาพได้ไม่เต็มที่
- แต่ ทีมที่รับเอาปรัชญาและแนวคิดของ Clojure ไปจริง ๆ จะมีความสามารถด้านการออกแบบซอฟต์แวร์ที่ดีกว่าเดิม
- ชุมชน Clojure ตั้งคำถามกับวิธีพัฒนาแบบเดิมอย่างต่อเนื่อง และสำรวจหนทางที่ดีกว่า
- การบรรยายของ Rich Hickey (ผู้สร้าง Clojure) ไม่ได้เป็นเพียงการแนะนำเทคโนโลยี แต่คือการ สำรวจหลักการพื้นฐานของการออกแบบซอฟต์แวร์
- ในงานประชุม Clojure เนื้อหาหลักมักเน้น แนวคิด การวิเคราะห์งานวิจัย และการแบ่งปันประสบการณ์ มากกว่าการแนะนำไลบรารี
บทสรุป
- Clojure ไม่ใช่แค่ภาษาโปรแกรม แต่เป็น ชุมชนของผู้คนที่ครุ่นคิดถึงวิธีพัฒนาซอฟต์แวร์ที่ดีกว่า
- ในชุมชนนี้ คุณค่าหลักคือการขยายขอบเขตของตนเองและสำรวจความเป็นไปได้ใหม่ ๆ
- นักพัฒนาที่เติบโตในวัฒนธรรมแบบนี้ จะไม่ได้เก่งแค่การใช้ Clojure แต่จะกลายเป็น วิศวกรซอฟต์แวร์ที่มีความสามารถในการแก้ปัญหาที่ดีกว่าเดิม
3 ความคิดเห็น
ส่วนตัวผมใช้ Clojure อยู่ และเห็นด้วยกับเนื้อหาในบทความมาก
ในการทำงานผมใช้ Python และ Java(Type)Script เป็นหลักมาโดยตลอด แต่ถ้าดูแลไม่ดีแม้เพียงนิดเดียว ก็มักจะตามการเปลี่ยนแปลงของตัวภาษาและไลบรารีต่าง ๆ ไม่ทัน จนโค้ดกลายเป็น legacy code ได้ง่ายอยู่เสมอ แต่สิ่งที่ผมพอใจมากเกี่ยวกับ Clojure คือโค้ดที่เขียนไว้ครั้งหนึ่งแล้ว แม้กลับมาดูอีกหนึ่งปีให้หลัง ก็ยังแก้ไขและพัฒนาต่อได้อย่างสะดวกทันที
หลังจากนั้น สำหรับการใช้งานส่วนตัว หากไม่ได้ติดข้อจำกัดจากไลบรารีเฉพาะบางตัว ผมก็มักเลือกใช้ Clojure เป็นหลักครับ
ทำไมต้อง Clojure?
Jank Jank~!
ความเห็นจาก Hacker News
ถ้าถามว่าสนุกกับการเขียนโปรแกรมแบบไหน คำตอบคือการสร้าง pipeline สำหรับประมวลผลข้อมูลในเชลล์ และการเขียน Clojure กับ ClojureScript ตลอด 5 ปีที่ผ่านมา
ใช้ Clojure มา 12 ปี และก่อนหน้านั้นก็ใช้ Java มานานกว่า 12 ปี
รักการเขียน Clojure มาก และเมื่อนำไปเทียบกับภาษาอื่นก็พบว่าไม่จำเป็นต้องอธิบายความรักอันลึกซึ้งที่มีต่อ Clojure
ผู้ร่วมก่อตั้งตั้งเป้าหมายที่จะสร้างผลิตภัณฑ์ให้ได้มากที่สุดด้วยบริษัทที่เล็กที่สุดเท่าที่จะเป็นไปได้
ทำธุรกิจ SaaS ด้วย Clojure มา 10 ปี และคงเป็นไปไม่ได้หากไม่มี Clojure
แนะนำ <a href="https://www.flow-storm.org/">Flow Storm</a> สำหรับคนที่ใช้ Clojure
ได้เรียนรู้อะไรมากมายจาก Rich Hickey และเคยมีความหลงใหลใน Clojure กับ FP
มีข้อสังเกตว่าเอกสารของ ClojureDocs ค่อนข้างล้าสมัย และอยากเพิ่มฟีเจอร์ให้โหวตคำตอบได้
รู้สึกประหลาดใจกับเรื่องความเสถียรของ Clojure เพราะทุกครั้งที่ลองในแต่ละปีเหมือนทุกอย่างเปลี่ยนไปหมด
เริ่มจาก Common Lisp แล้วจึงย้ายไป Go และ Rust แต่ช่วงนี้กลับมามอง Clojure อีกครั้ง