Clojure vs Lisps คนอื่น ๆ [ปิด]


94

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

ฉันได้อ่านหนังสือหลายเล่มเกี่ยวกับ Clojure ( Programming Clojure , Practical Clojure , The Joy of Clojureและ Manning Early Access edition of Clojure in Action ) และฉันคิดว่ามันเป็นภาษาที่ยอดเยี่ยม ฉันกำลังอ่านLet Over Lambdaซึ่งส่วนใหญ่เกี่ยวข้องกับมาโคร Lisp ทั่วไปและมันก็เป็นภาษาที่น่าสนใจมากเช่นกัน

ฉันไม่ใช่ผู้เชี่ยวชาญด้าน Lisp (เป็นมือใหม่มากกว่า) แต่ภาษาตระกูลนี้ทำให้ฉันหลงใหลเช่นเดียวกับการเขียนโปรแกรมเชิงฟังก์ชันโดยทั่วไป

ข้อดีของ Clojure (และข้อเสียของ "อื่น ๆ "):

  • ทำงานบน JVM

    • JVM เป็นสภาพแวดล้อมทางภาษาที่มีความเสถียรและมีประสิทธิภาพสูงซึ่งตรงตามความฝันของ Sun ในเรื่อง "เขียนครั้งเดียววิ่ง [เกือบ] ที่ไหนก็ได้" ฉันสามารถเขียนโค้ดบน Macbook Pro รวบรวมเป็นไฟล์ JAR ที่ปฏิบัติการได้จากนั้นเรียกใช้บน Linux และ Microsoft Windows โดยมีการทดสอบเพิ่มเติมเล็กน้อย

    • JVM (ฮอตสปอตและอื่น ๆ ) รองรับการรวบรวมขยะคุณภาพสูงและการรวบรวมและการเพิ่มประสิทธิภาพแบบทันเวลาที่มีประสิทธิภาพมาก เมื่อไม่กี่ปีที่ผ่านมาฉันเขียนทุกอย่างที่ต้องทำงานเร็วใน C ตอนนี้ฉันไม่ลังเลที่จะทำใน Java

    • แบบมาตรฐานเรียบง่ายแบบมัลติเธรด Common Lisp มีแพ็คเกจมัลติเธรดมาตรฐานหรือไม่

    • เที่ยวบินไปถึงความน่าเบื่อของวงเล็บทุกคนด้วย[], {}และ#{}แม้ผู้เชี่ยวชาญสามัญชัดอาจจะบอกว่ามีแมโครอ่านคุณสามารถเพิ่มเหล่านั้นเพื่อ CL

ข้อเสียของ Clojure :

  • ทำงานบน JVM
    • ไม่มีการเรียกซ้ำหรือการต่อเนื่องของหาง Common Lisp สนับสนุนความต่อเนื่องหรือไม่? ฉันเชื่อว่าโครงการต้องการการสนับสนุนทั้งสองอย่าง

ข้อดีของผู้อื่น (โดยเฉพาะ Lisp โดยเฉพาะ) (และข้อเสียของ Clojure):

  • มาโครตัวอ่านที่ผู้ใช้กำหนดเองได้

  • ข้อดีอื่น ๆ ?

ความคิด? ความแตกต่างอื่น ๆ ?


15
โดยส่วนตัวฉันชอบวงเล็บชนิดหนึ่ง) ดูเหมือนโค้ด "สะอาดกว่า"
Moe

3
จากสิ่งที่ฉันอ่านในรายการข้อดีของคุณฉันคิดว่าคุณอาจจะชอบ Erlang www.erlang.org
Peer Stritzinger

4
Clojure รองรับการเรียกซ้ำหางอย่างชัดเจนผ่านแบบฟอร์มพิเศษ "ซ้ำ" สิ่งนี้ช่วยให้คุณได้รับประโยชน์ทั้งหมดของการเรียกซ้ำหางหากคุณต้องการอย่างชัดเจน (ข้อยกเว้นเพียงอย่างเดียวคือในปัจจุบันไม่สนับสนุนการเรียกซ้ำหางร่วมกันระหว่างหลายฟังก์ชัน)
mikera

1
Clojure ยังสนับสนุนความต่อเนื่องอย่างน้อยก็ในแง่ของ "สไตล์การส่งผ่านความต่อเนื่อง" คุณถูกต้องที่ไม่มีการต่อเนื่องชั้นหนึ่ง ดูstackoverflow.com/questions/1173133/continuate-in-clojure
mikera

@mikera: หางซ้ำในฟังก์ชั่นเดียว สองฟังก์ชั่นที่โทรหากันต้องทำด้วย "trampolining" ซึ่งเป็นลักษณะของ kludgy (แต่สง่างามในแบบของมันเอง :-))
Ralph

คำตอบ:


52

