ความไม่เปลี่ยนแปลงในการเขียนโปรแกรมเชิงฟังก์ชั่นมีอยู่จริงหรือไม่?


9

แม้ว่าฉันจะทำงานเป็นโปรแกรมเมอร์ในชีวิตประจำวันของฉันและใช้ภาษายอดนิยมทั้งหมด (Python, Java, C, ฯลฯ ) ฉันยังไม่มีมุมมองที่ชัดเจนเกี่ยวกับการเขียนโปรแกรมที่ใช้งานได้ จากสิ่งที่ผมได้อ่านหนึ่งทรัพย์สินของภาษาหน้าที่คือว่าโครงสร้างข้อมูลจะไม่เปลี่ยนรูป สำหรับฉันคนเดียวนี่ทำให้เกิดคำถามมากมาย แต่ก่อนอื่นฉันจะเขียนสิ่งที่ฉันเข้าใจเกี่ยวกับความไม่สามารถเปลี่ยนแปลงได้และถ้าฉันผิดฉันรู้สึกอิสระที่จะแก้ไขให้ถูกต้อง

ความเข้าใจของฉันเกี่ยวกับความไม่สามารถเปลี่ยนแปลงได้:

  • เมื่อโปรแกรมเริ่มทำงานจะมีโครงสร้างข้อมูลคงที่พร้อมข้อมูลคงที่
  • ไม่มีใครสามารถเพิ่มข้อมูลใหม่ให้กับโครงสร้างเหล่านี้
  • ไม่มีตัวแปรในรหัส
  • คุณสามารถ "คัดลอก" จากข้อมูลที่มีอยู่แล้วหรือข้อมูลที่คำนวณได้ในปัจจุบัน
  • เนื่องจากทั้งหมดข้างต้นการเปลี่ยนแปลงไม่ได้เพิ่มความซับซ้อนของพื้นที่ขนาดใหญ่ให้กับโปรแกรม

คำถามของฉัน:

  1. หากโครงสร้างข้อมูลควรจะยังคงเหมือนเดิม (ไม่เปลี่ยนรูป) จะมีคนเพิ่มรายการใหม่ในรายการได้อย่างไร
  2. อะไรคือจุดที่มีโปรแกรมที่ไม่สามารถรับข้อมูลใหม่ได้? สมมติว่าคุณมีเซ็นเซอร์ติดอยู่กับคอมพิวเตอร์ของคุณที่ต้องการป้อนข้อมูลเข้าสู่โปรแกรม นั่นหมายความว่าเราไม่สามารถจัดเก็บข้อมูลขาเข้าได้ทุกที่หรือไม่
  3. การเขียนโปรแกรมใช้งานได้ดีสำหรับการเรียนรู้ของเครื่องอย่างไร เนื่องจากการเรียนรู้ของเครื่องสร้างขึ้นจากสมมติฐานของการปรับปรุง "การรับรู้" ของสิ่งต่าง ๆ - จึงเก็บข้อมูลใหม่

2
ฉันไม่เห็นด้วยกับคุณเมื่อคุณบอกว่าไม่มีตัวแปรในรหัสการทำงาน มีตัวแปรในความหมายทางคณิตศาสตร์ของ“ ปริมาณที่อาจถือว่าเป็นหนึ่งในชุดของค่าใด ๆ ” พวกเขาไม่แน่นอนไม่แน่นอนแต่ไม่ใช่ในวิชาคณิตศาสตร์
Édouard

1
ฉันคิดว่าความสับสนของคุณเป็นเพราะคุณกำลังคิดถึงภาษาที่ใช้งานได้อย่างเป็นนามธรรม เพียงแค่ใช้โปรแกรมใด ๆ ใน Haskell เช่นโปรแกรมที่อ่านรายการตัวเลขจากคอนโซลเรียงลำดับอย่างรวดเร็วและแสดงผลและหาวิธีการทำงานและวิธีหักล้างความสงสัยของคุณ ไม่มีทางที่จะเคลียร์สิ่งต่าง ๆ ได้โดยไม่ต้องดูตัวอย่างของโปรแกรมที่แท้จริงแทนที่จะเป็นปรัชญา คุณจะพบโปรแกรมมากมายในบทช่วยสอน Haskell
jkff

@jkff คุณพยายามจะพูดอะไร Haskel นั้นมีคุณสมบัติที่ไม่สามารถใช้งานได้ คำถามไม่เกี่ยวกับ Haskell แต่เกี่ยวกับการเขียนโปรแกรมการทำงาน หรือคุณยืนยันว่าทั้งหมดนั้นใช้งานได้หรือไม่ อย่างไร? ดังนั้นสิ่งที่ควรจะผิดกับ philosophizing อย่างที่คุณพูด สิ่งที่เป็นนามธรรมทำให้เกิดความสับสนในสิ่งที่? คำถาม OP เป็นคำถามที่สมเหตุสมผลมาก
babou

