프로그래밍 세계의 일등 시민

Minho Jang
ryanjang-devnotes
Published in
7 min readSep 18, 2021

이 글은 제가 쓴 ‘Who Is the First-Class Citizen In Programming World?’ 을 번역하였습니다.

Intro

프로그래밍 언어에서 “일급(First-class)” 라는 말을 들어본 적이 있으신가요? 자바스크립트, 스칼라 또는 일급 함수 사용을 권장하는 다른 언어를 사용하는 중이라면, 이 개념에 대해 친숙하실 것입니다.

‘일급 객체'라는 개념은 Christopher Strachey에 의해 1960년대 처음 등장하였습니다. 그는 이것을 실수(Real numbers)와 절차(Procedures)를 구별하기 위해 도입하였습니다. 이후, Robin Popplestone은 이러한 개념을 현대적으로 정의하며, 아래와 같은 조건을 포함해야한다고 내세웠습니다.

  1. 함수의 실제 파라미터가 될 수 있다.
  2. 함수의 결과값으로 리턴될 수 있다.
  3. 변수 할당문의 대상이 될 수 있다.
  4. 등식(Equality)을 테스트할 수 있다.

프로그래밍 언어에서는 일급 함수, 일급 제어, 일급 메세지 등 여러 종류의 데이터가 이러한 조건을 성립합니다. 그 중에서 개발자들이 가장 많이 사용하는 일급 함수에 대해 오늘 살펴보고자 합니다.

First-class Function

일반적으로 함수가 변수처럼 취급되어질 때 우리는 해당 프로그래밍 언어가 일급 함수를 가지고 있다고 이야기합니다. 이 말인 즉슨, 예를 들어 하나의 함수는 다른 메소드의 파라미터로 넘겨질 수 있고, 결과값이 되거나 변수값으로 할당될 수가 있다는 것입니다.

자바스크립트를 사용하면, 변수로 익명 함수를 할당해서 그 변수 끝에 () 를 붙이는 것만으로 함수를 불러올 수 있습니다.

하나의 함수는 또한 다른 함수를 파라미터로 받을 수 있는 데, 이 때의 함수를 콜백 함수라고 합니다. 반대로, 함수가 또 다른 함수를 결과값으로 리턴하는 것도 가능합니다. (고차 함수)

First-class Collection

일급 컬렉션은 하나의 컬렉션 외에 다른 멤버 변수를 두지 않는 클래스를 말합니다. 2008년 ThoughtWorks Anthology의 공저자 Jeff Bay에 의해 제안된 이러한 개념은 사실 이전에 말씀드린 일급 객체와는 그다지 큰 관련은 없습니다. 그보다, 이것은 객체 지향의 관점에서 어떻게하면 소프트웨어 디자인을 더욱 개선할 수 있는 가에 관한 내용입니다. 저자는 다음과 같이 일급 컬랙션 사용을 제안합니다.

… 각 컬렉션은 고유한 클래스에 의해 감싸지게 되면 그 컬렉션과 관련된 액션들이 속할 수 있는 공간이 생기게 된다. 필터들이 이러한 새로운 클래스의 부분이 되었다고 하자. 필터들은 또한 함수 객체가 될지도 모른다. 그뿐 아니라, 이 새 클래스는 두 그룹을 합친다던지 또는 그룹의 각 요소에 새로운 규칙을 적용한다던가 하는 활동들을 제어할 수 있게 된다. 이것은 인스턴스 변수들에 관한 규칙의 명백한 연장이지만 그 자체로서도 중요하다. 컬랙션은 매우 유용한 원시형 데이터 타입이다. 이것은 다양한 행동을 가지지만 유지보수 또는 인수자를 위해 어떠한 의도나 단서를 제공하지 못하기 때문이다.

- Jeff Bay, The ThoughtWorks Anthology: Essays on Software Technology

예시 코드에서 일급 컬랙션은 하나의 컬랙션을 클래스로 감싸는 것을 통해 구현될 수 있습니다. 이렇게 일급 컬렉션을 사용하는 것은 몇 가지 장점이 있습니다.

  1. 데이터 구조가 비즈니스 서비스 로직에 종속된다.
  2. 컬렉션의 불변성을 보장한다.
  3. 상태와 액션을 동시에 관리한다.

