Javascript เป็นภาษาเขียนโปรแกรมเชิงฟังก์ชันหรือไม่


137

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


12
@slashmais: ไม่! นั่นเป็นเพียงการป้องกันไม่ให้เป็นภาษาที่ใช้งานได้จริง ML (อย่างน้อยภาษาถิ่นสมัยใหม่) ก็ไม่บริสุทธิ์เช่นกัน - แต่คงไม่มีใครกล้าเรียกมันว่าใช้งานไม่ได้)

4
มีภาษามากมายที่ถือว่าใช้งานได้โดยทั่วไป แต่ไม่บริสุทธิ์ ฉันไม่เห็นว่านั่นเป็นข้อกำหนดอย่างไร หากคุณต้องการเข้มงวดขนาดนั้นภาษา OOP ที่เรียกว่าส่วนใหญ่ก็ไม่ใช่ OOP เช่นกัน คุณพบว่าประมาณ 95% ของภาษาทั้งหมดเป็นภาษาที่ไม่มีกระบวนทัศน์
jalf

6
ทำไมมันถึงมีความสำคัญ? เมื่อฉันเขียนโค้ดใน C ++ ฉันไม่สนใจว่าภาษาจะ "เป็น OOP" หรือไม่ ฉันสนใจว่ามันมีคุณสมบัติ OOP บางอย่างและมีคุณสมบัติการเขียนโปรแกรมที่ใช้งานได้สองสามคุณสมบัติและคุณสมบัติการเขียนโปรแกรมที่จำเป็นมากมายและคุณสมบัติการเขียนโปรแกรมทั่วไปมากมาย แต่ไม่ว่าจะเป็นภาษา OOP "is-a" หรือภาษา FP หรืออย่างอื่นก็ไม่สำคัญ ในทำนองเดียวกันเมื่อฉันเขียนโค้ดใน JS ไม่สำคัญว่าจะเป็น FP หรือไม่ สิ่งสำคัญคือรองรับคุณสมบัติ FP ที่ดีมากมาย ดูเหมือนว่านี่จะเป็นคำถามที่ผิดที่จะถาม
jalf

3
@hvgotcodes: เหรอ? ไม่มีกฎที่บอกว่าไม่ใช่ กฎทั่วไปของฉันคือมันเป็นภาษาที่ใช้งานได้หากคุณสามารถใช้เพื่อตั้งโปรแกรมในรูปแบบการทำงานได้ เนื่องจาก Javascript มีฟังก์ชันระดับเฟิร์สคลาสการปิดและแลมบ์ดาฉันเชื่อว่าคุณทำได้และเท่าที่ฉันกังวลมันเป็นภาษาที่ใช้งานได้ ไม่ใช่ภาษาที่บริสุทธิ์ แต่ก็ไม่ใช่ภาษาส่วนใหญ่ที่เรามักพิจารณา FP (เช่น SML) จริงๆฉันคิดว่าคุณแค่ต้องคลาย หากทำให้ตากระตุกคุณต้องไปพบแพทย์
jalf

3
@jalf อย่างแน่นอน แรงจูงใจสำหรับคำถามคือฉันอยากรู้ว่าเพื่อนและคนที่ฉลาดกว่าฉันคิดอย่างไร
hvgotcodes

คำตอบ:


182

ทำซ้ำคำตอบของตัวเองสำหรับคำถามที่คล้ายกัน

ไม่มีคำจำกัดความที่ยอมรับของภาษาการเขียนโปรแกรมเชิงฟังก์ชัน

หากคุณกำหนดภาษาที่ใช้งานได้เป็นภาษาที่รองรับฟังก์ชันชั้นหนึ่งและแลมบ์ดาใช่แล้ว JavaScript * คือ * ภาษาที่ใช้งานได้

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


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


30
+1 เพื่อชี้ให้เห็นว่าไม่มีคำจำกัดความที่เป็นสากลและนำตัวอย่างบางส่วนของคุณลักษณะภาษาที่ใช้งานได้ตามแบบฉบับ JS ไม่มี

1
การใช้งาน JavaScript ของ Mozilla เวอร์ชันที่ใหม่กว่า (การจ้องมองด้วย 1.7) มีการจับคู่รูปแบบในรูปแบบของการกำหนดทำลายโครงสร้าง: developer.mozilla.org/en/New_in_JavaScript_1.7#section_20
jbeard4

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

2
@OpenLearner แอปพลิเคชันบางส่วนได้รับการสนับสนุนในทุกภาษาที่ฉันนึกออกแม้แต่ C. สำหรับคำจำกัดความบางอย่างของ "การสนับสนุน" อย่างไรก็ตาม กรณีกับ JS ไม่แตกต่างกัน ประเด็นคือการใช้งานบางส่วนนั้นทำได้ง่ายและเป็นภาษาชั้นหนึ่ง ใน JS ไม่ใช่ หากคุณอยากรู้ว่าฉันหมายถึงอะไรลองดูที่ OCaml หรือ Haskell
missingfaktor

JavaScript รองรับการเปลี่ยนรูปแบบ afaik
fka

26

