เครื่องหมายโคลอนในบล็อกหลามเป็นสิ่งจำเป็นทางเทคนิคหรือไม่


19

นี่เป็นเพียงคำถามเชิงทฤษฎีของ newbie ใหญ่ที่ต้องการเข้าใจมากขึ้น

ฉันลืมโคลอนไปเรื่อย ๆ หลังจากบล็อกข้อความเริ่มต้นในไพ ธ อน นี่คือสิ่งที่ฉันหมายถึง:

  • for <variable> in <sequence>:
  • if <blah blah>:

ความคิดของฉันคือเหตุผลหนึ่งที่ฉันลืมอยู่เสมอว่ามันเป็นความจริงโดยนัย: โคลอนหรือไม่คำแถลงลงท้ายด้วยบรรทัดนั้น

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


4
ฉันคิดว่าคุณไม่เข้าใจคำถามซึ่งเป็นสิ่งที่โคลอนจำเป็นสำหรับการทำงานของไวยากรณ์หรือไม่ นอกจากนี้ไม่ว่าคำตอบของคุณคืออะไรควรมีคำอธิบายด้วย
Tomáš Zato - Reinstate Monica

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

ฉันไม่รู้ว่าจะพูดยังไงดีกว่านี้ คำถามของฉันโดยทั่วไปคือถ้าคุณสามารถเปลี่ยนไวยากรณ์หลามทั้งหมดเพื่อให้มันไม่จำเป็นต้องลำไส้ใหญ่หลังจากif, else, whileและอื่น ๆ ถ้าคุณทำอย่างนั้นงูหลามจะยังคงเป็นภาษาที่สามารถใช้งานได้โดยไม่คลุมเครือ
Tomáš Zato - Reinstate Monica

เข้าใจแล้ว! มันเป็นคำถามเกี่ยวกับการตัดสินใจออกแบบไวยากรณ์ของงูใหญ่ ขออภัยเข้าใจผิด ขอบคุณสำหรับการอธิบาย
bhan sur

เก็งกำไร ราวกับว่าการขึ้นบรรทัดใหม่นั้นยากต่อการตรวจสอบโดยล่าม / ตัวแยกวิเคราะห์ในทางปฏิบัติหรือมีความสามารถในการอ่าน ใน LUA คุณสามารถเขียนif .. then .. endในบรรทัดเดียว ดังนั้นใน python thenจะถูกแทนที่ด้วยสองสิ่ง:และขึ้นบรรทัดใหม่ที่ต้องการ หนึ่งในนั้นดูเหมือนจะซ้ำซ้อน
bhan sur

คำตอบ:


9

ใช่ลำไส้ใหญ่จำเป็นต้องสร้างความสับสนให้กับโครงสร้างบางอย่าง if x - y < z: passพิจารณาตัวอย่างเช่น หากไม่มีเครื่องหมายโคลอนเราจะไม่สามารถตัดสินใจได้ว่าจะวิเคราะห์คำนี้อย่างไรโดยไม่ทราบบริบทของ x, y และ z if x: -y < z...ถูกต้องถ้า x เป็นบูลีนif x - y < z:เป็นอย่างอื่นถูกต้อง

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


1
รอคุณสามารถมีคำสั่งหลังเครื่องหมายจุดคู่ในบรรทัดเดียวกันได้หรือไม่ ฉันค่อนข้างมั่นใจว่ามันไม่ได้รับอนุญาต
Tomáš Zato - Reinstate Monica

1
มันได้รับอนุญาต แต่เฉพาะกับการหยุดสายหลังจากนั้น
Phoshi

ยังคงสับสนเล็กน้อย if condition: print("Condition passed")\nอนุญาตหรือไม่: อนุญาต \nสัญลักษณ์บรรทัดใหม่หลังจากคำสั่งพิมพ์
Tomáš Zato - Reinstate Monica

แน่นอนว่าลองดู
RemcoGerlich

1
@TomasZato: ใช่คุณสามารถมีงบใด ๆ หลังลำไส้ใหญ่ มันยุติบล็อกทันทีดังนั้นมันจึงมีประโยชน์ส่วนใหญ่เมื่อบล็อกนั้นเป็นซับเล็ก ๆ
Lie Ryan

14

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

สาเหตุหลักที่ทำให้ต้องใช้โคลอนในงูหลามคือความสามารถในการอ่านของมนุษย์ อ้างจากPython คำถามที่พบบ่อย :

ทำไมโคลอนจำเป็นสำหรับคำสั่ง if / while / def / class?

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

if a == b
    print(a)

กับ

if a == b:
    print(a)

สังเกตว่าคนที่สองอ่านได้ง่ายขึ้นเพียงเล็กน้อย แจ้งให้ทราบเพิ่มเติมว่าลำไส้ใหญ่ออกตัวอย่างในคำตอบที่พบบ่อยนี้; มันเป็นมาตรฐานการใช้ภาษาอังกฤษ

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

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


