프로그래밍 언어에서 가장 큰 디자인 결함은 무엇입니까? [닫은]


29

모든 프로그래밍 언어는 다른 언어와 마찬가지로 단일 언어만으로는 완벽하지 않기 때문에 설계상의 결함이 있습니다. 프로그래밍 언어에서 어떤 디자인 결함이 프로그래머로서의 역사를 통해 가장 귀찮게 했습니까?

특정 언어를 위해 설계된 것이 아니기 때문에 언어가 "나쁜"경우에는 디자인 결함이 아니라 디자인 의 특징 이므로 언어의 성가심을 나열하지 마십시오. 언어가 설계된 언어에 적합하지 않은 경우, 이는 디자인의 결함입니다. 구현 관련 사항과 중요 사항도 포함되지 않습니다.


6
누군가 가이 질문이 얼마나 건설적인지 질문하고 싶다면 언어 디자이너 (피해야 할 실수)에 대해 건설적인 것입니다.
Anto


1
@greyfade : 실제로는 실제 언어의 결함에 관한 것이 아닙니다. 언어의 채택률을 낮추는 것, 표준 라이브러리 또는 언어에 대한 나쁜 웹 사이트가 포함될 수 있습니다. 예를 들어, 잘못된 구문과 같은 답변이 있지만 특정 설계 결함 은 아닙니다.
Anto

8
모든 프로그래밍 언어에서 가장 큰 결함이 있습니까? 인간.
Joel Etherton

이 답변이 가장 큰 결함이라면 프로그래밍 언어에 깊은 감명을받습니다.
Tom Hawtin-tackline

답변:


42

나의 큰 성가심 중 하나는 switchC 파생 언어의 사례가 사용을 잊어 버린 경우 다음 사례로 넘어가는 방식 break입니다. 나는 이것이 매우 낮은 수준의 코드 (예 : Duff 's Device ) 에서 유용 하지만 일반적으로 응용 프로그램 수준 코드에는 부적절하며 일반적인 코딩 오류 소스라는 것을 이해합니다.

나는 1995 년에 처음으로 Java의 세부 사항에 대해 읽었을 때, switch성명서 에 대한 부분에 도달했을 때 그들이 기본 추락 행동을 유지했다는 것에 매우 실망했다. 이것은 다른 이름 switch으로 영화 롭게 goto됩니다.


3
@Christopher Mahan : switch그런 식으로 작동하지 않아도됩니다. 예를 들어, Ada의 경우 / 문장 (스위치 / 케이스와 동일)에는 넘어지는 동작이 없습니다.
Greg Hewgill

2
@Greg : switchC와 관련이없는 언어의 -like 문은 그런 식으로 작동하지 않아도됩니다. 당신은 C 스타일의 제어 흐름 (사용한다면 {... }, for (i = 0; i < N; ++i), return, 등), 언어 추론은 사람들이 기대하는 것 switchC와 같은 일을하고, 에이다 / 파스칼 / BASIC 같은 의미를 혼동했을 사람들을주고. C #은 필요 breakswitch, 같은 이유로 문 차종하지만 그것은 덜 오류가 발생하기 쉬운 조용한 위해 fallthrough을 금지하여. (하지만 fall;추한 대신 쓸 수 있으면 좋겠다 goto case.)
dan04

4
그런 다음 스위치를 쓰지 말고 if ()를 쓰십시오. 당신이 불평하는 이유는 스위치를 더 좋게 만드는 이유입니다. 그것은 참 / 거짓 조건이 아니며, 조건부 숫자이며, 그것이 다르게 만듭니다. 당신은 또한 자신의 스위치 기능을 작성할 수 있습니다.
jokoon

9
-1 넘어 질 수 있다는 이점이 있다고 생각하지만 어리 석음 외에 다른 위험은 없지만 추가 기능을 부여합니다.
Orbling

11
문제는되지 않도록 switch 할 수 있습니다 위해 fallthrough. 폴 스루의 대부분의 사용은 의도적이지 않습니다.
dan04

41

나는 C 파생 언어에서 =할당과 ==평등 테스트에 사용하는 것을 정말 좋아하지 않았습니다 . 혼란과 오류의 가능성이 너무 높습니다. 그리고 ===Javascript로 시작하지 마십시오 .

:=할당과 =평등 테스트에 더 좋을 것 입니다. 의미는 오늘날과 정확히 동일 할 수 있습니다. 여기서 할당은 값을 생성하는 표현식입니다.


3
@ Nemanja Trifunovic : 나는 원래 그 제안을 생각했지만 C에서 불행한 모호성을 가지고 x<-5있습니다. C 프로그래머는 그런 종류의 공백을 용납하지 않을 것입니다 :)
Greg Hewgill

7
@Greg : 나는 선호 :===는 잊지 너무 쉬운 것입니다 때문 :이 아니라 당신이 잊지 때 (복귀하지만) 이미 경우처럼 통보 =오늘. 이것에 대한 컴파일러 경고에 감사드립니다 ...
Matthieu M.

13
필자가 사용한 거의 모든 키보드에서 ": ="는 입력하는 동안 Shift 키를 변경해야합니다. 지금 사용하고있는 것에서 ':'는 대문자이고 '='는 소문자이며 반대로 바 꾸었습니다. 나는 많은 과제를 입력하고, 타이핑 번거 로움이 필요하지 않습니다.
David Thornley

14
@David Thornley : 코드 는 작성된 것보다 여러 번 읽습니다 . "타이핑 번거 로움"에 대한 논쟁은 없습니다.
Greg Hewgill

8
@ 그레그 휴길 : 물론 글보다 더 자주 읽습니다. 그러나 사이의 문제 =와는 ==읽기, 그들은 때문에있는 거 별개의 상징이 아니다. 서면으로 작성하고 올바른 것을 얻었는지 확인하십시오.
David Thornley

29

추가문자열 연결을+ 위해 Javascript에서 선택 하는 것은 끔찍한 실수였습니다. 값은 형식이 지정되지 않으므로 각 피연산자의 정확한 내용에 따라 추가 또는 연결 여부를 결정하는 비잔틴 규칙이 발생합니다 .+

처음 $에는 문자열 연결 과 같은 완전히 새로운 연산자를 도입하는 것이 쉬웠을 것 입니다.


13
@Barry :별로. +강력한 형식의 언어로 된 문자열 연결 연산자로 의미가 있습니다. 문제는 Javascript가 그것을 사용하지만 강력하게 입력되지 않는다는 것입니다.
메이슨 휠러

13
@Mason : +연결은 확실히 정류 적이 지 않기 때문에 연결에는 의미가 없습니다. 내가 아는 한 학대입니다.
Matthieu M.