@babou ฉันพยายามที่จะพูดว่าวิธีที่ดีที่สุดในการทำความเข้าใจว่าภาษาการเขียนโปรแกรมที่ใช้งานได้อย่างมีประสิทธิภาพสามารถใช้อัลกอริธึมและโครงสร้างข้อมูลได้อย่างไรเพื่อดูตัวอย่างของอัลกอริธึมและโครงสร้างข้อมูล สำหรับฉันดูเหมือนว่า OP พยายามที่จะเข้าใจว่ามันเป็นไปได้ในแนวความคิดอย่างไร - ฉันคิดว่าวิธีที่เร็วที่สุดในการเข้าใจนั่นคือการดูตัวอย่างแทนที่จะอ่านคำอธิบายเชิงแนวคิด
jkff

วิธีหนึ่งในการดูการเขียนโปรแกรมการทำงานคือการบอกว่าเป็นการเขียนโปรแกรมโดยไม่มีผลข้างเคียง คุณสามารถทำได้ในภาษา "อินเทรนด์" ที่คุณเลือก อย่าหลีกเลี่ยงการมอบหมายใหม่ทั้งหมด: เช่นใน Java ตัวแปรทั้งหมดของคุณจะถือเป็นที่สิ้นสุดและวิธีการทั้งหมดของคุณจะเป็นแบบอ่านอย่างเดียว
reinierpost

คำตอบ:


10

เมื่อโปรแกรมเริ่มทำงานจะมีโครงสร้างข้อมูลคงที่พร้อมข้อมูลคงที่

นี่เป็นความเข้าใจที่คลาดเคลื่อน มันมีรูปแบบที่ตายตัวและชุดของกฎการเขียนซ้ำที่คงที่ แต่กฎการเขียนซ้ำเหล่านี้สามารถระเบิดเป็นสิ่งที่มีขนาดใหญ่กว่ามาก ตัวอย่างเช่นนิพจน์ [1..100000000] ใน Haskell แสดงด้วยรหัสจำนวนน้อยมาก แต่รูปแบบปกติมีขนาดใหญ่

ไม่มีใครสามารถเพิ่มข้อมูลใหม่ให้กับโครงสร้างเหล่านี้

ใช่และไม่. เซตย่อยที่ใช้งานได้จริงของภาษาเช่น Haskell หรือ ML ไม่สามารถรับข้อมูลจากโลกภายนอก แต่ภาษาใด ๆ สำหรับการเขียนโปรแกรมเชิงปฏิบัติมีกลไกสำหรับการแทรกข้อมูลจากโลกภายนอกเข้าสู่เซตย่อยที่ใช้งานได้อย่างหมดจด ใน Haskell จะทำอย่างระมัดระวัง แต่ใน ML คุณสามารถทำได้ทุกเมื่อที่คุณต้องการ

ไม่มีตัวแปรในรหัส

นี่เป็นเรื่องจริงมาก แต่อย่าสับสนกับแนวคิดที่ว่าจะไม่มีชื่อ คุณตั้งชื่อนิพจน์ที่เป็นประโยชน์ตลอดเวลาและนำมาใช้ซ้ำ ทั้ง ML และ Haskell Lisp ทุกตัวที่ฉันได้ลองและลูกผสมเช่น Scala ล้วนมีวิธีสร้างตัวแปร พวกเขาไม่ได้ใช้กันทั่วไป และอีกส่วนย่อยที่ทำงานได้อย่างหมดจดของภาษาดังกล่าวไม่ได้มี

คุณสามารถ "คัดลอก" จากข้อมูลที่มีอยู่แล้วหรือข้อมูลที่คำนวณได้ในปัจจุบัน

คุณสามารถทำการคำนวณโดยลดขนาดให้เป็นแบบปกติ สิ่งที่ดีที่สุดที่ควรทำคือไปเขียนโปรแกรมในภาษาที่ใช้งานได้เพื่อดูว่าพวกเขาทำอย่างไรในการคำนวณ

ยกตัวอย่างเช่น "sum [1..1000]" ไม่ใช่การคำนวณที่ฉันต้องการจะทำ แต่มันก็ทำได้โดย Haskell เราให้ความรู้สึกเล็ก ๆ น้อย ๆ ที่มีความหมายกับเราและ Haskell ให้ตัวเลขที่สอดคล้องกัน ดังนั้นมันจึงทำการคำนวณอย่างแน่นอน

