문제에 대한 풀이는 공부하는 과정에 푼 과정이므로, 실제 답안과 다를수도 있습니다. |
Q1.
프로그래밍 언어에서 타입이 제공되는 목적은 무엇인가?
타입은 여러 연산자들에게 맥락을 명시해줘, 프로그래머들이 따로 명시해주지 않게 해준다. 또한, 어떤 종류의 데이터들이 연산자 내에서 수행되고 출력되는지를 알 수 있다. |
Q2.*
언어가 strongly typed, statically typed되었다는 것은 무슨 의미이며, 예를들어 C가 strongly typed되는 것을 막는 것은 무엇인가?
우선 strongly typed 된 언어는, 모든 객체(object)에 대해 타입 오류를 검사하는 언어이다. (실행시점에 검사) 이런류의 언어들은 신뢰성이 높지만 효율이 낮아지게된다. 그리고, statically typed 된 언어는 strongly typed되고 type checking이 컴파일 시점에 이뤄지는 언어이다.
이때, 대부분의 오늘날 언어들이 strongly type고 statically typed는 아닌편이다. 예를 들어 C언어는 실행시점에 어떤 점검도 하지 않고, strongly type 된 상태에서 type checking이 실행 시점에 수행되는 것을 지양한다. 그래서 C는 strongly type되는 것을 방지한다.(?) ( +) C언어는 지속적으로 발전되며 strongly typed되가고 있지만 C언어 특성상 실행시점 checking을 거의 하지 않는다로 이해) |
Q3.
strongly but dynamically typed 된 언어 두개를 말해라.
python, ruby (대부분의 스크립팅 언어) dynamically typed 된 언어에서는 변수의 타입이 프로그램 실행도중 동적으로 변할 수 있다. |
Q4
type clash란 무엇인가?
프로그램이 무조건 언어의 '타입 호환성 규칙'에 종속된다는 type checking 규칙을 위반한 것이다, ex) int a; a = "Hello!"; // type clash 발생, '타입 호환성 규칙'은 7-2장에 자세히 나옵니다 |
Q5.
타입에 대한 denotational, structural, abstraction-based 관점의 차이점을 설명해라
Denotational : 표시론적 관점. 타입을 단순히 값들의 집합으로 보는 관점이다. 값이 값들의 집합에 속해 있으면 해당 타입이라고 본다. ex) 열거형 타입
structural : 구조적 관점. 타입을 built-in 타입의 작은 모임이나, 합성형 타입(Composite type)으로 보는 관점이다. ex) 배열
abstraction-based : 추상기반 관점. 타입을 잘 정의 되고 상호간에 일치하는 시맨틱과 연산자들의 집합으로 구성된 인터페이스로 보는 관점. 단순히, 우리가 일반적으로 알고 있는 타입이라 보면 된다 ex) 정수형 타입(interger) |
Q6.
언어의 특징의 집합(타입 시스템)이 orthogonal 이라는 것은 무슨 뜻인가?
한국말로는 '직교성'이라고 하는 특징은 여러 특성들을 다른 특성들과 관계없이 각 특성들의 의미가 일치함을 유지한 상태로 조합해서 사용할 수 있고, 모두 이치에 맞는 것을 의미한다. 이러한 직교성을 잘 지키는 언어는 쉽게 사용되고 이해될 수 있으며, 많은 타입시스템들또한 이러한 직교성을 유지하고 강화 하기 위해 여러 타입들을 만들어 냈다. 대표적인 예시로, 1) void(유용한 값 반환 안하는 경우), 2) null(유효하지 않은 값 가르키는 경우), 3) aggregate 들이 있다. |
Q7.
aggregate란 무엇인가?
연습문제 6-13에서 말했듯이 '집약'이라는 뜻으로, 사용자가 정의한 합성형 타입(Composite type)들에 대한 컴파일 시점 초기화를 의미한다. ex) struct { int x, y, z; } ... nums = {1, 2, 3} |
Q8.
option 타입이란 무엇이고, 어떤 목적을 가지고 있는가?
option타입과 maybe 타입은 직교성의 예시중 하나였던 "none of the above"를 충족 시키기위해, 많은 함수형, 명령형 언어들이 지원하는 특별한 타입 구조이다. ex) if d == 0 { return nil } .. if v == nil { return "??" } |
Q9.*
다형성(polymorphism)이란 무엇인가? 또한 parametric과 subtype 변수들과 구별되는 요소는 무엇인가? 그리고 일반화(generics)란 무엇인가?
다형성 : name으로 다양한 타입의 값들 대해 작동하도록 디자인된 코드이다. parametric 다형성 : 코드가 타입을 파라미터로 받는 방식으로, 명시적인 방법과 암시적인 방법으로 나뉜다. 명시적인 방법은 일반적으로 아는 Generic의 개념이며 정적으로 타입되는 언어에서 보여지고 컴파일 시점에 주로 실행된다 암시적인 방법은 동적 타이핑과 실행 시점 타입 체킹 발생과 병행된다.
subtype 다형성 : 객체지향 언어에서 주로 사용되며, 다른 데이터 유형에서 상속되는 데이터 유형이다. 코드가 특정 타입 T에 대해 값과 함께 동작하지만, 프로그래머가 추가적인 타입이 확장되고 T를 개선할 수 있다. ( = 상속의 개념) 마찬가지로 타입 체킹은 컴파일 시점에 발생. but 실행시점에 하위 타입에 따라 결정된다. |
Q10.*
discrete 타입과 scalar 타입의 차이점은 무엇인가?
discrete 타입 : integer, boolean, character과 같은 기본 타입들과 두개의 사용자 정의 타입인 열거형 타입과 subranges 타입과 같이 각 원소들간에 ordered되고 셀수있는(countable) 값을 가지고 있는 타입이다.( = ordinary type) scalar 타입 : 특정 시점에 오직 한개의 값만 가지고 있는 타입들을 의미한다. ( = simple type) discrete 타입을 포함하고 있고, real(float), complex type들 전부 포함하고 있다. |
Q11.
boolean 타입이 없는 언어 두개를 말하고, 그럼 그들은 어떤 방식을 대신 사용하는지 말해라
우선 booelan 타입은 single-type으로 0으로 true, 1로 false를 나타낸다. 풀이 생략. 교재 305p 참고 |
Q12.*
열거형 타입이 상수형 named의 집합에대해 선호되려면 어떻게 해야하는가?
subrange 타입이 base type으로 선호되려면 어떻게 해야하는가?
열거형 타입은 사용자 정의 타입이고, 열거형 타입에 데이터를 추가 시킬 수 있다. 열거형 타입의 데이터 혹은 원소들은 memebers, enumerators, elements 라고 불린다. 열거형 타입이 정의되면, 열거형 name들을 데이터 타입으로써 사용할 수 있고, 이러한 특징들은 C++ 에서 허용된다.
열거형 타입의 원소들인 enumerators들은 어느것이 몇개나 사용되는 상관없이 할당될 수 있다. 그리고, 각 enumerators원소들이 ordered되게끔 정수값(시작값 0)들을 부여해준다.
결론적으로, 이러한 특성들이 열거형이 collection of named constants 에 주로 사용되게끔 한다.
subrange 타입은 discrete 유형의 값에서 subrange 집합을 구성하는 타입이다. 이 방식을 사용하면 예를 들어 정수형에서 사용하고자하는 특정 값들을 가지고 subrange를 만들어 적은양의 bit만으로 컴파일러가 표시할 수 있고, 프로그램 문서화하는데 도움이 되기에 base type으로서 사용되곤 한다. |
Q13.
타입 동등성(type equivalence)과 타입 호환성(type compatibility)의 차이점은 무엇인가?
타입 동등성은 사용자가 새로운 타입을 정의하는 것을 허용하는 언어에서 타입의 동등성을 결정하는 두가지 기준이 있다. 1) 구조적 동등성 : 타입 정의 내용 기반으로 동등성을 판단하며, 즉 구조체상 같은형태일때 동등하다고 판단한다. ex) C 2) name 동등성 : 타입 정의가 발생한 맥락 기준으로 동등성을 판단하며, 각 타입 정의할때마다 새로운 타입으로 취급한다. ex) Java, C#
타입 호환성은 서로 다른 타입이라도 서로간 호환되는 타입 여부를 결정하는 것이며, 대부분의 언어가 타입 동등성 대신에사용하는 방식이다. 언어마다 타입 호환성의 정의 범위가 다르다 |
Q14.
타입에 대한 구조적 동등성과 name 동등성의 비교 우위를 논해라. 그리고 각 방식을 사용하는 언어를 3가지씩 말해라.
q13 참고.. 구조적 동등성 사용 언어 : Algol 68, Modula-3, C name 동등성 사용 언어 : Java, C#, Pascal |
Q15.
strict name 동등성과 loose name 동등성의 차이에 대해 설명해라.
우선 예를 들어 typedef A B; 처럼 B가 A에 대해 alias 된다고 가정할때, 엄격한 이름 동등성은 aliased type 관계인 A와 B를 서로 다른 타입으로 취급하고, 느슨한 이름 동등성은 위 두 타입을 서로 같은 타입으로 취급한다. |
Q16.
Ada에서의 derived types과 subtyps의 차이에 대해 설명해라.
Ada에서 drived types는 엄격한 이름 동등성 가지는 타입을 의미하고, subtypes는 느슨한 이름 동등성을 가지는 타입을 의미한다. |
Q17.*
type conversion(타입 변환), type coercion(타입 자동형변환), nonconverting type casts의 차이에 대해 설명해라.
type conversion은 static-typing 되는 언어에서 기대되는 타입과 들어가는 타입과 다를때 사용하는 방법으로 run-time에 실행된다. ex) float a = b; // b는 int 형 type coercion은 암시적으로 일어나는 자동 형변환이다. 이때 format의 손상이 일어날 수 있다 (동적 시맨틱 오류 검사 X)
nonconverting type casts은 변수가 타입 변환되어도 변수의 format을 바꾸는 것이 아니라, 기존 값을 그대로 두고 사용하는 방법이다. 즉, 값이 더 작은 범위로 변환되었다 다시 변환되도, 값의 손실이 발생하지 않는다. |
Q18.
자동 형변환(coercion)의 찬성과 반대에 대해 요약해라.
자동 형변환은 기본적으로 매우 유용하다. 추상화와 확장성을 자연스러운 방식으로 지원한다. 하지만, 타입 시스템을 악화시키고 논의의 여지가 있다. 그리고 사용자 의도와 다르게 암묵적으로 수행되게 된다. |
Q19.
type conversion이 실행시점 검사(run-time check)이 필요한 이유가 무엇인가?
실행시점 검사는 목적지의 타입이 들어가는 값을 받을 수 있는지 확인한다. 만약 들어가지 못하면 오류 조건문이 실행된다. |
Q20.
universal reference types의 목적은 무엇인가?
다른 객체들 참조를 유지하기위한 일반적 목적 컨테이너 객체(general-purpose container objects)를 작성할때 유용한다. |
Q21.
type inference란 무엇인가? 이가 발생하는 3가지 맥락을 묘사해라.
타입추론으로 연산자의 결과의 타입을 추론하는 것이다. 1) 산술 연산의 결과는 주로 피연산자의 타입을 따라간다 2) 비교연산자의 결과는 boolean 타입이다 3) 함수의 호출의 결과는 함수의 header에 정의되어있는 타입이다. |
Q26.
명시적 파라미터의 다형성과 암시적 파라미터의 다형성에 대해 설명해라. 이 둘의 비교우위는 무엇인가? (7-1-2)
파라미터의 다형성은 다형성을 구현하기 위해 타입을 파라미터로써 받는 코드를 의미한다. 주로, 컴파일 시점 타입 추론이 없는 언어들이 실행시점까지 타입 검사를 미루기 위해 사용된다. (오류발생시 run-time error) 이런 방식이 바로 암시적 파라미터의 다형성 방식이고 런타임 checking을 하며 높은 비용과 오류 알림의 지연을 유발한다. 이때 명시적 파라미터의 다형성, 즉. 일반화는 프로그래머가 서브루틴이나 클래스를 선언할때 타입 파라미터들을 명시할 수 있게 해줘, 컴파일 시점에 checking 할 수 있게 해준다. |
Q27.
duck typing이란 무엇인가? 그리고 다형성과 어떤 연관이 있는가? 어떤 언어에서 나타나는가?
duck typing이란 객체가 사용된 메소드에 수용 가능하면 적절한 타입이라 취급하는 방식으로 일반화와 반대되는 방법이다. 이런 방식은 암시적인 파라미터의 다형성에서 주로 사용하는 방법이다. 하지만 암시적 파라미터의 다형성답게 run-time checking 되며, 객체에 대해 의도와는 다른 결과가 나올수 있다. |
Q28.
오버로딩과 일반화의 차이에 대해 설명해라.
오버로딩은 앞장에서 본 같은 이름의 메소드를 매개변수의 타입과 개수에 따라 여러개 구현 하는 기술이다. 즉, 일반적으로 다형성을 구현하는 방식이다. 하지만 이방식은 중복되는 메소드 코드 내용을 매개변수의 타입과 개수에 따라 중복되게 구현해줘야 되는 문제점이 있는데 이를 일반화의 방식으로 해결할 수 있다. (컴파일 시점 checking) 일반화는 언어마다 허용되는 타입이 다르다. ex) JAVA : container 형태로 전달되는 클래스에 주로 사용 / C++ : 상수도 허용 / Ada : 변수도 허용 이런 일반화 기술이 없으면 위의 오버로딩의 방식 또는 universal 클래스를 사용해야하지만 type cast 필요, run-time checking 된다. 일반화 : 둘 이상의 타입간의 부분집합을 정의한 것. ( 컴파일 시점 검사) |
Q29.
일반화의 주요 목적은 무엇인가? 그리고 JAVA와 C#에 비해 C++와 Ada에서 더 광범위한 목적으로 일반화가 사용된다는 것은 무슨뜻인가?
일반화는 동일한 코드에서 수많은 서로다른 타입의 파라미터들이 동작 할 수 있게끔해준다. 그리고 객체지향 언어인 JAVA와 C#는 이런 일반화가 적용되는 타입의 범위를 container로 한정 지었지만, (container : primitive type들과 배열, 리스트, 해시테이블 등과같은 ) C++과 Ada는 이런 일반화의 범위를 상수로 까지 확대했다. (단, C++는 컴파일 시점에 확정되는 상수만 / Ada는 실행시점에 결정되는 상수까지 )
ex) C++ 예시 : template<class item, int max_items = 100> |
Q30.
어떤 과정으로 분리된 일반화의 인스턴스에서 언어의 실행이 코드를 공유할 수 있는가?
일반화는 여러가지 방법으로 실행될 수 있다. 우선 순수한 정적 매커니즘인 Ada와 C++같은 경우엔 모든 작업이 컴파일 시점에 일반화 코드의 다중 인스턴스들이 생성되고 사용되어야 한다. 그래서 컴파일러는 일반화 코드의 모든 인스턴스에 대해 separate copy를 생성한다. 그리고 같은 종류의 타입을 가지고 있는 클래스는 enqueue, dequeue 루틴 코드를 공유한다.
반대로, JAVA 같은 경우엔, 일반화에 주어진 모든 인스턴스들이 실행 시점에 같은 코드를 공유한다. 이는 객체들의 베이스를 Object(최상위)로 잡기에, 일반화가 어떤 종류의 파라미터를 받던간에 같은 코드를 공유한다. |
Q31.
container 클래스란 무엇인가? 그리고 이들이 일반화에서 무엇을 하는가?
컨테이너 클래스란, 클래스 템플릿으로, 컨테이너 변수를 선언할때 컨테이너에 포함할 요소의 타입을 명시할 수 있다. List, Set, Queue, Map등 과같은 기본 타입이 이에 해당된다. 그리고 일반화는 이 컨테이너 클래스들을 매개변수화 하는데 사용된다. (객체지향 언어에선 컨테이너 클래스들에 대해서만 허용. C++, Ada는... 위에서 설명함)
ex) ArrayList<String> a = new ArrayList<String>(); // 컨테이너 클래스인 list에 대해 일반화 수행 |
Q32.
일반화 파라미터가 제약되었다(constrained)는 무슨 의미인가? 명시적 제약과 암시적 제약의 차이점에 대해 설명해라. 인터페이스 클래스들이 JAVA와 C#에서 제약을 명시하는데 사용될 수 있다는 것에 대해 설명해라.
제약된 일반화 파라미터(constrained generic parameter) : 연산자 파라미터 타입이 명시되게 선언되는걸 허용되는 연산자가 필요. 명시적 제약은 프로그래머에 의해 명시하는 방법이고,(ex. new) 암시적 제약은 컴파일러에 의해 내부적으로 제약을 생성해주는 방법이다.(ex.자바가 기본형 못받는 것처럼) 제약 조건 상속. 자세히는 생략 |
Q33.
C#은 int를 generic 인자로 받을 수 있지만, JAVA는 왜 받지 못하는가?
JAVA는 기본형(primitive) 타입을 generic 인자로 지원하지 않는다. 대신 자바에선 클래스. 인터페이스, 메소드등을 인자로 받는다. ex) ArrayList<int> 불가능 / ArrayList<Integer>은 가능.. 클래스인 Integer.. (?) |
Q34.
어떤 상황에서 C++는 암시적으로 일반 함수를 인스턴스화할 것인가?
현재 컴파일 유닛은 자동으로 컴파일러가 자동으로 인스턴스화된 전문 템플릿 코드를 사용해야 한다. |
Q35.
균등 테스트가 처음 나왔을때에 비해 미묘해진 이유를 말해라.
초반에는 기본 타입들만 단순히 비교하면 되었기에 (s == t) 시웠지만, 점점 타입이 추상화되고 복잡해진 형태가 되면서 어려워 졌다. +) 's==t'는 주소값 기준 비교 (swallow 방식) / clone(), equals()는 내용을 기준 비교 (deep 방식) +) 오늘날 대부분의 언어들은 shallow comparison과 shallow assigment 방식이다. |
이하 생략 |
'[프로그래밍 언어론] > 언어론 연습문제' 카테고리의 다른 글
프로그래밍 언어론 6강 연습문제 (0) | 2019.12.07 |
---|---|
프로그래밍 언어론 3강 연습문제 (0) | 2019.11.01 |
프로그래밍 언어론 1강 정리 및 연습문제 (2) | 2019.10.14 |