Tôi nghi ngờ điều này phụ thuộc vào ngôn ngữ. Theo như lập trình chức năng, tôi chủ yếu tìm hiểu về Haskell, vì vậy tôi sẽ giải thích cách nó hoạt động ở đó.
Mã Haskell được tổ chức thành các "mô-đun" về cơ bản chỉ là tập hợp các hàm và kiểu dữ liệu. Mỗi mô-đun là một tập tin duy nhất. Một mô-đun là một thứ gì đó pha trộn giữa một lớp Java và một gói Java - phạm vi chính xác của những gì một mô-đun thực hiện khác nhau. Một mô-đun cũng có quyền kiểm soát các hàm và loại hàm xây dựng cần xuất và hàm nào cần ẩn; điều này tương tự private
và public
trong Java.
Trong các chương trình của riêng tôi, tôi muốn có các mô-đun làm một việc, về mặt ngữ nghĩa; điều này làm cho chúng giống như một lớp Java ngoại trừ việc chúng có thể định nghĩa nhiều loại dữ liệu. Các mô-đun tôi sử dụng từ thư viện tiêu chuẩn, giống Data.List
như các gói hơn - chúng cung cấp một tập hợp các hàm tiện ích tương tự. Điều này cũng rất giống với các lớp Java tĩnh như java.util.Arrays
.
Các mô-đun cũng giống như các gói Java ở chỗ chúng có thể được lồng vào nhau cho rõ ràng (tôi không nghĩ rằng điều này có bất kỳ ảnh hưởng nào đến chính mã). Nói chung, đối với một dự án duy nhất, tôi đặt tên cho nó Project
và nói rằng tất cả các mô-đun của tôi là một phần của điều này (ví dụ Project.Parse
và Project.Run
). Nếu tôi đang viết mã giống như một thư viện hơn là một ứng dụng, tôi sẽ tổ chức nó dựa trên những gì nó đang làm, như Data.List
hoặc Control.Monad
. Một điểm khác biệt lớn so với các ngôn ngữ khác là Haskell khuyến khích giới hạn IO và đặt tất cả ở một nơi. Một số lượng lớn các mô-đun hoàn toàn không có IO, và đối với bất kỳ dự án cụ thể nào, tôi muốn có càng nhiều mô-đun càng thuần càng tốt.
Ví dụ, tôi đang làm việc với một ngôn ngữ lập trình đơn giản mà tôi đang gọi TPL (không có lý do chính đáng). Để làm điều này, tôi đã tạo ra hai mô-đun đơn giản: TPL.Parse
xác định biểu diễn bên trong của ngôn ngữ và cách phân tích cú pháp, và TPL.Run
chạy trình thông dịch và xử lý các biến và IO. Để thực sự biên dịch và chạy mã, thường có một Main
mô-đun là điểm cuối cùng của chương trình.
Có sự tự do đáng kể trong việc tổ chức các chức năng trong một tệp; đây chỉ là những gì tôi muốn làm Tôi xác định các loại dữ liệu của mình về phía trên, trước khi chúng được sử dụng ở nơi khác. Ngay sau khi xác định các kiểu dữ liệu, tôi thực hiện bất cứ điều gì tôi cần để biến chúng thành một phần của kiểu chữ phù hợp của chúng - đây giống như việc thực hiện một giao diện. Sau đó, tôi làm theo logic và các chức năng trợ giúp khác nhau, khi thích hợp. Cuối cùng, tôi muốn có tất cả các chức năng IO của mình ở cuối cùng main
. Điều này làm cho nó rõ ràng chính xác những gì đang làm bất kỳ IO và nơi chương trình bắt đầu.
Vì vậy, tóm lại: các hàm được chứa trong các mô-đun, mỗi hàm được tạo thành từ một tệp duy nhất. Một số mô-đun có thể tạo nên một chương trình hoặc thư viện; cái trước thường bao gồm một Main
mô-đun là điểm vào của nó. Trong một tệp, có các tùy chọn khác nhau cho tổ chức, nhưng tôi thích nhóm các loại dữ liệu gần đầu, IO gần cuối và logic ở giữa.
What's stopping you from...
Nhiều năm và nhiều năm lập trình với một tư duy hoàn toàn khác, đến mức mã Haskell không tính toán được về mặt tinh thần. Và tất nhiên, bạn đang giả định rằng các dự án thực tế luôn được tổ chức chính xác và gọn gàng (có thể chúng là như thế nào nhưng một người mới như tôi biết?)