프로그래밍 언어의 역사에서 알 수 있듯이 각 시대마다 언어가 추구하는 곳이 다르다.
한 언어가 파일 처리를 위해 나왔을 경우, 다른 언어는 수학 교육용으로, 다른 언어는 초보자의 간단한 언어 액세스를 위한 목적으로 나온 언어도 있다.
이러한 언어의 주요 설계 원칙과 다른 설계 원칙을 알고 시대마다 어느 원칙을 중심으로 생각하여 언어를 개발했는지를 생각해야 한다.
언어 설계의 원칙
- 언어 설계의 기본 원칙
– 효율(efficiency): 고속 런타임
– 일반성(generality): 관련 개념을 하나로 통합
– 직관성(orthogonality): 서로 다른 기본 개념을 만들고 충돌하지 않고 병합하는 기능
– 균일성 (uniformity) : 같은 것은 같은 방식으로 행동
- 기타 설계 원칙
– 간결함, 표현력, 안전성, 정확성, 확장성
– 제약성, 부분성, 기존 표기 및 규칙에 대한 일관성, 기계 독립성
설계 기준의 역사적 변천
- 성공한 언어
->내적 요인: 언어 설계 원칙에 따른 언어
-> 외부 요인 : 가격, 시대, 번역자의 성격
- 성공적인 언어의 외부 요인
- 시대별 설계 기준의 중심 변화
– 1950년대 초반 : 실행 효율에 중점 – > 고속 실행 시간 ex. Fortran
– 1950년대 중후반: 일반(write and read) 원칙 중시 -> 읽기/쓰기 가능한 언어
ex. Algol 60: 블록 구조, 재귀적인 사용법으로 알고리즘을 논리적이고 간결하게 명료하게 표현했다
Cobol : 프로그램 가독성을 설계 목표, 영어와 유사한 문법 구조
-1960년대: 복잡성 제어 -> 추상화 기술 -> 언어의 규칙과 한계를 줄이기 위한 것입니다.
ex. Simula 67 : 강력한 추상화 기술, 클래스, 객체 지향의 개념이 등장
Algol 68: 일반성, 직교성이 뛰어나고, 데이터형 변수 선언
– 1970-80년대 초: 간결성 + 추상화 강조
-> 언어 구성에 수학적 정의를 도입하고 프로그램의 정확성 증명 기법을 갖춘 언어가 주목되었다.
ex. Pascal , C, Euclid, Modula2, Ada
– 1980년대 중반 : 논리 강조
-> 언어에 논리 또는 수학 개념 삽입
-> 로직을 프로그래밍 언어 자체에 포함
-> 함수형 언어와 객체 지향 언어가 주목되었다.
ex. ML, Miranda , C++
언어 설계 원칙에 따른 분류
참고 자료
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=yoonkh2000&logNo=50010399986
- 효율성
1. 목적 코드의 효율성
– 번역자가 효율적인 실행 코드 생성 -> 최적화
– 정적 데이터 타입 변수 사용, 스택을 이용한 효율적인 처리
– 상수를 수식으로 표현하지 않고 (계산 시간 X) 번역 과정에서 할당된 값으로 대체하여 실행 (실행 시간 전에 확정)
– 병렬 코드 생성
2. 번역의 효율성(컴파일)
– 적절한 크기의 번역기에 신속하게 번역 할 수 있습니까?
3. 실장성
– 번역자의 효율적인 구현 문제
– Algol 60은 번역 실행 알고리즘이 잘 이해되지 않았기 때문에 성공하지 못했습니다.
4. 프로그래밍 효율
– 프로그램 작성의 단순성, 용이성
– 언어 표현성, 추상화 메커니즘 관련
– 이상적인 언어 – Lisp (단순 언어 구성자), Prolog (논리) -> 대부분의 처리는 런타임에 수행됩니다.
– 가독성과 실행의 효율성, 신뢰성은 서로 충돌하는 성질이 있습니다.
- 일반성, 직교성, 균일성
일반성 : 밀접하게 관련된 것은 하나의 개념으로 통합 (일반화)
직교성: 완전히 독립적인 언어 구성자가 의미 있는 채로 결합하여 보다 복잡한 기능을 수행합니다.
균일성 : 유사하게 보이는 것은 유사한 의미를 가지며 유사하게 작동합니다.
1. 일반성
-> Pascal: 프로시저 선언 및 프로시저에 매개변수를 제공합니다.
그러나 프로 시저 유형 변수는 제공하지 않습니다.
-> 가변 배열이 없는 경우도 일반성이 떨어지는 예에 속한다.
-> Fortran : call by value 는 불가능하고 call by reference 만을 허가한다.
-> Fortran : 상수 이름이 존재하지 않음 ( const )
위의 예는 일반성이 저하된 경우입니다.
일반성이 커지면 무한히 좋은 것 같지만, 실제로는 일반성이 크면 가독성이 저하되는 경우가 많다.
예를 들어, C 언어는 포인터를 사용하여 일반성을 높였지만 반대로 포인터로 인해 프로그래머가 코드를 읽는 것이 어려워지는 문제가 있습니다.
대조적으로 Java는 포인터를 허용하지 않고 참조만 허용함으로써 신뢰성과 가독성이 향상된 예입니다.
파스칼은 또한 이명과 위험을 줄이기 위해 포인터를 제한합니다.
즉, 일반성이 커지면 언어의 간결성, 판독성 및 신뢰성이 저하되는 문제가 발생할 수 있다.
(Writablity가 증가하면 표현한다)
2. 직교성
– 문맥에 의존하는 제한이 발생한다 = 직교성이 저하된다
– 문맥에 관계없는 제한이 발생한다 = 일반성이 저하한다
-> 함수의 반환값에 예외 또는 제한이 있는 경우
–> c 언어는 배열형을 돌려줄 수 없고, Pascal은 스칼라형, 포인터형만을 돌려줄 수가 있다.
-> Pascal은 파일을 데이터 유형의 특수 상태로 취급합니다.
따라서, 데이터형은 가능한 기능이지만, 파일의 경우는 할 수 없는 경우가 생깁니다.
-> Modula-2는 더 긴 문자열의 문자열 배열에 할당할 수 있습니다.
크기가 다른 객체에 할당이 허용되는 유일한 경우입니다.
-> C 언어는 배열은 call by reference 하지만, 다른 모든 데이터형은 call by value 방식이다.
위의 예는 직교성이 저하된 경우입니다.
3. 균일성
– 유사한 것은 유사하게 보이고, 다른 것은 다르게 보여야 한다.
– 유사한 것은 똑같이 행동하고 다른 것은 다르게 작동한다.
-> Pascal은 if,while 문에서 begin – end의 구조를 요구한다.
그러나 repeat 문에서는 begin – end 의 구조를 요구하지 않는다.
-> Pascal 가변 레코드의 case 문과 case 제어문의 구문이 다르다.
-> Pascal은 함수 값을 반환하는 방법이 할당 문과 유사하기 때문에 혼동을줍니다.
위의 예는 균일성이 저하된 경우입니다.
- 간결함
– Pascal은 위의 설계 원칙에서 나쁜 예로 많이 사용되었지만, 반대로 간결성에서는 뛰어나다(설계 원칙이 간결성에 있다)
– 직교성, 일반성, 균일성이 뛰어나면 간결성을 보장하기 어렵다.
– 구성자의 수가 적은 것과 간결성이 뛰어난 것은 별개다.
Lisp과 Prolog에는 소수의 구성자가 있지만 복잡한 구현 시스템으로 인해 간결성이 떨어집니다.
– 과도한 간결성과 단순성은 언어 사용을 오히려 낮추고 표현력이 부족하다.
-> 제한 발생!
- 표현력
– 복잡한 프로세스나 구조를 표현하기 쉽다 = 표현력이 좋다
– 표현력이 뛰어나지만 단순하지 않은 언어 => Lisp, Prolog, Algol 68
– 표현력이 뛰어나 간단한 언어=C
- 정확도
– 언어의 정의가 올바른가 = 언어의 행위가 정확하게 예측 가능한 정의가 존재하는가
– 언어의 정확한 정의는 언어의 신뢰성을 높일 수 있다.
- 기계 독립성
– 기계 독립 언어 정의를 통해 보장한다.
– 저장 위치 할당과 기계 구조와는 별도이며, 정의된 데이터 유형을 사용하여 기계 독립성을 높일 수 있습니다.
=> 잘 이해하지 못했지만 특정 머신에서만 되돌아가는 언어는 머신의 독립성이 떨어지는 것을 알았습니다.
=> 정확한 이해를 원한다면 좀 더 내용을 찾아봐야 한다고 생각한다.
- 안전성
– 프로그래밍 오류를 줄이고 오류 발견을 용이하게 합니다.
– 신뢰성과 밀접한 관계에 있다.
- 기존 표기 및 규칙과의 일관성
– 표준화된 특성과 개념을 갖도록 언어를 설계해야 합니다.
– Algol 69와 동일하면 type 대신 mode를 사용합니다.
이것은 표준화된 표기를 잘 따르지 않는 예입니다.
- 확장성
– 사용자가 언어 특성을 쉽게 추가할 수 있는 기술
– 확장성이 있는 언어 – Lisp, C ( -> C++, C# )
– 명령형 언어는 함수형 언어보다 확장하기 어렵다.
– 추상화 개념이 확장성을 높이는 데 도움이됩니다.
- 제약성, 부분성
– 일부 언어 지식과 언어 구조만으로도 효과적인 프로그램 작성이 가능
– 언어 제한이 뛰어난 경우 프로그래머는 언어의 효과적인 사용을 위해 전체 언어를 배울 필요가 없습니다.
자신이 원하는 부분만을 공부하고 사용할 수 있다.
성공적인 언어 설계
- 프로그램의 신뢰성을 위해 진단 컴파일러 또는 검사 컴파일러 사용
- 효율적인 번역 기능을 갖는 것
- 코드 최적화를 통해 효율적인 목적 코드를 생성합니다.
그러나 최적화가 좋을수록 느리고 비용이 증가합니다. - 과도한 간결성과 생략으로 신뢰성과 가독성을 떨어뜨리지 마십시오.
기타