ฟังก์ชั่นการทำงานการสำแดงและการโปรแกรมจำเป็น [ปิด]


466

การทำงานของคำศัพท์, การประกาศและการเขียนโปรแกรมเชิงความหมายหมายถึงอะไร?


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

1
@Kit Imo คำตอบบางส่วนในหน้านี้กำลังทำให้เกิดข้อผิดพลาด DP == Referential transparent (RT) DP & IP เป็นสิ่งที่ตรงกันข้ามดังนั้น afaics ไม่ได้เติมเต็มทั้งหมดเช่นโปรแกรมทั้งหมดสามารถเขียนได้ทั้งสองสไตล์ การเรียกใช้ฟังก์ชันสามารถเป็น DP (RT) หรือ IP การใช้งานอาจเป็นได้ทั้งแบบผสมกันก็ได้ พวกเขาไม่ได้เป็นแบบ symbiotic ในแง่ที่ว่าการเรียกใช้ฟังก์ชัน IP ในฟังก์ชัน DP นั้นสามารถเรียก IP ของฟังก์ชัน DP ได้ พวกเขาเป็น symbiotic ในแง่ที่ว่าโลกแห่งความเป็นจริง (เช่นฟังก์ชั่นการตอบสนอง) โปรแกรมสามารถใช้การผสมผสานเช่นการโทรระดับ IP ระดับสูงเข้าสู่ฟังก์ชั่น DP
Shelby Moore III

ควรเพิ่มวิกิหรือลิงก์ในบางสิ่งที่คล้ายคลึงกับวิกิ ฯลฯ ที่นี่เป็นลิงค์ที่ยอดเยี่ยมในวิกิพีเดียen.wikipedia.org/wiki/Comparison_of_programming_paradigms
Joe


1
คำถามนี้กำลังถูกกล่าวถึงที่ Meta: meta.stackoverflow.com/q/342784/2751851
duplode

คำตอบ:


262

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

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

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

คำจำกัดความของการแสดงออกที่เปิดเผย

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

ภาษาที่ประกาศ 100% (เช่นหนึ่งในทุก ๆ นิพจน์ที่เป็นไปได้คือ RT) ไม่ได้ (ในข้อกำหนด RT อื่น ๆ ) อนุญาตให้ทำการเปลี่ยนแปลงค่าที่เก็บไว้เช่น HTML และ Haskell ส่วนใหญ่

ความหมายของการแสดงออก RT

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

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

นิยามของฟังก์ชั่นบริสุทธิ์

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

ฟังก์ชั่นที่บริสุทธิ์มีคุณสมบัติดังต่อไปนี้

  • เอาต์พุตที่สามารถสังเกตได้เท่านั้นคือค่าส่งคืน
  • การพึ่งพาเอาต์พุตเท่านั้นคืออาร์กิวเมนต์
  • อาร์กิวเมนต์จะถูกกำหนดอย่างสมบูรณ์ก่อนที่จะสร้างเอาต์พุตใด ๆ

โปรดจำไว้ว่า RT ใช้กับนิพจน์ (ซึ่งรวมถึงการเรียกใช้ฟังก์ชัน) และความบริสุทธิ์นำไปใช้กับฟังก์ชัน (การนำไปปฏิบัติ)

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

คุณลักษณะอนุพันธ์ของ RT

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

หมายเหตุความไม่สามารถเปลี่ยนแปลงได้ของค่าภายนอกเป็นส่วนย่อยของข้อกำหนดสำหรับ RT

  • ภาษาที่เปิดเผยไม่ได้มีการวนรอบโครงสร้างการควบคุมเช่นforและwhileเพราะเนื่องจากการเปลี่ยนไม่ได้สภาพห่วงจะไม่เคยเปลี่ยน

  • ภาษาที่มีการประกาศไม่ได้แสดงถึงการควบคุมการไหลนอกเหนือจากลำดับของฟังก์ชันที่ซ้อนกัน (การอ้างอิงแบบลอจิคัลที่รู้จัก) เนื่องจาก เนื่องจากความไม่สามารถเปลี่ยนได้

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

    ตัวอย่างเช่นย่อหน้า HTML <p>ไม่สามารถแสดงได้จนกว่านิพจน์ย่อย (เช่นแท็ก) ในวรรคนั้นจะได้รับการประเมิน ไม่มีสถานะที่ไม่แน่นอนเพียงการพึ่งพาคำสั่งซื้อเนื่องจากความสัมพันธ์เชิงตรรกะของลำดับชั้นแท็ก (การซ้อนของนิพจน์ย่อยซึ่งเป็นการเรียกใช้ฟังก์ชันซ้อนกันแบบอะนาล็อก )

  • ดังนั้นจึงมีแอตทริบิวต์ที่มาของการเปลี่ยนไม่ได้ (มากขึ้นโดยทั่วไป RT) ที่แสดงออกเปิดเผยแสดงเพียงตรรกะความสัมพันธ์ของส่วนประกอบ (เช่นย่อยแสดงออกอาร์กิวเมนต์ของฟังก์ชัน) และไม่ได้รัฐไม่แน่นอนความสัมพันธ์

ลำดับการประเมินผล

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

ตัวอย่างเช่นกำหนดแสดงออกซ้อนกันบางอย่างเช่นf( g(a, b), h(c, d) )การประเมินผลความกระตือรือร้นและขี้เกียจของการขัดแย้งการทำงานจะให้ผลลัพธ์ที่เหมือนกันถ้าฟังก์ชั่นf, gและhมีความบริสุทธิ์

ในขณะที่ถ้าฟังก์ชั่นf, gและhก็ไม่บริสุทธิ์แล้วทางเลือกของการประเมินผลเพื่อสามารถให้ผลที่แตกต่างกัน

