อัฒภาคที่เป็นตัวเลือก


10

ส่วนใหญ่มักจะใช้ภาษาที่มีจุดประสงค์ทั่วไป - อัฒภาคเมื่อต้องมีตัวคั่นคำสั่งหรือไม่ได้รับอนุญาตอย่างสมบูรณ์ (เช่น C และ Python)

อย่างไรก็ตามบางภาษาเช่น JavaScript อนุญาตให้คุณเลือกที่จะไม่ลบงบของคุณด้วยเครื่องหมายอัฒภาคเพื่อสนับสนุนตัวคั่นอื่น ๆ (เช่นขึ้นบรรทัดใหม่)

การตัดสินใจด้านการออกแบบคืออะไร ฉันเข้าใจว่าเครื่องหมายอัฒภาคมีความสำคัญเมื่อเขียนหลาย ๆ ข้อความในบรรทัดเดียวกัน แต่มีเหตุผลอื่นที่ทำให้จำเป็น (ยกเว้นตาม C) หรือไม่


1
คุณต้องคิดถึงคำสั่ง terminator (perl, c) และตัวคั่นคำสั่ง (javascript, pascal)

5
ใน Python สามารถใช้เครื่องหมายอัฒภาคเพื่อคั่นหลาย ๆ ข้อความในบรรทัดเดียวกัน และเนื่องจากคำสั่ง "ว่าง" ได้รับอนุญาตอัฒภาคสามารถใช้ในตอนท้ายของงบส่วนใหญ่
Greg Hewgill

1
I understand that semicolons are essential when writing multiple statements on the same line- ขึ้นอยู่กับภาษา อันที่ฉันโปรดปรานไม่มีตัวคั่นดังกล่าวเลยข้อความต่อไปเริ่มต้นเมื่ออาร์กิวเมนต์ของฟังก์ชันทั้งหมดถูกใช้หมด
Izkata

1
@MichaelT: ฉันไม่คิดว่าการแบ่งประเภทของคุณถูกต้อง: Perl เนื้อหาเป็นของทั้งสองกลุ่มและ JavaScript เป็นจริงในค่าย "statement terminators" (เนื่องจากการใช้งานจำเป็นต้องใช้เซมิโคลอนก่อน}หรือท้ายไฟล์)
ruakh

ใช่ขึ้นอยู่กับภาษาอย่างแน่นอน การเดาส่วนตัวของฉันน่าจะเป็นว่าเครื่องหมายอัฒภาคเป็นเพียงรูปแบบของการประชุมที่ตกลงกันโดยทั่วไปซึ่งนักออกแบบภาษาส่วนใหญ่ติดตาม อย่างน้อยก็ทำให้รู้สึกบางอย่างจากมุมมองภาษาที่เป็นธรรมชาติมากขึ้น เช่นเดียวกับ {และ} สำหรับบล็อกโดยวิธีการ: พวกเขาจะใช้หลายภาษา แต่ไม่ทั้งหมดและคุณไม่จำเป็นต้องทำเช่นนี้ ไม่มีเหตุผลสากลที่อยู่เบื้องหลังสิ่งนี้
JensG

คำตอบ:


24

ทำให้เป็นข้อบังคับ (หรือไม่อนุญาตให้สมบูรณ์) ลดจำนวนกรณีมุมลดแหล่งที่มาของข้อบกพร่องที่คลุมเครือและลดความซับซ้อนของการออกแบบคอมไพเลอร์ / ล่าม

นักออกแบบภาษาที่เลือกที่จะทำให้พวกเขาเลือกที่จะเลือกที่จะอยู่กับความกำกวมในทางกลับกันเพื่อความยืดหยุ่นทางไวยากรณ์ที่มากขึ้น


7
@ RobertHarvey นอกรีต! ควรมีหนึ่งวิธีที่ชัดเจนในการทำและมีเพียงหนึ่งเดียว บังเอิญมีวิธีเดียวที่จะทำได้ใน Perl

1
BTW - ภาษาบางภาษามีความซ้ำซ้อนในไวยากรณ์โดยทั่วไปดังนั้นการเลือกเซมิโคลอนจึงไม่ชัดเจนในบางครั้งในทางปฏิบัติ ที่กล่าวว่าฉันคิดว่าเครื่องหมายอัฒภาคเป็นบิตผิดพลาดของการลดลง - ฉันค่อนข้างชอบ Haskell ที่คุณวาง parens และเครื่องหมายจุลภาคสำหรับข้อโต้แย้งแทน ตกลงคุณสามารถวางเครื่องหมายอัฒภาคใน Haskell ได้ด้วย แต่ก็ไม่เหมือนกับ Javascript
Steve314

2
IIRC ปัญหาคือพวกเขาไม่พอดีกับแบบจำลองอย่างเป็นทางการ แต่ตัวแยกวิเคราะห์ไม่ได้สร้างข้อความแสดงข้อผิดพลาดที่ดี นั่นคือพวกเขามีความรู้ จำกัด เกี่ยวกับข้อผิดพลาดทั่วไปในขณะที่ parser ที่เขียนด้วยมือสามารถได้รับข้อความแสดงข้อผิดพลาดที่เป็นประโยชน์มากขึ้น Gcc ตัวอย่างเช่นใช้ในการใช้วัวกระทิงสำหรับไวยากรณ์ C ในทำนองเดียวกันปัญหาก็คือ 'edge case' ไม่ใช่คดีขอบอย่างเป็นทางการ แต่ soft case - เช่นสำหรับ parser AST นั้นชัดเจนและสำหรับมนุษย์ AST 'ชัดเจน' แต่พวกเขาไม่เห็นด้วยกับ AST
Maciej Piechotka

