Như Yannis đã chỉ ra, có một số yếu tố đã ảnh hưởng đến việc áp dụng các hàm bậc cao trong các ngôn ngữ mà trước đây không có. Một trong những mục quan trọng mà anh ta chỉ chạm nhẹ là sự phổ biến của bộ xử lý đa lõi và cùng với đó là mong muốn xử lý song song và đồng thời hơn.
Kiểu bản đồ / bộ lọc / rút gọn của lập trình chức năng rất thân thiện với việc song song hóa, cho phép lập trình viên dễ dàng sử dụng nhiều lõi, mà không cần viết bất kỳ mã luồng rõ ràng nào.
Như Giorgio lưu ý, có nhiều thứ để lập trình chức năng hơn là chỉ các hàm bậc cao. Các hàm, cộng với một bản đồ / bộ lọc / giảm mẫu lập trình và tính bất biến là cốt lõi của lập trình hàm. Những điều này làm cho các công cụ mạnh mẽ của lập trình song song và đồng thời. Rất may, nhiều ngôn ngữ đã hỗ trợ một số khái niệm về tính bất biến và thậm chí nếu không, các lập trình viên có thể coi mọi thứ là bất biến cho phép các thư viện và trình biên dịch tạo và quản lý các hoạt động không đồng bộ hoặc song song.
Thêm các hàm bậc cao vào một ngôn ngữ là một bước quan trọng để đơn giản hóa việc lập trình đồng thời.
Cập nhật
Tôi sẽ thêm một vài ví dụ chi tiết hơn để giải quyết những lo ngại mà Loki đã lưu ý.
Hãy xem xét mã C # sau đây đi qua bộ sưu tập các vật dụng, tạo ra một danh sách mới về giá vật dụng.
List<float> widgetPrices;
float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}
Đối với một bộ sưu tập lớn các widget hoặc phương thức CompateWidgetprice (Widget) tính toán chuyên sâu, vòng lặp này sẽ không sử dụng tốt bất kỳ lõi có sẵn nào. Để thực hiện các tính toán giá trên các lõi khác nhau sẽ yêu cầu lập trình viên tạo và quản lý rõ ràng các luồng, chuyển công việc xung quanh và thu thập kết quả cùng nhau.
Hãy xem xét một giải pháp khi các hàm bậc cao đã được thêm vào C #:
var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );
Vòng lặp foreach đã được chuyển vào phương thức Chọn, ẩn chi tiết triển khai của nó. Tất cả những gì còn lại cho lập trình viên là nói với Chọn chức năng nào sẽ áp dụng cho từng phần tử. Điều này sẽ cho phép triển khai Chọn để chạy các phép tính theo parellel, xử lý tất cả các mối quan tâm đồng bộ hóa và quản lý luồng mà không cần sự tham gia của lập trình viên.
Nhưng, tất nhiên, Chọn không hoạt động song song. Đó là nơi mà tính bất biến xuất hiện. Việc triển khai Chọn không biết rằng hàm được cung cấp (Tính toán trên đây) không có tác dụng phụ. Hàm này có thể thay đổi trạng thái của chương trình bên ngoài giao diện Chọn và đồng bộ hóa, phá vỡ mọi thứ. Ví dụ: trong trường hợp này, giá trị của salesTax có thể bị thay đổi do lỗi. Các ngôn ngữ chức năng thuần túy cung cấp tính bất biến, do đó, chức năng Chọn (bản đồ) có thể biết chắc chắn rằng không có trạng thái nào thay đổi.
C # giải quyết vấn đề này bằng cách cung cấp PLINQ thay thế cho Linq. Điều đó sẽ trông giống như:
var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );
Việc này sử dụng đầy đủ tất cả các lõi của hệ thống của bạn mà không cần quản lý rõ ràng các lõi đó.