진실 2: Smalltalk는 어렵다 -1- (C언어, 왜 어려운가?)

Jun 14, 2005 16:40
 
차례
 
SmalltalkSmalltalk
Smalltalk
에 대한 오해 중 하나는 이것이다.
Smalltalk는 배우기 어렵다.
 
정말 먹음직스러운 이 초밥을 만들기가 쉬울까 어려울까?정말 먹음직스러운 이 초밥을 만들기가 쉬울까 어려울까?
정말 먹음직스러운 이 초밥을 만들기가 쉬울까 어려울까?
 
회전초밥집의 멋드러진 요리를 만들어 내는 요리사에게는 그런 요리를 만드는 것이 '여라운 일'은 아니겠지만, 전혀 모르는 다른 사람들에게는 가히 범접하기 어려운 예술의 경지라 할 수 있다. 그러면 무엇인가를 어렵게 만드는 요인에는 어떤 것들이 있을까?
 

1. '어렵다'는 것이 무엇인가?

'어렵다'는 것은 여러 가지 뜻을 가지고 있지만, 결국은 '익숙하지 않아서 불편하다'라는 느낌이 제일 강할 것이다. 어떤 것이'배우기 어렵다'라고 생각되는 데에는 다음과 같이 몇 가지 이유가 있다고 볼 수 있겠다. 물론 내가 찾은 이유 말고 다른 이유가 더 있을 수 있다. 여러분들께서 다른 이유를 찾았다면 필자에게 알려주기 바란다..
 
'배우기 어렵다'고 생각되는 이유들을 정리해 보면 이렇다.
 

1) 다르다 / 새롭다

 
처음 한자 공부를 시작했을 때의 어리둥절함을 생각해 보자.처음 한자 공부를 시작했을 때의 어리둥절함을 생각해 보자.
처음 한자 공부를 시작했을 때의 어리둥절함을 생각해 보자.
 
 
사람들은 같은 것에서 안정을 느끼고, 익숙한 것에서 편안함을 얻는다. 무언가 '다르다'는 것은 '긴장'이요 '불안'이며, '자극'이요 '스트래스'이다. 이는 '새로운 것'에 대한 '거부'나 '부정적인 생각'으로 표출되기 쉽다.
 

2) 크다 / 많다

 
산더미 같은 교과서를 이렇게라도 해서 재미있게 만들어보려는 아이들이... 불쌍하다.산더미 같은 교과서를 이렇게라도 해서 재미있게 만들어보려는 아이들이... 불쌍하다.
산더미 같은 교과서를 이렇게라도 해서 재미있게 만들어보려는 아이들이... 불쌍하다.
 
다른 점'이 적다는 것은 그만큼 '비슷한 점이 많다'는 뜻이므로, 이것은 결국 '새로운 것'에 대한 충격을 줄여준다. 하지만 배워야 할 대상이 '크거나' '많으면' 배우는 사람들은 기가 질린다.
 '언제 저걸 다 배워?'
그래서 배우려는 것의 규모가 크거나 양이 많다면 결국 그것이 '어렵다'는 것이다.
 

3) 복잡하다

 
보기만 해도 눈이 핑핑 돈다보기만 해도 눈이 핑핑 돈다
보기만 해도 눈이 핑핑 돈다
 

4) 예외가 많다 (일관성이 적다)

 
에휴... 또 외울 거야?에휴... 또 외울 거야?
에휴... 또 외울 거야?
 
'새로운' 것이 복잡할 수록 배우는 사람은 쉽게 그것을 소화하는데 어려움을 느낀다. '복잡하다'는 말을 조금 더 구체적으로 말해보면, '작관적이지 못하다'거나 혹은 '여러 단계의 생각이 필요하다'는 것이다.
새로운 것을 배우고 그것을 써먹을 때 머릿속에서 얼른 떠오르는 대로 되지 않으면 시행착오가 늘어나고, 이는 결국 배우는 사람들을 위축시킨다. '새로운 것'이 단순하면 단순할 수록, 그리고 '직관적'이면 직관적일 수록 배우는 사람들은 그것을 쉽게 자기 것으로 만들 가능성이 크다.
 