หมายเหตุนิพจน์ที่ซ้อนกันเป็นฟังก์ชั่นที่ซ้อนกันในเชิงแนวคิดเนื่องจากตัวดำเนินการนิพจน์เป็นเพียงการเรียกใช้ฟังก์ชันที่ปลอมเป็นคำนำหน้าของยูนารี

สัมผัสถ้าตัวบ่งชี้ทั้งหมดเช่นa, b, c, dจะไม่เปลี่ยนรูปทุกรัฐภายนอกในการเขียนโปรแกรมไม่สามารถเข้าถึง (เช่น I / O) และไม่มีความแตกแยกชั้น abstraction แล้วฟังก์ชั่นอยู่เสมอบริสุทธิ์

โดยวิธีการที่ Haskell f (g a b) (h c d)มีไวยากรณ์ที่แตกต่างกัน

การประเมินรายละเอียดการสั่งซื้อ

ฟังก์ชั่นคือการเปลี่ยนสถานะ (ไม่ใช่ค่าที่เก็บไว้ไม่แน่นอน) จากอินพุตไปยังเอาต์พุต สำหรับองค์ประกอบ RT ของการเรียกไปยังฟังก์ชันบริสุทธิ์ลำดับของการดำเนินการเปลี่ยนสถานะเหล่านี้เป็นอิสระ การเปลี่ยนสถานะของการโทรแต่ละฟังก์ชั่นเป็นอิสระจากคนอื่น ๆ ที่เกิดจากการขาดผลข้างเคียงและหลักการที่ว่าฟังก์ชั่น RT อาจถูกแทนที่ด้วยค่าแคชของมัน เพื่อแก้ไขความเข้าใจผิดที่เป็นที่นิยมองค์ประกอบ monadic บริสุทธิ์มักจะประกาศและ RTทั้งๆที่ความจริงที่ว่าIOmonad ของ Haskell เป็นเนื้อหาที่ไม่บริสุทธิ์และจำเป็นดังนั้น wrt Worldรัฐภายนอกโปรแกรม (แต่ในแง่ของข้อแม้ด้านล่างผลข้างเคียง แยกต่างหาก)

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

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

แนวคิดการแสดงออกทั้งหมดที่มี (เป็นองค์ประกอบของ) สายงานเช่นค่าคงที่จะมีฟังก์ชั่นโดยไม่ต้องปัจจัยการผลิตผู้ประกอบการไม่มีทั้งฟังก์ชั่นด้วยการป้อนข้อมูลผู้ประกอบการมัดไบนารีฟังก์ชั่นที่มีสองปัจจัยการผลิต, การก่อสร้างที่มีฟังก์ชั่นและงบแม้กระทั่งการควบคุม (เช่นif, for, while) สามารถสร้างแบบจำลองด้วยฟังก์ชั่น เพื่อที่ว่าเหล่านี้ อาร์กิวเมนต์ฟังก์ชั่น (อย่าสับสนกับฟังก์ชั่นการสั่งซื้อโทรซ้อนกัน) จะมีการประเมินไม่ได้ประกาศโดยไวยากรณ์เช่นf( g() )กระหายสามารถประเมินgแล้วfในgผล 's หรืออาจประเมินfและมีเพียงอย่างเฉื่อยชาประเมินเมื่อผลของมันเป็นสิ่งจำเป็นภายในgf

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

ฟังก์ชั่นการเขียนโปรแกรม

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

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

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

ตัวอย่างเช่นแทนที่จะเขียนฟังก์ชั่นแยกต่างหาก (และใช้การเรียกซ้ำแทนที่จะเป็นลูปหากฟังก์ชันนั้นต้องมีการประกาศ) สำหรับแต่ละจำนวนอนันต์ของการกระทำพิเศษที่เป็นไปได้ที่สามารถนำไปใช้กับองค์ประกอบแต่ละส่วนของคอลเลกชัน ฟังก์ชั่นเช่นmap, ,fold filterฟังก์ชั่นวนซ้ำเหล่านี้ป้อนฟังก์ชั่นการทำงานพิเศษชั้นหนึ่ง ฟังก์ชันการวนซ้ำเหล่านี้ทำซ้ำการรวบรวมและเรียกใช้ฟังก์ชันการดำเนินการอินพุตเฉพาะสำหรับแต่ละองค์ประกอบ ฟังก์ชั่นการกระทำเหล่านี้มีความกระชับมากกว่าเพราะไม่จำเป็นต้องมีคำสั่งวนซ้ำเพื่อย้ำการรวบรวม

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

ความเท่าเทียม

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

หลักการของเบรนต์: การคำนวณด้วยงาน w และความลึก d สามารถนำมาใช้ใน p-processor PRAM ในเวลา O (สูงสุด (w / p, d))

ทั้งการเกิดพร้อมกันและการขนานจะต้องมีการเขียนโปรแกรมที่ประกาศเช่น immutability และ RT

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

ใบสั่งประเมินผล FP

หมายเหตุลำดับการประเมินยังส่งผลต่อการเลิกจ้างและผลข้างเคียงขององค์ประกอบการทำงาน

Eager (CBV) และ lazy (CBN) เป็นการดวลแบบเด็ดขาด [ 10 ] เนื่องจากพวกเขามีลำดับการประเมินกลับกันคือว่าฟังก์ชันด้านนอกหรือด้านในจะถูกประเมินก่อน ลองนึกภาพต้นไม้ที่กลับหัวกลับหางแล้วกระตือรือร้นที่จะประเมินจากฟังก์ชั่นกิ่งต้นไม้ฟังก์ชั่นเคล็ดลับขึ้นลำดับชั้นสาขาเพื่อลำต้นฟังก์ชั่นระดับบนสุด; ในขณะที่สันหลังยาวประเมินจากลำต้นลงไปที่ปลายกิ่ง ความกระตือรือร้นไม่มีผลิตภัณฑ์ที่เชื่อมโยงกัน ("และ", a / k / a เด็ดขาด "ผลิตภัณฑ์") และขี้เกียจไม่มีการเชื่อมต่อที่แยกจากกัน ("หรือ", "/" / a / k หมวดหมู่ "สรุป") [ 11 ]

