본문 바로가기

수업 기록/(21-2)프로그래밍언어구조론

[프로그래밍 언어 구조론]제 1장. 서론

§학습목표

프로그래밍언어의 간단한 역사, 추상화, 패러다임, 언어정의 및 번역에 대한 날카로운 시각 함양

 

PL과 관련된 여러 가지 배경지식에 대해서 정리해 봅시다

 


PL 왜 공부하나?

우리는 왜 프로그래밍 언어를 공부하는가?

  우리가 의사 소통하는 방식은 우리가 생각하는 방식에 영향을 미칩니다

  우리가 컴퓨터를 프로그래밍하는 방법은 계산에 대해 생각하는 방법에 영향을 미칩니다

 

PL의 기본 원리와 개념은 컴퓨터 과학 지식의 기본 체계의 일부입니다.

이러한 원리에 대한 연구는 프로그래머와 컴퓨터 과학자에게 필수적입니다.

 

PL의 역사

프로그래밍 언어: "우리가 원하는 것을 컴퓨터와 통신하기 위한 표기법"으로 정의

1940년대 중반 이전에 컴퓨터 운영자는 요청된 작업을 수행하기 위해 컴퓨터의 내부 배선을 조정하기 위해 스위치를 설정했습니다.

PL을 통해 컴퓨터 사용자는 하드웨어를 재구성하지 않고도 문제를 해결할 수 있습니다.

 

기계어와 최초의 저장 프로그램

  • 존 폰 노이만(John von Neumann): 컴퓨터는 소규모의 범용 작업으로 영구적으로 하드와이어링되어야 한다고 제안했습니다.
  • 운영자가 일련의 이진 코드를 입력하여 보다 구체적인 문제를 해결하기 위해 기본 하드웨어 작업을 구성할 수 있습니다.
  • 작업자는 기계어라고 하는 이러한 코드를 메모리에 입력하기 위해 스위치를 뒤집을 수 있습니다.

기계언어

코드의 각 줄에는 16비트 또는 이진수가 있습니다.

  • 단일 기계어 명령어 또는 단일 데이터 값을 나타냅니다.

프로그램 실행은 코드의 첫 번째 줄에서 시작됩니다.

  • 코드를 메모리에서 가져와 디코딩(해석)하고 실행합니다.

그런 다음 제어는 다음 코드 줄로 이동하고 정지 명령에 도달할 때까지 계속됩니다.

 

Opcode: 코드 라인의 처음 4비트

  • 수행할 작업 유형을 나타냅니다.

다음 12비트는 명령어의 피연산자에 대한 코드를 포함합니다.

피연산자 코드는 기계 레지스터의 수이거나 메모리의 다른 데이터 또는 명령어의 주소와 관련됩니다.

기계 언어 프로그래밍은 지루하고 오류가 발생하기 쉽습니다.

어셈블리 언어

어셈블리 언어: 명령어 코드 및 메모리 위치에 대한 니모닉 기호 집합

(니모닉 코드: 사람이 알아보기 쉽도록 나타낸 기호이다.)

  • 예: LD R1, FIRST

어셈블러: 기호 어셈블리 언어 코드를 이진 기계 코드로 변환하는 프로그램

로더: 기계어 코드를 컴퓨터 메모리에 로드하는 프로그램

입력 장치 : 키펀 머신, 카드 리더...

 

니모닉 기호 단점

  • 기존 수학적 표기법의 추상화 부족
  • 각 유형의 컴퓨터 하드웨어 아키텍처에는 고유한 기계어 명령어 세트가 있으며 고유한 어셈블리 언어 방언이 필요합니다.

어셈블리 언어는 1950년대에 처음 등장했으며 오늘날에도 저수준 시스템 도구 또는 수동 최적화에 사용됩니다.

FORTRAN 및 대수 표기법

FORTRAN: 수식 번역 언어

  • 1950년대 초 John Backus가 개발
  • 특정 유형의 기계 아키텍처 반영
  • 이후 고급 언어의, 구조화된 제어 명령문 및 데이터 구조 부족

