디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

제네릭 프로그래밍에 대한 단상

ㅆㅇㅆ(124.216) 2025.02.11 08:32:50
조회 880 추천 11 댓글 15
														




3db2d377abc236a14e81d2b628f1716f840977

제네릭 프로그래밍(Generic Programming)은 구체적인 효율적인 알고리즘에서 추상화를 수행하여 제네릭 알고리즘을 도출하고,

이를 다양한 데이터 표현과 결합하여 유용한 소프트웨어를 생성하는 아이디어를 중심으로 한다.

예를 들어, 유한한 시퀀스(finite sequences)에서 동작하는 **제네릭 정렬 알고리즘(generic sorting algorithms)**을 정의할 수 있으며,

이를 배열(arrays)이나 연결 리스트(linked lists)와 같은 서로 다른 데이터 구조에 적용하여 다양한 정렬 알고리즘을 생성할 수 있다.


논문에서는 데이터(data), 알고리즘적(algorithmic), 구조적(structural), 표현적(representational) 추상화의 네 가지 유형을 다루고 있으며,

이를 활용하여 Ada 라이브러리에서 소프트웨어 컴포넌트를 구축하는 예제를 소개한다.


주요 논점은 제네릭 알고리즘과 그 형식적 명세(formal specification) 및 검증(verification) 방법이며, 이를 퀵소트(quicksort) 알고리즘에서

사용되는 **분할 알고리즘(partitioning algorithm)**을 예로 들어 설명한다.


논문의 결론은, 제네릭 프로그래밍을 이용한 소프트웨어 컴포넌트 라이브러리가 소프트웨어 생산성 향상에 중요한 이점을 제공할 수 있다는 점을 강조한다.

Alexander A.Stepanov 1988



제네릭 프로그래밍이란 무엇인가?


제네릭 프로그래밍이란 하나의 데이터가 특정 데이터 타입에만 종속되지 않고, 여러 데이터 타입을 가질 수 있는 기술에 중점을 두어

재사용성을 높일 수 있는 프로그램 방식이라고 요약할 수 있다.


그럼 우선 우리가 시작해야할 지점은 무엇인가? 그 부분을 찾아보자.


우리는 왜 제네릭 프로그래밍이 나왔는가에 대해서 시작할 것이다.


3db2d372abc236a14e81d2b628f170698f1a81




제네릭 프로그래밍의 시작은 1980년대 OOP의 부상속에서 차별화에서 시작했다.


1980년대 초 OOP는 '객체', '클래스'를 중심으로 프로그래밍의 대세를 차지하기 시작했다.


하지만 이러한 접근 방식에는 한계가 엄연히 존재했다.


1. 타입에 종속적인 코드: 특정 데이터 타입에만 작동하는 클래스를 작성한다.

예를들어 정수 배열을 정렬하는 함수와, 문자열 배열을 정렬하는 함수는 같은 알고리즘을 공유함에도 불구하고 별개로 작성해야만 한다


2. 재사용성의 제한: OOP는 상속과 다형성을 통해 일부 문제를 해결할 수 있었지만 여전히 코드의 재사용성에는 제약이 있었다.


제네릭 프로그래밍은 이러한 문제를 극복하기 위해 등장했다.


위에 논문의 서문에도 나왔듯


다양한 데이터 표현 방식과 결합할 수 있는 일반적 알고리즘을 얻는데 집중할 수 있다.


제네릭 프로그래밍의 특징은 많지만, 현대의 제네릭 프로그래밍은 다음 3가지를 가진다.


1. 타입 독립성(Type Independence): 특정 데이터 타입에 종속되지 않음


2. 코드 재사용성(Code Reusability) : 동일 알고리즘이 다른 타입에도 적용될 수 있음


3. 효율성(Efficiency) : 런타임 오버헤드 없이 컴파일 타입에 최적화된 코드를 생성한다.



3db2d375abc236a14e81d2b628f17069cd854c


STL은, 적어도 나에게 있어서, 프로그래밍이 가능하게 하는 유일한 길을 의미합니다. 사실 STL은 대부분의 교과서에서 제시되었고 

여전히 제시되고 있는 C++ 프로그래밍과는 꽤 다릅니다. 하지만 아시다시피, 저는 C++로 프로그래밍하려고 했던 것이 아니라, 

소프트웨어를 다루는 올바른 방법을 찾으려고 노력했습니다. 저는 오랫동안 제가 말하고 싶은 것을 표현할 수 있는 언어를 찾아왔습니다. 

다시 말해서, 저는 제가 무엇을 말하고 싶은지 알고 있습니다. 저는 C++로 말할 수 있고, Ada로 말할 수 있으며, Scheme으로도 말할 수 있습니다. 

