คำถามติดแท็ก language-design

คำถามที่เกี่ยวข้องกับการออกแบบและโครงสร้างของภาษาโปรแกรม

2
ทำไมผู้ประกอบการระดับบิตมีลำดับความสำคัญต่ำกว่าการเปรียบเทียบ?
ใครบางคนสามารถอธิบายเหตุผลได้ทำไมในภาษายอดนิยม (ดูหมายเหตุด้านล่าง) ตัวดำเนินการเปรียบเทียบ (==,! =, <,>, <=,> =) มีลำดับความสำคัญสูงกว่าตัวดำเนินการระดับบิต (&, |, ^ , ~)? ฉันไม่คิดว่าฉันเคยเจอการใช้งานที่สำคัญกว่านี้จะเป็นธรรมชาติ มันเป็นสิ่งที่ชอบเสมอ: if( (x & MASK) == CORRECT ) ... // Chosen bits are in correct setting, rest unimportant if( (x ^ x_prev) == SET ) // only, and exactly SET bit changed if( (x & …

6
เหตุใด C # จึงสร้างด้วยคำหลัก“ ใหม่” และ“ เสมือน + แทนที่” ซึ่งไม่เหมือนกับ Java
ใน Java ไม่มีvirtual, new, overrideคำหลักสำหรับความหมายวิธีการ ดังนั้นการทำงานของวิธีจึงง่ายต่อการเข้าใจ สาเหตุถ้าDerivedClassขยายBaseClassและมีเมธอดที่มีชื่อเดียวกันและลายเซ็นเดียวกันของBaseClass การแทนที่จะเกิดขึ้นที่ polymorphism แบบรันไทม์ (จัดเตรียมเมธอดไม่ใช่static) BaseClass bcdc = new DerivedClass(); bcdc.doSomething() // will invoke DerivedClass's doSomething method. ตอนนี้มาถึง C # จะมีความสับสนมากและยากที่จะเข้าใจวิธีการnewหรือvirtual+deriveหรือใหม่ + เสมือนแทนที่คือการทำงาน ฉันไม่สามารถเข้าใจว่าทำไมในโลกนี้ฉันจะเพิ่มวิธีการในDerivedClassชื่อและลายเซ็นเดียวกันกับBaseClassและกำหนดพฤติกรรมใหม่ แต่ที่ polymorphism เวลาทำงานBaseClassวิธีการจะถูกเรียก! (ซึ่งไม่ใช่การเอาชนะ แต่ควรมีเหตุผล) ในกรณีที่virtual + overrideแม้ว่าการใช้งานเชิงตรรกะที่ถูกต้อง แต่โปรแกรมเมอร์ต้องคิดว่าวิธีการที่เขาควรให้สิทธิ์แก่ผู้ใช้ในการแทนที่ในเวลาที่เข้ารหัส ซึ่งมีข้อดีบางอย่าง(อย่าไปที่นั่นตอนนี้) เหตุใดใน C # จึงมีพื้นที่เหลือเฟือสำหรับการใช้เหตุผลและความสับสน ดังนั้นฉันจึงอาจ reframe คำถามของฉันเป็นที่บริบทของโลกแห่งความจริงฉันควรคิดว่าการใช้งานvirtual + overrideแทนnewและยังใช้newแทนvirtual + …