หากโครงสร้างข้อมูลควรจะยังคงเหมือนเดิม (ไม่เปลี่ยนรูป) จะมีคนเพิ่มรายการใหม่ในรายการได้อย่างไร

คุณไม่ได้เพิ่มรายการใหม่ลงในรายการคุณสร้างรายการใหม่จากรายการเก่า เนื่องจากไม่สามารถเปลี่ยนรูปแบบเก่าได้จึงปลอดภัยที่จะใช้ในรายการใหม่หรือที่ใดก็ตามที่คุณต้องการ ข้อมูลจำนวนมากสามารถแชร์ได้อย่างปลอดภัยในสคีมานี้

อะไรคือจุดที่มีโปรแกรมที่ไม่สามารถรับข้อมูลใหม่ได้? สมมติว่าคุณมีเซ็นเซอร์ติดอยู่กับคอมพิวเตอร์ของคุณที่ต้องการป้อนข้อมูลเข้าสู่โปรแกรม นั่นหมายความว่าเราไม่สามารถจัดเก็บข้อมูลขาเข้าได้ทุกที่หรือไม่

เท่าที่ผู้ใช้ป้อนภาษาการเขียนโปรแกรมเชิงปฏิบัติใด ๆ มีวิธีรับอินพุตผู้ใช้ สิ่งนี้เกิดขึ้น อย่างไรก็ตามมีส่วนย่อยที่ใช้งานได้อย่างสมบูรณ์ของภาษาเหล่านี้ที่คุณเขียนโค้ดส่วนใหญ่และคุณได้รับประโยชน์จากวิธีนี้

การเขียนโปรแกรมใช้งานได้ดีสำหรับการเรียนรู้ของเครื่องอย่างไร เนื่องจากการเรียนรู้ของเครื่องสร้างขึ้นจากสมมติฐานของการปรับปรุง "การรับรู้" ของสิ่งต่าง ๆ - จึงเก็บข้อมูลใหม่

นี่จะเป็นกรณีของการเรียนรู้เชิงรุก แต่การเรียนรู้ของเครื่องส่วนใหญ่ที่ฉันได้ทำงานด้วย (ฉันทำงานเป็นรหัสลิงในกลุ่มการเรียนรู้ของเครื่องและได้ทำเช่นนั้นมาสองสามปี) มีกระบวนการเรียนรู้ครั้งเดียวที่โหลดข้อมูลการฝึกอบรมทั้งหมด ในครั้งเดียว แต่สำหรับการเรียนรู้อย่างกระตือรือร้นคุณไม่สามารถทำสิ่งต่าง ๆ ได้อย่างสมบูรณ์ 100% คุณจะต้องอ่านข้อมูลบางอย่างจากโลกภายนอก


ฉันรู้สึกว่าคุณเพิกเฉยต่อสิ่งที่อาจเป็นจุดที่สำคัญที่สุดในโพสต์ของ @ Pithikos ซึ่งเป็นปัญหาด้านอวกาศ - โปรแกรมที่ใช้งานได้ใช้พื้นที่มากกว่าที่จำเป็น (คุณไม่สามารถเขียนอัลกอริธึมในสถานที่และอื่น ๆ )
user541686

2
สิ่งนี้ไม่จริง การขาดการกลายพันธุ์นั้นส่วนใหญ่เกิดจากการแบ่งปันและเหนือสิ่งอื่นใดความแตกต่างของขนาดที่คุณอ้างถึงนั้นเล็กไปด้วยคอมไพเลอร์สมัยใหม่ รหัสส่วนใหญ่ในรายการใน haskell มีประสิทธิภาพในสถานที่หรือไม่ใช้หน่วยความจำเลย
Jake

1
ฉันคิดว่าคุณเข้าใจผิด ML ค่อนข้าง ใช่ I / O สามารถเกิดขึ้นได้ทุกที่ แต่วิธีการที่นำข้อมูลใหม่เข้าสู่โครงสร้างที่มีอยู่นั้นถูกควบคุมอย่างเข้มงวด
dfeuer

@Pithikos มีตัวแปรอยู่ทั่วทุกที่ พวกมันต่างจากสิ่งที่คุณคุ้นเคยตามที่Édouardระบุ และมีการจัดสรรสิ่งของอย่างต่อเนื่องและเก็บขยะ เมื่อคุณเข้าโปรแกรมที่ใช้งานได้จริงคุณจะเข้าใจได้ว่ามันเป็นอย่างไร
dfeuer

