5.1 Coding!

프로그래밍이란?

1. Computational thinking

Coding(프로그래밍)은 수행되어져야 하는 명령을 컴퓨터에 전달하는 일종의 커뮤니케이션이다. 이때 “수행되어져야 하는 명령”을 정의하기 위해서는 해결 과제(문제/요구사항)를 명확히 이해한 후, 복잡함을 단순하게 분해(Decomposition)하고 자료를 정리하고 구분(Modeling)해야하며 순서에 맞게 행위를 배열해야 한다.

즉 코딩에 앞서 해결 과제(요구사항과 해결과제가 일치하기를 소망한다)를 명확히 이해한 후 적절한 문제 해결 방안의 정의가 필요한데 이때 요구되는 것이 문제 해결 능력이다. 혹자는 문제 해결 능력을 알고리즘과 동일시하려는 경향이 있지만 반드시 그런것은 아니다. 물론 문제 해결 능력의 함양에 있어 알고리즘 학습은 큰 도움이 되지만 문제 해결 능력은 더 큰 차원의 능력이다. 코딩은 문제 해결의 최종 결과물을 작성하는 도구이지 결코 코딩이 문제를 해결하지는 않는다. 해결 과제를 명확히 이해한 이후 그 문제의 해결 방안을 고려할 때 컴퓨터의 관점에서 문제를 바라보아야 한다. 이때 필요한 것이 Computational thinking이다.

사람의 일반적인 사고 방식은 매우 포괄적이며 실생활에서 경험하고 있는 익숙한 사항에 대해 당연시하는 안이한 인식이 있다. 예를 들어 “듣다(Listen)”라는 행위를 사람은 하나의 간단하고 당연한 기능으로 생각하지만 컴퓨터에게 이 행위를 설명하는 것은 단순하지 않다. 그리고 소리의 크기를 사람은 크다 또는 작다라고 표현하지만 컴퓨터에게 크다 또는 작다라는 의미는 상대적인 개념으로 양적 개념인 숫자로 표현되는 것이 일반적이다. 또한 “좋다”, “붉다”, “사랑”과 같은 관념적 개념은 컴퓨터에게는 매우 난해한 개념이다. 사람은 지인의 얼굴을 보고 누구인지 바로 인지하지만 컴퓨터에게 이것은 매우 어려운 일이다. 3479의 계산은 사람에게는 어렵지만 컴퓨터에게는 매우 쉬운 작업이다.

이처럼 컴퓨터와 사람은 사고, 인지의 방식이 다르다. 따라서 해결 과제를 컴퓨터의 관점으로 사고(Computational thinking)해야 한다. 이에는 논리적, 수학적 사고가 필요하게 되며 해결 과제를 작은 단위로 분해하고 패턴화하여 추출하며 프로그래밍 내에서 사용될 모든 개념은 평가 가능하도록 정의되어야 한다.

예를 들어 사람처럼 두발로 걷는 로봇을 위해 “걷다”라는 기능을 design해 보자.

walk

상태를 판단하는 시기와 판단하여야 하는 상태와 그 기준을 정의하여야 하며 이를 바탕으로 분해한 처리(Process)의 실행 여부를 결정한다. 예를 들어 장애물은 어떤 것(크기, 움직임…)인지 어떤 범위 내에 있는 것인지 명확히 수치화하여 정의해야 한다.

2. Syntax & Semantics

Coding(프로그래밍)은 수행되어져야 하는 명령을 컴퓨터에 전달하는 일종의 커뮤니케이션이다.

이때 명령을 수행할 주체는 컴퓨터이므로, 인간이 이해할 수 있는 자연어가 아니라 컴퓨터가 이해할 수 있는 언어인 기계어로 명령을 전달해야 한다. 컴퓨터는 아쉬울 것이 전혀 없다..

하지만 인간이 기계어를 이해하여 직접 명령을 전달하는 것은 매우 어려운 작업이다. 왜냐하면, 기계어는 우리가 사용하는 언어와는 너무나도 다른 체계를 가지기 때문이다. 심지어 비트 단위로 기술되어 있다.

