ดังที่Yannisชี้ให้เห็นมีหลายปัจจัยที่มีอิทธิพลต่อการยอมรับฟังก์ชั่นระดับสูงในภาษาที่ไม่เคยมีมาก่อน หนึ่งในสิ่งสำคัญที่เขาสัมผัสเบา ๆ คือการเพิ่มจำนวนโปรเซสเซอร์แบบมัลติคอร์และด้วยความปรารถนาที่จะประมวลผลแบบขนานและพร้อมกันมากขึ้น
แผนที่ / ตัวกรอง / ลดรูปแบบการเขียนโปรแกรมฟังก์ชั่นนั้นเป็นมิตรกับการขนานซึ่งทำให้โปรแกรมเมอร์สามารถใช้ประโยชน์จากหลายคอร์ได้อย่างง่ายดายโดยไม่ต้องเขียนโค้ดเกลียวใด ๆ ที่ชัดเจน
ตามบันทึกของ Giorgio มีฟังก์ชั่นการโปรแกรมมากกว่าฟังก์ชั่นคุณภาพสูง ฟังก์ชั่นรวมถึงแผนที่ / ตัวกรอง / ลดรูปแบบการเขียนโปรแกรมและการเปลี่ยนแปลงไม่ได้เป็นหลักของการเขียนโปรแกรมการทำงาน สิ่งเหล่านี้ทำให้เครื่องมือที่ทรงพลังสำหรับการเขียนโปรแกรมแบบขนานและพร้อมกัน โชคดีที่หลาย ๆ ภาษารองรับความคิดที่ไม่สามารถเปลี่ยนแปลงได้และแม้ว่าพวกเขาจะไม่ทำก็ตามโปรแกรมเมอร์ก็สามารถปฏิบัติต่อสิ่งต่าง ๆ ที่ไม่เปลี่ยนแปลงทำให้ห้องสมุดและคอมไพเลอร์สามารถสร้างและจัดการการดำเนินงานแบบอะซิงโครนัสหรือขนาน
การเพิ่มฟังก์ชั่นสูงในภาษาเป็นขั้นตอนสำคัญในการทำให้การเขียนโปรแกรมพร้อมกันง่ายขึ้น
ปรับปรุง
ฉันจะเพิ่มตัวอย่างที่มีรายละเอียดเพิ่มเติมสองสามข้อเพื่อแก้ไขปัญหาที่โลกิระบุไว้
พิจารณารหัส C # ต่อไปนี้ซึ่งสำรวจชุดของวิดเจ็ตสร้างรายการราคาใหม่ของวิดเจ็ต
List<float> widgetPrices;
float salesTax = RetrieveLocalSalesTax();
foreach( Widget w in widgets ) {
widgetPrices.Add( CalculateWidgetPrice( w, salesTax ) );
}
สำหรับคอลเลกชันขนาดใหญ่ของวิดเจ็ตหรือเมธอด CalculateWidgetPrice (Widget) แบบเข้มข้นการคำนวณวงนี้จะไม่ใช้ประโยชน์จากคอร์ใด ๆ ที่มีอยู่ หากต้องการทำการคำนวณราคาบนแกนที่ต่างกันจะต้องให้โปรแกรมเมอร์สร้างและจัดการเธรดอย่างชัดเจนผ่านการทำงานรอบ ๆ และรวบรวมผลลัพธ์ด้วยกัน
พิจารณาวิธีแก้ปัญหาเมื่อมีการเพิ่มฟังก์ชั่นการสั่งซื้อขั้นสูงใน C #:
var widgetPrices = widgets.Select( w=> CalculateWidgetPrice( w, salesTax ) );
foreach loop ถูกย้ายไปที่ Select method โดยซ่อนรายละเอียดการใช้งาน สิ่งที่เหลืออยู่สำหรับโปรแกรมเมอร์คือการบอกให้เลือกฟังก์ชั่นที่จะใช้กับแต่ละองค์ประกอบ สิ่งนี้จะช่วยให้การใช้งานแบบเลือกเพื่อเรียกใช้การคำนวณเป็นแบบพาร์เลลจัดการการซิงโครไนซ์และการจัดการเธรดทั้งหมดโดยไม่ต้องมีส่วนร่วมของโปรแกรมเมอร์
แต่แน่นอนว่า Select ไม่ได้ทำงานแบบขนาน นั่นคือสิ่งที่ไม่สามารถเปลี่ยนแปลงได้การใช้งาน Select ไม่ทราบว่าฟังก์ชั่นที่ให้ไว้ (CalculateWidgets ด้านบน) ไม่มีผลข้างเคียง ฟังก์ชั่นสามารถเปลี่ยนสถานะของโปรแกรมนอกมุมมองของ Select และการซิงโครไนซ์ทำลายทุกอย่าง ตัวอย่างเช่นในกรณีนี้มูลค่าของ salesTax อาจมีการเปลี่ยนแปลงข้อผิดพลาด ภาษาที่ใช้งานได้จริงให้ความไม่สามารถเปลี่ยนแปลงได้ดังนั้นฟังก์ชั่น Select (map) สามารถรู้ได้ว่าไม่มีการเปลี่ยนแปลงสถานะ
C # เน้นเรื่องนี้โดยการให้ PLINQ เป็นทางเลือกแทน Linq ที่จะมีลักษณะ:
var widgetPrices = widgets.AsParallel().Select(w => CalculateWidgetPrice( w, salesTax) );
ซึ่งใช้ประโยชน์จากคอร์ทั้งหมดของระบบอย่างเต็มที่โดยไม่ต้องจัดการคอร์เหล่านั้นอย่างชัดเจน