본문 바로가기
프로그래밍언어론

[프로그래밍언어론] 11. 이름(Name), 바인딩(Binding)

by 파스텔코랄 2023. 10. 10.
이름(Name)이란?

 


 

이름(Name)

  • 이름은 단지 다른 객체를 대표(represent)하는(또는 의미(denote)하는) 일련의 문자일 뿐이다.
  • 대부분의 프로그래밍 언어에서 이름은 식별자 형식을 갖는다.
  • 예) 영숫자 토큰(v1, v2, func 등) 또는 기타 기호(_, $).

이름(Names) ≠ 개체(object)

  • 이름과 그 이름으로 표시되는 대상동일한 것이 아니다.
  • 하나의 이름은 여러 가지 다른 개체를 나타낼 수 있다.
  • 또한 하나의 개체가 여러 가지 다른 이름을 가질 수 있다.

 


 

표시 가능한 객체(Denotable Objects)

  • 표시 가능한 개체이름을 지정할 수 있는 개체이다.
  • 사용자가 이름을 부여한 객체: 변수(variables), 매개변수(parameters), 함수(functions), 사용자 정의 유형 등
  • 프로그래밍언어가 이름을 부여된 객체: 기본 유형, 기본 연산, 사전 정의된 상수 등

 


 

 

바인딩(Binding)이란?

 


 

바인딩(Binding)

  • 이름과 표시된 개체 간의 연결이다.
  • 바인딩은 다양한 시점에 생성될 수 있다.
    • "정적(static)" 및 "동적(dynamic)"으로 나눌 수 있다.
  • 정적(static) : 언어 설계, 프로그램 작성, 컴파일 시간
  • 동적(dynamic) : 런타임

 


 

언어 디자인 바인딩

  • 기본 유형(int, double 등), 기본 연산(+, - 등).
  • 같은 것다른 언어에서는 다른 이름으로 표시될 수 있다.
  • 예) Java 및 Python의 "AND" 논리 연산
JAVA

if (a > 0 && b > 0) {
    q = a / b
}
Python

if a > 0 and b > 0:
    q = a / b

 


 

바인딩 시간

  • 프로그램 작성: 프로그래머는 바인딩의 부분 정의인 식별자를 선택한다. 이러한 바인딩은 나중에 완료된다.
    • 예) int x = 0;     x를 int 타입 변수로 바인딩
  • 컴파일 시간: 변환하는 동안 컴파일러는 전역 변수와 같은 일부 데이터 구조에 메모리를 할당한다.
    • 예) 전역변수, 정적 변수
  • 런타임: 아직 생성되지 않은 모든 바인딩을 완료한다.
    • 예) 지역 변수, 포인터 변수 등.

 


 

참조 환경(Referencing Environment)

  • 참조 환경(Referencing Environment)(또는 간단히 환경(Environment))런타임 시 프로그램의 특정 지점에 존재하는 이름과 개체 간의 바인딩 집합이다.
  • 바인딩의 집합
  • 특정 실행 지점의 이름과 개체의 경우.
  • 일반적으로 언어 정의에 의해 설정되지 않은 바인딩만 참조한다.

 


 

선언(Declaration)

  • 선언은 환경에 바인딩을 도입하는 것이다.
  • int x;     x를 int 타입의 변수의 이름으로 선언
  • int func() {
        return 0;
    }
  • public class Foo;     클래스 내부에 선언된 경우 외부 클래스를 통해서만 클래스에 액세스할 수 있습니다.

 


 

다양한 사례

  • 이름과 표시 가능한 개체 간의 바인딩.
  • 단일 이름 - 다른 개체(Single Name - Different Objects)
  • 단일 개체 - 다른 이름(Single Object - Different Names)
  • 다양한 환경에서
  • 동일한 환경에서 - 앨리어싱(aliasing)

 


 

단일 이름 - 다른 개체

  • 두 위치에 같은 이름의 변수 두 개가 있다.
  • 이름은 동일하지만 실제로는 서로 다른 두 개체를 가리킨다.
  • Java 클래스의 예
public class Example {
	public int sum;
	public int method() {
		int sum = 0;
		return sum;
	}
}

 


 

다양한 환경에서 단일 개체 - 다른 이름

  • 다양한 환경에서 일반적
  • Call by reference
  • put() 메소드 내에서 변수 list는 동일한 ArrayList, strings을 나타낸다.
// 환경1
public static void main() {
	List<String> strings = new ArrayList<>();
	put(strings, "Middle");
}

// 환경2
public static void put(List<String> list, String str) {
	list.set(list.size()/2, str); // 변경 사항이 strings에도 영향을 미친다.
}

 


 

Call by Value는 어떨까?

  • Call by Value는 값을 복사하여 메소드에 전달한다.
  • 따라서 단일 또는 다른 이름으로 표시되는 여러 개체이다.
  • put() 메소드 내에서 변수 oldStr은 main()의 str과 동일한 값을 갖는 다른 객체를 나타낸다.
public static void main() {
	String str = "Before";
	put(str, "After");
}
public static void put(String oldStr, String newStr) {
	oldstr = newStr; // 변경 사항이 Str에 영향을 미치지 않는다.
}

 


 

동일한 환경에서 단일 개체 - 다른 이름

  • 동일한 환경에서는 더 까다롭다.
  • 앨리어싱(Aliasing) : 하나의 객체가 서로 다른 이름을 갖는 경우
  • 앨리어스(Alias) : 서로 다른 이름을 갖는 경우
int *x, *y;				x, y 선언
x = (int *) malloc(sizeof(int));	힙메모리 선언
*x = 5;					* 역참조
y = x;					x와 동일한 y 포인터
*y = 10;
print("%d\n", *x);			10 출력

댓글