5) 성취도를 맛보기가 쉽지 않다

 
 
의술은 결코 금방 되는 게 아니니라.의술은 결코 금방 되는 게 아니니라.
의술은 결코 금방 되는 게 아니니라.
 
 
'뇌'는 무엇인가를 '성취'했다는 느낌을 받으면 더욱 더 그 능력이 배가되는 법이다. '새로운 것'을 배울 때마다 금방 금방 눈에 보이는 성과가 나타나지 않으면 배우는 사람들은 자기가 제대로 하고 있는지에 대한 피드백을 받기 어려워지며 이것은 사람을 쉽게 피로하고 지치게 만든다. 그리고 이런 현상은 결국 '새로운 것'에 대한 흥미를 떨어뜨리는 요인이 된다.
 

6) 지루하다(흥미가 적다)

 
 
10뿐만 보고 있어도 졸음이 쏟아질 것 같다.10뿐만 보고 있어도 졸음이 쏟아질 것 같다.
10뿐만 보고 있어도 졸음이 쏟아질 것 같다.
 
다른 사람이 보기에 '어려운' 일을 척척 배우고 해 내는 사람들을 가만히 보면 그 일을 '즐기고' 있다. 아무리 일의 '양'이 많다고 해도, 그 일을 '즐길 수' 있다면, 그리고 '새로운 것'을 즐겁게 배울 수 있다면 학습의 성과는 배가되기 마련이다.
 

7) 잘못 가르치고 있다.

 
낭만파? 인상파? 도대체 음악이 언제부터 '음악'이 암기 과목이 되었나?낭만파? 인상파? 도대체 음악이 언제부터 '음악'이 암기 과목이 되었나?
낭만파? 인상파? 도대체 음악이 언제부터 '음악'이 암기 과목이 되었나?
 
'잘 가르치는 사람'은 '어려운 것을 쉽게' 가르치는 사람이다. 그러므로 배우는 사람이 위에서 말한 여섯 가지 함정을 제대로 피해가거나 혹은 함정에 빠졌을 때 그 상황을 잘 극복할 수 있도록 도와주어야 한다.
그러나 '쉬운 것을 어렵게' 가르치는 사람들은 위의 원칙을 잘 알지도 못할 뿐더러 '가르치'는 것에만 이상하리만치 집착을 보이며 배우는 사람을 '따라오라'고 한다. 이렇게 되면 본질적으로 재미있고 흥미로운 것이라도 재미 없고 따분하게 된다.
도대체 '음악' 시간에 '낭만파는 누구, 인상파는 누구' 라는 식의 단순한 암기가 무슨 도움이 된단 말인가? '음악'은 듣고 부르라고 있는 것이지 머리로 외우라고 있는 게 아닌데 말이다...
 
지금까지 필자 나름대로 '새로운 것'이 어렵게 느껴지는 이유를 정리해 보았다. 이에 동의하는 분들도 계시겠지만, 동의하지 않는 분들도 계실 거라고 믿는다. 하지만 --비록 짧은 기간이지만-- 여러 학생들을 가르쳐 오면서 나름대로 느낀 점들이기 때문에, 필자의 제시가 엉뚱하다고는 생각하지 않는다.
이제 이 아래 부분부터는 필자가 제시한 위의 7가지 이유를 근거로 글을 쓰겠다. 따라서 위에서 제시한 것들이 타당하지 않다고 느꼈다면 꼭 덧글을 달아주시기를 부탁드린다. 왜냐하면 토대에서부터 큰 잘못이 있다면 글 전체가 오류에 빠질 수 있기 때문이다. 그러니 여러분들도 이 글을 읽을 때 수동적으로 따라오지 말고 의식을 가지고 읽어 주실 것을 부탁드린다.
 

2. 사례 1: C/C++ 언어

 
오늘도 밤잠을 설치며 공부에 매진하는 학생들오늘도 밤잠을 설치며 공부에 매진하는 학생들
오늘도 밤잠을 설치며 공부에 매진하는 학생들
 
