함수형 코딩 책의 가이 스틸(Guy Steele) 추천사 인데,
프로그래밍 패러다임의 변화를 이 보다 더 잘 설명한 글이 없다.
많은 사람들에게 널리 알리고 싶어, 허락 없이 게재하는데 용서해 줄거라고 기대한다.

저는 52년 넘게 프로그래밍을 했는데, 프로그래밍은 여전히 즐겁습니다. 새로운 문제에 도전하고 아직도 배울 것이 많기 때문입니다. 수십 년 동안 프로그래밍을 하면서 새로운 언어와 알고리즘, 코드를 구성하는 기술들을 배우면서 제 프로그래밍 스타일도 많이 바뀌었습니다.
제가 프로그래밍을 처음 배운 1960년대에는 코드를 만들기 전에 순서도를 그리는 것이 일반적이었습니다. 계산은 사각형으로, 조건문은 다이아몬드로, 입출력은 다른 도형으로 표시했습니다. 그리고 실행 흐름은 화살표로 표시했습니다. 프로그래밍은 단순히 순서도를 코드로 옮기는 일이었습니다. 순서도에서 화실표가 다음 상자를 가리키면 코드 위치와 상관없이 제어권을 넘기기 위해 goto 문을 작성했습니다. 그래서 스파게티 코드가 되는 경우가 많았습니다. 당시에는 '스파게티 코드'가 이해하기 어렵다는 이야기와 유지보수를 잘할 수 있는 방법에 대한 논의가 정말 많았습니다.

구조적 프로그래밍structured programming

1970년대 초반 구조적 프로그래밍structured programming이라고 하는 개념이 많이 회자되었습니다. 구조적 프로그래밍은 제 프로그래밍 스타일에 처음으로 큰 영향을 줬습니다. 그 당시 커뮤니티에서 논의되던 구조적 프로그래밍의 중용한 핵심은 두 가지였습니다. 모두 흐름 제어 구조organizing control flow에 관한 내용이었습니다. 흐름 제어를 단순한 패턴으로 만들자는 것이 가장 유명해진 내용입니다. 순차적 실행과 if-then-else, switch 같은 다양한 방법으로 분기하는 구문, for 및 while과 같은 반복적 실행을 위한 구문들입니다. 'goto 문을 몰라내자!'라는 슬로건 아래 너무 과하게 단순화하는 경우도 있었지만, 이 패턴을 일관되게 사용한다면 실제로 goto 문을 사용할 일이 거의 없다는 것이 핵심이었습니다. 구조적 프로그래밍의 두 번째 핵심 개념은 덜 유명하지만 중요한 개념이었습니다. 중첩할 수 있는 블록으로 순차적으로 실행되는 구문을 나눌 수 있었습니다. 또 제어권을 비지역non-local 범위로 넘길 수 있어서 블록에서 블록 끝으로 가너가continue 블록 밖으로 나갈break 수 있었습니다. 하지만 블록 안으로 들어올 수는 없었습니다.
구조적 프로그래밍 개념을 처음 접했을 때 구조적 프로그래밍 언어를 쓰지는 않았습니다. 대신 쓰고 있던 포트란Fortran 코드를 구조적 프로그래밍 개념에 맞춰 조금씩 고쳤습니다. 어떤 경우에는 구조적 프로그래밍 언어의 컴파일러가 기계어로 바꾸는 것처럼 저수준의 어셈블리어를 써야 했습니다. 이런 원칙을 지키면 프로그램을 더 쉽게 만들 수 있고 유지보수도 잘할 수 있다는 것을 알았습니다. goto 문이나 분기문을 완전히 없애지는 못했지만, 항상 일관된 패턴을 만들어 썼기 때문에 코드가 명확하고 읽기 쉬웠습니다.
포트란으로 코드를 작성할 때는 모든 변수를 프로그램 상단에 미리 선언해야 했고, 변수 선언 이후에 실행할 코드를 작성했습니다. 코볼COBOL 언어는 변수 선언을 더 업격하게 제한해서, 모든 변수는 언어에서 지정된 공간인 '데이터 영역'이라는 곳에 정의해야 했습니다. 실제로 데이타 영역은 'DATA DIVISION'이라는 구문을 사용했고, 또 실행할 코드는 'PROCEDURE DIVISION'이라는 구문 이후에 작성했습니다. 포트란의 모든 변수는 코드의 어떤 곳에서도 접근할 수 있었기 때문에 어떤 변수를 어디에서 쓰는지 파악하기 힘들었습니다.

객체 지향 프로그래밍object-oriented programming