1
มันเป็นความจริงที่ว่ามีอัลกอริธึมที่ไม่มีการใช้งานอย่างหมดจดด้วยความซับซ้อนในเวลาเดียวกันกับการใช้งานที่จำเป็นที่รู้จักกันดีที่สุด - เช่นโครงสร้างการค้นหายูเนี่ยน - (และ, um, อาร์เรย์ :)) ฉันคิดว่า ความซับซ้อน แต่สิ่งเหล่านี้เป็นข้อยกเว้น - อัลกอริทึมทั่วไป / โครงสร้างข้อมูลส่วนใหญ่มีการใช้งานที่มีเวลาและความซับซ้อนที่เท่ากัน มันเป็นเรื่องส่วนตัวของสไตล์การเขียนโปรแกรมและ (ถึงปัจจัยคงที่) ของคุณภาพของคอมไพเลอร์
jkff

4

การเปลี่ยนรูปไม่ได้หรือความไม่แน่นอนไม่ใช่แนวคิดที่เหมาะสมในการโปรแกรมเชิงฟังก์ชัน

บริบทการคำนวณ

นี่เป็นคำถามที่ดีมากที่มีการติดตามที่น่าสนใจ (ไม่ซ้ำกัน) ไปยังอีกอันหนึ่งเมื่อเร็ว ๆ นี้: อะไรคือความแตกต่างระหว่างการมอบหมายการประเมินค่าและการผูกชื่อ

แทนที่จะตอบกลับข้อความของคุณทีละคนฉันพยายามที่นี่เพื่อให้ภาพรวมที่มีโครงสร้างของสิ่งที่เป็นเดิมพัน

มีหลายประเด็นที่ต้องพิจารณาเพื่อตอบคุณรวมถึง:

  • แบบจำลองการคำนวณคืออะไรและแนวคิดใดที่เหมาะสมสำหรับแบบจำลองที่ระบุ

  • ความหมายของคำที่คุณใช้คืออะไรและขึ้นอยู่กับบริบทอย่างไร

รูปแบบการเขียนโปรแกรมใช้งานดูเหมือนโง่เพราะคุณเห็นด้วยตาโปรแกรมเมอร์ที่จำเป็น แต่มันเป็นกระบวนทัศน์ที่แตกต่างกันและแนวคิดและการรับรู้ที่จำเป็นของคุณนั้นเป็นมนุษย์ต่างดาว คอมไพเลอร์ไม่มีอคติดังกล่าว

แต่ข้อสรุปท้ายคือมันเป็นไปได้ที่จะเขียนโปรแกรมในลักษณะการทำงานอย่างหมดจดรวมถึงการเรียนรู้ของเครื่องการคิดว่าการเขียนโปรแกรมการทำงานไม่ได้มีแนวคิดของการจัดเก็บข้อมูล ฉันดูเหมือนจะไม่เห็นด้วยกับประเด็นนี้พร้อมคำตอบอื่น ๆ

ด้วยความหวังมีน้อยคนที่จะสนใจแม้จะมีความยาวของคำตอบนี้

กระบวนทัศน์การคำนวณ

คำถามเกี่ยวกับการเขียนโปรแกรมการทำงาน (การเขียนโปรแกรมประยุกต์ aka) รูปแบบเฉพาะของการคำนวณซึ่งเป็นตัวแทนทางทฤษฎีและง่ายที่สุดคือแลมบ์ดาแคลคูลัส

หากคุณอยู่ในระดับทฤษฎีมีหลายรุ่นของการคำนวณ: เครื่องทัวริง (TM), เครื่อง RAM และอื่น ๆแคลคูลัสแลมบ์ดา, combinatory ตรรกะทฤษฎี recursive ฟังก์ชั่นระบบกึ่งพวก ฯลฯ ที่มีประสิทธิภาพมากขึ้น รุ่นที่ได้รับการพิสูจน์เทียบเท่าในแง่ของสิ่งที่พวกเขาสามารถอยู่และที่เป็นส่วนสำคัญของ วิทยานิพนธ์โบสถ์ทัวริง

แนวคิดที่สำคัญคือการลดรูปแบบซึ่งกันและกันซึ่งเป็นพื้นฐานสำหรับการสร้างความเท่าเทียมที่นำไปสู่วิทยานิพนธ์ทัวริส - ทัวริง เห็นได้จากมุมมองโปรแกรมเมอร์ลดรูปแบบหนึ่งไปยังอีกเป็นสิ่งที่เรียกว่าคอมไพเลอร์ หากคุณใช้การเขียนโปรแกรมแบบลอจิกเป็นแบบจำลองการคำนวณของคุณมันค่อนข้างแตกต่างจากรุ่นที่จัดทำโดยพีซีที่คุณซื้อในร้านค้าและคอมไพเลอร์แปลโปรแกรมที่เขียนด้วยภาษาโปรแกรมตรรกะไปเป็นรูปแบบการคำนวณที่แสดงโดยพีซีของคุณ คอมพิวเตอร์ RAM)