아래는 x86 아키텍처 리눅스 환경에서 그 유명한 “hello world”를 출력하는 기계어 코드이다.

7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00 02 00 03 00 01 00 00 00 35 40 B3 04 2C 00 00 00 00 00 00 00 00 00 00 00 34 00 20 00 01 00 00 00 00 00 00 00 00 40 B3 04 B2 0C EB 1C 62 00 00 00 62 00 00 00 05 00 00 00 00 10 00 00 48 65 6C 6C 6F 20 77 6F 72 6C 64 0A B9 4C 40 B3 04 93 CD 80 EB FB

가장 유용한 대안은 인간이 이해할 수 있도록 약속된 문법(Syntax)을 사용하여 프로그램을 작성한 후, 그것을 컴퓨터가 이해할 수 있는 기계어로 변환하여 주는 일종의 번역기를 이용하는 것이다. 이 일종의 번역기를 컴파일러(compiler) 혹은 인터프리터(interpreter)라고 한다.

아래는 “hello world”를 출력하는 javascript 코드이다. 위의 기계어 코드보다 인간이 이해하기 쉬운(읽기 쉬운) 코드가 되었다.

console.log('hello world');

따라서 프로그래밍을 학습한다고 하는 것은 문법을 배우는 것이 된다. 이는 외국어 학습과도 유사하다 할 수 있는데 문법을 잘 안다고해서 외국어를 잘한다고 말 할 수는 없을 것이다. 외국어를 잘하려면 외국어 화자의 말이나 문장을 정확히 이해한 후, 문맥에 따른 적절한 어휘 선택과 결론으로 이끌어가는 순차적인 문장 구성이 필요할 것이다.

각각의 낱말들이 모여서 완전한 하나의 생각을 표현하게 되는데, 그 생각은 글쓴이의 머리 속에서 탄생하여 읽는이의 머리 속으로 전해진다.
- 스티븐 킹의 ‘유혹하는 글쓰기’

의미(Semantics)를 가지고 있어야 한다.

Colorless green ideas sleep furiously.
- Noam Chomsky

MIT의 저명한 언어학자인 노엄 촘스키는 이 문장을 통해서 언어의 의미는 문맥에 있는 것이지 문법에 있는 것이 아니란 것을 지적하고 있다. 위 문장은 문법(Syntax)적으로 전혀 문제가 없지만 의미(Semantics)는 없다.

// syntax is okay (type identifier = value),
// semantics is wrong ("five" is not an int).
// Syntax is what the grammar allows, semantics is what it means.

int x = "five"; // warning: incompatible pointer to integer conversion initializing 'int' with an expression of type 'char [5]' [-Wint-conversion]

위 C언어 구문은 문법적으로 문제가 없으나 의미적으로는 틀리다. (“five”는 정수가 아니라 문자열이다.)

결국 프로그래밍은 문법에 부합하는 것은 물론이고 수행하고자 하는 바를 정확히 수행하는 것 즉, 요구사항이 실현(문제가 해결)되어야 의미가 있다.

이것을 위하여 대부분의 프로그래밍 언어는 변수와 값, 키워드, 연산자, 표현식(Expression. 결국 하나의 값으로 수렴되는 식이다), 조건문반복문에 의한 흐름제어(Flow control), 구문(Statement), 구문의 집합인 함수 그리고 객체, 배열 등의 자료구조를 제공한다.

자연어 문장은 프로그래밍 언어의 구문(Statement)에 해당한다. 구문은 변수와 값, 키워드, 연산자, 표현식, 주석으로 구성된다. 즉, 변수를 통해 값을 저장하고 참조하며 연산자로 값을 연산, 평가하고 조건문과 반복문에 의한 흐름제어로 데이터의 흐름을 제어하고 함수로 재사용이 가능한 구문의 집합을 만들며 객체, 배열 등으로 자료를 구조화한다.

프로그래밍은 요구사항의 집합을 분석하여 적절한 자료구조와 함수의 집합으로 변환한 후 그 흐름을 제어하는 것이다.

Back to top
Close