Java 04
변수: 값에 이름 붙이는 마법
자료형, 변수명, 대입, 초기화가 한 줄에 섞여 있어 값을 저장한다는 감각보다 문법 순서만 보인다.
근거 · 교안 p30-p36
1장: 값에 이름 붙이기, 왜 필요할까?
1장. 값에 이름 붙이기, 왜 필요할까?
솔라의 손가락이 노트북 터치패드 위에서 초조하게 맴돌았다. 화면에는 솔라가 방금 작성한 몇 줄 안 되는 코드 조각이 떠 있었다. 복잡한 프로그램은 아니었다. 간단한 게임 시나리오를 흉내 내 본, 어설픈 계산식 몇 개가 전부였다. 하지만 솔라의 미간은 잔뜩 찌푸려져 있었다.
“아, 진짜….”
작게 터져 나온 짜증 섞인 목소리에, 옆에서 조용히 책을 읽던 언니 루나가 고개를 들었다. 루나는 아무 말 없이 솔라의 노트북 화면을 곁눈질했다.
System.out.println("포션을 사용했습니다. 체력이 30 회복되었습니다.");
playerHP = playerHP + 30;
System.out.println("몬스터를 공격했습니다! 50의 데미지를 입혔습니다.");
monsterHP = monsterHP - 50;
System.out.println("상점에서 포션을 구매했습니다. 30 골드가 필요합니다.");
playerGold = playerGold - 30;
“왜 그래?”
루나의 차분한 물음에 솔라는 의자를 휙 돌려 언니를 마주 봤다.
“언니, 이것 좀 봐. 내가 게임에서 포션의 회복량을 30에서 50으로 바꾸고 싶거든? 근데 코드에 ‘30’이 너무 많아. 첫 줄에 있는 ‘30’은 포션 회복량이 맞는데, 마지막 줄에 있는 ‘30’은 포션 가격이잖아. 만약 내가 깜빡하고 가격까지 50으로 바꿔버리면 어떡해?”
솔라의 말대로였다. 화면 속 숫자 ‘30’은 그 자체로는 아무런 의미를 말해주지 않았다. 체력을 회복시켜주는 양인지, 물건을 사는 데 필요한 돈인지, 오직 코드를 읽는 사람이 앞뒤 문맥을 보고 파악해야만 했다. 지금은 코드가 세 줄뿐이라 금방 구분할 수 있지만, 수백, 수천 줄이 된다면 어떨까? 생각만 해도 아찔했다.
“하나씩 찾아서 바꾸는 것도 일인데, 실수할까 봐 더 걱정돼. 포션 회복량만 바꾸려다가 상점 물가까지 다 올려버릴 수도 있잖아.”
솔라는 한숨을 쉬며 덧붙였다. “분명히 ‘변수’라는 걸 쓰면 된다고 배웠는데… int a = 10; 같은 거. 근데 그게 그냥 문법 규칙 같아서 와닿지가 않아. 자료형 쓰고, 이름 짓고, 값을 넣는 순서만 외웠지, 이걸 왜 이렇게 써야 하는지는 모르겠어.”
솔라의 시선은 다시 화면으로 향했다. 뒤섞인 문법 요소들보다, 당장 눈앞의 ‘30’이라는 숫자를 안전하게 바꾸는 것이 더 큰 문제처럼 느껴졌다.
루나는 잠시 생각에 잠기더니, 솔라의 책상 위에 놓인 메모지와 펜을 끌어당겼다. 그리고는 솔라가 짠 코드를 간단히 옮겨 적기 시작했다. 하지만 숫자 부분은 빈칸으로 남겨두었다.
체력 회복: [ ]
포션 가격: [ ]
“솔라, 네가 지금 바꾸고 싶은 값은 ‘포션의 체력 회복량’이지? 그리고 변하지 말아야 할 값은 ‘포션의 가격’이고.”
“응, 맞아.”
“만약 이 두 숫자에 각각 이름을 붙여준다면 어떨까? 그냥 ‘30’이라고 쓰는 대신에.”
루나는 펜을 들어 빈칸 위에 작은 글씨로 이름을 적었다.
체력 회복: [potionHealAmount]
포션 가격: [potionPrice]
솔라는 루나가 적은 글씨를 가만히 들여다보았다. potionHealAmount, potionPrice. 영문이었지만 의미는 명확하게 들어왔다. ‘포션 치유량’, ‘포션 가격’.
“이렇게 이름을 붙여놓고…,” 루나는 메모지 위쪽에 이렇게 덧붙였다.
potionHealAmount = 30
potionPrice = 30
“이렇게 각 이름이 어떤 값을 가리키는지 맨 위에 한 번만 정해두는 거야. 그리고 코드에서는 숫자 대신 이름을 쓰는 거지.”
루나는 솔라의 코드를 흉내 내 다시 적었다.
체력 += potionHealAmount
골드 -= potionPrice
“만약 포션 회복량을 50으로 바꾸고 싶으면, 이제 어디를 고쳐야 할까?”
“어…?” 솔라는 잠시 멍하니 메모지를 보다가 무릎을 탁 쳤다. “아! 맨 위에 적어둔 potionHealAmount = 30을 potionHealAmount = 50으로 딱 한 번만 바꾸면 되겠네!”
그녀의 목소리에 흥분이 실렸다. 이제 더 이상 코드 속 수많은 숫자들을 뒤지며 이게 회복량인지 가격인지 고민할 필요가 없었다. potionHealAmount라는 이름이 붙은 곳은 모두 알아서 50으로 바뀐 것처럼 동작할 테고, potionPrice는 전혀 영향을 받지 않을 터였다. 반복되는 작업을 줄여주는 것은 물론, 실수의 가능성까지 원천적으로 차단하는 방법이었다.
“그리고… 이렇게 이름을 붙여두니까 나중에 다른 사람이 코드를 봐도 ‘아, 이건 포션 치유량이구나’하고 바로 알 수 있겠다.”
솔라는 감탄하며 중얼거렸다. 이전까지 문법 규칙의 나열로만 보였던 변수가, 비로소 ‘값에 의미 있는 이름을 붙이는 마법’처럼 느껴지는 순간이었다. 그냥 값을 저장하는 것을 넘어, 코드를 읽는 사람을 위한 친절한 안내판을 세우는 행위였던 것이다.
“바로 그거야.” 루나가 부드럽게 말했다. “그게 우리가 값에 이름을 붙이는, 변수를 사용하는 가장 중요한 이유 중 하나야. 컴퓨터를 위해서이기도 하지만, 미래의 나, 그리고 함께 일할 다른 사람들을 위해서.”
솔라는 고개를 끄덕였다. 이제 int potionHealAmount = 30; 이라는 코드가 다르게 보였다. 여전히 int가 무엇인지, 컴퓨터가 potionHealAmount라는 이름을 어디에 어떻게 저장해두는지는 궁금했지만, 적어도 ‘왜’ 이름이 필요한지는 확실히 알 것 같았다.
문득, 솔라는 새로운 의문에 사로잡혔다.
“언니, 그런데 ‘이름을 붙인다’는 건 알겠어. 그럼 컴퓨터는 이 이름을 어디에 기억해두는 거야? potionHealAmount라는 이름표랑 ‘30’이라는 값을 담아두는 상자라도 있는 건가?”
2장: 변수, 어떤 값을 담을지 미리 정하기 (선언)
솔라의 질문이 끝나자, 루나는 말없이 자리에서 일어났다. 그리곤 방 한쪽에 놓인 작은 수납장으로 향했다. 잠시 뒤적이는 소리가 들리더니, 루나는 손바닥만 한 빈 상자 두 개와 포스트잇 한 뭉치를 들고 돌아왔다. 예전에 차를 마시고 남겨둔 티백 상자처럼 보였다. 루나는 상자들을 솔라와 자신의 사이, 책상 한가운데에 나란히 놓았다. 갑작스러운 실물 소품의 등장에 솔라는 어리둥절한 표정으로 언니와 상자들을 번갈아 쳐다봤다.
루나는 아무 말 없이 포스트잇 한 장을 떼어내 펜으로 무언가를 적기 시작했다. 그리고 첫 번째 빈 상자 정면에 꾹 눌러 붙였다. 솔라가 고개를 기울여 라벨처럼 붙은 포스트잇을 읽었다.
종류: 숫자 (정수) 이름:
potionHealAmount
“이게… 내가 말한 그 ‘상자’야?” 솔라가 조심스럽게 물었다.
“응, 네 말이 맞았어. 컴퓨터도 비슷하게 값을 담아둘 상자를 준비해.” 루나는 상자를 가리키며 말했다. “그리고 방금 네가 본 코드, int potionHealAmount; 가 하는 일이 바로 이거야. 상자를 준비하고, 라벨을 붙이는 일.”
솔라는 눈을 동그랗게 떴다. 그녀의 시선이 코드 조각과 라벨이 붙은 상자 사이를 오갔다. int와 potionHealAmount. 이전까지는 그저 순서에 맞춰 써야 하는 문법 기호의 나열로 보였다. 하지만 지금, 눈앞의 상자와 라벨은 그 기호들이 실은 구체적인 ‘지시’였음을 보여주고 있었다.
“잠깐만. 그럼 int라는 게… 이 상자에는 ‘숫자’만 담을 수 있다고 종류를 정해주는 거고, potionHealAmount는 그 상자에 붙이는 이름표인 거야?”
“바로 그거야. int는 정수(integer)를 뜻하는 약속이야. 컴퓨터에게 ‘지금부터 정수를 담을 공간을 하나 만들 건데, 크기는 이 정도로 해줘’ 하고 알려주는 거지. 그리고 그 공간에 potionHealAmount라는 이름을 붙여서 우리가 쉽게 찾아 쓸 수 있도록 하는 거고.”
루나는 두 번째 빈 상자를 솔라 쪽으로 살짝 밀었다. 포스트잇과 펜도 함께였다.
“만약 네 게임 캐릭터의 이름, 예를 들어 ‘솔라’라는 글자들을 저장하고 싶다면, 어떤 라벨을 붙여줘야 할까?”
솔라는 잠시 망설이다 펜을 집어 들었다. 그리곤 또박또박 포스트잇에 적어 내려갔다.
종류: 글자들 (문자열) 이름:
characterName
자신이 쓴 라벨을 두 번째 상자에 붙이고 나자, 솔라는 무언가 중요한 것을 깨달았다는 표정을 지었다. “아! 알겠다. 값을 넣기 전에, 어떤 종류의 값을 담을지 미리 알려주고, 그 공간에 이름표를 붙여서 ‘예약’해두는 거구나. 그래서 int나 String 같은 자료형을 먼저 쓰는 거였어.”
이전까지 솔라에게 변수 선언은 의미 없는 문법 규칙이었다. 하지만 이제는 달랐다. 무작정 외우던 행위가 ‘값을 담을 공간을 용도에 맞게 준비하는’ 구체적인 이미지로 전환되는 순간이었다. 컴퓨터의 보이지 않는 공간에서 일어나는 일이, 눈앞의 상자와 라벨처럼 명확하게 이해되기 시작했다.
“맞아. 그렇게 값을 담을 공간을 미리 마련하고 이름 붙이는 행위를 우리는 **‘변수를 선언한다’**고 불러.” 루나가 차분하게 정리해주었다.
솔라는 자신이 라벨을 붙인 두 개의 상자를 나란히 보았다. potionHealAmount 상자와 characterName 상자. 둘 다 말끔한 이름표를 달고 주인을 기다리는 것처럼 보였다. 그런데 둘 다 텅 비어 있었다. 그 사실을 깨닫자 솔라의 머릿속에 새로운 질문이 떠올랐다.
“언니, 이제 상자는 다 준비됐어. ‘정수’를 담을 상자도 있고, ‘글자’를 담을 상자도 있고. 그런데… 아직 비어 있잖아. 여기에 어떻게 진짜 값, 그러니까 숫자 ‘30’이나 ‘솔라’라는 글자를 넣는 거야?”
3장: 선언한 변수에 처음 값을 넣기 (초기화)
솔라의 질문이 남긴 조용한 정적 속에서, 루나는 책상 위에 놓인 두 개의 빈 상자를 말없이 바라보았다. 하나는 ‘종류: 숫자, 이름: potionHealAmount’ 라벨이, 다른 하나는 ‘종류: 글자들, 이름: characterName’ 라벨이 붙어 있었다. 상자는 있었지만, 그 안은 텅 비어 있었다. 그 모습이 꼭 아직 열리지 않은 선물 상자 같았다.
루나는 다시 포스트잇 한 장을 떼어냈다. 그리고는 펜으로 숫자 ‘30’을 큼직하게 썼다. 그 포스트잇을 떼어내 potionHealAmount 상자 옆에 나란히 내려놓았다. 라벨이 붙은 빈 상자와, 그 안에 들어가야 할 내용물이 비로소 분리되어 눈앞에 놓인 순간이었다. 솔라의 시선이 두 개의 대상을 번갈아 좇았다. ‘이름표가 붙은 공간’과 그 공간에 담길 ‘실제 값’.
“아….”
솔라는 나지막이 탄성을 내뱉었다. 그리고는 마치 자석에 이끌리듯, 숫자 ‘30’이 적힌 포스트잇을 집어 들었다. 그녀는 잠시 망설이더니, potionHealAmount 라벨이 붙은 상자의 열린 틈으로 그 포스트잇을 쏙 집어넣었다. 상자가 제 주인을 찾은 듯 완벽하게 들어맞았다.
“이거네. 상자를 준비하고(선언), 그 안에 값을 집어넣는 거.”
솔라가 만족스러운 표정으로 말했다.
“바로 그거야.” 루나가 조용히 동의하며, 솔라가 방금 한 행동을 코드로 표현해주었다. 그녀는 새 메모지에 이렇게 적었다.
potionHealAmount = 30;
솔라는 코드를 뚫어지게 쳐다봤다. “어, 나는 그냥 포스트잇을 상자에 넣었을 뿐인데… 그게 이 코드였어? 이 등호(=)가 ‘넣는다’는 뜻이구나!”
“맞아. 수학에서는 ‘같다’는 뜻이지만, 프로그래밍에서는 ‘오른쪽의 값을 왼쪽의 상자에 넣어라’라는 대입 명령이야. 그래서 이걸 ‘대입 연산자’라고 불러.”
루나의 설명에 솔라는 무릎을 탁 쳤다. “아! 그래서 int potionHealAmount = 30; 이렇게 한 줄로 쓰는 거였구나! 나는 이 한 줄이 그냥 외워야 하는 주문인 줄 알았어. 그런데 사실은 int potionHealAmount; 로 ‘정수를 담을 상자를 만들고’, potionHealAmount = 30; 으로 ‘그 상자에 30을 넣는’ 두 가지 행동을 합쳐놓은 거였네!”
솔라의 목소리에는 흥분이 가득했다. 지금까지 하나의 덩어리로 보였던 문법이 비로소 두 개의 논리적인 단계로 분리되어 이해되기 시작했다. 선언과 대입. 공간을 마련하는 행위와 그 공간을 처음 채우는 행위. 너무나 당연한 순서였다.
“정확해. 그렇게 변수를 선언하고, 처음으로 값을 대입해서 채워주는 행위를 우리는 **‘초기화(initialization)’**라고 불러. 말 그대로 텅 빈 상태에서 쓸모 있는 초기 값을 설정해준다는 뜻이지.”
‘초기화’. 솔라는 그 단어를 입안에서 굴려보았다. 값을 담을 상자를 처음으로 채워주는 행위. 그저 값을 넣는다는 표현보다 훨씬 더 명확하고 의미 있는 이름처럼 느껴졌다.
솔라는 자신감을 얻어, 두 번째 상자인 characterName을 향해 손을 뻗었다. 스스로 포스트잇에 ‘솔라’라고 적고, 따옴표로 감싸는 것도 잊지 않았다. 그리곤 그 포스트잇을 상자 안에 넣으며 입으로 코드를 읊조렸다.
“String characterName = "솔라";”
이제 두 상자는 모두 제 값을 품고 있었다. 하나는 숫자 30을, 다른 하나는 ‘솔라’라는 글자를. 텅 비어 있던 상자들이 비로소 제 역할을 할 준비를 마친 것처럼 보였다.
솔라는 자신이 완성한 두 개의 상자를 뿌듯하게 바라보다가, 문득 라벨에 적힌 이름들을 다시 한번 유심히 보게 되었다. potionHealAmount와 characterName. 언니가 처음 썼던 이름과, 자신이 방금 쓴 이름.
“언니, 그런데 이름은 왜 이렇게 지었어? potionHealAmount처럼 단어 여러 개를 붙여 쓰는데, 중간에 대문자가 들어가네. characterName도 그렇고. 그냥 potion이나 name이라고 짧게 쓰면 안 되는 거야? 아니면 potion_heal_amount처럼 써도 되나? 이름 짓는 데에도 뭔가 약속이 있는 거야?”
4장: 변수 이름을 짓는 약속 (이름 규칙)
4장. 변수 이름을 짓는 약속 (이름 규칙)
솔라의 질문이 방 안의 공기를 가볍게 흔들었다. 루나는 대답 대신, 솔라 앞에 놓여 있던 노트북을 자기 쪽으로 살짝 돌렸다. 그리고는 아무 말 없이 새로운 코드를 입력하기 시작했다. 이전의 게임 시나리오와는 전혀 상관없는, 완전히 새로운 코드 조각이었다. 솔라는 언니의 손끝에서 나타나는 글자들을 잠자코 지켜보았다.
int a = 20;
int b = 24;
int c = a * b * 7;
System.out.println(c);
짧은 코드가 완성되자, 루나는 화면을 가리키며 솔라를 바라보았다. 질문은 눈빛에 담겨 있었다. 솔라는 미간을 살짝 찌푸리며 코드를 해석하기 시작했다. 컴퓨터가 이 코드를 어떻게 실행할지는 명확했다. 20과 24를 곱하고, 다시 7을 곱한 결과를 화면에 보여줄 것이다. 암산으로도 가능한 간단한 계산이었다.
“음… 20 곱하기 24는 480이고, 거기에 7을 곱하면… 3360. 화면에 3360이 출력되겠네.”
솔라는 계산 결과를 말했지만, 어딘가 개운치 않은 표정이었다.
“그런데… 이게 다야? a, b, c가 대체 뭔데? 그냥 아무 의미 없는 숫자들 같은데. 이게 월급 계산이야? 아니면 게임 점수? 이 코드만 봐서는 도대체 뭘 계산한 건지 전혀 모르겠어.”
솔라의 목소리에는 답답함이 묻어났다. 코드를 실행하는 컴퓨터에게는 a, b, c라는 이름으로도 충분하겠지만, 그것을 읽는 사람에게는 암호나 다름없었다. 짧고 간결해서 편해 보였지만, 실상은 의미를 파악하기 위해 더 많은 노력을 요구하는 불친절한 코드였다.
그때 루나가 다시 키보드를 두드렸다. 방금 작성했던 코드의 변수 이름들을 하나씩 바꾸기 시작했다. a, b, c가 지워지고 새로운 이름들이 그 자리를 채웠다.
int workHoursPerDay = 20;
int workDaysPerMonth = 24;
int monthlyWage = workHoursPerDay * workDaysPerMonth * 7;
System.out.println(monthlyWage);
코드가 바뀌는 순간, 솔라의 눈이 동그래졌다. “아!”
수수께끼가 풀리는 듯한 짧은 탄성이 터져 나왔다. 숫자는 그대로였지만, 변수 이름이 바뀌자 코드의 모든 것이 명확해졌다. workHoursPerDay는 하루 근무 시간, workDaysPerMonth는 한 달 근무 일수, 그리고 monthlyWage는 그 모든 것을 곱한 월급. 7이라는 숫자의 의미는 여전히 불분명했지만, 적어도 이 코드가 월급을 계산하는 중이라는 사실은 누구라도 알 수 있었다.
“이제 알겠지?” 루나가 처음으로 입을 열었다. “컴퓨터에게는 첫 번째 코드나 두 번째 코드나 아무 차이가 없어. 똑같이 3360을 계산할 뿐이야. 하지만 이걸 읽는 사람에게는 완전히 다른 이야기지. 이름은 컴퓨터를 위한 명령이기도 하지만, 우리, 사람을 위한 약속이기도 해.”
솔라는 고개를 주억거렸다. potionHealAmount, characterName처럼 여러 단어를 붙여 쓰면서 중간에 대문자를 넣는 이유가 바로 이것이었다. potionhealamount나 potion_heal_amount보다 potionHealAmount처럼 단어의 시작을 대문자로 구분해주는 방식(카멜 케이스, camelCase)이 여러 단어를 훨씬 쉽게 읽을 수 있게 해주는, 사람들 사이의 약속이었던 것이다.
“그럼 변수 이름을 지을 때 지켜야 하는 건, 이런 ‘약속’들뿐이야? 아니면 꼭 지켜야만 하는 ‘규칙’도 있어?”
“둘 다 있어.” 루나는 간결하게 답했다. “컴퓨터가 혼동하지 않도록 반드시 지켜야 하는 규칙이 있고, 다른 개발자와 나 자신을 위해 지키는 게 좋은 관례(convention), 즉 약속이 있지.”
루나는 메모지에 간단히 정리해주었다.
[규칙: 안 지키면 에러!]
class,int처럼 이미 약속된 단어(예약어)는 이름으로 쓸 수 없어.- 숫자로 시작할 수 없어. (
1stPlayer는 안 되지만player1은 돼.) +,-같은 특수문자는 대부분 안 되지만_와$는 예외적으로 가능해.
[관례: 더 좋은 코드를 위한 약속]
- 이름만 봐도 용도를 알 수 있게 의미 있는 이름으로 짓기. (
a대신workHoursPerDay) - 여러 단어를 합칠 땐
camelCase방식으로 가독성 높이기.
솔라는 메모를 꼼꼼히 읽어보았다. 이전에는 그저 외워야 할 제약 조건으로 보였던 것들이, 이제는 명확한 이유를 가진 지침으로 보였다. 규칙은 컴퓨터와의 소통을 위한 최소한의 문법이었고, 관례는 사람과의 소통을 위한 배려였다. 변수 이름 하나를 짓는 데에도 코드를 읽을 누군가를 생각하는 마음이 담겨야 한다는 것을 깨닫는 순간이었다.
“그랬구나… 변수 이름은 그냥 나 편하자고 a, b, c로 짓는 게 아니었어. 미래의 내가, 혹은 다른 팀원이 이 코드를 봤을 때 ‘이 변수는 이런 값을 담아두는 상자구나’ 하고 바로 이해할 수 있도록 붙이는 안내판 같은 거였네.”
솔라는 자신이 처음 만들었던 potionHealAmount와 characterName이라는 이름을 떠올렸다. 이제 그 이름들이 훨씬 더 자랑스러워 보였다.
모든 조각이 맞춰지는 느낌에 잠시 만족하던 솔라의 머릿속에, 문득 흩어져 있던 개념들이 떠올랐다. 값에 이름을 붙여주면 편하다는 것을 깨달았고(필요성), 값을 담을 상자의 종류와 이름을 정해 준비했고(선언), 그 상자에 처음으로 값을 넣었다(초기화). 그리고 이제, 그 상자의 이름을 잘 짓는 법까지 알게 되었다. 하지만 여전히 무언가 마지막 한 걸음이 남은 기분이었다.
“언니, 이제 변수를 왜 쓰는지, 어떻게 선언하고 초기화하는지, 이름은 어떻게 지어야 하는지도 알겠어. 그런데 이 모든 과정이… 각각 따로 노는 느낌이야. 이 모든 행동들이 결국 ‘값에 이름을 붙인다’는 하나의 목표로 어떻게 합쳐지는 거지?”
5장: 이름 붙인 값, 이제 제대로 활용하자!
5장. 이름 붙인 값, 이제 제대로 활용하자!
솔라의 마지막 질문이 남긴 여운 속에서, 루나는 말없이 책상 위를 정리하기 시작했다. 솔라가 막 값을 채워 넣었던 두 개의 상자를 다시 비웠다. ‘potionHealAmount’ 라벨이 붙은 상자, ‘characterName’ 라벨이 붙은 상자, 숫자 ‘30’이 적힌 포스트잇, ‘솔라’라고 적힌 포스트잇. 루나는 그것들을 솔라 앞에 나란히 두지 않고, 마치 아무렇게나 흩어놓은 부품들처럼 책상 위에 띄엄띄엄 늘어놓았다. 마치 선언, 초기화, 이름 규칙이라는 개념들이 솔라의 머릿속에서 따로 떠다니는 모습을 그대로 옮겨놓은 듯했다.
솔라는 흩어진 조각들을 멍하니 내려다보았다. 상자를 준비하는 행위(선언), 값을 써넣는 행위(초기화), 이름을 잘 짓는 규칙. 모두 이해했지만, 이것들을 언제, 어떤 순서로 엮어내야 하나의 의미 있는 행동이 되는지 여전히 막막했다. 솔라는 자기도 모르게 중얼거렸다.
“이게 딱 내 머릿속 같아. 재료는 다 있는데, 이걸로 뭘 어떻게 만들어야 할지… 따로따로인 느낌.”
루나는 대답 대신 솔라의 노트북을 다시 가져와 화면을 켰다. 빈 코드 에디터가 창백한 빛을 밝혔다.
“요리법을 외우는 대신, 직접 만들 요리를 정해보는 건 어때?” 루나가 부드럽게 제안했다. “아주 간단한 게임을 하나 만든다고 상상해 봐. 하늘에서 떨어지는 별을 받아먹는 게임이야. 우리는 이 게임에 필요한 정보를 컴퓨터에게 기억시켜야 해. 어떤 정보들이 필요할까?”
‘만들 요리를 정하기.’ 그 말이 솔라의 마음에 와닿았다. 지금까지는 주어진 코드의 문법을 분석하는 데 급급했다면, 이제는 풀어야 할 문제에서부터 시작하는 것이었다.
솔라는 잠시 눈을 감고 게임 화면을 상상했다. 반짝이는 별, 그걸 받아먹는 내 캐릭터, 화면 한쪽에 표시될 점수…
“일단… 내 점수가 필요해! 별을 먹을 때마다 올라가는 점수.” 솔라가 가장 먼저 떠오른 것을 말했다.
“좋아, ‘플레이어의 점수’. 그걸 변수로 만들어보자. 어떤 순서로 생각해야 할까?”
솔라는 눈앞의 흩어진 조각들과 빈 화면을 번갈아 보았다. ‘점수’라는 값을 담아야 한다. 그러자 머릿속에서 흩어져 있던 과정들이 스스로 자리를 찾아가기 시작했다.
‘첫째, 점수는 100점, 200점 같은 숫자니까… 정수(int) 상자가 필요하겠네.’
솔라는 상자의 종류, 즉 자료형을 가장 먼저 떠올렸다. 이것은 선언의 시작이었다.
‘둘째, 상자에 이름을 붙여줘야지. 그냥 score라고 해도 되지만… 나중에 다른 점수랑 헷갈릴 수 있으니 playerScore 가 좋겠다.’
사람을 위한 약속, 이름 규칙이 자연스럽게 따라왔다.
‘셋째, 게임은 0점에서 시작해야지. 그럼 상자를 만들 때 아예 0을 넣어두는 게 맞겠어.’ 처음 가져야 할 값, 초기화의 필요성을 느꼈다.
솔라는 마치 물 흐르듯 생각의 흐름을 따라 키보드에 손을 올렸다. 그리고 한 줄의 코드를 입력했다.
int playerScore = 0;
코드를 입력하고 난 솔라는 잠시 숨을 멈췄다. 방금 자신이 한 행동을 되짚어보았다. 자료형을 고민하고, 의미 있는 이름을 짓고, 초기 값을 정하는, 이전 장들에서 각각 배웠던 모든 행위가 이 한 줄의 코드를 완성하기 위한 유기적인 사고 과정이었던 것이다. 따로 노는 부품이 아니라, ‘플레이어의 점수를 0점으로 기록해둔다’는 하나의 목표를 가진 문장이었다.
“아!”
솔라는 짧은 탄성을 터뜨렸다.
“int playerScore = 0; 이라는 코드는 그냥 문법 순서가 아니었어! ‘**정수(int)**를 담을 공간을 만들고, 거기에 playerScore 라는 이름을 붙인 다음, 처음 값으로 0을 넣어줘’ 라고 컴퓨터에게 내 생각을 순서대로 이야기하는 거였구나!”
솔라의 목소리에는 이제껏 없던 확신이 담겨 있었다. 변수를 만드는 행위가 더 이상 낯선 외국어를 흉내 내는 것이 아니라, 자신의 생각을 논리적으로 표현하는 과정임을 깨달은 순간이었다.
“하나 더. 플레이어의 목숨도 필요해. 보통 3개로 시작하잖아.”
솔라는 망설임 없이 다음 코드를 작성했다.
int playerLives = 3;
그녀는 이제 ‘정수 타입의, playerLives라는 이름의, 초기값 3을 가진 변수를 만든다’고 생각하지 않았다. 그저 ‘플레이어 목숨을 3개로 시작한다’는 게임의 규칙 하나를 코드로 옮겼을 뿐이다. 선언, 이름 짓기, 초기화는 이미 그녀의 사고 과정에 자연스럽게 녹아들어 있었다.
루나는 조용히 지켜보다가, 처음 변수에 대해 찾아봤던 책의 한 구절을 읊어주었다.
“‘변수는 데이터를 저장하기 위해 이름을 붙인 메모리 공간이다.’”
예전 같았으면 ‘메모리 공간’이라는 추상적인 단어에 막혔을 것이다. 하지만 이제 솔라에게 그 문장은 완전히 다르게 들렸다.
‘데이터를 저장하기 위해(왜?)’ -> ‘플레이어 점수나 목숨 같은 정보를 기억해두려고.’
‘메모리 공간(어디에? 어떻게?)’ -> ‘컴퓨터에게 int 같은 종류를 알려주고 상자를 만들어서.’
‘이름을 붙인(무엇으로?)’ -> ‘playerScore처럼 나중에 내가 알아보기 쉬운 이름으로.’
딱딱한 정의가 비로소 자신의 경험과 연결되어 살아있는 의미를 갖게 된 것이다. 흩어져 있던 부품들은 더 이상 존재하지 않았다. 오직 문제를 해결하기 위해 ‘값에 이름을 붙이는’ 자연스러운 행위만 남았다.
솔라는 자신이 작성한 두 줄의 코드를 뿌듯하게 바라보았다. 이것은 단순히 문법을 연습한 결과가 아니었다. 게임의 규칙이라는 실생활의 정보를 변수라는 도구로 깔끔하게 모델링한, 작은 설계도였다. 그녀는 이제 어떤 문제를 만나든, 그 문제에 필요한 정보 조각들을 찾아내 멋진 이름표를 붙여줄 수 있을 것 같았다.