9
เหตุใดภาษาต่างๆจึงไม่รวมความหมายไว้เป็นตัวดำเนินการเชิงตรรกะ
อาจเป็นคำถามที่แปลก แต่ทำไมไม่มีความหมายเป็นตัวดำเนินการเชิงตรรกะในหลายภาษา (Java, C, C ++, Python Haskell - แม้ว่าสุดท้ายจะมีตัวดำเนินการที่ผู้ใช้กำหนดไว้เล็กน้อยเพื่อเพิ่มมัน)? ฉันพบความหมายเชิงตรรกะที่ชัดเจนมากขึ้นในการเขียน (โดยเฉพาะอย่างยิ่งในการอ้างหรือการแสดงออกที่เหมือนยืนยัน) แล้วปฏิเสธด้วยหรือ: encrypt(buf, key, mode, iv = null) { assert (mode != ECB --> iv != null); assert (mode == ECB || iv != null); assert (implies(mode != ECB, iv != null)); // User-defined function }

4
เพราะเหตุใดประเภทจึงตามหลังชื่อตัวแปรในภาษาการเขียนโปรแกรมสมัยใหม่
ทำไมในภาษาการเขียนโปรแกรมสมัยใหม่เกือบทุกภาษา (Go, Rust, Kotlin, Swift, Scala, Nim หรือ Python เวอร์ชันล่าสุด) มักเกิดขึ้นหลังชื่อตัวแปรในการประกาศตัวแปรและไม่ใช่มาก่อน? ทำไมx: int = 42ไม่int x = 42? สิ่งหลังไม่สามารถอ่านได้มากกว่าในอดีตหรือไม่ มันเป็นเพียงเทรนด์หรือมีเหตุผลที่มีความหมายจริงๆที่อยู่เบื้องหลังโซลูชันนี้หรือไม่?

2
เหตุใดจึงไม่อนุญาตให้ 'void' เป็นประเภททั่วไปใน C #
อะไรคือการตัดสินใจในการออกแบบที่แย้งว่าvoidไม่สามารถสร้างได้และไม่ได้รับอนุญาตให้เป็นประเภททั่วไป? structท้ายที่สุดมันก็ว่างเปล่าเป็นพิเศษและจะหลีกเลี่ยง PITA โดยรวมที่มีความแตกต่างFuncและActionผู้ได้รับมอบหมาย (C ++ อนุญาตให้voidส่งคืนอย่างชัดเจนและอนุญาตให้voidเป็นพารามิเตอร์เทมเพลต)

3
ระบบประเภทคืออะไร?
พื้นหลัง ฉันกำลังออกแบบภาษาเป็นโปรเจคต์ด้านข้าง ฉันมีแอสเซมเบลอร์ทำงานตัววิเคราะห์แบบคงที่และเครื่องเสมือนสำหรับมัน เนื่องจากฉันสามารถรวบรวมและเรียกใช้โปรแกรมที่ไม่น่าสนใจโดยใช้โครงสร้างพื้นฐานที่ฉันได้สร้างขึ้นฉันจึงคิดที่จะนำเสนอที่มหาวิทยาลัยของฉัน ในระหว่างการพูดคุยของฉันฉันบอกว่า VM ให้ระบบประเภทถูกถามว่า " ระบบประเภทของคุณคืออะไร " หลังจากตอบฉันได้รับเสียงหัวเราะจากผู้ที่ถามคำถาม ดังนั้นแม้ว่าฉันเกือบจะเสียชื่อเสียงในการถามคำถามนี้ แต่ฉันกลับไปที่โปรแกรมเมอร์ ความเข้าใจของฉัน ตามที่ฉันเข้าใจแล้วระบบประเภทถูกใช้เพื่อให้ข้อมูลเพิ่มเติมเกี่ยวกับเอนทิตีในโปรแกรมเพื่อให้รันไทม์หรือคอมไพเลอร์หรือเครื่องจักรอื่น ๆ รู้ว่าต้องทำอย่างไรกับสตริงของบิตที่ทำงาน พวกเขายังช่วยรักษาสัญญา - คอมไพเลอร์ (หรือตัววิเคราะห์โค้ดหรือรันไทม์หรือโปรแกรมอื่น ๆ ) สามารถตรวจสอบว่า ณ จุดใดก็ตามที่โปรแกรมทำงานกับค่าโปรแกรมเมอร์ที่คาดหวังว่ามันจะทำงาน ประเภทยังสามารถใช้เพื่อให้ข้อมูลกับโปรแกรมเมอร์มนุษย์เหล่านั้น ตัวอย่างเช่นฉันพบประกาศนี้: function sqrt(double n) -> double; มีประโยชน์มากกว่านี้ sqrt(n) ก่อนหน้านี้ให้ข้อมูลมากมาย: sqrtตัวระบุเป็นฟังก์ชั่นรับdoubleอินพุตหนึ่งตัวและสร้างอีกdoubleอันเป็นเอาต์พุต หลังบอกคุณว่ามันอาจเป็นฟังก์ชั่นการใช้พารามิเตอร์เดียว คำตอบของฉัน ดังนั้นหลังจากถูกถามว่า "ระบบประเภทของคุณคืออะไร" ฉันตอบดังนี้: ระบบประเภทเป็นแบบไดนามิก (ประเภทถูกกำหนดให้กับค่าไม่ใช่ตัวแปรที่เก็บไว้) แต่มีความแข็งแกร่งโดยไม่มีกฎบังคับที่น่าแปลกใจ (คุณไม่สามารถเพิ่มสตริงลงในจำนวนเต็มเนื่องจากมันเป็นประเภทที่เข้ากันไม่ได้ แต่คุณสามารถเพิ่มจำนวนเต็มเป็นจำนวนจุดลอยตัว) . ระบบชนิดถูกใช้โดย VM …

5
เหตุใดฟังก์ชัน <algorithm> ทั้งหมดจึงมีเพียงช่วงเท่านั้นไม่ใช่คอนเทนเนอร์?
มีฟังก์ชั่นที่มีประโยชน์มากมาย&lt;algorithm&gt;แต่ทุกฟังก์ชั่นทำงานใน"ลำดับ" - คู่ของตัววนซ้ำ เช่นถ้าฉันมีที่เก็บและต้องการที่จะใช้std::accumulateมันฉันต้องเขียน: std::vector&lt;int&gt; myContainer = ...; int sum = std::accumulate(myContainer.begin(), myContainer.end(), 0); เมื่อทั้งหมดที่ฉันตั้งใจจะทำคือ: int sum = std::accumulate(myContainer, 0); ในสายตาของฉันซึ่งอ่านได้ชัดเจนขึ้น ตอนนี้ฉันเห็นแล้วว่าอาจมีบางกรณีที่คุณต้องการใช้งานเฉพาะในส่วนของคอนเทนเนอร์ดังนั้นจึงมีประโยชน์อย่างมากที่จะมีตัวเลือกในการผ่านช่วง แต่อย่างน้อยในประสบการณ์ของฉันนั่นเป็นกรณีพิเศษที่หายาก ฉันมักจะต้องการที่จะทำงานบนภาชนะทั้งหมด มันง่ายที่จะเขียนฟังก์ชั่น wrapper ซึ่งใช้คอนเทนเนอร์และการโทรbegin()และend()บนมัน แต่ฟังก์ชั่นความสะดวกสบายนั้นไม่รวมอยู่ในไลบรารี่มาตรฐาน ฉันต้องการทราบเหตุผลที่อยู่เบื้องหลังตัวเลือกการออกแบบ STL นี้

4
ทำไมตัววนซ้ำใน Python จึงทำให้เกิดข้อยกเว้น?
นี่คือไวยากรณ์สำหรับตัววนซ้ำใน Java (ค่อนข้างคล้ายไวยากรณ์ใน C #): Iterator it = sequence.iterator(); while (it.hasNext()) { System.out.println(it.next()); } ซึ่งทำให้รู้สึก นี่คือไวยากรณ์ที่เทียบเท่าใน Python: it = iter(sequence) while True: try: value = it.next() except StopIteration: break print(value) ฉันคิดว่ามีการใช้ข้อยกเว้นในกรณีพิเศษเท่านั้น ทำไมไพ ธ อนใช้ข้อยกเว้นเพื่อหยุดย้ำ?

8
ทำไมจึงต้องออกแบบภาษาสมัยใหม่โดยไม่มีกลไกการจัดการยกเว้น?
ภาษาสมัยใหม่หลายคนให้การจัดการข้อยกเว้นที่อุดมไปด้วยคุณสมบัติ แต่แอปเปิ้ลของการเขียนโปรแกรมภาษาสวิฟท์ไม่ได้ให้กลไกการจัดการข้อยกเว้น ขณะที่ฉันกำลังจมดิ่งอยู่ในข้อยกเว้นฉันมีปัญหาในการคิดสิ่งที่มันหมายถึง Swift มีคำยืนยันและแน่นอนว่ามีค่าตอบแทน แต่ฉันกำลังมีปัญหาในการนึกภาพว่าวิธีคิดตามข้อยกเว้นของฉันทำแผนที่โลกโดยไม่มีข้อยกเว้น (และสำหรับเรื่องนั้นทำไมโลกเช่นนี้เป็นที่น่าพอใจ ) มีสิ่งใดบ้างที่ฉันไม่สามารถทำได้ในภาษาอย่าง Swift ที่ฉันสามารถทำได้ด้วยข้อยกเว้น ฉันจะได้รับบางอย่างจากการสูญเสียข้อยกเว้น? ยกตัวอย่างเช่นฉันจะแสดงสิ่งที่ดีที่สุดได้อย่างไร try: operation_that_can_throw_ioerror() except IOError: handle_the_exception_somehow() else: # we don't want to catch the IOError if it's raised another_operation_that_can_throw_ioerror() finally: something_we_always_need_to_do() ในภาษา (ตัวอย่างเช่น Swift) ที่ไม่มีการจัดการข้อยกเว้น?

13
ทำไมโอเปอเรเตอร์ที่ได้รับมอบหมายจึงอยู่ทางซ้ายมือ
ฉันเริ่มสอนการเขียนโปรแกรมเพื่อนเมื่อเร็ว ๆ นี้ (เรากำลังใช้ Python) และเมื่อเราเริ่มพูดคุยเกี่ยวกับการสร้างตัวแปรและผู้ดำเนินการที่ได้รับมอบหมายเธอถามว่าทำไมค่าทางด้านขวาถูกกำหนดให้กับชื่อทางด้านซ้ายไม่ใช่ในทางกลับกัน . ก่อนหน้านี้ฉันไม่ได้คิดมากเพราะมันดูเป็นธรรมชาติสำหรับฉัน แต่เธอบอกว่าซ้าย - ขวาดูเหมือนจะดูเป็นธรรมชาติมากกว่าสำหรับเธอเพราะนั่นเป็นวิธีที่พวกเราส่วนใหญ่อ่านภาษาธรรมชาติ ฉันคิดเกี่ยวกับมันและสรุปว่ามันทำให้การอ่านรหัสง่ายขึ้นมากเนื่องจากชื่อที่กำหนดให้ (ซึ่งโปรแกรมเมอร์จะต้องนำมาใช้ใหม่) สามารถมองเห็นได้ง่ายจัดเรียงชิดซ้าย aligned = 2 on = 'foo' + 'bar' + 'foobar' the = 5.0 / 2 left = 2 + 5 ตรงข้ามกับ: 2 = aligned 'foo' + 'bar' + 'foobar' = on 5.0 / 2 = the …

5
เหตุใดภาษาการเขียนโปรแกรมเก่าจึงยังคงได้รับการแก้ไข
คำถามนี้ไม่ใช่ "ทำไมผู้คนยังใช้ภาษาโปรแกรมเก่าอยู่" ฉันเข้าใจว่าค่อนข้างดี อันที่จริงแล้วภาษาการเขียนโปรแกรมสองภาษาที่ฉันรู้จักดีที่สุดคือ C และ Scheme ซึ่งทั้งสองอย่างนี้ย้อนกลับไปในยุค 70 เมื่อเร็ว ๆ นี้ฉันได้อ่านเกี่ยวกับการเปลี่ยนแปลงใน C99 และ C11 เทียบกับ C89 (ซึ่งดูเหมือนว่าจะยังคงเป็นเวอร์ชัน C ที่ใช้มากที่สุดในทางปฏิบัติและรุ่นที่ฉันเรียนรู้จาก K&amp;R) เมื่อมองไปรอบ ๆ ดูเหมือนว่าภาษาการเขียนโปรแกรมทุกภาษาที่ใช้งานหนักจะได้รับคุณสมบัติใหม่อย่างน้อยหนึ่งครั้งต่อทศวรรษหรือมากกว่านั้น แม้ฟอร์แทรนยังคงได้รับการแก้ไขใหม่แม้ว่าผู้ใช้ส่วนใหญ่จะใช้ฟอร์แทรน 77 ก็ตาม เปรียบเทียบสิ่งนี้กับแนวทางการพูดระบบเรียงพิมพ์ TeX ในปี 1989 ด้วยการเปิดตัว TeX 3.0, Donald Knuth ประกาศว่า TeX เป็นคุณสมบัติที่สมบูรณ์และการเปิดตัวในอนาคตจะมีเพียงการแก้ไขข้อบกพร่อง ถึงแม้จะเกินกว่านี้เขาก็แจ้งว่าเมื่อเขาตาย "บั๊กที่เหลือทั้งหมดจะกลายเป็นคุณสมบัติ" และจะไม่มีการอัพเดทใด ๆ เพิ่มเติม คนอื่น ๆ มีอิสระในการแยก TeX และทำเช่นนั้น แต่ระบบที่ได้จะถูกเปลี่ยนชื่อเพื่อระบุว่าแตกต่างจาก …

4
ทำไมโครงสร้างและคลาสแยกแนวคิดใน C #
ในขณะที่การเขียนโปรแกรมใน C # ฉันสะดุดกับการตัดสินใจออกแบบภาษาแปลก ๆ ที่ฉันไม่เข้าใจ ดังนั้น C # (และ CLR) มีชนิดข้อมูลรวมสองประเภท: struct(ค่าประเภทเก็บไว้ในสแต็กไม่มีการสืบทอด) และclass(อ้างอิงประเภทเก็บไว้ในกองมีมรดก) การตั้งค่านี้ฟังดูดีในตอนแรก แต่จากนั้นคุณสะดุดวิธีที่ใช้พารามิเตอร์ของชนิดรวมและเพื่อหาว่าจริง ๆ แล้วเป็นประเภทค่าหรือประเภทอ้างอิงคุณต้องค้นหาการประกาศของประเภทนั้น บางครั้งอาจทำให้สับสนได้ วิธีแก้ปัญหาที่เป็นที่ยอมรับโดยทั่วไปดูเหมือนว่าจะประกาศstructว่า "ไม่เปลี่ยนรูป" (ตั้งค่าเขตข้อมูลไว้readonly) เพื่อป้องกันความผิดพลาดที่อาจเกิดขึ้นโดย จำกัดstructประโยชน์ของ ตัวอย่างเช่น C ++ ใช้โมเดลที่สามารถใช้งานได้มากขึ้น: ช่วยให้คุณสร้างอินสแตนซ์ของวัตถุบนสแต็กหรือบนฮีปและส่งผ่านตามค่าหรือโดยการอ้างอิง (หรือโดยตัวชี้) ฉันได้ยินอยู่เสมอว่า C # ได้รับแรงบันดาลใจจาก C ++ และฉันก็ไม่เข้าใจว่าทำไมมันไม่ใช้เทคนิคนี้ การรวมclassและสร้างstructเป็นหนึ่งเดียวกับตัวเลือกการจัดสรรที่แตกต่างกันสองตัว (ฮีปและสแต็ค) และส่งต่อให้เป็นค่าหรือ (อย่างชัดเจน) เนื่องจากการอ้างอิงผ่านทางrefและoutคำหลักดูเหมือนเป็นสิ่งที่ดี คำถามคือทำไมclassและstructกลายเป็นแนวคิดที่แยกต่างหากใน C # และ CLR แทนที่จะเป็นประเภทรวมหนึ่งที่มีสองตัวเลือกการจัดสรร?

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

15
ภาษามีอิทธิพลต่อการออกแบบ CPU อย่างไร [ปิด]
เรามักจะบอกว่าฮาร์ดแวร์ไม่สนใจภาษาที่โปรแกรมเขียนเนื่องจากเห็นเฉพาะรหัสไบนารี่ที่คอมไพล์ แต่นี่ไม่ใช่ความจริงทั้งหมด ยกตัวอย่างเช่นพิจารณา Z80 ผู้ต่ำต้อย ส่วนขยายไปยังชุดคำสั่ง 8080 มีคำแนะนำเช่น CPIR ซึ่งจะเป็นประโยชน์สำหรับการสแกนแบบ C (NULL สิ้นสุด) strlen()สตริงเช่นการดำเนินการ ผู้ออกแบบจะต้องระบุว่าการรันโปรแกรม C (ตรงข้ามกับ Pascal ที่ความยาวของสตริงอยู่ในส่วนหัว) เป็นสิ่งที่การออกแบบของพวกเขาน่าจะใช้ อีกตัวอย่างที่คลาสสิกเป็นเครื่องเสียงกระเพื่อม มีตัวอย่างอะไรอีกบ้าง? เช่นคำแนะนำจำนวนและประเภทของการลงทะเบียนโหมดการกำหนดแอดเดรสที่ทำให้ตัวประมวลผลเฉพาะสนับสนุนหลักการของภาษาเฉพาะหรือไม่ ฉันสนใจเป็นพิเศษในการแก้ไขครอบครัวเดียวกัน

22
พื้นที่ว่างในตัวระบุเคยเป็นสำนวนหรือไม่? [ปิด]
สไตล์C #แนะนำให้ใช้CamelCaseในตัวระบุเพื่อคั่นคำ ประเพณีเสียงกระเพื่อมแนะนำให้ใช้ - ขีดกลาง - แทน เคยมีภาษาการเขียนโปรแกรมที่ไม่อนุญาตให้ใช้ช่องว่างในตัวระบุ แต่เป็นสำนวนที่ใช้กันทั่วไปเมื่อใช้ตัวระบุหลายคำ? เป็นไปได้ที่จะมีตัวระบุที่มีช่องว่างในการใช้งานบางอย่างของSchemeแต่ก็ไม่ใช่วิธีปฏิบัติที่แพร่หลาย นี่คือตัวอย่าง: Petite Chez Scheme Version 8.4 Copyright (c) 1985-2011 Cadence Research Systems &gt; (define |hey there| 100) &gt; (define |x y z| 200) &gt; (list |hey there| |x y z|) (100 200)

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