12
@ Matthieu : 음 ... 왜 중요한가요? 연결은 덧셈과 같은 방식으로 계산되지 않지만 두 문자열의 추가는 의미가 없으므로 아무도 그렇게 생각하지 않습니다. 존재하지 않는 문제를 발명하고 있습니다.
메이슨 휠러

4
C ++로 전환하고 난해한 오버로드에 원하는 연산자를 추가하십시오
Newtopian

8
@ Matthieu : 여기에서 Commutativity는 문제가되지 않습니다. JS에 Matrix 클래스가 있다면, *연산자 를 갖는 것이 남용으로 간주 됩니까?
dan04

24

JSLint 등을 사용하지 않으면 Javascript가 기본적으로 전역 문제이며, 버그의 원인이되는 경우가 많습니다.


2
기본적으로 전역? JS를 사용하지 않아서 다행입니다 ...
Anto

5
실제로 몇 가지 나쁜 디자인 선택이있는 매우 좋은 언어입니다. 변수의 범위를 지정하지 않으면 전역 범위로 지정됩니다. 좋은 점은 Doug Crockford의 Jslint 프로그램을 사용하면이 오류와 더 많은 것을 포착 할 수 있다는 것입니다.
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이며, 체처럼 누출되는 추상화를 생성하고, 쥐의 #ifdef문장을 통해 스파게티 코드를 장려하며 , ALL_CAPS그 한계를 극복하기 위해 끔찍한 읽을 수없는 이름이 필요합니다 . 이러한 문제의 근본 원인은 구문 또는 의미 수준이 아닌 텍스트 수준에서 작동한다는 것입니다. 다양한 사용 사례를 위해 실제 언어 기능으로 대체되어야합니다. 다음은 C ++, C99 또는 비공식이지만 사실상 표준 확장 으로 해결되는 몇 가지 예입니다 .

  • #include 실제 모듈 시스템으로 교체해야합니다.

  • 인라인 함수 및 템플릿 / 일반은 대부분의 함수 호출 사용 사례를 대체 할 수 있습니다.

  • 이러한 상수를 선언하는 데 일종의 매니페스트 / 컴파일 타임 상수 기능을 사용할 수 있습니다. D의 enum 확장은 여기서 잘 작동합니다.

  • 실제 구문 트리 수준 매크로는 많은 기타 사용 사례를 해결할 수 있습니다.

  • 코드 믹스 유스 케이스에 문자열 믹스 인 을 사용할 수 있습니다.

  • static if또는 version명령문을 조건부 컴파일에 사용할 수 있습니다.


2
@ dsimcha : #include문제에 동의 하지만 모듈 시스템이 발명되었습니다 ... 나중에! 그리고 C와 C ++는 최대 역 호환성을 목표로합니다 : /
Matthieu M.

@Matthieu : 그렇습니다. 모듈 시스템은 사후에 발명되었지만, 우리는 여하튼 여기서 가늠에 대해 이야기하고 있습니다.
dsimcha

3
나는 이것이 다양한 신체 부위에 엄청난 고통이라는 것에 동의하지만 멀티 패스 디자인은 단순성의 이점을 가지고 있습니다 .C 컴파일러는 C 코드 덩어리를 성공적으로 컴파일하기 전에 연산 컨텍스트에 대해 많이 알 필요가 없습니다. . C 언어 자체 (예 : C ++ 유사 클래스) 내에서 가상 모듈 시스템을 사용하는 비용이 항상 현재 cpp 기반 #include해킹 보다 낮거나 비슷하다는 것을 보여줄 수있는 경우 이는 설계 오류로만 검증 될 수 있습니다 .
reinierpost

동의한다. 그러나 일부 사람들은 전처리가 좋은 것이라고 생각하고 (예를 들어) Java에서 지원되지 않는다고 불평합니다.
Stephen C

5
@Stephen : 프리 프로세서가있는 Java가없는 Java보다 낫다는 데 동의 하지만 , Java에는 프리 프로세서를 대체하는 데 필요한 "실제"기능이 몇 가지 없기 때문 입니다. D와 같은 기능과 동적 기능을 통해 다른 방식으로 유연성을 얻는 Python과 같은 언어에서는 한 가지를 놓치지 않습니다.
dsimcha

21

수백 개의 언어로 수백 개의 실수를 나열 할 수 있지만 IMO는 언어 설계 관점에서 유용한 연습이 아닙니다.

왜?

한 언어에서 실수가 된 것이 다른 언어에서는 실수가 아니기 때문입니다. 예를 들어 :

  • C를 관리되는 (즉, 가비지 수집 된) 언어로 만들거나 기본 유형을 묶는 것은 반 휴대형 저수준 언어로서의 유용성을 제한합니다.
  • C 스타일 메모리 관리를 Java에 추가하면 (예 : 성능 문제를 해결하기 위해) 깨뜨릴 수 있습니다.

있는 역사적 맥락이 배워야 할 교훈은,하지만 수업은 거의 명확한, 그리고 그들을 이해하는 당신은 기술적 인 장단점을 이해해야 ...합니다. 예를 들어 번거로운 Java 제네릭 구현은 이전 버전과의 호환성을 유지하기 위해 비즈니스 요구 사항재정 의 한 결과입니다 .

IMO, 새로운 언어 디자인에 대해 진지하게 생각한다면 실제로 는 광범위한 기존 언어를 사용 하고 (역사를 연구) 실수가 무엇인지 스스로 생각해야합니다. 또한 이러한 각 언어는 특정 요구 사항을 충족시키기 위해 특정 역사적 맥락에서 설계되었다는 점을 명심해야합니다.

배워야 할 일반적인 교훈이 있다면 "메타"수준입니다.

  • 모든 목적에 이상적인 프로그래밍 언어를 설계 할 수는 없습니다.
  • 실수를 피할 수는 없습니다. 특히 뒤에서 볼 때 특히 그렇습니다.
  • 귀하의 언어 사용자를 위해 많은 실수를 고치기가 어렵습니다.
  • 대상 고객의 배경과 기술을 고려해야합니다. 즉, 기존 프로그래머.
  • 모두를 기쁘게 할 수는 없습니다.

9
-1-프로그래밍 언어는 디자인 목표를 따릅니다. 이러한 목표에 맞서는 언어의 특징은 다른 목표 중 하나에 필요한 타협이 아닌 한 설계상의 결함입니다. 모든 사람을 만족시키기위한 언어는 많지 않지만, 모든 언어는 처음에 만족시키기 시작한 사람들을 만족 시키려고 노력해야합니다. 이런 종류의 포스트 모더니즘 적 정치적 정확성은 프로그래밍 언어 연구와 개발에 상당히 걸림돌입니다.
Rei Miyasaka