2
@Maciej Piechotka - ฉันไม่ได้ตั้งใจจะบอกว่า parens เป็นตัวเลือกใน Haskell ฉันกำลังพูดถึงการทิ้งสิ่งที่ซ้ำซ้อนไว้เป็นการตัดสินใจออกแบบภาษา ประเด็นคือคุณไม่ได้ใช้ parens หรือเครื่องหมายจุลภาคสำหรับการเรียกใช้ฟังก์ชันใน Haskell คุณสามารถส่งผ่าน tuple เป็นอาร์กิวเมนต์ แต่ยังคงเป็นไวยากรณ์สำหรับ tuple ไม่ใช่ผ่านการขัดแย้ง Haskell (และ ML และอื่น ๆ ) "ดร็อป" parens และเครื่องหมายจุลภาคสำหรับอาร์กิวเมนต์ของฟังก์ชันในแง่ที่ว่ามีการประชุมทั่วไปในภาษาอื่น (ตั้งแต่ Algol?) แต่ Haskell ไม่ทำเช่นนั้น
Steve314

1
@Maciej Piechotka - แน่นอนว่ามันไม่เคยเป็นอนุสัญญาสากลเลย - เพราะภาษาตระกูลอัลกอลไม่ได้หมายความว่าภาษาอื่นจะนิยามตัวเองเมื่อเทียบกับสิ่งนั้นดังนั้นการอ้างสิทธิ์ "หลุด" ของฉันจึงผิด ภาษา C-family ทุกวันนี้มันรู้สึกแบบนั้น
Steve314

15

JavaScript แสดงให้เราเห็นว่านี่เป็นความคิดที่แย่มาก ตัวอย่างเช่น:

return
0;

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


1
@delnan: Python ไม่ได้ถูกออกแบบมาให้มีลักษณะเหมือน C. เป็นที่รู้จักกันดีว่าอิงตามการเยื้องและเน้นบรรทัดมากและไม่ต้องใช้เครื่องหมายอัฒภาค JavaScript ในทางเทคนิคไม่ต้องการให้พวกเขา; มันแทรกหนึ่งเมื่อพบว่ามีสิ่งที่ขาดหายไปซึ่งจะแปลงสิ่งที่ดูเหมือนว่าคำสั่งที่ถูกต้องหนึ่งประโยคเป็นสองประโยคที่มีความหมายแตกต่างกันโดยสิ้นเชิง
Mason Wheeler

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

4
@delnan: สาเหตุที่น่าแปลกใจคือ JavaScript มักจะไม่ใส่เครื่องหมายอัฒภาคที่ท้ายบรรทัดยกเว้นการแก้ไขโปรแกรมที่ไม่ถูกต้อง หลังจากนั้นreturnเป็นหนึ่งในไม่กี่กรณีที่ JavaScript จะแทรกเครื่องหมายอัฒภาคแม้ว่าโปรแกรมจะถูกต้องหากไม่มี ( แต่แน่นอนนี้ทำลายจุด Mason ล้อปัญหาไม่ได้อยู่ที่อัฒภาคเป็นตัวเลือกก็ว่ากฎจะไม่สอดคล้องกัน..)
ruakh

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

1
javascript ได้แสดงให้เห็นว่าการใช้เซมิโคลอนเสริมนั้นไม่สมบูรณ์ มันไม่ได้แสดงว่าอัฒภาคที่ไม่จำเป็นนั้นไม่ดีต่อเซ
CodesInChaos

4

ช่วยให้ไวยากรณ์และตัวแยกวิเคราะห์ของคุณง่ายขึ้นเพื่อให้ใช้เครื่องหมายอัฒภาค โดยพื้นฐานแล้วจะช่วยให้ lexer ถ่ายโอนพื้นที่ว่างทั้งหมดรวมถึงการขึ้นบรรทัดใหม่และ parser ไม่ต้องกังวลกับมันเลย

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

ตัวอย่างเช่นลองแทรกเครื่องหมายอัฒภาคลงในชุดคำสั่ง C ต่อไปนี้

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

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


เมื่อ C ได้รับการพัฒนาในช่วงต้นทศวรรษ 1970 จำเป็นต้องมี terminators ของคำสั่งเพื่อทำให้คอมไพเลอร์ง่ายขึ้น ในช่วงกลางยุค 90 เมื่อ Javascript ได้รับการพัฒนามันเป็นเรื่องที่น่าเป็นห่วงน้อย
Sean McSomething

3

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

functionCall(3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

ลองนึกภาพคุณพิมพ์หนึ่ง paren เปิดพิเศษ:

functionCall((3, 4) 9 + (3 / 8) variable++ while(1) { printf("Hello, world\n") }

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

functionCall((3, 4);  <- something is wrong here. emit error and keep going.
                      9 + (3 / 8); variable++; while(1) { printf("Hello, world\n"); }

ตอนนี้การแยกวิเคราะห์ง่ายขึ้นเพื่อรายงานข้อผิดพลาดและง่ายต่อการค้นหาบรรทัด / คอลัมน์ที่เกิดขึ้น


1
Fortran และ Basic อย่างน้อยเลือกเครื่องหมายต่อเนื่องของบรรทัด (& และ _, ตามลำดับ) อย่างเหมาะสม สำหรับเลี่ยง "" OMG สิ่งที่พวกเขาคิด "ไม่มีอะไรเต้น FoxPro เพื่อดำเนินการต่อบรรทัดคุณใช้เครื่องหมายอัฒภาค
DougM

2

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

--One statement per line
x = 1
y = 2

--Multiple statements per line
x = 1 y = 2

--You can add semicolons if you want but its just for clarity:
x = 1; y = 2

0

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

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