프로그래밍 언어를 배울 때 문법을 먼저 외우기 쉽습니다. 하지만 다른 언어로 옮겨 갈 때 더 중요한 질문은 비슷합니다. 변수에는 무엇이 들어 있는가, 함수에 넘기면 무엇이 복사되는가, 객체는 언제까지 살아 있는가? 이 질문으로 실행을 따라가면 문법 차이 뒤의 공통 구조가 보입니다.
프로그램의 동작을 다른 언어로 옮겨 설명할 때는 문법보다 값의 위치, 객체 공유, 호출 시점, 부수 효과, 수명이라는 실행 모델을 먼저 고정합니다. 같은 모양의 대입이나 함수 호출도 언어의 복사·참조·타입·정리 규칙에 따라 다른 결과를 낼 수 있으므로, 작은 상태 trace로 공통 개념과 언어별 차이를 분리해 봅니다.
값·변수·객체
변수는 프로그램에서 값을 가리키거나 보관하는 이름입니다. 숫자처럼 값 자체를 다루는 경우와, 여러 이름이 같은 객체를 가리키는 경우를 구별해야 합니다. 아래는 특정 언어 문법이 아닌 참조 공유 모형입니다.
a = 새 목록 [10, 20]
b = a와 같은 목록의 참조
b의 첫 원소 = 99
이 모형에서는 a로 읽어도 첫 값이 99입니다. b가 별도 목록을 복사한 것이 아니기 때문입니다. 반대로 새 목록을 만들어 내용을 복사했다면 목록의 변경은 분리할 수 있습니다. 다만 원소가 또 다른 가변 객체의 참조라면 안쪽 객체는 여전히 공유될 수 있습니다.
이 구별은 C++의 값 복사, Java와 Python의 객체 참조, JavaScript의 객체, Go slice의 기반 배열을 이해하는 출발점입니다. 실제 전달·복사 규칙은 언어별로 확인해야 하며 같은 대입 문법이 항상 같은 메모리 동작을 뜻하지는 않습니다.
함수 호출과 부수 효과
함수를 호출하면 인자와 지역 상태를 사용해 계산합니다. price(amount, rate)가 두 숫자로만 결과를 계산한다면 같은 입력에서 같은 결과를 재현하기 쉽습니다. 반면 함수 안에서 현재 시각이나 전역 세율을 읽으면 인자가 같아도 결과가 달라질 수 있습니다.
입력 목록을 정렬하거나 파일을 쓰는 일도 호출 밖에서 관찰할 수 있는 변화입니다. 이런 변화를 부수 효과라고 합니다. 부수 효과는 잘못된 것이 아니라, 언제 누구의 상태를 바꾸는지 드러내야 하는 작업입니다. 계산과 저장을 나누면 계산은 값으로 시험하고 저장의 실패는 별도로 다룰 수 있습니다.
그림을 글로 읽기
- 입력 값·정책
- 함수 · 결과 계산
- 저장·화면 변경·네트워크
- 입력 값·정책 → 함수 · 결과 계산: 인자
- 함수 · 결과 계산 → 저장·화면 변경·네트워크: 계산 결과
타입과 허용 연산
타입은 값에 어떤 연산을 적용할 수 있는지 표현합니다. 숫자 덧셈과 문자열 연결은 같은 + 기호를 쓰더라도 다른 연산일 수 있습니다. 타입 검사가 컴파일 때 이루어지는지, 실행 중 값에 따라 이루어지는지, 암묵 변환이 있는지는 언어마다 다릅니다.
타입이 맞아도 업무 규칙은 틀릴 수 있습니다. 정수형 금액 −100은 문법상 유효할 수 있지만 결제 금액으로는 거절해야 할 수 있습니다. 타입 검사는 표현 가능한 연산을 제한하고, 업무 검증은 그중 허용할 값을 더 좁힙니다.
런타임과 객체 수명
소스가 실행되기까지는 기계어 컴파일, 바이트코드 실행, 해석, 실행 중 컴파일 등이 조합될 수 있습니다. 언어 이름 하나만으로 모든 실행 방식을 고정하지 않습니다. 예를 들어 같은 Java 프로그램도 JVM과 옵션에 따라 최적화 시점이 달라집니다.
메모리를 회수하는 방법도 다릅니다. 소유 범위 종료, 참조 계수, 도달 가능성을 추적하는 GC는 각각 다른 원리입니다. GC가 있어도 파일이나 DB 연결을 필요한 시점에 닫는 책임은 남습니다. 객체가 메모리에 살아 있는 것과 현재 요청에 그 객체를 사용할 권한이 있는 것도 별개입니다.
| 질문 | 세부 개념 |
|---|---|
| 같은 객체인가, 같은 값인가 | 참조 동일성·값 동등성 |
| 무엇이 복사되는가 | 값 복사·얕은 복사·깊은 복사 |
| 언제 실행되는가 | 동기 호출·작업 큐·코루틴 |
| 언제 정리되는가 | 소유권·참조 계수·GC·명시적 종료 |
상태 trace를 작성할 때 a와 b가 같은 목록을 가리키는 경우와 복사된 목록을 가리키는 경우를 두 행으로 나누고, 함수 호출 전후 객체 값과 반환값을 함께 기록하십시오. 예상 결과는 공유 모형에서 한 이름을 통한 변경이 다른 이름에도 보이고, 복사 모형에서는 바깥 목록 변경이 분리되는 것입니다. 그다음 동일한 입력의 순수 계산과 파일 쓰기 함수를 나누어 테스트하면 값 재현성과 효과 관찰을 별도로 확인할 수 있습니다.
언어별 연결
C++ 값 범주, Java 값 동등성, JavaScript 바인딩, Python 객체 공유, Go slice는 위 질문을 각 언어의 실제 규칙으로 이어 주는 문서입니다.