내 목표는 디자인 목표를 고려하지 않고 수업을 배우기가 어렵다는 것입니다.
Stephen C

1
OP가 이미 질문의 두 번째 단락에서 귀하의 답변을 설명 한 것으로 보입니다.
Aidan Cully

20

C and C ++ : 아무것도 의미 하지 않는 모든 정수 유형 .

특히 char. 텍스트입니까 아니면 작은 정수입니까? 텍스트 인 경우 "ANSI"문자입니까, 아니면 UTF-8 코드 단위입니까? 정수인 경우 부호가 있거나 부호가 없습니까?

int "네이티브"크기의 정수로 의도되었지만 64 비트 시스템에서는 그렇지 않습니다.

long보다 크거나 같지 않을 수 있습니다 int. 포인터의 크기 일 수도 있고 아닐 수도 있습니다. 컴파일러 작성자가 32 비트인지 64 비트인지에 대해 거의 임의의 결정입니다.

1970 년대의 언어. 유니 코드 이전. 64 비트 컴퓨터 이전.


10
C는 모든 언어에 맞는 표준으로 설계되지 않았으므로 설계 오류가 될 수 없습니다. CPU 관련 어셈블러 코드를 피하면서 휴대용 어셈블러로 CPU를 모델링하도록 설계되었습니다. 그러나 Java로 수정되었습니다.

7
역사상 우리에게 끔찍한 아이디어가 있음에도 불구하고 더 큰 문제는 동일한 의미가없는 용어를 계속 사용하는 새로운 언어라고 생각합니다. 적어도 C 사람들은 실수를 발견하고 표준 int 유형을 만들었습니다.
Mark H

5
문자는 utf-8 단위가 아닙니다. utf-8 문자는 저장하는 데 8 비트 이상이 걸릴 수 있습니다. C는 1970 년대의 언어가 아니며, 현재 (자발적으로) 프로젝트에 사용하고 있습니다.
dan_waterworth

4
C는 PDP-11 프로세서의 고급 추상화에 지나지 않습니다. 예를 들어, 사전 및 사후 증분은 PDP-11에 의해 직접 지원되었습니다.
비트 트위 들러

5
이것은 끔찍한 오답입니다. 먼저, C와 C ++는 서로 호환되지 않습니다. 둘째, 언어 사양은 char가 무엇인지 명확하게 정의합니다. char 유형으로 선언 된 객체는 기본 실행 문자 집합의 모든 구성원을 저장할 수있을만큼 큽니다. . 셋째, C는 "70 년대의 언어"가 아니며, 하드웨어에 가까운 언어이며 아마도 모든 고급 추상화가 실제로 CPU에 의미가있는 언어 일 것입니다. 고급 언어 만 알고 실제로 작동하는 방식에 대한 인식이없는 사람으로 출발합니다. -1
Ed S.

18

null.

발명가 토니 호 아레 (Tony Hoare)는 이를 "십억 달러의 실수"라고 부릅니다 .

ALGOL은 60 년대에 소개되었으며 오늘날 가장 일반적으로 사용되는 프로그래밍 언어로 존재합니다.

OCaml 및 Haskell과 같은 언어에서 사용되는 더 나은 대안은 아마도 입니다. 일반적으로 객체 참조는 명시 적 표시가없는 한 null / empty / 존재하지 않을 수 없습니다.

(토니는 겸허 한 태도를 보였지만 거의 모든 사람이 같은 실수를 저지른 것 같습니다.


발명가와도 동의하지 않습니다 !!! null은 포인터 / 참조 데이터 유형의 빈 값입니다. 문자열은 빈 문자열, 세트는 빈 세트 (Pascal empty set = []), 정수는 0을 갖습니다. 변수가 올바르게 할당 된 경우 null / nil /을 사용하는 대부분의 프로그래밍 언어는 null 오류를 방지 할 수 있습니다.
umlcat

4
@ user14579 : 모든 종류의 집합 또는 문자열 또는 배열을 지원하는 모든 언어에는 {}가 있지만, 이는 의미 적으로 적절하며 이미 배열 경계 오류를 일으킬 수있는 것이 없다면 충돌하지 않습니다. 그러나 그것은 또 다른 문제입니다. 빈 문자열을 처리하여 모든 문자를 대문자로 만들면 빈 문자열이됩니다. null 문자열에서 같은 것을 시도하면 적절한 고려가 없으면 충돌이 발생합니다. 문제는 이러한 적절한 고려가 지루하고 종종 잊혀지고 단일 표현 함수 (람다)를 작성하는 것이 어렵다는 것입니다.
Rei Miyasaka

1
null을 입력 할 때마다 돈을 버는 것입니다. 이번 만 빼고
kevpie

3
@umlcat-Ocaml, Haskell 및 F #과 같은 패턴 일치 언어가있는 경우 Maybe x | None 패턴은 컴파일 타임에 null을 잊어 버리지 못하게합니다. 널이 확립 된 관용구 인 언어에서는 컴파일 타임 속임수가 얼마든지 오류를 잡을 수 없습니다. Maybe와 Some 모나드가있는 언어에서는 널 (null) 대소 문자를 처리하지 않기로 명시 적으로 선택해야하므로 "null"방식에 비해 심각한 이점이 있습니다.
JasonTrue

1
@Jason maybe-null 옵트 인 으로 생각 하고 null 예외는 옵트 아웃입니다. 물론 런타임 오류와 컴파일 타임 오류의 차이점에 대해서도 언급해야 할 것이 있지만 null이 본질적으로 동작을 주입한다는 사실 자체가 주목할 만합니다.
Rei Miyasaka

14

PHP를 디자인 한 사람들은 일반 키보드를 사용하지 않았고 콜막 키보드를 사용하지 않는다는 느낌이 들었습니다.

저는 PHP 개발자입니다. PHP는 입력하기가 재미 있지 않습니다.

Who::in::their::right::mind::would::do::this()? ::연산자 들고 이동하고 두 개의 키 누름을 필요로한다. 에너지 낭비 야

비록->이->-> 아무-> 더 낫다. 또한 두 심볼 사이에 시프트가있는 세 번의 키 누름이 필요합니다.

$last = $we.$have.$the.$dumb.'$'.$character. 달러 기호는 엄청나게 사용되며 키보드 상단까지의 어워드 스트레치와 Shift 키 누름이 필요합니다.

입력 속도가 훨씬 빠른 키를 사용하도록 PHP를 설계 할 수없는 이유는 무엇입니까? 왜 we.do.this()vars가 단일 키 누르기 만 필요하거나 전혀 아님 (JavaScript) 키로 시작 하지 못하고 모든 var를 미리 정의해야합니까 (어쨌든 E_STRICT를 위해 해야하는 것처럼)!

나는 타이피스트가 느리지 않습니다. 그러나 이것은 단지 절름발이 디자인 선택입니다.


펄은이 고통을 공유한다.
Daenyth

2
C ++과 설명 할 수없는 기이 한 이유로 PowerShell도 마찬가지입니다.
Rei Miyasaka

2
보다 강력한 편집기를 사용하고 해당 연산자에 대한 고유 한 키 시퀀스를 정의하십시오.
케빈 클라인

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

1
쿼티 키보드를 사용하지 않을 수도 있습니다. $ 및 : 키보드와 같은 모든 아제 라이트에서 Shift 키를 누르지 않아도됩니다.
Arkh

13

asp.net 내 데스크탑 기반 양식 사용 .

그것은 항상 퍼지를 느꼈고 웹이 실제로 작동하는 방식이나 방식에 들어갔습니다. 고맙게도 asp.net-mvc는 같은 방식으로 고통받지 않지만 Ruby 등의 영감을 얻었습니다.


18
도서관이 아닌가?
Nikie

좋은 점이다 @nikie)
비둘기

