การเขียนโปรแกรมฟังก์ชั่นแตกต่างกันไปหรือเป็นจริงที่ยากขึ้นจริงหรือ


12

การเขียนโปรแกรมฟังก์ชั่นแตกต่างกันไปหรือเป็นจริงที่ยากขึ้นจริงหรือ

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

คำถามของฉัน: พูดว่าปัญหาตอนนี้คือการป้อนข้อมูลอูฐกรณี

เช่นนั้นqwe_asd_zxc_rty_fgh_vbnจะกลายเป็นqweAsdZxcRtyFghVbn

วิธีการขั้นตอนคือ:

  1. แยกมันตาม _
  2. วนรอบอาร์เรย์ที่กระโดดข้ามรายการแรก
  3. สำหรับแต่ละรายการเราใช้อักษรตัวแรกเป็นตัวพิมพ์ใหญ่
  4. เข้าร่วมผลลัพธ์ด้วยกัน

วิธีการทำงานคือ:

  1. หากไม่พบ_ผลตอบแทนinput
  2. ตัดinputพร้อมแรก_(เช่นที่เราได้รับqweและasd_zxc_rty_gfh_cvb)
  3. ใช้อักษรตัวแรกของheadและตกลงด้วยตัวพิมพ์ใหญ่ที่มีf(tail)

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

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


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

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

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

1
ฉันคิดว่าความแตกต่างระหว่างฟังก์ชั่นและขั้นตอนกลายเป็นที่สงสัยเนื่องจากภาษา maintstream เช่น JavaScript, C #, Groovy มีคุณสมบัติการทำงานมากขึ้น
281377

2
การโปรแกรมเชิงซ้อนนั้นยากขึ้นและตอบโต้ได้ง่ายสำหรับผู้ที่ไม่มีประสบการณ์การเขียนโปรแกรมมาก่อน การแสดงออกเช่นx=x+1สามารถระเบิดสมองที่ไม่คาดหวัง ฟังก์ชั่นการเขียนโปรแกรมเป็นเรื่องธรรมชาติไม่มีอะไรมากไปกว่าฟังก์ชั่นทางคณิตศาสตร์ที่บริสุทธิ์และน่าเชื่อถือ
SK-logic

คำตอบ:


12

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

สำหรับผู้มาใหม่บ่อยครั้งที่คุณจะไม่สามารถเปลี่ยนค่าของบางสิ่งได้

ที่ฉันเรียน CS เราได้รับการสอนภาษาที่ใช้งานได้เป็นหลักสูตรแรกของเรา และทุกคนที่ได้เรียนรู้ C ++ หรือ Java ก่อนหน้านี้จะต้องดิ้นรนต่อสู้กับมัน ผู้ที่ยังใหม่ต่อการเขียนโปรแกรมก็หยิบมันขึ้นมาได้ง่ายๆ


คุณเป็นหนึ่งในผู้ที่เพิ่งเริ่มโปรแกรมและหยิบมันขึ้นมาได้ง่ายๆใช่ไหม?
Pacerier

ฉันอยู่ที่ไหนสักแห่งระหว่าง ฉันแหย่รอบเล็กน้อยด้วย C ++ และ PHP ก่อนหน้านี้ แต่ไม่เพียงพอที่จะคุ้นเคยกับความคิดที่จำเป็น รูปแบบที่ค่อนข้างชัดเจนเมื่อคุณดูที่ชั้นโดยรวม นอกจากนี้เป็นเวลาเกือบทศวรรษที่ผ่านมาจึงไม่มีผมไม่ได้ค่อนข้างใหม่ในการเขียนโปรแกรมในวันนี้;)
jalf

ตัวแปรไม่เปลี่ยนรูป? mathematica ไม่ใช่ภาษาโปรแกรมที่ใช้งานได้หรือ ตัวแปรใน mathematica นั้นแน่นอนไม่แน่นอนใช่ไหม?
user56834

20

มันแตกต่างกัน

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

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

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

