본문 바로가기

Programming Languages [PL]

[PL] 01. Preliminaries

프로그래밍의 적용 분야 (Programming Domain)

  • 과학 : 대규모 소수점 연산, 배열 사용 / Fortran
  • 비즈니스 : 리포트 생성, 10진수 및 문자 사용 / COBOL
  • AI : 숫자 대신 기호 조작, 리스트 사용 / LISP
  • 시스템 프로그래밍 : 지속적인 사용으로 인한 필요성 / C
  • 웹 소프트웨어 : 마크업(문서나 데이터의 구조를 표현하는 것)(HTML), 스크립팅(PHP), 일반 목적(JAVA)

언어 평가 기준 (Language Evaluation Criteria)

Readability

  • 전반적인 간단함 : 관리 가능한 구조와 특징의 집합 / 최소한의 기능 다중성 / 최소한의 연산자 오버로딩
  • 직교성(Orthogonality) : 상대적 작은 수의 기본 구성요소가 상대적으로 적은 방법으로 결합이 된다. 모든 가능한 결합이 합법이어야 함
  • 데이터 타입 : 적당한 미리 선언된 데이터 타입 (언어 구성 요소가 서로 독립적이며 일관성 있는 방식으로 조합될 수 있는 정도)
  • 구문(Syntax) 고려 사항 : 식별자 형태 (유연한 구성) / 특별한 예약어 / 자기 서술적인 구성 요소 / 의미 있는 키워드

Writability

  • 간단함, 직교성 : 기본 제공 구조의 수가 적고, 이를 조합하는 일관된 규칙이 있는 것이 좋다.
  • 추상화 : 복잡한 구조와 작업을 세부 사항이 무시될 수 있게 정의하는 능력
  • 표현법 : 비교적 편리한 표현 방법 (Ex. a++) / 추상화와 표현법을 높이는 것은 오히려 Readability는 떨어트릴 수 있음

Reliability

  • 나의 의도에 맞게 코드를 짤 수 있는가?
  • Type Checking / Exception Handling : E.H.이 많아지면 Reliability는 올라가지만 Writability는 떨어질 수 있음
  • Aliasing : 동일 메모리에 접근할 수 있는 두 개 이상의 다른 이름을 가지는 것 -> 높으면 Reliability 떨어짐
  • Readability, Writability가 높아야 자연스러운 표현이 가능, 접근이 가능. Reliability 높아짐. (아닌 경우:과도한 동적 바인딩)

Cost

  • 개발자 양성
  • 작성, 실행, 컴파일
  • 유,무료 컴파일러
  • 낮은 신뢰성 -> 높은 비용 / 프로그램 유지 보수

Portability(이식성)

  • 프로그램을 다른 곳에서 쉽게 이동하여 구현할 수 있는가? (하드웨어나 OS에 상관없이, Java, C 등)

Generality(일반성)

  • 다른 응용 분야로의 적용 가능성

Well-definedness(명확성)

  • 언어의 공식 정의 문서의 완전성과 정확성

Computer Architecture Influence

프로그램 디자인 방법론

  • 간단한 응용프로그램, 효율적인 변화(구조적 프로그래밍, top-down design, step-wise 개선)
  • 프로세스 중심 -> 데이터 중심 (데이터 추상화)
  • 객체 지향 프로그래밍 (데이터 추상화 + 상속 + 다양성)