흔히 많은 사람들이 "
CC
C
/
C++C++
C++
언어는 어렵다"고 말한다. 그러면 위의 일곱 가지 이유에 하나씩 비교하면서 왜 어려운지에 대하여 같이 생각해 보기로 하자.
 

1) 다르다 / 새롭다.

프로그래밍 언어를 처음 공부하는 사람들에게는 모든 것이 생소하다. 따라서 C언어 뿐만이 아니라 '프로그래밍' 자체가 다르고 새로운 것이다. 결국 프로그래밍의 초심자들은 '프로그래밍의 개념'과 'C/C++언어'라는 두 가지 어려움을 함께 겪게 된다. 이것은 초심자들에게 그대로 부담으로 다가 온다.
만일 Visual Basic(
BASICBASIC
BASIC
)이나 Delphi (
Pascal Pascal
Pascal
) 등 다른 프로그래밍 언어를 접한 분이라면 상대적으로 '새로운 것'에 대한 장벽은 그나마 훨씬 낮을 것이다. 그러나 결국 C/C++를 접하는 많은 사람들은 이 언어가 가지는 독특한 표기법과 다른 언어와는 다른 구문에 일단은 어려움을 느낀다. 결국 이것은 C/C++언어 속을 흐르고 있는 정신이나 철학을 깨닫지 못하고는 결코 넘을 수 없는 산 앞에 서 있는 것과 다를 바 없다.
 

2) 크다 / 많다

프로그래밍 언어를 구성하는 부분을 크게 두 가지로 나누면 다음과 같다.
 
  • 언어의 기본 골격(구성요소(문법)
  • 추가적인 기능(라이브러리)
 
C/C++ 언어를 포함한 모든 프로그래밍 언어는 그 언어 자체를 규정하는 구성 요소, 그러니까 '문법'이 있고, 이 토대 위에 프로그램의 기능을 결정하는 '라이브러리'가 있다.
이 둘 중에 프로그래밍 언어에서 반드시 알아야 하는 것은 '문법'이다. 왜냐하면 '문법'을 통해서 프로그래머의 생각을 표현해야하기 때문이다. 하지만 라이브러리는 다르다. 이것은 언어의 기능적인 부분이므로 프로그래머가 개발해야 하는 프로그램에 따라 달라질 수 있으며 자신의 상황에 맞게 선택적으로 공부할 수 있는 부분이다.
그러므로 언어의 구성 요소 중에서 문법이 차지하는 비율이 얼마나 큰가에 따라 프로그래밍 언어의 학습 난이도가 결정된다고 해도 과언이 아니다. C언어의 문법은 C++에 비해서 간단한 편이지만, Visual Basic이나 Pascal, 또는 
PythonPython
Python
같은 다른 프로그래밍 언어들보다는 확실히 구성 집합이 크다.
여러 기능을 받아들이면서 발전해 온 C++ 언어의 경우는 말할 필요도 없다. C/C++ 를 설명한 책들의 절반 가까이는 '문법'에 대한 설명이며 이는 C/C++ 언어의 표준을 정해 놓은 문서 역시 크게 다르지 않다.
 
 
ECMA의 ANSI 표준 문서. C++는 두 배 정도 더 복잡하다.ECMA의 ANSI 표준 문서. C++는 두 배 정도 더 복잡하다.
ECMA의 ANSI 표준 문서. C++는 두 배 정도 더 복잡하다.
 
따라서 이러한 '문법의 방대함'은 학습자들에게 '벽'과 같은 느낌을 주기 쉽다. 여러분은 C/C++의 40개가 넘는 연산자들의 의미와 우선순위, 결합성을 두루두루 모두 줄줄이 꿰고 있다고 자신할 수 있는가? C/C++ 언어에서 선언(declaration)과 정의(definition)이 가지는 문법상의 특징과 차이점을 정리해서 말할 수 있는가?
아주 간단한 예제로써 대부분의 경우 프로그래밍 언어의 첫번째 예제인 "Hello, world"의 코드는 아래와 같다.
 
#include <stdio.h> void main( void ) { printf("Hello, World\n"); }
 
이와 같이 비교적 단순한 일을 하는 프로그램에 대해서 설명하려고 해도 우선 #include 선행처리 지시자부터 설명하는 일이 예사롭지 않다. void, main' printf, \n 등등등... 이런 구성요소들을 프로그래밍 초심자에게 설명하는 것은 정말 쉬운 일이 아니다. 그렇다고 대강 넘어갈 수도 없는 노릇이다. C/C++ 로 일을 해야 할 때 기본적으로 알아야 할 것이 많다는 것은 그만큼 학습의 난이도를 올려놓는 중요한 요인이다.
 

3) 복잡하다