1
@nikie 실제로 XML 기반 ASPX 코드는 언어이므로이 코드를 비틀어 작동시킬 수 있습니다. : D
CodexArcanum

2
ASP.NET의 실제 문제는 프로그래머가 웹의 세부 정보를 숨기려는 것이 얼마나 어려운 가라고 생각합니다. 실제로 ASP.NET에는 정말 깔끔하고 유용한 것들이 있지만 너무 열심히 싸워서 깊이 파고 들어야합니다.
CodexArcanum

1
반면에 "클래식"데스크톱 앱을 사용하여 결합한 단순하고 성공적인 데이터 수집 앱은 수천만 개가 있습니다. 유일한 나쁜 점은 MVC 이전까지 유일한 Microsoft 옵션은 Windows 양식이었습니다.
ElGringoGrande

13

나에게 그것은 표준 라이브러리에서 PHP 의 이름 지정 및 인수 순서 규칙이 절대적으로 부족합니다.

하지만 JASS 참조 된 개체 후 무효 참조의 필요성이 제거 / 출시 된 (또는 참조가 누출 것이다 메모리의 여러 바이트가 손실됩니다) 더 심각한이지만, JASS 단일 목적의 언어이기 때문에, 그 중요하지 않습니다.


9
PHP의 stdlib에 규칙이 없다는 것은 언어 설계 결함이 아니라는 주장 입니다.

3
@delnan : 규칙이 없기 때문에 PHP가 어떻게 설계 되었는가에 따라 언어 설계와 많은 관련이 있습니다. 또한 라이브러리와 언어 사이에 명확한 구분이 있다는 것이 분명하지 않습니다. 특히 Lisp은 한 언어를 다른 언어 위에 부트 스트랩하는 자랑스러운 전통을 가지고 있습니다.
btilly

1
JASS에 대한 진정으로 주목할만한 점은 핸들에 대한 참조 카운트가 있었지만 수동으로 파괴되지 않는 한 (그리고 그래픽 인터페이스가 모든 곳에서 메모리를 누출시키는 기능을 생성하지 않았다면) 정리하지 않을 것이라는 점입니다!
Craig Gidney

13

내가 직면 한 가장 큰 디자인 결함은 파이썬이 파이썬 3.x와 같이 처음부터 설계되지 않았다는 것입니다.


1
음, Guido조차도 모든 것을 한 번에 바로 얻을 수있는 것은 아닙니다 .

5
@delnan, 아 알다시피 python <3은 여전히 ​​굉장히 좋은 언어이지만 python 3.x의 형태로 더 나은 언어를 사용하는 것은 좋지 않습니다. 난 필요해.
dan_waterworth

파이썬 3.x 모듈을 계속 로비하십시오! 한편 나는 2.5.4로 계속 쓸 것이다. SO 덕분에 실제로 3.x가 살아 있고 잘 작동합니다.
kevpie

@kevpie 먼저 로비는 라이브러리 관리자가 쉽게 전환 할 수 있도록 조건부 컴파일을 파이썬에 추가합니다. 2to3은 장기적으로 유지 관리 가능한 솔루션이 아닙니다.
Evan Plaice

12

C에서 배열 붕괴 및 결과적으로 C ++.


적절한 배열 지원을 원합니다. C ++에서 당신은 abscons 구문과 템플릿을 사용하여 부패 방지 할 수 있습니다 ...하지만 그것은 더 해킹의 : /
마티유 M.

1
이 C ++ 별도 가져야하는 이유입니다 주 deletedelete[]운영자가.
dan04

배열을 구조체에 넣고 원하는 경우 값으로 전달할 수 있지만 일반적으로 원래 문제보다 더 어색합니다. C ++에서는 일반적으로 배열을 사용할 필요가 없습니다.
David Thornley

2
적어도 C의 경우에, 적절한 배열 지원에 대한 논쟁은 특히 C 포인터 산술이 작동하는 방식을 고려할 때 "배열 범위 검사 비용이 비싸다"입니다.
Stephen C

@Stephen C : 배열의 붕괴와 관련된 배열 경계 검사는 무엇입니까?
Nemanja Trifunovic

11

Java의 기본 유형.

그것들은 모든 것이 자손이라는 원칙을 깨뜨 렸는데 java.lang.Object, 이는 이론적 관점에서 언어 사양의 추가 복잡성을 초래하고 실제적인 관점에서 컬렉션의 사용을 매우 지루하게 만듭니다.

오토 박싱 (Autoboxing)은 실제 단점을 완화하는 데 도움이되었지만 사양을 더욱 복잡하게 만들고 큰 뚱뚱한 바나나 스킨을 도입하는 비용으로 이제 간단한 산술 연산에서 null 포인터 예외를 얻을 수 있습니다.


기본 유형을 제거하면 심각한 성능 문제가 발생할 수 있습니다. 그리고 오토 박싱은 매우 쉽게 엉망이 될 수 있으므로 아무것도 개선되지 않습니다.
deadalnix 2018 년

당시, 이것은 Java 디자이너의 합리적인 결정이었습니다. 90 년대에 사용할 수있는 머신 / VM이 주어 졌을 때의 성능 향상은 java.lang.Object 주변의 모든 것을 단일화하는 것의 개념적 장점을 능가했습니다.
mikera

10

나는 Perl을 가장 잘 알고 있으므로 그것을 고를 것이다.

