Hãy cùng điểm qua sự phát triển của ngôn ngữ lập trình và hãy xem chúng ta học được gì từ đó. Bài được đăng trên blog herbertograca.com.
Những năm 1950 – Lập trình phi cấu trúc
Assembly ~1951
Phát triển Phần mềm (software developement) là một hoạt động khá phức tạp. Việc lập trình chỉ được thực hiện ở một vài nơi trên thế giới. Assembly là một ngôn ngữ phổ biến thời điểm đó, nó sử dụng các thao tác cấp thấp như “add”, “sub”, “goto” và thao tác trực tiếp các địa chỉ bộ nhớ. Việc xây dựng một ứng dụng đơn giản rất chậm và khó. Để tạo một câu lệnh IF đơn giản, cần một vài dòng code và đối với một vòng lặp, sẽ mất nhiều hơn một vài dòng… Sau đó, khả năng nhóm (grouping) và sử dụng lại các đoạn code đã xuất hiện, và kiểu code rất tuyến tính và việc sử dụng lại code chỉ giới hạn trong phạm vi sao chép, dán trong cùng file hoặc giữa các files.
Những năm 1960 – lập trình có cấu trúc
Algol ~1958, Fortran
Lập trình có cấu trúc ra đời, giới thiệu các code blocks, các cấu trúc cho cấu trúc điều khiển (if / then / else, case, for, while, do,…) và các quy trình con. Sau đó, người ta có thể tạo ra các code flows thú vị hơn và quan trọng hơn. Đã có thể nhóm các mã lệnh (code instruction) và sử dụng lại chúng mặc dù còn một số hạn chế như các quy trình con luôn hoạt động trên cùng các biến toàn cục. Đó là thời điểm những ý tưởng đầu tiên về khả năng tái sử dụng (reusability) được đưa vào thực tế.
Những năm 1970 – lập trình thủ tục và lập trình hàm
Pascal ~1970, C ~1972
Lập trình thủ tục (procedural programming) và lập trình hàm (functional programming) ra đời vào những năm 1970. Trong thời gian này chúng ta có:
- Procedures: Tập hợp các lệnh không trả về dữ liệu;
- Functions: Tập hợp các lệnh trả về dữ liệu;
- Cấu trúc dữ liệu: Bản ghi, tương tự như một mảng kết hợp;
- Mô-đun: Các code file có thể được nhập (import) vào các code file khác.
Trong những năm 1970 cũng là lúc thuật ngữ “Spaghetti code” được đặt ra, sau lá thư của Edsger W. Dijkstra gửi cho Bộ phận Truyền thông của Hiệp hội Máy tính (CACM) vào năm 1968, với tiêu đề “Đi đến Tuyên bố được coi là Có hại” (Go To Statement Considered Harmful)
Vào cuối những năm 1970, những ý tưởng đầu tiên về Lập trình sự kiện (Event Oriented Programming) và Trygve Reenskaug viết bài báo của mình về MVC (sử dụng các sự kiện – events).
Với những cải tiến này, chúng ta có khả năng tái sử dụng (reusability) tốt hơn, vì các chương trình con hay subroutines (hàm và thủ tục) có thể thực hiện cùng một logic với các dữ liệu khác nhau. Chúng ta cũng có thể sử dụng model domain concepts bằng cách nhóm các dữ liệu liên quan thành các cấu trúc dữ liệu phức tạp. Và, cuối cùng, ta đã đưa ra các bước đầu tiên trong việc chia tách và mô-đun hóa, nơi chúng ta có thể tạo code có thể sử dụng lại trong các tập và sự kiện để tách code khách khỏi logic đang được thực thi.
Những năm 1980 – lập trình hướng đối tượng
Simula ~1965, Smalltalk-71 ~1971, C++ ~1980, Erlang ~1986, Perl ~1987,
Python ~1991, Ruby ~1993, Delphi, Java, Javascript, PHP ~1995
Lý thuyết và những manh nha về OOP bắt đầu từ những năm 1960, và được thực hiện lần đầu tiên trong những năm 1960 trong ngôn ngữ Simula.
Tuy nhiên, trong những năm 1980, việc sử dụng mô hình lập trình hiện tại đã trở nên tổng quát: Lập trình hướng đối tượng, với các mức độ hiển thị, phương thức (thông báo), đối tượng, lớp và sau này là các gói. Điều này cũng giống như nói tăng tính đóng gói và mô-đun
- Visibility levels (Mức độ phạm vi): cho phép bạn điều khiển những gì code có thể truy cập vào một tập dữ liệu cụ thể.
- Classes (lớp): cho phép định nghĩa hay mô hình hóa các domain concepts.
- Objects (đối tượng): cho phép chúng ta có các instances khác nhau trong cùng domain concepts.
- Packages (gói): cho phép nhóm các lớp lại với nhau để thể hiện một domain hay khái niệm hàm và làm việc cùng nhau trên cùng một ya1c vụ.
- Methods (phương thức): đại diện cho các thủ tục và chức năng, nhưng về mặt khái niệm nên được xem như là các thông báo (hoặc tốt hơn là các lệnh) có thể được cấp cho một loại đối tượng cụ thể.
Những năm 1990 – Lập trình hướng chủ đề và khía cạnh (Subject & Aspect Oriented Programming)
Trong những năm 1990, Lập trình hướng chủ đề và Lập trình hướng theo khía cạnh được đưa ra.
Lập trình hướng chủ đề (Subject Oriented Programming) yêu cầu các đại diện khác nhau của các đối tượng, tùy theo đối tượng đang “nhìn” vào nó. Ví dụ, trong khi con người có thể nhìn thấy gỗ khi nhìn cây, thì một con chim có thể nhìn thấy một lượng thức ăn và nơi trú ẩn. Dịch điều này sang một chương trình, có nghĩa là các thuộc tính và hành vi của đối tượng có thể khác nhau, tùy thuộc vào người gửi thông báo đến đối tượng (ai kích hoạt một phương thức trên một đối tượng).
Lập trình hướng theo khía cạnh (Aspect Oriented Programming)cố gắng tách biệt hoàn toàn các mối quan tâm xuyên suốt khỏi logic nghiệp vụ thực tế bằng cách đưa mã bổ sung vào thời điểm “biên dịch”. Một khía cạnh, ví dụ, một tên phương thức. Ví dụ, một mối quan tâm xuyên suốt là khai thác gỗ. Sử dụng AOP, chúng tôi có thể chỉ cần cấu hình hệ thống để đưa mã thực hiện đăng nhập vào tất cả các phương thức tuân theo một mẫu cụ thể, ví dụ: “ghi lại tất cả các lệnh gọi đến các phương thức có tên bắt đầu bằng‘ find ’“. (TYPO3 là một ví dụ về CMS sử dụng AOP)
Vượt qua OOP
Sau khi thành lập OOP, trọng tâm lớn là điều chỉnh bản thân để lập trình cho web, phát triển các ngôn ngữ hiện có, tạo ra các ngôn ngữ mới chuyên dụng cho phát triển web, phát triển các frameworks, điều chỉnh các công cụ và kiến trúc cho số lượng lớn các yêu cầu và dữ liệu ngày nay. .
Đã có một số nỗ lực để phát triển Ngôn ngữ lập trình, như Lập trình hướng theo chủ đề (hành vi của đối tượng là khác nhau, tùy thuộc vào chủ thể kích hoạt hành vi) hoặc Lập trình hướng theo khía cạnh (chèn mã tại thời điểm biên dịch), nhưng về bản chất là mô hình ngôn ngữ lập trình không thay đổi nhiều vì chúng tôi vẫn sử dụng OOP cho hầu hết các trường hợp, mặc dù các ngôn ngữ chức năng dường như đã được một số người áp dụng vào cuối năm nay (có thể là cường điệu?).
Kết luận
Trên đây là những tóm tắc những thập kỷ đầu tiên của lịch sử phát triển phần mềm. Các ngôn ngữ lập trình đã phát triển để cung cấp khả năng tái sử dụng, nhưng cũng để chuẩn bị cho phần mềm thay đổi (có thể là thay đổi chức năng, cấu trúc lại hoặc hoán đổi hoàn toàn một phần mã ), chúng phát triển theo hướng Modularity (ghép nối thấp) và Encapsulation (gắn kết cao).
Bài viết gốc có thể xem tại: https://herbertograca.com/2017/07/10/programming-language-evolution/