อย่างไรก็ตามมันไม่ได้หมายความว่าทั้งสองรุ่นทำในลักษณะเดียวกันหรือแนวคิดที่มีความหมายสำหรับหนึ่งสามารถถ่ายโอนได้เช่นกัน โดยทั่วไปขั้นตอนการคำนวณใน TM มีความสัมพันธ์เพียงเล็กน้อยกับขั้นตอนการลด( -) ในแลมบ์ดาแคลคูลัสแม้ว่าพวกเขาจะสามารถแปลได้ แนวคิดของการประเมินผลที่เหมาะสมที่สุดของการแสดงออกแลมบ์ดาค่อนข้างห่างไกลจากปัญหาความซับซ้อนในโมเดล TMβ

ในทางปฏิบัติภาษาการเขียนโปรแกรมที่เราใช้มักจะผสมผสานแนวคิดจากจุดกำเนิดทางทฤษฎีที่แตกต่างกันพยายามที่จะทำเพื่อให้บางส่วนของโปรแกรมที่เลือกจะได้รับประโยชน์จากคุณสมบัติของแบบจำลองบางอย่างที่เหมาะสม ในทำนองเดียวกันคนสร้างระบบอาจเลือกภาษาที่แตกต่างกันสำหรับส่วนประกอบที่แตกต่างกันเพื่อให้เหมาะกับภาษาให้เหมาะกับงาน

ดังนั้นคุณไม่ค่อยเห็นกระบวนทัศน์การเขียนโปรแกรมในสถานะที่บริสุทธิ์ในภาษาการเขียนโปรแกรม ภาษาการเขียนโปรแกรมยังคงจำแนกตามกระบวนทัศน์ที่โดดเด่น แต่คุณสมบัติของภาษาอาจได้รับผลกระทบเมื่อแนวคิดจากกระบวนทัศน์อื่นเกี่ยวข้อง

โดยทั่วไปแล้วภาษาเช่น Haskell และ ML หรือ CAML ถือว่าเป็นหน้าที่ แต่พวกเขาสามารถอนุญาตให้มีพฤติกรรมที่จำเป็น ... อีกอย่างหนึ่งทำไมจะพูดถึง " ชุดย่อยที่ใช้งานได้อย่างแท้จริง "?

จากนั้นหนึ่งสามารถอ้างว่าคุณสามารถทำสิ่งนี้หรือว่าในภาษาการเขียนโปรแกรมการทำงานของฉัน แต่มันไม่ได้ตอบคำถามเกี่ยวกับการเขียนโปรแกรมการทำงานเมื่อมันขึ้นอยู่กับสิ่งที่ถือได้ว่าเป็นฟังก์ชั่นพิเศษ

คำตอบควรเกี่ยวข้องกับกระบวนทัศน์เฉพาะอย่างแม่นยำยิ่งขึ้น

ตัวแปรคืออะไร

ปัญหาอีกประการคือการใช้คำศัพท์ ในวิชาคณิตศาสตร์ตัวแปรเป็นเอนทิตีที่ใช้แทนค่าที่ไม่ได้ระบุในบางโดเมน มันถูกใช้เพื่อวัตถุประสงค์ต่าง ๆ ใช้ในสมการมันอาจหมายถึงสิ่งที่มีค่าเช่นว่าการตรวจสอบสมการ วิสัยทัศน์นี้ใช้ในการเขียนโปรแกรมเชิงตรรกะภายใต้ชื่อ " ตัวแปรเชิงตรรกะ " อาจเป็นเพราะตัวแปรชื่อมีความหมายอื่นอยู่แล้วเมื่อพัฒนาโปรแกรมเชิงตรรกะ

ในการเขียนโปรแกรมที่จำเป็นแบบดั้งเดิมตัวแปรถูกเข้าใจว่าเป็นคอนเทนเนอร์ (หรือตำแหน่งหน่วยความจำ) ที่สามารถจดจำการแสดงค่าและอาจได้รับค่าปัจจุบันแทนที่ด้วยอีกอันหนึ่ง)

ในการเขียนโปรแกรมฟังก์ชั่นตัวแปรมีจุดประสงค์เดียวกับที่ใช้ในวิชาคณิตศาสตร์ในฐานะตัวยึดสำหรับค่าบางอย่าง แต่ยังไม่ได้จัดเตรียม ในการเขียนโปรแกรมแบบดั้งเดิมจำเป็นบทบาทนี้เล่นจริงโดยคงที่ (เพื่อไม่ให้สับสนกับตัวอักษรซึ่งเป็นค่าที่กำหนดไว้แสดงด้วยสัญกรณ์เฉพาะสำหรับโดเมนของค่าเช่น 123, จริง, ["abdcz", 3.14])

