메뉴 건너뛰기

IT기술과 인간 8 – 프로그래밍(코딩) 이야기

코난(진보교육연구소 회원)

올해(2018)부터 드디어 소프트웨어 교육이 의무화되었습니다. 저는 어렸을 때부터 컴퓨터에 흥미가 많아 독학으로 공부를 할 정도로 프로그래밍을 좋아했던 사람이지만, 교사로서 이 정책은 반갑기 보다는 우려가 앞섭니다. 교사로 지내오면서 사회적으로 뭐든 이슈가 되거나 문제가 생기면 그 문제를 근본적으로 해결하기 보다는, 대책이랍시고 일시적 미봉책을 만들어 교육에 집어넣곤 하는 정치적 관행이 교육에 도움이 되기는커녕 방해가 되는 경우를 끊임없이 보아 왔기 때문입니다. 최근에 대통령 직속 ‘저출산고령사회위원회’에서 ‘초등학생 3시 하교’ 정책을 추진한 것도 마찬가지입니다. 소프트웨어 교육 의무화도 학생의 발달을 고려한 교육적 정책이라기보다는, 인공지능을 필두로 한 4차 산업혁명에 대비해야 한다는 사회적 필요성에 의해 외부로부터 도입된 측면이 매우 강합니다. 실제로 소프트웨어 교육이 논란이 되면서 모든 학생이 프로그램을 짜는 코딩을 배울 필요가 있느냐는 문제 제기가 있었고, 코딩이 아닌 문제해결력을 배우는 것이 실제 소프트웨어 교육의 목표가 되어야 한다는 말도 나왔지만, 왜 문제해결력을 꼭 코딩으로만 배워야 하는 것인지, 문제풀이 능력과는 무엇이 다른지 잘 모르겠습니다. 
중학교의 경우 신입생은 올해부터 ‘정보’ 과목으로 소프트웨어 교육을 3년간 최소 34시간 받아야 한다는 규정하에 저희 학교에서는 1학년에 ‘정보’ 과목(주당 1시간)이 신설되었습니다. 저희 학교 1학년은 9학급(주당 수업시수 9시간)이라 새로 오신 정보 교과 선생님은 월,화,수는 본교에서 목,금은 인근학교에서 근무하는 순환교사 형태로 배치되었습니다. 정보 선생님께 물어보니 1학기 때는 기본적인 것을 가르치고, 2학기 때부터 ‘스크래치(Scratch)’를 사용하여 코딩 교육을 하신다고 하더군요. ‘스크래치’란 기존의 일반적인 프로그래밍 언어와는 달리, 그래픽 환경을 이용하여 블록을 끌어당겨 쌓는 것처럼 코딩을 하기 때문에 프로그래밍 입문자가 배우기 쉬운 교육용 프로그래밍 언어로 잘 알려져 있습니다. 저도 사용해 보았는데 실제로 직관적이고 사용이 쉬워 코딩의 기초를 배우기에 좋다는 생각이 듭니다. 그런데 요즘 소프트웨어 교육에서 강조하는 ‘코딩’이라는 것이 실제로 무엇인지 소개해 보고자 합니다.

위키백과에 보면 “컴퓨터 프로그래밍(간단히 프로그래밍 혹은 코딩)은 하나 이상의 관련된 추상 알고리즘을 특정한 프로그래밍 언어를 이용해 구체적인 컴퓨터 프로그램으로 구현하는 기술을 말한다.”고 합니다. 간단히 말해 코딩이란 (프로그래밍 언어를 이용하여) 알고리즘을 소프트웨어로 구현하는 것이라고 할 수 있습니다.
하드웨어가 컴퓨터의 모든 물리적 부품을 가리킨다면, 소프트웨어란 하드웨어에게 어떤 문제를 처리할 수 있도록 지시하는 컴퓨터 프로그램들의 모음이라고 말할 수 있습니다(일상에서는 컴퓨터 소프트웨어와 프로그램은 거의 같은 말로 사용됩니다). 아주 단순화하여 컴퓨터를 사람에 비유할 경우 하드웨어는 몸에 소프트웨어는 정신에 비유하기도 합니다. 여기서 컴퓨터 프로그램이란 컴퓨터에서 실행될 때 특정 작업을 수행하는 일련의 명령어들의 모음을 말하는데, 이러한 컴퓨터 프로그램을 작성하는 것을 컴퓨터 프로그래밍(간단히 코딩)이라고 말합니다. 컴퓨터 프로그램을 (사람이 읽을 수 있는) 프로그래밍 언어로 기술한 글을 소스 코드라고 하는데, 이러한 소스 코드를 작성하다는 의미에서 코딩이라는 말이 생긴 것으로 보입니다.
알고리즘이란 어떤 문제를 해결하기 위한 일련의 절차를 공식화한 형태로 표현한 것으로, 컴퓨터가 등장하기 이전부터 ‘문제를 해결하기 위한 절차나 방법’을 의미하는 단어로 널리 사용되어 왔습니다. 컴퓨터(computer)는 말 그대로 (자동 전자) 계산기이기 때문에 스스로 알고리즘을 고안해 내지는 못합니다. 알고리즘은 당연히 사람이 고안해야 합니다. 대신 컴퓨터는 사람보다 아주 빠르고 정확하게 알고리즘을 실행(계산)할 수 있습니다. 여기서 컴퓨터가 많은 양의 계산을 인간 보다 훨씬 빠르고 정확하게 할 수 있다는 사실 때문에, 알고리즘을 인간이 고안한다는 사실을 망각하면 컴퓨터가 인간의 정신 능력을 초월할 수 있다는 막연한 환상이 생겨날 수 있음에 유의해야 합니다. 자동차가 인간보다 빠르게 달리고 기중기가 인간보다 무거운 것을 들어 올리는 것처럼 계산기는 인간보다 빠르게 계산을 할 뿐입니다. 