2)와 관련되는 이야기이다. C언어의 구조는 복잡하다. C언어의 '겉모습'이 '간결하다'라고 말할 수 있을지는 몰라도 결코 언어 자체가 '간결다'라고 말할 수는 없다. 이는 C언어가 개발자의 생각을 그대로 표현할 수 있을 만큼 직관적이지도 않고 그렇다고 그 표현 방식이 단순하지도 않음을 의미한다.
 
기계어와 친숙한 사람은 C언어도 쉽게 다룰 수 있다.기계어와 친숙한 사람은 C언어도 쉽게 다룰 수 있다.
기계어와 친숙한 사람은 C언어도 쉽게 다룰 수 있다.
 
물론, 하드웨어와 어셈블리 언어 같은 저수준(low-level) 처리에 대한 이해와 경험이 풍부한 개발자들은 C언어를 사용해서 직관적으로 생각을 표현할 수 있을지 모르겠다. 그러나 '언제나 기계와 친해져야만 한다는 것이 얼마나 괴롭고 위험한 일인지는 경험해보지 않은 사람은 모른다. 결국 C언어는 기계와 시스템을 가장 효율적으로 다룰 수 있는 언어일지는 몰라도 일상적인 문제를 효과적으로 풀 수 있는 언어는 결코 아니다.
이런 복잡성을 가진 C언어의 유산을 고스란히 물려받은 C++언어... 정말, C++는 워낙 복잡한 언어여서 '간결하다'는 말을 붙이기도 민망할 노릇이다. 그러므로 여기에 군말을 덧붙이는 것 자체가 '잔소리'이다.
위에서도 예를 들었지만, C언어에서는 각종 연산자와 자료형을 포함하여 지정어(reserved words)의 위치에 따라서 달라지는 의미에 이르기까지 상당히 복잡한 문법 구조를 가지고 있다. 다음을 보자.
 
if ((a == 3) || (b == 5)) printf("The result is %d\n", r);
 
프로그래밍 언어의 초심자들 뿐만 아니라 Visual Basic이나 Pascal에서 온 사람들도 족히 당황하게 만드는 저 문형식에 익숙해지기 까지는 꽤 오랜 시간이 필요하다. 분명히 위의 코드는
 
.
if ((a = 3) or (b = 5)) then WriteLn('The result is', r);
 
보다는 읽고 쓰기가 어렵다.
C++에서도 이는 그대로 적용 된다. 다음을 보자.
 
int data[10]; int i; { for ( i = 0; i < 10; i++ ) cout << i << endl; }
 
위의 코드가 어떻게 동작하는지를 알기 위해서는 필히 for 제어문에 대해서 당연히 알아야 한다. for 제어문에 있는 세 개의 식이 차례 대로 초기식, 조건식, 증감식이라는 것을 알지 못한다면 위의 코드를 해석하기가 여간 까다롭지 않다.
 
var data: array[0 .. 9] of Integer; i: Integer; begin for i := 0 to 9 do WriteLn( i ); end;
 
위의 Pascal 코드와 C/C++ 코드가 있고, 여러분이 만약 프로그래밍 언어의 초심자라면 둘 중 어떤 표기법이 좀 더 간단하겠는지 생각해 보자. (겉모습이 간결한 것과 언어 자체가 간결한 것을 혼동하지 말기 바란다.)
 
척 보면 압니다~ 이것 말고 다른 설명이 필요할까?척 보면 압니다~ 이것 말고 다른 설명이 필요할까?
척 보면 압니다~ 이것 말고 다른 설명이 필요할까?
 