두 번째로 제 프로그래밍 스타일에 큰 영향을 준 개념은 '객체 지향 프로그래밍object-oriented programming'이었습니다. 객체 지향 프로그래밍은 객체와 클래스, '정보 은닉information hiding', '추상 데이터 타입abstract data type'에 대한 초기 개념을 정리했습니다. 생각해 보면 객체 지향 프로그래밍의 핵심은 두 가지였는데, 모두 데이터 접근 구조organizing access to data에 관한 내용이었습니다. 객체 지향 프로그래밍의 첫 번째 핵심 개념은 모든 변수가 어떤 구조에 '캡슐화encapsulated'되거나 '포함contained'된다는 것 입니다. 코드의 특정 부분에서만 변수에 접근할 수 있기 때문에 코드를 관리하고 읽기 쉬워집니다. 프로그램 가장 위에 변수를 선언하지 않고 블록 안에 로컬 변수를 선언하거나 클래스(또는 모듈)의 메서드(모듈에 있는 프로시저)만 접근할 수 있도록 안전하게 변수를 선언할 수 있었습니다. 클래스나 모듈에 있는 변숫값이 변경되면 관련된 변수가 함께 변경되도록 메서드 또는 프로시저를 만들기 때문에 변수들의 집합이 일관된 속성을 따르게 할 수 있습니다. 객체 지향 프로그래밍의 두 번째 핵심 개념은 상속inheritance입니다. 상속은 단순한 클래스에 변수나 메서드를 추가하거나 메서드를 재정의해서 더 복잡한 객체를 만드는 것을 의미합니다. 상속도 캡슐화가 있기 때문에 가능한 것입니다.
객체와 추상 데이터 타입에 대해 많이 배웠지만 당시 주로 사용하던 리스프Lisp는 객체 지향 언어가 아니었습니다. 하지만 리스프로 허용된 메서드(리스프 함수)만 데이터 구조에 접근하도록 만드는 것은 어렵지 않았습니다. 데이터 접근 구조에 대한 개념에 집중했기 때문에 객체 지향 언어를 사용하지 않아도 장점들을 얻을 수 있었습니다.

함수형 프로그래밍functional programming

다음으로 프로그래밍 스타일에 큰 영향을 준 개념은 '함수형 프로그래밍functional programming'이었습니다. '부수 효과side effect를 없애라!'라는 슬로건 때문에 너무 단순하게 생각할 수도 있지만, 사실 함수형 프로그래밍은 부수 효과 구성organizing side effect에 관한 내용입니다. 부수 효과를 잘 관리해서 코드의 아무 곳에나 있지 않도록 하는 것입니다. 이 책의 주제이기도 합니다.
함수형 프로그래밍도 서로 연결된 두 가지 핵심 개념이 있습니다. 하나는 계산computation과 액션action을 구분하는 것입니다. 계산은 외부에 어떤 영향을 주지 않기 때문에 여러 번 실행해도 같은 결과를 돌려줍니다. 하지만 화면에 글씨를 표시하거나 로켓을 발사하는 것과 같은 액션은 실행할 때마다 다른 결과가 나올 수도 있습니다. 액션은 부수 효과를 가지고 있습니다. 코드에 어떤 부분에 부수 효과가 있고 어떤 부분이 '순수한 계산'인지 쉽게 구분할 수 있는 패턴으로 구성하면 프로그램을 쉽게 이해할 수 있습니다. 이 패턴은 단일 스레드(순차적 실행)에서 실행하는 경우와 다중 스레드(동시 실행)에서 실행하는 경우로 나눌 수 있습니다.
함수형 프로그래밍의 두번째 핵심 개념은 배열, 리스트, 데이터베이스와 같은 컬렉션을 하나씩 처리하지 않고 '한 번에' 처리한다는 개념입니다. '한 번에' 처리하기 위해서는 컬렉션 항목에 외부에 영향을 주는 부수 효과가 없어야 합니다. 항목이 독립적일 때 가장 효과적입니다. 이 개념은 첫 번째 개념인 계산과 액션의 구분이 었어야 동작하는 개념입니다.

저는 1995년 자바Java 프로그래밍 언어의 첫 번째 스펙을 작성하는 데 참여했습니다. 그리고 다음 해에 자바스크립트JavaScript 표준(ECMAScript 표준)을 작성하는 데 도움을 줬습니다. 둘 다 객체 지향 언어라고 할 수 있습니다. 자바에는 전역변수가 없고 모든 변수는 클래스나 메서드 안에 정의합니다. 또 두 언어에는 goto 문이 없습니다. 언어를 설계한 사람이 구조적 프로그래밍 운동에 대해 성공적이었다고 생각했기 때문에 goto 문을 없앴습니다. 수많은 개발자들이 요즘도 goto 문이나 전역변수 없이 프로그래밍을 잘하고 있습니다.
함수형 프로그래밍은 어떨까요? 하스켈Haskell과 같이 대중적인 순수 함수형 프로그래밍이 있습니다. 하스켈로 화면에 글씨를 표시하거나 로켓을 발사할 수 있지만, 이런 부수 효과를 사용하러면 매우 엄격한 원칙을 따라야 합니다. 그중 하나는 어떤 일이 생기는지 확인해 보기 위한 코드 중간중간 print 구문을 쓸 수 없다는 것입니다.
순수 함수형 언어가 아니지만 자바나 자바스크립트, C++, 파이썬과 같은 언어에 대해서도 함수형 프로그래밍 개념을 사용해 프로그래밍을 더 쉽게 할 수 있습니다. 부수 효과를 다루는 원칙을 이해하면 어떤 프로그래밍 언어를 사용하더라도 함수형 프로그래밍의 개념을 적용할 수 있습니다. 바로 이 책, <<쏙쏙 들어오는 함수형 코딩>>에서 부수 효과를 다루는 원칙을 확인할 수 있습니다. 저도 코드에 적용할 수 있는 몇 가지 개념을 배웠고 정말 재밌게 읽었습니다. 여러분도 이 책과 함께 즐거운 시간이 되길 바랍니다!

0개의 댓글