ตัวแปรของชนิดใด ๆ รวมทั้งค่าคงที่อาจถูกแทนด้วยตัวระบุ

ตัวแปรที่จำเป็นสามารถเปลี่ยนค่าได้และนั่นคือพื้นฐานของความผันแปร ตัวแปรการทำงานไม่สามารถ

ภาษาการเขียนโปรแกรมมักจะอนุญาตให้เอนทิตีขนาดใหญ่สร้างจากภาษาที่เล็กกว่าในภาษานั้น

ภาษาที่จำเป็นต้องมีเพื่อให้โครงสร้างดังกล่าวรวมตัวแปรและนั่นคือสิ่งที่ทำให้คุณมีข้อมูลที่ไม่แน่นอน

วิธีอ่านโปรแกรม

โปรแกรมเป็นคำอธิบายที่เป็นนามธรรมของอัลกอริทึมของคุณคือบางภาษาไม่ว่าจะเป็นการออกแบบเชิงปฏิบัติหรือภาษาบริสุทธิ์แบบกระบวนทัศน์

โดยหลักการแล้วคุณสามารถจดทุกคำพูดสำหรับสิ่งที่ควรจะหมายถึง abstractedly จากนั้นคอมไพเลอร์จะแปลว่าเป็นรูปแบบที่เหมาะสมเพื่อให้คอมพิวเตอร์ดำเนินการได้ แต่นั่นไม่ใช่ปัญหาของคุณในการประมาณครั้งแรก

แน่นอนความเป็นจริงนั้นค่อนข้างรุนแรงและเป็นเรื่องดีที่จะมีความคิดว่าเกิดอะไรขึ้นเพื่อหลีกเลี่ยงโครงสร้างที่คอมไพเลอร์จะไม่ทราบวิธีจัดการกับการดำเนินการที่มีประสิทธิภาพ แต่นั่นเป็นการเพิ่มประสิทธิภาพแล้ว ... ซึ่งคอมไพเลอร์สามารถทำได้ดีมากมักจะดีกว่าโปรแกรมเมอร์

ฟังก์ชั่นการเขียนโปรแกรมและความไม่แน่นอน

ความไม่แน่นอนขึ้นอยู่กับการดำรงอยู่ของตัวแปรที่จำเป็นที่สามารถมีค่าที่จะเปลี่ยนโดยการกำหนด เนื่องจากสิ่งเหล่านี้ไม่มีอยู่ในฟังก์ชันการเขียนโปรแกรมทุกอย่างจึงไม่อาจเปลี่ยนแปลงได้

การเขียนโปรแกรมแบบ Fuctional เกี่ยวข้องเฉพาะกับค่า

สี่ข้อความแรกของคุณเกี่ยวกับความไม่สามารถเปลี่ยนได้นั้นส่วนใหญ่ถูกต้อง แต่อธิบายด้วยมุมมองที่จำเป็นบางอย่างที่ไม่จำเป็น มันเป็นเหมือนการอธิบายด้วยสีในโลกที่ทุกคนตาบอด คุณกำลังใช้แนวคิดที่เป็นคนต่างด้าวกับการเขียนโปรแกรมการทำงาน

คุณมีเพียงค่าบริสุทธิ์และอาร์เรย์ของจำนวนเต็มเป็นค่าจริง ในการรับอาเรย์อื่นที่แตกต่างในองค์ประกอบเดียวคุณต้องใช้ค่าอาเรย์ที่แตกต่างกัน การเปลี่ยนองค์ประกอบเป็นเพียงแนวคิดที่ไม่มีอยู่ในบริบทนี้ คุณอาจมีฟังก์ชั่นที่มีอาร์เรย์และดัชนีบางส่วนเป็นอาร์กิวเมนต์และส่งกลับผลลัพธ์ที่เป็นอาร์เรย์ที่เกือบเหมือนกันซึ่งแตกต่างกันเฉพาะที่ระบุโดยดัชนี แต่มันก็ยังคงเป็นค่าอาร์เรย์อิสระ คุณค่าเหล่านี้เป็นอย่างไรไม่ใช่ปัญหาของคุณ บางทีพวกเขาอาจ "แบ่งปัน" เป็นจำนวนมากในการแปลที่จำเป็นสำหรับคอมพิวเตอร์ ... แต่นั่นเป็นหน้าที่ของคอมไพเลอร์ ... และคุณไม่ต้องการที่จะรู้ว่าสถาปัตยกรรมเครื่องมันกำลังรวบรวมอะไรอยู่