หน้าที่และขั้นตอนเป็นแนวคิดที่ค่อนข้างราบรื่นอย่างไรก็ตามพวกเขามักจะทับซ้อนกัน


4

ใช่การเขียนโปรแกรมเชิงฟังก์ชั่นมีแนวโน้มที่จะยากสำหรับคนหลายคนที่จะเข้าใจ (ฉันมักจะพูดว่า

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

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

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

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

ผลก็คือเราสามารถพูดคุยปัญหาทั่วไปได้ค่อนข้างง่าย แทนการเข้ารหัสอย่างหนัก '_' และ "ตัวพิมพ์ใหญ่" โดยตรงในการแปลงอย่างไรก็ตามเราสามารถมีสิ่งต่อไปนี้:

s&r(pattern, transform, string) {
    if (!pattern(string))
        return string
    else
        return transform(matched part of string) + s&r(rest of string);
}

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

my_pattern(string) return beginning(string) == '_';

จากนั้นเราก็ส่งฟังก์ชั่นนั้นไปยัง s & r ตอนนี้มันเป็นฟังก์ชั่นเล็ก ๆ น้อย ๆ และเราได้เข้ารหัสมันแบบคงที่ทั้งหมด ภาษาที่ใช้งานได้กลายเป็นเรื่องที่น่าสนใจเมื่อเราใช้เหมือนที่เราสามารถ REs และสร้างฟังก์ชั่นใหม่ทั้งหมดได้ทันทีบนพื้นฐานของสิ่งที่ชอบป้อนข้อมูลจากผู้ใช้ แต่ต่างจาก RE ที่ฟังก์ชั่นนั้นไม่จำเป็นต้องใช้ ฟังก์ชั่นปกติเหมือนคนอื่น ๆ


4

นี่คือรหัสที่สมบูรณ์ในRacket :

;; camelize : string -> string
(define (camelize str)
  (let ([parts (regexp-split #rx"_" str)])
    ;; result of regexp-split is never empty
    (apply string-append
           (first parts)
           (map string-titlecase (rest parts)))))

(camelize "qwe_asd_zxc_rty_fgh_vbn")
;; => "qweAsdZxcRtyFghVbn"

ในฐานะโปรแกรมเมอร์ที่ใช้งานได้ซึ่งมีประสบการณ์เชิงกระบวนการฉันไม่คิดว่ามันจะใช้เวลานานกว่าที่จะ "คิดออก" วิธีแก้ปัญหาขั้นตอน แต่แน่นอนว่าจะต้องใช้เวลานานกว่าในการพิมพ์

BTW ตัวอย่างที่คาดไว้ผลการโพสต์ต้นฉบับผิด: มันหายไป "h" ใกล้ถึงจุดสิ้นสุด


gd เพื่อชี้ให้เห็นว่า แก้ไขแล้ว
Pacerier

3

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

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

(I amคุ้นเคยกับความคิดที่ว่าสถาปัตยกรรม von Neumann เป็นพลที่สุดและเราไม่ควรจิตใจอคติเริ่มต้นของรายละเอียดที่ไม่เกี่ยวข้องเช่นสถาปัตยกรรมเครื่องและแทนที่จะโดยตรงแนะนำให้ความหมายของการเขียนโปรแกรมภาษา. ในความเป็นจริงฉันได้ สอนหลักสูตรดังกล่าวด้วยตัวเอง แต่ยิ่งฉันรู้สึกว่านี่เป็นเป้าหมายที่สูงส่ง แต่เข้าใจผิดผู้คนเรียนรู้การเขียนโปรแกรมโดยการสร้างความเข้าใจจากล่างขึ้นบน


7
โดยตรรกะที่ควรจะประกอบที่ง่ายที่สุดของทุกภาษาที่จะเรียนรู้ :)
Homde

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

2
@mko ไม่โดยตรรกะนี้ไบต์จริง011011001001101...จะเป็นภาษาที่ง่ายที่สุดในการเรียนรู้!
MarkJ

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