본문 바로가기
공학/CAE

포트란: 기계어와의 백병전에서 인류를 해방시킨 언어

by 도서관경비원 2025. 12. 13.
반응형

FORTRAN 77

 

1. 탄생의 배경 — "기계와의 백병전"

1950년대 초, 컴퓨터 프로그래밍은 소수의 전문가만이 다룰 수 있는 난해한 영역이었다. 프로그래머들은 0과 1로 이루어진 기계어 코드를 한 줄 한 줄 직접 작성해야 했고, 전체 작업 시간의 절반을 디버깅에 쏟아부어야 했다. 포트란의 주요 설계자 존 배커스(John Backus) 는 이 현실을 가리켜 "기계와의 백병전"이라고 표현하였다.

 

배커스는 이 현실을 바꾸겠다는 구상을 품었다. 수학 공식을 컴퓨터가 이해할 수 있는 코드로 자동 번역하는 언어를 만들겠다는 것이었다. 그는 체스 전문가, 결정학자, 암호학자, MIT 연구원 등 다양한 배경의 인재들을 모아 팀을 꾸렸다. 당초 6개월이면 완성될 것으로 예상했던 프로젝트는 결국 3년이 걸렸다.

 

1957년 4월, IBM 704 사용자들에게 최초의 포트란 컴파일러가 배포되었다. 세계 최초의 고수준 프로그래밍 언어가 역사의 무대에 등장한 순간이었다.


2. 포트란이 가져온 혁신

포트란(FORmula TRANslation)은 이름 그대로 수식을 코드로 번역하는 언어였다. 이 언어의 등장으로 과학자, 수학자, 엔지니어들은 프로그래머의 도움 없이 컴퓨터에 직접 문제를 입력할 수 있게 되었다.

 

회의적인 시각도 많았다. 자동으로 생성된 코드가 숙련된 프로그래머가 손으로 짠 기계어 코드만큼 빠를 리 없다는 것이었다. 그러나 배커스 팀이 구현한 최적화 컴파일러는 이 편견을 보기 좋게 깨뜨렸다. 포트란이 생성한 기계어 코드는 수작업 코드에 버금가는 실행 속도를 보여주었다. 초기 컴퓨터가 느리고 비쌌던 시대에, 이 효율성이 포트란의 성공을 결정지었다.


3. 버전의 역사 — 70년에 걸친 진화

포트란은 약 10년 주기로 새로운 버전을 출시하며 꾸준히 발전해 왔다.

 

FORTRAN I (1957): 최초의 고수준 프로그래밍 언어. 제한된 데이터 타입, 서브루틴 없음.

FORTRAN II (1958): 사용자 정의 함수와 서브루틴 도입. 절차적 프로그래밍과 코드 재사용이 가능해졌다.

FORTRAN IV: IF/THEN 개념, 논리 표현식(.AND., .OR., .EQ.), 복소수 기본 타입 추가.

FORTRAN 66 (1966): 컴퓨터 과학 역사상 최초로 공식 표준으로 정의된 프로그래밍 언어라는 이정표를 세웠다.

FORTRAN 77 (1977): C, 파스칼, 알골 등과의 경쟁에 대응하여 8년간의 작업 끝에 완성. 블록 IF문, CHARACTER 자료형, 직접 접근 입출력 도입. 역사상 가장 널리 사용된 포트란 버전이 되었다.

Fortran 90 (1990): 배열 프로그래밍, 모듈식 프로그래밍, 자유 소스 형식 도입. 이전 버전 대비 가장 극적인 개선이었다.

Fortran 95 (1995): 병렬 컴퓨팅 지원 강화, FORALL 구성, 순수 함수 추가.

Fortran 2003: 객체 지향 프로그래밍(OOP) 지원, C 언어와의 상호 운용성, 유니코드 문자 집합 도입.

Fortran 2008: 공배열(coarray)과 동시성 프로그래밍 지원. 역호환성 철저히 유지.

Fortran 2023 (2023년 11월): 조건부 표현식, 열거형, 삼각함수 확장 등 실용적 기능 추가. ISO 표준으로 발표.


4. 표준화 — 어느 기업도 독점하지 않는다

