수정입니다
Name, Bindings, and Scope(2) - Scope 본문
Scope
- the range of statements over which it is visible
- local variable -> 어떤 프로그램 or 블록 내에서 정의된 변수
- nonlocal variable -> 그 지역 내에서 정의되지 않았는데 visible한 변수
- global -> non-local의 special category
Static Scope
- 두가지 유형 - nested subprogram(함수안에 함수 정의) 허용 or 비허용
- 작성 위치에 따라 scope가 달라짐
- Search process : 변수가 정의된 부분을 찾아야함. 지금 내 지역부터, 더 큰 지역.. 계속 찾을 때까지 탐색
- static ancestor : subprogram을 포함하고 있는 모든 program 전부
- static parent : 나(subprogram)을 선언한 subprogram (ancestor 중 가장 nearest 한 것)
- nested subprogram 허용언어 - Ada, JavaScript, Common Lisp, Scheme, Fortran 2003+, F#, Python)
- C 기반 언어들은 허용하지 않는다.
- 일단 여기선 허용된 언어 기반으로 생각
func2와 func3의 ancestor는 func1이다
func2에서 x를 정의하고, func3을 호출했지만, 실제로 둘은 아무 관계도 아님
이때 func2의 int x = 3은 int x = 5 에 의해서 은폐된다(hidden)
Blocks
- a method of creating static scopes inside program units(from ALGOL 60)
- C, C++ 에서는 허용되지만, C#, java 에선 허용 x
- let 이라고 명시된 키워드로 보통 사용
- let construct 2가지로 구성됨
--> 1. binds name to value
--> 2. uses the names defined in the first part
이 구조는 (a + b) / (c + d)의 식을 계산하고 그 값을 반환한다.
+ In F#
Declaration order
- C99, C++, Java, C# 은 변수 선언이 프로그램 어디든지 나타나는 것을 허용
C99, C++, Java
--> 변수 사용하기 전에 반드시 선언 먼저 해야됨
--> scope는 선언된 순간부터 그 block 끝까지
C#
--> 변수 사용전 반드시 선언 먼저 해야하는 것은 맞음
--> scope가 선언된 순간부터가 아니라 선언된 block 전체임
--> main.cs(13,9): warning CS0219: The variable `b' is assigned but its value is never used
--> 변수의 scope가 block 전체라서 if문 내에서 변수를 선언을 안하면 밖에다 선언해도 못씀
C++, Java, C#
- for문 state안에 선언할 수 있음
Global scope
- C, C++, PHP, Python 은 일련의 함수 정의들로 구성된 프로그램 구조를 허용함
--> 이러한 구조에서 변수 정의들이 함수 외부에서 올 수 있음
- C, C++ 은 전역 데이터의 선언과 정의를 가짐
--> declaration(선언) : 타입이나 다른 속성들을 특정하지만, 기억공간 할당x
--> definition(정의) : 속성들을 특정하고 기억공간을 할당 o
--> 함수 정의 외부에 위치한 변수 선언은 그 변수가 다른 파일에 정의되어 있다는 것을 말함
file1 에서 정의된 b를 file1 에서 extern 키워드를 쓰며 선언
-> file2에서 visible 해진다
- PHP
--> 전역 변수 A를 함수 내부에서 쓰려면 내부에서 $global A 라고 해줘야함
--> 만약에 A와 같은 이름이 함수 내부에 존재한다면 $GLOBALS 배열을 이용해서 새로운 변수 지정
==> PHP에서 전역 변수는 선언 후 부터 프로그램의 끝까지 scope를 가지지만, 중간에 함수 정의들이 끼어 있다면, 그 함수 정의는 scope에서 빠지게 된다.
- Python
--> day = "Tuesday" 문장이 없다면, 전역변수를 함수 내에서 그냥 참조 가능
--> day = "Tuesday" 문장이 생겨서, 함수 내에서 변수를 선언하기 전에 print ("The global day is : ", day)를 출력 하라고 시킨 꼴이 되는거라 에러가 발생
The global day is : Monday
The new value of day is : Tuesday
출력결과
Evaluation of static scoping
- works well in many situations
- Problems :
--> too much access is possible
--> 프로그램이 계속 develop될 때, 전역 변수 때문에 원치 않는 설계를 하게 될 수가 있음
Dynamic Scope
- based on calling sequences of program units not their textual layout
- temproal(dynamic) vs spatial(static)
- searching back through the chain of subprogram calls that forced execution to this points
함수의 호출부분을 제외한 코드임
만약에 big -> sub1 -> sub2 로 calling sequence가 이루어졌다면
지역프로시저 sub2부터 그 호출자 sub1으로 진행되고, sub1에서 x에 대한 선언이 발견되었으므로
이때 dynamic scoping : sub1의 x는 sub1의 x를 참조한다( x = 7 )
이때 static scoping : sub2의 parent가 big이므로, big의 x를 참조한다( x = 3)
만약 그냥 big -> sub2라면 dynamic과 static scope는 같을 것이다.
Evaluation of Dynamic Scoping
- 장점 : 편하다
- 단점
- 내가 호출한 모든 subprogram이 실행되고 있으면 계~속 지역변수가 노출된다(reliability가 낮아짐)
- Impossible to statically type check
- readability가 낮아짐 (calling sequence를 인간이 눈으로 찾기 힘들다)
Scope and Lifetime
- 둘은 관련 있어 보이지만 사실은 다른 컨셉
scope -> visibility
lifetime -> storage binding
- sum 은 printheader 함수 내에서 사용(참조?)할 수는 없지만 binding은 어딘가의 공간에 계속 살아있다...
Referencing environments
- statement에서 볼 수 있는 모든 name들의 집합
- static scope
지역변수 + 모든 닫힌({} 이런거) scope내의 모든 visible한 변수
- dynamic scope
지역변수 + 모든 active(활성화)되어 있는 subprogram 내의 모든 visible한 변수
ex) static scope
** 이게 교재 코든데 뭐가 이상함 sub1 scope가 sub3의 ancestor가 아니라는데 sub1 밑에 sub2 밑에 sub3가 정의가 돼 있는데 왜 아닌지 모르겠고 설명이 sub1 영역이 sub 3보다 높은 수준이긴한데 덜 깊숙하게 중첩되어 있다고 그래서 아니라는데 아니애초에 파이썬에서 indentation을 저렇게 애매하게 설정할 수가 없는데 뭐지 밑에 설명 보면 sub1이 실행중이 아닐 때 sub3이 실행중 일 수 있어서 뭐 sub3이 sub1변수에 접근하는게 안된다는데 이게 sub1 밑에 sub3가 중첩됐을 경우에 이렇게 될 수가 있나? 이상함 아무튼 근데 말하고자 하는 바는 어쨌든 sub3랑 sub1이랑 관계없다는거 같아서 걍 indentation빼고 생각함
아무튼 이렇게 생각하면 깔끔함,,
함수를 호출하지 않아도 알 수 있는 참조 환경 == static scope
ex) dynamic scope
call stack 그대로 따라가면서 영역 결정, 은폐시키는 변수에 대한 선언 가능
Named constant
- 딱 한번만 binding 되는 변수
- 장점 : readability and modifiability
--> 프로그램 매개변수로써 사용할 수 있음
만약에 myArray[10] 일 때, 이 array 사이즈를 그냥 처음부터 len = 10; 이렇게 박아버리면 나중에 이 10 이라는 숫자가 바뀌게 됐을 때 코드 쫓아가면서 하나하나 바꿀 필요 없이 len만 바꾸면 돼서 편하다
- Language
C++, Java : 어느 타입이든 가능, dynamic binding
C# : 두가지 존재
- const : compile time에
- readonly : dynamical binding
// end of chapter 5
'전공 > 프로그래밍언어론' 카테고리의 다른 글
Expressions and Assignment Statements (1) | 2023.12.28 |
---|---|
Data types(2) - record, tuple, list, union, pointer, type checking (0) | 2023.12.28 |
Data Types(1) - numeric, string, array (1) | 2023.12.28 |
Name, Bindings, and Scope(1) - Name, Bindings (0) | 2023.12.28 |
Bottom-up Parsing (0) | 2023.12.28 |