본문 바로가기

Programming Languages [PL]

[PL] 04. Names, Bindings, and Scopes

기본 개념

명령형 언어(Imperative language)는 폰 노이만 아키텍처(컴퓨터를 처리장치와 메모리가 연결된 것)를 가정. 

CPU가 메모리에서 명령어를 가져오고 가져온 명령어를 해석하고 해석한 것을 실행. 실행한 것을 다시 레지스터(임
시저장)와 메모리에 써준다. 결국 변수를 처리하는 것이다. 변수는 속성(attribute)에 따라 특징이 결정됨. (type을 디
자인하려면, scope, lifetime, type checking, initialization, type compatibility를 고려)

  • 변수의 이름
  • 변수의 주소(메모리의 번지수)
  • 변수의 값
  • 변수의 타입
  • 변수의 Scope (변수를 볼 수 있는 영역은 어떻게 되느냐) (내가 변수를 선언한 블럭의 아래 블럭에선 쓸 수 있지만 위에선 불가능)
  • 변수의 Lifetime (Static, Global 변수는 프로그램이 시작될 때 시작, 로컬 변수는 속해있는 함수가 호출될 때 시작)

Name

변수, 함수, 클래스 등의 이름

  • 대소문자 구분(C,C++,Java,Python 모두 Case sensitive하다. SQL은 안함) 및 특수 문자 사용 가능 여부
     -> Case sensitivity : Readability가 떨어진다. (대소문자 차이로 구별해야 하기 때문)

길이 제한 (너무 짧으면 함축적인 뜻을 전달하기 어려움, 너무 길어도 안 좋다)

  • C99: 제한은 없지만 처음 63개만 중요합니다.
  • C# 및 Java : 제한이 없으며 모든 문자가 중요합니다.
  • C++ : 제한은 없지만 구현자(implementer)는 종종 제한을 부과합니다.

Special characer를 쓸 수 있는 언어, 없는 언어가 있다. 쓰면 Readability가 높아질 수 있음. 번거로워 질 수 있음

  • PHP: 모든 변수 이름은 달러 기호로 시작해야 함
  • Perl: 모든 변수 이름은 변수의 유형을 지정하는 특수 문자로 시작함 (배열은 @로 시작, Hash structure는 %로 시작) -
  • Ruby: @로 시작하는 변수 이름은 인스턴스 변수, @@로 시작하는 변수 이름은 클래스 변수임

Special words : readability 향상을 위한 도구

  • 예약어 > 키워드 : 예약어이지만 키워드는 아닌 것이 있다.
  • 반대로 모든 키워드는 예약어.(예약어 순위 C++90>java60>C40>python30)
  • 키워드 : if for switch (의미를 가지는 것) / 예약어 : 내가 못 쓰는 이름(reserved words)
  • Java는 4개 중 Reliability가 제일 좋다. 위험한 것을 최대한 없앰. (goto가 키워드는 아니지만 예약어다. Python은 예약어도 X)

Variable (메모리 셀의 추상화)

  • 변수의 주소 : 내 변수가 저장되는 메모리의 위치. 같은 위치를 다른 이름으로 접근하면 Aliasing이다. Aliasing을 만드는 것은 포인터, Reference 변수(주로 C++, Java와 Python의 대부분 변수 : 주소를 가르키는 변수), 유니온(C, C++)
  • 변수의 값 : 변수의 주소에 실제로 들어가는 값 (Scala 값이냐, 주소 값이냐)
  • 변수의 타입 : 내가 사용하고자 하는 값의 범위 + 이 값을 가지고 할 수 있는 연산의 종류
    타입이 결정된 변수에 값을 줄 때는 assignment가 실행이 된다. A = B 일때 assignment의 L-value엔 주소, R-value에는 값

Binding : 변수와 여러 attribute(type or value)가 묶이는 것 (보통은 type을 말한다.)

 

Binding이 결정되는 시기 (우리는 3번째부터 가능)

  • Language design time - 연산자 심볼을 연산에 할당
  • Language implementation(구현) time - C에서 int의 가능한 값 범위 (시스템에 따라서 결정)
  • Compile time - C 또는 Java에서 변수를 type에 바인딩 (대부분 타입)
  • Load time - C 또는 C++ 정적 변수를 메모리 셀에 바인딩 (대부분 주소)
  • Runtime - 비정적 로컬 변수를 메모리 셀에 바인딩 (Python은 변수의 타입과 주소를 이때 바인딩)

type을 어느 시점에 결정을 하느냐

  • Static Bind(프로그램이 실행되기 전, Compile time에)
  • Dynamic Bind(실행 뒤, Runtime시)