ประสิทธิภาพ

  • กระตือรือร้น

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

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

  • ขี้เกียจ

    เช่นเดียวกับที่ไม่ใช่การเลิกจ้าง, ขี้เกียจขี้เกียจเกินไปกับองค์ประกอบการทำงานลักษณะที่แยกออกคือวาระสุดท้าย coinductive สามารถเกิดขึ้นได้ช้ากว่าที่จำเป็นส่งผลให้ในการทำงานทั้งที่ไม่จำเป็นและไม่ชะตาของความล่าช้าที่ไม่ได้เป็นกรณีที่มีความกระตือรือร้นที่ [ 10 ] [ 11 ] . ตัวอย่างของความเด็ดขาดคือสถานะ, เวลา, การไม่สิ้นสุดและการยกเว้นรันไทม์ สิ่งเหล่านี้เป็นผลข้างเคียงที่จำเป็น แต่แม้ในภาษาที่บริสุทธิ์ (เช่น Haskell) มีสถานะในคำสั่ง IO monad (หมายเหตุ: ไม่ใช่ monads ทั้งหมดที่จำเป็น!) โดยปริยายในการจัดสรรพื้นที่และเวลาเป็นสถานะที่สัมพันธ์กับความจำเป็น โลกแห่งความจริง. การใช้ขี้เกียจแม้จะมีตัวเลือกความกระตือรือร้นที่ต้องการรั่วไหล "ความเกียจคร้าน" ใน coproducts ภายในเพราะความขี้เกียจความขี้เกียจความไม่ถูกต้องมาจากฟังก์ชั่นด้านนอก(ดูตัวอย่างในส่วนปลอดการสิ้นสุดโดยที่ == เป็นฟังก์ชันตัวดำเนินการไบนารีภายนอก) นี่เป็นเพราะ coproducts ถูก จำกัด ขอบเขตโดย finality เช่นแบบเหรียญกับพีชคณิตสุดท้ายบนวัตถุสุดท้าย [ 11 ]

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

ไม่สิ้นสุดลง

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

  • กระตือรือร้น

    ด้วยความกระตือรือร้น แต่ไม่ขี้เกียจสำหรับการรวมกันของHead"และ" Tailถ้าอย่างใดอย่างหนึ่งHeadหรือTailไม่ยุติแล้วตามลำดับอย่างใดอย่างหนึ่งList( Head(), Tail() ).tail == Tail()หรือList( Head(), Tail() ).head == Head()ไม่เป็นความจริงเพราะด้านซ้ายไม่ได้และด้านขวาจะยุติ

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

  • ขี้เกียจ

    ด้วยความขี้เกียจ แต่ไม่กระตือรือร้นสำหรับการแบ่งแยกของ1"หรือ" 2ถ้าfไม่ยุติก็List( f ? 1 : 2, 3 ).tail == (f ? List( 1, 3 ) : List( 2, 3 )).tailไม่เป็นความจริงเพราะด้านซ้ายยุติและด้านขวาไม่ได้

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

[ 10 ] ความต่อเนื่องของการประกาศและความเป็นคู่อย่างมีส่วนร่วม, Filinski, ส่วนที่ 2.5.4 การเปรียบเทียบ CBV และ CBN และ 3.6.1 CBV และ CBN ใน SCL

[ 11 ] ความต่อเนื่องของการประกาศและความเป็นคู่อย่างมีส่วนร่วม, Filinski, ส่วนที่ 2.2.1 ผลิตภัณฑ์และ Coproducts, 2.2.2 เทอร์มินัลและวัตถุเริ่มต้น, 2.5.2 CBV กับผลิตภัณฑ์ที่ขี้เกียจ, และ 2.5.3 CBN พร้อม Coproducts กระตือรือร้น


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

3
ตัวย่อไม่ได้หมายถึงการให้คำจำกัดความ ที่ฉันเขียนว่า "RT มักจะย่อว่า 'ไม่มีผลข้างเคียง'" นั่นไม่ได้หมายความว่าคำจำกัดความของ RT คือ "ไม่มีผลข้างเคียง" เพราะคนอาจมีคำจำกัดความที่แตกต่างกันสำหรับ 'ผลกระทบ' ถ้าฉันพูดว่า "RT มักจะมีตัวย่อ 'xyz'" สัญลักษณ์ที่ไม่มีความหมายจะไม่ให้คำจำกัดความใด ๆ กับ RT RT มีคำจำกัดความที่แม่นยำซึ่งไม่เคยเปลี่ยนแปลงไม่ว่าจะใช้สัญลักษณ์ใดในการอ้างอิง
Shelby Moore III

ฉันไม่สามารถหาตัวอย่างโต้แย้งเพื่ออ้างสิทธิ์ว่า DP ทุกประเภทเป็น RT ตัวอย่างเช่นความหมาย (เช่นค่า) ของเงื่อนไขของไวยากรณ์ไวตามบริบทจะไม่เปลี่ยนแปลงในเวลาหรือตำแหน่งที่แตกต่างกันภายในไวยากรณ์ ดูความคิดเห็นการเขียนโปรแกรมข้อ จำกัด ของฉันด้านบน
Shelby Moore III

1
การเทียบC ในรูปแบบ ESPกับ RT ในสถานะ monad นั้นไม่ถูกต้องเนื่องจากแต่ละคำสั่ง C อาจกลายเป็นสถานะโกลบอลในขณะที่ "ภายใน" สถานะ monad แต่ละคำสั่งที่สอดคล้องกันจะสร้างสำเนาของรัฐ (แก้ไขดังนั้น) หลังคือ RT-- อดีตไม่ใช่ องค์ประกอบของ Monadic นั้นเป็นRT เสมอ DP == RT เป็นความหมายเดียวสำหรับ DP ที่เป็นชุดของคุณสมบัติที่แยกจากกัน (หลักฐานทางคณิตศาสตร์ที่ฉันถูกต้องมิฉะนั้น DP ก็ไม่มีความหมาย)
Shelby Moore III

