เหตุใดภาษาการเขียนโปรแกรมส่วนใหญ่จึงไม่ซ้อนบล็อกความคิดเห็น


18

ไม่กี่คนที่ทำ แต่ไม่ได้รับความนิยมเท่าที่ฉันรู้ มีบางอย่างที่ไม่ดีเกี่ยวกับความคิดเห็นในการซ้อนหรือไม่

ฉันวางแผนที่จะบล็อกความคิดเห็นซ้อนในภาษา (เล็ก) ที่ฉันกำลังทำงานอยู่ แต่ฉันอยากจะรู้ว่านี่เป็นความคิดที่ไม่ดีหรือไม่


ตอบคำถามอีกสองสามข้อ: โอ้ว, นั่นสมเหตุสมผลแล้ว =) ฉันแสดงความคิดเห็นบล็อกซ้อนกันโดยสิ้นเชิงแล้ว; แม้ว่าฉันจะมีขั้นตอนการแยกที่แยกกัน แต่ก็ไม่ได้อธิบายถึงการเรียงลำดับ SK-logic ที่ จำกัด

@Vuntic: หากคุณมีขั้นตอนการแยกที่ใช้สิ่งที่ซับซ้อนกว่านิพจน์ทั่วไปคุณอาจมีปัญหาด้านประสิทธิภาพ REs นั้นใช้งานง่ายและรวดเร็วโดยการใช้ DFA
David Thornley

มันจับข้อผิดพลาดเพิ่มเติมก่อนหน้านี้เพื่อไม่ให้มีการซ้อน

4
@ David: ... ไม่เลย มันเร็วจริง ๆ
amara

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

คำตอบ:


6

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

ก่อนอื่นให้ยอมรับว่ามีเพียง "ซ้อน" หรือ "ไม่ซ้อน" เท่านั้นที่โปรแกรมเมอร์จะเห็นได้คือเมื่อโปรแกรมเมอร์เขียนสิ่งที่มีโครงสร้างเช่นนี้:

do_something();
/* comment /* nested comment */ more comment */
do_something_else();

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

do_something();  /* do a thing */
/* [ajo] 2017-12-03 this turned out to be unnecessary
do_something_else(); /* do another thing */
*/

และนี่คือBAD นี่ไม่ใช่รูปแบบที่เรา (ในฐานะนักออกแบบภาษา) ต้องการให้กำลังใจ! ที่ถูกต้องวิธีการเขียนข้อมูลข้างต้นเป็น:

do_something();  /* do a thing */

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

สิ่งนี้ทำให้คุณเข้าใจกฎง่ายๆที่คุณอาจเคยได้ยินมาก่อน: อย่าใส่รหัส (กำลังหาวลีนี้จะเปิดขึ้นมาก ของ ความคิดเห็น ใน ข้อตกลง .)

ก่อนที่คุณจะถามใช่ภาษาเช่น C, C # และ C ++ แล้วให้โปรแกรมเมอร์อีกเครื่องมือในการ "ความคิดเห็นออก" #if 0บล็อกขนาดใหญ่ของรหัส: แต่นี่เป็นเพียงแอปพลิเคชันเฉพาะของตัวประมวลผลล่วงหน้า C ซึ่งเป็นเครื่องมือขนาดใหญ่และมีประโยชน์ในตัวของมันเอง มันจริงจะเป็นเรื่องยากมากและพิเศษ casey สำหรับภาษาที่จะสนับสนุนการรวบรวมเงื่อนไขด้วย#ifและยังไม่#if 0สนับสนุน


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

เพื่อให้การอ้างเหตุผลสมบูรณ์เราต้องยอมรับว่านักออกแบบภาษามีความสนใจในการส่งเสริมสิ่งที่ดีและท้อแท้สิ่งเลวร้าย (สมมติว่าทุกอย่างเท่าเทียมกัน)