언어를 복잡하게 만드는 요인 중에 하나는 '직관적이지 못하다'는 것이다. 생각한 것을 그대로 쓰면 문제를 일으키는 대표적인 경우 두 가지를 아래에 들겠다.
첫번째의 경우로, 배열의 내용을 통째로 복사하는 함수가 있다고 하자.
 
arrayCopy(target, source);
 
만약 이렇게 썼다면 여지없이 틀린다. 아니, C언어에서라면 아예 저런 것 자체가 불가능하다. 왜냐하면 C언어에서는 함수에 매개변수를 전달할 때 반드시 값 의미(value sementic)로만 전달을 해야 하고 가리킴, 즉 참조(reference) 의미로 전달하려면 반드시 포인터를 사용해야 한다. 그런데 배열 변수는 포인터 상수이므로 함수로 넘어가는 매개변수는 사실은 배열이 아니라 배열의 포인터일 뿐이다.  arrayCopy() 함수에서는 넘어온 매개변수가 배열인지 포인터인지도 알 수 없으며 당연히 넘어온 배열의 크기 또한 모른다. 결과적으로 C언어에서는 다음과 같이 해야 한다.
 
arrayCopy(target, source, arraySize);
 
이렇게 배열의 크기를 따로 넘겨주지 않으면 제대로 배열이 복사되지 않는다. '하나가 더 붙는다'는 것은 '실수할 여지가 하나 더 늘어난다'는 것과 마찬가지이다.
 
두 번째는 선행처리기의 대표적 활용이라고 할 수 있는 매크로 함수이다.
#define square(x) x * x
 
위의 선행처리 지시문은 x의 제곱을 돌려주는 매크로 함수이다. 그런데 저걸 저렇게 쓰면 치명적인 문제를 가지게 된다. 어떤 경우일까?
 
a = square(3 + 4);
 
언뜻 생각하면 a에는 7의 제곱, 즉 49가 들어갈 거라고 예상할 것이다. 하지만 실제로 저렇게 하면 a에는 (3 + 4 * 3 + 4), 즉 19가 들어간다. 매크로는 식을 계산하는 것이 아니라 단순히 치환하는 것이기 때문에 저런 일을 방지하기 위해서는 매크로 함수의 매개변수와 전체 식을 모두 괄호로 둘러주어야 한다.
 
#define square(x) ((x) * (x));
 
이렇게 매크로 함수의 특성이라는 '배경 지식'을 이해하지 못하고 손이 가는 대로 코딩을 하게 되면 그것이 바로 재앙을 불러온다. 더 무서운 것은, 초심자들은 자기가 쓰고 있는 저것이 재앙을 부른다는 사실도 모르고 있다는 것이다. 이 얼마나 끔찍한 일인가. 정말 디버거를 아무리 돌려봐도 위의 매크로 버그는 찾기가 쉽지 않다.
사실 위와 같은 안전장치를 했다고 하더라도
 
b = square(a++);
 
 
과 같이 부작용이 있는 ++/-- 등을 사용하면 정말 어쩔 수 없는 버그를 만들어낸다. 만일 square()를 정의한 소스 코드가 없다면, square()가 매크로 함수인지 일반함수인지 조차도 알 수 없는 최악의 상황이 벌어지기도 한다. C/C++ 프로그래머들이 그토록 좋아하는 증감 연산자에 부작용이 있으니 함수를 호출할 때에나 기타의 경우에 함부로 남용하면 안된다는 것을 알고 있는 사람이 얼마나 될지 걱정스럽다. 물론 이것이 필자의 속 좁은 기우였으면 얼마나 좋을까....
C++언어에서 복잡한 것이라면 이런 것 말고도 훨씬 많은 예를 들 수 있다. 하지만 이러면 끝이 없을 것이므로 복잡도에 대해서는 이쯤에서 줄이기로 한다. 다만 복잡도 이야기를 마치기 전에 아래의 코드가 도대체 무엇을 하는 것인지 곰곰히 생각해 보았으면 좋겠다.
 
