Có phải lập trình trong triết lý UNIX giống như lập trình Chức năng?


30

Môi trường lập trình UNIX (văn bản cổ điển) nói rằng phương pháp lập trình UNIX là xây dựng các công cụ nhỏ, được xác định rõ có thể kết hợp để giải quyết các vấn đề phức tạp hơn. Khi học C và shell Bash, tôi đã thấy đây là một khái niệm mạnh mẽ có thể được sử dụng để giải quyết một loạt các vấn đề lập trình.

Chỉ cần sử dụng nền tảng Linux, khái niệm này khá rõ ràng và được sử dụng mọi lúc. Bất kỳ biểu thức nào được hình thành trên dòng lệnh chuyển hướng I / O, liên kết các công cụ hệ thống như ls, grep, v.v., cho thấy khái niệm này mạnh đến mức nào.

Điều làm tôi bối rối là nhiều chương trình trong số này được viết bằng C, sử dụng kiểu lập trình bắt buộc / thủ tục, nhưng cách chúng được sử dụng và kết hợp với nhau trên dòng lệnh có vẻ giống như lập trình chức năng đối với tôi, trong đó mỗi chương trình là một chức năng riêng biệt không phụ thuộc vào trạng thái của bất kỳ chương trình nào khác mà nó có thể được tham gia.

Điều này có chính xác không, hiểu triết lý lập trình UNIX về cơ bản là lập trình chức năng bằng cách sử dụng các công cụ có thể đã được xây dựng bằng cách sử dụng một kiểu lập trình bắt buộc?


5
Tôi không nghĩ điều quan trọng là sự tương tự đó có chính xác hay không. Câu hỏi là, nó là một tương tự hữu ích cho bạn? Liệu suy nghĩ về nó trong các điều khoản đó có giúp bạn viết chương trình và hoàn thành công việc không?

Câu trả lời:


19

Tôi nghĩ rằng bạn đã có một điểm ở đó, nhưng cp, rm, cdvà rất nhiều người khác thay đổi trạng thái, vì vậy họ không thực sự chức năng. Triết lý UNIX là nhiều hơn về việc chỉ làm một điều nhưng làm nó tốt; thường làm tốt điều đó có nghĩa là cho phép sử dụng chức năng, nhưng không phải lúc nào cũng vậy.


9

Câu trả lời là trong "Lập trình vỏ đơn và UNIX" của Oleg Kiselyov.

Đây là một bài tiểu luận lấy cảm hứng từ bài viết "Cách tuyên bố mệnh lệnh" của Philip Wadler [ Wadler97 ]. Chúng tôi sẽ chỉ ra những điểm tương đồng kỳ lạ giữa i / o đơn âm trong Haskell và các chế phẩm bộ lọc UNIX dựa trên các đường ống và chuyển hướng. Các ống UNIX (được xử lý theo ngữ nghĩa như ghi vào các tệp tạm thời) khá giống với các đơn nguyên. Hơn nữa, ở cấp độ lập trình UNIX, tất cả i / o có thể được coi là đơn nguyên ...


6

Chà, tôi đoán bạn có thể nhìn nó theo cách đó nếu bạn bỏ qua toàn bộ vấn đề tác dụng phụ. Các lệnh Unix thường KHÔNG hoạt động chức năng liên quan đến việc luôn trả về cùng một tập dữ liệu với cùng các đầu vào. Tuy nhiên, như bạn đã đề cập, khía cạnh đường ống tương tự như cách lập trình chức năng có thể được thực hiện.


1
Bạn đã thực sự có một chiếc máy bay ?? ;) (xin lỗi vì nhận xét không chính thức)
BlackBear

@BlackBear Không phải cá nhân của riêng tôi. Tôi đang ở trong một câu lạc bộ nơi có khoảng 50 người trong chúng ta cùng sở hữu 4 máy bay. Đó là một chút giá cả phải chăng theo cách đó. :-)
Brian Knoblauch

@Brian Knoblauch: Tôi muốn có một chiếc máy bay trong tương lai .. tiền cho phép: P
BlackBear

5
Lập trình chức năng không ngụ ý "không có tác dụng phụ". Khái niệm trong đó cùng một chức năng luôn tạo ra cùng một kết quả được gọi là "idempotence" và không phải là điều kiện cần thiết để một chương trình có chức năng. Điều này còn được gọi là "chức năng thuần túy".

2

Ở một mức độ nào đó bạn có thể nói rằng. Nhưng điều đó không nhất thiết đúng. Tôi nghĩ bạn nên đọc nhiều hơn như 'khả năng đạt được nhiều hơn' với phương pháp thiết kế đơn giản. Và để đơn giản, bạn sẽ phải phân chia nhiệm vụ thành các phần dễ hiểu và dễ lắp ráp. Triết lý UNIX thẳng thắn với bạn, có thể được giải thích với ví dụ sau.

