Monthly Archives: August 2017

Clojure กับเครื่องหมายมากกว่าและเครื่องหมายน้อยกว่า

Twitter thread นี้คุยกันเรื่องเครื่องหมายมากกว่าและน้อยกว่า ผมได้เทคนิคที่มีประโยชน์กับผมมากเลยครับ

DG0IhziUAAE1Lg2.jpg

ผมเป็นคนที่มีประสบการณ์เดียวกับคนต้น tweet ที่ครูสมัยประถมสอนการจำเครื่องหมายมากกว่าและน้อยกว่าว่า เหมือนกับปาก ที่จะหันไปกินสิ่งที่มากกว่าเสมอ ซึ่งผมก็จำแบบนั้นมาตลอดชีวิตการเรียนวิชาเลข จนมาถึงการเขียนโปรแกรมด้วยภาษาอื่นๆ ที่เป็น infix notation ผมมองเห็นภาพปากหันไปด้านที่มากกว่าเสมอ

พอมาเขียน Clojure ซึ่งเป็น prefix notation ผมต้องใช้วิธีจินตนาการย้ายตำแหน่งของโอเปอเรเตอร์กลับไปอยู่ตรงกลางแบบ infix ทุกครั้ง ที่ก็ถูกต้อง แต่มันมีข้อเสียอยู่ตรงที่ผมกลายเป็นต้องคิด 2 จังหวะอยู่ตลอด ซึ่งมันช้า ในลักษณะเดียวกับที่เวลาเราจะพูดภาษาอังกฤษเราต้องคิดเป็นภาษาไทยก่อนแล้วค่อยๆ แปลเป็นภาษาอังกฤษนั่นแหละ

และโดยเฉพาะอย่างยิ่งโอเปอเรเตอร์ของ Clojure สามารถเปรียบเทียบได้มากกว่า 2 ค่าอีก เช่น (> 3 7 8 5) ผมต้องค่อยๆ มองทีละคู่ ยิ่งทำให้ช้าไปกันใหญ่

ใน twitter thread นี้มีการพูดถึงวิธีการมองที่เหมาะกับ prefix notation ของ Clojure มากกว่า โดยให้มองเป็นการเพิ่มของค่าและการลดของค่าแทน ดังนี้

มองที่ขีดบนของเครื่องหมาย < ซึ่งจะเป็น / หมายถึงการเพิ่มจากน้อยไปมาก ถ้าตัวเลขที่ตามมาเพิ่มขึ้นจากน้อยไปมาก แปลว่าเป็น true หากไม่เป็นไปตามนั้น แปลว่า false
(< 1 4 5 7 9)

เช่นเดียวกัน > คือ \ หมายถึงการลดลงจากมากไปน้อย ถ้าตัวที่ตามมาลดลงจากมากไปน้อย แปลว่า true หากไม่เป็นไปตามนั้น แปลว่า false
(> 8 7 3 2)

สำหรับผมแล้วมันง่ายและเร็วมากขึ้นมากเลยครับ

REPL ของ Clojure

ตอบคำถามในกรุ๊ป Clojure in Thai

REPL ถ้ามองเผินๆ ก็จะคล้าย console หรือ interpreter ของภาษาอื่นๆแหละครับ แต่ของ Clojure จะเน้นให้เราสามารถส่งโค้ดจาก editor ได้ และด้วยความที่ภาษาออกแบบเรื่องการ redefine มาไว้ตั้งแต่ต้น ทำให้เราพัฒนาแบบ incremental / interactive ได้จริงๆ บวกกับการที่มันมีวงเล็บแสดงขอบเขตชัดเจนทำให้การเลือกส่งโค้ดกลุ่มใดๆ ไปที่ repl มันตรงไปตรงมาชัดเจนกว่า ลองคิดภาพดูว่าถ้าเราต้องการเปลี่ยน implementation แค่เมท็อดเดียวใน Ruby เราจะต้อง select โค้ดยังไงใน editor หรือถ้าเราจะ redefine class ใน python เราต้อง select โค้ดยังไง วงเล็บที่ชัดเจนของ Clojure ช่วยในเรื่องนี้ได้มาก

อีกเรื่องหนึ่งที่สำคัญ คือ การทำงานของ Clojure แบบที่เราสั่งให้มันอ่านไฟล์ทั้งหมดเอง กับการที่เราค่อยๆ ส่งทีละ expression ไปที่ repl จะมีค่าเหมือนกัน 100% ทำให้เราไม่ต้องคอยกังวลถึงความแตกต่างใดๆ

ถ้าใครเป็นคนที่ชอบได้รับ feedback เร็วๆ ในระหว่างการ development ชอบ feedback เร็วๆ ของ TDD สำหรับผมแล้ว REPL นี่เร็วกว่า TDD อีก

ถ้าใครที่เชื่อในเรื่องการ make it work ก่อน make it right จะพบว่าเราสามารถเริ่มจากโค้ด snippet ที่ทำงานได้ แล้วค่อยๆ ปั้นไปจนได้โปรแกรมที่มีโครงสร้างชัดเจน maintain ง่ายได้เลยผ่านการเล่นกับ REPL นี่แหละ

Clojure กับการ model โปรแกรมด้วย data structures

ตอบคำถามในกรุ๊ป Clojure in Thai

การ model โปรแกรมด้วย data structures เนี้ยก็คือ model โดยใช้ map ซ้อน map ซ้อน map นี่หละครับ ตอนที่เห็นครั้งแรกผมคิดว่านี่เราถอยหลังลงคลองกันหรือเปล่า นี่มัน Primitive Obsession ซึ่งเป็น code smell แบบหนึ่งหนิ ผมถูกสอนมาในยุค OO ที่เค้าให้ผมสร้าง class ขึ้นมาเพื่อให้เกิด encapsulation และ data hiding เพื่อที่จะได้ระบบที่ high cohesion, low coupling

  • แต่พอได้ทำลองทำจริงๆ กับ Clojure ก็พบว่า เออมันก็ยืดหยุ่นกว่านะ
    มันทำให้ reuse โค้ดได้ง่ายขึ้น เพราะฟังก์ชันไม่ผูกกับ class เราจะเอาฟังก์ชันนี้ไปใช้กับ data structure ไหนก็ได้ ส่งผลให้โค้ดเบสโดยรวมมีขนาดเล็กลงด้วย
  • สร้าง data ขึ้นมาสำหรับเทสก็ง่าย
  • debug ก็ง่าย print ออกมาดูได้เลย ไม่ต้องไป override toString ของ class นั้นๆ
  • จะเทียบ equality ก็ทำได้ทันที ไม่ต้องไป override hashCode
  • แปลงเป็น json ก็ง่าย serialize, deserialize ได้ไม่ยาก

หลายๆ คนที่เค้าเขียน JavaScript ในสไตล์ functional programming เค้าก็อาจจะใช้วิธีนี้กันอยู่บ้างแล้ว แต่พอเป็น Clojure ก็จะได้ข้อดีครงที่ immutable data ก็จะเพิ่มปลอดภัยให้อีกชั้นนึง และมี standard library พร้อม ทำให้ทุกๆ คนใช้ไลบราลีเดียวกัน