รายการเหตุผลส่วนตัวของฉันที่เลือก Clojure กับ Lisps คนอื่น ๆ (ป.ล. ฉันยังคิดว่า Lisps ทุกคนยอดเยี่ยมมาก!):

  • ทำงานบน JVM - ด้วยเหตุนี้จึงได้รับการเข้าถึงโดยอัตโนมัติไปยังวิศวกรรมที่ยอดเยี่ยมใน JVM เอง (อัลกอริธึมการรวบรวมขยะขั้นสูงการเพิ่มประสิทธิภาพ HotSpot JIT เป็นต้น)

  • ความสามารถในการทำงานร่วมกันของ Java ที่ดีมาก - ให้ความเข้ากันได้กับไลบรารีที่หลากหลายในระบบนิเวศของภาษา Java / JVM ฉันใช้ Clojure เป็นภาษา "กาว" เพื่อเชื่อมต่อไลบรารี Java ที่แตกต่างกันโดยมีผลดี ในขณะที่ฉันพัฒนาโค้ด Java จำนวนมากมันมีประโยชน์สำหรับฉันที่ Clojure ทำงานร่วมกับเครื่องมือ Java ได้ดี (เช่นฉันใช้ Maven, Eclipse พร้อมปลั๊กอินทวนเข็มนาฬิกาสำหรับการพัฒนา Clojure ของฉัน)

  • ไวยากรณ์ที่ดีสำหรับเวกเตอร์[1 2 3]แผนที่{:bob 10, :jane 15}และชุด#{"a" "b" "c"}- ฉันพิจารณาเครื่องมือที่จำเป็นสำหรับการเขียนโปรแกรมสมัยใหม่ (นอกเหนือจากรายการแน่นอน!)

  • โดยส่วนตัวแล้วฉันชอบการใช้วงเล็บเหลี่ยมสำหรับการผูกแบบฟอร์ม: เช่น(defn foo [a b] (+ a b))- ฉันคิดว่ามันทำให้อ่านโค้ดได้ชัดเจนขึ้นเล็กน้อย

  • เน้นการเขียนโปรแกรมที่ขี้เกียจและใช้งานได้โดยมีโครงสร้างข้อมูลแบบต่อเนื่องไม่เปลี่ยนรูปโดยเฉพาะไลบรารี Clojure หลักทั้งหมดได้รับการออกแบบมาเพื่อรองรับสิ่งนี้โดยค่าเริ่มต้น

  • การใช้งาน STM ที่ยอดเยี่ยมสำหรับการทำงานพร้อมกันแบบมัลติคอร์ ฉันเชื่อว่า Clojure มีเรื่องราวการทำงานร่วมกันที่ดีที่สุดของภาษาใด ๆ ในขณะนี้ (ดูวิดีโอนี้เพื่อดูรายละเอียดเพิ่มเติมโดย Rich Hickey เอง )

  • มันเป็น Lisp-1 (เช่น Scheme) ซึ่งโดยส่วนตัวแล้วฉันชอบ (ฉันคิดว่าในภาษาที่ใช้งานได้มันสมเหตุสมผลที่จะเก็บฟังก์ชันและข้อมูลไว้ในเนมสเปซเดียวกัน)


2
+1 สำหรับ STM โดยตัวมันเองก็เพียงพอที่จะพิสูจน์โดยใช้ Clojure
André Caron

2
คุณยังสามารถรับ STM ได้โดยใช้ไลบรารี CL-STM
Mike Manilone

2
@ AndréCaronเฉพาะในกรณีที่คุณต้องการ
พับขวา

หากคุณต้องการเขียนเว็บแอปพลิเคชันแบบธรรมดาและโฮสต์ไว้ให้พูดว่าโฮสต์ราคาถูก $ 5 / เดือนซึ่งเป็นไปไม่ได้กับ Clojure เนื่องจาก JVM ถูกต้องหรือไม่?
Hexatonic

@Hexatonic ฉันไม่ค่อยมีประสบการณ์ แต่มันยากที่จะเชื่อว่าเครื่องที่ใช้งานอยู่ทุกวันนี้จะไม่มี JVM
MasterMastic

25

โปรดทราบว่า Clojure เป็นภาษาและการนำไปใช้งาน (โดยปกติจะอยู่ใน JVM) Common Lisp เป็นภาษาที่มีการใช้งานที่แตกต่างกันมากกว่าสิบแบบ เราจึงมีหมวดหมู่ที่ไม่ตรงกันตรงนี้ ตัวอย่างเช่นคุณอาจเปรียบเทียบ Clojure กับ SBCL

