Functional programming không có gì to tát

Hãy tưởng tượng bạn đang phụ trách triển khai một dự án, thời gian diễn ra của cuộc tưởng tượng là một ngày đẹp trời, đường khô ráo và không kẹt xe. Bạn đến công ty. Bạn đưa cho nhân viên kế toán một bảng kê gồm dăm mục các khoản doanh thu và chi phí dự trù của một dự án và yêu cầu nhân viên này tính toán và đưa lại con số lợi nhuận(*). Một giờ sau, khi được hỏi lại, nhân viên này vừa khóc mếu trả lời “Đây là bản doanh thu dự trù mà ban nãy anh vừa yêu cầu, có điều em không chắc là kết quả có đúng hay không, vì hôm nay giá xăng vừa tăng thêm 500 đồng/lít!”

Bạn nổi giận trước nguyên nhân vô lí này thì nhận được lời giải thích rất cảm động: “Vì giá xăng tăng, hôm nay chị kế toán trưởng cứ cằn nhằn cả buổi, làm em không tài nào tập trung cộng trừ cho được…”.
Bạn muốn phát điên!

Câu chuyện chưa dừng lại. Mặc dù bạn đang bực tức thay cho nhân vật mà mình nhập vai thì hôm đó trời vẫn đẹp. Bạn đành tự tính toán lấy mấy con số rồi cầm bản kế hoạch với đầy đủ chữ kí xuống phòng tài chính để lấy kinh phí triển khai. Nhưng mặc dù đã được duyệt chi, bạn vẫn phải chờ… bộ phận an ninh cầm chìa khoá đến mở két.

Đến đây thì bạn hoàn toàn thất vọng và quyết định… ngừng tưởng tượng. Bạn trở lại với bài viết này. Về phần công ty kia, với cung cách làm việc như thế, cũng đã phá sản khi bạn đọc đến dòng cuối cùng của bài viết. :)

Ở Việt Nam, khái niệm functional programming hoàn toàn xa lạ. Cá biệt, có trường hợp người ta tìm cách khiến cụm từ này trở nên xa lạ hơn bằng cách dịch từng-từ-một, gây choáng váng cho không ít người chỉ quen tiếp cận với các tài liệu về công nghệ bằng tiếng Việt.

Cũng may ở Việt Nam mô thức phát triển theo MVC được thừa nhận rộng rãi (mặc dù số áp dụng đúng lại vô cùng hiếm hoi!) nên việc giải thích về functional programming cũng dễ dàng hơn.
Mô thức MVC là việc phân tách rõ ràng giữa dữ liệu (Model), cấu trúc điều khiển/logic (Controller) và cách thức trình bày (View).

The central idea behind MVC is code reusability and separation of concerns. (Ý tưởng chủ đạo đằng sau MVC là tính tái sử dụng và sự phân tách các yếu tố quan trọng).

Functional programming (FP) trước hết cũng là cách tiếp cận theo hướng trên, nhưng áp dụng đến cấp độ từng “tế bào” (các cấu trúc nhỏ nhất, chẳng như các function). Đó là việc phân chia hợp lí mã nguồn thành các đoạn chương trình độc lập với nhau. “Độc lập” có nghĩa là mỗi đoạn chương trình này không phụ thuộc vào nhau cũng như không phụ thuộc vào môi trường chung.

Để kiểm nghiệm được tính độc lập nói trên: các đoạn chương trình luôn trả về một kết quả duy nhất với mỗi bộ tham số truyền vào (chúng giống các hàm trong toán học!).  Các đoạn chương trình đảm bảo được tính chất này được gọi là các pure function.

Ngược lại với các pure function là các non-pure function: chúng hoặc phụ thuộc vào môi trường bên ngoài, hoặc làm thay đổi yếu tố nào đó của môi trường (gọi là có “side-effect”).

Tất nhiên khi phát triển các phần mềm thực sự thì không tránh khỏi các hàm non-pure. Tuy nhiên, cần đảm bảo:

  • Tránh tối đa các hàm non-pure
  • Khi buộc phải sử dụng một hàm non-pure, phải khoanh vùng được các tác nhân khiến cho hàm có tính chất “lật lọng” -> cho vào danh sách đen và kiểm soát thay vì “thả gà ra để bắt”.