저는 언어에 저 자신을 맞춥니다. 하지만 제가 말하려는 것의 본질은 언어에 구애받지 않습니다. 

지금까지, C++는 제가 말하고 싶은 것을 말하기에 제가 발견한 최고의 언어입니다. 이상적인 매개체는 아니지만, 

저는 다른 어떤 언어보다 C++에서 더 많은 것을 할 수 있습니다. 

사실 언젠가 제네릭 프로그래밍을 염두에 두고 특별히 설계된 언어가 나오기를 저는 진심으로 바랍니다.

-Alexander A.Stepanov


제네릭 프로그래밍은 1970년대 후반부터 연구하다가, Ada에서 시작해 Scheme을 거쳐 C++에 정착하여 


알렉산더 스테파노프는 C++에서


알고리즘은 데이터 구조에 독립적이어야한다는 철학을 실현할 라이브러리 STL을 만든다.


사실 C++의 시작이 C에서 OOP를 적용하기 위해서 시작된 것이라는 걸 생각하면 조금 블랙코미디처럼 느껴지기도 한다.


OOP의 핵심 개념의 캡슐화는 데이터와 행위의 결합인데, STL은 그 행위와 데이터를 분리하는데 힘을 쓰기때문에,


마치 OOP를 위해 태어난 언어에서 OOP와는 다른 철학을 구현하는 핵심 라이브러리가 탄생했다는 것은 참 재밌는 것이다.

(물론 생각에 따라 정반대의 철학은 아니기때문에 충분히 나올 수 있는 개념이긴했다)


실제로 제네릭 프로그래밍이 OOP에 대항해서 나왔다는 사실은 이후에


C++ 표준 템플릿 라이브러리(STL)의 창시자인 알렉산더 스테파노프가 말한다



3db2d374abc236a14e81d2b628f17668e91579

네, STL은 객체 지향적이지 않습니다. 저는 객체 지향성이라는 것이 거의 인공 지능만큼이나 사기라고 생각합니다.

저는 이 OOP를 하는 사람들로부터 흥미로운 코드 조각을 아직 보지 못했습니다. 어떤 면에서는, 제가 AI에게 불공평하긴 합니다.

저는 MIT AI 연구소 사람들로부터 많은 것을 배웠고, 그들은 정말 근본적인 작업을 해냈습니다.

빌 고스퍼의 Hakmem은 프로그래머가 읽어야 할 최고의 것들 중 하나입니다. AI는 진지한 기반이 없을 수도 있지만,

고스퍼와 스톨먼(Emacs), 모세스(Macsyma), 그리고 서스만(가이 스틸과 함께 Scheme)을 만들어냈습니다.

저는 OOP가 기술적으로 건전하지 않다고 생각합니다. OOP는 단일 유형에서만 달라지는 인터페이스의 관점에서 세상을 분해하려고 시도합니다.

실제 문제를 다루려면 여러 유형에 걸쳐있는 인터페이스 패밀리인 다중 정렬 대수가 필요합니다.

저는 OOP가 철학적으로 건전하지 않다고 생각합니다. OOP는 모든 것이 객체라고 주장합니다.

그것이 사실이라 할지라도 그다지 흥미롭지 않습니다. 모든 것이 객체라고 말하는 것은 아무것도 말하지 않는 것과 같습니다.

저는 OOP가 방법론적으로 잘못되었다고 생각합니다. OOP는 클래스로 시작합니다.

마치 수학자들이 공리부터 시작하는 것과 같습니다. 당신은 공리부터 시작하지 않습니다.

당신은 증명부터 시작합니다. 관련 증명들을 많이 발견했을 때만 공리를 떠올릴 수 있습니다. 당신은 공리로 끝을 맺습니다.

프로그래밍에서도 마찬가지입니다. 흥미로운 알고리즘부터 시작해야 합니다.

알고리즘을 잘 이해했을 때만 알고리즘이 작동하도록 하는 인터페이스를 떠올릴 수 있습니다.

-Alexander A.Stepanov


알렉산더는 OOP를 기술적으로나 철학적으로 극렬하게 비판하는데, 사실 현대 언어들의 OOP 개념을 보면 어느정도 이해가 가는 맥락이다.


왜냐하면 C#과 자바등 현대의 언어들은 모든것을 'object'를 상속받는 식으로 설계되어있기때문에, 생성하는 모든것을 Object(객체)라는 관점에서 보기때문이다.


이렇게 되면 객체의 경계가 모호해지기때문에, 이론상의 OOP와 현실적 구현의 간극이 엄연히 존재하게 되는 것이다.