ฉันจะบอกว่ามันเป็นภาษาหลายกระบวนทัศน์

แก้ไข: เป็นหลายกระบวนทัศน์และรวมถึงโครงสร้างที่ใช้งานได้


ใช่ฉันยอมรับว่ามันเป็นการผสมผสานและหลายอย่างที่แตกต่างกัน
Ashley Grenon

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

15

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

คำตอบสำหรับคำถามของคุณในระดับชีวิตประจำวันมากขึ้นคือ"ไม่"

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

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


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

2
รองรับการเขียนโปรแกรมเชิงฟังก์ชันได้มากพอ ๆ กับ C ++ หากคุณเขียนพื้นฐานที่เหมาะสมสำหรับสิ่งนี้ด้วยตัวเอง - เท่าที่คุณสามารถเลียนแบบไวยากรณ์ที่จำเป็นได้เช่น Haskell ด้วยการทำงานเพียงเล็กน้อย อย่างไรก็ตามไวยากรณ์ของ JavaScript นำไปสู่การนึกถึงขั้นตอนการทำงานมากกว่าการประเมินฟังก์ชัน ด้วยเหตุนี้ฉัน (หรือโปรแกรมเมอร์ที่ใช้งานได้ส่วนใหญ่) มองว่าการใช้คำว่า "functional" นั้นกว้างขวางเกินไป
shuhalo

@ user411768: คุณกำลังบอกว่าภาษาจะใช้งานได้หรือไม่นั้นขึ้นอยู่กับการออกแบบไลบรารีมาตรฐาน ฉันไม่เคยได้ยินคำจำกัดความนั้นมาก่อน Java มีเครื่องมือส่วนใหญ่ที่จำเป็นในการเขียนโปรแกรมในรูปแบบการทำงาน (เช่นการปิดและฟังก์ชันที่ไม่ระบุตัวตนเป็นต้น) ซึ่ง C ++ (ในปัจจุบัน) ไม่มี ฉันคิดว่านั่นทำให้ JS มี FP มากกว่า C ++ มาก ความจริงที่ว่าภาษาไม่ได้บังคับให้คุณเขียนโปรแกรมในรูปแบบ FP ไม่ได้ทำให้ "ใช้งานได้น้อยลง" ใช่หรือไม่?
jalf

1
(i) ไลบรารีมาตรฐานเป็นส่วนหนึ่งของมาตรฐานเช่นเดียวกับคุณสมบัติทางวากยสัมพันธ์และเน้นรูปแบบสำนวนและแนวความคิดบางอย่าง เช่น "C ++ กับ STL" แตกต่างจาก "C กับคลาส" มาก มันมีผลกระทบ (ii) JavaScript มีการวางแนววัตถุฟังก์ชันพลเมืองชั้นหนึ่ง - คุณลักษณะค่อนข้างตั้งฉากกับ imperativ / functional-dichotomy อย่างไรก็ตามมันไม่ได้ใช้แกงโดยตรงหรือไม่ให้ความบริสุทธิ์และไม่เคยมีจุดมุ่งหมายเพื่อสิ่งนี้ (iii) คำพูดสุดท้ายของฉันเกี่ยวกับเรื่องนั้นโปรดดูย่อหน้าแรกของโพสต์
shuhalo

3
คำกล่าวที่ว่า JavaScript และ C ++ มีความสะดวกในการเขียนโปรแกรมแบบเดียวกันนั้นผิดอย่างแน่นอน JavaScript ทำให้การเขียนโปรแกรมเชิงฟังก์ชันค่อนข้างตรงไปตรงมาและเรียบง่ายโดยไม่ต้องมีโครงสร้างที่ยุ่งเหยิงทั้งหมดที่คุณต้องทำใน C ++ เพื่อให้ได้สิ่งเดียวกัน มีโปรแกรม
เข้ารหัส

9

คำว่าภาษา "การเขียนโปรแกรมเชิงฟังก์ชัน" มีงานล้นมือมากจนทุกวันนี้แทบไม่มีประโยชน์ มีสองความหมายที่โดดเด่น:

  1. มีฟังก์ชั่นชั้นหนึ่ง
    • Javascript นี่แหละ!
  2. ขึ้นอยู่กับฟังก์ชันที่ใช้ในแคลคูลัสแลมบ์ดาโดยเน้นที่การหลีกเลี่ยงสถานะที่เปลี่ยนแปลงไม่ได้ถาวร (มักแทนที่ด้วยพารามิเตอร์ที่ส่งผ่านไปยังฟังก์ชัน)
    • ตามที่เขียนกันทั่วไป Javascript ไม่ใช่สิ่งนี้จากระยะไกล

เลือกความหมายของคุณจากนั้นคำถามก็ตอบได้


มีแหล่งที่มาที่ใช้ "การเขียนโปรแกรมเชิงฟังก์ชัน" เพื่ออ้างถึงภาษาที่มีฟังก์ชันเป็นพลเมืองลำดับแรกหรือไม่
shuhalo

