การเปลี่ยนรูปไม่ได้หรือความไม่แน่นอนไม่ใช่แนวคิดที่เหมาะสมในการโปรแกรมเชิงฟังก์ชัน
บริบทการคำนวณ
นี่เป็นคำถามที่ดีมากที่มีการติดตามที่น่าสนใจ (ไม่ซ้ำกัน) ไปยังอีกอันหนึ่งเมื่อเร็ว ๆ นี้: อะไรคือความแตกต่างระหว่างการมอบหมายการประเมินค่าและการผูกชื่อ
แทนที่จะตอบกลับข้อความของคุณทีละคนฉันพยายามที่นี่เพื่อให้ภาพรวมที่มีโครงสร้างของสิ่งที่เป็นเดิมพัน
มีหลายประเด็นที่ต้องพิจารณาเพื่อตอบคุณรวมถึง:
รูปแบบการเขียนโปรแกรมใช้งานดูเหมือนโง่เพราะคุณเห็นด้วยตาโปรแกรมเมอร์ที่จำเป็น แต่มันเป็นกระบวนทัศน์ที่แตกต่างกันและแนวคิดและการรับรู้ที่จำเป็นของคุณนั้นเป็นมนุษย์ต่างดาว คอมไพเลอร์ไม่มีอคติดังกล่าว
แต่ข้อสรุปท้ายคือมันเป็นไปได้ที่จะเขียนโปรแกรมในลักษณะการทำงานอย่างหมดจดรวมถึงการเรียนรู้ของเครื่องการคิดว่าการเขียนโปรแกรมการทำงานไม่ได้มีแนวคิดของการจัดเก็บข้อมูล ฉันดูเหมือนจะไม่เห็นด้วยกับประเด็นนี้พร้อมคำตอบอื่น ๆ
ด้วยความหวังมีน้อยคนที่จะสนใจแม้จะมีความยาวของคำตอบนี้
กระบวนทัศน์การคำนวณ
คำถามเกี่ยวกับการเขียนโปรแกรมการทำงาน (การเขียนโปรแกรมประยุกต์ aka) รูปแบบเฉพาะของการคำนวณซึ่งเป็นตัวแทนทางทฤษฎีและง่ายที่สุดคือแลมบ์ดาแคลคูลัส
หากคุณอยู่ในระดับทฤษฎีมีหลายรุ่นของการคำนวณ: เครื่องทัวริง (TM), เครื่อง RAM และอื่น ๆแคลคูลัสแลมบ์ดา, combinatory ตรรกะทฤษฎี recursive ฟังก์ชั่นระบบกึ่งพวก ฯลฯ ที่มีประสิทธิภาพมากขึ้น รุ่นที่ได้รับการพิสูจน์เทียบเท่าในแง่ของสิ่งที่พวกเขาสามารถอยู่และที่เป็นส่วนสำคัญของ
วิทยานิพนธ์โบสถ์ทัวริง
แนวคิดที่สำคัญคือการลดรูปแบบซึ่งกันและกันซึ่งเป็นพื้นฐานสำหรับการสร้างความเท่าเทียมที่นำไปสู่วิทยานิพนธ์ทัวริส - ทัวริง เห็นได้จากมุมมองโปรแกรมเมอร์ลดรูปแบบหนึ่งไปยังอีกเป็นสิ่งที่เรียกว่าคอมไพเลอร์ หากคุณใช้การเขียนโปรแกรมแบบลอจิกเป็นแบบจำลองการคำนวณของคุณมันค่อนข้างแตกต่างจากรุ่นที่จัดทำโดยพีซีที่คุณซื้อในร้านค้าและคอมไพเลอร์แปลโปรแกรมที่เขียนด้วยภาษาโปรแกรมตรรกะไปเป็นรูปแบบการคำนวณที่แสดงโดยพีซีของคุณ คอมพิวเตอร์ RAM)
อย่างไรก็ตามมันไม่ได้หมายความว่าทั้งสองรุ่นทำในลักษณะเดียวกันหรือแนวคิดที่มีความหมายสำหรับหนึ่งสามารถถ่ายโอนได้เช่นกัน โดยทั่วไปขั้นตอนการคำนวณใน TM มีความสัมพันธ์เพียงเล็กน้อยกับขั้นตอนการลด( -) ในแลมบ์ดาแคลคูลัสแม้ว่าพวกเขาจะสามารถแปลได้ แนวคิดของการประเมินผลที่เหมาะสมที่สุดของการแสดงออกแลมบ์ดาค่อนข้างห่างไกลจากปัญหาความซับซ้อนในโมเดล TMβ
ในทางปฏิบัติภาษาการเขียนโปรแกรมที่เราใช้มักจะผสมผสานแนวคิดจากจุดกำเนิดทางทฤษฎีที่แตกต่างกันพยายามที่จะทำเพื่อให้บางส่วนของโปรแกรมที่เลือกจะได้รับประโยชน์จากคุณสมบัติของแบบจำลองบางอย่างที่เหมาะสม ในทำนองเดียวกันคนสร้างระบบอาจเลือกภาษาที่แตกต่างกันสำหรับส่วนประกอบที่แตกต่างกันเพื่อให้เหมาะกับภาษาให้เหมาะกับงาน
ดังนั้นคุณไม่ค่อยเห็นกระบวนทัศน์การเขียนโปรแกรมในสถานะที่บริสุทธิ์ในภาษาการเขียนโปรแกรม ภาษาการเขียนโปรแกรมยังคงจำแนกตามกระบวนทัศน์ที่โดดเด่น แต่คุณสมบัติของภาษาอาจได้รับผลกระทบเมื่อแนวคิดจากกระบวนทัศน์อื่นเกี่ยวข้อง
โดยทั่วไปแล้วภาษาเช่น Haskell และ ML หรือ CAML ถือว่าเป็นหน้าที่ แต่พวกเขาสามารถอนุญาตให้มีพฤติกรรมที่จำเป็น ... อีกอย่างหนึ่งทำไมจะพูดถึง " ชุดย่อยที่ใช้งานได้อย่างแท้จริง "?
จากนั้นหนึ่งสามารถอ้างว่าคุณสามารถทำสิ่งนี้หรือว่าในภาษาการเขียนโปรแกรมการทำงานของฉัน แต่มันไม่ได้ตอบคำถามเกี่ยวกับการเขียนโปรแกรมการทำงานเมื่อมันขึ้นอยู่กับสิ่งที่ถือได้ว่าเป็นฟังก์ชั่นพิเศษ
คำตอบควรเกี่ยวข้องกับกระบวนทัศน์เฉพาะอย่างแม่นยำยิ่งขึ้น
ตัวแปรคืออะไร
ปัญหาอีกประการคือการใช้คำศัพท์ ในวิชาคณิตศาสตร์ตัวแปรเป็นเอนทิตีที่ใช้แทนค่าที่ไม่ได้ระบุในบางโดเมน มันถูกใช้เพื่อวัตถุประสงค์ต่าง ๆ ใช้ในสมการมันอาจหมายถึงสิ่งที่มีค่าเช่นว่าการตรวจสอบสมการ วิสัยทัศน์นี้ใช้ในการเขียนโปรแกรมเชิงตรรกะภายใต้ชื่อ " ตัวแปรเชิงตรรกะ " อาจเป็นเพราะตัวแปรชื่อมีความหมายอื่นอยู่แล้วเมื่อพัฒนาโปรแกรมเชิงตรรกะ
ในการเขียนโปรแกรมที่จำเป็นแบบดั้งเดิมตัวแปรถูกเข้าใจว่าเป็นคอนเทนเนอร์ (หรือตำแหน่งหน่วยความจำ) ที่สามารถจดจำการแสดงค่าและอาจได้รับค่าปัจจุบันแทนที่ด้วยอีกอันหนึ่ง)
ในการเขียนโปรแกรมฟังก์ชั่นตัวแปรมีจุดประสงค์เดียวกับที่ใช้ในวิชาคณิตศาสตร์ในฐานะตัวยึดสำหรับค่าบางอย่าง แต่ยังไม่ได้จัดเตรียม ในการเขียนโปรแกรมแบบดั้งเดิมจำเป็นบทบาทนี้เล่นจริงโดยคงที่ (เพื่อไม่ให้สับสนกับตัวอักษรซึ่งเป็นค่าที่กำหนดไว้แสดงด้วยสัญกรณ์เฉพาะสำหรับโดเมนของค่าเช่น 123, จริง, ["abdcz", 3.14])
ตัวแปรของชนิดใด ๆ รวมทั้งค่าคงที่อาจถูกแทนด้วยตัวระบุ
ตัวแปรที่จำเป็นสามารถเปลี่ยนค่าได้และนั่นคือพื้นฐานของความผันแปร ตัวแปรการทำงานไม่สามารถ
ภาษาการเขียนโปรแกรมมักจะอนุญาตให้เอนทิตีขนาดใหญ่สร้างจากภาษาที่เล็กกว่าในภาษานั้น
ภาษาที่จำเป็นต้องมีเพื่อให้โครงสร้างดังกล่าวรวมตัวแปรและนั่นคือสิ่งที่ทำให้คุณมีข้อมูลที่ไม่แน่นอน
วิธีอ่านโปรแกรม
โปรแกรมเป็นคำอธิบายที่เป็นนามธรรมของอัลกอริทึมของคุณคือบางภาษาไม่ว่าจะเป็นการออกแบบเชิงปฏิบัติหรือภาษาบริสุทธิ์แบบกระบวนทัศน์
โดยหลักการแล้วคุณสามารถจดทุกคำพูดสำหรับสิ่งที่ควรจะหมายถึง abstractedly จากนั้นคอมไพเลอร์จะแปลว่าเป็นรูปแบบที่เหมาะสมเพื่อให้คอมพิวเตอร์ดำเนินการได้ แต่นั่นไม่ใช่ปัญหาของคุณในการประมาณครั้งแรก
แน่นอนความเป็นจริงนั้นค่อนข้างรุนแรงและเป็นเรื่องดีที่จะมีความคิดว่าเกิดอะไรขึ้นเพื่อหลีกเลี่ยงโครงสร้างที่คอมไพเลอร์จะไม่ทราบวิธีจัดการกับการดำเนินการที่มีประสิทธิภาพ แต่นั่นเป็นการเพิ่มประสิทธิภาพแล้ว ... ซึ่งคอมไพเลอร์สามารถทำได้ดีมากมักจะดีกว่าโปรแกรมเมอร์
ฟังก์ชั่นการเขียนโปรแกรมและความไม่แน่นอน
ความไม่แน่นอนขึ้นอยู่กับการดำรงอยู่ของตัวแปรที่จำเป็นที่สามารถมีค่าที่จะเปลี่ยนโดยการกำหนด เนื่องจากสิ่งเหล่านี้ไม่มีอยู่ในฟังก์ชันการเขียนโปรแกรมทุกอย่างจึงไม่อาจเปลี่ยนแปลงได้
การเขียนโปรแกรมแบบ Fuctional เกี่ยวข้องเฉพาะกับค่า
สี่ข้อความแรกของคุณเกี่ยวกับความไม่สามารถเปลี่ยนได้นั้นส่วนใหญ่ถูกต้อง แต่อธิบายด้วยมุมมองที่จำเป็นบางอย่างที่ไม่จำเป็น มันเป็นเหมือนการอธิบายด้วยสีในโลกที่ทุกคนตาบอด คุณกำลังใช้แนวคิดที่เป็นคนต่างด้าวกับการเขียนโปรแกรมการทำงาน
คุณมีเพียงค่าบริสุทธิ์และอาร์เรย์ของจำนวนเต็มเป็นค่าจริง ในการรับอาเรย์อื่นที่แตกต่างในองค์ประกอบเดียวคุณต้องใช้ค่าอาเรย์ที่แตกต่างกัน การเปลี่ยนองค์ประกอบเป็นเพียงแนวคิดที่ไม่มีอยู่ในบริบทนี้ คุณอาจมีฟังก์ชั่นที่มีอาร์เรย์และดัชนีบางส่วนเป็นอาร์กิวเมนต์และส่งกลับผลลัพธ์ที่เป็นอาร์เรย์ที่เกือบเหมือนกันซึ่งแตกต่างกันเฉพาะที่ระบุโดยดัชนี แต่มันก็ยังคงเป็นค่าอาร์เรย์อิสระ คุณค่าเหล่านี้เป็นอย่างไรไม่ใช่ปัญหาของคุณ บางทีพวกเขาอาจ "แบ่งปัน" เป็นจำนวนมากในการแปลที่จำเป็นสำหรับคอมพิวเตอร์ ... แต่นั่นเป็นหน้าที่ของคอมไพเลอร์ ... และคุณไม่ต้องการที่จะรู้ว่าสถาปัตยกรรมเครื่องมันกำลังรวบรวมอะไรอยู่
คุณไม่ได้คัดลอกค่า (มันไม่สมเหตุสมผลเป็นแนวคิดของเอเลี่ยน) คุณเพียงแค่ใช้ค่าที่มีอยู่ในโดเมนที่คุณกำหนดไว้ในโปรแกรมของคุณ ไม่ว่าคุณจะอธิบาย (เป็นตัวอักษร) หรือเป็นผลลัพธ์ของการใช้ฟังก์ชันกับค่าอื่น ๆ คุณสามารถตั้งชื่อให้พวกเขาได้ (ซึ่งเป็นการกำหนดค่าคงที่) เพื่อให้แน่ใจว่ามีการใช้ค่าเดียวกันในที่ต่างๆในโปรแกรม โปรดทราบว่าแอปพลิเคชันฟังก์ชันไม่ควรถูกมองว่าเป็นการคำนวณ แต่เป็นผลลัพธ์ของแอปพลิเคชันต่ออาร์กิวเมนต์ที่กำหนด การเขียน5+2
หรือการเขียน7
จำนวนเดียวกัน ซึ่งสอดคล้องกับย่อหน้าก่อนหน้า
ไม่มีตัวแปรที่จำเป็น ไม่สามารถกำหนดได้ คุณสามารถผูกชื่อกับค่าเท่านั้น (เพื่อสร้างค่าคงที่) ซึ่งแตกต่างจากภาษาที่จำเป็นที่คุณสามารถผูกชื่อกับตัวแปรที่กำหนดได้
ไม่ว่าจะมีค่าใช้จ่ายในความซับซ้อนไม่ชัดเจนโดยสิ้นเชิง สำหรับสิ่งหนึ่งคุณอ้างอิงถึงความซับซ้อนเกี่ยวข้องกับกระบวนทัศน์ที่จำเป็น มันไม่ได้ถูกกำหนดไว้สำหรับการเขียนโปรแกรมฟังก์ชั่นเว้นแต่คุณเลือกที่จะอ่านโปรแกรมการทำงานของคุณเป็นสิ่งจำเป็นซึ่งไม่ใช่เจตนาของนักออกแบบ แน่นอนว่ามุมมองการทำงานมีจุดประสงค์เพื่อให้คุณไม่ต้องกังวลเกี่ยวกับปัญหาดังกล่าวและมุ่งเน้นไปที่สิ่งที่คำนวณ มันเป็นเหมือนสเปคและการใช้งาน
คอมไพเลอร์จะต้องดูแลการใช้งานและฉลาดพอที่จะปรับสิ่งที่ต้องทำกับฮาร์ดแวร์ที่จะทำสิ่งที่ดีที่สุด
ฉันไม่ได้บอกว่าโปรแกรมเมอร์ไม่ต้องเป็นห่วง ฉันยังไม่ได้บอกว่าภาษาการเขียนโปรแกรมและเทคโนโลยีคอมไพเลอร์มีความเป็นผู้ใหญ่อย่างที่เราอยากให้เป็น
ตอบคำถาม
คุณไม่ได้ปรับเปลี่ยนค่าที่มีอยู่ (แนวคิดต่างด้าว) แต่คำนวณค่าใหม่ที่แตกต่างกันตามที่ต้องการโดยอาจมีองค์ประกอบพิเศษหนึ่งรายการซึ่งเป็นรายการ
โปรแกรมสามารถรับข้อมูลใหม่ได้ ประเด็นทั้งหมดคือวิธีที่คุณแสดงออกในภาษา ตัวอย่างเช่นคุณสามารถพิจารณาว่าโปรแกรมทำงานกับค่าที่ระบุเพียงค่าเดียวซึ่งอาจมีขนาดไม่ใหญ่มากซึ่งเรียกว่าอินพุตสตรีม มันเป็นค่าที่ควรจะนั่งที่นั่น (ไม่ว่าจะเป็นที่รู้จักกันอย่างเต็มที่หรือไม่ไม่ใช่ปัญหาของคุณ) จากนั้นคุณจะมีฟังก์ชันที่คืนค่าคู่ที่ประกอบด้วยองค์ประกอบแรกของสตรีมและสตรีมที่เหลือ
คุณสามารถใช้มันเพื่อสร้างเครือข่ายของการสื่อสารส่วนประกอบด้วยวิธีการประยุกต์ใช้อย่างหมดจด (coroutines)
การเรียนรู้ของเครื่องเป็นอีกปัญหาหนึ่งเมื่อคุณต้องรวบรวมข้อมูลและแก้ไขค่า ในการเขียนโปรแกรมการทำงานคุณไม่ได้ทำเช่นนั้น: คุณเพียงแค่คำนวณค่าใหม่ที่แตกต่างกันอย่างเหมาะสมตามข้อมูลการฝึกอบรม เครื่องผลลัพธ์ก็จะทำงานเช่นกัน สิ่งที่คุณกังวลคือการคำนวณเวลาและประสิทธิภาพของพื้นที่ แต่อีกครั้งนั่นเป็นปัญหาที่แตกต่างที่ควรได้รับการจัดการโดยคอมไพเลอร์
หมายเหตุสุดท้าย
มันค่อนข้างชัดเจนจากความคิดเห็นหรือคำตอบอื่น ๆ ว่าภาษาการเขียนโปรแกรมฟังก์ชั่นในทางปฏิบัติไม่ได้ทำงานอย่างหมดจด นั่นเป็นภาพสะท้อนถึงความจริงที่ว่าเทคโนโลยีของเรายังคงได้รับการปรับปรุงโดยเฉพาะอย่างยิ่งเมื่อมีการรวบรวม
เป็นไปได้ไหมที่จะเขียนในลักษณะการประยุกต์ใช้อย่างหมดจด? คำตอบนั้นเป็นที่รู้จักกันมาประมาณ 40 ปีและเป็น "ใช่" จุดประสงค์ของการตีความหมายเชิง Denotational ตามที่ปรากฏในปี 1970 นั้นมีความแม่นยำในการแปลภาษา (คอมไพล์) เป็นรูปแบบการทำงานล้วนๆถือว่าเข้าใจได้ดีกว่าในเชิงคณิตศาสตร์และถือว่าเป็นการให้เงินสนับสนุนที่ดีกว่าเพื่อกำหนดความหมายของโปรแกรม
สิ่งที่น่าสนใจคือโครงสร้างการเขียนโปรแกรมที่จำเป็นรวมถึงตัวแปรสามารถแปลเป็นสไตล์การทำงานได้โดยการแนะนำโดเมนของค่าที่เหมาะสมเช่นแหล่งข้อมูล และแม้จะมีสไตล์การใช้งานก็ยังคงคล้ายกับรหัสของคอมไพเลอร์จริงที่เขียนในรูปแบบที่จำเป็น