Programming Paradigms: Không chỉ có hướng đối tượng
Các mẫu hình lập trình khác nhau sẽ cho lập trình viên hay người sử dụng ngôn ngữ đó một cái nhìn chung về cách mà ngôn ngữ đó vận hành...

Happy New Year 2022!
Chúc các đọc giả của Góc Của Chung có một năm mới bình an và đạt được các mục tiêu tiếp theo 🎈🎉🎊
Mặc dù đã bỏ bê việc viết blog trong một khoảng thời gian khá dài, nghĩ đi nghĩ lại thì cảm thấy bản thân mình thật vô trách nhiệm. Nhưng cái quan trọng hơn là tài khoản sắp bị trừ thêm hai triệu tiền hosting nên ít nhiều mình cũng nên viết blog lại để xứng đáng với số tiền bỏ ra 🥲. Vòng vo vậy đủ rồi, vào với nội dung chính của bài viết hôm nay thôi. Là một người học lập trình cũng khá lâu, tuy nhiên mình cũng chưa thể nắm hết được những điều thú vị của nó. Trong lập trình, có một khái niệm là Programming Paradigms hay Mẫu hình lập trình mà nếu bạn hứng thú về khoa học máy tính thì không nên bỏ qua.
Ngôn ngữ lập trình (Programming Language)
Trước khi đào sâu vào các mẫu hình lập trình phổ biến của các ngôn ngữ hiện nay thì như thường lệ, chúng ta sẽ đi qua về khái niệm và nguồn gốc của cụm từ này trước. Ngôn ngữ lập trình không chỉ có một, hiện nay có tới loanh quanh đâu đó 700 ngôn ngữ lập trình. Mỗi ngôn ngữ lập trình sẽ đóng vai trò riêng trong việc phát triển, giao tiếp với máy tính. Thậm chí cũng có các ngôn ngữ lập trình tạo ra chỉ cho vui và không một mục đích cụ thể nào cả (ngoài mục đích tấu hài).

Lấy ví dụ như TypeScript, đây đơn giản chỉ là một bản nâng cấp của Javascript với hệ thống kiểu dữ liệu (Type system) chặt chẽ hơn. Về bản chất thì Typescript để được hiểu bởi trình duyệt hoặc hệ thống cũng sẽ được biên dịch thành mã Javascript. Hay phổ biến hơn là C++ và C. Mặc dù được coi là hai ngôn ngữ lập trình khác nhau tuy nhiên với mình, C++ cũng giống như bản nâng cấp của C (nó rõ ràng vậy cơ mà 🙃). Từ đó, chúng ta có thể chia ra 2 dạng ngôn ngữ lập trình là Native và Non-native Programming Language. Nhưng chung quy thì các ngôn ngữ này vẫn đem lợi ích lớn đến việc cải thiện trải nghiệm của nhà phát triển và tối ưu hoá hiệu suất của chương trình. Không như là...

Cũng giống như trong crypto, nếu họ có memecoin thì ở đây chúng tôi cũng vậy, chúng tôi có meme programming language. Một trong các meme programming language mà mình thấy khá thú vị là TrumpScript. Đúng vậy, như cái tên của nó, ngôn ngữ này lấy cảm hứng từ Donald Trump và những điều luật, nghị định ông làm cho nước Mỹ.
Mẫu hình lập trình (Programming Paradigms)
Vòng vo vậy đủ rồi, bây giờ chúng ta sẽ đào sâu vào các mẫu hình lập trình được quy ước cho các ngôn ngữ lập trình nhé. Các mẫu hình lập trình khác nhau sẽ cho lập trình viên hay người sử dụng ngôn ngữ đó một cái nhìn chung về cách mà ngôn ngữ đó vận hành (thông qua cú pháp (syntax), hệ thống biên dịch, hàm built-in...). Tuỳ vào kiến trúc của hệ thống và mục đích sử dụng mà người dùng sẽ lựa chọn ngôn ngữ cho phù hợp.

Một số loại mẫu hình lập trình phổ biến