@ user411768: จริงๆแล้วผู้ตอบอีกคนหนึ่งที่เชื่อมโยงกับบทความของ Wikipedia ซึ่งใช้คำจำกัดความนั้น en.wikipedia.org/wiki/Javascript - Joel Spolsky ยังกล่าวถึงคำจำกัดความนี้ใน "ภาษาโปรแกรมของคุณสามารถทำสิ่งนี้ได้หรือไม่" โพสต์เกี่ยวกับประโยชน์ของ "โปรแกรมการทำงาน"
Chuck

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

@OpenLearner: ใช่ แต่ Java ก็เหมือนกันและภาษาอื่น ๆ อีกมากมายที่โดยทั่วไปถือว่ามีความจำเป็นอย่างเคร่งครัด - คุณสามารถเขียนมันในรูปแบบที่ใช้งานได้ แต่ไม่ใช่เส้นทางแห่งความสุขของภาษา
Chuck

... แต่ JS ล่าสุดจะรองรับ
Erik Reppen

3

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


2

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


ด้วยเหตุผลดังกล่าว F # ไม่สามารถเรียกได้ว่าเป็นฟังก์ชันได้อีกต่อไป
Eric Mickelsen

1
ขวา. ตามวิกิพีเดีย F # คือสิ่งที่ฉันเพิ่งเรียกว่า Javascript: "F # [... ] เป็นภาษาการเขียนโปรแกรมแบบหลายกระบวนทัศน์ [... ] ที่ครอบคลุมการเขียนโปรแกรมเชิงฟังก์ชันและสาขาการเขียนโปรแกรมเชิงวัตถุที่จำเป็น"
Brian Onn

2

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


0

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

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


2
JavaScript เป็นเชิงวัตถุ OO ไม่ต้องการคลาส แต่ต้องการอ็อบเจ็กต์
ไม่ระบุตัวตน

3
Javascript ไม่ใช่เชิงวัตถุ แต่เป็นแบบต้นแบบ
Kris

1
JavaScript คือซุปการเขียนโปรแกรม สิ่งนี้และเล็กน้อย
Andrew S

0

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


0

@petraszd ฉันเขียนโค้ดของคุณใหม่เล็กน้อยเพื่อรับ "ใหม่" สำหรับโอเปอเรเตอร์:

   
   function ffor(a, b, f){
     function it(i){
       if(i > b)return
       f(i)
       it(i+1)
     }
     it(a)
   }

   print("----" + new Date()+"----")

   var funcs = []
   ffor(0, 9, function(i){
     funcs.push(function(){return i})
   })

   ffor(0, 9, function(i){
     print(funcs[i]())
   })

แต่ฉันรู้ว่าวิธีนี้มีข้อเสียสำหรับลูปใหญ่ ...

คำถามที่เกี่ยวข้องเกี่ยวกับการเพิ่มประสิทธิภาพการเรียกซ้ำหางใน JS

ป.ล. โพสต์ที่นี่เนื่องจากมีปัญหากับการจัดรูปแบบโค้ดขณะโพสต์เป็นความคิดเห็น


0

ใน Javascript คุณสามารถทำสิ่งนี้ได้ !!

// Data
var fruits = [
    { name: 'apple',  price: 5 }, 
    { name: 'orange', price: 10 }, 
    { name: 'lemon',  price: 15 }
]

// Request Data from magicURL
request('magicURL')
    .then(selectKeyOf('price'))
    .then(priceMethod('sum'))
    .then((result)=>{
        console.log(result) // 30
    })

ฉันได้สร้างหน้า githubเพื่อสาธิตแนวคิดนี้และคุณสามารถโคลน / ดูการใช้งานของฉันได้


0

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


-2

สิ่งที่ฉันเกลียดมากในจาวาสคริปต์ (ถ้าคุณพยายามมองว่ามันเป็นภาษา FP) คือ:

function getTenFunctionsBad() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push(function () {
      return i;
    });
  }
  return result;
}

function getTenFunctions() {
  var result = [];
  for (var i = 0; i < 10; ++i) {
    result.push((function (i) {
      return function () {
        return i;
      }
    })(i));
  }
  return result;
}

var functionsBad = getTenFunctionsBad();
var functions = getTenFunctions()
for (var i = 0; i < 10; ++i) {
  // using rhino print
  print(functionsBad[i]() + ', ' + functions[i]());
}

// Output:
//   10, 0
//   10, 1
//   10, 2
//   10, 3
//   10, 4
//   10, 5
//   10, 6
//   10, 7
//   10, 8
//   10, 9

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

ในรูปแบบเช่นคุณไม่สามารถสร้างสิ่งนั้นได้ (โอเคตกลง - ด้วยความช่วยเหลือของการอ้างอิงภาษาพื้นฐานคุณสามารถสร้างได้):

(define (make-ten-functions)
  (define (iter i)
    (cond ((> i 9) '())
          (else (cons (lambda () i) (iter (+ i 1))))))
  (iter 0))

(for-each (lambda (f)
            (display (f))
            (newline)) (make-ten-functions))

1
หืมมมผมคิดว่า Javascript ถืออ้างอิงถึงตัวแปรแต่ไม่ได้ถือการอ้างอิงถึงความคุ้มค่า
aeracode

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