const int * const * ppi = &pi;
(어쩌면
C언어 복잡한 선언문 해석 방법
을 읽고 내용을 익혔다면 위의 코드를 더 쉽게 읽을 수 있을 지도 모르겠다. 하지만 선언문이 복잡하고 직관적이지 않다는 사실은 변하지 않는다.)
 

4) 예외가 많다(일관성이 적다)

C/C++ 언어는 프로그래밍 언어 중에도 상당히 많은 예외를 가지고 있다. 그러니까 문법이나 개념의 일관성이 결여되어 있다는 말이다. C/C++ 언어를 좋아하시는 분들이 이 말씀을 들으면 불쾌하실지도 모르겠지만 이것은 부정할 수 없는 사실이니 인정하셨으면 좋겠다. (정말 사랑한다면 그 사람의 단점까지 사랑해야 옳지 않겠는가?)
C/C++ 언어가 일관성이 결여된 언어라는 단적인 예를 하나만 들도록 하자.
 
#include <stdio.h> void main( void ) { int data; data = 5; printf("%d\n", data); printf("=>"); scanf("%d", &data); printf("%d", data); }
 
이것은 정수 데이터를 변수에 대입해서 출력하고, 사용자의 입력을 받아서 다시 그것을 출력하는 코드이다. 그럼 아래를 보자.
 
#include <stdio.h> #include <string.h> void main( void ) { char data[30]; strpcy(data, "Hello!"); printf("%s\n", data); printf("=>"); scanf("%s", data); printf("%s", data); }
 
이것은 문자열을 대입한 뒤 출력하고 다시 사용자에게서 문자열을 입력 받은 다음 그것을 그대로 출력하는 똑같은 구조의 프로그램이다. 즉 자료형만 바뀌었다.
printf()와 scanf()의 형식 지정자는 정수(decimal radix integer)와 문자열(string)의 차이 때문에 어쩔 수 없다 하더라도 변수에 정수를 저장할 때와 문자열을 저장할 때의 차이는 어떻게 설명해 줄 것인가?왜 정수를 저장할 때는 = 를 쓸 수 있는데 문자열의 경우는 strcpy() 함수를 써야 할까? 만약 여러분이 강사이고, 학생들이 이렇게 묻는다면 뭐라고 답할 것인가? 또 scanf() 함수에서 값을 입력 받을 때에도, 정수의 경우는 & 연산자를 쓰지만 문자열의 경우는 & 연산자를 쓰지 않았다. 이건 또 어떻게 설명해 줄 것인가?
 
방법은 두 가지다
  • 예외 상황은 무조건 외우게 한다.
  • 왜 다른지에 대해서 상세하게 셜명해 준다.
단순 암기가 아니라 실제로 이 차이점을 배우는 사람들이 내용을 알 수 있도록 설명하기 위해서는 다음과 같은 사실들을 먼저 알려주어야 한다.
 
  • C언어에서 문자열은 존재하지 않으며 문자의 배열로 문자열을 구현한다.
  • " " 속에 있는 것은 문자열 상수가 아니라 문자 배열 상수이다.
  • 배열변수의 이름은 그 배열의 첫번째 원소를 가리키는 포인터 상수이다.
 
위의 세 가지 중 어느 하나라도 제대로 개념을 잡지 못한다면 위의 보기가 왜 저렇게 다른 점을 가질 수 밖에 없는지를 전혀 이해하지 못하게 된다. 더구나 위에서 설명한 것들은 모두 문제를 풀기 위하여 겉으로 드러나는 특성이 아니라 단순히 언어 자체의 구현상의 특징일 뿐이다. C/C++ 언어를 상당 기간 마스터하고 전체를 꿰뚤어볼 수 있을 때에만 깨달을 수 있는 상당히 고차원적인 지식인데 저것을 초심자들에게 무슨 수로 설명해 줄 수 있단 말인가?
내 경험으로 볼 때, C언어를 처음 배우는 사람 중에 이와 같은 방법으로 가르치는 것은 거의 불가능에 가까웠다. 결국 전자의 방법으로 무조건 외우게 해야 하는데 이게 배우는 사람들을 엄청 짜증나고 난감하게 하는 요인이다. 결국 C/C++언어를 사용해서 프로그래밍의 기초를 시작할 때에는 '프로그래밍'의 본질인 '문제 해결'에 중점을 맞추기가 어렵고 '언어'에 매여 있을 수밖에 없다.
 
