ข้อบกพร่องด้านการออกแบบที่ยิ่งใหญ่ที่สุดที่คุณประสบในภาษาการเขียนโปรแกรมคืออะไร? [ปิด]


29

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

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


6
โปรดทราบว่านี่เป็นสิ่งที่สร้างสรรค์สำหรับนักออกแบบภาษา (ข้อผิดพลาดที่ควรหลีกเลี่ยง) หากใครบางคนต้องการตั้งคำถามว่าคำถามนี้สร้างสรรค์เพียงใด
Anto


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

8
ข้อบกพร่องที่ยิ่งใหญ่ที่สุดในภาษาการเขียนโปรแกรมใด ๆ มนุษย์
Joel Etherton

หากคำตอบเหล่านี้เป็นข้อบกพร่องที่ยิ่งใหญ่ที่สุดฉันก็ประทับใจในภาษาโปรแกรม
Tom Hawtin - tackline

คำตอบ:


42

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

ฉันจำได้เมื่อประมาณปี 1995 เมื่อฉันอ่านรายละเอียดของ Java เป็นครั้งแรกเมื่อฉันไปถึงส่วนที่เกี่ยวกับswitchข้อความที่ฉันรู้สึกผิดหวังมากที่พวกเขายังคงรักษาพฤติกรรมการตกผ่านที่เป็นค่าเริ่มต้น นี่ทำให้switchเป็นที่สรรเสริญgotoด้วยชื่ออื่น


3
@ คริสโตเฟอร์มาฮัน: switchไม่ต้องทำงานแบบนั้น ตัวอย่างเช่นกรณีของ Ada / เมื่อคำสั่ง (เทียบเท่ากับสวิตช์ / กรณี) ไม่ได้มีพฤติกรรมการตก
Greg Hewgill

2
@Greg: switchข้อความเหมือนในภาษาที่ไม่เกี่ยวข้องกับ C ไม่จำเป็นต้องทำเช่นนั้น แต่ถ้าคุณใช้ C-สไตล์การควบคุมการไหล ( {... }, for (i = 0; i < N; ++i), returnฯลฯ ), การอนุมานภาษาจะทำให้ผู้คนคาดหวังswitchในการทำงานเช่น C, และให้มันคน Ada / Pascal / ขั้นพื้นฐานเช่นความหมายจะได้สับสน C # ต้องการbreakในswitchงบด้วยเหตุผลเดียวกันถึงแม้ว่าจะทำให้เกิดข้อผิดพลาดน้อยลงโดยการห้ามการผิดพลาดแบบเงียบ (แต่ฉันหวังว่าคุณจะสามารถเขียนfall;แทนคนอัปลักษณ์goto caseได้)
dan04

4
จากนั้นอย่าเขียนสวิตช์เขียนถ้า () อื่น เหตุผลที่คุณบ่นเกี่ยวกับสิ่งที่ทำให้สวิตช์ดีขึ้น: ไม่ใช่เงื่อนไขที่ถูก / ผิด, เป็นตัวเลขที่มีเงื่อนไขและนั่นทำให้แตกต่างกัน คุณสามารถเขียนฟังก์ชันสวิตช์ของคุณเองได้เช่นกัน
jokoon

9
-1 ฉันคิดว่ามันเป็นประโยชน์ที่จะอนุญาตให้ตกผ่านไม่มีอันตรายจากมันนอกเหนือจากความโง่เขลา แต่มันก็มอบฟังก์ชั่นเพิ่มเติม
Orbling

11
ปัญหาไม่ได้เป็นสิ่งที่switch ทำให้เข้าใจผิด นั่นคือการใช้งานโดยไม่ได้ตั้งใจส่วนใหญ่ไม่ได้ตั้งใจ
dan04

41

ฉันไม่เคยชอบการใช้=งานที่ได้รับมอบหมายและ==สำหรับการทดสอบความเท่าเทียมกันในภาษาที่ได้รับจาก C โอกาสที่จะเกิดความสับสนและข้อผิดพลาดนั้นสูงเกินไป และอย่าทำให้ฉันเริ่มต้นด้วย===Javascript

จะดีกว่า:=สำหรับการมอบหมายและ=การทดสอบความเท่าเทียมกัน ความหมายอาจเหมือนกันทุกวันนี้โดยที่การมอบหมายนั้นเป็นนิพจน์ที่ให้คุณค่า


3
@Nemanja Trifunovic: ตอนแรกฉันคิดว่าข้อเสนอแนะนั้น แต่มันมีความคลุมเครือที่โชคร้ายใน C ที่มีการเปรียบเทียบน้อยกว่าเมื่อเทียบกับจำนวนลบ (เช่นx<-5) โปรแกรมเมอร์ C จะไม่ยอมให้ชนิดของช่องว่างที่จำเป็น :) ว่า
เกร็ก Hewgill

7
@ Greg: ฉันต้องการ:=และ==เพราะมันง่ายเกินไปที่จะลืม:และไม่ได้รับการแจ้งเตือนเหมือนเป็นกรณี (แม้ว่าจะย้อนกลับ) เมื่อคุณลืม=วันนี้ ฉันรู้สึกขอบคุณสำหรับคำเตือนของคอมไพเลอร์เกี่ยวกับเรื่องนี้ ...
Matthieu M.

13
ในเกือบทุกคีย์บอร์ดที่ฉันเคยใช้ ": =" ต้องเปลี่ยนปุ่ม Shift ในขณะที่พิมพ์ ในสิ่งที่ฉันกำลังใช้อยู่ตอนนี้ ':' เป็นตัวพิมพ์ใหญ่และ '=' เป็นตัวพิมพ์เล็กและฉันกลับตัวแล้ว ฉันพิมพ์งานจำนวนมากและไม่ต้องการความยุ่งยากในการพิมพ์
David Thornley

14
@David Thornley: อ่านโค้ดได้หลายครั้งมากกว่าที่เขียน ฉันไม่ได้ซื้อข้อโต้แย้งใด ๆ เกี่ยวกับ "การพิมพ์ที่ยุ่งยาก"
Greg Hewgill

8
@ Greg Hewgill: แน่นอนว่าอ่านบ่อยกว่าที่เขียน อย่างไรก็ตามปัญหาระหว่าง=และ==ไม่ได้อยู่ในการอ่านเพราะพวกเขาเป็นสัญลักษณ์ที่แตกต่างกัน เป็นลายลักษณ์อักษรและทำให้แน่ใจว่าคุณได้รับสิ่งที่ถูกต้อง
David Thornley

29

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

มันจะเป็นเรื่องง่ายในการเริ่มต้นที่จะแนะนำผู้ประกอบการรายใหม่อย่างสมบูรณ์เช่นการ$ต่อสตริง


13
@ Barry: ไม่จริง +ทำให้รู้สึกมากในฐานะผู้ประกอบการเรียงสตริงในภาษาที่พิมพ์อย่างยิ่ง ปัญหาคือ Javascript ใช้ แต่ไม่ได้พิมพ์อย่างมาก
Mason Wheeler

13
@ ช่างก่ออิฐ: +ไม่สมเหตุสมผลสำหรับการต่อข้อมูลเนื่องจากการต่อข้อมูลไม่แน่นอน มันเป็นการละเมิดเท่าที่ฉันกังวล
Matthieu M.

12
@ Matthieu: อืมม ... ทำไมถึงเป็นเช่นนั้น การต่อข้อมูลไม่ใช่การสลับ (เช่นการเพิ่ม) แต่การเพิ่มสองสตริงนั้นไร้สาระดังนั้นจึงไม่มีใครคิดแบบนั้น คุณกำลังคิดค้นปัญหาที่ไม่มีอยู่จริง
Mason Wheeler

4
เพียงสลับไปที่ C ++ และเพิ่มรูปแบบการโอเวอร์โหลดแบบลึกลับให้กับผู้ให้บริการที่คุณต้องการ
Newtopian