바인딩이 실행 시점 이전에 처음 발생하고 프로그램 실행 중에 변경되지 않으면 정적(static)

바인딩이 실행 중에 처음 발생하거나 프로그램 실행 중에 변경될 수 있는 경우 동적(dynamic) - Python, JavaScript

 

명시적(Explicit) 선언은 변수의 유형을 선언하는 데 사용

묵시적(Implicit) 선언은 선언문이 아닌 기본 규칙을 통해 변수 유형을 지정 ($, @는 Implicit)

 

Basic, Perl, Ruby, JavaScript 및 PHP는 묵시적(Implicit) 선언을 제공합니다.

장점: Writability / 단점: Reliability
일부 언어에서는 변수의 유형을 결정하기 위해 유형 추론을 사용합니다(컨텍스트)

 

Dynamic Type Binding

Python, JavaScript, C#(제한적) - 변수의 타입을 선언하지 않고 바로 사용

변수에 어떤 타입의 값이든지 저장 가능

장점 : 유연성(Flexibility)

단점 : 비용(시간, 메모리) 많이 듬. 컴파일러에 의한 타입 에러 detection이 어려움


변수의 Lifetime

변수가 어디에 들어오는지. (Data, Stack, Heap) 

변수가 살아있는 시간 = 메모리에 올라와 있는 시간 = Storage랑 바인딩되는 시간(Allocation부터 Deallocation까지)


변수의 Scope

변수의 범위(scope)는 해당 변수가 보이는(변수를 쓸 수 있는) 범위를 의미합니다.

  • Static Scope language (우리가 쓰는 4개 언어)
  • Dynamic Scope language (LISP)

프로그램 단위의 지역(local) 변수는 해당 단위 내에서 선언된 변수입니다. (블록 안에서만 유효) 

프로그램 단위의 비지역(nonlocal) 변수는 해당 단위에서 보이지만 그곳에서 선언되지 않은 변수입니다. 

전역(global) 변수는 nonlocal 변수 중 가장 큰 범위. 선언을 어디에 했는냐에 따라 Scope이 결정

언어의 범위 규칙(scope rules)은 변수 이름에 대한 참조가 변수와 연결되는 방식을 결정 (Lexical Scope = Static Scope)

같은 이름을 가진 더 가까운 변수가 있어 해당 변수가 가려지면 그 변수는 해당 블록에서 보이지 않게 됩니다.

 

Static Scope

 

블록 밖에 선언된 변수는 Global Scope을 갖는 변수다.

C, C++, PHP 및 Python은 파일 내 함수 정의의 연속으로 구성된 프로그램 구조를 지원 / 함수 정의 외부에 변수 선언이 가능
C 및 C++은 선언 (속성만 있는 것)과 정의 (속성과 저장소를 가지는 것)를 모두 가지고 있습니다. 

함수 정의 외부의 선언은 다른 파일에서 정의되어 있음을 지정합니다. 

파이썬은 전역 변수를 함수 내에서 참조할 수 있지만, 함수 내에서 할당하려면 해당 함수 내에서 global로 선언되어야 함. 
(함수에서 전역 변수를 쓸 수는 있지만 전역 변수의 값은 수정되지 않기 때문에) (global로 선언하면 가능)

 

Static Scope의 문제?
특정 변수에 접근이 몰리는 경우가 많아서 분산하는 것이 좋음
같은 변수명을 많이 쓰면 코드 유지 보수 중 정확도가 떨어질 수 있다.

 

Dynamic Scope

호출하는 순서에 의해서 변수의 Scope이 결정된다. 

변수에 대한 참조는 실행을 이 지점으로 강제한 하위 프로그램 호출 체인을 통해 되돌아가며 선언과 연결됩니다.


Referencing Environments (참조 환경)

문장의 참조 환경(reference environment)은 해당 문장에서 볼 수 있는 모든 이름(변수)의 집합을 말합니다.

정적 범위(Static scope)를 가지는 언어에서는, 이는 해당 문장이 속한 지역 변수와 그 주변 범위에 있는 모든 볼 수 
있는 변수를 포함합니다.

동적 범위(Dynamic Scope)를 가지는 언어에서는, 참조 환경은 해당 문장이 속한 지역 변수와 활성화된 모든 서브 프로그램에서 볼 수 있는 모든 변수를 포함합니다.

 

'Programming Languages [PL]' 카테고리의 다른 글

[PL] 06. Expressions and Assignment Statements  (0) 2024.01.10
[PL] 05. Data Types  (1) 2024.01.10
[PL] 03. Lexical and Syntax Analysis  (1) 2024.01.09
[PL] 02. Describing Syntax and Semantics  (0) 2024.01.09
[PL] 01. Preliminaries  (1) 2024.01.09