개요 - 프로그래머라면 당연히 알아야 할 기초 지식에 대해 #1

블로그에 굉장히 오랜만에 글을 작성하네요 ^^;

오늘은 Code Spitz 73 – ES6+ 기초편의 1회차 강의를 듣고 돌아온 내용과 기록해 두었던 내용들에 대해 정리를 한번 해볼까 합니다.

강의를 듣고 나서, 내가 알고있다고 믿고있는 것들을 정말 알고있다 표현해도 되는것일까? 라며 많이 돌아보게 되었던 귀한 시간이었습니다.

부족함 많은 글이겠지만, 오늘 들었던 것을 나름대로 정리해 보려 합니다. 아직 잘 모르거나 정확하게 알고있지 않은 것들 투성이인 사람이기에, 혹시 잘못된 부분이 보인다면 그냥 지나치지 마시고 꼭 지적 부탁드리겠습니다!


프로그램이란 무엇인가?

프로그램이란, 작성한 코드가 메모리에 적재되어 실행할 수 있는 상태로 하드웨어에 안에 존재하는 소프트웨어를 의미합니다.

전통적인 프로그램은 다음의 과정을 거치게 됩니다.

| Step             | Time         |
|------------------|--------------|
| Language Code    | Lint Time    |
| Machine Language | Compile Time |
| File             |              |
| Load             |              |
| Run              | Run Time     |
| Terminate        |              |

위와 같은 과정을 거치는 프로그래밍 언어인 경우에는 에러를 검출할 수 있는 세 번의 기회를 가집니다. Lint Time과 Compile Time, 그리고 Run Time입니다.

  • Lint Time

우리가 텍스트 에디터 또는 통합 개발 환경(IDE)을 이용해 작성한 코드는, 에디팅 툴이 지원한다면 문법적으로 어떤 부분에 오류가 있는지 검사해주는 역할을 하거나, MS의 트레이드마크인 인텔리센스와 같이 코드를 자동으로 완성하는데 도움을 주기도 합니다. 저는 이렇게 사람이 직접 코드를 작성하는 시점을 Lint Time으로 표현한 것으로 이해했습니다.

lint라는 단어는 원래 양모와 같은 섬유의 보푸라기와 같은 부분을 의미하는것으로 알려져 있는데요, 프로그래밍쪽에서 사용되기 시작한 lint란 이러한 어원으로부터 시작되어, 원래 C언어 소스코드의 잘못된 부분을 표시해줄 때 사용되던 유닉스용 프로그램의 이름이었습니다. 작성중인 소스 코드에 문법적으로 오류가 감지되면 그 부분에 오류를 어떤 방식으로든 표시해 주는 것을 lint로 표현하게 된 것으로 보입니다. 우리가 이 강의를 통해 배우게 될 ES6 문법에 대한 lint를 해주는 ESLint라는 자바스크립트 linter도 있는데, 동료가 이를 ‘코드계의 시어머니’(시어머님들께는 죄송합니다 -_-)라고 표현하더라구요. 틀리면 즉시 알려줘서, 문법을 잘못 사용하여 발생할 수 있는 이후의 시간 낭비를 줄여주는 역할을 해 줍니다.


  • Compile Time

이렇게 Lint Time을 무사히 통과한 소스는 컴퓨터가 이해할 수 있는 언어인 기계어로의 번역이 필요합니다. 이를 컴파일이라고 하며, 이 컴파일을 하는 시점을 Compile Time이라고 표현합니다. 이때 오류가 발생한다면, 이를 Compile Time Error로 표현할 수 있을 것입니다.


  • Run Time

Compile Time을 거쳐 파일이 생성되고, 이 파일을 메모리에 적재하기 위해 만들어진 프로그램을 통해 메모리에 올리고 나면 CPU를 비롯한 여러 컴퓨터 자원을 이용하여 프로그램을 실행하게 됩니다. 이렇게 프로그램이 실행되고 있는 시점을 Run Time이라고 부르며, 이때 검출되는 오류가 있다면 이것은 Rum Time Error로 표현할 수 있을 것입니다.

위 과정을 거치는 동안에도 검출할 수 없는 오류가 있습니다. 그것은 정말 지옥과도 같은 오류인데요, 이를 Context Error로 표현한다고 합니다. 예를들어, 슈팅 게임을 하다가 3번째 스테이지의 보스를 만났을 때 폭탄을 두 번 사용하면 게임이 멈춘다거나, 월급날에 자동으로 입금하는 프로그램을 작성했는데 이 금액이 절반씩 들어온다거나 하는 것들을 의미합니다. (정말 끔찍하네요 ㄷㄷ)


자바스크립트와 같은 스크립트 언어

자바스크립트와 같은 스크립트 언어들은 복잡한 컴파일 타임 없이 런타임 스크립트를 도입하게 됩니다. 이러한 언어를 통해 작성된 프로그램은 다음과 같은 과정을 거치게 됩니다.

| Step             | Time         |
|------------------|--------------|
| Language Code    | Lint Time    |
| File             |              |
| Load             |              |
| Machine Language |              |
| Run              | Run Time     |
| Terminate        |              |

Lint Time에서 Compile Time을 거치지 않고 바로 Run Time으로 넘어갑니다.


자바스크립트 엔진이 소스코드를 컴파일하는 과정

최근의 Javascript 엔진들은 대부분 Adaptive JIT Compilation 방식을 택하고 있다고 합니다. Adaptive compilation이란, 모든 코드를 일괄적으로 같은 수준의 최적화를 적용하는 것이 아니라, 반복 수행되는 정도에 따라 유동적으로(adaptive) 서로 다른 최적화 수준을 적용하는 방식입니다. (이곳을 클릭하여 자세한 내용을 확인하실 수 있습니다.)