8
@ Matthieu: การสับเปลี่ยนไม่ใช่ปัญหาที่นี่ หาก JS มีคลาส Matrix คุณจะพิจารณาว่าเป็นการละเมิดเพื่อให้มี*โอเปอเรเตอร์หรือไม่
dan04

24

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


2
เริ่มต้นที่ทั่วโลก? ฉันดีใจที่ฉันไม่ได้ใช้ JS แล้ว ...
Anto

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

1
เพียงใช้varทุกครั้งที่คุณประกาศตัวแปรและคุณพร้อมที่จะไป และอย่าบอกฉันว่ามันพิมพ์มากเกินไปเพราะ Java บังคับให้คุณประกาศทุกประเภทสองครั้งและไม่มีใครบ่นว่ามันเป็นตัวเลือกการออกแบบที่ไม่น่าเชื่อ
davidk01

3
@ davidk01: ผู้คนบ่นเกี่ยวกับเรื่องนี้ ในทำนองเดียวกันคนบ่นเกี่ยวกับการประกาศstd::map<KEY, VALUE>::const_iteratorตัวแปรใน C ++ พอที่autoจะถูกเพิ่มลงในภาษานั้น
dan04

1
"use strict"สั่งเพิ่มเข้ามาใน ES5 เปลี่ยนแปลงการอ้างอิงที่ไม่ได้ประกาศลงในข้อผิดพลาด
Sean McMillan

22

ตัวประมวลผลล่วงหน้าใน C และ C ++ เป็น kludge ขนาดใหญ่สร้าง abstractions ที่รั่วไหลเหมือน sieves กระตุ้นสปาเก็ตตี้โค้ดผ่านทาง#ifdefคำแถลงของหนูและต้องการALL_CAPSชื่อที่อ่านไม่ได้อย่างน่ากลัวเพื่อแก้ไขข้อ จำกัด ของมัน รากของปัญหาเหล่านี้คือมันทำงานในระดับข้อความมากกว่าระดับไวยากรณ์หรือความหมาย มันควรจะถูกแทนที่ด้วยคุณสมบัติภาษาจริงสำหรับกรณีการใช้งานที่หลากหลาย ต่อไปนี้เป็นตัวอย่างบางส่วนแม้ว่าบางส่วนจะได้รับการแก้ไขใน C ++, C99 หรือไม่เป็นทางการ แต่เป็นส่วนขยายมาตรฐานแบบพฤตินัย :

  • #include ควรถูกแทนที่ด้วยระบบโมดูลจริง

  • ฟังก์ชั่นแบบอินไลน์และแม่แบบ / ข้อมูลทั่วไปสามารถแทนที่กรณีการเรียกใช้ฟังก์ชันส่วนใหญ่

  • คุณลักษณะค่าคงที่เวลาแสดง / คอมไพล์บางชนิดสามารถใช้สำหรับการประกาศค่าคงที่ดังกล่าว ส่วนขยาย D ของ enumทำงานได้ดีที่นี่

  • มาโครระดับแผนผังไวยากรณ์ที่แท้จริงสามารถแก้ปัญหากรณีใช้เบ็ดเตล็ดได้มากมาย

  • String mixinsสามารถใช้สำหรับกรณีการใช้การฉีดโค้ด

  • static ifหรือversionงบสามารถใช้สำหรับการรวบรวมเงื่อนไข


2
@dsimcha: ฉันเห็นด้วยกับ#includeปัญหา แต่ระบบโมดูลถูกคิดค้น ... หลังจากนั้น! และ C และ C ++ มีจุดมุ่งหมายเพื่อความเข้ากันได้แบบย้อนกลับสูงสุด: /
Matthieu M.

@ Matthieu: ใช่ระบบโมดูลถูกประดิษฐ์ขึ้นมาในภายหลัง แต่เรากำลังพูดถึงการเข้าใจถึงปัญหาที่นี่ แต่อย่างใด
dsimcha

3
ฉันยอมรับว่านี่เป็นความเจ็บปวดครั้งใหญ่ในส่วนต่างๆของร่างกาย แต่การออกแบบแบบหลายพาสมีข้อดีของความเรียบง่าย: คอมไพเลอร์ C ไม่จำเป็นต้องรู้มากเกี่ยวกับบริบทของการทำงานก่อนที่จะสามารถรวบรวมรหัส C ได้สำเร็จ . สิ่งนี้จะมีคุณสมบัติเป็นข้อผิดพลาดในการออกแบบเท่านั้นหากคุณสามารถแสดงให้เห็นว่าค่าใช้จ่ายในการใช้ระบบโมดูลสมมุติภายในภาษา C เอง (เช่นคลาส C ++ เหมือนคลาส) จะต่ำกว่าหรือเทียบเท่ากับการ#includeแฮ็คที่ใช้ cpp
reinierpost

ฉันเห็นด้วย. อย่างไรก็ตามบางคนคิดว่าการประมวลผลล่วงหน้าเป็นสิ่งที่ดีและบ่นว่าไม่รองรับ Java (เช่น) Java
สตีเฟ่นซี

5
@Stephen: ฉันยอมรับว่า Java ที่มี preprocessor อาจจะดีกว่า Java ที่ไม่มีแต่เพียงเพราะ Java ไม่มีคุณสมบัติ "ของจริง" หลายประการที่จำเป็นในการแทนที่ preprocessor ในภาษาอย่าง D ซึ่งรวมถึงฟีเจอร์ดังกล่าวและ Python ซึ่งมีความยืดหยุ่นในรูปแบบอื่นโดยการเป็นแบบไดนามิกฉันไม่ควรพลาดเลยแม้แต่น้อย
dsimcha

21

อาจมีรายการข้อผิดพลาดหลายร้อยรายการในหลายร้อยภาษา แต่ IMO ไม่ใช่แบบฝึกหัดที่มีประโยชน์จากมุมมองการออกแบบภาษา

ทำไม?

เพราะสิ่งที่จะเป็นความผิดพลาดในภาษาหนึ่งจะไม่เป็นความผิดพลาดในภาษาอื่น ตัวอย่างเช่น

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

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

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

หากมีบทเรียนทั่วไปที่ต้องเรียนรู้พวกเขาจะอยู่ในระดับ "เมตา":

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

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

ประเด็นของฉันคือมันยากที่จะเรียนรู้บทเรียนโดยไม่คำนึงถึงเป้าหมายการออกแบบ
สตีเฟ่นซี

1
ดูเหมือนว่าฉันว่า OP ได้คำนึงถึงคำตอบของคุณในย่อหน้าที่สองของคำถามแล้ว
Aidan Cully

20

CและC ++ : จำนวนเต็มทั้งหมดนั้นไม่ได้มีความหมายอะไรเลย

charโดยเฉพาะอย่างยิ่ง มันเป็นข้อความหรือเป็นจำนวนเต็มเล็กน้อย หากเป็นข้อความแสดงว่าเป็นอักขระ "ANSI" หรือหน่วยรหัส UTF-8 หรือไม่ หากเป็นจำนวนเต็มจะมีการลงชื่อหรือไม่ได้ลงชื่อหรือไม่?

int มีวัตถุประสงค์เพื่อเป็นจำนวนเต็มขนาดดั้งเดิม "แต่ในระบบ 64 บิตไม่ใช่

longintอาจหรือไม่อาจมีขนาดใหญ่กว่า มันอาจจะใช่หรือไม่ใช่ขนาดของพอยน์เตอร์ มันเป็นการตัดสินใจตามอำเภอใจในส่วนของผู้เขียนคอมไพเลอร์ไม่ว่าจะเป็นแบบ 32 บิตหรือ 64 บิต

ภาษาของปี 1970 แน่นอน ก่อน Unicode ก่อนคอมพิวเตอร์ 64 บิต