โดยทั่วไป:

  • Common Lisp เวอร์ชันหนึ่งทำงานบน JVM: ABCL

  • การใช้ Lisp ทั่วไปส่วนใหญ่ไม่ทำ

  • การใช้งาน CL ส่วนใหญ่มีความสามารถในการทำงานหลายอย่างพร้อมกันไลบรารีมีอินเทอร์เฟซทั่วไป

  • Common Lisp มีไวยากรณ์สำหรับอาร์เรย์ ไวยากรณ์สำหรับชนิดข้อมูลอื่น ๆ สามารถเขียนโดยผู้ใช้และจัดเตรียมโดยไลบรารีต่างๆ

  • Common Lisp ไม่สนับสนุนทั้งการเพิ่มประสิทธิภาพการโทรหางหรือการต่อเนื่อง การดำเนินการจัดเตรียม TCO และไลบรารีมีรูปแบบของการต่อเนื่อง


24

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

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

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


3
@ ชาร์ลีดอกไม้: ฉันเชื่อว่าใน Common Lisp มันเป็นไปได้ที่จะตั้งโปรแกรมในรูปแบบ "ใช้งานได้อย่างหมดจด" (การสนับสนุนโครงสร้างข้อมูลแบบต่อเนื่อง ฯลฯ ) แต่ต้องมีระเบียบวินัย แก้ไข?
Ralph

2
เพียงแค่คำชี้แจงเกี่ยวกับ "ไม่มีผลข้างเคียงไม่มีสถานะที่เปลี่ยนแปลงได้" - Clojure มีสถานะที่ไม่แน่นอน (การอ้างอิงอะตอมตัวแทน ฯลฯ ทั้งหมดไม่แน่นอน) แต่ต้องการให้คุณเข้าถึงด้วยวิธีการควบคุม (เช่นผ่านกลไก STM และธุรกรรมที่เกี่ยวข้อง ปรับปรุงความหมาย)
mikera

5
@mikera: ยกเว้นว่า Clojure ต้องอาศัยการใช้ไลบรารี Java เพื่อให้สามารถใช้งานได้และไลบรารีเหล่านั้นทั้งหมดต้องการรูปแบบที่จำเป็นและเต็มไปด้วยผลข้างเคียง ฉันพบว่าการผูกกับ Java เป็นของขวัญที่มีพิษ ...
André Caron

1
@Andre - แน่นอนว่าถ้าคุณตัดสินใจที่จะใช้ไลบรารีที่ต้องการสถานะที่ไม่แน่นอนและความหมายที่จำเป็นคุณต้องจัดการสิ่งนี้ สิ่งนี้ไม่แตกต่างจากถ้าคุณเข้าถึงห้องสมุดดังกล่าวจากภาษาอื่น ๆ แต่คุณมีสองตัวเลือกที่ดี: a) อย่าใช้ไลบรารีดังกล่าว - คุณสามารถเขียนโค้ดที่ดีอย่างสมบูรณ์แบบใน Clojure ที่บริสุทธิ์หรือ b) ตัดความซับซ้อนของการเชื่อมต่อกับไลบรารีเหล่านี้ในอินเทอร์เฟซการทำงานสไตล์ Clojure ที่ดีซึ่งโดยปกติจะใช้งานง่าย มาโครหรือเอเจนต์เป็นต้นโดยรวมแล้วฉันพบว่าความสามารถในการควบคุมไลบรารี Java มีประโยชน์มากกว่าที่เป็นอยู่
mikera

4
@mikera: ห้องสมุดมีประโยชน์ ฉันแค่ชี้ให้เห็นว่าการใช้ไลบรารี Java (นี่เป็นหนึ่งในเป้าหมายหลักของ Rich Hickey สำหรับภาษานี้) ขัดกับแง่มุมที่ "ใช้งานได้มากกว่า lisps อื่น ๆ " ของ Clojure ความคิดเห็นของฉันตั้งใจจะหมายความว่า: "เว้นแต่คุณจะเขียนใหม่ / ปิดไลบรารีเหล่านี้คุณจะได้รับโค้ดที่ดูจำเป็นและจะไม่ได้รับประโยชน์จากส่วนที่ดีกว่าของ Clojure"
André Caron

10

นี่เป็นวิดีโอที่ดีกับการเปรียบเทียบของโครงการ (ไม้ส่วนใหญ่) และ Clojure

เพื่อความเป็นธรรมแร็กเก็ตมีน้ำตาลไวยากรณ์ (ข้อมูลผู้อ่านเพิ่มเติม) สำหรับประเภทข้อมูลด้วย (#hash, #, วงเล็บเหลี่ยม ฯลฯ )

นอกจากนี้วิธีเดียวของ Clojure ในการโทรหางที่เหมาะสมคือการใช้recurนั่นคือข้อเสียของการรวบรวมไปยัง JVM

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


ฉันเดาว่าลิงค์ตายไปแล้ว
nawfal

1
@nawfal ฉันคิดว่าฉันแก้ไขแล้ว
Daniil

6
ลิงค์ตาย (อีกแล้ว?)
ทิ้งบัญชี

1
หน้าตาเช่นวิดีโอลิงค์ที่สามารถพบได้ที่นี่: vimeo.com/22675078
GDP2

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