คุณไม่ได้คัดลอกค่า (มันไม่สมเหตุสมผลเป็นแนวคิดของเอเลี่ยน) คุณเพียงแค่ใช้ค่าที่มีอยู่ในโดเมนที่คุณกำหนดไว้ในโปรแกรมของคุณ ไม่ว่าคุณจะอธิบาย (เป็นตัวอักษร) หรือเป็นผลลัพธ์ของการใช้ฟังก์ชันกับค่าอื่น ๆ คุณสามารถตั้งชื่อให้พวกเขาได้ (ซึ่งเป็นการกำหนดค่าคงที่) เพื่อให้แน่ใจว่ามีการใช้ค่าเดียวกันในที่ต่างๆในโปรแกรม โปรดทราบว่าแอปพลิเคชันฟังก์ชันไม่ควรถูกมองว่าเป็นการคำนวณ แต่เป็นผลลัพธ์ของแอปพลิเคชันต่ออาร์กิวเมนต์ที่กำหนด การเขียน5+2หรือการเขียน7จำนวนเดียวกัน ซึ่งสอดคล้องกับย่อหน้าก่อนหน้า

ไม่มีตัวแปรที่จำเป็น ไม่สามารถกำหนดได้ คุณสามารถผูกชื่อกับค่าเท่านั้น (เพื่อสร้างค่าคงที่) ซึ่งแตกต่างจากภาษาที่จำเป็นที่คุณสามารถผูกชื่อกับตัวแปรที่กำหนดได้

ไม่ว่าจะมีค่าใช้จ่ายในความซับซ้อนไม่ชัดเจนโดยสิ้นเชิง สำหรับสิ่งหนึ่งคุณอ้างอิงถึงความซับซ้อนเกี่ยวข้องกับกระบวนทัศน์ที่จำเป็น มันไม่ได้ถูกกำหนดไว้สำหรับการเขียนโปรแกรมฟังก์ชั่นเว้นแต่คุณเลือกที่จะอ่านโปรแกรมการทำงานของคุณเป็นสิ่งจำเป็นซึ่งไม่ใช่เจตนาของนักออกแบบ แน่นอนว่ามุมมองการทำงานมีจุดประสงค์เพื่อให้คุณไม่ต้องกังวลเกี่ยวกับปัญหาดังกล่าวและมุ่งเน้นไปที่สิ่งที่คำนวณ มันเป็นเหมือนสเปคและการใช้งาน

คอมไพเลอร์จะต้องดูแลการใช้งานและฉลาดพอที่จะปรับสิ่งที่ต้องทำกับฮาร์ดแวร์ที่จะทำสิ่งที่ดีที่สุด

ฉันไม่ได้บอกว่าโปรแกรมเมอร์ไม่ต้องเป็นห่วง ฉันยังไม่ได้บอกว่าภาษาการเขียนโปรแกรมและเทคโนโลยีคอมไพเลอร์มีความเป็นผู้ใหญ่อย่างที่เราอยากให้เป็น

ตอบคำถาม

  1. คุณไม่ได้ปรับเปลี่ยนค่าที่มีอยู่ (แนวคิดต่างด้าว) แต่คำนวณค่าใหม่ที่แตกต่างกันตามที่ต้องการโดยอาจมีองค์ประกอบพิเศษหนึ่งรายการซึ่งเป็นรายการ

  2. โปรแกรมสามารถรับข้อมูลใหม่ได้ ประเด็นทั้งหมดคือวิธีที่คุณแสดงออกในภาษา ตัวอย่างเช่นคุณสามารถพิจารณาว่าโปรแกรมทำงานกับค่าที่ระบุเพียงค่าเดียวซึ่งอาจมีขนาดไม่ใหญ่มากซึ่งเรียกว่าอินพุตสตรีม มันเป็นค่าที่ควรจะนั่งที่นั่น (ไม่ว่าจะเป็นที่รู้จักกันอย่างเต็มที่หรือไม่ไม่ใช่ปัญหาของคุณ) จากนั้นคุณจะมีฟังก์ชันที่คืนค่าคู่ที่ประกอบด้วยองค์ประกอบแรกของสตรีมและสตรีมที่เหลือ

    คุณสามารถใช้มันเพื่อสร้างเครือข่ายของการสื่อสารส่วนประกอบด้วยวิธีการประยุกต์ใช้อย่างหมดจด (coroutines)

  3. การเรียนรู้ของเครื่องเป็นอีกปัญหาหนึ่งเมื่อคุณต้องรวบรวมข้อมูลและแก้ไขค่า ในการเขียนโปรแกรมการทำงานคุณไม่ได้ทำเช่นนั้น: คุณเพียงแค่คำนวณค่าใหม่ที่แตกต่างกันอย่างเหมาะสมตามข้อมูลการฝึกอบรม เครื่องผลลัพธ์ก็จะทำงานเช่นกัน สิ่งที่คุณกังวลคือการคำนวณเวลาและประสิทธิภาพของพื้นที่ แต่อีกครั้งนั่นเป็นปัญหาที่แตกต่างที่ควรได้รับการจัดการโดยคอมไพเลอร์