10
C ไม่ได้ถูกออกแบบมาให้เป็นมาตรฐานที่เหมาะกับทุกภาษาดังนั้นจึงไม่สามารถเกิดข้อผิดพลาดในการออกแบบได้ มันถูกออกแบบมาเพื่อจำลอง cpu เป็นแอสเซมเบลอร์แบบพกพาหลีกเลี่ยงโค้ดแอสเซมเบลอร์ของ cpu อย่างไรก็ตามมันได้รับการแก้ไขใน Java

7
ฉันคิดว่าปัญหาที่ใหญ่กว่านั้นคือภาษาที่ใหม่กว่าที่ยังคงใช้คำที่ไม่มีความหมายเหมือนเดิมต่อไปแม้ว่าประวัติศาสตร์จะแสดงให้เราเห็นว่าเป็นความคิดที่แย่ อย่างน้อยพวก C สังเกตเห็นความผิดพลาดและสร้างประเภท int มาตรฐาน
ทำเครื่องหมาย H

5
ถ่านไม่ได้เป็นหน่วย utf-8 อักขระ utf-8 สามารถใช้ 8 บิตเพื่อจัดเก็บได้มากขึ้น C ไม่ใช่ภาษาของปี 1970 ฉันใช้มันสำหรับโครงการตอนนี้ (สมัครใจ)
dan_waterworth

4
C น้อยกว่าการเป็นนามธรรมในระดับสูงของโปรเซสเซอร์ PDP-11 ตัวอย่างเช่นการเพิ่มก่อนและหลังได้รับการสนับสนุนโดยตรงจาก PDP-11
bit-twiddler

5
นี่คือคำตอบที่เข้าใจผิดอย่างมาก ก่อนอื่น C และ C ++ จะไม่สามารถใช้แทนกันได้ ประการที่สองสเป็คภาษากำหนดไว้อย่างชัดเจนว่าถ่านคืออะไร - วัตถุที่ประกาศเป็นถ่านประเภทมีขนาดใหญ่พอที่จะเก็บสมาชิกของชุดอักขระการดำเนินการพื้นฐานใด ๆ . ประการที่สาม C ไม่ใช่ "ภาษาของยุค 70" เป็นภาษาที่อาศัยอยู่ใกล้กับฮาร์ดแวร์และอาจเป็นภาษาที่ท้ายที่สุดทำให้ abstractions ระดับสูงทั้งหมดของคุณให้ความรู้สึกกับซีพียู คุณออกมาในฐานะคนที่รู้ภาษาระดับสูงเท่านั้นและไม่ซาบซึ้งในสิ่งที่ใช้งานได้จริง -1
Ed S.

18

null.

ประดิษฐ์โทนี่โฮร์เรียกมันว่า "ความผิดพลาดพันล้านดอลล่า"

มันได้รับการแนะนำใน ALGOL ในยุค 60 และมีอยู่ในภาษาโปรแกรมส่วนใหญ่ที่ใช้กันทั่วไปในปัจจุบัน

ทางเลือกที่ดีกว่าที่ใช้ในภาษาเช่น OCaml และ Haskell เป็นบางที แนวคิดทั่วไปคือการอ้างอิงวัตถุไม่สามารถเป็นโมฆะ / ว่างเปล่า / ไม่มีอยู่เว้นแต่ว่ามีข้อบ่งชี้ชัดเจนว่าอาจเป็นเช่นนั้น

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


ไม่เห็นด้วยแม้แต่กับนักประดิษฐ์ !!! null เป็นค่าว่างสำหรับตัวชี้ / ประเภทข้อมูลอ้างอิง สตริงมีสตริงว่างชุดมีชุดว่าง (Pascal empty set = []) จำนวนเต็มมี 0 ภาษาการเขียนโปรแกรมส่วนใหญ่ที่ใช้ null / nil / อะไรก็ตามหากตัวแปรถูกกำหนดอย่างถูกต้องข้อผิดพลาด null สามารถป้องกันได้
umlcat

4
@ user14579: ทุกภาษาที่รองรับชุดหรือสตริงหรืออาร์เรย์ใด ๆ ที่มี {} แต่ยังคงเหมาะสมทางความหมายและจะไม่ผิดพลาดหากคุณมีบางอย่างที่อาจทำให้เกิดข้อผิดพลาดในขอบเขตของอาร์เรย์ - แต่นั่นเป็นปัญหาอื่น คุณสามารถประมวลผลสตริงว่างเพื่อพิมพ์อักขระทั้งหมดซึ่งจะส่งผลให้เป็นสตริงว่าง คุณลองทำสิ่งเดียวกันกับสตริงว่างและหากไม่มีการพิจารณาอย่างเหมาะสมมันจะพัง ปัญหาคือการพิจารณาที่เหมาะสมนี้น่าเบื่อมักลืมและทำให้ยากต่อการเขียนฟังก์ชั่นการแสดงออกเดียว (เช่น lambdas)
Rei Miyasaka

1
ฉันทำเงินทุกครั้งที่ฉันพิมพ์เป็นโมฆะ ... โอ้ถูกต้องแล้วใครบางคนสูญเสียเงินทุกครั้งที่ฉันพิมพ์โมฆะ ยกเว้นเวลานี้
kevpie

3
@umlcat - เมื่อคุณมีภาษาที่มีการจับคู่รูปแบบเช่น Ocaml, Haskell และ F # โดยใช้บางที x | ไม่มีรูปแบบใดที่จะป้องกันไม่ให้คุณลืมกรณีที่เป็นโมฆะในเวลารวบรวม ไม่มีเล่ห์เหลี่ยมเวลารวบรวมไม่สามารถจับข้อผิดพลาดในภาษาที่ null เป็นสำนวนที่จัดตั้งขึ้น เนื่องจากคุณต้องเลือกอย่างชัดเจนว่าจะไม่จัดการกับคดีโมฆะในภาษาที่มีแบบบางทีและแบบบางคนจึงมีข้อได้เปรียบที่ร้ายแรงกว่าวิธีการแบบ "ว่าง"
JasonTrue

1
@ Jason - ฉันชอบคิดว่าmaybeการเลือกใช้เป็นโมฆะในขณะที่ข้อยกเว้น null เป็นการเลือกไม่ใช้ แน่นอนว่ามีบางสิ่งที่จะกล่าวเกี่ยวกับความแตกต่างระหว่างข้อผิดพลาดรันไทม์และข้อผิดพลาดในการคอมไพล์เวลาเกินไป แต่เพียงความจริงที่ว่าโมฆะเป็นหลักพฤติกรรมการฉีดเป็นสำคัญในตัว
Rei Miyasaka

14

ฉันรู้สึกว่าคนที่ออกแบบ PHP ไม่ได้ใช้แป้นพิมพ์ปกติพวกเขาไม่ได้ใช้คีย์บอร์ด colemak เพราะพวกเขาควรจะรู้ว่าพวกเขากำลังทำอะไรอยู่

ฉันเป็นนักพัฒนา PHP PHP ไม่สนุกที่จะพิมพ์

Who::in::their::right::mind::would::do::this()? ::ผู้ประกอบการต้องมีการเปลี่ยนแปลงการถือครองและจากนั้นกดปุ่มสอง สิ่งสิ้นเปลืองพลังงาน

Although-> this-> ล์> not-> much-> ดีกว่า ซึ่งยังต้องใช้การกดปุ่มสามครั้งโดยมีการเลื่อนอยู่ระหว่างสัญลักษณ์ทั้งสอง

$last = $we.$have.$the.$dumb.'$'.$character. เครื่องหมายดอลลาร์นั้นถูกใช้เป็นจำนวนมากและต้องได้รับรางวัลซึ่งทอดยาวไปถึงส่วนบนสุดของแป้นพิมพ์รวมถึงการกดปุ่ม Shift

