ทำไมการเรียนล่ามเสียงกระเพื่อมในเสียงกระเพื่อมจึงสำคัญ?


30

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

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

ฉันถามสิ่งนี้เพราะฉันเพิ่งเสร็จสิ้นการเขียนล่ามแบบแผนในโครงการ (นำมาจาก SICP http://mitpress.mit.edu/sicp/ ) และตอนนี้ฉันกำลังเขียนล่ามหลามในแบบแผนและฉันกำลังพยายามที่จะมีความศักดิ์สิทธิ์ตามตำนานนี้ ที่ควรมาจากอดีตโดยเฉพาะ ฉันกำลังมองหารายละเอียดทางเทคนิคเฉพาะระหว่างสองภาษาที่ฉันสามารถใช้ประโยชน์จากล่ามในโครงการเพื่อทำความเข้าใจเกี่ยวกับวิธีการทำงานของโปรแกรม

โดยเฉพาะอย่างยิ่ง:

เหตุใดการศึกษาล่ามที่เขียนด้วยภาษาที่ล่ามจึงเน้น - เป็นเพียงการออกกำลังกายทางจิตที่ดีในการรักษาภาษาดั้งเดิมและภาษาที่สร้างขึ้นตรงหรือมีปัญหาเฉพาะที่สามารถหาวิธีแก้ปัญหาในลักษณะของ ภาษาต้นฉบับ?

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

ฉันจะพลาดอะไรถ้าฉันทำแบบฝึกหัดนี้ในภาษาอื่นเช่น C ++ หรือ Java

เป็นสิ่งที่ใช้มากที่สุด Takeaway หรือ "เครื่องมือทางจิต" จากการออกกำลังกายนี้? **

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



4
@gnat ไม่ใช่คำแนะนำด้านอาชีพ แต่มีคำถาม "มีอะไรที่ยอดเยี่ยมมากสำหรับ Lisp"
Robert Harvey

1
@ RobertHarvey ลิงค์นั้นไม่เพียง แต่สำหรับอาชีพ แต่ยังรวมถึงคำแนะนำด้านการศึกษาฉันหมายถึงสิ่งนี้ แต่ก็ดีLisp-is-great-ก็น่าจะเป็นแบบที่ดีเช่นกัน
ริ้น

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

2
ในขณะที่คำถามนี้เกี่ยวข้องกับการศึกษาโดยรวมฉันจะไม่จัดเป็น "คำแนะนำด้านการศึกษา" ในทาง "ฉันควรเรียนภาษาอะไร คือ. นั่นคือมันไม่ได้เฉพาะเจาะจงกับหลักสูตรหรืองานบางประเภท อันที่จริงถ้าคุณตัดคำศัพท์การศึกษาบางส่วนออกไปนี่เป็นคำถามเกี่ยวกับการเขียนโปรแกรมภาษาโดยรวม ไม่เฉพาะเจาะจงกับ Lisp แต่สามารถนำไปใช้กับภาษา homoiconic อื่น ๆ เช่น xslt ดังนั้นฉันจะไม่พูดว่านี่เป็นคำถามที่สมบูรณ์แบบซึ่งไม่ใช่แค่ "คำแนะนำด้านอาชีพ"
TheRubberDuck

คำตอบ:


17

ความเสี่ยงของการให้คำตอบ "ฉันด้วย" ถ้าคุณลองคุณจะเห็น ...

หากคุณศึกษาภาษาคอมพิวเตอร์คุณมีแนวโน้มที่จะได้รับความประทับใจว่าอย่างน้อยครึ่งหนึ่งเกี่ยวกับการแยกวิเคราะห์ หากคุณเรียนรู้ Lisp คุณจะรู้ได้ว่าการแยกวิเคราะห์ไวยากรณ์ของพื้นผิวนั้นไม่มีอะไรมากไปกว่าความสะดวกสบายสำหรับผู้คน

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

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

ใส่เพื่อตอบความคิดเห็น Izkata:

  • โปรแกรมการทำความเข้าใจภาษาธรรมชาติ SHRDLU ทำงานโดยการแปลข้อความหรือคำถามภาษาอังกฤษเป็นโปรแกรมในภาษา Lisp ที่เรียกว่า MICRO-PLANNER และดำเนินการ
  • โปรแกรมที่ใช้งานโปรแกรมตัวอย่างเช่นเพื่อทำให้ง่ายขึ้นหรือพิสูจน์ว่าถูกต้องจะเขียนใน Lisp
  • ฉันใช้การสร้างโปรแกรมในโปรแกรมเพื่อทำความเข้าใจกับฉากที่มองเห็นซึ่งมันต้องจัดการกับความสมมาตรทั้งหมดที่มีความสามารถในวัตถุ 3 มิติโดยไม่ต้องคูณรหัส
  • สิ่งใดที่เกี่ยวข้องกับข้อตกลงเชิงตรรกะและทฤษฎีในการจัดการกับการแสดงออกทางตรรกะซึ่งเป็นรูปแบบของโปรแกรม
  • คณิตศาสตร์เชิงสัญลักษณ์เช่นอินทิกรัลเชิงสัญลักษณ์หรืออนุพันธ์แคลคูลัสเกี่ยวข้องกับการจัดการนิพจน์ทางคณิตศาสตร์ซึ่งคล้ายกับโปรแกรมขนาดเล็ก
  • ปัญหาใด ๆ ที่เกี่ยวข้องกับการสร้างรหัสหรือคำที่สูงกว่า "การประเมินบางส่วน" เป็นเรื่องปกติใน Lisp ฉันทำสิ่งนี้เพื่อโปรแกรมบริดจ์ฐานข้อมูลเมื่อนานมาแล้ว ฉันทำมันใน C ซึ่งไม่ใช่เรื่องง่ายเหมือน Lisp แต่ฉันได้รับแนวคิดจาก Lisp ซึ่งถือเป็นเทคนิคที่แทบจะไม่มีใครสามารถทำได้ในเวลานั้น (โดยเฉพาะหัวโคบอล) บางทีตอนนี้ฉันหวังว่า

... นั่นเป็นเพียงไม่กี่ ...

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

นั่นไม่ได้หมายความว่าภาษาสมัยใหม่จะไม่มีแนวความคิดใหม่ ๆ ที่ดีเช่น OOP เป็นต้น แต่ถ้าคุณเรียนรู้ Lisp มันจะทำให้มุมมองของคุณกว้างขึ้น


You can do it in other languages, but not nearly so easily.- ชอบ? (คำถามสำหรับฉันดูเหมือนจะเป็นเพราะข้อความเช่นนี้มักเกิดขึ้น แต่แทบจะไม่เจาะจงเลย)
Izkata

ฉันแรกคิดว่าโลกถูกปฏิวัติเมื่อฉันตระหนักจาวาสคริปต์สามารถพิมพ์รหัสต้นฉบับของตัวเองและวัตถุสามารถ traversed เพื่อรับตัวอักษรสตริงที่สามารถ evald เป็นวัตถุตัวอักษร จากนั้นฉันก็รู้ว่า Perl มีทั้งหมดนี้พร้อมกับ $ Data :: Dumper :: Deparse แล้วฉันก็รู้ว่า lisp มีสิ่งนี้ตลอดไป การทำความเข้าใจกับนักแปลจะปลดล็อคพลังนี้ที่มีอยู่เสมอเพื่อสร้างโมดูลการใช้ชีวิตและใน Lisp นี่สามารถเข้าถึงได้มากกว่าภาษาอื่น ๆ
Dmitry

สิ่งที่ตลกคือโปรแกรมเมอร์ Lisp ตระหนักถึง Lisps internals สามารถทำให้ส่วนหน้า Lisp ของตัวเองเป็นภาษาแบบไดนามิกใด ๆ จาก javascript ถึง bash หรือ perl หรือ python; เสียงกระเพื่อมอย่างบูตจากสภาพแวดล้อมที่มีอยู่
Dmitry

19

คำตอบง่ายๆกับคำถามของคุณคือการพยายามที่ชัดโดยเฉพาะอย่างยิ่งในการร่วมกับSICP จากนั้นคุณจะรู้แจ้ง

ที่กล่าวว่า ...

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

ส่วนนี้เป็นจริงเนื่องจากไวยากรณ์ของภาษานั้นง่ายมาก มันทำให้สิ่งต่าง ๆ เป็นไปได้ใน Lisp (เช่น metaprogramming) ซึ่งใช้งานไม่ได้ในภาษาอื่นเพราะไวยากรณ์เข้ามาขวางทาง

อ่านเพิ่มเติม
ตีค่าเฉลี่ย


3
ย่อหน้าที่สองไม่สมเหตุสมผล: homoiconicity! = ไวยากรณ์ง่าย; ไวยากรณ์ง่าย ๆทำให้การเขียนตัวแยกเสียงในภาษาใด ๆ (ดูนี้ ) เป็นเรื่องง่าย ย่อหน้าที่ 3 คลุมเครือต้องการตัวอย่าง

@ MattFenwick มันเป็นเรื่องจริงที่ homoiconicity นั้นสามารถทำได้ด้วย syntax ที่ซับซ้อน แต่มันก็ยากมาก มันยุติธรรมที่จะสมมติว่าถ้าคุณกำลังจัดการกับไวยากรณ์ของ homoiconic มันจะง่ายถ้าไม่มีเหตุผลอื่นใดนอกจากความมั่นคงที่ต้องการมันจะทำให้ง่ายต่อการติดตามมากกว่าไวยากรณ์ที่ไม่ใช่ homoiconic แม้ว่าจุดที่สองของคุณเป็นหนึ่งที่ดี LISP เป็นเรื่องง่ายที่จะแยกเพราะมันเป็นไวยากรณ์ที่เรียบง่ายไม่ได้เพราะ homoiconicity (แม้ว่า homoiconicity เป็นสาเหตุสำหรับความเรียบง่ายนั้น)
จิมมี่ฮอฟฟา

1
ไม่ว่าในกรณีใดมีค่าใช้จ่ายเล็กน้อยในการรับค่าข้อมูลและตีความมันเป็นโปรแกรม นี่เป็นสิ่งที่ดี การเขียนโปรแกรมตามการกำหนดค่าเป็นแบบตรงไปตรงมาเมื่อสิ่งที่คุณต้องทำคือการเขียนล่ามสำหรับข้อมูลการกำหนดค่า การเปลี่ยนแปลงทางคณิตศาสตร์ขั้นสูง (ซึ่งยากที่จะนำไปใช้ใน langauges stateful) มักจะ "ลดลง" เป็นเพียงการแปลงทางวากยสัมพันธ์ของชิ้นส่วนบริสุทธิ์ของ Lisp
nomen

1
@ MattFenwick: ฉันได้ลบคำว่า "Homoiconicity" ออกจากคำตอบของฉัน
Robert Harvey

1
ฉันหวังว่าฉันจะให้มากกว่า 1 สำหรับธรรมชาติของเสียงกระเพื่อม; ฉันไม่เคยเห็นคำอธิบายที่ดีเช่นนี้มาก่อน
Doval

9

ทำไมการศึกษาล่ามที่เขียนด้วยภาษาที่ใช้ล่ามจึงเน้น

โดยทั่วไปแล้วการศึกษาล่ามจะช่วยให้คุณเข้าใจภาษาและคุณลักษณะต่างๆ โดยทั่วไปแล้วการเรียนรู้รหัสในภาษาการเขียนโปรแกรมก็เหมือนกับการฝึกภาษาพูดด้วยการฟังและการอ่าน: มันทำให้คุณคุ้นเคยกับสิ่งที่ภาษานั้นสามารถทำได้วิธีการใช้งานและ "สำนวน" ทั่วไป โดยเฉพาะอย่างยิ่งเสียงกระเพื่อมเป็นภาษา homoiconic หมายถึงไวยากรณ์สำหรับการแสดงออกเป็นเช่นเดียวกับไวยากรณ์สำหรับข้อมูล การเขียนโค้ดใน Lisp ดูเหมือนว่าคุณกำลังเขียนรายการและในทางกลับกัน ดังนั้นการตีความรหัสเสียงกระเพื่อมด้วยรหัสเสียงกระเพื่อมเป็นง่ายๆเป็นวิ่งผ่านรายการที่มีและcarcdr

ฉันจะใช้ประโยชน์จากแบบฝึกหัดนี้ให้เกิดประโยชน์สูงสุดจากแนวคิดนี้ได้อย่างไร

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

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

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

ฉันจะพลาดอะไรถ้าฉันทำแบบฝึกหัดนี้ในภาษาอื่นเช่น C ++ หรือ Java

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

Takeaway ที่ใช้มากที่สุดหรือ "เครื่องมือทางจิต" จากการออกกำลังกายนี้คืออะไร?

ฉันไม่แน่ใจว่าฉันมีคำตอบที่ดีสำหรับสิ่งนี้; เพียงเพื่อช่วยให้เห็นว่าล่ามทำงานอย่างไรและที่สำคัญกว่านั้นคือผู้ใช้งานจะเห็นว่าการเปลี่ยนแปลงภาษาสามารถนำไปปฏิบัติได้ง่ายเพียงใด


5

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

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

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


ไม่ใช่ Lisp ที่แยกวิเคราะห์ได้ง่าย S-Expressions แยกวิเคราะห์ได้ง่าย นอกเหนือจากนั้นคุณต้องแยก Lisp
Rainer Joswig

@Rainer: นั่นไม่ใช่แค่ nitpicking? ในโลกของฉันการแยกวิเคราะห์หมายถึงการเปลี่ยนจากข้อความไปเป็น AST ซึ่งไม่ได้พูดถึงการตีความคำสั่ง
Alexander Torstling

ใน C ++ โปรแกรมวิเคราะห์คำจะตรวจพบการประกาศฟังก์ชันผิดไวยากรณ์ ในเสียงกระเพื่อมไม่ได้ ผู้อ่านไม่รู้อะไรเกี่ยวกับภาษาการเขียนโปรแกรม Lisp ตัวแยกวิเคราะห์ C ++ รู้ไวยากรณ์ C ++ ทั้งหมด ผู้อ่านเสียงกระเพื่อมเท่านั้นที่รู้ว่าการแสดงออก
Rainer Joswig

อ่าฉันเข้าใจสิ่งที่คุณหมายถึง จริงแม้ว่าฉันยังคิดว่าตัวประเมินเสียงกระเพื่อมอย่างง่ายจะสร้างได้ง่ายกว่า c ++ ตัวเดียว นั่นคือสิ่งที่พวกเขาทำใน SICP ใช่มั้ย (อ่านมานานแล้ว)?
Alexander Torstling

ภาษาที่ใช้ใน SICP นั้นง่ายมากไม่ได้เป็นแบบแผนเต็มรูปแบบ ล่ามสำหรับภาษาซีเล็ก ๆ เช่นภาษาควรเรียบง่ายเช่นกัน C ++ มีขนาดใหญ่ ปัญหาบางอย่างมาจากไวยากรณ์ในตัวที่ค่อนข้างสูง ในระบบเสียงกระเพื่อมทั่วไปของไวยากรณ์ส่วนใหญ่ถูกสร้างขึ้นด้วยมาโคร - ด้านนอกของล่าม แมโครใช้ไวยากรณ์และกลไกส่วนขยายสำหรับการแปลงแหล่งที่มา สิ่งนี้ทำให้แกนกลางเล็กลง แต่มาโครนั้นมีขนาดใหญ่มาก ตัวอย่างเช่นการใช้งานสำหรับการสร้าง LOOP มีมากกว่า 2,000 บรรทัดของรหัสแมโครที่ซับซ้อน
Rainer Joswig

4

ฉันไม่แน่ใจว่ามันเป็นสิ่งสำคัญสำหรับทุกคน คุณสามารถเป็นนักพัฒนาที่ประสบความสำเร็จได้โดยไม่ต้องรู้ว่า Lisp interpreter ทำงานอย่างไร เมื่อเรียนวิทยาศาสตร์คอมพิวเตอร์แนวคิดพื้นฐานของเสียงกระเพื่อมควรได้รับการเรียนรู้ว่า

Lisp interpreters มีความสำคัญสำหรับ Lisp โปรแกรมเมอร์ พวกเขาจำเป็นต้องเข้าใจวิธีการทำงานของล่าม ([และคอมไพเลอร์] 1 ) เพื่อเข้าใจวิธีการใช้ภาษาอย่างเต็มที่

Lisp interpreter มักใช้เป็นเครื่องมือในวิทยาการคอมพิวเตอร์เพื่อสอนนักเรียนสองสามสิ่ง:

  • การทำความเข้าใจความหมายที่ภาษาที่กะทัดรัดและน้อยที่สุดผ่านการดำเนินงาน: อลันเคย์เรียกว่าแมกซ์เวลสมการของซอฟแวร์

  • การทำความเข้าใจการเขียนโปรแกรมระดับภาษาโดยการเปลี่ยนและขยายล่าม

  • ทำความเข้าใจเกี่ยวกับการเขียนโปรแกรมระดับเมตาและผลกระทบที่มีต่อการออกแบบและการใช้ภาษาโปรแกรม ตัวอย่างเช่นการทำความเข้าใจความหมายของ 'การอ้างอิง' และทำไมจึงจำเป็น

  • เข้าใจการตีความภาษา LISP และการเชื่อมต่อกับแลมบ์ดาแคลคูลัส

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

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