버그 괴물이다~~~버그 괴물이다~~~
버그 괴물이다~~~
 
이런 예외들이 C언어에는 수십 개가 넘고 C++의 경우는 설상가상으로 C언어의 수십 배에 달한다. 이런 일관되지 못한 개념과 표현은 배우는 사람들 뿐만 아니라 현업에서 개발을 맡고 있는 개발자들도 쉽게 혼동할 수 있는 부분이기에 더 심각하다. 이러한 언어의 의미론적 불일치에서 오는 버그에 논리적인 버그가 합쳐진다면 가히 '버그 괴물'의 탄생은 안 봐도 비디오다. (너무 과장이 심했나?)
심한 말로 들리겠지만 C/C++ 에는 문제를 해결하는 데 방해가 되는 요소가 너무 많다. 이러한 함정을 멋지게 피해 가면서 능수능란하게 C/C++ 코드를 다루는 사람들은 회전초밥집의 주방장과 같이 가히 예술의 경지라해도 과언이 아닐 것이다.
 

5) 성취도를 맞보기가 쉽지 않다.

C/C++ 언어는 모두 컴파일러형 언어이다. 그러므로 이러한 언어들에서 결과가 바로 바로 나오는 대화식 접근법을 사용할 수 없음은 당연하다. 또한 위에서 설명한 문법과 언어, 라이브러리의 복잡함 때문에 눈에 보이는 성과물을 얻기 까지 상당한 시간과 노력이 필요하다. 물론 뭐든지 금방 되는 일도 없고 그만한 시간과 노력이 필요한 것은 당연하지만 지름길을 두고 먼 길을 돌아가느라 쏟은 시간과 노력은 아깝다고 해야 할 것이다.
대학교 때 C언어를 들은 학생들은 언제나 까만 화면에 무언가를 입력하면 결과값으로 무엇을 출력하거나 혹은 간단한 계산 문제를 풀거나 하는 것으로 한 학기를 마친다. 마음 먹고 C/C++로 window를 하나 만들어 보려고 하면 알아야 하는 게 너무 많다. 결국 1년 동안 C/C++를 배운 학생들이, 파일을 기반으로 하는 간단한 GUI 전화번호부 하나를 만들어 내기 까지는 정말 '뼈를 깎는 고통'이 따른다.
이렇게 성취도를 확인하기가 상당히 힘든 언어가 C/C++이기 때문에 많은 사람들이 C/C++의 학습을 쉽게 포기해 버린다. 눈에 보이는 무언가를 얻어내기 까지 너무나 많은 시행착오가 기다리고 있으므로...
물론 C/C++를 이런 식으로 '수행'과 '고행'을 하듯이 배우는 것도 꼭 나쁘다라고 말하기는 어렵다. 이런 식의 학습 방법에서도 나름대로 얻는 것이 있기 마련이다. 그러나 요즈음의 개발 환경은 이런 '수행'과 '고행'을 단련할 만큼 결코 많은 시간을 주지 않는다.
 

6) 지루하다(흥미가 적다)

 
열심히 만든  C/C++  프로그램. 하지만 겉 모습은?열심히 만든  C/C++  프로그램. 하지만 겉 모습은?
열심히 만든 C/C++ 프로그램. 하지만 겉 모습은?
 
지금까지의 모든 상황이 C/C++ 학습을 지루하고 흥미가 떨어지게 만든다. 뭘 좀 해보려고 하면 알 수 없는 버그들로 머리를 싸매야 하고 기껏 문제를 하나 풀어서 실행하면 까만 화면에 글자 몇 개 입력하는 수준이니 처음에 '청운의 꿈을 안고 시작한 프로그래밍 공부'가 나중에는 '내가 왜 이 짓을 하고 있지?'라는 회의로 돌변하고야 만다.
학습에 있어서 흥미는 정말 중요한 요소이다. '따분하다'고 생각하기 쉬운 것도 스스로 흥미를 느끼기 시작하면 다른 사람의 몇 배를 배울 수 있기 때문이다. 하지만 아무리 둘러봐도, C/C++를 재미있게 공부할 방법이 떠오르지 않는 것은 순전히 필자의 부족함 탓일까?
 