ทำไมพวกเขาถึงออกแบบ PHP ไม่ให้ใช้คีย์ที่พิมพ์เร็วกว่ากัน? เหตุใดwe.do.this()vars จึงไม่สามารถเริ่มต้นด้วยคีย์ที่ต้องใช้การกดเพียงปุ่มเดียว - หรือไม่ใช่เลย (JavaScript) และเพียงแค่กำหนด vars ทั้งหมดล่วงหน้า (เหมือนที่ฉันต้องทำเพื่อ E_STRICT)!

ฉันไม่ใช่คนพิมพ์ดีดช้า - แต่นี่เป็นเพียงตัวเลือกการออกแบบที่อ่อนแอ


Perl แบ่งปันความเจ็บปวดนี้
Daenyth

2
ดังนั้น C ++ และเหตุผลที่แปลกประหลาดบางอย่างที่อธิบายไม่ได้ PowerShell
Rei Miyasaka

2
ใช้เครื่องมือแก้ไขที่มีประสิทธิภาพยิ่งขึ้นและกำหนดลำดับคีย์ของคุณเองสำหรับผู้ให้บริการ
วินไคลน์

1
I::have::nothing::against::this->at.all()
Mateen Ulhaq

1
บางทีพวกเขาอาจไม่ใช้แป้นพิมพ์แบบ qwerty $ และ: ไม่จำเป็นต้องกดปุ่ม Shift บนแป้นพิมพ์ทั้งหมดเช่นแป้นพิมพ์
Arkh

13

การใช้งานของสก์ท็อปแรงบันดาลใจในรูปแบบภายในasp.net

มันมักจะรู้สึกเหลวไหลและไปในทางหรือวิธีที่เว็บใช้งานได้จริง โชคดีที่ asp.net-mvc ไม่ได้ประสบในลักษณะเดียวกันแม้ว่าจะให้เครดิตกับ Ruby และอื่น ๆ สำหรับแรงบันดาลใจนั้น


18
นั่นไม่ใช่ห้องสมุดหรอกเหรอ?
nikie

@ นิกกี้นั่นเป็นจุดที่ดี;)
นกพิราบ

1
@nikie จริง ๆ แล้วรหัส ASPX ที่ใช้ XML เป็นภาษาหนึ่งดังนั้นคุณสามารถบิดรหัสนี้เพื่อใช้งานได้ : D
CodexArcanum

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

1
ในทางกลับกันมีแอพการรวบรวมข้อมูลที่ง่ายและประสบความสำเร็จมากมายที่ซึ่งรวมกันโดยใช้แอพเดสก์ท็อป "คลาสสิค" สิ่งเลวร้ายอย่างเดียวก็คือจนกระทั่ง MVC ตัวเลือกเดียวของ Microsoft คือแบบฟอร์ม windows
ElGringoGrande

13

สำหรับฉันมันคือPHPขาดการตั้งชื่อและการโต้แย้งการสั่งการประชุมในห้องสมุดมาตรฐานของมัน

ถึงแม้ว่าความจำเป็นของJASSในการลบล้างการอ้างอิงหลังจากที่วัตถุอ้างอิงถูกปล่อย / ลบออก (หรือการอ้างอิงจะรั่วและหน่วยความจำหลายไบต์จะหายไป) นั้นร้ายแรงกว่า แต่เนื่องจาก JASS เป็นภาษาวัตถุประสงค์เดียวจึงไม่สำคัญ


9
การขาดการประชุมใน stdlib ของ PHP นั้นพิสูจน์ได้ว่าไม่ใช่ข้อบกพร่องด้านการออกแบบภาษา

3
@delnan: การขาดการประชุมเป็นผลมาจากวิธีการออกแบบ PHP และดังนั้นจึงมีหลายสิ่งที่เกี่ยวข้องกับการออกแบบภาษา ยังไม่ชัดเจนสำหรับฉันว่ามีความแตกต่างที่ชัดเจนระหว่างห้องสมุดและภาษา เสียงกระเพื่อมโดยเฉพาะอย่างยิ่งมีความภาคภูมิใจของประเพณี bootstrapping ภาษาหนึ่งด้านบนของอีกภาษาหนึ่ง
btilly