포트란의 새 버전 개발은 국제표준화기구(ISO) 산하 포트란 작업 그룹 WG5가 총괄하고, 실제 작업은 미국 INCITS J3 위원회에 위임된다. 개발 과정은 제안 수집 → 구현 가능성 검토 → 초안 작성 및 전 세계 배포 → 수정과 합의 → 최종 국제 투표의 순서로 이루어지는 장기적 과정이다.

 

포트란의 진화는 어느 한 기업이나 기관이 주도하는 것이 아니라, 전 세계 이해 당사자들의 집단적 합의를 통해 이루어진다. 이것이 포트란을 70년 동안 특정 기업의 종속 없이 살아남게 한 핵심 요인 중 하나다.


5. 하위 호환성 — 과거를 품고 미래로

포트란 설계자들이 항상 마주해 온 가장 큰 딜레마는 새로운 기능 도입기존 코드 보호 사이의 균형이었다. 수십 년간 과학·공학 분야에서 축적된 방대한 포트란 코드들이 여전히 현업에서 살아 있기 때문이다.

 

이를 위해 도입된 것이 '구식 기능(obsolescent feature)' 제도다. 더 나은 방식으로 대체된 오래된 기능을 즉시 삭제하는 대신, 먼저 '구식'으로 선언하여 새 프로그램에서의 사용을 권장하지 않고, 실제 사용이 무시할 수 있는 수준으로 줄어든 이후에야 공식 삭제한다.

 

그 결과, Fortran 2008 컴파일러는 1957년에 작성된 포트란 I 프로그램을 몇 가지 사소한 수정만으로 여전히 컴파일할 수 있다. 70년을 넘는 하위 호환성 — 이는 어떤 프로그래밍 언어에서도 찾아보기 어려운 경이로운 기록이다.


6. 현재와 미래 — 슈퍼컴퓨터의 언어

1968년 한 학술지가 포트란을 "구식"이라고 선언한 지 반세기가 넘었다. 그러나 포트란은 오늘도 살아 있다.

 

수치 기상 예측, 유한요소 해석, 전산 유체 역학, 플라즈마 물리학, 지구물리학, 전산 화학 — 이 모든 수치 집약적 과학·공학 분야에서 포트란은 여전히 핵심 언어다. 세계에서 가장 빠른 슈퍼컴퓨터들의 성능 벤치마크에도 포트란 프로그램이 사용된다.

 

이것은 단순한 관성이 아니다. 수십 년간 검증된 방대한 과학 계산 라이브러리, 축적된 알고리즘, 그리고 꾸준한 표준 개정을 통한 현대화가 포트란을 계속 살아 숨 쉬게 한다.


마치며

포트란은 단순한 프로그래밍 언어를 넘어 컴퓨팅의 역사 그 자체다. 기계어와의 백병전에서 인류를 해방시킨 첫 번째 고수준 언어로 시작하여, 70년에 걸친 꾸준한 진화를 통해 현대 과학 계산의 근간으로 자리를 지키고 있다. 과거의 유산을 품으면서도 미래의 요구에 응답해 온 포트란의 여정은, 좋은 기술이 어떻게 시대를 초월하여 살아남는지를 보여주는 가장 훌륭한 사례 중 하나다.

FORTRAN I 코드

C SOLVE QUADRATIC EQUATION IN FORTRAN I
    READ 100,A,B,C
100 FORMAT(3F12.4)
    DISCR = B**2-4*A*C
    IF (DISCR) 10,20,30
 10 X1=(-B)/(2.*A)
    X2=SQRTF(ABSF(DISCR))/(2.*A)
    PRINT 110,X1,X2
110 FORMAT(5H X = ,F12.3,4H +i ,F12.3)
    PRINT 120,X1,X2
120 FORMAT(5H X = ,F12.3,4H -i ,F12.3)
    GOTO 40
 20 X1=(-B)/(2.*A)
    PRINT 130,X1
130 FORMAT(11H X1 = X2 = ,F12.3)
    GOTO 40
 30 X1=((-B)+SQRTF(ABSF(DISCR)))/(2.*A)
    X2=((-B)-SQRTF(ABSF(DISCR)))/(2.*A)
    PRINT 140,X1