사실 스테파노프의 OOP 비판은 상속Inheritance 에 국한되어있던 90년대 초반의 OOP에 가깝다. 실제로 OOP는 그 초기에 모습에 변화가 되기도했고


최근에는 명확한 is-a 관계가 아니면 상속을 가급적 쓰지 않기를 권장하는 부분도 있다.


이 글을 보고 그럼 OOP가 무조건 나쁜 것인가? 라고 볼 사람떄문에 부연설명하자면


스테파노프의 OOP의 '타입' 문제에 초점을 맞추지만, 실제로 OOP 프로그래밍은 일반적으로 '관계'에 초점을 두기때문에


뛰어난 프로그래머의 자신의 학문에 대한 자부심으로 인해서 조금 다른 철학을 깍아 내리는 것이 아닐까하는 것도 사실이다.


이제 역사를 알았으니, 이제 어떻게 사용하는지 한번 보자.


현대에서의 제네릭 프로그래밍



3db2d373abc236a14e81d2b628f1726be87f2f

제네릭을 구분 짓는데 여러가지가 있다.


기본적으로 여러방식이 나뉘지만 일반적으로 자주 사용되는 분류법으로 어떻게 분리되어있는지만 이야기해보자.



정적 제네릭 vs 동적 제네릭



3db2d370abc236a14e81d2b628f17c6e90ef

(C++로 작성된 제네릭)


C++ 템플릿, Rust, Swift가 가지고 적용하는 방식으로


컴파일 타임에 타입이 결정된다.


코드가 인스턴스화될때(사용 되어질때) 타입이 결정되어지므로, 오버헤드 없이 최적화된 코드가 생성된다.(인스턴스화 시점 명확한 타입이 결정된다)


타입을 직접 지정하거나, 컴파일러가 타입을 추론하는 형식이다.


3db2d371abc236a14e81d2b628f1756de34cea

(Java로 작성된 제네릭)


Java,C# 제네릭이 가지고 있는 방식.


Jjav,C#의 제네릭은 내부적으로 런타임에 타입이 결정되지 않고, 타입정보를 삭제하는 type erasure를 사용한다.(타입 체크 후, 런타임시 타입삭제)


즉, 컴파일 타입에만 타입을 체크, 런타임에는 제네릭이 object나, system.object로 변환된다.


덕분에 같은 바이트 코드를 사용하여 런타임 오버헤드를 없애는 방식이다.


타입 매개변수 vs 컨셉 기반 제네릭



3db2d37eabc236a14e81d2b628f1706c4ffe

C++ 템플릿, Java제네릭,C# 제네릭이 사용하는 방식으로


T,K,V 같은 타입 매개변수를 사용하여 코드 재사용성을 높이는 방식이다.




3db2d37fabc236a14e81d2b628f17068a432

C++20 Concepts, Rust의 Trait Bounds, Swift의 Protocol Generics등이 사용하는 방식으로


제약조건을 추가하여 안정성을 높인 방식이다.


이후에 제네릭은 발전해서 


템플릿 메타 프로그래밍이 된다.


3db2d377b49c28a8699fe8b115ef046a56e69d

기존에 타입을 일반화하여 재사용 가능한 코드를 작성하는 프로그래밍 방식이 '제네릭 프로그래밍'이라면


템플릿 메타 프로그래밍은 컴파일 타임에 코드를 실행하고, 최적회된 결과를 생성하는 방식이다.


즉 제네릭 프로그래밍의 코드 실행시점이 런타임 이면, 템플릿 메타 프로그래밍의 코드 실행시점은 컴파일 타임이라고 할 수 있다.


핵심은 템플릿을 프로그래밍 언어 처럼 사용한다는 것이고, 템플릿 안에서 다양한 프로그램을 만들 수 있다.


즉 제네릭 프로그래밍에서 성능을 얻기 위해 만들어진 방식인 것이다.


제네릭은 잘 보면 마치 은탄환처럼 알고리즘을 추출하여 모든것에 적용하기 쉬운 것처럼 보인다.


하지만 이는 이론의 관점이지 실적용에서는 많은 비판을 받는다



3db2d377b69c32b6699fe8b115ef046c68b2c675


3db2d377b79c28a8699fe8b115ef0465a5ad4413

리누스가 앞장서서 STL을 비판했지만 너무 직설적이라서 번역은 하지 않겠다.


제네릭 프로그래밍은 장점만 보이는 것 같은데 단점은 없어?


3db2d377b69c28a8699fe8b115ef0469f61eed

예시 코드를 하나보자.