펄은 많은 아이디어를 시도했다. 일부는 좋았습니다. 일부는 나빴다. 일부는 독창적이며 합당한 이유로 널리 복사되지 않았습니다.

하나는 컨텍스트 라는 개념입니다. 모든 함수 호출은 목록 또는 스칼라 컨텍스트에서 발생하며 각 컨텍스트에서 완전히 다른 작업을 수행 할 수 있습니다. http://use.perl.org/~btilly/journal/36756 에서 지적했듯이 이것은 모든 API를 복잡하게 만들고 종종 Perl 코드에서 미묘한 디자인 문제를 유발합니다.

다음은 구문과 데이터 유형을 완전히 묶는 아이디어입니다. 이는 객체가 다른 데이터 유형으로 가장 할 수 있도록하는 넥타이의 발명으로 이어집니다. (과부하를 사용해도 동일한 효과를 얻을 수 있지만 Perl에서는 타이가 더 일반적입니다.)

여러 언어로 인한 또 다른 일반적인 실수는 어휘보다는 동적 범위 지정을 제공하는 것입니다. 이 설계 결정을 나중에 되 돌리는 것은 어렵고 오래 지속되는 사마귀로 이어집니다. Perl에서 이러한 사마귀에 대한 일반적인 설명은 http://perl.plover.com/FAQs/Namespaces.html 입니다. 이것은 Perl이 our변수와 static변수를 추가하기 전에 작성되었습니다 .

사람들은 정적 입력과 동적 입력에 대해 합의에 동의하지 않습니다. 나는 개인적으로 다이나믹 한 타이핑을 좋아합니다. 그러나 오타를 잡을 수 있도록 충분한 구조를 갖추는 것이 중요합니다. Perl 5는이 작업을 엄격히 수행합니다. 그러나 Perl 1-4는 이것을 잘못 알고 있습니다. 다른 여러 언어에는 엄격한 것과 동일한 기능을하는 린트 체커가 있습니다. 보푸라기 검사를 시행하는 것이 좋다면 가능합니다.

더 나쁜 아이디어 (많은 아이디어)를 찾고 있다면 PHP를 배우고 그 역사를 연구하십시오. 내가 가장 좋아하는 과거의 실수 (많은 보안 허점으로 인해 수정되었습니다)는 기본적으로 양식 매개 변수를 전달하여 변수를 설정할 수 있도록 기본 설정되어있었습니다. 그러나 그것은 유일한 실수와는 거리가 멀다.


5
사실, Perl은 많은 실수를 겪었습니다. 왜냐하면 그것을 만든 사람들은 새로운 아이디어를 시도하고 있었고, 그렇게 할 때 종종 잘못 생각하기 때문입니다. (Perl은 또한 아주 좋은 것들을 가지고 있으며 다른 사람들이 복사 한 것으로 보이는 정규 표현식의 표준입니다)
Zachary K

@ zachary-k : 물론 동의했습니다. 그리고 나는 문제를 겪기 전에 그것을 분명히하려고 노력했다.
btilly

4
Lisp는 원래 동적으로 범위가 지정되었으며 시간이 지남에 따라 어휘 범위가 변경되었습니다 (적어도 Scheme 및 Common Lisp). 변경할 수 없습니다.
David Thornley

4
@ david-thornley : 이전 버전과의 호환성을 희생하지 않으면 불가능합니다. 체계는 항상 어휘 범위가 지정되었습니다. 커먼 리스프는 표준화 된 시점부터 어휘 적으로 범위가 정해졌지만, 다양한 리스프 커뮤니티는 그것을 채택하는 데 어려움을 겪었습니다. 그리고 Emacs Lisp는 오랫동안 그것을 바꾸고 자했지만 여전히 동적 범위 지정을 사용하고 있습니다.
btilly

1
BTW, 사람들이 Perl을 싫어하는 많은 것들이 Perl에서 발명 된 것이 아니라 다른 언어, 주로 Bourne 쉘에서 취해졌습니다.
reinierpost

10

코드 블록 및 객체 리터럴에 대한 JavaScript 모호성.

  {a:b}

코드 블록 일 수 있으며, 여기서 a레이블과 b표현식입니다. 또는 a값을 가진 속성으로 객체를 정의 할 수 있습니다.b


나는 실제로 JavaScript에 대해 이것을 좋아합니다. 언어 구조의 단순성은 훌륭하며 개발자가 자신이하는 일을 알고 있다면 그 목적이 분명해야합니다.
Xeoncross

2
제온 크로스 : 나는 일반적으로 모호성을 싫어한다. 이 경우 개발자에게는 분명하지만 eval ()에는 추가 괄호가 필요합니다.
user281377

2
@ ammoQ : 분명해? 그때는 무엇입니까? 객체 또는 코드 블록?
구성자

구성자 : 분명히 객체입니다. 제정신의 사람은이라는 라벨을 사용하지 않습니다 a.
user281377

10

FORTRAN으로 돌아가고 공백은 둔감합니다.

그것은 사양을 만회했다. 이 END카드는 7-72 ​​열에서 'E', 'N'및 'D'의 순서로 카드로 정의되어야하며 적절한 "END"카드가 아닌 다른 비 공백이 없습니다. 열과 다른 것.

그것은 쉬운 구문 혼동을 초래했다. DO 100 I = 1, 10는 루프 제어문 이었지만 DO 100 I = 1. 10, 변수 1.1에 값 1.1을 할당 한 명령문이었습니다 DO10I. (변수를 선언하지 않고 만들 수 있다는 사실, 첫 글자에 따른 유형)에 기여했습니다. 다른 언어와 달리 공백을 사용하여 명확성을 기하기 위해 토큰을 분리 할 방법이 없었습니다.

또한 다른 사람들이 정말 혼란스러운 코드를 작성할 수있게했습니다. FORTRAN의이 기능이 다시는 복제되지 않은 이유가 있습니다.


1
최악의 예인 리터럴을 재정의 할 수있는 언어에서는 작은 우주선 하나만 충돌 한 것입니다
Martin Beckett

초기에는 DIMENSION 대신 DAMNATION을 쓸 수 있었고 작동했습니다.
Mike Dunlavey

CS 외부의 사람들이 여전히 가르치고 있습니다. 나는 여전히 a) 선언과의 싸움, b) 공백과의 싸움, c) "연속 선"과 같은 것, d) 6 자 이름 사용, 또는 4, d) 그들이 볼 때 뭉개지는 사람들을 처리 (test ? a : b)해야한다. **f 를 사용 하면 f) 대소 문자 구분을 처리 할 수 ​​없습니다. 이것의 대부분은 50 년대의 키펀치 때문이었습니다.
Mike Dunlavey