140 FORMAT(6H X1 = ,F12.3)
    PRINT 150,X2
150 FORMAT(6H X2 = ,F12.3)
 40 CONTINUE
    STOP 25252

FORTRAN 77 코드

PROGRAM QUAD4
C
C This program reads the coefficients of a quadratic equation of
C the form
C A * X**2 + B * X + C = 0,
C and solves for the roots of the equation (FORTRAN 77 style).
C
C Get the coefficients of the quadratic equation.
C
    WRITE (*,*) 'Enter the coefficients A, B and C: '
    READ (*,*) A, B, C
C
C Echo the coefficients to make sure they are entered correctly.
C
    WRITE (*,100) 'The coefficients are : ', A, B, C
100 FORMAT (1X,A,3F10.4)
C
C Check the discriminant and calculate its roots.
C
    DISCR = B**2 - 4.*A*C
    IF ( DISCR .LT. 0) THEN
    WRITE (*,*) ' This equation has complex roots:'
    WRITE (*,*) ' X = ', -B/(2.*A), ' +i ', SQRT(ABS(DISCR))/(2.*A)
    WRITE (*,*) ' X = ', -B/(2.*A), ' -i ', SQRT(ABS(DISCR))/(2.*A)
    ELSE IF ( (B**2 - 4.*A*C) .EQ. 0) THEN
    WRITE (*,*) ' This equation has a single repeated real root:'
    WRITE (*,*) ' X = ', -B/(2.*A)
    ELSE
    WRITE (*,*) ' This equation has two distinct real roots:'
    WRITE (*,*) ' X = ', (-B + SQRT(ABS(DISCR)))/(2.*A)
    WRITE (*,*) ' X = ', (-B - SQRT(ABS(DISCR)))/(2.*A)
    END IF
C
	END

FORTRAN 2008 코드

PROGRAM roots
! Purpose:
! This program solves for the roots of a quadratic equation of the form
! A * X**2 + B * X + C = 0. It calculates the answers regardless of the
! type of roots that the equation possesses (Fortran 95/2003 style).
!
IMPLICIT NONE
! Declare the variables used in this program
REAL :: a ! Coefficient of X**2 term of equation
REAL :: b ! Coefficient of X term of equation
REAL :: c ! Constant term of equation
REAL :: discriminant ! Discriminant of the equation
REAL :: imag_part ! Imaginary part of equation (for complex roots)
REAL :: real_part ! Real part of equation (for complex roots)
REAL :: x1 ! First solution of equation (for real roots)
REAL :: x2 ! Second solution of equation (for real roots)
! Prompt the user for the coefficients of the equation
WRITE (*,*) 'This program solves for the roots of a quadratic '
WRITE (*,*) 'equation of the form A * X**2 + B * X + C = 0. '
WRITE (*,*) 'Enter the coefficients A, B, and C:'
READ (*,*) a, b, c
! Echo back coefficients
WRITE (*,*) 'The coefficients A, B, and C are: ', a, b, c
! Calculate discriminant
discriminant = b**2 - 4. * a * c
! Solve for the roots, depending upon the value of the discriminant
IF ( discriminant > 0. ) THEN ! there are two real roots, so...
X1 = ( -b + sqrt(discriminant) ) / ( 2. * a )
X2 = ( -b - sqrt(discriminant) ) / ( 2. * a )
WRITE (*,*) 'This equation has two real roots:'
WRITE (*,*) 'X1 = ', x1
WRITE (*,*) 'X2 = ', x2
ELSE IF ( discriminant == 0. ) THEN ! there is one repeated root, so...
x1 = ( -b ) / ( 2. * a )
WRITE (*,*) 'This equation has two identical real roots:'
WRITE (*,*) 'X1 = X2 = ', x1
ELSE ! there are complex roots, so ...
real_part = ( -b ) / ( 2. * a )
imag_part = sqrt ( abs ( discriminant ) ) / ( 2. * a )
WRITE (*,*) 'This equation has complex roots:'
WRITE (*,*) 'X1 = ', real_part, ' +i ', imag_part
WRITE (*,*) 'X2 = ', real_part, ' -i ', imag_part
END IF
END PROGRAM roots
반응형