1
ฉันหวังว่าฉันจะสามารถเข้าใจประโยคแรกที่ผ่านมานี้ ฉันอ่านคู่มือสำหรับ DAX ซึ่งระบุว่าเป็น 'ภาษาที่ใช้งานได้' สิ่งนี้หมายความว่า? ฉันไม่รู้จะไปถามป๊อปของคุณสิ
Nick.McDermaid

103

ไม่มีคำจำกัดความที่ไม่ชัดเจนและไม่ชัดเจนใด ๆ นี่คือวิธีที่ฉันจะกำหนดพวกเขา:

จำเป็น - โฟกัสอยู่ที่ขั้นตอนที่คอมพิวเตอร์ควรทำมากกว่าสิ่งที่คอมพิวเตอร์จะทำ (เช่น C, C ++, Java)

Declarative - จุดเน้นคือสิ่งที่คอมพิวเตอร์ควรทำมากกว่าวิธีที่ควรทำ (เช่น SQL)

ฟังก์ชั่น - ส่วนย่อยของภาษาที่ประกาศที่มีความสำคัญอย่างมากในการเรียกซ้ำ


1
ระลึกไว้สองสามสิ่ง: 1) คำอธิบายนั้นมีจุดประสงค์ที่จะง่ายมากกว่าการรวมทุกอย่าง 2) อย่างที่ฉันพูดมีหลายวิธีในการกำหนดภาษาเหล่านี้ ดังนั้นคำตอบอาจผิดกับคุณและถูกต้องกับคนอื่น
เจสันเบเกอร์

3
ฟังก์ชั่นการเขียนโปรแกรมไม่ใช่ "ส่วนย่อยของภาษาที่ประกาศ" การเขียนโปรแกรมที่เปิดเผยต้องไม่เปลี่ยนรูปของค่าที่เก็บไว้เขียนโปรแกรมการทำงานไม่ได้ถ้ามันไม่บริสุทธิ์ FP ดูคำตอบของฉัน ดูเพิ่มเติมคำอธิบายสำหรับเซลล์สเปรดชีต คำจำกัดความของวัตถุประสงค์ที่ถูกต้องไม่ใช่ "ไม่ชัดเจน" การเขียนโปรแกรมที่จำเป็นยังเน้นไปที่ "สิ่งที่คอมพิวเตอร์ควรทำ" ความแตกต่างเพียงอย่างเดียวคือการเขียนโปรแกรมที่จำเป็นต้องจัดการกับค่าที่เก็บไว้ไม่แน่นอน
Shelby Moore III

5
@ShelbyMooreIII - ฉันมักจะเห็นด้วยกับ Eric Meijer ในอันนี้ ไม่มีสิ่งเช่น "ภาษาที่ใช้งานไม่บริสุทธิ์" เท่าที่ฉันเกี่ยวข้อง Ocaml, F # และชอบเป็นภาษาที่จำเป็นกับโครงสร้างข้อมูลการทำงาน แต่อย่างที่ฉันพูดในคำตอบของฉันฉันไม่เชื่อว่ามีคำตอบที่ไม่ชัดเจนและไม่ชัดเจนสำหรับคำถามนี้ มีหลายวิธีในการกำหนดสิ่งต่าง ๆ
Jason Baker

3
เราสามารถพิสูจน์ได้ว่าเขาเป็นคนทำคำศัพท์ทางคณิตศาสตร์เมื่อไม่มีคำนิยามใด ๆ ที่ชัดเจนเพราะแอตทริบิวต์ที่เลือกไม่ใช่ชุดที่ไม่ต่อเนื่องกัน หากคุณกำหนดว่า FP เป็นเพียง FP บริสุทธิ์ (เช่น RT) ก็ไม่แตกต่างจาก DP, cf คำตอบของฉัน แอ็ตทริบิวต์ที่แยกจากกันของ FP รวมถึงประเภทฟังก์ชันชั้นหนึ่งซึ่งอาจเป็นฟังก์ชันที่จำเป็น ฉันพบแง่พื้นฐานความคลุมเครือที่นี่และที่นี่ การเลือกFP บริสุทธิ์เป็นมุมฉากกับนิยามของ FP เพียงอย่างเดียว
Shelby Moore III

21
@ShelbyMooreIII - ฉันกำลังตั้งสมมติฐานว่า OP ต้องการคำตอบของเขาในภาษาอังกฤษไม่ใช่ Math Nerd-ese ถ้านั่นเป็นข้อสันนิษฐานที่ไม่ถูกต้อง
Jason Baker

54

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

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

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

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

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

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

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

เพื่อสรุปจากนั้น:

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

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

ดังนั้น "ฟังก์ชั่นการเขียนโปรแกรม" มักจะอธิบายว่า "ประกาศ"


5
คำอธิบายที่ดีที่สุดจนถึงตอนนี้ ดูเหมือนว่าฟังก์ชั่นและ OOP เป็นฉากฉากกับความจำเป็นและปฏิญญา
Didier A.

คุณจะบอกว่าการเขียนโปรแกรมลอจิกคือการประกาศ? หรือมันเป็นมุมฉากเอง?
Didier A.

51

โดยสังเขป:

ภาษาจำเป็น specfies ชุดของคำสั่งที่รันคอมพิวเตอร์ในลำดับ (ทำเช่นนี้แล้วจะทำอย่างนั้น)

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