그러나 컴퓨터는 인간의 언어를 알아듣지 못하기 때문에, 이 알고리즘은 컴퓨터가 알아듣고 실행할 수 있는 언어인 ‘기계어(machine language)’로 구현되어야 합니다. 초창기 컴퓨터 프로그래머는 알고리즘을 바로 이 기계어로 구현해야 했습니다. 하지만 0과 1로만 구성된 2진수비트(bit) 단위로 이루어진 기계어는 거꾸로 인간에게 매우 어렵고 난해합니다. 예를 들어 숫자 ‘9’를 2진수로 쓰면 ‘1001’이 되고, ‘240’은 2진수로 쓰면 ‘11110000’이 됩니다. 그런데 비트는 너무 작은 단위(0 또는 1)이기 때문에 보통 컴퓨터에서는 8개의 비트를 모은 바이트(byte)를 기본적인 저장단위로 이용합니다(1바이트 = 8비트). 컴퓨터나 스마트폰의 파일, 메모리, 디스크 등의 크기나 용량을 이야기 할 때 1KB(킬로바이트), 5MB(메가바이트), 2GB(기가바이트) 등의 용어를 쓰는데, 맨 뒤에 붙는 ‘B’가 바로 바이트입니다. 이 때 2진수로 표현된 8비트는 너무 길기 때문에, 흔히 컴퓨터에서는 16진수를 사용하게 됩니다. 16진수를 쓰려면 우리가 쓰는 10진수보다 숫자가 6개 더 필요합니다. 그래서 10은 A, 11은 B, 12는 C, 13은 D, 14는 E, 15는 F로 정해서 사용하고 있습니다. 이에 따라 기계어로 된 프로그램은 다음과 같이 보이게 됩니다. 2진수로 표시할 경우 “11111111 11111001 00110011 01111110”, 16진수로 표시할 경우 “0F 3B 67 5C”와 같이 보입니다. 일반인이 보면 완전 암호입니다. 
이 간극을 메우기 위해 탄생한 것이 프로그래밍 언어라고 할 수 있습니다. 맨 처음 탄생한 프로그래밍 언어는 ‘어셈블리어’라고 하는데, 기계어와 일대일 대응이 되는 장점이 있지만 여전히 배우고 이해하기가 쉽지 않았습니다. 그래서 어셈블리어보다 더 인간이 이해하기 쉬운 고급 프로그래밍 언어(코볼, 포트란, C언어 등)가 탄생하여 발달하게 됩니다. 이 때 어셈블리어나 고급 프로그래밍 언어는 당연히 컴퓨터가 이해할 수 없기 때문에 프로그래밍 언어를 기계어로 번역하는 번역기가 필요하게 됩니다. 어셈블리어를 기계어로 번역하는 프로그램을 ‘어셈블러’라고 하며, 고급 프로그래밍 언어를 기계어로 번역하는 프로그램은 그 방식에 따라 ‘컴파일러’(전체를 한 번에 번역)나 ‘인터프리터’(한 번에 한 줄씩 번역하면서 실행)라고 합니다. 
이를 정리하여, 나중에는 기계어를 1세대 프로그래밍 언어, 어셈블리어를 2세대 프로그래밍 언어, 최초의 고급 프로그래밍 언어들을 3세대 프로그래밍 언어라 부르게 되었고, 지금은 4세대, 5세대 프로그래밍 언어까지 나오게 되었습니다. 

당연히 고급 언어일수록 사람의 언어에 가깝고 사용이 편리하기 때문에, 특별한 경우를 제외하고는 대부분의 프로그램은 3세대 이상의 고급 프로그래밍 언어를 사용하여 작성하게 됩니다. 따라서 프로그램을 짜려면 프로그래밍 언어를 배워야 합니다. 
예를 들어 ‘1부터 100까지 정수의 합’을 구하는 프로그램을 알고리즘(순서도)과 소스 코드(C언어)로 나타내면 그림1, 그림2와 같습니다. 컴퓨터는 한 번에 두 개의 숫자만 더할 수 있기 때문에 1부터 100까지 더하기(1+2+3+...+100) 위해서는, 먼저 1에다 2를 더하고, 그 결과값인 3에 다시 3을 더하고, 그 결과값인 6에 다시 4를 더하고 하는 과정을 100까지 반복해야 합니다. 눈치 빠른 분들은 순서도는 물론이고, C언어 소스 코드도 (맨 앞 두 줄 정도만 뺀다면) 어느 정도 이해할 수 있으리라 생각합니다. 