Khi đọc về FP, nhiều người thốt lên: Oh, tôi cũng ít nhiều áp dụng nó đấy! Vâng, điều này là hoàn toàn tự nhiên. Điều bạn cần là áp dụng nó một cách triệt để. Khi đó, bạn sẽ có được những  lợi ích của functional programming như:

  • dễ dàng tái sử dụng mã
  • dễ thích nghi khi có thay đổi
  • dễ thực hiện unit test, đặc biệt là TDD, do đó chương trình ít lỗi hơn hẳn.
  • dễ dò tìm lỗi khi phát sinh

Theo bạn, trong trường hợp nào thì chương trình dễ đọc hơn và kết quả có độ tin cậy cao hơn?

Kết luận:

Bài viết ở đây chỉ là chuyện phiếm, để hiểu lợi ích của functional programming, hãy dành thời gian để học một ngôn ngữ thuần functional (pure functional programming language) trước. Erlang/Haskell/Clojure/Racket/Shen… là những lựa chọn tốt. Tránh những ngôn ngữ “thập cẩm” như Python, Scala, F#, ít nhất là đến khi bạn đã thực sự hiểu được FP là gì.
FP sẽ giúp bạn có tư duy đúng đắn và thực sự hiệu quả về input/output của từng đoạn chương trình.
FP là một hướng tiếp cận đã có từ lâu nhưng mãi đến gần đây mới giành được sự quan tâm rộng rãi, khi mà khối lượng của các bài toán thông tin đã lớn hơn trước rất nhiều lần. Các khái niệm xuất phát từ FP cũng được các ngôn ngữ non-FP đưa vào như closure, higher-order function, lazy evaluation.

Tham khảo thêm:

https://en.wikipedia.org/wiki/Functional_programming
http://en.wikipedia.org/wiki/Imperative_programming
http://www.haskell.org/haskellwiki/Functional_programming
http://www.haskell.org/haskellwiki/Why_Haskell_matters
http://dunsmor.com/lisp/onlisp/onlisp_7.html
http://doc.cat-v.org/programming/bad_properties_of_OO

Việc bạn sử dụng ngôn ngữ gì phụ thuộc vào công việc và cả sở thích (mặc dù một số thì có hại hơn số khác!), nhưng những kĩ thuật của FP cũng có thể áp dụng vào các ngôn ngữ non-FP (cách này gọi là functional programming style). Nhưng để áp dụng hiệu quả – tốt nhất, như đã nói – là thành thục ít nhất một ngôn ngữ FP.

Trách nhiệm với bài viết

  • Tác giả đảm bảo trách nhiệm cá nhân với nội dung bài viết và có thể cập nhật/bổ sung/sửa đổi để phù hợp với tình hình.
  • Người đọc được quyền đăng tải lại bài viết với mục đích phi lợi nhuận với điều kiện tôn trọng nguyên bản bài viết, bao gồm giữ nguyên cả thông tin bản quyền dưới đây. Việc giữ liên kết đến bài viết khi đem chia sẻ cũng là cách bạn giúp tác giả đảm bảo trách nhiệm được cam kết ở trên.
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Vietnam License.

Posted on by Hoàng Minh Thắng | Leave a comment

Test Driven Development (TDD), why?