1
@Martin Beckett-FORTRAN에서 리터럴을 재정의하는 것은 실제로 언어 기능이 아니라 컴파일러 결함이었습니다. 의도적 인 언어 기능은 아니 었습니다.
Stephen C

1
@oosterwal : 확실히 했어요. 틀릴 수도 있지만 펀치 카드를 기반으로 한 언어 정의를 모호하게 기억합니다. 그것들은 당시 FORTRAN 프로그램을 입력하는 주요 방법이었으며 73-80 열이있는 80 열 줄의 아이디어는 펀치 카드에서 나온 것입니다.
David Thornley

9

BASIC의 가장 큰 문제 중 하나는 초기 환경을 넘어 언어를 확장 할 수있는 잘 정의 된 방법이 없다는 것인데, 이는 완전히 호환되지 않는 구현들 (그리고 표준화에서 거의 관련이없는 사후 시도)을 초래합니다.

거의 모든 언어는 미친 프로그래머가 범용으로 사용하게됩니다. 미친 아이디어가 떠오를 경우 처음에는 일반적인 용도로 계획하는 것이 좋습니다.


2
+1 : 적절한 모듈과 라이브러리가없는 언어는 실수를 기다리고 있습니다. COBOL은 이로 인해 호환되지 않는 독특한 변형을 초래했습니다.
S.Lott

8

나는 DSL (도메인 특정 언어)을 믿고 언어에서 내가 중요하게 생각하는 것은 DSL을 정의 할 수 있는지 여부입니다.

Lisp에는 매크로가 있습니다. 대부분의 사람들이 나처럼 이것을 좋은 것으로 간주합니다.

C와 C ++에는 매크로가 있습니다. 사람들은 그것에 대해 불평하지만 DSL을 정의하는 데 사용할 수있었습니다.