หมายเหตุสุดท้าย

มันค่อนข้างชัดเจนจากความคิดเห็นหรือคำตอบอื่น ๆ ว่าภาษาการเขียนโปรแกรมฟังก์ชั่นในทางปฏิบัติไม่ได้ทำงานอย่างหมดจด นั่นเป็นภาพสะท้อนถึงความจริงที่ว่าเทคโนโลยีของเรายังคงได้รับการปรับปรุงโดยเฉพาะอย่างยิ่งเมื่อมีการรวบรวม

เป็นไปได้ไหมที่จะเขียนในลักษณะการประยุกต์ใช้อย่างหมดจด? คำตอบนั้นเป็นที่รู้จักกันมาประมาณ 40 ปีและเป็น "ใช่" จุดประสงค์ของการตีความหมายเชิง Denotational ตามที่ปรากฏในปี 1970 นั้นมีความแม่นยำในการแปลภาษา (คอมไพล์) เป็นรูปแบบการทำงานล้วนๆถือว่าเข้าใจได้ดีกว่าในเชิงคณิตศาสตร์และถือว่าเป็นการให้เงินสนับสนุนที่ดีกว่าเพื่อกำหนดความหมายของโปรแกรม

สิ่งที่น่าสนใจคือโครงสร้างการเขียนโปรแกรมที่จำเป็นรวมถึงตัวแปรสามารถแปลเป็นสไตล์การทำงานได้โดยการแนะนำโดเมนของค่าที่เหมาะสมเช่นแหล่งข้อมูล และแม้จะมีสไตล์การใช้งานก็ยังคงคล้ายกับรหัสของคอมไพเลอร์จริงที่เขียนในรูปแบบที่จำเป็น


0

มันเป็นความเข้าใจผิดที่โปรแกรมการทำงานไม่สามารถจัดเก็บข้อมูลและฉันไม่คิดว่า Jakes ตอบอธิบายได้ดีมาก

โปรแกรมทำงานได้เช่นเดียวกับโปรแกรมใด ๆ ฟังก์ชั่นการทำแผนที่จำนวนเต็มกับจำนวนเต็ม โปรแกรมที่จำเป็นใด ๆ ที่ทำงานกับโครงสร้างข้อมูลที่ไม่สามารถเปลี่ยนแปลงได้จะมีฟังก์ชันที่เหมือนกัน นี่เป็นอีกวิธีหนึ่งในการบรรลุเป้าหมายเดียวกัน

วิธีการทำงานของการจัดเก็บข้อมูลการทดสอบจากแหล่งที่มาบางอย่างจะเรียกใช้ฟังก์ชันการจัดเก็บด้วยโครงสร้างข้อมูลเป็นอาร์กิวเมนต์และแสดงผลการเชื่อมโยงของโครงสร้างข้อมูลที่มีอยู่และข้อมูลใหม่และข้อมูลจะถูกเก็บไว้โดยไม่ต้องคิดโครงสร้างข้อมูลที่ไม่แน่นอน

จากประสบการณ์ของฉันเองฉันคิดว่าแนวคิดของโครงสร้างข้อมูลที่ไม่เปลี่ยนรูปแบบกำลังนำไปสู่นักพัฒนาทั่วไปที่จะคิดว่ามีบางสิ่งที่ไม่สามารถทำได้ กรณีนี้ไม่ได้.


"ฟังก์ชั่นโปรแกรมเหมือนกับโปรแกรมใด ๆ ทำหน้าที่จับคู่จำนวนเต็มกับจำนวนเต็มจริง ๆ " Minecraft พูดว่าเป็นฟังก์ชั่นการจับคู่จำนวนเต็มกับจำนวนเต็มได้อย่างไร
David Richerby

อย่างง่ายดาย ทุกไบต์สามารถตีความได้ว่าเป็นจำนวนเต็มไบนารี สถานะในคอมพิวเตอร์คือชุดของไบต์ โปรแกรมแม้แต่ Minecraft จะควบคุมสถานะของคอมพิวเตอร์ทำการแมปจากสถานะหนึ่งไปอีกสถานะหนึ่ง
Jeppe Hartmund

ข้อมูลที่ป้อนโดยผู้ใช้ดูเหมือนจะไม่สอดคล้องกับโลกนี้
David Richerby

อินพุตของผู้ใช้เป็นส่วนหนึ่งของสถานะคอมพิวเตอร์ มันไม่ได้มีอยู่แค่บนหน้าจอของคุณ
Jeppe Hartmund
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.