ในกรณีที่มีความคิดเห็นซ้อนกันสิ่งอื่น ๆมีค่าเท่ากันคุณสามารถเพิกเฉยต่อคำตอบที่ได้รับการโหวตต่ำซึ่งอ้างว่าการแยกวิเคราะห์ซ้อนกัน/*จะเป็น "ยาก" สำหรับตัวแยกวิเคราะห์ (ซ้อนกัน/*ไม่ยากกว่าซ้อนกัน(ซึ่งเกือบทุก parser ในโลกจำเป็นต้องจัดการแล้ว)

ดังนั้นสิ่งอื่น ๆ ที่เท่าเทียมกันนักออกแบบภาษาควรทำให้ง่ายต่อการซ้อนความคิดเห็น (เช่นเพื่อใส่รหัส) หรือยาก? จำได้ว่ารหัสความคิดเห็นเป็นสิ่งที่ไม่ดี

QED


เชิงอรรถ. โปรดสังเกตว่าหากคุณไม่อนุญาตให้แสดงความคิดเห็นซ้อนกัน

hello /* foo*/bar.txt */ world

เป็น "ความคิดเห็น" ที่ทำให้เข้าใจผิด - มันเทียบเท่ากับ

hello bar.txt */ world

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

hello /* foo/*.txt */ world

เป็น "ความคิดเห็น" ที่ทำให้เข้าใจผิด - มันเทียบเท่ากับ

hello

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


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

@greenoldman: ภาษาส่วนใหญ่ไม่มีความเห็นแบบซ้อนได้ แต่พวกเขาจะมีคุณสมบัติที่แท้จริงสำหรับ "ลบบล็อกของโค้ด" ซึ่งใช้น้อยกว่าฟีเจอร์ "ฝากความคิดเห็น" C's #if DEADเป็นตัวอย่างที่ได้รับการยอมรับและดีที่สุด if (DEAD)ในหลายภาษาคุณก็สามารถตัดรหัสตายในเทียบเท่า และในหลาย ๆ IDEs คุณสามารถลบรหัสที่ตายแล้วและใช้การควบคุม Ctrl + Z และ / หรือการควบคุมเวอร์ชันเพื่อให้ได้รับคืนหากคุณต้องการ การออกความคิดเห็น docstring อะไรก็ตามที่มีข้อความเป็นรหัสตายรหัสยังคงเป็นตัวเลือกที่แย่ที่สุดสำหรับการอ่าน
Quuxplusone

11

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


3
ฉันจะไม่เห็นด้วยกับ 'มากที่สุด' ในปัจจุบัน แน่นอนว่าเป็นวิธีการดั้งเดิม แต่ฉันรู้ว่าสำหรับ C, EDG รวมตัวประมวลผลก่อนการ lexing และการแยกวิเคราะห์และฉันสงสัยว่าทั้ง GCC และ Microsoft ทำเช่นกัน ประโยชน์คือช่วยให้คุณสามารถนำไปใช้แยกต่างหากหากคุณต้องการ
Andrew Aylett

เสียงดังกราวก็ทำเช่นเดียวกัน แต่นั่นก็เป็นเพียงส่วนเล็ก ๆ ของคอมไพเลอร์ภาษายอดนิยมที่มีอยู่ในปัจจุบัน
SK-logic

@ Neil Butterworth ลองดูที่ mcs, javac, gcc (ใช่มันจะแปะไว้ที่ lexer แต่ก็ยังเป็น lexing pass โดยเฉพาะ), clang (เหมือนกับ gcc), dmd, fpc และอื่น ๆ อีกมากมาย
SK-logic

ไม่มีใครใช้การแสดงออกปกติใน lexing ของพวกเขาสำหรับคอมไพเลอร์ที่ไม่สำคัญ
Nuoji

@Nuoji - สำหรับคนที่ไม่สำคัญ - แน่นอน แต่คนที่ต้องพึ่งพาเฟล็กซ์และเครื่องมือที่คล้ายกัน
SK-logic

7

เป็นไปได้อย่างสมบูรณ์ที่จะสร้าง lexer ที่สามารถจัดการกับความคิดเห็นที่ซ้อนกัน เมื่อมันกินช่องว่างเมื่อมันเห็น/*มันสามารถเพิ่มตัวนับความลึกและลดลงเมื่อมันเห็น*/และหยุดเมื่อความลึกเป็นศูนย์ ที่กล่าวว่าฉันได้ทำ parsers จำนวนมากและไม่เคยพบเหตุผลที่ดีสำหรับความคิดเห็นที่จะทำรัง

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