자바에서는 그것들이 빠져 있었고 (따라서 C #에서는) 미결 한 것으로 선언되었습니다. 물론 그것은 당신이 지능을 가질 수있게하지만, 나에게 그것은 단지 oeuvre 입니다. DSL을 수행하려면 직접 확장해야합니다. 그것은 고통스럽고 코드를 적게 사용하여 훨씬 더 많은 것을 할 수 있지만 나쁜 프로그래머처럼 보이게합니다.


4
적절한 매크로가없는 언어는 수정 불가능한 디자인 결함 중 하나라는 데 동의합니다. 그러나 ' 그들이 빠졌다 ' 것은 무엇을 의미 합니까? C 전처리 기는 어떤 종류의 괜찮은 매크로 시스템이 아니 었습니다. Java는 매크로가있는 적절한 언어에서 파생되지 않습니다.
SK-logic

1
외부 매크로 처리 언어로 DSL을 작성할 수 있습니다 (예 : m4 등).
저의 정확한 의견 그냥

4
@ SK : C 전처리 기가 Lisp에 비해 괜찮은 매크로 시스템이라고는 말할 수 없습니다 (예 :). 그러나 아무것도 아닌 것과 비교하면 매우 유용합니다.
Mike Dunlavey 2016 년

4
@reinierpost : 차동 실행 및 역 추적과 같은 제어 구조를 도입하는 것과 같이 Lisp에서 할 수있는 일을 생각하고 있습니다. 이들은 Lisp 매크로로 수행 할 수 있습니다. C / C ++에서는 C 매크로 (및 약간의 프로그래머 원칙)를 사용하여 차등 실행을 수행 할 수 있지만 역 추적은 할 수 없습니다. C #을 사용하면 둘 다 할 수 없습니다. 내가 교환하는 것은 지능과 같은 것입니다. 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
Lisp는 이것을 위해 잘 작동합니다.
David Thornley

1
@ SK-logic : FORTRAN, ALGOL 및 COBOL을 통해 기계어에서 문장이 맹목적으로 상속 된 것으로 보입니다.
David Thornley

1
나는 기계어가 공통 조상이라고 확신하며, 폰 노이만 아키텍처 기반의 현대 컴퓨터는 명령을 순차적으로 실행하고 상태를 수정한다는 사실을 반영합니다. 궁극적으로 IO가 발생하면 의미있는 데이터를 생성하지 않는 표현식이 있으므로 일부 코드에는 부작용이 있음을 의미 적으로 나타내는 데 문장이 의미가 없습니다. 문장 대신 unit유형 (aka ()) 의 개념을 가진 언어조차도 경고를 던지거나 다르게 행동하지 않도록 특별히 고려해야합니다.
Rei Miyasaka

6

저에게는 C에서 파생 된 모든 언어를 괴롭히는 것이 디자인 문제입니다. 즉, " dangling else " 입니다 . 이 문법 문제는 C ++에서 해결되었지만 Java 및 C #으로 수행되었습니다.


3
C ++의 핵심 목표 중 하나는 C와 완전히 역 호환되는 것이 었습니다. 시맨틱 동작이 급격히 변경된 경우에는 그랬던 것처럼 (또는 적어도 당시에는 생각했던 것) 잡히지 않았을 수 있습니다.
Ed S.

2
그러나 @Ed S.는 <compound_statement> (일명 <block>) 문법 생성을 제거하고 중괄호를 조건부 및 반복적 제어 구조에 통합함으로써 "dangling else"문제를 제거 할 수있었습니다. try / catch 예외 처리 제어 구조를 추가했습니다. Java와 C #에서이 문법적 모호성을 수정하지 않을 이유는 없습니다. 현재이 문법적 모호성에 대한 방어적인 해결책은 조건부 또는 반복 제어문 다음에 나오는 모든 명령문을 복합 명령문으로 만드는 것입니다.
비트 트위 들러

1
그게 무슨 뜻 이니? 이것은 "문법 문제"가 아닙니다 (완전히 모호하지 않습니다). 어떻게 그것을 "해결"하시겠습니까? 실제로 C 규칙이 만족 스럽습니다. 논란의 여지가 있지만, 파이썬과 같은 구문 (= 의미있는 들여 쓰기)만으로이 문제를 해결할 수 있습니다. 또한 현대 언어가 중괄호를 의무화 하지 않는다는 것이 실제로 매우 기쁩니다 . 나는 모든 C와 같은 구문이 빠르지 만 매달려 있지만 다른 문제는 가장 적다는 데 동의합니다.
Konrad Rudolph

1
계속 : 나는 파이썬이 문장 목록을 묘사하는 수단으로 들여 쓰기를 사용하는 것이 믿는 것 이상으로 이상하다고 생각합니다. 이 기술은 어휘 스캐닝과 구문 분석을 밀접하게 결합하여 "관심 분리"원칙을 위반합니다. 문맥없는 문법은 소스의 레이아웃에 대해 전혀 몰라도 구문 분석 할 수 있어야합니다.
bit-twiddler

3
@ bit-twiddler : 아니요. 그렇지 않습니다. Python lexer는 공백을 적절한 INDENT 및 DEDENT 토큰으로 변환합니다. 일단 완료되면 파이썬은 매우 일반적인 문법을 가지고 있습니다 ( docs.python.org/reference/grammar.html ).
dan04

6

지금까지의 모든 대답은 많은 주류 언어의 단일 실패를 지적한다고 생각합니다.

이전 버전과의 호환성에 영향을주지 않고 핵심 언어를 변경할 수있는 방법이 없습니다.

이것이 해결되면 다른 모든 그립을 거의 해결할 수 있습니다.

편집하다.

이것은 서로 다른 네임 스페이스를 사용하여 라이브러리에서 해결할 수 있으며 언어의 대부분의 핵심에 대해 비슷한 것을 수행 할 수 있지만 여러 컴파일러 / 통역을 지원해야 할 수도 있습니다.

궁극적으로 나는 완전히 만족스러운 방법으로 그것을 해결하는 방법을 모른다고 생각하지만 해결책이 존재하지 않거나 더 이상 할 수 없다는 것을 의미하지는 않습니다.


1
이 문제를 "해결"하는 방법은 무엇입니까?
Bjarke Freund-Hansen

나는 확실히 그것을 완전히 해결 될 수 아니에요 - 나는 끝까지 수 있기 때문에이 밀어하려고 거라고 생각 때문에 분명히 도움이되는 핵심 언어에서와 표준 라이브러리에 물건을 유지
JK.

1
이전 버전과 호환되므로 최신 컴파일러가 이전 코드를 컴파일 할 수 있어야합니까?
Rei Miyasaka

나는 새로운 컴파일러는 그 일부가 될 것입니다 컴파일에 실패, 이전 코드의 의미를 변경해서는 안 의미
JK.

대부분의 경우 특정 기능이 존재하지 않거나 변경하려는 경우 사람들은 이전 기능을 기반으로 새로운 언어를 만듭니다. 클래스가있는 C => C ++
umlcat 18.54의


4

Java와 C # 모두 제네릭을 추가하면서 이전 버전과의 호환성을 유지하려는 요구로 인해 유형 시스템에 성가신 문제가 있습니다. Java는 제네릭과 배열을 혼합하는 것을 좋아하지 않습니다. C #에서는 값 형식을 범위로 사용할 수 없으므로 유용한 서명을 허용하지 않습니다.

후자의 예로써,

public static T Parse <T> (Type <T> 유형, 문자열 str) 여기서 T : Enum
나란히 또는 교체
공용 정적 객체 구문 분석 (유형, 문자열 str)
에서 Enum클래스 허용 것
MyEnum e = Enum.Parse (typeof (MyEnum), str);
긴장 론보다는
MyEnum e = (MyEnum) Enum.Parse (typeof (MyEnum), str);

tl; dr : 버전 1을 게시 한 후가 아니라 유형 시스템 설계를 시작할 때 파라 메트릭 다형성에 대해 생각하십시오.


2
형식을 열거 형으로 제한 할 수 없다는 것은 C #에서 성가 시지만 이런 식으로 해결할 수는 있지만 MyMethod<T>(T value) where T : struct, IComparable, IFormattable, IConvertible 여전히 열거 형을 테스트해야하며 해킹입니다. 나는 C # 제네릭에 더 큰 부족이 더 높은 종류를 지원하지 않는다고 생각합니다.
CodexArcanum

4

나는 화를 내기 위해 자신을 열어 놓은 것처럼 느껴지지만 C ++에서 참조로 일반 오래된 데이터 유형을 전달하는 기능이 정말로 싫어합니다. 나는 복잡한 유형을 참조로 전달하는 것이 약간 싫어. 함수를보고 있다면 :

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

호출 지점부터는 bar완전히 다른 파일로 정의 될 수있는 다음과 같은 방법을 알 수 없습니다.

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

어떤 사람들은 이와 같은 일을하는 것이 나쁜 소프트웨어 디자인 일 뿐이고 언어를 비난하지는 않을 것이라고 주장 할 수도 있지만, 그 언어로 인해 처음부터 이것을 할 수있는 것은 마음에 들지 않습니다. 포인터 사용 및 호출

bar(&a);

훨씬 더 읽기 쉽습니다.


+1 나는 당신에 동의하지 않지만, 당신의 추론에 감사드립니다.
Jon Purdy

@Jon 나는 실제로 당신이 생각하는 것에 매우 관심이 있습니다. "언어를 비난하지 마십시오"라는 견해를 가지고 있습니까?
제프

6
@Jeff : 한 가지 이유는, 참조 시맨틱이 C ++로 들어간 주요 이유는 연산자 오버로딩인데, 이는 균일 한 참조 동작이 단순히 의미가 있습니다. 더 중요한 것은 C ++은 프로그래머 오류가 발생할 위험이 크 더라도 다목적으로 설계되고 세밀한 기능을 제공 한다는 점입니다. 예, 적어도이 특별한 경우에는 언어를 비난하지 마십시오. 차라리 언어가 방해를받는 것보다 실수를 저지를 수 있습니다.
Jon Purdy

@Jon은 POD 이외의 모든 것에 적용하기 위해 참조로 전달하는 것이 매우 이상하다고 동의했다. 이 기능이 대안으로 C ++에서 완전히 누락 된 경우 선호하지만 동의하지 않을 수도 있습니다 :). 입력 주셔서 감사합니다!
Jeff

Java는 당신만큼 포인터를 좋아하지 않는 것 같습니다.
Mateen Ulhaq

4

바꾸다

COBOL을 배울 때 ALTER 문 은 여전히 ​​표준의 일부였습니다. 간단히 말해서이 명령문을 사용하면 런타임 동안 프로 시저 호출을 수정할 수 있습니다.

위험하지 않은 코드 부분에이 문장을 넣을 수 있으며 나머지 프로그램의 흐름을 완전히 바꿀 가능성이 있습니다. 여러 ALTER 문을 사용하면 어느 시점에서 프로그램이 무엇을했는지 알기가 거의 불가능합니다.

저의 대학 강사는 매우 강조하면서 어떤 프로그램에서라도 그 진술을 본다면 자동으로 우리를 끌어들일 것이라고 말했습니다.


스텁 또는 메모와 같은 유용한 사용 사례가 있습니다. 대신 쓰는 v() { if (not alreadyCalculatedResult) { result = long(operation); alreadyCalculatedResult = true; } result; }v() { result = long(operation); v = () => result; result; }
피규