대수 표기법 및 부동 소수점 숫자 지원으로 과학자 및 엔지니어에게 인기 있음

알골 패밀리

ALGOL: 1960년에 출시된 ALGOLithmic Language

  • 컴퓨터 과학자가 저널에 알고리즘을 게시할 수 있는 표준 표기법 제공
  • 시퀀싱(begin-end 블록), 루프(for 루프) 및 선택(if 및 if-else 문)을 위한 구조화된 제어 문 포함
  • 지원되는 다양한 숫자 유형
  • 배열 구조 도입
  • 재귀 절차를 포함하여 지원되는 절차

ALGOL은 각 유형의 하드웨어와 함께 ALGOL 컴파일러에 대한 충족을 통해 기계 독립성을 달성했습니다.

 

컴파일러: 프로그래밍 언어 문장을 기계어로 번역

 

ALGOL은 공식적인 사양이나 정의를 얻은 최초의 언어였습니다.

  •   프로그래머와 컴파일러 작성자 모두를 위한 기능을 정의한 문법 포함

다음을 포함하여 ALGOL에서 파생된 많은 고급 언어:

  •   파스칼: 1970년대 프로그래밍 교육용 언어
  •   Ada: 미 국방부의 임베디드 애플리케이션용

폰 노이만 아키텍처 없이 계산

고급 언어는 여전히 기계의 폰 노이만 모델의 기본 아키텍처를 반영했습니다.

  • 프로그램 및 데이터를 위한 메모리 영역이 저장됩니다.
  • 메모리에서 가져온 명령어를 순차적으로!! 실행하는 별도의 CPU

프로세서 속도 향상 및 PL의 추상화 증가로 정보화 시대

 

언어 추상화 및 하드웨어 성능의 발전->장애물

  • 하드웨어는 무어의 법칙에 의해 예측된 개선의 한계에 도달하기 시작하여 멀티 코어 접근 방식으로 이어졌습니다.
  • 대형 프로그램은 디버그 및 수정이 어려웠습니다.
  • 단일 프로세서 계산 모델은 병렬로 실행되는 여러 CPU의 새로운 아키텍처에 쉽게 매핑될 수 없습니다.
  • (순차적으로 한 번에 하나의 명령어만을 처리하기 때문에 CPU를 효율적으로 사용하지 못한다)

솔루션: 언어는 특정 하드웨어 모델을 기반으로 할 필요는 없고 문제 해결 스타일에 적합한 계산 모델을 지원하기만 하면 됩니다.

 

람다 미적분: 수학자 Alonzo Church가 개발한 계산 모델

  •   재귀 함수 이론을 기반

Lisp: 계산의 기능적 모델을 사용하는 프로그래밍 언어

 

병렬 처리에 적합한 비 폰 노이만 컴퓨팅 모델을 기반으로 하는 다른 언어는 다음과 같습니다.

  • 자동 정리 증명 기능이 있는 형식 논리 모델
  • 메시지 전달을 통한 객체의 상호 작용을 포함하는 모델

PL의 추상화(주로 사람의 가독성을 위해)

추상화 프로세스 특징

  • 세부 정보 숨기기
  • 중요한 부분을 보여줌

추상화 유형

  • 데이터 추상화: 인간을 위한 데이터의 동작 및 속성 단순화 (예: 숫자, 문자열, 검색 트리)
  • 제어 추상화: 제어 전송 속성 단순화 (예: 루프, 조건문, 프로시저 호출)

추상화 수준(정보의 양)

  • 기본 추상화: 가장 로컬의 기계 정보 수집
  • 구조적 추상화: 프로그램 구조에 대한 중간 정보 수집
  • 단위 추상화: 프로그램에서 대규모 정보 수집

기본적, 구조적 , 단위 추상화

데이터 기본 추상화: 데이터 값의 내부 표현을 숨깁니다.

  • 변수: 데이터 값을 포함하는 컴퓨터 메모리 위치를 숨기기 위해 기호 이름 사용
  • 데이터 유형: 데이터 값의 종류에 부여되는 이름
  • 선언: 변수에 이름과 데이터 유형을 지정하는 프로세스
  • 예) 덧셈과 곱셈과 같은 표준 수학 연산