(Lưu ý:

  • Tài liệu này được tôi viết với tư cách là một nhà thực hành. Mục đích chủ yếu là phân tích tính ưu việt của TDD với hi vọng giành được sự đồng tình của các nhà quản lí, người dạy và người học.
  • Quy trình được giới thiệu sau đây không quá phức tạp, tuy nhiên nó đòi hỏi phải hiểu đúng và thực hiện nghiêm túc: một nguyên tắc bị làm trái sẽ giống như vào phòng mổ với một trong các dụng cụ phẫu thuật chưa vô trùng!
  • Sẽ có người muốn lướt nhanh để tìm một danh sách dạng “làm thế nào”. Nhưng đáng tiếc tôi không thể viết các hướng dẫn “cầm tay chỉ việc” hơn được, vì:
    • Có quá đa dạng các ngôn ngữ lập trình (và kéo theo đó là các test framework).
    • Tài liệu là một bài viết, tức là việc giao tiếp một chiều, do đó không có cách nào để đảm bảo người thực hành không vô tình “bỏ bớt” một quy trình, trong khi việc đó dẫn đến mất ngay hiệu quả và tâm lí chán nản.
    • Bài viết không tham vọng diễn đạt bằng chữ nghĩa thứ mà người ta cần khoảng một giờ đồng hồ thực hành để hiểu và nhiều ngày tháng để ghi nhớ.
    • Việc thống nhất được cái “vì sao” quan trọng hơn, còn “làm thế nào” nên là phần việc chính của người học. Chỉ có hiểu bản chất mới giúp bạn đi đúng đường.
    • Quy trình TDD đứng riêng rẽ (không thực hành, không lí giải) trông rất ngớ ngẩn! :)
  • Để sử dụng thành thục TDD cũng đòi hỏi một thời gian để thay đổi thói quen.
    • Hãy thường xuyên đối chiếu những gì bạn làm với tài liệu này, điều chỉnh dần cho đến khi không còn “phạm quy”!
    • Xem mục “Nếu bạn chưa thành công, đừng ngần ngại!”)
Posted in Programmable | Tagged , , , , , , , , , | 5 Comments

Quản lí phiên bản (Revision Control hay Version Control)

(Lưu ý:

  • Đây là một bài viết giới thiệu chung nhất về quản lí phiên bản.
  • Bài viết hướng đến đông đảo người đọc: bạn không bắt buộc phải biết về CNTT để hiểu bài viết này.
  • Bạn không bắt buộc phải đọc hết ngay bài viết mà có thể lướt qua các chủ đề mình quan tâm. Cuối bài có phần tổng kết cho những ai muốn có kết luận nhanh.
  • Những ai muốn tìm hiểu sâu hơn nên tiếp cận các tài liệu tiếng Anh với mục “Đọc thêm” ở cuối bài.)

Quản lí phiên bản là gì? Nó có cần thiết không? Nó có khó học không?

Có vẻ như Quản lí phiên bản (Revision Control/Version Control) không mấy phổ biến ở Việt Nam, phải chăng đây là một thứ rất hi-tech, làm những công việc hết sức phức tạp và cao siêu? Ai đó có thể thốt lên: cả đời tôi chưa bao giờ động đến thứ đó! Vậy liệu rằng Quản lí phiên bản có phải là việc riêng của lập trình viên? Hãy thử cùng nhau xem một vài ví dụ:

Continue reading

Posted in Programmable | Tagged , , , , , , , , , , , | Leave a comment

Học văn… (tưởng tượng thôi!)

Suy nghĩ lẽ ra phải có của mấy vị suốt ngày đưa thông tin giáo điều về “ốp” dân ta, kiểu “Đấy, giá Việt Nam ta làm cái A, cái B, cái C… có phải là giờ sướng rồi không?”

Continue reading

Posted in Life is simply Uncategorizable | Tagged , , , , , | Leave a comment

Về cuộc thi “Mùa hè sáng tạo” 2012

Ban đầu tôi định viết thành một bài dài, nhưng sau đó thấy cần thiết phải chia thành nhiều thread ngắn (các mục Thảo luận phía sau đây khi gửi lên mailing list mỗi thảo luận này sẽ là một thread) để mọi người dễ theo dõi và trao đổi thẳng thắn.

Các mục thảo luận này khi được đưa ra trao đổi có thể gây tranh cãi, do đó cần thống nhất (thông qua trao đổi) trước mấy nguyên tắc:

  • không vì số đông mà bỏ ĐÚNG theo SAI, ưu tiên MỤC TIÊU hơn HIỆN TRẠNG
  • mục tiêu của MHST là mục tiêu của khoa học và giáo dục, tức là mục tiêu dài hạn.
  • cụ thể hơn nữa, mục tiêu của MHST là vì sinh viên/những người đang học CNTT và vì tương lai ngành CNTT Việt Nam
  • nguyên tắc sự thật: trung thực và công khai khi cung cấp các thông tin trong tranh luận, cũng như trong việc công bố quá trình cộng tác của người dự thi, doanh nghiệp, và chuyên gia.
Posted in Life is simply Uncategorizable | Tagged , , , , , , , , , , , | 1 Comment