물론 알고리즘이 복잡할수록 순서도는 길고 복잡해지며, 소스 코드는 점점 더 이해하기 힘들어 질 것입니다. 하지만 모든 프로그램의 핵심은 동일합니다. 사람이 알고리즘을 고안하여 코드를 작성하면, 컴퓨터는 코드를 기계어로 번역하여 빠르고 정확히 실행하여 결과를 산출합니다. 
여기서 ‘정확히’ 실행한다는 말의 의미를 집고 넘어갈 필요가 있습니다. 이는 컴퓨터 프로그램의 한 측면을 잘 드러내기 때문입니다. 보통 컴퓨터 프로그램이 잘못되거나 예상치 못한 결과를 산출하는 경우가 종종 있기 때문에, 컴퓨터도 인간처럼 실수를 할 수도 있다는 생각을 하기 쉽습니다. 하지만 컴퓨터에게는 실수라는 말은 적합하지 않습니다. 컴퓨터는 언제나 프로그램으로 구현된 명령을 절차대로 정확히 수행합니다. 사람처럼 실수로 한 단계를 건너뛰거나 ‘2 + 2’를 5라고 착각하는 경우는 없습니다. 전자계산기에 사람이 실수로 ‘2 + 2’를 ‘2 + 3’이라 입력하지 않는 한 ‘5’라는 결과를 내지 않는 것과 마찬가지입니다. 입력이 올바른데 컴퓨터가 잘못된 결과를 출력한다면 컴퓨터를 의심하기 보다는, 알고리즘에 오류가 있거나 미처 생각하지 못한 경우의 수가 있기 때문이라고 생각해야 합니다. 이는 사람의 실수나 기계의 오작동과는 다릅니다. 따라서 결과가 잘못 되었다면 알고리즘을 수정하거나 코드에서 오류를 찾아 수정해야 합니다. 프로그램에 버그가 있다는 말도 바로 이런 경우를 가리키는 것입니다. 프로그램이 오작동으로 어쩌다 그런 결과를 내놓은 것이 아니라, 프로그램에 미처 생각하지 못한 오류가 있었던 것입니다. 사람의 실수가 10번에 1~2번과 같은 식으로 무작위적으로 일어난다면, 프로그램에 버그가 있고 입력이 똑같다면 프로그램은 언제나 동일한 잘못을 반복합니다. 실수를 한 것이 아니라 알고리즘대로 정확히 실행했더니 그런 결과가 나온 것이기 때문입니다. 



프로그램의 이러한 측면 때문에 코딩은 기본적으로 경우의 수를 정확히 따지는 절차적(논리적) 사고를 요구하며, 이는 수학적 사고와 매우 유사합니다. 하지만 수학이 추상적인 수의 세계를 다루는 반면, 컴퓨터는 그림, 소리, 영상과 같은 직관적인 세계도 다룰 수 있기 때문에, 이러한 세상을 자기 마음대로 다루고 만들어 보는 코딩은 어떤 면에서 많은 학생들에게 수학보다 훨씬 매력적일 수 있습니다. 그래서 대부분의 코딩 교육에서 입문용으로 사용하는 ‘스크래치’라는 프로그램은 직관적인 캐릭터를 조절하여 움직이게 하거나 간단한 게임을 만드는 등의 활동을 중심으로 하며, 요즘에는 스크래치 프로그램을 통해 실제로 움직임을 조절할 수 있는 ‘햄스터 로봇’까지 개발되어 판매가 되고 있습니다. 
하지만 학생들의 흥미를 끌기 위해 어떤 수단을 이용할지라도 코딩의 기본은 분명 절차적(논리적), 수학적 사고에 있다고 생각합니다. 따라서 수학을 못하는 학생은 코딩도 못하고, 수학을 잘하는 학생은 코딩도 잘할 가능성이 많으며, 수학과 코딩이 요구하는 정신 능력은 많은 부분 서로 겹칠 수밖에 없어 보입니다. 또한 수학에 스토리텔링만 도입하면 모든 학생이 다 수학을 좋아하고 잘 하게 되는 것이 아닌 것처럼, 코딩 교육을 흥미만으로 이끌어 나가는 데에는 분명 한계가 있을 것입니다. 대부분의 학생들은 재미없는 게임을 만드는 것보다는 재미있는 게임을 하는 것을 더 좋아하기 때문입니다.

화가나 조각가를 양성하는 것이 보편적인 미술교육의 목표가 아니듯, 프로그래머를 양성하는 것이 보편적인 소프트웨어 코딩 교육의 목표가 아니라면, 발달이라는 보편 교육의 목적 속에서 소프트웨어 코딩 교육이 담당하는 고유한 역할이 무엇인지가 앞으로 분명히 드러나야 할 것입니다. 그렇지 못한다면 소프트웨어 교육은 조용히 사라져, 또 한 번의 교육 정책 실패의 사례로 남을 수밖에 없을 것입니다.