Blending functional programming with imperative. Higher-level of abstraction or functional core.

ดัดแปลงและเพิ่มเติมจากคอมเมนต์คำถามในโพสนี้ https://www.facebook.com/nuttanart/posts/1015437440718608 เป็นคำถามจาก Supanat IBoss Potiwarakorn

ผมได้ยินคนพูดถึง functional core, imperative shell มาซักพักและ แต่ผมก็มักจะได้ยินว่า functional เนี่ยเป็น higher level abstraction เราแอบเอาลำดับขั้นตอนการทำงานต่างๆ ไปแอบไว้ภายใต้ declarative code ผมก็เลยยังรู้สึกสับสนอยู่เล็กน้อย (รู้สึกว่าเห้ย ถ้าเป็น shell มันต้องอยู่บนกว่าสิ)

เท่าที่ผมเข้าใจคือ monad เนี่ยมันคือเหมือน imperative shell ซึ่งจริงๆ แล้วมันก็คือ เรา แอบ state mutation เอาไว้ ไอสองเรื่องที่ผมพูดอ้างถึงบนนี่มันไม่ได้ขัดแย้งกัน แต่มันแค่อธิบายในคนละมุมกันถูกมั้ยฮะ

คำตอบของผม

จริงๆ เราคิดอะไรคล้ายๆ กันนะเนี้ย ผมก็เคยสงสัยเรื่องเดียวกันนี้เลย จำไม่ได้แล้วว่าตอนนั้นตอบตัวเองว่ายังไง แต่ถ้าพยายามตอบคำถามนี้ด้วยความเข้าใจในปัจจุบันจะตอบแบบนี้

ตอนนี้มีสองเรื่อง
a) functional เป็น declarative (higher-level abstraction) อยู่ด้านบน ส่วน imperative (lower-level abstraction) อยู่ด้านล่าง อย่างเช่นเราเขียน map,reduce โดยไม่ต้องวนลูปเอง
b) imperative อยู่ด้านบน functional อยู่ด้านล่าง ตามแนวคิด Functional Core, Imperative Shell เช่น เอา UI, http request, database ไว้ด้านบน หรืออย่าง Actor  model

เวลาเราเขียนโปรแกรมจริงๆ เราจะไม่ได้คำนึงถึงข้อ a) อะเพราะไม่ใช่หน้าที่เราจะต้องไปสนใจการทำงานตรงนั้น platform มีหน้าที่การันตีให้เรา ด้านล่างของเรามันไม่ functional อยู่แล้ว แต่ platform ทำให้เรารู้สึกว่าเราควบคุมทุกอย่างได้ในลักษณะ functional (input – output) แต่สำหรับ b) เราต้องสนใจเพราะเป็นสิ่งที่เราต้องเป็นคนสั่งให้มันทำ เพราะฉะนั้นแล้วในชั้นของเราที่ใช้ภาษาเขียนเพื่อแก้ปัญหาอื่นๆ เราคงโฟกัสที่ b) มากกว่า ส่วน a) สำหรับเราน่าจะสำคัญแค่ตอนที่เราอธิบายให้คนอื่นฟังว่า functional มันทำงานยังไงแค่นั้นมั้ง

จริงๆ แล้วเราอาจจะต้องไปเขียน imperative ด้านล่างบ้างก็ได้ แต่เราก็ควรห่อให้ imperative นั้นเรียบร้อยอยู่ภายในแล้ว expose ออกมาเป็นแค่ functional ให้ด้านบนใช้ ผมเชื่อว่าการที่ด้านล่างของเราเรียบง่ายและตรงไปตรงมาจะทำให้เราสามารถเข้าใจระบบโดยรวมของเราได้ง่ายกว่า จะเพิ่มฟีเจอร์ก็มั่นใจ จะ debug ก็ไล่ได้ง่าย

ผมชอบประโยคนี้ของ José Valim (ผู้สร้าง Elixir)

I often summarize functional programming as a paradigm that forces us to make the complex parts of our system explicit

ผมคิดว่าการที่เราเอา imperative ซึ่งเป็นส่วนที่ยากขึ้นมาไว้ด้านบน (ไม่ซ่อนอยู่ด้านล่าง) เป็นตัวอย่างที่ดีมากของการทำให้ complex parts explicit

ส่วนเรื่อง monad นี่ไม่รู้เลยอะ(เขียน clojure ไม่ต้องรู้จัก monad 😜) แต่ก็เคยได้ยินมาบ้างเหมือนกันที่ว่ามองมันเป็น imperative shell ได้

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s