컴퓨터 구조

  • Von Neumann(폰 노이만) 아키텍처를 기반으로 개발된다. (명령형 언어)
  • Memory와 CPU 분리 / CPU는 메모리에 저장돼있는 프로그램의 명령어를 한 번에 하나씩 가져와 해석 후 실행
  • 변수는 메모리 셀을 모델링 / 대입문은 파이핑을 모델링 / 반복문(Iteration)은 효율적
  • 프로그램 내장 방식 컴퓨터(메모리에 프로그램(명령어+데이터) 저장
  • 메모리에 저장된 명령어를 순차 실행 / 명령어는 메모리에 저장된 값을 조작 혹은 연산

폰 노이만 병목 현상

  • 프로그램 명령어가 연결 속도보다 더 빨리 실행됨.
  • 그 연결 속도가 병목 현상을 초래. 이것이 컴퓨터 속도의 주요 제한 요소.
  • 메모리와 프로세서의 연결 속도가 컴퓨터의 속도를 결정하는 주요 요소이다.

Language Categories

Imperative (명령형)

  • 변수, 할당문, 반복문이 주요 특징
  • 객체지향, 스크립팅 언어, 시각적 언어 포함 (C, Java, Perl, JavaScript, C++)

Functional (함수형)

  • 함수를 인자로 취하고 결과를 반환하는 방식으로 계산을 수행
  • 변수, 대입문, 반복문(루프) 없음
  • 자기호출(recursion)에 의한 반복
  • 수학을 기반으로 프로그램 의미를 명확히 정의 가능, 기계 모델과 무관 (LISP, Scheme, ML, F#)

Logic (논리형)

  • p->q 형태의 술어 논리를 기반
  • 선언적으로 프로그래밍하는 언어
  • 증명하는 것을 계산하는 것으로 간주
  • 기계독립적. 정확한 의미구조
  • 문제를 해결하는 방법보다 문제가 무엇인지를 논리 문장으로 표현
  • 루프나 선택문 등의 제어 추상화가 없다. 제어는 하부 시스템에 의해 제공
  • 변수는 메모리 위치가 아니라 부분 결과 값에 대한 이름 (Prolog)

Language Design Trade-Offs

Reliability vs Execution Cost

Java는 배열 요소에 대해 모든 참조가 적절한 인덱싱인지 확인하도록 요구 -> 실행 비용 증가

 

Readability vs Writability

APL은 많은 강력한 연산자로 복잡한 계산을 간결하게 할 수 있지만 가독성이 낮아짐

 

Writability vs Reliability

C++ 포인터는 강력하고 유연하지만 신뢰성이 낮음


구현 방법

컴파일러(Compilation) : 대규모 상업적 응용 프로그램에 쓰임

  • 소스 코드로 작성된 고급 프로그램을 기계어로 번역
  • 번역 속도는 느리지만 실행 속도는 빠름
  • 어휘 분석(Lexical analysis) : 소스 프로그램의 문자를 어휘 단위로 변환 (Symbol table : #define MAX 100 등을 저장)
  • 구문 분석(Syntax analysis) : 어휘 단위를 구문 구조를 나타내는 Parse Tree로 변환 (문법적 에러를 검출)
  • 의미 분석(Semantics analysis) : 중간(intermediate) 코드 생성
  • 코드 생성(Code generation) : 기계어(Machine code) 생성
  • 로드 모듈 (실행 이미지) : 사용자 코드와 시스템 코드가 함께 있는 것 (프로그램을 실행하는 데 필요한 모든 정보를 가짐)
  • Linking : 시스템 프로그램 유닛을 수집하고 사용자 프로그램에 연결하는 과정

Pure Interpretation

  • 프로그램이 인터프리터에 의해 해석. 
  • 작은 프로그램이나 효율성이 문제가 되지 않는 프로그램에 사용 (JavaScript, PHP)
  • 번역이 없음
  • 프로그램 구현이 쉬움 (런타임 오류를 쉽고 즉각적으로 발견)
  • 실행 속도가 느리다.
  • 보통 더 많은 공간이 필요하다. 

Hybrid 구현 시스템 : 컴파일러와 순수 인터프리터의 절충안

  • 효율성이 첫 번째 우선순위가 아닌 중소규모의 시스템에서 사용
  • 고수준의 언어 프로그램이 쉽게 해석 가능한 중간 언어로 번역됨
  • 순수 인터프리터보다 빠름
  • Java의 초기는 하이브리드였음
  • 중간 형태인 바이트 코드는 바이트 코드 인터프리터와 런타임 시스템 (두 개를 합쳐서 Java Virtual Machine)이 있는 모든 기계에서 이식성 제공
  • Just-in-Time Implementation System : 프로그램을 처음에 중간 언어로 번역. 그리고 실행 중에 해당 언어의 메소드가 호출되면 기계어로 번역
  • 번역된 기계어는 이후 호출을 위해 기계어로 유지. JIT 시스템은 Java에서 널리 사용

전처리기(Preprocessor)

전처리기 매크로(명령어)는 다른 파일에서도 그 코드를 사용하기 위해서 쓴다. 

프로그램을 컴파일하기 직전에 내장된 전처리기 매크로를 확장하는 과정을 거친다. C의 전처리기 : #include, #define


언어 정의

어휘 구조(Lexical Structure) : 언어에서 사용하는 단어의 구조, 철자법을 의미

구문법(Syntax) : 구성요소를 이용하여 문장/프로그램을 구성하는 방법, 문법을 이용하여 기술 가능 (CFG in BNF) (Context free grammar in Backus-Naur Form)

의미론(Semantics) : 문장/프로그램의 의미를 정하는 것. 자연어 혹은 수학적으로 기술

 

프로그래밍 언어 구현

입력 프로그램 -> Syntax -> Semantics -> Interpret/Compile -> 입력 받은 소스 프로그램을 구문법에 맞는지 검사 -> 그 의미에 맞게 동작하도록 해석하거나 기계어로 번역


프로그래밍 환경

  • 소프트웨어 개발에 사용되는 도구의 집합
  • UNIX : 오래된 운영체제와 도구 모음
  • Microsoft Visual Studio.NET : 큰 복잡한 시각적 환경
  • Eclipse와 같은 IDE 도구
  • 웹 브라우저 환경