7) 잘못 가르치고 있다.

C/C++ 언어 자체가 이런 '어려울 수 밖에 없는 특징'을 가지고 있는 것과 함께 상당히 많은 학원이나 심지어는 '전산학의 본산'이라는 대학의 전산학과에서조차 잘못된 접근방법으로 C/C++언어를 가르치고 있다는 것은 참으로 안타까운 일이다.
'프로그래밍'의 개념이 전혀 잡히지 않은 사람들에게 C언어를 가르친다는 것이 당췌 말이나 되는 소리인가? 더구나 아직 객체지향의 개념도 없는 사람들에게 C++를 가르친다면서 철저히 절차지향적인 개념을 불어 넣어준 뒤에 사람들이 절차지향의 [관]에 익숙해졌을 즈음에 완전히 새로운 패러다임인 '객체지향'을 가르치려고 한다. 이는 정말 학생들을 두 번 죽이는 꼴이다.
'새로운 것'을 배울 때 어떻게 하면 '새로운 것'으로부터의 충격을 최소화 할지를 고민해야 하는 교육자들이 오히려 학생들에게 실컷 절차지향적 사고를 심어준 뒤에 'class'가 나올 때 쯤 '객체지향'을 강조하니, 학생들은 여기 저기서 '패러다임의 대 혼란' 속에 휩쓸려 떠내려가며 처절한 비명을 지른다. 이건 정말 눈 뜨고는 볼 수 없는 아비규환 그 자체이다.
더 암울한 것은 이러한 혼란 속에서 학생들을 건져주고, '프로그래밍 패러다임'의 뚜렷한 가치관을 세우도록 도와줄 수 있는 사람이 적을지도 모른다는 것이다. 학생들은 안 그래도 배울 거 많고 외울 게 많은데, [객체지향]에 따라다니는 '클래스'니, '상속'이니 '다형성'이니 하는 것들을 '외워야' 한다면 이건 정말 학생들의 짐을 덜어주는 게 아니라 아예 몇 배로 늘려 주는 꼴이다.
'객체지향'이라는 '관'을 박아주는데 심혈을 기울여도 모자랄 판에 단순히 '객체지향'에서 쓰이는 용어들의 쓰임새를 알아오라고 리포트를 시키거나 암기하도록 하는 교육방법은 도대체 곱셈도 안 가르치고 미적분을 가르치는 엉터리 교육법이 아니고 그 무엇이란 말인가!
결국 이러한 방법은 많은 수의 학습자들을 '프로그래밍 혐오자'로 만들고 있다. 안 그래도 어려운 C/C++를 백 배는 더 어렵게 만드는 이런 잘못된 교육법은 하루빨리 고쳐져야 한다.
 
진정한 스승의 방에는 결코 불이 꺼지지 않는다.진정한 스승의 방에는 결코 불이 꺼지지 않는다.
진정한 스승의 방에는 결코 불이 꺼지지 않는다.
 
그러나 다행인 것은 강단에서 열을 올리며 이러한 현실을 깨뜨리기 위해 불철주야 노력하시고 좀 더 새롭고 합리적인 교육방법을 밤낮으로 연구하시는 훌륭하신 스승님들이, 아직까지 우리 곁에 적지 않게 계신다는 점이다. 만약 이런 스승님 밑에서 C/C++ 언어를 전수받는다면 그는 '무림비공'을 전수받는 것처럼 고통 속에서도 즐거울 것이다.

 

관련 글

진실 0: 이제는 말할 수 있다
진실 1: Smalltalk는 느리다
진실 2: Smalltalk는 어렵다 -1- (C언어, 왜 어려운가?)
진실 2: Smalltalk는 어렵다 -2-