위 링크를 통해 확인해보면, 굉장히 복잡한 방식을 통해 최적화된 컴파일 처리를 하고 있음을 알(?!?) 수 있습니다…


스크립트 개발론

A가 B에게 불리울 수 있으려면, B에게 A는 반드시 static한 존재여야 합니다. 내가 그를 부르기 위해서는 그가 세상에 이미 존재해야만 합니다. 즉, static한 존재로 이미 존재하고 있는 대상을 통해서만 존재할 수 있는(…) 의존성을 가진 존재의 입장에서는, 그가 static해야만 자기 자신이 runtime에 존재할 수 있게 됩니다. 하지만 그러한 대상을 또 다른 자식이 참조해야 하는 상황이 된다면? 아까는 runtime에 존재했던 것이 새로 생길 대상에게는 static한 존재여야만하는 거겠죠.

이러한 상대적인 개념으로, 어떠한 가치를 지닌 존재들끼리의 구분선이 상대적으로 생성되게 됩니다. 이것을 ‘격리(isolation)’라고 표현합니다. 컴파일 시에 오류를 검출해낼 수 있는 것 처럼, 스크립트 언어에서는 그러한 과정이 없기 때문에 보완할 수 있는 방법은 이것밖에 없게 된다고 합니다. 즉, 어떤 대상이 오류를 가지게 되는지 정확하게 확정할 수 있도록 임의의 구간을 인간이 만들어 두는 것을 격리라고 표현합니다. 그 구간이 바로 격리 구간이 되는 것입니다.

제가 그렇듯 개발에 부족함이 있는 사람들이 개발 과정에서 어려움을 겪는 이유는, 격리에 대한 개념이 희박하거나 없기 때문에 개체간에 어느정도까지 책임을 위임하게 하고 어떤 행위는 누구의 책임인지, 또는 이러한 특질은 어떤 개체가 가져야만 하는가에 대한 충분한 고려 없는 설계과정을 거쳐 코딩을 하는 것으로부터 기인한다고 생각합니다. 어떤 행위가 누가 가져야하는 책임인지, 즉 부장이 작성한 서류에 대해 사원이 최종 결재권자가 될 수 있다거나 하는 식의 일이 일어나면 매우 곤란하지 않을까요? (실제로 일어나면 재밌겠네요 -_-)


Lexical Grammer

한글을 배우기 위해서는, 한글을 구성요소를 배우는 것이 당연하듯, 자바스크립트 세계에서도 마찬가지입니다. 자바스크립트에서 정한 문법 요소들은 다음과 같습니다.

  • Control characters (제어문자)

눈에 보이지 않지만 자바스크립트 엔진한테 일을 시킬 때 사용할 수 있는 문자라고 합니다. 한국어 문화권에서는 쓸일이 없다고 하네요. 참고 링크는 여기에 있습니다.

  • White space (공백문자)

자바스크립트 엔진이 공백으로 인식하는 문자들을 의미합니다. 우리가 일반적으로 스페이스바를 이용하여 입력하는 공백문자나, 스페이스바나 자바스크립트 엔진에게는 똑같은 공백문자로 인식됩니다. 총 6가지의 공백 문자가 존재합니다.

  • Line terminators (개행문자)

줄바꿈을 인식할 때 사용하는 문자입니다. 자동 세미콜론 삽입(ASI) 규칙(개행문자를 만났을 때 세미콜론이 없으면 자바스크립트 엔진이 알아서 세미콜론을 붙여주는 것)에도 영향을 주는 문자입니다. Line Feed, Carriage Return 외 LS/PS 총 4가지 문자가 개행 문자로 존재합니다.

  • Comments (주석)

자바스크립트 엔진이 주석을 만나면 무시하고 지나칩니다. 100% 사람을 위한 문법입니다.

  • Keywords (예약어)

자바스크립트 엔진이 이 예약어를 만나면 특별한 행위를 하도록 되어있습니다. ES6 기준 총 33개의 예약어가 있는 것으로 파악됩니다. 자세한 정보는 여기의 Keywords 섹션을 참고하시면 됩니다.

  • Literals (리터럴)

언어에서 더이상 쪼갤 수 없는 값의 표현을 의미합니다. 만약 37이라는 숫자를 표현하고자 할 때, 이보다 더 작은 단위로 37이라는 숫자를 표현할 수 있는 방법이 있을까요? 존재하지 않습니다. 이러한 것을 리터럴이라고 표현합니다. 늘릴 수 있는 방법은 매우 많습니다. 30 + 7로 표현할 수도 있고, 이보다 더 많은 + 연산자를 사용하여 표현할 수도 있지만, 이것은 가장 작은 단위의 표현입니다. 말 그대로 이러한 것을 리터럴이라고 표현합니다.


마치며

이 외 Language Element인 Statement, Expression, Identifier[, Comments]와 Flow Control 대한 강의도 함께 들었으며 이 부분 역시 매우 중요한 부분이지만, 시간 관계상 나머지는 다음 게시글로 이어 작성할 수 있도록 할 계획입니다. 특히 의도를 코드에 담는다는 것에 대한 참된 의미의 힌트를 조금 맛보게된 것 같아서, 아주 미세한 느낌의 차이를 변수가 아닌 제어문을 통해 표현할 수 있음에 대해 처음으로 느낄 수 있었던 것은 정말 행운과도 같았던 것 같습니다.

혹시 읽으시던 도중 잘못된 내용이 있거나 보충해주시고 싶은 내용이 있다면 꼭 댓글 달아주셨으면 좋겠습니다!

읽어주셔서 감사합니다 :)