แบบจำลองทางจิตหรือคำอุปมาอุปมัยโลกแห่งความจริงสำหรับการเขียนโปรแกรมฟังก์ชั่น


16

ไม่มีใครมีแบบจำลองทางจิตที่ดีหรือคำอุปมาสำหรับการเขียนโปรแกรมการทำงานซึ่งอ้างอิงบางสิ่งบางอย่างในโลกแห่งความจริง?

การวางโปรแกรมเชิงวัตถุนั้นเหมาะสมกับฉัน มีบางสิ่งที่มีคุณสมบัติและบางครั้งพวกเขายังสามารถทำสิ่งต่าง ๆ หรือทำการคำนวณเกี่ยวกับคุณสมบัติ (วิธีการ) (เช่นรถรูปร่างแมว)

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

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


คุณหมายถึงรูปธรรมใดของ "การเขียนโปรแกรมเชิงหน้าที่" ที่คุณอ้างถึง "ไม่มีผลข้างเคียง / ประกาศ" หรือ "ฟังก์ชั่นชั้นหนึ่ง / องค์ประกอบของฟังก์ชั่น" หรือทั้งคู่?
acelent

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

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

แบบจำลองทางจิตที่ดีจริงๆถ้าคุณมีประสบการณ์ในการใช้ระบบที่เหมือนยูนิกซ์ (หรือ PowerShell ใน Windows สมัยใหม่) ก็คือ shell one-liners พวกมันไม่เหมือนกันเพราะเชลล์ไพพ์เป็นเทคนิคการโปรแกรมแบบอิงโฟล์กแทนที่จะใช้งานได้ แต่มันมี "ความรู้สึก" เหมือนกับโปรแกรมเมอร์
slebetman

1
นอกจากนี้คุณยังจะพบว่าเมื่อคุณเรียนรู้ภาษาที่ใช้งานได้ในการเขียนโปรแกรมเชิงวัตถุจะใช้เป็นเครื่องมือเช่นการแสดงออกปกติ บางสิ่งที่คุณสามารถใช้ได้หากคุณต้องการ แต่คุณไม่จำเป็นต้อง ในบางภาษาเช่น lisp และ tcl and out OO ไม่ใช่คุณสมบัติในภาษา แต่เป็นไลบรารีที่คุณสามารถใช้ (หรือคุณสามารถเขียน OO ของคุณเองได้หากคุณกล้า) ดังนั้นปัญหาที่ธรรมชาติมีทางออก OO สามารถแก้ไขได้โดยใช้ OO ในภาษาที่ใช้งานได้ส่วนใหญ่ ผู้คนแค่ไม่ปฏิบัติต่อ OO เป็นศาสนา
slebetman

คำตอบ:


32

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

smallest  = head . sort

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

smallestEven = head . sort . filter even

เป็นอีกขั้นตอนหนึ่งในสายพานลำเลียง

สรุปฟังก์ชั่นเพียงอธิบายขั้นตอนที่ใช้ในการแปลงอินพุตดิบ (ชิ้นส่วน) เป็นสินค้าที่ประมวลผล (เอาท์พุท)


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

3
@GuidoAnselmi วิธีหนึ่งที่จะคิดเกี่ยวกับมันคือสายการประกอบในการเขียนโปรแกรมการทำงานสร้างผลลัพธ์ใหม่ในขณะที่ปล่อยให้อินพุทเหมือนเดิมในขณะที่สายการประกอบใน OOP แบบดั้งเดิมเปลี่ยนอินพุต
Doval

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

3
@bstamour: จะแม่นยำหนึ่งควรเขียนว่า(f . g) (x)วิธีการf(g(x))หรือวิธีการf . g \x -> f (g (x))
จอร์โจ

3
@MarjanVenema การไหลของสิ่งที่เหลืออยู่ในตัวอย่างนั้นเพียงเพราะนั่นเป็นวิธีที่.กำหนดไว้ นี้ไม่ได้เป็นวิธีการทำงานของ Haskell ทั่วไป คุณสามารถกำหนดตัวดำเนินการ|>ไพพ์ไปข้างหน้าของ F # ( ) ใน Haskell และเขียนsmallest x = (sort x) |> headและข้อมูลก็จะไหลไปทางขวา แค่คิดว่าฉันจะชี้ให้เห็นว่า
Doval