4

프로그래밍 언어의 최악의 죄는 잘 정의되어 있지 않습니다. 내가 기억하는 경우는 C ++이며 그 기원은 다음과 같습니다.

  1. 다음 책이나 예제를 통해 프로그램을 컴파일하고 실행할 수 없도록 잘못 정의되어 있습니다.
  2. 하나의 컴파일러와 OS에서 컴파일하고 실행하도록 프로그램을 조정 한 후에는 컴파일러 나 플랫폼을 전환 한 경우 다시 시작해야합니다.

내가 기억 하듯 이 C ++를 C만큼 전문적으로 신뢰할 수 있도록 C ++을 충분히 정의 하는 데 약 10 년이 걸렸 습니다.

내가 생각하는 다른 것 (다른 대답으로 가야합니까?)은 일반적인 작업을 수행하는 "최상의"방법을 두 가지 이상 가지고 있습니다. (다시) C ++, Perl 및 Ruby의 경우입니다.


1
진화하는 언어에서 부정확성을 피하는 방법을 보지 못했습니다. 또는 그 문제에 대해 원래 디자이너가 파스칼과 같은 중요한 점을 놓친 사전 디자인 된 언어로.
David Thornley

@David Thornley 잘 정의되어 있습니다. 버그는 물론 대부분의 프로그래밍 언어 디자이너가 처음부터 바로 사용할 수 있습니다. 툴은 문법이 완료 될 때 (C ++에 최소한 3 개의 문법이 필요함) 모호하지 않은지 확인할 수 있으며 표준 구현에 대한 의미를 지정해야합니다.
Apalala

잘 정의 된 언어는 가능하지만 사전 표준 C ++과 같은 진화하는 언어에서는 발생하지 않을 것에 동의합니다. 대안은 각 언어가 출시 전에 철저하게 설계되었으며 반드시 최상의 언어를 얻을 수있는 방법은 아닙니다. 언어 디자인이 매우 복잡하기 때문에 대부분의 프로그래밍 언어 디자이너는 처음에는 문제가 있다고 말합니다.
David Thornley

"잘 정의 된"의 의미를 이해하는 데 문제가있는 것 같습니다. 다른 C ++ 컴파일러가 실제로 동일한 언어를 컴파일하지 않았다는 불만이 있습니까?
Sean McMillan

3

C ++의 클래스는 언어에서 일종의 강제 디자인 패턴입니다.

런타임에 구조체와 클래스 사이에는 실질적인 차이가 없으며 "정보 숨기기"의 실제 프로그래밍 이점이 무엇인지 이해하는 것이 혼란 스럽습니다.

나는 그것을 위해 하향 투표 할 것이지만, 어쨌든 C ++ 컴파일러는이 언어를 작성하기가 너무 어려워 괴물처럼 느껴집니다.


2
정보 숨기기는 API의 액세스 가능한 부분 (API의 "UI")에서 변경 될 수있는 구현 별 세부 정보를 숨겨서 프로그램 변경을보다 쉽고 덜 고통스럽게 만들 수 있기 때문에 중요합니다.
Anto

1
API의 UI ... 아니요, 진지하게, 나는 그것을 사지 않습니다.
jokoon

3
이 차이는 C ++에서 가장 반란을 불러 일으키는 부분이 아니며 가깝지도 않습니다. 유일한 차이점은 기본 액세스 수정 자입니다 (structs에는 public, 클래스에는 private). C ++은 끔찍하고 괴물 같은 언어이지만 확실히이 부분에는 해당되지 않습니다.
SK-logic

sk-logic : 글쎄, 나는 공포가 시작된다고 말할 수있다.
jokoon

2
정보 숨기기가 좋습니다. 당신은 그 모든 것에 대한 토론을 찾을 수 있습니다. 내가 생각할 수있는 유일한 저명한 소프트웨어 책은 Brooks의 "The Mythical Man-Month"였으며 나중에이 책에서 가장 큰 실수라고 생각했습니다. 장점을 이해하지 못하면 실제로 판단을 내릴 자격이 없습니다.
David Thornley

3

모든 언어에는 결점이 있지만, 일단 당신이 그들에 대해 알고 있다면 귀찮은 것은 없습니다. 이 쌍을 제외하고 :

복잡한 API와 결합 된 복잡한 구문

이것은 특히 Objective-C와 같은 언어에 해당됩니다. 구문은 매우 복잡 할뿐만 아니라 API는 다음과 같은 함수 이름을 사용합니다.

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

나는 명백하고 모호하지 않은 것이지만 이것은 우스운 일입니다. xcode로 앉을 때마다 n00b와 같은 느낌이 들며 정말 실망 스럽습니다.


Objective-C 구문이 압도적으로 복잡합니까? C ++을 보지 못했습니까? 그리고 실제 분석법 이름 tableView:cellForRowAtIndexPath:은 내 의견으로는 매우 설명 적입니다.
오른쪽

터치 식을 배우십시오.
finnw

2
  1. C로 서명 된 문자-수학자들이 작은 물건을 많이 모을 수 있도록 고안된 가증
  2. 이야기를 사용할 필요가없고 수식을위한 충분한 공간 이없는 수학자에게 다시 의미 론적 내용을 전달하기 위해 사례 사용
  3. 기본 방언에서하자 / 일반 과제 대 과제 할당-여기에 관련된 수학자가 없습니다.

서명 된 문자 의견에 대해 길을 잃었습니다. 설명 할 수 있습니까?
Winston Ewert

1
인간에게 (부호없는) 문자의 개념과 부호없는 문자를 기본값으로 사용하도록 컴파일러에 지시해야 할 필요성은 수학자에게 2와 같은 주장 인 것처럼 2! = 2라는 주장은 분명히 미쳤습니다. 또는 이탤릭체.
Ekkehard.Horner

5
문제는 C가 "char"(즉, 텍스트 문자열의 일부)과 "byte"(즉, (u)int_least8_t) 의 개념을 혼동한다는 것입니다 . 부호는 작은 정수에는 완벽하게 적용되지만 문자에는 전혀 의미가 없습니다.
dan04

@ dan04 : 동의합니다. 작은 정수 (서명 및 부호없는), 바이트 및 문자에 대해 다른 유형을 가지기를 바랍니다. 원시 메모리를 조작하려면 초보자 char*에게 C-String과 같이 캐스팅해야 한다고 설명하면 실제로 혼란스러워집니다.
Matthieu M.

C #은 별도 sbytebyte, 및 char유형 으로이 권리를 얻었습니다 .
dan04
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.