데이터 구조가 비즈니스 로직에 종속된다.

예제를 통해 한 번 살펴보도록 합시다. 이번 예제에서 LottoService 클래스는 로또 숫자가 필요한 모든 곳에서 다음과 같은 검증 로직을 필요로 한다는 문제를 가지고 있습니다. 이로 인해 검증 메소드들의 중복 호출이 이루어질 수 있고 만약 여러분의 동료가 관련 코드의 히스토리를 모른다면 에러가 발생할 수도 있습니다. LottoTicket이라는 일급 컬렉션을 두고 관련 메소드를 클래스 안에 포함시킨다면 우리는 이러한 문제를 손쉽게 해결할 수 있습니다.

컬렉션의 불변성을 보장한다.

컬렉션을 한 클래스의 변수로 만드는 것은 컬렉션 내부의 값들이 변하지 않게 만들 수 있습니다. 분명 누군가는 final 키워드를 통해 똑같이 해결할 수 있다고 말합니다. 음, 그러나 이건 반은 맞고 반은 틀립니다. 왜냐하면 final 변수는 오직 한 번만 인스턴스로 만들어지는데, 그렇다고 해서 컬렉션 변수의 경우 그 값을 만들어지는 시점에 모두 넣어야 하는 것은 아니기 때문입니다. 실제로, 일단 생성되면 값은 언제든 넣을 수 있습니다.

반대로, 일급 객체는 여러분의 필요에 따라 커스터마이징될 수 있습니다. 위 예제 코드는 Order 클래스가 생성된 이후 추가적으로 값을 넣는 것을 방지하는 코드입니다. 이렇게 하면 컬렉션 내부에 저장된 값들이 추가되거나 변경되는 일은 절대로 일어나지 않습니다. 이는 관련 사이드 이팩트들을 최소화시켜 줍니다.

상태와 액션을 동시에 관리한다.

상태와 액션을 동시에 관리한다는 말은 한 클래스 내에 관련 코드를 모두 집어넣는 것을 의미합니다. 왜 이것이 필요할까요? 우선, 컬렉션 변수를 초기화하는 코드와 이를 활용해 비즈니스 로직을 구현하는 코드가 완전히 분리되어있다고 상상해봅시다.

이는 몇 가지 실수를 유발할 수 있습니다. 만약 여러분 또는 다음 프로그래머가 와서 히스토리를 모른 채 관련 기능을 참조해 다른 UI에서 만들어야 한다면, 위 예제에서 totalSum 로직은 그대로 복붙될 가능성이 높습니다. 결국 중복된 코드가 만들어지고, 이러한 일이 반복된다면 코드의 유지보수가 어려워집니다. 하지만 이를 일급 컬렉션으로 만들어 getTotalSum() 을 구현한다면, 차후 새로운 코드는 해당 클래스의 메소드를 사용하기만 하면 되므로 이러한 문제가 생기지 않습니다. 이를 통해 여러분은 상태와 액션을 동시에 관리할 수 있게 됩니다.

Conclusion

‘일급(first-class)’ 라는 이름은 실제 사회에서 기득권층과 일반 대중들을 차별하는 용어로 사용되어왔습니다. 그래서 사회과학도의 시각에서 이러한 개념이 남아있다는 것이 놀라웠고, 또 이것이 우리 사회와는 전혀 다르게 사용되고, 더 나아가 어플리케이션 개발과 유지보수를 위해 장려될 필요가 있다는 점이 흥미로웠습니다.

그러나 한 가지 기술할 점은, 일급 컬렉션을 사용하는 것은 다소 논쟁의 여지가 있습니다. 왜냐하면 관련하여 영문 자료를 거의 찾을 수 없었고, 대부분 한국 개발자의 블로그 글에 의존해있기 때문입니다. 만약 여러분이 추가적으로 알고 있는 내용이 있으면 언제든지 알려주시기 바랍니다. 이 글을 읽어주셔서 감사합니다.

--

--