데이터 구조 추상화: 관련 데이터 값을 단일 단위로 수집

  • 구성 요소 부품을 숨기지만 부품에서 구성할 수 있으며 부품에 액세스하고 수정할 수 있습니다.
    • 예 1) 사원 레코드에 이름, 주소, 전화번호, 급여가 포함됨(데이터 유형이 다름)
    • 예 2) 배열: 동일한 데이터 유형을 가진 개별적으로 인덱싱 된 항목의 시퀀스
    • 예 3) 텍스트 파일: 외부 저장 장치와 주고받기 위한 일련의 문자

데이터 단위 추상화: 종종 추상 데이터 유형과 연관됨

  •   데이터 값 집합 및 해당 값에 대한 작업
  •   정보 은닉: 정보를 숨기는 새로운 데이터 유형 정의

 

인터페이스, 구현

  • 인터페이스: 사용자가 사용할 수 있는 작업 집합
  • 구현: 값 및 작업의 내부 표현

예:

  • ML, Haskell 및 Python의 모듈
  • Lisp, Ada 및 Java의 패키지
  • 객체 지향 언어의 클래스 메커니즘

단위 추상화는 또한 재사용성을 제공합니다.

일반적으로 구성 요소는 라이브러리에 입력되고 라이브러리 메커니즘의 기반이 됩니다.

  •   상호 운용성으로 유닛 조합 가능

API: 리소스 구성 요소에 대한 정보 제공

제어: 기본 및 구조적 추상화, 단위 추상화

기본 제어 추상화: 몇 가지 기계 명령을 이해하기 쉬운 추상 명령문으로 결합하는 명령문

구문 설탕: 복잡한 표기법을 더 간단한 속기 표기법으로 대체할 수 있는 메커니즘

  • 예: x = x + 10 대신 x += 10

구조화 제어 추상화: 프로그램을 실행을 제어하는 테스트 내에 중첩된 명령어 그룹으로 나눕니다.

  • 시퀀싱, 선택 및 반복의 기본 제어 구조의 논리를 표현하는 데 도움이 됩니다.

예: 분기 명령어, 반복자, 프로시저, 런타임 환경, 함수, 재귀, 고차 함수

 

단위 제어 추상화: 프로그램의 다른 부분에 논리적으로 관련된 서비스를 제공하는 독립 실행형 절차 모음

  •   장치에서 제공하는 서비스의 세부 사항을 알 필요 없이 프로그램 전체를 이해할 수 있습니다.

스레드: Java 시스템 내에서 별도로 실행되는 제어 경로

프로세스: Java 시스템 외부에서 실행되는 기타 프로그램

작업: 병렬 실행을 위한 Ada의 메커니즘

프로그래밍 패러다임

명령 패러다임: 세 가지 속성을 가진 언어

  • 명령을 나타내는 명령문의 시퀀스
  • 메모리 위치를 나타내는 변수 사용
  • 변수 값을 변경하기 위한 할당 사용
  • 순차적인 명령의 수행
  • von Neumann 병목 현상: 프로그램이 일련의 명령으로 설명되어야 한다는 요구 사항

함수형 패러다임

  • 람다 미적분학에서 함수의 추상적 개념을 기반으로

논리 패러다임

  • 수학적 연역의 기호 논리를 기반으로
  • 기능적 논리와 논리 모두 프로그램이 올바르게 실행되는지 여부를 더 쉽게 결정할 수 있습니다.

객체 지향 패러다임

  •   실제 객체의 동작을 모방하는 방식으로 작동하는 재사용 가능한 코드

명령형 프로그래밍 예제

더보기

function gcd (u, v: in integer) return integer is

  y, t, z: integer;

begin

  z := u;

  y := v;

  loop

    exit when y = 0;

    t := y;

    y := z mod y;

    z := t;

  end loop;

  return z;

end gcd;

 