Các mẫu hình lập trình thường sẽ được chia vào 2 nhóm chính là Imperative Programming Paradigm và Declarative Programming Paradigm. Sơ lược qua về 2 mẫu hình lập trình này thì:
- Imperative Programming Paradigm (Mẫu hình lập trình mệnh lệnh): Định nghĩa và quy ước các bước cần thiết để thay đổi các trạng thái của máy tính. Nói theo hướng trừu tượng hoá thì lập trình mệnh lệnh sẽ yêu cầu bạn cung cấp đầy đủ các yêu cầu tối thiểu để đưa ra được luồng điều khiển phù hợp.
- Declarative Programming Paradigm (Mẫu hình lập trình khai báo): Trong khi đó, declarative sẽ có khuynh hướng trừu tượng hơn vì đây một mẫu hình lập trình theo phong cách xây dựng cấu trúc và các yếu tố của chương trình máy tính để thể hiện tính logic của sự tính toán mà không mô tả luồng điều khiển của nó.
Vì không cần mô tả luồng điều khiển của chương trình một cách tường tận, declarative có khuynh hướng sẽ cho ra hướng giải quyết ngắn gọn nhưng sẽ trừu tượng hơn cho lập trình viên chưa quen với mẫu hình này. Ngược lại với declarative, imperative yêu cầu người viết mã sẽ là người xác định luồng điều khiển của chương trình. Lấy ví dụ trực tiếp từ các ngôn ngữ đa hình như Python
# Imperative
small_nums = []
for i in range(20):
if i < 5:
small_nums.append(i)
# Declarative
small_nums = [x for x in range(20) if x < 5]
Hoặc một ví dụ khác từ ngôn ngữ lập trình PHP
# Imperative
$participantlist = [1 => 'Peter', 2 => 'Henry', 3 => 'Sarah'];
$firstnames= [];
foreach ($participantlist as $id => $name) {
$firstnames[] = $name;
}
# Declarative
$firstnames = array_values($participantlist);
Với mỗi mẫu hình tổng quát Imperative và Declarative, chúng ta sẽ có thêm các mẫu hình con của từng nhánh.
Các mẫu hình thuộc Imperative Paradigm

Đối với Imperative Programming, chúng ta sẽ có các nhánh con là (lưu ý: sẽ có các quy chuẩn khác nhau cho việc chia nhánh của từng loại mẫu hình. Tuy nhiên, phố biến nhất vẫn là các mẫu hình được liệt kê dưới đây)

- Structured Programming: Lập trình cấu trúc là một nhánh con của mẫu hình lập trình mệnh lệnh. Đây có thể được coi là mẫu hình tiền thân của mẫu hình lập trình phổ biến nhất - lập trình hướng đối tượng (Object-oriented Programming). Cách thiết kế của lập trình cấu trúc theo hướng top-down (trên xuống). Mẫu hình này nhắm vào việc cải thiện tính rõ ràng và chất lượng cũng như thời gian phát triển bằng cách sử dụng phiên bản mở rộng của các mệnh đề có điều kiện (if-else), vòng lặp (for-white), subroutines (các chương trình con) và block structure (cơ chế đóng - mở ngoặc tạo thành một khối code). Có thể kể đến 1 vài ngôn ngữ phổ biến thiết kế theo mẫu hình như là Pascal, ADA, Algorithmic Language...

- Procedural Programming: Lập trình thủ tục sử dụng phương pháp thủ tục chia một chương trình lớn thành các khối chức năng hay hàm đủ nhỏ để dễ lập trình và kiểm tra. Mỗi hàm có một điểm bắt đầu và một điểm kết thúc và có dữ liệu và logic riêng.
- Modular Programming: Lập trình mô-đun là một kỹ thuật thiết kế phần mềm nhấn mạnh việc tách chức năng của chương trình thành các mô-đun độc lập, có thể hoán đổi cho nhau, sao cho mỗi mô-đun chứa mọi thứ cần thiết để chỉ thực thi một khía cạnh của chức năng mong muốn. Mẫu hình lập trình này về định nghĩa khá là tương đồng với Procedural và Structure. Để có thể hiểu sâu hơn về điểm khác nhau và điểm mạnh cũng như điểm yếu của 3 loại mẫu hình imperative này, bạn cần có kinh nghiệm chinh chiến lâu năm với ngôn ngữ lập trình.

Các mẫu hình thuộc Declarative Paradigm

Đối với Declarative Programming, chúng ta sẽ có các nhánh con là
- Logic Programming: Lập trình logic là một mẫu hình lập trình dựa trên logic toán trong các mối quan hệ và các suy luận. Các chương trình được viết trong các Ngôn ngữ lập trình logic là các tập hợp câu logic, thể hiện sự thật và các luật về một vài vùng vấn đề nào đó. Cùng với các thuật toán suy luận, chúng hình thành nên chương trình.
- Functional Programming: Trong ngành khoa học máy tính, lập trình hàm là một mô hình lập trình xem việc tính toán là sự đánh giá các hàm toán học và tránh sử dụng trạng thái và các dữ liệu biến đổi. Lập trình hàm nhấn mạnh việc ứng dụng hàm số, trái với phong cách lập trình mệnh lệnh, nhấn mạnh vào sự thay đổi trạng thái. Quan điểm của mình thì để có thể thành thục Declarative Programming cần quá trình tu luyện và sự am hiểu về logic của ứng dụng rất nhiều. Vì điểm mạnh của lập trình hàm là tận dụng sức mạnh của các hàm thông qua việc điều khiển hàm số nên là kiến thức toán học cũng rất cần thiết.

Và đó là những gì mà bài viết mở màng sau 7 tháng không viết blog mang đến. Đây cũng là bài viết mở màng cho một năm 2022 đầy suông sẻ. Hi vọng trong năm nay, mình sẽ có thể viết được nhiều bài viết hay hơn về lập trình nói riêng và về cuộc sống của mình nói chung. Chúc các bạn có một năm mới đầy điều tốt đẹp! 🥰