1
สิ่งที่น่าทึ่งอย่างแท้จริงเกี่ยวกับ JASS ก็คือมันมีการอ้างอิงนับที่ด้ามจับ แต่จะไม่ทำความสะอาดเว้นแต่ว่าพวกเขาจะถูกทำลายด้วยตนเอง (และอินเทอร์เฟซกราฟิกที่สร้างฟังก์ชั่น
Craig Gidney

13

ข้อบกพร่องในการออกแบบที่ยิ่งใหญ่ที่สุดที่ฉันเผชิญคือหลามนั้นไม่ได้ออกแบบมาเช่น python 3.x เพื่อเริ่มต้น


1
ไม่แม้แต่กุยโด้ก็สามารถทำทุกอย่างได้ในครั้งเดียว ...

5
@delnan โอ้ฉันรู้แล้วและ python <3 ยังคงเป็นภาษาที่ดี แต่มันน่ารำคาญเล็กน้อยที่มีภาษาที่ดีกว่าในรูปแบบของ python 3.x ที่ฉันไม่สามารถใช้เพราะแบ่งโมดูลทั้งหมดที่ ฉันต้องการ.
dan_waterworth

เข้าสู่ล็อบบี้สำหรับโมดูล python 3.x ของคุณต่อไป! ในขณะเดียวกันฉันจะเขียน 2.5.4 ต่อไป ขอบคุณดังนั้นฉันจริง ๆ แล้วเตือนว่า 3.x มีชีวิตอยู่และดี
kevpie

@kevpie ก่อนอื่นล็อบบี้เพื่อเพิ่มการคอมไพล์ตามเงื่อนไขให้กับ python เพื่อให้การเปลี่ยนแปลงง่ายขึ้นสำหรับผู้ดูแลห้องสมุด 2to3 ไม่ใช่วิธีการบำรุงรักษาในระยะยาว
Evan Plaice

12

Array สลายตัวใน C และต่อมา C ++


ฉันหวังว่าจะสนับสนุนอาร์เรย์ที่เหมาะสมเช่นกัน ใน C ++ คุณสามารถป้องกันการสลายตัวโดยใช้ไวยากรณ์และเทมเพลต abscons ... แต่มันเป็นเรื่องของแฮ็ค: /
Matthieu M.

1
โปรดทราบว่านี่คือเหตุผลที่ C ++ ต้องแยกต่างหากdeleteและdelete[]ตัวดำเนินการ
dan04

คุณสามารถใส่อาเรย์เข้าไปใน struct ได้และให้มันผ่านไปตามค่าถ้าคุณชอบ แต่มันมักจะแปลกกว่าปัญหาเดิม ใน C ++ คุณสามารถหลีกเลี่ยงความจำเป็นในการใช้อาร์เรย์
David Thornley

2
อย่างน้อยในกรณี C การโต้แย้งกับการสนับสนุนอาเรย์ที่เหมาะสมคือ "การตรวจสอบขอบเขตอาเรย์นั้นมีราคาแพง" โดยเฉพาะอย่างยิ่งเมื่อพิจารณาจากวิธีการคำนวณทางคณิตศาสตร์ของตัวชี้ C
Stephen C

@Stephen C: การตรวจสอบขอบเขตของอาเรย์จะทำอย่างไรกับการสลายตัวของอาเรย์
Nemanja Trifunovic

11

ประเภทดั้งเดิมใน Java

พวกเขาทำลายหลักการที่ว่าทุกอย่างเป็นลูกหลานของjava.lang.Objectซึ่งจากมุมมองทางทฤษฎีนำไปสู่ความซับซ้อนเพิ่มเติมของการกำหนดภาษาและจากมุมมองการปฏิบัติพวกเขาใช้คอลเลกชันที่น่าเบื่ออย่างยิ่ง

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


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

ในเวลานี้เป็นการตัดสินใจที่สมเหตุสมผลจากนักออกแบบ Java ประสิทธิภาพที่เพิ่มขึ้นนั้นเกิดจากเครื่องจักร / VMs ที่มีอยู่ในยุค 90 นั้นมีข้อดีมากกว่าแนวคิดในการรวมทุกอย่างรอบ ๆ java.lang.Object
mikera

10

ฉันรู้ว่า Perl ดีที่สุดดังนั้นฉันจะเลือกมัน

Perl ลองหลายความคิด บางคนดี บางคนก็ไม่ดี บางคนเป็นต้นฉบับและไม่ได้คัดลอกอย่างกว้างขวางด้วยเหตุผลที่ดี

หนึ่งคือแนวคิดของบริบท - การเรียกใช้ฟังก์ชันทุกครั้งเกิดขึ้นในรายการหรือบริบทสเกลาร์และสามารถทำสิ่งที่แตกต่างอย่างสิ้นเชิงในแต่ละบริบท ขณะที่ผมชี้ให้เห็นที่http://use.perl.org/~btilly/journal/36756นี้มีความซับซ้อนทุก API และมักจะนำไปสู่ปัญหาการออกแบบที่ละเอียดอ่อนในรหัส Perl

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

ข้อผิดพลาดทั่วไปอีกอย่างที่เกิดขึ้นในหลายภาษาคือเริ่มจากการกำหนดขอบเขตแบบไดนามิกแทนที่จะเป็นศัพท์ ยากที่จะคืนการตัดสินใจการออกแบบนี้ในภายหลังและนำไปสู่หูดที่ติดทนนาน คำอธิบายคลาสสิกของหูดผู้ที่อยู่ใน Perl เป็นhttp://perl.plover.com/FAQs/Namespaces.html โปรดทราบว่าสิ่งนี้ถูกเขียนก่อน Perl เพิ่มourตัวแปรและstaticตัวแปร

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

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


5
ใช่ Perl มีข้อผิดพลาดมากเพราะคนที่สร้างมันกำลังพยายามคิดใหม่และเมื่อคุณทำเช่นนั้นคุณมักจะทำให้พวกเขาผิด (Perl นอกจากนี้ยังมีบางสิ่งที่ดีมากและเป็นมาตรฐานสำหรับ regexps ว่าคนอื่น ๆ ดูเหมือนว่าจะมีการคัดลอก)
รี K

@ zachary-k: เห็นด้วยอย่างแน่นอน และฉันพยายามที่จะทำให้ชัดเจนก่อนที่ฉันจะเริ่มเดินผ่านปัญหา
btilly

4
เดิมที Lisps ถูกกำหนดขอบเขตแบบไดนามิกและเมื่อเวลาผ่านไปก็เปลี่ยนเป็น scax แบบ lexically (อย่างน้อยก็ใน Scheme และ Common Lisp) ไม่สามารถเปลี่ยนแปลงได้
David Thornley

4
@ david-thornley: มันเป็นไปไม่ได้เว้นแต่คุณจะเสียสละความเข้ากันได้ไปข้างหลังบางแห่ง โครงการถูกกำหนดขอบเขตเสมอ Common Lisp ถูก จำกัด ขอบเขตจากช่วงเวลาที่เป็นมาตรฐาน แต่ชุมชน LISP หลายแห่งมีการดิ้นรนที่จะยอมรับมัน และ Emacs Lisp ยังคงใช้การกำหนดขอบเขตแบบไดนามิกแม้ว่าจะมีความปรารถนาที่จะเปลี่ยนแปลงมันเป็นเวลานาน
btilly

1
BTW หลายสิ่งที่ผู้คนไม่ชอบ Perl สำหรับที่ไม่ได้ประดิษฐ์ใน Perl แต่นำมาจากภาษาอื่น ๆ ซึ่งส่วนใหญ่เป็น Bourne shell
reinierpost

10

ความคลุมเครือของ JavaScript สำหรับบล็อคโค้ดและตัวอักษรของวัตถุ

  {a:b}

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


ฉันชอบสิ่งนี้จริงเกี่ยวกับ JavaScript ความเรียบง่ายของโครงสร้างภาษานั้นดีและวัตถุประสงค์ควรชัดเจนหากผู้พัฒนารู้ว่าพวกเขากำลังทำอะไรอยู่
Xeoncross

2
Xeoncross: โดยทั่วไปแล้วฉันไม่ชอบความกำกวม ในกรณีนี้ผู้พัฒนาเห็นได้ชัด แต่ eval () ต้องการวงเล็บเพิ่มเติม
281377

2
@ammoQ: มันชัดเจน ถ้าเช่นนั้นจะเป็นอะไร วัตถุหรือบล็อครหัส?
กำหนดค่า

เครื่องมือกำหนดค่า: เห็นได้ชัดว่าเป็นวัตถุ aไม่มีคนมีสติจะใช้ฉลากที่เรียกว่า
281377

10

ฉันจะกลับไปที่ฟอร์แทรนและการไม่รู้สึกถึงช่องว่าง

มันแผ่ซ่านสเปค ENDบัตรจะต้องมีการกำหนดให้เป็นบัตรที่มี 'E' เป็น 'N' และ 'D' ในการสั่งซื้อในคอลัมน์ที่ 7-72 และไม่มี nonblanks อื่น ๆ มากกว่าบัตรที่มี "END" ในที่เหมาะสม คอลัมน์และไม่มีอะไรอื่น

มันนำไปสู่ความสับสนทางวากยสัมพันธ์ง่าย DO 100 I = 1, 10เป็นคำสั่งการควบคุมวงในขณะที่DO 100 I = 1. 10เป็นคำสั่งที่ได้รับมอบหมายมูลค่า 1.1 DO10Iตัวแปรที่เรียกว่า (ความจริงที่ว่าตัวแปรสามารถสร้างขึ้นได้โดยไม่มีการประกาศประเภทของพวกเขาขึ้นอยู่กับตัวอักษรตัวแรกของพวกเขามีส่วนร่วมในเรื่องนี้) ซึ่งแตกต่างจากภาษาอื่น ๆ ไม่มีวิธีการใช้ช่องว่างเพื่อแยกโทเค็นออก

นอกจากนี้ยังอนุญาตให้ผู้อื่นเขียนโค้ดที่สับสนได้ มีเหตุผลที่คุณสมบัติของ FORTRAN นี้ไม่เคยซ้ำกันอีกเลย


1
ในภาษาที่คุณสามารถกำหนดตัวอักษรใหม่ได้นั่นคือตัวอย่างที่แย่ที่สุด - ฉันหมายความว่ามันทำให้ยานอวกาศตัวเล็ก ๆ ตัวหนึ่งพังได้เท่านั้น
Martin Beckett

คุณสามารถเขียน DAMNATION แทน DIMENSION และทำงานได้
Mike Dunlavey

มันยังคงถูกสอนโดยคนที่อยู่นอก CS ฉันยังต้องจัดการกับผู้ที่ก) ต่อสู้กับคำประกาศข) ต่อสู้กับช่องว่างค) เช่น "เส้นต่อเนื่อง" d) ใช้ชื่อ 6 ตัวอักษรหรือ 4, d) นิ่งงันเมื่อพวกเขาเห็น(test ? a : b)e) ยืนยัน ในการใช้**งาน f) ไม่สามารถรับมือกับตัวพิมพ์ใหญ่และเล็ก ส่วนใหญ่เป็นเพราะ keypunches ใน 50s
Mike Dunlavey

1
@Martin Beckett - การกำหนดตัวอักษรใหม่ใน FORTRAN เป็นข้อบกพร่องของคอมไพเลอร์จริงๆมากกว่าเป็นภาษา แน่นอนว่ามันไม่ใช่คุณสมบัติทางภาษาโดยเจตนา
สตีเฟ่นซี

