1. 개요
擬似— ・ pseudo-code[1]알고리즘을 표현하는 방법 중 하나로, 일반적으로는 자연어[2]를 이용해 만든 문장을 프로그래밍 언어와 유사한 형식으로 배치한 코드를 뜻한다. 용도는 미술의 스케치와 같다.
2. 상세
대부분의 프로그래밍 언어는 영어를 기반으로 하기에 영어로 작성된 의사코드는 얼핏 봐서는 실제 코드와 구별이 잘 안 된다. 그러나 변환 과정을 거쳐 컴퓨터가 읽을 수 있게 바꾸는 프로세스가 반드시 있는 프로그래밍 언어와는 달리, 의사코드는 그런 것이 존재하지 않는다. 당연히 의사코드로 작성된 코드를 컴파일러나 빌더에 넣고 백날 돌려봐야 에러만 뱉어낼 뿐 절대로 실행되지 않는다. 즉, 의사코드는 애초부터 컴퓨터가 읽을 수 없는 코드다. '가짜' 코드라는 말도 의사코드의 이러한 특징에서 비롯된 것이다.그럼 '컴퓨터에서 작동하지도 않을 무의미한 코드를 왜 짜는가?' 하는 의문이 생길 것이다. 하지만 아무리 유능한 프로그래머라고 해도 결국은 사람이기 때문에 머릿속의 생각은 모국어에 묶일 수밖에 없고, 그러한 이유로 알고리즘을 구상하는 단계에서부터 프로그래밍 언어로 생각을 하는 것은 몹시 힘들고 지치는 작업이 된다. 그렇다고 마냥 자연어로 논문 쓰듯이 코드를 늘어놓자니, 가독성도 떨어지고 코딩 단계에서 그걸 다시 번역하는 과정도 필요해진다.
의사코드는 이런 두 이질적인 언어 체계인 자연어와 프로그래밍 언어 사이를 중계하는 역할을 한다. 문장 하나 하나는 자연어에 가까운 표현을 사용하지만 그걸 실제 프로그래밍과 비슷하게 실행 순서를 명시해 나열함으로써 두 언어의 장점을 적절히 취한 것이다. 의사코드는 알고리즘을 실행 가능한 코드로 옮길 때 높은 편의성을 제공하는 한편, 알고리즘을 특정 프로그래밍 언어에 종속되지 않고 보다 일반적으로 표현할 수 있게 한다. 물론 의사코드는 이 과정에서 엄밀한 문법을 포기하기에 컴퓨터가 알아들을 수는 없게 되지만, 상술했듯이 의사코드는 컴퓨터가 아닌 사람이 보라고 만드는 것이라 이런 단점은 거의 문제가 되지 않는다.
의사코드는 프로그래머들의 협업이 필요한 프로젝트에서 프로그램 제작 과정을 준비하거나 원활한 의사소통을 위해 활용되어 왔다. 일반적인 프로그램 제작 과정을 고객 요구 사항→설계도 작성→프로그램 코드 작성→테스트→디버깅이라고 한다면, 여기에 의사코드를 넣은 상황은 고객 요구 사항→설계도 작성→의사 코드 작성→프로그램 코드 작성→테스트→디버깅 정도로 생각하면 된다. 단, 실제로는 의사 코드 작성은 설계 단계의 일부로 취급하는 경우가 많다.
여러 명이서 작업하는 팀 시스템의 경우 팀을 체계적으로 관리하는 곳에서는 팀 관리에 특화된 멤버들이 투입되는 경우가 많다. 이런 사람들은 프로그래밍 코드를 이해하기 위한 지식은 별로 없거나 전문 언어가 다른 경우가 잦으므로, 그들을 앞에 두고 회의를 할 때엔 의사코드로 된 내용을 첨부하는 것이 진행에 보다 유익하다. 다만 이건 개발자와 관리자의 차이를 인식하고 있는 외국에서나 그렇고 한국은 그렇지 않을 가능성이 높은데, 한국의 IT 문화에서는 몇십 년째 코드밖에 모르고 살던 코덕 개발자가 팀 관리 방법을 배우지도 않고 그대로 팀 관리자로 넘어가는 승진 시스템을 고집하는 경우가 많아 팀 관리자가 기본적인 코드도 이해 못하는 경우는 그다지 없어서이다.
또한 시간이나 일손의 부족으로 알바생을 고용할 때, 알바생이 아무리 실력이 뛰어나다 하더라도 검증되지 않은 사람을 신용하는 것은 무리가 있다. 이러한 작업 방식은 결국 버그나 보안 취약점을 발생시킬 리스크를 안고 있기 때문이다. 이를 줄이기 위해서는 이들에게 보다 구체적으로 "더도 덜도 말고 딱 이렇게만 해!"라는 식으로 지시를 명확하게 할 필요가 있다. 이때 주로 의사 코드를 사용한다.
하지만 위의 응용은 현대에 와서는 퇴색되었는데, 프로그래밍 언어의 발전으로 Python처럼 의사코드에 가까운 간략한 문법으로 실행 가능한 언어들이 있기 때문이다. 그래서 현업에서 의사코드를 사용할 경우, 회사에서 커뮤니케이션 비효율만 쓸대없이 늘어나는 경우가 늘어났다. 의사코드를 사용하면 오히려 의사코드라는 언어를 새로 배워야 하고, 문법을 사용자가 일일이 검정해야 하는데, 반대로 상용 프로그래밍 언어들은 컴파일러가 최소한의 문법 검정과 구문 분석은 해 주기 때문에 사용하기에 오히려 더 쉬운 경우가 많다.
게다가 언어학적으로는 의사코드라도 문법이 엄밀하게 정의되면 촘스키 계층에 따라 해당 문법의 구문 분석을 기계적으로 해줄 컴파일러의 존재가 자연스럽게 수반되기 때문에 위에서 말하는 "컴퓨터가 읽어낼 필요가 없는 언어"라는 구분 자체가 의미 없다. 하지만 컴퓨터에 어셈블리로 돌려야 할 이유는 없고, 문서의 표현에만 사용하면 되기 때문에 프로그래밍 언어가 아니라 마크업 언어처럼 기능할 수는 있다.
그래서 현대에 와서는 의사코드는 수학이나 전산학에서 알고리즘을 표현할 때 정도의 학술적인 용도로 축소되었다. 학술적인 용도로는 알고리즘을 최대한 추상적으로 표현하고자 하기 때문에 특정 프로그래밍 언어에 종속되려고 하지 않는 편이다. 여기에 쓰이는 의사코드는 수식, 순서도, 집합론, 논리학 등에서 사용되는 추상적인 기호들을 섞어서 사용해서 표현하고 의사코드를 이해하는 능력은 독자의 수학적인 백그라운드에 따르는 편이라고 볼 수 있다.
3. 작성 방법
의사코드는 정해진 작성 기준이나 문법 같은 게 없다. 의사코드는 어디까지나 자신의 생각을 자연스럽게 실제 코드에 가깝게 표현할 수 있기 때문에 사용하는 것이므로, 형식이나 틀을 정해놓으면 그 장점이 퇴색되기 때문이다. 그러니 그렇게 어렵게 생각할 필요가 없다. 위에서도 설명했지만 의사코드는 프로그래밍 언어처럼 보이는 형식에 사람이 잘 이해할 수 있으면 장땡이다. 내가 만든 의사 코드로 기본적인 프로그래밍 지식이 있는 다른 사람이 실제 코드를 만들 수 있다면 더할 나위 없이 훌륭한 의사코드다.처음에는 자기가 짜려고 하는 언어의 형식에다가 영어 대신 한국어 단어나 문장을 넣는다는 느낌으로 몇 번 만들어 보면 쉽게 감을 잡을 수 있다. 다만 형식이 자유롭다고 너무 일관성 없게 코드를 작성하면 자기 외엔 아무도 알아먹을 수 없는 괴문서가 나올 확률이 높다. 표현은 널널히 하되 나름대로의 원칙은 세워두고, 타인의 작성법을 무작정 따라하기보단 여러 번 작성해 가면서 스타일을 확립해 나가는 것이 중요하다.
만약 학교에 다니고 있다면, 스터디 클럽을 만들고, A학생이 만든 의사코드로 B라는 학생이 실제 코드를 만들 수 있는지 확인해보는 방식을 사용하는 스터디 그룹을 결성하면 좋다. 의사 코드를 만드는 담당은 꾸준히 로테이션으로 바꾸면 된다. 스터디 그룹 멤버가 3명 이상이면 UML을 만드는 담당도 정해서 로테이션 돌리면 더 좋다. 혼자서 일하는 게 아니라 팀이나 회사 소속으로 일한다면, 팀 프로젝트나 회사에서 이전에 누군가 작성한 의사코드를 참고하거나, 만약 그런 것이 없다면 옆자리 동료에게 자신이 만든 의사 코드를 보여주면서 꾸준히 피드백을 받다 보면 자연스럽게 나만의 의사코드 작성 스타일이 성립된다.
4. 작성 예제
4.1. 요구 정의
#!syntax java
"a * b = 값"
의 형식으로 구구단을 2단부터 9단까지 출력한다.
4.2. 의사코드
#!syntax java
반복문 시작 (a를 2에서 9까지)
반복문 시작 (b를 1에서 9까지)
출력 : a * b = 값 (개행)
반복문 종료
반복문 종료
4.3. 완성된 코드
4.3.1. C언어
#!syntax cpp
#include <stdio.h>
int main(void) {
int i, j;
for (i = 2; i <= 9; i++) {
for (j = 1; j <= 9; j++)
printf("%d * %d = %d\n", i, j, i * j);
}
return 0;
}
4.3.2. C++
#!syntax cpp
#include <iostream>
using namespace std;
int main(void)
{
for(int A = 2; A < 10; A++)
{
for(int B = 1; B < 10; B++)
{
cout << A << " * " << B << " = " << A*B << endl;
}
}
return 0;
}
4.3.3. Java
#!syntax java
public class Foo {
public static void main(String[] args) {
for (int a = 2; a <= 9; a++)
for (int b = 1; b <= 9; b++)
System.out.printf("%d * %d = %d\n", a, b, a * b);
}
}
4.3.4. Python 3[3]
#!syntax python
for i in range(2,10):
for j in range(1,10):
print(f'{i} * {j} = {i * j}')
4.3.5. JavaScript
#!syntax javascript
for (let i = 2; i <= 9; i++)
for (let j = 1; j <= 9; j++)
console.log(`${i} * ${j} = ${i * j}`);
4.3.6. PHP
#!syntax php
foreach (range(2, 9) as $i)
foreach (range(1, 9) as $j)
echo "<p>${i} * ${j} = ${i * j}</p>";
5. 관련 문서
- 순서도 - 알고리즘을 각종 기호와 화살표로 이루어진 그림으로 표현한 것. 사실 알고리즘을 표현하는 데 있어서 순서도와 의사코드는 같은 것이라고 보면 된다. 단지 표현하는 수단이 '각종 기호와 화살표로 이루어진 그림'이냐(순서도) 아니면 '코드의 형식을 빌린 텍스트'냐(의사코드)의 차이만 있을 뿐이다.
- DSL - Domain-specific language. 의사 코드와는 다르게, DSL을 처리할 수 있는 전용 파서와 관련 툴이 존재한다는 것이 차이다. 즉 의사코드는 종이에 끼적이는 용도라면, DSL은 특정 분야에서만 쓰이는 개념을 추상화하기 위해 만든 형식 언어이다. 다만 모든 DSL이 완전한 프로그래밍 언어인 것은 아니다.
[1] '수도코드' 혹은 '슈도코드'라고 읽는다. '가짜의', '유사한'을 의미하는 접두어 'pseudo-'와 코드를 의미하는 'code'에서 유래한 단어이다.[2] 프로그래밍에서 말하는 자연어란 프로그래밍 언어가 아닌 모든 언어, 쉽게 말하면 한국어와 영어처럼 일상생활에서 평소 사용하는 모든 언어다.[3] 파이썬은 별명이 "실행할 수 있는 의사 코드(Executable pseudocode)"일 정도로 간결하다.