C++의 std::transform 함수는 입력범위[first,last]의 각 요소에 대해 단항 연산자(unary_op)를 적용하고, 결과를 출력한 후, 반복자(d_first)로 저장한다.


이 코드는 매우 간단한 코드지만, 문제가 생길때 오류 메시지를 길게 내뿜기 시작한다.


템플릿 코드에서 문제가 발생하면, 컴파일러는 추상화 계층까지 올라가 분석하고, 이 과정에서 복잡한 오류 메세지를 발생시켜 프로그래머로 하여금 실수를 찾기 힘들게 한다.


흔히 우리가 하는 프로그래밍 방식인 '레고 조립(래핑된 메서드 블록을 가져와 조립)'하는 방식은 실수가 눈에 금방 잡히지만, 템플릿 인스턴스화 실패는 정말 버그 잡기가 어렵다.


또한 자바 제네릭 방식인 Type Erasure 방식은


컴파일러가 체크하는 것처럼 보이지만, 런타임에는 타입 정보가 소거되어 예상치 못한 오류가 발생할 수도 있다. 

(C#은 런타임에도 제네릭 타임 정보가 유지된다 Reification - IL에서 구체적인 제네릭 타입이 보존되어 런타임에도 타입정보를 확인할 수 있기에 자바 제네릭의 문제다.) 


그리고 타입 매개변수 제네릭 프로그래밍은 가독성을 떨어뜨리기로 악명높고.


결국 


이론상으로는 우월하고 멋있어보이지만, 실무에서는 프로그래머에게 지옥을 선사한다고 할 수 있다.


제네릭 프로그래밍은 정말로 아름다운 프로그래밍을 가능하게 만들 수 있고,


이를 통해서 엄청난 소프트웨어 공학의 '부'를 축적할 수 있다.


하지만 잘못 사용하면 제네릭 프로그래밍 속에 숨겨진 추상화의 '빚'을 판단하지 못해, 프로그래밍이 지옥이 되는 대공황도 올 수 있다는 점을 알아야한다.


결국 이 모든 것을 감안해서 조절하는 것이 프로그래머의 실력인 것이다.






추천 비추천

11

고정닉 1

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 가수에서 배우로 전향 했지만 기대에 못 미치는 스타는? 운영자 25/02/24 - -
이슈 [디시人터뷰] 모델에서 배우로, 떠오르는 스타 이수현 운영자 25/02/21 - -
AD [베이비챗] 제약 없는 AI 채팅, 숨김없이 솔직하게 운영자 25/02/20 - -
2817554 찰리 푸스, '나치 찬양' 칸예에게 경고... 발명도둑잡기갤로그로 이동합니다. 02.11 52 0
2817553 전산실 연봉이 더 높다는 xx업는소리는 [4] 프갤러(115.23) 02.11 101 0
2817552 애널의 ✨영상 ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 68 0
2817551 와 gpt랑 에미나이 결제 해야되나.. 프갤러(49.165) 02.11 68 0
2817549 나님이 봤을때 M6 가 명작일듯 ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 45 0
2817548 나트륨은 초코냥을 애도합니다 ㅇㅅㅇ [6] 나트륨찡갤로그로 이동합니다. 02.11 90 0
2817546 Orange FM 게임보이 라디오 팩 발명도둑잡기갤로그로 이동합니다. 02.11 34 0
2817545 진짜 프로그램이 뭔지 알려줄게 드루와 FA자동화 오픈톡 프갤러(211.235) 02.11 39 0
2817542 대출 없는 강남 자가 보유자 송해나의 한 달 카드값 발명도둑잡기갤로그로 이동합니다. 02.11 58 0
2817540 업무 속도 조절 좀 해야지 후우... [3] AppHiki갤로그로 이동합니다. 02.11 71 0
2817539 “성병 싫어” 항의한 여친 폭행한 30대 男 발명도둑잡기갤로그로 이동합니다. 02.11 49 0
2817538 '2분짜리 은행 강도가 어디 있나'…윤 대통령 소환된 이유가 발명도둑잡기갤로그로 이동합니다. 02.11 108 0
2817536 진정한 개발자가되야한다 ㅠㅠ [6] 초코냥갤로그로 이동합니다. 02.11 133 0
2817534 [2] ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 50 0
2817533 화교분탕들과의 화장실갤 공방전 ㅇㅇ(39.7) 02.11 47 0
2817532 윤석열의 최후 [1] 발명도둑잡기갤로그로 이동합니다. 02.11 58 0
2817530 스마트폰백신 추천좀 갤갤갤(106.101) 02.11 41 0
2817526 ❤✨☀⭐나님 시작합니당⭐☀✨❤ [1] ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 42 0
2817525 화교분탕들의 대학축제 억까질 - 직캠 억까 종합(2차 썰재업) ㅇㅇ(175.223) 02.11 59 0
2817523 뉴프로 좋아요 2개시 화려한 이팩트 추가 헬마스터갤로그로 이동합니다. 02.11 39 0
2817521 왜곡 없는 진짜 땅 크기 발명도둑잡기갤로그로 이동합니다. 02.11 56 0
2817519 나도 말 적게 한 날엔 밤에 자기 전에 오늘 한 말 전부 복기가 [1] 발명도둑잡기갤로그로 이동합니다. 02.11 57 0
2817518 먼접 보고 왔는데 그린라이트임? [9] ㅇㅇ갤로그로 이동합니다. 02.11 114 1
2817517 젠투는 밤에 설치하고 자라 뒷통수한방(1.213) 02.11 61 0
2817516 파이썬 같은 기능 코드 길이 C++의 1/3 [1] 발명도둑잡기갤로그로 이동합니다. 02.11 77 0
2817515 종북내란선동사들 방심위의 철퇴에 언론정상화 박차 ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 43 0
2817514 노력하면 중간층은 갈수있을까?? [2] 뒷통수한방(1.213) 02.11 64 0
2817513 파이썬이 언어 병신이고, 성능 좆병신이고 이런걸로 까는건 이해되는데 [5] ㅆㅇㅆ(124.216) 02.11 121 1
2817512 wsl2 + 윈도우 세팅 암걸리노ㅋㅋㅋ [2] 프갤러(218.151) 02.11 59 0
2817511 막걸리 발명도둑잡기갤로그로 이동합니다. 02.11 43 0
2817510 리눅스 왜씀? [2] 프갤러(49.165) 02.11 80 0
2817509 파이썬은 왜 하는거냐? [7] 프갤러(59.16) 02.11 139 0
2817508 새벽출근 11시 퇴근 사무직도 정병생김 ㅋㅋㅋㅋ [1] 뒷통수한방(1.213) 02.11 59 0
2817507 흐린이 피티받았다 [3] hrin(118.235) 02.11 66 0
2817506 좆기도 씨발련들 존나 싫네 진짜 프갤러(211.193) 02.11 43 0
2817505 내란듀스101 [1] 발명도둑잡기갤로그로 이동합니다. 02.11 50 0
2817504 근데 진짜 오늘 말 한마디도 안하고 코딩만하니까 정신 이상 올거같더라 [6] ㅆㅇㅆ(124.216) 02.11 82 0
2817503 당신의 수괴에게 투표하세요! <내란듀스 101> 발명도둑잡기갤로그로 이동합니다. 02.11 42 0
2817502 극좌 인민재판관 탄핵 청원 5만권 돌파 심의 들어간다 ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 34 0
2817501 미래의 마누라(처녀) 내가 게임 열심히 만들어서 널 데리러 갈게... [9] ㅆㅇㅆ(124.216) 02.11 105 0
2817500 발정난 극좌 문괴뢰 불법음란물 공유 논란 이딴게 무슨 헌재재판관? ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 44 0
2817499 포기하면 한결편하다 [5] jonny갤로그로 이동합니다. 02.11 72 0
2817497 부모 뒤질때되면 존나 슬퍼해서 눈물 나냐?? 뒷통수한방(1.213) 02.11 57 0
2817496 23살은 책읽기엔 좀 늦은 나이인가?? ㅇㅇ(223.33) 02.11 41 0
2817495 벜클리 조쟈텍 CS 논문 성과들 죄다 오픈소스인데 프갤러(49.165) 02.11 65 0
2817493 독학으로 프로그래밍 가능하냐? [1] ㅇㅇ(116.43) 02.11 89 0
2817492 ❤✨☀⭐나님 시작합니당⭐☀✨❤ ♥멸공의냥덩♥갤로그로 이동합니다. 02.11 31 0
2817491 오픈소스가 착한애들이 아니면 간단함 소스보는데 결제로 바꾸면됌 [1] 뒷통수한방(1.213) 02.11 67 0
2817490 왜 이딴 인간들이 강제적으로 법이란것에 지배하는 뒷통수한방(1.213) 02.11 56 0
2817488 오픈소스나 대기업이나 똑같은데 오픈소스가 착한건맞지 [1] 뒷통수한방(1.213) 02.11 54 0
뉴스 2NE1 박봄, 이민호 열애설 해명에 “셀프 NO…이민호가 시켰다” [왓IS] 디시트렌드 02.23
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2