ภาษาทำงานประกาศชุดของฟังก์ชั่นทางคณิตศาสตร์ / ตรรกะซึ่งกำหนดวิธีการป้อนข้อมูลจะแปลให้เอาท์พุท เช่น. f (y) = y * y มันเป็นประเภทของภาษาที่ประกาศ


1
ฟังก์ชั่นการเขียนโปรแกรมไม่ใช่ "ประเภทของภาษาที่ประกาศ" การเขียนโปรแกรมที่เปิดเผยต้องไม่เปลี่ยนรูปของค่าที่เก็บไว้ไม่บริสุทธิ์โปรแกรมการทำงานไม่ได้ ดูคำตอบของฉัน ดูเพิ่มเติมคำอธิบายสำหรับเซลล์สเปรดชีต เพียงเหตุผลตรรกะความจำเป็น (aka คำแนะนำ) ดำเนินการในลำดับคือว่าเนื่องจากการปรากฏตัวของค่าที่เก็บไว้ไม่แน่นอนผลที่ได้จะขึ้นอยู่กับการสั่งซื้อการประเมินผล การใช้คำศัพท์ของคุณ "คำสั่ง" สามารถ (และ "กฎ" ไม่ได้) ดำเนินการกับค่าที่ไม่แน่นอน
Shelby Moore III

23

จำเป็น: วิธีการบรรลุเป้าหมายของเรา

   Take the next customer from a list.
   If the customer lives in Spain, show their details.
   If there are more customers in the list, go to the beginning

ประกาศ: สิ่งที่เราต้องการบรรลุ

   Show customer details of every customer living in Spain

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

22

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

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

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

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

การเขียนคำซ้ำ (เช่น CASL) เป็นรูปแบบการเขียนโปรแกรมอีกรูปแบบหนึ่ง มันเกี่ยวข้องกับการแปลงสัญลักษณ์ของคำพีชคณิต มันแตกต่างอย่างสิ้นเชิงจากการเขียนโปรแกรมตรรกะและการเขียนโปรแกรมการทำงาน


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

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

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

13

จำเป็น - นิพจน์อธิบายลำดับของการกระทำที่จะดำเนินการ (เชื่อมโยง)

declarative - การแสดงออกคือการประกาศที่นำไปสู่พฤติกรรมของโปรแกรม (เชื่อมโยง commutative, idempotent, monotonic)

ฟังก์ชั่น - การแสดงออกมีมูลค่าเป็นผลกระทบเท่านั้น ความหมายสนับสนุนการใช้เหตุผลที่เท่าเทียมกัน


1
สำนวนการสำแดงให้ข้อมูลแก่พฤติกรรมที่ตั้งใจของโปรแกรมความจำเป็นสามารถมีส่วนร่วมในการตั้งใจหรือไม่ตั้งใจ Declarative ไม่จำเป็นต้องเป็น commutative และ idempotent ถ้าเป็น semantics แบบจงใจ ฉันชอบสาระสำคัญที่กระชับของคุณเกี่ยวกับการใช้งานดังนั้นฉันจึงยกมันขึ้น
Shelby Moore III

10

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

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

คำอธิบายที่ยกมาของคำนิยามกล่าวถึงบทบาทการเขียนโปรแกรมฟังก์ชั่นการทำงานที่บริสุทธิ์ในการเขียนโปรแกรมประกาศ

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

การประกาศเทียบกับความจำเป็น

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

มันเป็นเปลือกเทคนิคคลุมเครือและมักจะไม่ชัดเจนในการกำหนดเปิดเผยเป็นสิ่งที่ต้องทำและความจำเป็นเป็นวิธีการทำ กรณีที่คลุมเครือคือ " อะไร " คือ " วิธี " ในโปรแกรมที่ส่งออกโปรแกรม - คอมไพเลอร์

เห็นได้ชัดว่าการเรียกซ้ำที่ไม่ได้ จำกัด ซึ่งทำให้ภาษาทัวริงสมบูรณ์นั้นก็มีความคล้ายคลึงกันในความหมาย - ไม่เพียง แต่ในโครงสร้างของการประเมินผลไวยากรณ์ (อาคาความหมายเชิงปฏิบัติการ) นี่เป็นตัวอย่างที่สมเหตุสมผลตามทฤษฎีบทของGödel -“ ระบบสัจพจน์ที่สมบูรณ์ใด ๆ ก็ไม่สอดคล้องกันเช่นกัน ” ไตร่ตรองความแปลกประหลาดที่ขัดแย้งของคำพูดนั้น! นอกจากนี้ยังเป็นตัวอย่างที่แสดงให้เห็นว่าการแสดงออกของความหมายไม่ได้มีขอบเขตที่พิสูจน์ได้ดังนั้นเราจึงไม่สามารถพิสูจน์ได้2ว่าโปรแกรม (และความหมายของความหมายของมันคล้ายกัน) หยุดยั้งทฤษฎีบท Halting