1
@oosterwal: ฉันทำอย่างแน่นอน ฉันอาจจะผิด แต่ฉันจำคำนิยามภาษาที่คลุมเครือโดยใช้บัตรชก พวกเขาเป็นวิธีหลักในการป้อนโปรแกรม FORTRAN ย้อนหลังและแนวคิดของคอลัมน์ 80 คอลัมน์ที่มีคอลัมน์ 73-80 ที่สงวนไว้นั้นมาจากบัตรเจาะ
David Thornley

9

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

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


2
+1: ภาษาใด ๆ ที่ไม่มีโมดูลและไลบรารีที่เหมาะสมเป็นความผิดพลาดที่เกิดขึ้น ภาษาโคบอลได้รับผลกระทบจากสิ่งนี้เช่นกันซึ่งนำไปสู่ตัวแปรที่แปลกประหลาดซึ่งไม่เข้ากัน
S.Lott

8

ฉันเชื่อใน DSL (ภาษาเฉพาะโดเมน) และสิ่งหนึ่งที่ฉันให้ความสำคัญกับภาษาคือถ้ามันอนุญาตให้ฉันกำหนด DSL ที่อยู่ด้านบนของมัน

ใน Lisp มีมาโคร - คนส่วนใหญ่คิดว่านี่เป็นสิ่งที่ดีเช่นเดียวกับฉัน

ใน C และ C ++ มีมาโคร - คนบ่นเกี่ยวกับพวกเขา แต่ฉันสามารถใช้พวกเขาเพื่อกำหนด DSL