18

ไม่มีใครมีแบบจำลองทางจิตที่ดีสำหรับการเขียนโปรแกรมฟังก์ชั่น?

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


1
ขอบคุณ อย่างไรก็ตามฉันต้องการคำอุปมาจากโลกแห่งความเป็นจริง (เช่นไม่ใช่จากคอมพิวเตอร์หรือคณิตศาสตร์)
Guido Anselmi

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

16

วิธีการเกี่ยวกับหนังสือพลิก ?

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

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

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


3

สัมพันธ์

เพื่อน: ให้คนสองคนความสัมพันธ์เพื่อนปฏิบัติตามกฎหมายทั่วไปเหล่านี้

  1. มีความปรารถนาดีต่อกัน
  2. คิดว่าเป็นเพื่อนกับพวกเขา (ดังนั้นสมาชิกจะต้องปฏิบัติตามกฎหมายในความสัมพันธ์นี้)
  3. สนุกกับการใช้เวลาร่วมกัน

Monoid: มีหลายรายการและฟังก์ชั่นที่ใช้ 2 รายการและส่งคืน 1 ความสัมพันธ์แบบ monoidal เป็นไปตามกฎหมายทั่วไปเหล่านี้

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

ฟังก์ชั่นการเขียนโปรแกรมนั้นเกี่ยวกับการสรุปทั่วไปเพื่อนเป็นความสัมพันธ์ทั่วไปที่สามารถมองเห็นได้ในหลาย ๆ สถานการณ์

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

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


2

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


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

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

แต่คณิตศาสตร์นั้นมีพื้นฐานอยู่บนโลกแห่งความจริง 1 อาทิตย์ 9 ดาวเคราะห์ 2 แอปเปิ้ลบวก 2 แอปเปิ้ลทำให้สี่แอปเปิ้ล
Guido Anselmi

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

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

1

สิ่งสำคัญที่ต้องคำนึงถึงเกี่ยวกับการวางโปรแกรมการใช้งานคือทุกอย่างมีค่าแม้กระทั่งรหัสเองก็คือ 'ค่า'

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

เมื่อหนึ่งย้ายไปเป็นภาษาทำงานแทนของตารางคาร์ทีเซียนของA1และB42ฟังก์ชั่นมีชื่อ นั่นคือทั้งหมดที่มันเป็นจริง

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

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


0

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

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

ฉันพบว่ารูปแบบการใช้งานนั้นมีความซื่อสัตย์มากกว่าเกี่ยวกับสิ่งที่คอมพิวเตอร์กำลังทำอยู่ new Tesla()ท้ายที่สุดฉันไม่สามารถคิดออกมาจากอากาศ :)


-5

ประโยคมีฟังก์ชั่นมากกว่าเชิงวัตถุโดยสมมติว่าคุณแยกประโยคเหล่านั้นมากหรือน้อยเช่นนี้ ...

The brown cow is in the meadow across the deep river.

ดังนั้นเราจำเป็นต้องค้นหาวลีที่หัวแล้วส่วนที่เหลือ:

The cow (brown)
the meadow (across)
the river (deep)

ในครั้งเดียว:

sentence: The cow ((the meadow (the river (deep)) (across)) brown)

แยกวิเคราะห์ต้นไม้:

|                     sentence
|                      /         
|                  The cow
|                 /       \
|            the meadow   brown
|            /         \
|      the river      across
|              \
|              deep

Parsimony ทำให้เกิดความคิดเชิงหน้าที่

ถอดหมวกไปที่ Gottlieb Frege 1890s, Alan Turing (entschiedungsprobleme) 1930, Noom Chomsky (1960s)


4
นี่เป็นคำอธิบายที่สับสนและฉันคุ้นเคยกับ FP เพื่อเริ่มต้น
Daenyth

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