ความคิดเห็นที่ไม่ซ้อนกันคืออะไรเช่นนี้

/*
some code
more code
blah blah blah
/**/

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


1
//ความคิดเห็นยังเป็นสไตล์ C99
JAB

อีกทางเลือกหนึ่งภาษาที่สามารถระบุเป็นจุดเริ่มต้นของการแสดงความคิดเห็นเป็น/*$tokenที่identifierเป็นเครื่องหมายและตัวเลขใด ๆ token$*/และการสิ้นสุดของความคิดเห็นเป็น มันจะค่อนข้างง่ายสำหรับ tokenizer ที่จะรวมรหัสเพื่อตรวจสอบว่าเครื่องหมายความคิดเห็นปลายทางทุกอันมีโทเค็นที่เหมาะสมสำหรับบล็อกความคิดเห็นเริ่มต้นที่ตรงกัน
supercat

5

เนื่องจากไม่มีใครพูดถึงมันฉันจะเขียนรายการภาษาที่รองรับความคิดเห็นซ้อน: Rexx, Modula-2, Modula-3, Oberon แม้จะมีข้อร้องเรียนทั้งหมดที่นี่เกี่ยวกับปัญหาความยากและความเร็ว แต่ก็ไม่มีใครที่มีปัญหาใหญ่


4
ซึ่งฉันเพิ่ม: Haskell, Frege
Ingo

สนับสนุนโดย Scala ด้วย
Matt R

4

จุดที่ดีในการคอมเม้นท์บล็อกซ้อนคือคุณสามารถคอมเม้นต์โค้ดขนาดใหญ่ได้ง่าย (ดีเกือบยกเว้นคุณมีลำดับความคิดเห็นบล็อกบล็อกในค่าคงที่สตริง)

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

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


3

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

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


1
+1 สำหรับ "ง่ายต่อการเพิ่มคุณสมบัติมากกว่าที่จะลบ"
. ..

3
เมื่อคุณไม่อนุญาตให้แสดงความคิดเห็นที่ซ้อนกันคุณจะไม่สามารถช่วยให้พวกเขาเช่นกันเพราะมันจะทำลายความคิดเห็นเช่น:/*/**/
Riad

2

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


3
มันไม่ใช่ "รสชาติ" คำว่า "ปกติ" ในการแสดงออกปกติยกเว้นการเรียกซ้ำ
. ..

3
@R: ในวิชาคณิตศาสตร์แน่นอน แต่ในการเขียนโปรแกรมเรามีสิ่งที่เราเรียกว่า regexes ที่รองรับการเรียกซ้ำ
amara

คำถามคือ: นี่คือปัญหาหรือไม่ ภาษาส่วนใหญ่มีการจัดการกับวงเล็บที่ซ้อนอยู่แล้ว ในการตั้งชื่อบางอย่าง: Lisp, C, Java, Python, Ruby, Perl
Thomas Eding

วงเล็บที่ซ้อนกันนั้นใช้ได้เพราะทุกอย่างในวงเล็บนั้นเหมือนกับสิ่งที่อยู่ข้างนอก: โทเค็นปกติ ในความคิดเห็นคุณไม่มีโทเค็นคุณแค่มีข้อความ คุณต้องสามารถจับคู่โทเค็นความคิดเห็นเริ่มต้นและสิ้นสุดเพื่อให้คุณทราบว่า 'int' เป็นประเภทหรือเพียงแค่คำในความคิดเห็น (โดยเฉพาะถ้าคุณกำจัดความคิดเห็นใน lexer.)
Alan Shutko

2
@ThePopMachine: ฉันแน่ใจในสิ่งที่ฉันกล่าวว่าประจำมีความหมายอย่างเป็นทางการที่กำหนดไว้ไม่ใช่ความหมายที่คุณใช้และว่า "ปกติ" ใน "การแสดงออกปกติ" ถูกเลือกสำหรับความหมายนี้ การไม่เรียกซ้ำเป็นผลมาจากคำจำกัดความ
ร ..

-1

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


-1

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


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