ในจาวาพวกเขาถูกละทิ้ง (และดังนั้นใน C #) และการขาดของพวกเขาถูกประกาศให้เป็นคุณธรรม แน่ใจว่ามันจะช่วยให้คุณมี IntelliSense แต่กับผมว่าเป็นเพียงผลงาน ในการทำ DSL ของฉันฉันต้องขยายด้วยตัวเอง มันเป็นความเจ็บปวดและมันทำให้ฉันดูเหมือนโปรแกรมเมอร์ที่ไม่ดีถึงแม้ว่ามันจะช่วยให้ฉันสามารถทำสิ่งต่าง ๆ ได้มากขึ้นด้วยรหัสน้อยกว่า


4
ฉันยอมรับว่าภาษาใดก็ตามที่ไม่มีมาโครที่เหมาะสมก็เป็นข้อบกพร่องที่ไม่สามารถแก้ไขได้ขนาดใหญ่ แต่คุณหมายถึง ' พวกเขาถูกทิ้ง '? ตัวประมวลผลล่วงหน้า C ไม่ใช่ระบบมาโครที่เหมาะสมชนิดใด Java ไม่ได้มาจากภาษาที่เหมาะสมกับมาโคร
SK-logic

1
คุณสามารถเขียน DSL ของคุณในภาษาการประมวลผลแมโครภายนอก (เช่น m4, พูด, ในจำนวนอื่น ๆ )
เพียงความคิดเห็นที่ถูกต้องของฉัน

4
@SK: ฉันจะไม่พูดว่า C preprocessor เป็นระบบมาโครที่ดีเมื่อเทียบกับ Lisp (ตัวอย่าง) แต่เมื่อเปรียบเทียบกับสิ่งใดมันมีประโยชน์มาก
Mike Dunlavey

4
@reierierpost: ฉันกำลังคิดถึงสิ่งที่ฉันสามารถทำได้ใน Lisp เช่นแนะนำโครงสร้างการควบคุมเช่นการดำเนินการที่แตกต่างกันและการย้อนกลับ สิ่งเหล่านี้สามารถทำได้ด้วยมาโคร Lisp ใน C / C ++ ฉันสามารถทำการแตกต่างกับ C แมโคร (และวินัยโปรแกรมเมอร์เล็กน้อย) แต่ไม่ย้อนกลับ ด้วย C # ฉันไม่สามารถทำได้ สิ่งที่ฉันได้รับจากการแลกเปลี่ยนคือสิ่งต่าง ๆ ที่เหมือน intellisense BFD
Mike Dunlavey

1
@ David: วิธีที่ฉันทำมันคือฉันมีมาโครเพื่อล้อมรอบโค้ดสามัญเช่นรายการของคำสั่ง มันจะใช้cdrรายการและสร้างแลมบ์ดาปิดมัน (เช่นความต่อเนื่อง) และผ่านมันเป็นข้อโต้แย้งไปcarยังรายการ แน่นอนว่าจะทำซ้ำและจะ "ทำสิ่งที่ถูกต้อง" สำหรับเงื่อนไขลูปและการเรียกใช้ฟังก์ชัน จากนั้นฟังก์ชั่น "ทางเลือก" ก็กลายเป็นวงปกติ ไม่สวย แต่ก็แข็งแกร่ง ปัญหาคือมันทำให้การวนซ้ำซ้อนกันง่ายสุด ๆ
Mike Dunlavey

7

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

// With statements:
node.listen(function(arg) {
  var result;
  if (arg) {
    result = 'yes';
  } else {
    result = 'no';
  }
  return result;
})

// Without:
node.listen(function(arg) if (arg) 'yes' else 'no')

ฉันสับสนที่นี่: คุณต้องการวิธีที่ง่ายกว่าในการทำสิ่งต่าง ๆ หรือไม่?
TheLQ

2
แก้ไข. การแสดงออกสำหรับทุกสิ่ง
munificent

1
เสียงกระเพื่อมทำงานได้ดีสำหรับเรื่องนี้
David Thornley

1
@ SK-logic: ฉันสงสัยว่าคำสั่งนั้นสืบทอดมาจากภาษาเครื่องผ่าน FORTRAN, ALGOL และ COBOL
David Thornley

1
ฉันค่อนข้างมั่นใจว่าภาษาเครื่องเป็นบรรพบุรุษร่วมกันและนั่นเป็นเพียงภาพสะท้อนของความจริงที่ว่าคอมพิวเตอร์สมัยใหม่ที่ใช้สถาปัตยกรรม von Neumann ดำเนินการคำสั่งตามลำดับและแก้ไขสถานะ ในที่สุดเมื่อ IO เกิดขึ้นจะมีนิพจน์ที่ไม่ให้ข้อมูลที่มีความหมายดังนั้นข้อความสั่งไม่ไร้ประโยชน์โดยสิ้นเชิงในการระบุความหมายว่าโค้ดบางตัวมีผลข้างเคียงเท่านั้น แม้แต่ภาษาที่มีความคิดunitประเภท (aka ()) แทนที่จะเป็นข้อความก็มีการพิจารณาเป็นพิเศษเพื่อให้แน่ใจว่าพวกเขาจะไม่ทิ้งคำเตือนหรือทำตัวแปลก ๆ
Rei Miyasaka

6

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


3
หนึ่งในเป้าหมายหลักของ C ++ คือการเข้ากันได้อย่างสมบูรณ์แบบย้อนหลังกับ C หากพวกเขาเปลี่ยนพฤติกรรมเชิงความหมายอย่างรุนแรงมันอาจไม่ติดเหมือนที่ทำ (หรืออย่างน้อยนั่นก็เป็นความคิดในเวลานั้น)
Ed S.

2
@Ed S. อย่างไรก็ตามการขจัดปัญหา "ห้อยต่องแต่งอย่างอื่น" สามารถทำได้โดยการกำจัด <compound_statement> (aka <block>) การผลิตทางไวยากรณ์และผสมผสานเครื่องหมายปีกกาเข้ากับโครงสร้างการควบคุมแบบมีเงื่อนไขและวนซ้ำเหมือนเมื่อพวกมันทำ เพิ่มโครงสร้างการควบคุมข้อยกเว้นการลอง / จับการจัดการ ไม่มีข้อแก้ตัวใด ๆ ที่จะไม่แก้ไขความคลุมเครือทางไวยากรณ์นี้ใน Java และ C # ขณะนี้การป้องกันเพื่อแก้ไขความคลุมเครือทางไวยากรณ์นี้คือการทำให้ทุกคำสั่งที่เป็นไปตามคำสั่งการควบคุมตามเงื่อนไขหรือซ้ำคำสั่งผสม
bit-twiddler

1
คุณหมายถึงอะไร? นี่ไม่ใช่ "ปัญหาทางไวยากรณ์" (มันไม่ชัดเจนอย่างสมบูรณ์) คุณจะ“ แก้ไข” อย่างไร? จริง ๆ แล้วฉันพบว่ากฎใน C เป็นที่น่าพอใจ มีเพียงไวยากรณ์เหมือนงูใหญ่ (= การเยื้องที่มีความหมาย) เท่านั้นที่สามารถแก้ปัญหานี้ได้ นอกจากนี้ฉันมีความสุขมากที่ภาษาสมัยใหม่ไม่ได้จัดฟัน ฉันยอมรับว่าซินแท็กซ์ของ C-like ทั้งหมดดูด แต่ dangling-else เป็นปัญหาน้อยที่สุด
Konrad Rudolph

1
ดำเนินการต่อ: ฉันคิดว่าการใช้ Python ของการเยื้องเป็นวิธีที่ใช้ในการวิเคราะห์รายการคำสั่งนั้นแปลกเกินความเชื่อ เทคนิคนี้ละเมิดหลักการ "การแยกความกังวล" โดยการสแกนคำศัพท์อย่างแน่นหนาด้วยการวิเคราะห์ไวยากรณ์ ไวยากรณ์ที่ปราศจากบริบทควรสามารถแยกวิเคราะห์ได้โดยไม่ต้องรู้อะไรเกี่ยวกับเค้าโครงของแหล่งที่มา
bit-twiddler

3
@ bit-twiddler: ไม่ไม่ได้ Python lexer เพียงแปลงช่องว่างเป็นโทเค็น INDENT และ DEDENT ที่เหมาะสม เมื่อเสร็จสิ้นแล้ว Python ก็มีไวยากรณ์ที่ค่อนข้างธรรมดา ( docs.python.org/reference/grammar.html )
dan04

6

ฉันคิดว่าคำตอบทั้งหมดชี้ไปที่ความล้มเหลวเดียวของภาษากระแสหลักจำนวนมาก:

ไม่มีวิธีการเปลี่ยนภาษาหลักโดยไม่มีผลต่อความเข้ากันได้ย้อนหลัง

ถ้านี่ถูกแก้ไขแล้วกริปเปอร์อื่น ๆ ทั้งหมดนั้นสามารถแก้ไขได้

แก้ไข

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

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


1
คุณจะไปเกี่ยวกับ "การแก้ปัญหา" นี้ได้อย่างไร
Bjarke Freund-Hansen

ฉันไม่แน่ใจว่าสามารถแก้ไขได้ทั้งหมด - ช่วยให้สิ่งต่าง ๆ ออกจากภาษาแกนกลางและในห้องสมุดมาตรฐานช่วยฉันคิดว่าฉันจะพยายามผลักดันสิ่งนี้ให้ไกลที่สุดเท่าที่จะเป็นไปได้
เจเค

1
คุณหมายถึงคอมไพเลอร์รุ่นใหม่ที่สามารถคอมไพล์โค้ดเก่าได้หรือไม่?
Rei Miyasaka

ฉันหมายถึงคอมไพเลอร์รุ่นใหม่ไม่ควรเปลี่ยนความหมายของรหัสเก่าความล้มเหลวในการรวบรวมจะเป็นชุดย่อยของ
jk

กรณีส่วนใหญ่เมื่อไม่มีคุณลักษณะเฉพาะหรือต้องการเปลี่ยนแปลงผู้คนจะสร้างภาษาใหม่โดยอิงจากภาษาก่อนหน้า C พร้อมคลาส => C ++
umlcat


4

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

เป็นตัวอย่างของสิ่งหลังพิจารณาว่า

สาธารณะคงที่ T Parse <T> (ประเภท <T> ประเภทสตริงสตริง) ที่ T: Enum
ข้างหรือแทนที่
วัตถุคงที่สาธารณะแยกวิเคราะห์ (ประเภทประเภทสตริง STR)
ในEnumชั้นเรียนจะอนุญาต
MyEnum e = Enum.Parse (typeof (MyEnum), str);
มากกว่าการพูดซ้ำซาก
MyEnum e = (MyEnum) Enum.Parse (typeof (MyEnum), str);

tl; dr: คิดเกี่ยวกับตัวแปรหลายรูปแบบเมื่อคุณเริ่มออกแบบระบบชนิดของคุณไม่ใช่หลังจากที่คุณเผยแพร่เวอร์ชัน 1


2
การที่ไม่สามารถ จำกัด ประเภทของ enum นั้นน่ารำคาญใน C # แต่คุณสามารถแก้ไขมันได้เช่นนี้MyMethod<T>(T value) where T : struct, IComparable, IFormattable, IConvertible แต่คุณยังต้องทดสอบ enum และแฮ็ค ฉันคิดว่าสิ่งที่ขาดไปมากใน C # generics นั้นไม่ได้รับการสนับสนุนจากสิ่งที่สูงกว่าซึ่งจะเปิดภาษาให้กับแนวคิดที่ยอดเยี่ยมจริงๆ
CodexArcanum

4

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

void foo()
{
    int a = 8;
    bar(a);
}

จากจุดโทรไม่มีวิธีที่จะบอกว่าbarซึ่งอาจถูกกำหนดในไฟล์ที่แตกต่างอย่างสิ้นเชิงคือ:

void bar(int& a)
{
    a++;
}

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

bar(&a);

สามารถอ่านได้มากขึ้น


+1 ฉันไม่เห็นด้วยกับคุณ แต่ฉันขอขอบคุณที่ให้เหตุผล
Jon Purdy

@ จอนจริงๆแล้วฉันสนใจในสิ่งที่คุณคิด คุณถือมุมมอง "ไม่โทษภาษา" หรือไม่
Jeff

6
@Jeff: สำหรับเหตุผลหนึ่งที่เหตุผลหลักที่ความหมายของการอ้างอิงเข้ามาใน C ++ นั้นก็คือการใช้งานตัวดำเนินการมากเกินไปซึ่งการอ้างอิงแบบสม่ำเสมอนั้นสมเหตุสมผล แม้ว่าที่สำคัญกว่านั้น C ++ ถูกออกแบบมาให้ใช้งานได้หลากหลายและให้คุณสมบัติที่ละเอียดมากแม้ว่าการทำเช่นนั้นจะทำให้เกิดความเสี่ยงที่สำคัญของข้อผิดพลาดของโปรแกรมเมอร์ อย่างน้อยก็ในกรณีนี้อย่าโทษภาษานั้น ฉันควรจะทำผิดพลาดมากกว่าปล่อยให้ภาษาเข้ามาขวางทาง
Jon Purdy

@ จอนเห็นด้วยมันจะแปลกมากสำหรับการส่งผ่านโดยการอ้างอิงเพื่อนำไปใช้กับทุกอย่างนอกเหนือจาก POD ฉันต้องการมันหากคุณสมบัตินี้หายไปจาก C ++ เป็นทางเลือก แต่เราสามารถยอมรับไม่เห็นด้วย :) ขอบคุณสำหรับการป้อนข้อมูล!
Jeff

Java ดูเหมือนจะไม่ชอบพอยน์เตอร์เท่าที่คุณทำ
Mateen Ulhaq

4

แก้ไข

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

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

อาจารย์มหาวิทยาลัยของฉันอย่างเด่นชัดกล่าวว่าถ้าเขาเคยเห็นคำพูดนั้นในโปรแกรมใด ๆ ของเราเขาจะล้มเหลวเราโดยอัตโนมัติ


มันมีกรณีการใช้งานที่ดีแม้ว่า - การขัดถูหรือการบันทึกช่วยจำ แทนที่จะเขียนv() { if (not alreadyCalculatedResult) { result = long(operation); alreadyCalculatedResult = true; } result; }คุณบอกว่าv() { result = long(operation); v = () => result; result; }
configurator

