Kết quả của cuộc thảo luận bình luận ở đây , tôi tự hỏi liệu bạn có thể học Lập trình hàm trong C không?
Kết quả của cuộc thảo luận bình luận ở đây , tôi tự hỏi liệu bạn có thể học Lập trình hàm trong C không?
Câu trả lời:
Rõ ràng bạn có thể thực hiện lập trình chức năng trong C. Về lý thuyết, bạn cũng có thể học các nguyên tắc lập trình chức năng trong C, nhưng ngôn ngữ không làm cho nó dễ dàng.
Tôi giả sử bạn có ít nhất một chút nền tảng trong OOP; nếu bạn làm như vậy, bạn nên lưu ý rằng OOP có thể được thực hiện bằng C, bao gồm đa hình, getters / setters, quy tắc hiển thị, v.v., nhưng điều đó khá đau đớn để làm như vậy, và bạn cần biết cả OOP và C bên trong- ra để kéo nó ra Nó rất giống với FP.
Điều bạn nên làm trước tiên là học một ngôn ngữ lập trình chức năng (hầu hết chúng có các quy tắc cú pháp đơn giản đáng ngạc nhiên; đó không phải là cú pháp khiến chúng khó học), và sau đó để cho trí tuệ mới có được của bạn ảnh hưởng đến cách bạn viết C.
Theo yêu cầu, một vài điều bạn có thể học từ FP và sau đó áp dụng, giả sử, C, C ++ hoặc Java:
C có thể bị hack để cung cấp một số khái niệm chức năng:
Đây câu hỏi StackOverflow sẽ cho bạn biết thêm. Nhưng mặc dù có vẻ như có thể thực hiện lập trình chức năng (hoặc một tập hợp con lớn) trong C, hack và phần mở rộng trình biên dịch và bất cứ điều gì không phải là cách tốt nhất để tìm hiểu về một khái niệm.
Để thực sự học lập trình chức năng, đặt cược tốt nhất của bạn là một trong những ngôn ngữ lập trình chức năng nổi bật như Lisp và các phương ngữ của nó ( Clojure , Scheme ), Erlang và Haskell . Bất kỳ một trong số đó là những công cụ hoàn hảo hoạt động trong tư duy lập trình chức năng. F # cũng là một ứng cử viên tốt nếu bạn có nền tảng .Net, nhưng đó là ngôn ngữ đa mô hình, không hoàn toàn là ngôn ngữ lập trình chức năng.
Như tdammers ghi chú trong các ý kiến:
Trên thực tế, LISP, clojure và sơ đồ cũng là đa mô hình; Haskell, trong khi thuần túy và lười biếng mặc định, cũng cho phép lập trình bắt buộc trong khi trong một bối cảnh đơn điệu, và nó có hỗ trợ rộng rãi để xử lý đồng thời. Tất cả những điều này có các cơ chế thực hiện phần lớn trí tuệ được tập hợp trong thế giới OOP - đóng gói, kế thừa, chịu trách nhiệm đơn lẻ, sáng tác, v.v. đó là về mô hình hình thành điểm bắt đầu của ngôn ngữ.
Theo hiểu biết tốt nhất của tôi, Lisp và phương ngữ của nó và Erlang là những ứng cử viên tốt hơn F # bởi vì họ khuyến khích lập trình chức năng hơn các mô hình khác, điều mà các nhà soạn thảo nói rõ là điểm khởi đầu của ngôn ngữ . F # không bao gồm lập trình chức năng nhưng không khuyến khích nó vượt qua các mô hình được hỗ trợ khác, lập trình bắt buộc và oo.
Bạn không thể học tất cả các khía cạnh của lập trình chức năng trong C. Nhưng chắc chắn bạn có thể bắt đầu lập trình kiểu chức năng với bất kỳ ngôn ngữ bắt buộc nào. Các bit khởi đầu này là - "Cách giữ mọi thứ thuần túy trong khi lập trình." Và nó cũng có thể được thực hiện. Kiểm tra bài đăng trên blog này để biết chi tiết-
http://www.johndcook.com/blog/2011/07/24/get-started-feftal-programming/
Lập trình chức năng là về đóng cửa và các ứng dụng của họ. Trừ khi ai đó có thể chỉ cho bạn một thư viện đóng cửa gốc cho C, hãy quên sử dụng C để học lập trình chức năng.
Khái niệm chính yếu của lập trình chức năng là khái niệm về các bao đóng , nói một cách đại khái, nắm bắt một chức năng cùng với các ràng buộc biến. Bên cạnh việc sử dụng phổ biến các bao đóng, có một vài đặc điểm khác biệt trong lập trình chức năng, như sử dụng các hàm đệ quy và các giá trị bất biến (cả hai đều chơi tốt với nhau). Những đặc điểm này là một vấn đề văn hóa hơn bất kỳ điều gì khác và không có sự cản trở kỹ thuật nào để sử dụng chúng trong hầu hết mọi ngôn ngữ, đây là lý do tại sao tôi tập trung vào việc đóng cửa trong câu trả lời của mình: không phải ngôn ngữ nào cũng cho phép dễ dàng tạo ra sự đóng cửa.
Một cách sử dụng điển hình của việc đóng cửa là việc thực hiện các cơ chế bảo mật. Ví dụ, mã Javascript - trong các ví dụ tôi đã chọn Javascript vì đây là ngôn ngữ chức năng với cú pháp được gọi là cú pháp giống C của C và câu hỏi của bạn cho thấy bạn đã quen thuộc với C:
create_counter = function()
{
var x = 0;
var counter = function()
{
++x;
return x;
};
return counter;
}
Sau đó với
a = create_counter();
b = create_counter();
chúng tôi có hai chức năng a
và b
đếm các bộ sưu tập rời rạc. Điểm của ví dụ là các biến x
được bắt bởi bao đóng xác định bao counter
đóng và mỗi lần counter
đóng is instantiated by the function, it gets its fresh own idea of what
x` mới là.
Một cách sử dụng điển hình khác của bao đóng là định nghĩa ứng dụng một phần của các hàm. Giả sử rằng chúng ta có một cơ sở báo cáo tương tự như việc syslog
thực hiện một chức năng
var log = function(priority, message) {
…
};
trong đó các đối số priority
và message
được dự kiến là các chuỗi, đầu tiên là một trong số "debug"
, "info"
v.v. Chúng ta có thể định nghĩa một nhà máy đăng nhập như thế này:
var logWithPriority = function(priority) {
return function(message) {
log(priority, message);
};
};
và sử dụng nó để xác định các phiên bản chuyên biệt của cơ sở nhật ký của chúng tôi:
var debug = logWithPriority("debug");
var info = logWithPriority("info");
…
Điều này rất hữu ích, vì thay vì viết các lỗi dễ bị for
lỗi như thế này
for(i = 0; i < journal.length; ++i) {
log("info", journal[i]);
}
chúng ta có thể viết sạch hơn, ngắn hơn và đơn giản hơn nhiều (không có i
, điều đó tốt hơn nhiều ):
journal.forEach(logWithPriority("info"));
Một lĩnh vực ứng dụng quan trọng thứ ba của việc đóng cửa là việc thực hiện đánh giá lười biếng - lưu ý rằng hỗ trợ ngôn ngữ đặc biệt có thể cung cấp cho việc triển khai tốt hơn.
Một hàm lười biếng, thay vì thực hiện một phép tính thẳng, trả về một bao đóng có thể được gọi (hoặc bị ép buộc trong một thuật ngữ của sự lười biếng) để thực hiện câu hỏi. Động lực để làm điều này là nó tách ra chuẩn bị một tính toán và thực hiện một tính toán. Một ví dụ thực tế về điều này là biên dịch biểu thức chính quy: nếu một chương trình biên dịch nhiều biểu thức chính quy khi khởi động, nó sẽ cần rất nhiều thời gian để bắt đầu. Nếu thay vào đó, chúng ta lười biếng biên dịch các biểu thức chính quy và buộc chúng khi chúng cần, thì chương trình của chúng ta có thể nhanh chóng bắt đầu. Tất nhiên, các biểu thức chính quy có thể được thay thế ở đây với bất kỳ cấu trúc nào đòi hỏi thời gian khởi tạo đáng kể.
Dưới đây là cách thực hiện đánh giá lười biếng với đóng cửa. Hãy xem xét việc triển khai cổ điển của hàm ArrayMax trả về max trong một mảng:
function arrayMax(array) {
return array.reduce(function(a, b) {
return Math.min(a, b);
};
}
Biến thể lười biếng sẽ là:
function arrayMax(array) {
var memo = null;
function actuallyCompute() {
if(memo === null) {
memo = array.reduce(function(a, b) {
return Math.min(a, b);
});
}
return memo;
}
return actuallyCompute;
}
Giá trị được trả về là một bao đóng có thể được sử dụng để tính giá trị hoặc truy xuất nó vào lần khác nếu nó đã được tính toán.
Với ba ví dụ này, chúng ta nên tự tin rằng các bao đóng và các ứng dụng của chúng là cốt lõi của lập trình chức năng.
Học lập trình chức năng có nghĩa là học cách lập trình với các bao đóng. Do đó, các ngôn ngữ cho phép dễ dàng thao tác các bao đóng, và đặc biệt là ứng dụng một phần các chức năng, cần được xem xét khi tìm kiếm một ngôn ngữ để nghiên cứu lập trình chức năng. Ngược lại, các ngôn ngữ nơi đóng cửa không thể dễ dàng thao tác sẽ là lựa chọn kém.
Tôi nghĩ rằng các công cụ bạn sử dụng ảnh hưởng đến việc học của bạn rất nhiều. Hầu như không thể học các khái niệm lập trình mà ngôn ngữ lập trình bạn sử dụng không cung cấp phương tiện để sử dụng. Chắc chắn, bạn luôn có thể học một vài điều, nhưng bạn không thể học nó đúng cách.
Nhưng dù sao đó cũng là học thuật, bởi vì, như Martinho nói trong nhận xét của mình , ngay cả khi bạn có thể học lập trình chức năng, bạn không nên cố gắng làm điều đó, bởi vì có những ngôn ngữ mà việc này dễ hơn nhiều .
Bạn không nên học lập trình chức năng trong C, nhưng bằng ngôn ngữ chức năng nghiêm ngặt (Haskell, Caml, Erlang, v.v.).
Nếu bạn chưa quen với chức năng, bạn sẽ không bao giờ thực sự có được nó với một ngôn ngữ không chức năng. Nhiều khả năng, bạn sẽ tự rèn luyện để làm những gì bạn nghĩ là lập trình chức năng và học mọi thứ sai cách. Và luôn luôn khó khăn hơn để «học lại» mọi thứ theo cách đúng hơn là học chúng đúng cách lúc đầu.
Dù sao, tôi nghĩ làm chức năng trong C là một bài tập tốt cho những người đã biết chức năng. Bởi vì người đó sẽ học được những gì đang diễn ra đằng sau mui xe - những gì máy tính đang thực sự làm.