객체지향 프로그래밍 예제

더보기

1.

 

2.

 

 

함수형 프로그래밍

 

computation은 함수의 평가입니다.

  •   적용 언어

함수형 언어

  •   가치 지향적
  •   변수나 할당이 허용되지 않습니다.
  •   제어 변수를 정의할 수 없기 때문에 루프가 없습니다.

재귀 함수 이론의 이론적 속성 : 튜링 완전성(재귀를 충족하는 조건)

  • 정수 값
  • 산술 함수
  • 기존 함수, 선택 및 재귀를 사용하여 새 함수를 정의하는 메커니즘

함수형 프로그래밍 예제

논리 프로그래밍

계산은 증명이다

  •   선언적 언어

논리 언어

  • 프로그램은 참인 주장의 집합으로 구성됩니다.
  • 기본 시스템이 제어 흐름을 결정합니다.
  • 초고급 언어

논리형 프로그래밍 예제

더보기

gcd(U, V, U) :- V = 0.

gcd(U, V, X) :- not(V = 0),

                Y is U mod V,

                gcd(V, Y, X).

언어 정의

형식 언어 정의장점

  • 프로그램에 대해 수학적으로 추론할 수 있도록 도와줍니다.
  • 기계 또는 구현 독립성을 위한 표준화 촉진
  • 프로그램 동작 및 상호 작용 정의
  • 언어가 설계될 때 규율을 보장합니다.

언어 정의 방식

  • 구문: 프로그램의 구조
  • 의미론: 프로그램의 의미(실행)

언어 정의 방법

구문 정의

  • 토큰: 언어의 단어
    •   키워드, 식별자, 연산 기호, 특수 구두점 기호 등을 포함합니다.
  • 어휘 구조: 언어 단어의 구조
    •   자연어의 철자와 유사
    •   정규식
  • 문맥자유(Context-free) 문법
    •   <if-문> ::= if (<표현식>) <문>
    •   [기타 <문장>]

의미론적 정의

  • 프로그램 실행 시 어떠한 일이 일어나는가를 기술
  • 형식적 방법
  • 조작적, 지시적, 공리적 의미론
  • (일반적으로 인정되는 형식적 방법 없음)

언어번역기

언어 번역기

  •   언어로 된 프로그램을 받아들이고 실행
  •   언어 처리기라고도 함

두 가지 유형

  •   인터프리터: 프로그램을 직접 실행
  •   컴파일러: 실행에 적합한 형태로 동등한 프로그램을 생성합니다.
  • + 의사 인터프리터(하이브리드 번역기)

인터프리터

 

컴파일러

 

 

의사 인터프리터

 

에러처리

오류의 종류

  • 구문 오류: 프로그램이 제대로 구성되지 않았습니다.
  • 의미 오류
    • 정적 의미 오류: 컴파일 시간 동안 감지됨(예: 호환되지 않는 유형)
    • 동적 의미 오류: 런타임 중에 감지됨(예: 0으로 나누기)
  • 논리 오류: 프로그래머만 이러한 종류의 오류를 알고 있습니다.

 

대부분의 번역기는 몇 가지 종류의 디버깅 도구를 지원합니다.

 

에러 예제

 

프로그래밍 언어의 미래

1960년대에 컴퓨터 과학자들은 모든 요구 사항을 충족하는 단일 범용 프로그래밍 언어를 원했습니다.

 

1970년대 후반과 1980년대 초반에 그들은 사용자가 요구 사항을 정의한 다음 시스템을 생성할 수 있는 설계 언어를 원했습니다.

  •   이것이 논리 프로그래밍 언어가 시도하는 것입니다.

프로그래밍은 구식이 되지 않아왔습니다.

  •   새로운 기술을 지원하기 위해 새로운 언어가 등장할 것입니다.

뉴스 그룹의 게시물 수를 기준으로 2000년 이후 프로그래밍 언어의 상대적인 인기도:

연습문제

–1.4: abstraction에 대한 이해

–1.8 : programming paradigm에 대한 이해

–1.19 : programming error에 대한 이해