การทำงานของคำศัพท์, การประกาศและการเขียนโปรแกรมเชิงความหมายหมายถึงอะไร?
การทำงานของคำศัพท์, การประกาศและการเขียนโปรแกรมเชิงความหมายหมายถึงอะไร?
คำตอบ:
ในขณะที่เขียนสิ่งนี้คำตอบที่ได้รับการโหวตสูงสุดในหน้านี้จะไม่ถูกต้องและยุ่งเหยิงกับคำจำกัดความที่เปิดเผยและจำเป็นรวมถึงคำตอบที่เสนอราคา 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ทั้งๆที่ความจริงที่ว่าIO
monad ของ Haskell เป็นเนื้อหาที่ไม่บริสุทธิ์และจำเป็นดังนั้น wrt World
รัฐภายนอกโปรแกรม (แต่ในแง่ของข้อแม้ด้านล่างผลข้างเคียง แยกต่างหาก)
การประเมินความกระตือรือร้นหมายถึงฟังก์ชั่นการประเมินข้อโต้แย้งก่อนที่จะเรียกใช้ฟังก์ชั่นและการประเมินผลแบบขี้เกียจหมายความว่าข้อโต้แย้งจะไม่ได้รับการประเมินจนกว่า (และถ้า) พวกเขาจะเข้าถึงได้ภายในฟังก์ชั่น
คำจำกัดความ : พารามิเตอร์ของฟังก์ชันถูกประกาศที่ไซต์นิยามฟังก์ชันและอาร์กิวเมนต์ของฟังก์ชันจะมีให้ที่ไซต์เรียกฟังก์ชัน ทราบความแตกต่างระหว่างพารามิเตอร์และการโต้แย้ง
แนวคิดการแสดงออกทั้งหมดที่มี (เป็นองค์ประกอบของ) สายงานเช่นค่าคงที่จะมีฟังก์ชั่นโดยไม่ต้องปัจจัยการผลิตผู้ประกอบการไม่มีทั้งฟังก์ชั่นด้วยการป้อนข้อมูลผู้ประกอบการมัดไบนารีฟังก์ชั่นที่มีสองปัจจัยการผลิต, การก่อสร้างที่มีฟังก์ชั่นและงบแม้กระทั่งการควบคุม (เช่นif
, for
, while
) สามารถสร้างแบบจำลองด้วยฟังก์ชั่น เพื่อที่ว่าเหล่านี้ อาร์กิวเมนต์ฟังก์ชั่น (อย่าสับสนกับฟังก์ชั่นการสั่งซื้อโทรซ้อนกัน) จะมีการประเมินไม่ได้ประกาศโดยไวยากรณ์เช่นf( g() )
กระหายสามารถประเมินg
แล้วf
ในg
ผล 's หรืออาจประเมินf
และมีเพียงอย่างเฉื่อยชาประเมินเมื่อผลของมันเป็นสิ่งจำเป็นภายในg
f
Caveat ไม่มีภาษาทัวริงที่สมบูรณ์ (เช่นที่ช่วยให้การเรียกซ้ำไม่ได้ จำกัด ) เป็นการประกาศอย่างสมบูรณ์แบบเช่นการประเมินที่ขี้เกียจแนะนำหน่วยความจำและการกำหนดเวลาไม่แน่นอน แต่ผลข้างเคียงเหล่านี้เนื่องจากตัวเลือกของใบสั่งการประเมินผลจะถูก จำกัด การใช้หน่วยความจำเวลาดำเนินการเวลาแฝงไม่สิ้นสุดและภายนอก hysteresisดังนั้นการซิงโครไนซ์ภายนอก
ฟังก์ชั่นการเขียนโปรแกรม
เนื่องจากการเขียนโปรแกรมแบบประกาศไม่สามารถมีลูปได้ดังนั้นวิธีเดียวที่จะวนซ้ำคือการเรียกใช้ซ้ำ ในแง่นี้การโปรแกรมเชิงฟังก์ชันนั้นเกี่ยวข้องกับการเขียนโปรแกรมเชิงประกาศ
แต่เขียนโปรแกรมการทำงานไม่ได้ จำกัด อยู่กับการเขียนโปรแกรมที่เปิดเผย องค์ประกอบของการทำงานสามารถเทียบกับ subtypingโดยเฉพาะอย่างยิ่งเกี่ยวกับการแสดงออกปัญหาที่ขยายสามารถทำได้โดยทั้งเชื้อเพิ่มหรือสลายการทำงาน การขยายสามารถผสมผสานทั้งสองวิธี
ฟังก์ชั่นการเขียนโปรแกรมมักจะทำให้ฟังก์ชั่นเป็นวัตถุชั้นหนึ่งความหมายประเภทฟังก์ชั่นสามารถปรากฏในไวยากรณ์ที่ใดก็ได้ประเภทอื่น ๆ อาจ ผลที่สุดคือฟังก์ชั่นสามารถป้อนข้อมูลและดำเนินการกับฟังก์ชั่นได้ดังนั้นการแยกส่วนของข้อกังวลโดยเน้นองค์ประกอบของฟังก์ชั่นคือการแยกการพึ่งพาระหว่าง subcomputations ของการคำนวณที่กำหนดขึ้น
ตัวอย่างเช่นแทนที่จะเขียนฟังก์ชั่นแยกต่างหาก (และใช้การเรียกซ้ำแทนที่จะเป็นลูปหากฟังก์ชันนั้นต้องมีการประกาศ) สำหรับแต่ละจำนวนอนันต์ของการกระทำพิเศษที่เป็นไปได้ที่สามารถนำไปใช้กับองค์ประกอบแต่ละส่วนของคอลเลกชัน ฟังก์ชั่นเช่นmap
, ,fold
filter
ฟังก์ชั่นวนซ้ำเหล่านี้ป้อนฟังก์ชั่นการทำงานพิเศษชั้นหนึ่ง ฟังก์ชันการวนซ้ำเหล่านี้ทำซ้ำการรวบรวมและเรียกใช้ฟังก์ชันการดำเนินการอินพุตเฉพาะสำหรับแต่ละองค์ประกอบ ฟังก์ชั่นการกระทำเหล่านี้มีความกระชับมากกว่าเพราะไม่จำเป็นต้องมีคำสั่งวนซ้ำเพื่อย้ำการรวบรวม
อย่างไรก็ตามโปรดทราบว่าหากฟังก์ชั่นไม่บริสุทธิ์แล้วมันเป็นขั้นตอนจริงๆ เราอาจโต้แย้งได้ว่าการเขียนโปรแกรมฟังก์ชั่นที่ใช้ฟังก์ชั่นที่ไม่บริสุทธิ์เป็นขั้นตอนการเขียนโปรแกรมจริงๆ ดังนั้นถ้าเราเห็นด้วยว่าการแสดงออกที่สำแดงเป็น RT เราสามารถพูดได้ว่าการเขียนโปรแกรมตามขั้นตอนไม่ใช่การเขียนโปรแกรมเชิงประกาศและทำให้เราอาจโต้แย้งว่าการเขียนโปรแกรมการทำงานเป็น RT เสมอและต้องเป็นเซตย่อยของการเขียนโปรแกรมเชิงประกาศ
ความเท่าเทียม
องค์ประกอบการทำงานนี้พร้อมฟังก์ชั่นชั้นหนึ่งสามารถแสดงความลึกในขนานได้โดยการแยกฟังก์ชั่นอิสระ
หลักการของเบรนต์: การคำนวณด้วยงาน w และความลึก d สามารถนำมาใช้ใน p-processor PRAM ในเวลา O (สูงสุด (w / p, d))
ทั้งการเกิดพร้อมกันและการขนานจะต้องมีการเขียนโปรแกรมที่ประกาศเช่น immutability และ RT
ดังนั้นสมมติฐานที่อันตรายนี้ที่ Parallelism == เห็นพ้องด้วยมาจากไหน? มันเป็นผลตามธรรมชาติของภาษาที่มีผลข้างเคียง: เมื่อภาษาของคุณมีผลข้างเคียงทุกที่แล้วทุกครั้งที่คุณพยายามทำมากกว่าหนึ่งอย่างในแต่ละครั้งที่คุณมีปัจจัยไม่แน่นอนที่เกิดจากการแทรกของผลกระทบจากการดำเนินการแต่ละอย่าง . ดังนั้นในภาษาที่มีผลข้างเคียงวิธีเดียวที่จะได้รับความเท่าเทียมคือการเกิดขึ้นพร้อมกัน ดังนั้นจึงไม่น่าแปลกใจที่เรามักจะเห็นทั้งสองแฟทต์
หมายเหตุลำดับการประเมินยังส่งผลต่อการเลิกจ้างและผลข้างเคียงขององค์ประกอบการทำงาน
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 กระตือรือร้น
ไม่มีคำจำกัดความที่ไม่ชัดเจนและไม่ชัดเจนใด ๆ นี่คือวิธีที่ฉันจะกำหนดพวกเขา:
จำเป็น - โฟกัสอยู่ที่ขั้นตอนที่คอมพิวเตอร์ควรทำมากกว่าสิ่งที่คอมพิวเตอร์จะทำ (เช่น C, C ++, Java)
Declarative - จุดเน้นคือสิ่งที่คอมพิวเตอร์ควรทำมากกว่าวิธีที่ควรทำ (เช่น SQL)
ฟังก์ชั่น - ส่วนย่อยของภาษาที่ประกาศที่มีความสำคัญอย่างมากในการเรียกซ้ำ
ความจำเป็นและคำอธิบายที่อธิบายถึงสองรูปแบบของการเขียนโปรแกรมตรงข้าม สิ่งที่ขาดไม่ได้คือวิธีการ "ตามสูตรทีละขั้นตอน" แบบดั้งเดิมในขณะที่การประกาศมีมากกว่า "นี่คือสิ่งที่ฉันต้องการตอนนี้คุณต้องหาวิธีที่จะทำ"
วิธีการทั้งสองนี้เกิดขึ้นตลอดการเขียนโปรแกรม - แม้แต่ภาษาเดียวกันและโปรแกรมเดียวกัน โดยทั่วไปวิธีการที่ใช้ในการประกาศนั้นถือว่าดีกว่าเพราะมันทำให้โปรแกรมเมอร์ไม่ต้องระบุรายละเอียดมากมายในขณะที่ยังมีโอกาสที่จะเกิดข้อผิดพลาดได้น้อยลง (ถ้าคุณอธิบายผลลัพธ์ที่คุณต้องการและกระบวนการอัตโนมัติที่ผ่านการทดสอบแล้วบางอย่าง กำหนดขั้นตอนจากนั้นคุณอาจหวังว่าสิ่งต่าง ๆ น่าเชื่อถือมากกว่าต้องระบุแต่ละขั้นตอนด้วยตนเอง)
ในทางกลับกันวิธีการที่จำเป็นช่วยให้คุณควบคุมได้ในระดับต่ำมากขึ้น - เป็น "วิธีการสร้างไมโคร" สำหรับการเขียนโปรแกรม และนั่นอาจทำให้โปรแกรมเมอร์ใช้ประโยชน์จากความรู้เกี่ยวกับปัญหาเพื่อให้คำตอบมีประสิทธิภาพมากขึ้น ดังนั้นจึงไม่ใช่เรื่องผิดปกติสำหรับบางส่วนของโปรแกรมที่จะเขียนในรูปแบบที่ชัดเจนยิ่งขึ้น แต่สำหรับชิ้นส่วนที่มีความสำคัญต่อความเร็วนั้นมีความจำเป็นมากกว่า
อย่างที่คุณอาจจินตนาการภาษาที่คุณใช้ในการเขียนโปรแกรมส่งผลกระทบต่อวิธีการที่คุณสามารถประกาศได้ - ภาษาที่มี "smarts" ในตัวสำหรับการทำงานสิ่งที่ต้องทำเมื่อได้รับคำอธิบายของผลลัพธ์ เข้าใกล้กว่าที่โปรแกรมเมอร์ต้องการเพิ่มสติปัญญาประเภทนั้นด้วยรหัสที่จำเป็นก่อนที่จะสามารถสร้างเลเยอร์การประกาศเพิ่มเติมที่ด้านบน ยกตัวอย่างเช่นภาษาที่เป็นภาษาอารัมภบทถือเป็นการประกาศอย่างมากเพราะมีกระบวนการในตัวที่ค้นหาคำตอบ
จนถึงตอนนี้คุณจะสังเกตเห็นว่าฉันไม่ได้กล่าวถึงการเขียนโปรแกรมการทำงาน นั่นเป็นเพราะเป็นคำที่มีความหมายไม่เกี่ยวข้องกับอีกสองทันที การเขียนโปรแกรมที่ใช้งานง่ายที่สุดนั้นหมายความว่าคุณใช้ฟังก์ชั่น โดยเฉพาะอย่างยิ่งที่คุณใช้ภาษาที่รองรับฟังก์ชั่นเป็น "ค่าชั้นหนึ่ง" - ซึ่งหมายความว่าไม่เพียง แต่คุณสามารถเขียนฟังก์ชั่น แต่คุณสามารถเขียนฟังก์ชั่นที่เขียนฟังก์ชั่น (ที่เขียนฟังก์ชั่นที่ ... ) ฟังก์ชั่น. ในระยะสั้น - ฟังก์ชั่นนั้นมีความยืดหยุ่นและพบได้ทั่วไปเช่นเดียวกับสตริงและตัวเลข
มันอาจฟังดูแปลก ๆ ที่ฟังก์ชั่นความจำเป็นและการประกาศมักถูกกล่าวถึงด้วยกัน เหตุผลนี้เป็นผลมาจากการใช้ความคิดของการเขียนโปรแกรมการทำงาน "เพื่อที่สุด" ฟังก์ชั่นในความหมายที่บริสุทธิ์เป็นสิ่งที่มาจากคณิตศาสตร์ - ชนิดของ "กล่องดำ" ที่รับอินพุตและให้ผลลัพธ์เดียวกัน และพฤติกรรมแบบนั้นไม่ต้องการการเก็บตัวแปรที่เปลี่ยนแปลง ดังนั้นหากคุณออกแบบภาษาการเขียนโปรแกรมที่มีจุดประสงค์คือการใช้ความคิดที่บริสุทธิ์และได้รับอิทธิพลทางคณิตศาสตร์ของการเขียนโปรแกรมเชิงฟังก์ชันคุณจะต้องปฏิเสธความคิดส่วนใหญ่เกี่ยวกับค่านิยมที่สามารถเปลี่ยนแปลงได้ (ในแง่ที่ จำกัด เทคนิค)
และถ้าคุณทำเช่นนั้น - ถ้าคุณ จำกัด วิธีที่ตัวแปรสามารถเปลี่ยนแปลงได้ - โดยเกือบจะเกิดอุบัติเหตุคุณต้องบังคับให้โปรแกรมเมอร์เขียนโปรแกรมที่มีการประกาศมากขึ้นเพราะส่วนใหญ่ของการเขียนโปรแกรมเชิงความจำเป็นอธิบายถึงการเปลี่ยนแปลงของตัวแปรและคุณจะไม่สามารถ ทำอย่างนั้น! ดังนั้นปรากฎว่าการเขียนโปรแกรมการทำงาน - โดยเฉพาะการเขียนโปรแกรมในภาษาการทำงาน - มีแนวโน้มที่จะให้รหัสที่เปิดเผยมากขึ้น
เพื่อสรุปจากนั้น:
ความจำเป็นและการประกาศเป็นรูปแบบการเขียนโปรแกรมที่คัดค้านสองรูปแบบ (ชื่อเดียวกันใช้สำหรับภาษาโปรแกรมที่สนับสนุนสไตล์เหล่านั้น)
ฟังก์ชั่นการเขียนโปรแกรมเป็นรูปแบบของการเขียนโปรแกรมที่ฟังก์ชั่นมีความสำคัญมากและเป็นผลให้ค่าการเปลี่ยนแปลงมีความสำคัญน้อยลง ความสามารถที่ จำกัด ในการระบุการเปลี่ยนแปลงในค่าบังคับสไตล์ที่เปิดเผยมากขึ้น
ดังนั้น "ฟังก์ชั่นการเขียนโปรแกรม" มักจะอธิบายว่า "ประกาศ"
โดยสังเขป:
ภาษาจำเป็น specfies ชุดของคำสั่งที่รันคอมพิวเตอร์ในลำดับ (ทำเช่นนี้แล้วจะทำอย่างนั้น)
ภาษาที่เปิดเผยประกาศชุดของกฎเกี่ยวกับสิ่งที่ควรจะส่งผลผลจากการที่ปัจจัยการผลิต (เช่น. ถ้าคุณมีแล้วผลที่ได้คือข) เอ็นจินจะใช้กฎเหล่านี้กับอินพุตและให้เอาต์พุต
ภาษาทำงานประกาศชุดของฟังก์ชั่นทางคณิตศาสตร์ / ตรรกะซึ่งกำหนดวิธีการป้อนข้อมูลจะแปลให้เอาท์พุท เช่น. f (y) = y * y มันเป็นประเภทของภาษาที่ประกาศ
จำเป็น: วิธีการบรรลุเป้าหมายของเรา
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
การเขียนโปรแกรมจำเป็นหมายถึงรูปแบบของการเขียนโปรแกรมใด ๆ ที่โปรแกรมของคุณมีโครงสร้างจากคำแนะนำที่อธิบายถึงวิธีการดำเนินงานที่ดำเนินการโดยเครื่องคอมพิวเตอร์ที่จะเกิดขึ้น
การเขียนโปรแกรมเปิดเผยหมายถึงรูปแบบของการเขียนโปรแกรมใด ๆ ที่โปรแกรมของคุณคือคำอธิบายอย่างใดอย่างหนึ่งของปัญหาหรือการแก้ปัญหา - แต่ไม่ได้อย่างชัดเจนรัฐวิธีการทำงานจะทำ
หน้าที่ Programmingจะเขียนโปรแกรมโดยการประเมินการทำงานและหน้าที่ของฟังก์ชั่น ... ที่ (กำหนดอย่างเคร่งครัด) ทำงานหมายถึงการเขียนโปรแกรมการเขียนโปรแกรมด้วยการกำหนดผลข้างเคียงฟังก์ชั่นทางคณิตศาสตร์ฟรีเพื่อให้มันเป็นรูปแบบของการเขียนโปรแกรมที่เปิดเผย แต่มันไม่ได้เป็นเพียงชนิดของการเขียนโปรแกรมที่เปิดเผย .
การเขียนโปรแกรมลอจิก (ตัวอย่างใน Prolog) เป็นอีกรูปแบบหนึ่งของการโปรแกรมเชิงประกาศ มันเกี่ยวข้องกับการคำนวณโดยการตัดสินใจว่าคำสั่งแบบลอจิคัลเป็นจริงหรือไม่หรือสามารถทำให้พอใจได้ โดยทั่วไปโปรแกรมจะเป็นชุดของข้อเท็จจริงและกฎ - เช่นคำอธิบายมากกว่าชุดคำสั่ง
การเขียนคำซ้ำ (เช่น CASL) เป็นรูปแบบการเขียนโปรแกรมอีกรูปแบบหนึ่ง มันเกี่ยวข้องกับการแปลงสัญลักษณ์ของคำพีชคณิต มันแตกต่างอย่างสิ้นเชิงจากการเขียนโปรแกรมตรรกะและการเขียนโปรแกรมการทำงาน
จำเป็น - นิพจน์อธิบายลำดับของการกระทำที่จะดำเนินการ (เชื่อมโยง)
declarative - การแสดงออกคือการประกาศที่นำไปสู่พฤติกรรมของโปรแกรม (เชื่อมโยง commutative, idempotent, monotonic)
ฟังก์ชั่น - การแสดงออกมีมูลค่าเป็นผลกระทบเท่านั้น ความหมายสนับสนุนการใช้เหตุผลที่เท่าเทียมกัน
ตั้งแต่ฉันเขียนคำตอบก่อนหน้านี้ฉันได้กำหนดคำนิยามใหม่ของคุณสมบัติที่ประกาศซึ่งอ้างถึงด้านล่าง ฉันยังได้กำหนดโปรแกรมที่จำเป็นเป็นคุณสมบัติคู่
คำจำกัดความนี้ดีกว่าคำที่ฉันให้ไว้ในคำตอบก่อนหน้านี้เพราะสั้นกระชับและกว้างกว่า แต่มันอาจเป็นเรื่องยากที่จะคร่ำครวญเพราะความหมายของทฤษฎีความไม่สมบูรณ์ที่ใช้กับการเขียนโปรแกรมและการใช้ชีวิตโดยทั่วไปนั้นเป็นเรื่องยากสำหรับมนุษย์ที่จะปิดล้อมจิตใจของพวกเขา
คำอธิบายที่ยกมาของคำนิยามกล่าวถึงบทบาทการเขียนโปรแกรมฟังก์ชั่นการทำงานที่บริสุทธิ์ในการเขียนโปรแกรมประกาศ
ประเภทของการเขียนโปรแกรมที่แปลกใหม่ทั้งหมดเข้ากับอนุกรมวิธานต่อไปนี้ของการประกาศเทียบกับความจำเป็นเนื่องจากคำจำกัดความต่อไปนี้อ้างว่าพวกเขาเป็นคู่
การประกาศเทียบกับความจำเป็น
คุณสมบัติการประกาศเป็นสิ่งแปลก ๆ ป้านและยากที่จะจับภาพในคำจำกัดความทางเทคนิคที่แม่นยำยังคงทั่วไปและไม่คลุมเครือเพราะมันเป็นความเชื่อที่ไร้เดียงสาที่เราสามารถประกาศความหมาย (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 จดหมาย ฯลฯ )
การเขียนโปรแกรมที่จำเป็น: บอก“ เครื่องจักร” ว่าจะทำอะไรและผลที่ตามมาคือสิ่งที่คุณต้องการให้เกิดขึ้น
การเขียนโปรแกรมเพื่อการประกาศ: บอก“ เครื่องจักร” ว่าคุณต้องการจะเกิดอะไรขึ้นและปล่อยให้คอมพิวเตอร์หาวิธีการทำ
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);
}
หมายเหตุ: ความแตกต่างไม่ใช่ความกะทัดรัดหรือความซับซ้อนหรือสิ่งที่เป็นนามธรรม ตามที่ระบุไว้แตกต่างกันคือวิธีเทียบกับสิ่งที่
ความจำเป็น / การ declarative / ฟังก์ชั่นด้านเป็นสิ่งที่ดีในอดีตที่ผ่านมาในการจำแนกภาษาทั่วไป แต่ในปัจจุบันทุกคน "ภาษาใหญ่" (Java, Python, JavaScript, ฯลฯ ) มีตัวเลือกบางคน (โดยทั่วไปจะมีกรอบ ) ที่จะแสดงกับ "โฟกัสอื่น ๆ" มากกว่าหนึ่งหลัก (จำเป็นปกติ) และเพื่อแสดงกระบวนการแบบขนานฟังก์ชั่นที่ประกาศ, lambdas ฯลฯ
ดังนั้นตัวแปรที่ดีของคำถามนี้คือ"อะไรคือแง่มุมที่ดีในการจำแนกกรอบงานในวันนี้" ... สิ่งสำคัญคือสิ่งที่เราสามารถติดป้าย"รูปแบบการเขียนโปรแกรม" ...
ตัวอย่างที่ดีในการอธิบาย เท่าที่จะทำได้อ่านเกี่ยวกับ jQuery ที่วิกิพีเดีย ,
ชุดของคุณสมบัติหลักของ jQuery - การเลือกองค์ประกอบ DOM, การสำรวจเส้นทางและการจัดการ -, เปิดใช้งานโดยเอ็นจิ้นตัวเลือก (... ), สร้าง "รูปแบบการเขียนโปรแกรม" ใหม่, อัลกอริธึมหลอมรวมและโครงสร้างข้อมูล DOM
ดังนั้น jQuery จึงเป็นตัวอย่างที่ดีที่สุด (เป็นที่นิยม) ของการมุ่งเน้นไปที่"รูปแบบการเขียนโปรแกรมใหม่"ซึ่งไม่เพียง แต่วางแนววัตถุเท่านั้น " Fusing อัลกอริทึมและโครงสร้างข้อมูล " jQuery ค่อนข้างโต้ตอบเป็นสเปรดชีต แต่ไม่ใช่ "มุ่งเน้นเซลล์" คือ " DOM-node oriented " ... การเปรียบเทียบสไตล์หลักในบริบทนี้:
ไม่มีฟิวชั่น : ในทุก ๆ "ภาษาใหญ่" ในการแสดงออก / การทำงาน / การประกาศ / ความจำเป็นใด ๆ ปกติคือ "ไม่มีฟิวชั่น" ของข้อมูลและอัลกอริทึมยกเว้นโดยการวางแนววัตถุบางอย่างที่เป็นฟิวชั่นในมุมมองโครงสร้าง Algebric ที่เข้มงวด
ฟิวชั่นบางอย่าง : กลยุทธ์คลาสสิกทั้งหมดของฟิวชั่นในปัจจุบันมีกรอบการใช้เป็นกระบวนทัศน์ ... dataflow , การเขียนโปรแกรมที่ขับเคลื่อนด้วยกิจกรรม (หรือภาษาเฉพาะโดเมนเก่าเป็นawkและXSLT ) ... เช่นเดียวกับการเขียนโปรแกรมด้วยสเปรดชีตที่ทันสมัย ตัวอย่างของรูปแบบการเขียนโปรแกรมแบบโต้ตอบ
บิ๊กฟิวชั่น : คือ "สไตล์ jQuery" ... jQuery เป็นภาษาเฉพาะโดเมนที่มุ่งเน้นไปที่ " หลอมรวมอัลกอริทึมและโครงสร้างข้อมูล DOM "
PS: อื่น ๆ "ภาษาสอบถาม" เช่น XQuery, SQL (กับ PL เป็นตัวเลือกการแสดงออกความจำเป็น) นอกจากนี้ยังมีตัวอย่างข้อมูล algorith ฟิวชั่น แต่พวกเขาจะเกาะกับฟิวชั่นใด ๆ กับโมดูลของระบบอื่น ๆ ... ฤดูใบไม้ผลิเมื่อใช้ find()
-variants และข้อกำหนดของข้อกำหนดเป็นอีกตัวอย่างที่ดีของการหลอมรวม
การเขียนโปรแกรมแบบ 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
factorial
ไม่ได้เปลี่ยนแปลงค่าใด ๆ
บางคำตอบที่ดีที่นี่เกี่ยวกับ "ประเภท" ที่ระบุไว้
ฉันส่งแนวคิดเพิ่มเติม "แปลกใหม่" เพิ่มเติมที่มักเกี่ยวข้องกับฝูงชนการเขียนโปรแกรมใช้งาน:
ฉันคิดว่าอนุกรมวิธานของคุณไม่ถูกต้อง มีความต้องการและการประกาศที่ต่างกันสองชนิด ฟังก์ชั่นเป็นเพียงประเภทย่อยของการประกาศ BTW วิกิพีเดียระบุข้อเท็จจริงเดียวกัน
โดยสรุปสไตล์การเขียนโปรแกรมยิ่งเน้นสิ่งที่ (ต้องทำ) โดยย่อรายละเอียดของวิธีการ (ทำ) ยิ่งสไตล์นั้นถือเป็นการเปิดเผย ตรงข้ามเป็นจริงสำหรับความจำเป็น ฟังก์ชั่นการเขียนโปรแกรมที่เกี่ยวข้องกับรูปแบบการประกาศ