4

บาปที่เลวร้ายที่สุดของภาษาโปรแกรมไม่ได้ถูกกำหนดไว้อย่างดี กรณีที่ฉันจำได้คือ C ++ ซึ่งในต้นกำเนิด:

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

ดังที่ฉันจำได้ว่ามันใช้เวลาประมาณหนึ่งทศวรรษกว่าจะได้รับการนิยาม C ++ ที่ดีพอที่จะทำให้มันเชื่อถือได้อย่างมืออาชีพเหมือนกับ C. มันเป็นสิ่งที่ไม่ควรเกิดขึ้นอีก

มีอะไรอีกที่ฉันคิดว่าเป็นบาป (มันควรจะเป็นคำตอบที่ต่างออกไปหรือไม่) กำลังมีวิธี "ดีที่สุด" มากกว่าหนึ่งอย่างในการทำงานทั่วไป เป็นกรณีของ (อีกครั้ง) C ++, Perl, และ Ruby


1
ฉันไม่เห็นวิธีการหลีกเลี่ยงการกำหนดไม่ดีในภาษาที่กำลังพัฒนา หรือสำหรับเรื่องนั้นในภาษาที่ออกแบบไว้ล่วงหน้าซึ่งนักออกแบบดั้งเดิมพลาดจุดสำคัญบางอย่าง (เช่น Pascal)
David Thornley

@David Thornley ความชัดเจนเป็นอย่างดี ข้อบกพร่องนักออกแบบภาษาโปรแกรมส่วนใหญ่ทำให้ถูกต้องตั้งแต่เริ่มต้น เครื่องมือสามารถตรวจสอบว่าไวยากรณ์นั้นไม่คลุมเครือเมื่อมันเสร็จสมบูรณ์ (C ++ ต้องการอย่างน้อยสามไวยากรณ์) และควรระบุความหมายของการประยุกต์ใช้มาตรฐาน
Apalala

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

ฉันเดาว่าฉันมีปัญหาในการทำความเข้าใจความหมายของคำว่า "ชัดเจน" การร้องเรียนของคุณนั้นคอมไพเลอร์ C ++ ที่แตกต่างกันไม่ได้แปลภาษาเดียวกันหรือไม่?
Sean McMillan

3

คลาสใน C ++ เป็นรูปแบบการออกแบบที่บังคับในภาษา

ไม่มีความแตกต่างระหว่างรันไทม์ระหว่าง struct และคลาสและมันสับสนอย่างมากที่จะเข้าใจว่าอะไรคือข้อดีของการเขียนโปรแกรมที่แท้จริงของ "การซ่อนข้อมูล" ที่ฉันต้องการวางไว้ที่นั่น

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


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

1
UI ของ API ... ไม่เลยฉันไม่ซื้อมันอย่างจริงจัง
jokoon

3
ความแตกต่างนี้ไม่ได้เป็นส่วนที่น่ารังเกียจที่สุดของ C ++ หรือแม้แต่ใกล้เคียง ข้อแตกต่างเพียงอย่างเดียวคือตัวดัดแปลงการเข้าถึงเริ่มต้น (สาธารณะสำหรับ structs ส่วนตัวสำหรับคลาส) C ++ เป็นภาษาที่น่ากลัวและชั่วร้าย แต่ก็ไม่ได้อยู่ในส่วนนี้
SK-logic

sk-logic: เอ่อฉันบอกได้เลยว่าความน่ากลัวเริ่มต้นที่นั่น
jokoon

2
การซ่อนข้อมูลเป็นสิ่งที่ดี คุณสามารถค้นหาการสนทนาที่มีทั้งหมด หนังสือซอฟต์แวร์ที่โดดเด่นเพียงเล่มเดียวที่ฉันคิดได้ว่ามันขัดกับหนังสือเล่มนี้คือ "The Mythical Man-Month" ของบรูกส์และหลังจากนั้นเขาก็คิดว่ามันเป็นความผิดพลาดครั้งใหญ่ที่สุดในหนังสือเล่มนี้ หากคุณไม่เข้าใจข้อได้เปรียบคุณจะไม่ได้รับการตัดสินอย่างถูกต้อง
David Thornley

3

แม้ว่าทุกภาษาจะมีความผิดปกติ แต่ก็ไม่มีใครรำคาญเมื่อคุณรู้เกี่ยวกับพวกเขา ยกเว้นคู่นี้:

ไวยากรณ์ที่ซับซ้อนพร้อมกับ wordy APIs

นี่เป็นเรื่องจริงโดยเฉพาะอย่างยิ่งภาษาเช่น Objective-C ไม่เพียง แต่เป็นไวยากรณ์ที่ซับซ้อนอย่างท่วมท้น แต่ API ใช้ชื่อฟังก์ชั่นเช่น:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

ฉันทุกคนเป็นคนชัดเจนและไม่คลุมเครือ แต่มันไร้สาระ ทุกครั้งที่ฉันนั่งกับ xcode ฉันรู้สึกเหมือน n00b และมันน่าผิดหวังจริงๆ


ไวยากรณ์ Objective-C ซับซ้อนอย่างท่วมท้นหรือไม่ คุณไม่เห็น C ++ ใช่ไหม และชื่อวิธีการที่แท้จริงมีอยู่tableView:cellForRowAtIndexPath:ซึ่งเป็นคำอธิบายในความคิดของฉัน
rightfold

เรียนรู้ที่จะสัมผัสชนิด
finnw

2
  1. ตัวอักษรที่ลงนามใน C - สิ่งที่น่ารังเกียจที่คิดค้นขึ้นเพื่อให้นักคณิตศาสตร์มีคอลเล็กชั่นชิ้นเล็ก ๆ
  2. การใช้เคสเพื่อพกพาเนื้อหาเชิงความหมาย - อีกครั้งสำหรับนักคณิตศาสตร์ที่ไม่ต้องการพูดคุยและไม่มีพื้นที่เพียงพอสำหรับสูตรของพวกเขา
  3. Let / Plain assignment vs. Set assignment ในภาษาถิ่นพื้นฐาน - ไม่มีนักคณิตศาสตร์คนใดเข้ามาเกี่ยวข้องเลย

ฉันเสียความเห็นตัวอักษรที่คุณเซ็นไว้คุณช่วยอธิบายได้ไหม?
Winston Ewert

1
สำหรับมนุษย์แนวคิดของตัวอักษร (un) ที่ลงนามและความจำเป็นในการบอกคอมไพเลอร์ให้ใช้ตัวอักษรที่ไม่ได้รับการลงนามเป็นค่าเริ่มต้นแน่นอนเช่นเดียวกับนักคณิตศาสตร์ที่อ้างว่า 2! = 2 เพราะตัวที่สองเป็นตัวพิมพ์ใหญ่ หรือตัวเอียง
Ekkehard.Horner

5
ปัญหาคือ C สร้างแนวคิดของ "char" (เช่นส่วนหนึ่งของสตริงข้อความ) และ "byte" (เช่น(u)int_least8_t) การเซ็นสัญญาทำให้รู้สึกสมบูรณ์แบบสำหรับจำนวนเต็มเล็กน้อย แต่ไม่มีเหตุผลสำหรับตัวละครเลย
dan04

@ dan04: ฉันเห็นด้วยฉันหวังว่าพวกเขาจะมีประเภทที่แตกต่างกันสำหรับจำนวนเต็มขนาดเล็ก (ลงนามและไม่ได้ลงนาม), ไบต์และตัวอักษร เมื่อคุณอธิบายให้กับมือใหม่ว่าต้องจัดการกับหน่วยความจำแบบดิบพวกเขาจำเป็นต้องส่งไปยังchar*... เช่น C-String พวกเขาสับสนมาก
Matthieu M.

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