정적 스코프와 동적 스코프

같은 코드인데 y가 3도 되고 7도 된다면?

예제

sub2가 쓰는 x는 어느 x일까요

교재의 예제입니다. big 안에 함수 sub1과 sub2가 들어 있습니다. x는 두 군데에 선언돼 있습니다. big의 x는 3, sub1의 x는 7입니다. sub2는 x를 선언하지 않고 그냥 씁니다.

7편의 코드에 sub1을 더한 것입니다. sub1(); 처럼 이름 뒤에 괄호를 붙이면 그 함수를 부릅니다.

정적 스코프로 풀면

코드에서 둘러싼 곳으로

정적 스코프에서는 코드에 적힌 자리로 찾습니다. sub2 안에 x가 없으니 sub2를 둘러싼 big으로 나갑니다. 거기에 x = 3이 있습니다. sub1은 sub2를 둘러싸지 않으므로 보지 않습니다.

이렇게 함수 안에 함수를 넣을 수 있는 언어로 Ada, JavaScript, Common Lisp, Scheme, Fortran 2003 이상, F#, Python이 있습니다.

동적 스코프로 풀면

부른 쪽으로 거슬러 올라갑니다

동적 스코프(dynamic scope)는 코드의 구조가 아니라 함수를 부른 순서로 찾습니다. 지금 실행 중인 함수에 없으면, 그 함수를 부른 함수로 거슬러 올라갑니다. sub2를 부른 것은 sub1이고, 거기에 x = 7이 있습니다.

나란히

기준이 공간이냐, 시간이냐

같은 코드인데 스코프 규칙에 따라 y가 3도 되고 7도 됩니다. 정적 스코프는 코드에서의 자리, 곧 공간을 기준으로 삼습니다. 동적 스코프는 호출의 순서, 곧 시간을 기준으로 삼습니다.

예제는 자바스크립트 문법으로 적고 규칙만 바꿔 본 것입니다. 실제 자바스크립트는 정적 스코프를 씁니다.

동적 스코프의 어려움

누가 불렀느냐에 따라 달라집니다

동적 스코프에서는 같은 sub2라도 누가 불렀느냐에 따라 x가 달라집니다. 코드만 읽어서는 알 수 없어 읽기 어렵습니다. 어느 x가 쓰일지 실행해 봐야 알기 때문에, 실행 전에 타입을 검사할 수도 없습니다.

오른쪽은 big이 sub2를 바로 부른다고 가정한 예시입니다.

견주기

편한 쪽과 미리 아는 쪽

동적 스코프는 값을 인자로 넘기지 않아도 돼서 편리하지만, 어느 변수가 쓰일지 실행 전에 알 수 없습니다. 정적 스코프는 코드만 보고 미리 알 수 있습니다. 대신 안쪽에서 바깥의 변수가 필요 이상으로 많이 보입니다.

인자는 함수에 넣는 값입니다.

다음 편

스코프는 어디서 보이는가, 수명은 언제까지 사는가입니다. 둘은 늘 같을까요?

9편살아 있어도 보이지 않는 변수 4강 목록