Tất cả các chương trình là một số loại thao tác dữ liệu! Và trong một số trường hợp lập trình cũng là chính thao tác lập trình (lập trình Meta). Bây giờ cách triết lý UNIX hoạt động là, Hãy tưởng tượng xử lý văn bản. Văn bản là gì? Văn bản là một số loại dữ liệu sau khi tất cả. Khi tập hợp thành định nghĩa có tổ chức, Văn bản cũng trở thành của XML và JSON. Văn bản cũng có thể là một danh sách các số, Văn bản cũng có thể là csv, tsv và những gì không! Trong Văn bản hoặc chuỗi khác có thể đại diện cho một vùng dữ liệu lập trình khổng lồ thực sự, chỉ vì bối cảnh của nó có thể xoắn và biến thành những gì chúng ta muốn!

Tất cả các chương trình yêu cầu tổ chức dữ liệu của một số loại. Tổ chức yêu cầu tìm kiếm ...

a. Ở đó bạn chỉ cần có 'grep', 'fgrep' và gia đình của nó để làm điều đó.

Khi bạn tìm kiếm, bạn cần thực hiện một số sắp xếp ..

b. Bây giờ chúng ta có lệnh 'sort' để làm điều đó.

Bạn vừa mới sắp xếp hai tệp, bây giờ bạn muốn so sánh chúng.

c. Bây giờ chúng tôi có 'diff', 'cmp' et al để làm điều đó.

Bạn vừa tìm thấy không có sự khác biệt giữa các tập tin. Bạn cần thêm dữ liệu có tổ chức bây giờ.

d. Bạn có 'mèo', đường ống và toán tử chuyển hướng để ghi vào một tệp.

Bạn cần phân tích cú pháp cụ thể hơn ..

e. Bạn có đầu, đuôi, nhiều hơn, ít hơn, cắt et al để làm điều đó ...

Tất cả điều này được khâu lại với nhau bằng cách sử dụng '|' để tạo ra thứ thực sự mạnh mẽ một thời gian mà không cần viết bất kỳ mã nào cả. Để tìm kiếm nhiều hơn và may bạn có ..

f. awk, vỏ và sed.

awk, shell và sed cung cấp cho bạn quyền kiểm soát văn bản nhiều hơn những gì cắt, diff et al có thể cung cấp cho bạn. Bạn đã bao giờ tự hỏi rằng lệnh1 | lệnh2 | lệnh3 ... loạt là một loại cơ chế dòng công việc. Khi kết hợp với If, điều này trở nên mạnh mẽ hơn.

Bây giờ đến nhiều niềm vui.

Bạn đã bao giờ nghe nói về một tiện ích được gọi là 'Perl' , thứ này mạnh đến mức bạn hầu như có thể thực hiện bất kỳ nhiệm vụ nào trong tay với ít công việc có thể tưởng tượng được. Được kết hợp với một tiện ích như DBM, bạn có thể thực hiện các yêu cầu bền bỉ thời gian nhỏ cho ứng dụng của mình. Hãy nhớ rằng chúng ta thậm chí chưa bước ra khỏi thế giới văn bản nhưng vẫn xoay sở được hầu hết các khía cạnh của môi trường lập trình.

Vì vậy, tôi nghĩ UNIX không chỉ là một hệ điều hành. Đây là một bộ sưu tập các công cụ và môi trường được thiết kế để giải quyết các vấn đề theo cách đơn giản nhất. Một cách đơn giản không nhất thiết ngụ ý sự đơn giản của việc thực hiện giải pháp. Nhưng sự đơn giản tự nó không đưa bạn đi xa.

Tôi đọc cái này ở đâu đó trên reddit.

"Nếu mục tiêu thiết kế duy nhất của bạn là đơn giản, bạn sẽ có được nhiều người dùng như Plan9"


1

Cách chúng được nối với nhau trên dòng lệnh và tương tác với nhau rất có chức năng. Tuy nhiên, tôi muốn nói rằng điều này có liên quan nhiều hơn đến thiết kế của vỏ và ít liên quan đến việc các chương trình cơ bản đó được viết một cách bắt buộc hay theo chức năng. Hầu hết các ngôn ngữ chức năng tốt đều hỗ trợ các khái niệm bắt buộc / thủ tục, mặc dù thiết kế tổng thể của chúng cho vay để lập trình chức năng. Có nhiều tính năng shell UNIX sử dụng các khái niệm chức năng, nhưng, một lần nữa, điều này là do thiết kế của shell hơn là việc thực hiện cụ thể của các chương trình cơ bản.

Hi vọng điêu nay co ich,

-tjw

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.