3
“ สังเกตว่าคนที่สองอ่านได้ง่ายขึ้นเพียงเล็กน้อย” ฉันพบว่าคนแรกอ่านง่ายกว่า เสียงรบกวนน้อยลง
user76284

10

มันไม่จำเป็นสำหรับคอมพิวเตอร์ แต่สำหรับมนุษย์

Guido van Rossum (ผู้สร้าง Python) มีบล็อกประวัติ Python อยู่พักหนึ่ง เครื่องหมายทวิภาคได้รับการแนะนำในABCซึ่งเป็นที่มาของคุณลักษณะของ Python หลายประการ

ในบล็อกนี้โพสต์ใน "Karin Dewar, เยื้องและลำไส้ใหญ่" , Guido เขียน:

และที่นี่ฉันจะถอดความตามคำขอของ Lambert

ในปี 1978 ในการออกแบบในคฤหาสน์ในJabłonna (โปแลนด์), Robert Dewar, Peter King, Jack Schwartz และ Lambert ได้เปรียบเทียบรูปแบบทางเลือกที่นำเสนอสำหรับ B โดยเปรียบเทียบ (buggy) การเรียงลำดับฟองที่เขียนลงในแต่ละทางเลือก เนื่องจากพวกเขาไม่สามารถตกลงกันได้ภรรยาของ Robert Dewar ถูกเรียกตัวจากห้องของเธอและถามความเห็นของเธอเหมือนปารีสในปัจจุบันขอให้เปรียบเทียบความงามของ Hera, Athena และ Aphrodite แต่หลังจากเวอร์ชั่นแรกได้อธิบายให้เธอฟังเธอกล่าวว่า: "คุณหมายถึงในบรรทัดที่มันบอกว่า: 'สำหรับฉัน ... ' ต้องทำสำหรับบรรทัดที่ตามมาไม่ใช่แค่สำหรับบรรทัดนั้นเท่านั้น? !" และที่นี่นักวิทยาศาสตร์ตระหนักว่าการหลีกเลี่ยงความเข้าใจผิดจะเกิดขึ้นหากมีลำไส้ใหญ่ตอนท้ายของบรรทัดนั้น

( Bนี่คือชุดของภาษาต้นแบบ B0, B1, ... ที่นำไปสู่ ​​ABC ไม่ใช่ภาษา B ที่เป็นบรรพบุรุษของ C)

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


4

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

kons  = lambda hd, tl: lambda x: hd if x else tl
virst = lambda l: l(True )
rrest = lambda l: l(False)

หากไม่มีเครื่องหมายโคลอนเพื่อแยกเนื้อหาออกจากรายการพารามิเตอร์ฉันจะต้องใช้การเยื้อง:

kons  = lambda hd, tl
    lambda x
        hd if x else tl

virst = lambda l
    l(True )

rrest = lambda l
    l(False)

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

# idiomatic
while true do puts "I am awesome" end
#          ↑↑

# non-idiomatic, but legal
while true; puts "I am awesome" end
#         ↑

# non-idiomatic, but legal
while true
puts "I am awesome" end

# idiomatic
while true
  puts "I am awesome"
end

ใน Cobra เวอร์ชั่นปัจจุบันคุณสามารถใช้เครื่องหมายจุลภาค:

if x
    y

สามารถเขียนเป็น

if x, y

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

วิธีเดียวที่จะแน่ใจได้อย่างแน่นอนคือการทำให้ไวยากรณ์เป็นระเบียบโดยมีและไม่มีเครื่องหมายโคลอนและพิสูจน์ว่าไม่ใช่ความกำกวม

อย่างไรก็ตามโปรดสังเกตว่าหนึ่งในคำพังเพยของZen of Pythonคือ "Explicit is better กว่า Implicit" ดังนั้นการอธิบายความชัดเจนของบล็อกด้วยโคลอนดูเหมือนจะสอดคล้องกับปรัชญาทั่วไปของ Python ออกแบบและประวัติศาสตร์คำถามที่พบบ่อยยังกล่าวว่าการตัดสินใจครั้งนี้จะขึ้นอยู่กับหลักฐานเชิงประจักษ์จากบรรพบุรุษ ธ เอบีซี


3
ด้วยปรัชญาที่อธิบายไว้ในย่อหน้าสุดท้ายคุณอาจต้องการโคลอนในตอนท้ายของทุกบรรทัด Explicit vs implicit ทำให้เหมาะสมถ้าชัดเจนเพิ่มข้อมูล (เช่น. ตัวแปรที่ไม่ชัดเจนนั้นไม่ชัดเจน) ซึ่งเป็นคำถามของฉัน
Tomáš Zato - Reinstate Monica
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.