ทฤษฎีความไม่สมบูรณ์นั้นมาจากธรรมชาติพื้นฐานของจักรวาลของเราซึ่งตามที่ระบุไว้ในกฎข้อที่สองของอุณหพลศาสตร์คือ“ เอนโทรปี (หรือที่รู้จักกันว่า # ของความเป็นไปได้อิสระ) นั้นมีแนวโน้มสูงสุดตลอดกาล ” การเขียนโปรแกรมและการออกแบบของโปรแกรมไม่เคยเสร็จสมบูรณ์ - มีชีวิตอยู่! - เพราะมันพยายามตอบสนองความต้องการในโลกแห่งความเป็นจริงและความหมายของโลกแห่งความเป็นจริงนั้นเปลี่ยนแปลงอยู่เสมอและมีแนวโน้มที่จะเป็นไปได้มากขึ้น มนุษย์ไม่เคยหยุดค้นพบสิ่งใหม่ ๆ (รวมถึงข้อผิดพลาดในโปรแกรม ;-)

ในการจับภาพความคิดที่ต้องการดังกล่าวข้างต้นอย่างแม่นยำและทางเทคนิคภายในเอกภพแปลกประหลาดที่ไม่มีขอบ (ไตร่ตรองว่า! ไม่มี“ นอก” ของจักรวาลของเรา) ต้องใช้คำจำกัดความสั้น ๆ แต่ไม่หลอกลวงซึ่งจะฟังไม่ถูกต้องจนกว่าจะอธิบาย ลึก

ความหมาย:


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

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


คำจำกัดความของการประกาศนี้มีความชัดเจนในระดับท้องถิ่นในขอบเขตความหมายซึ่งหมายความว่ามันต้องมีความหมายแบบแยกส่วนรักษาความหมายที่สอดคล้องกันโดยไม่คำนึงถึงสถานที่และวิธีการที่ instantiated และใช้งานในขอบเขตทั่วโลก ดังนั้นความหมายของแต่ละแบบแยกส่วนที่เปิดเผยภายในควรจะตั้งฉากกับเป็นไปได้ทั้งหมด others- และไม่ได้เป็นไปไม่ได้ (เพราะทฤษฎีบทไม่สมบูรณ์) ทั่วโลกขั้นตอนวิธีการหรือรูปแบบการเป็นพยานความสอดคล้องซึ่งยังเป็นจุดของ“ อื่น ๆ ไม่ดีกว่าเสมอ ” โดยโรเบิร์ตฮาร์เปอร์ศาสตราจารย์ วิทยาศาสตร์คอมพิวเตอร์ที่ Carnegie Mellon University หนึ่งในนักออกแบบของ Standard ML

ตัวอย่างของความหมายเหล่านี้เปิดเผย modular รวมถึงทฤษฎีประเภท functors เช่นพิมพ์เล็กน้อย namespaces เขตข้อมูลชื่อและ WRT ไปถึงระดับการดำเนินงานของความหมายแล้วเขียนโปรแกรมการทำงานบริสุทธิ์Applicative

ดังนั้นภาษาที่ได้รับการออกแบบมาอย่างดีจะสามารถแสดงความหมายได้ชัดเจนยิ่งขึ้นแม้ว่าจะมีการสูญเสียความสามารถทั่วไปในสิ่งที่สามารถแสดงออกได้ แต่ก็ยังได้รับในสิ่งที่สามารถแสดงออกได้ด้วยความมั่นคงที่แท้จริง

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

Hyper Text Markup Language หรือ HTML - ภาษาสำหรับหน้าเว็บแบบสแตติก - เป็นตัวอย่างของภาษาที่มีการประกาศอย่างสูง (แต่ไม่สมบูรณ์แบบ3 ) ที่ (อย่างน้อยก่อน HTML 5) ไม่มีความสามารถในการแสดงพฤติกรรมแบบไดนามิก HTML อาจเป็นภาษาที่ง่ายที่สุดในการเรียนรู้ สำหรับพฤติกรรมแบบไดนามิกภาษาสคริปต์ที่จำเป็นเช่น JavaScript มักจะรวมกับ HTML HTML ที่ไม่มี JavaScript เหมาะกับคำนิยามที่ประกาศเนื่องจากแต่ละประเภทระบุ (แท็ก) รักษาความหมายที่สอดคล้องกันภายใต้องค์ประกอบภายในกฎของไวยากรณ์

คำจำกัดความเชิงแข่งขันสำหรับการประกาศคือคุณสมบัติการสับเปลี่ยนและidempotentของคำสั่งเชิงความหมายนั่นคือคำสั่งสามารถจัดลำดับใหม่และทำซ้ำโดยไม่เปลี่ยนความหมาย ตัวอย่างเช่นคำสั่งที่กำหนดค่าให้กับเขตข้อมูลที่มีชื่อสามารถจัดลำดับใหม่และทำซ้ำได้โดยไม่เปลี่ยนความหมายของโปรแกรมหากชื่อเหล่านั้นเป็นโมดูลาร์ wrt ไปยังลำดับใด ๆ บางครั้งชื่อหมายถึงคำสั่งซื้อเช่นตัวระบุเซลล์รวมถึงคอลัมน์และตำแหน่งแถวการย้ายผลรวมในสเปรดชีตจะเปลี่ยนความหมาย มิฉะนั้นคุณสมบัติเหล่านี้ต้องใช้ทั่วโลกความสอดคล้องของความหมาย โดยทั่วไปแล้วมันเป็นไปไม่ได้ที่จะออกแบบความหมายของคำสั่งเพื่อให้พวกเขายังคงสอดคล้องกันถ้าสุ่มสั่งหรือทำซ้ำเพราะคำสั่งและการทำซ้ำมีความหมายที่แท้จริงที่จะ ตัวอย่างเช่นข้อความว่า“ Foo ดำรงอยู่” (หรือกำลังก่อสร้าง) และ“ ไม่มีอยู่จริง” (และการทำลาย) ถ้าใครเห็นว่าสุ่ม endological ความหมายของความหมายจากนั้นก็ยอมรับคำนิยามนี้ทั่วไปพอสำหรับทรัพย์สินที่ประกาศ ในสาระสำคัญคือคำนิยามนี้ไม่มีความคิดเป็นคำนิยามทั่วไปเพราะมันพยายามที่จะทำให้ฉากสอดคล้องเพื่อความหมายคือจะต่อต้านความจริงที่ว่าจักรวาลของความหมายคือมากมายแบบไดนามิกและไม่สามารถจับในโลกกระบวนทัศน์การเชื่อมโยงกัน

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

C, Java, C ++, C #, PHP และ JavaScript ไม่ได้มีการประกาศโดยเฉพาะ ไวยากรณ์ของ Copute และไวยากรณ์ของ Python มีการประกาศควบคู่ไปกับผลลัพธ์ที่ตั้งใจไว้มากขึ้นเช่นความหมายเชิงไวยากรณ์ที่สอดคล้องกันซึ่งกำจัดสิ่งที่ไม่เกี่ยวข้องออกไปดังนั้นเราจึงสามารถเข้าใจรหัสได้อย่างง่ายดายหลังจากที่พวกเขาลืมไปแล้ว Copute และ Haskell บังคับใช้ระดับความหมายของความหมายในการปฏิบัติงานและสนับสนุนให้ " อย่าทำซ้ำตัวเอง " (DRY) เพราะพวกเขายอมให้กระบวนทัศน์การทำงานที่บริสุทธิ์


2แม้ในกรณีที่เราสามารถพิสูจน์ความหมายของโปรแกรมเช่นด้วยภาษา Coq สิ่งนี้ จำกัด อยู่ที่ความหมายที่แสดงในการพิมพ์และการพิมพ์ไม่สามารถจับความหมายทั้งหมดของโปรแกรมได้ - ไม่แม้แต่สำหรับภาษาที่ ไม่ทัวริงเสร็จเช่นกับ HTML + CSS เป็นไปได้ที่จะแสดงชุดค่าผสมที่ไม่สอดคล้องซึ่งทำให้มีความหมายที่ไม่ได้กำหนด

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


แก้ไข: ฉันโพสต์ความคิดเห็นต่อไปนี้ในบล็อกของ Robert Harper:

ในฟังก์ชั่นการเขียนโปรแกรม ... ช่วงของการเปลี่ยนแปลงของตัวแปรเป็นประเภท

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

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

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

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

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

ดังนั้นฉันจึงสรุปได้ว่ามีเพียงภาษาที่ไม่ใช่ทัวริงเท่านั้นที่สามารถประกาศได้

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

ดังนั้นสำหรับฉันแล้วดูเหมือนว่าภาษาที่ประกาศเป็นสิ่งที่ตรงกันข้ามกับการ เรียกซ้ำที่ไม่ได้ จำกัดเช่นทฤษฎีบทที่สองที่ไม่สมบูรณ์ของGödelไม่สามารถพิสูจน์ได้

Lesie Lamport เขียนเทพนิยายเกี่ยวกับวิธี Euclid อาจทำงานรอบทฤษฎีบทที่ไม่สมบูรณ์ของGödelนำไปใช้กับหลักฐานทางคณิตศาสตร์ในบริบทการเขียนโปรแกรมภาษาโดยเพื่อให้สอดคล้องกันระหว่างประเภทและตรรกะ (Curry-Howard จดหมาย ฯลฯ )


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

7

การเขียนโปรแกรมที่จำเป็น: บอก“ เครื่องจักร” ว่าจะทำอะไรและผลที่ตามมาคือสิ่งที่คุณต้องการให้เกิดขึ้น

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

ตัวอย่างของความจำเป็น

function makeWidget(options) {
    const element = document.createElement('div');
    element.style.backgroundColor = options.bgColor;
    element.style.width = options.width;
    element.style.height = options.height;
    element.textContent = options.txt;

    return element;
}

ตัวอย่างของการประกาศ

function makeWidget(type, txt) {
    return new Element(type, txt);
}

หมายเหตุ: ความแตกต่างไม่ใช่ความกะทัดรัดหรือความซับซ้อนหรือสิ่งที่เป็นนามธรรม ตามที่ระบุไว้แตกต่างกันคือวิธีเทียบกับสิ่งที่


2
ดีหนึ่ง แต่ดีกว่าถ้าคุณให้ตัวอย่างอย่างน้อยหนึ่งอย่างสำหรับทั้งสอง!
Pardeep Jain

4

ทุกวันนี้โฟกัสใหม่: เราต้องการการจำแนกแบบเก่าหรือไม่?

ความจำเป็น / การ declarative / ฟังก์ชั่นด้านเป็นสิ่งที่ดีในอดีตที่ผ่านมาในการจำแนกภาษาทั่วไป แต่ในปัจจุบันทุกคน "ภาษาใหญ่" (Java, Python, JavaScript, ฯลฯ ) มีตัวเลือกบางคน (โดยทั่วไปจะมีกรอบ ) ที่จะแสดงกับ "โฟกัสอื่น ๆ" มากกว่าหนึ่งหลัก (จำเป็นปกติ) และเพื่อแสดงกระบวนการแบบขนานฟังก์ชั่นที่ประกาศ, lambdas ฯลฯ

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

มุ่งเน้นไปที่การหลอมรวมของข้อมูลด้วยอัลกอริทึม

ตัวอย่างที่ดีในการอธิบาย เท่าที่จะทำได้อ่านเกี่ยวกับ jQuery ที่วิกิพีเดีย ,

ชุดของคุณสมบัติหลักของ jQuery - การเลือกองค์ประกอบ DOM, การสำรวจเส้นทางและการจัดการ -, เปิดใช้งานโดยเอ็นจิ้นตัวเลือก (... ), สร้าง "รูปแบบการเขียนโปรแกรม" ใหม่, อัลกอริธึมหลอมรวมและโครงสร้างข้อมูล DOM

ดังนั้น jQuery จึงเป็นตัวอย่างที่ดีที่สุด (เป็นที่นิยม) ของการมุ่งเน้นไปที่"รูปแบบการเขียนโปรแกรมใหม่"ซึ่งไม่เพียง แต่วางแนววัตถุเท่านั้น " Fusing อัลกอริทึมและโครงสร้างข้อมูล " jQuery ค่อนข้างโต้ตอบเป็นสเปรดชีต แต่ไม่ใช่ "มุ่งเน้นเซลล์" คือ " DOM-node oriented " ... การเปรียบเทียบสไตล์หลักในบริบทนี้:

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

  2. ฟิวชั่นบางอย่าง : กลยุทธ์คลาสสิกทั้งหมดของฟิวชั่นในปัจจุบันมีกรอบการใช้เป็นกระบวนทัศน์ ... dataflow , การเขียนโปรแกรมที่ขับเคลื่อนด้วยกิจกรรม (หรือภาษาเฉพาะโดเมนเก่าเป็นawkและXSLT ) ... เช่นเดียวกับการเขียนโปรแกรมด้วยสเปรดชีตที่ทันสมัย ตัวอย่างของรูปแบบการเขียนโปรแกรมแบบโต้ตอบ

  3. บิ๊กฟิวชั่น : คือ "สไตล์ jQuery" ... jQuery เป็นภาษาเฉพาะโดเมนที่มุ่งเน้นไปที่ " หลอมรวมอัลกอริทึมและโครงสร้างข้อมูล DOM "
    PS: อื่น ๆ "ภาษาสอบถาม" เช่น XQuery, SQL (กับ PL เป็นตัวเลือกการแสดงออกความจำเป็น) นอกจากนี้ยังมีตัวอย่างข้อมูล algorith ฟิวชั่น แต่พวกเขาจะเกาะกับฟิวชั่นใด ๆ กับโมดูลของระบบอื่น ๆ ... ฤดูใบไม้ผลิเมื่อใช้ find()-variants และข้อกำหนดของข้อกำหนดเป็นอีกตัวอย่างที่ดีของการหลอมรวม


3

การเขียนโปรแกรมแบบ Declarative เป็นการเขียนโปรแกรมโดยการแสดงตรรกะบางช่วงเวลาระหว่างอินพุตและเอาต์พุตตัวอย่างเช่นใน pseudocode ตัวอย่างต่อไปนี้จะเป็นการประกาศ:

def factorial(n):
  if n < 2:
    return 1
  else:
    return factorial(n-1)

output = factorial(argvec[0])

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

ผลลัพธ์เดียวกันในรูปแบบที่จำเป็นคือ:

a = 1
b = argvec[0]
while(b < 2):
  a * b--

output = a

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

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

ภาษาที่ประกาศอย่างหมดจด ได้แก่ Haskell และ Pure Prolog ขนาดเลื่อนจากที่หนึ่งไปยังที่อื่น ๆ คือ: Pure Prolog, Haskell, OCaml, Scheme / Lisp, Python, Javascript, C--, Perl, PHP, C ++, Pascall, C, Fortran, Assembly


คุณไม่ได้กำหนดโปรแกรมมิงฟังก์ชัน คุณนัยไม่ถูกต้อง "บางอย่างหมดจด 'ภาษาที่เปิดเผย" ที่เขียนโปรแกรมที่เปิดเผยสามารถที่ไม่บริสุทธิ์ การโปรแกรมมิชชันนารีแบบ Declarative ต้องการค่าที่ไม่เปลี่ยนแปลงของการจัดเก็บ ดูคำตอบของฉัน ความไม่สามารถเปลี่ยนแปลงได้คือคุณภาพ "อมตะ" - เห็นว่าการประกาศของคุณfactorialไม่ได้เปลี่ยนแปลงค่าใด ๆ
Shelby Moore III

3

บางคำตอบที่ดีที่นี่เกี่ยวกับ "ประเภท" ที่ระบุไว้

ฉันส่งแนวคิดเพิ่มเติม "แปลกใหม่" เพิ่มเติมที่มักเกี่ยวข้องกับฝูงชนการเขียนโปรแกรมใช้งาน:

  • โดเมนเฉพาะภาษาหรือการเขียนโปรแกรมDSL : สร้างภาษาใหม่เพื่อจัดการกับปัญหาที่เกิดขึ้นในมือ
  • Meta-Programming : เมื่อโปรแกรมของคุณเขียนโปรแกรมอื่น
  • การเขียนโปรแกรมเชิงวิวัฒนาการ : ที่ซึ่งคุณสร้างระบบที่ปรับปรุงตัวเองอย่างต่อเนื่องหรือสร้างโปรแกรมย่อยที่ดีขึ้นอย่างต่อเนื่อง

3

ฉันคิดว่าอนุกรมวิธานของคุณไม่ถูกต้อง มีความต้องการและการประกาศที่ต่างกันสองชนิด ฟังก์ชั่นเป็นเพียงประเภทย่อยของการประกาศ BTW วิกิพีเดียระบุข้อเท็จจริงเดียวกัน


+1: ใช่กระบวนทัศน์คือแอปเปิ้ลและส้ม
Nikhil Chelliah

FP ไม่ใช่ "เพียงประเภทย่อยของการประกาศ" FP นั้นมีมุมฉากกับขั้วของความต้องการเทียบกับ DP DP ต้องการความไม่เปลี่ยนแปลงของค่าที่เก็บไว้, FP ไม่บริสุทธิ์ Wikipedia กำลังทำให้บริสุทธิ์ FP กับ FP โดยอ้างว่าไร้สาระที่แนวคิดต่อไปนี้คือ "โดยทั่วไปต่างประเทศกับการเขียนโปรแกรมที่จำเป็น": ฟังก์ชั่นชั้นหนึ่งการเรียกซ้ำลำดับการประเมินผลและการพิมพ์แบบคงที่ วิกิพีเดียแล้วยอมรับว่าไม่บริสุทธิ์ "โปรแกรมการทำงานในภาษาที่ไม่ใช่หน้าที่"
Shelby Moore III

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

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

2

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


ดูความคิดเห็นของฉันด้านล่างคำตอบอื่น ๆ FP ไม่ได้ประกาศเสมอ อะไรคืออนุกรมวิธานที่ไม่ถูกต้องสำหรับ IP กับ DP เนื่องจาก DP และ IP มีตรรกะที่เกี่ยวข้องกับอะไรและอย่างไร
Shelby Moore III 3
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.