순수 객체 지향 프로그래밍 언어의 장단점은?

steve24l의 이미지

순수 객체 지향 언어로는

스몰토크와 루비밖에 없는것으로 알고 있는데요

일단 자바나 파이썬 C++등은

상수나 연산자 또는 for문등이

객체가 아니기 때문에

순수 객체 지향이 아니라고 하더군요

그러면

루비나 스몰토크처럼

연산자나 상수등 모든것이 객체일경우

장단점은 무엇인가요?

제가 알기로는 객체지향이라는게

프로그래밍 언어보다도

사람이 프로그램을 얼마나 객체지향적으로

디자인을 하느냐에 따라 좋고 안좋고가

나눠지는걸로 알고 있는데

예를 들어서

C++을 쓰더라도 정말 잘 쓰여진 객체 지향적 프로그램이 될 수도 있고

C++의 새로운 객체 지향 기능을 이용했을뿐

전체적으로 구조적 프로그래밍을 할 수도 있는거잖아요?

그렇다면

파이썬이나 자바,C++등 언어와

순수 객체 지향 언어인 스몰토크나 루비를 비교했을때

순수 객체 지향 언어의 장단점은 무엇인가요?

글쎄요의 이미지

수학적인 증명이 힘들겠지요.
Object에 대한 이론이 있기는 하지만 함수형 언어에서와 같은 완전함이 없기때문에, 어디서 에러가 나는지 확실하게 알려면 디버거와 노가다의 힘을 빌리는 수 밖에 없겠지요.

steve24l의 이미지

음...솔직히 이런 답변 말구
좀더 이해하기 쉽고 간단할줄 알았는데
어째 내용이 어려운것 같네요;
Object에 대한 이론이 있기는 하지만 함수형언어에서와 같은
완전함이 없기 때문이라고 하셨는데
함수형언어는 파이썬이나 C++등을 말씀하시는거지요?
그런 언어들이 Object에 대한 이론에 비해서
어떤점이 완전하다는 건가요??
그리고 구체적으로 어떤 예를 하나 보여주실 수 있을까요??
아직 실력이 부족해서 이해하기가 좀 힘드네요 ㅠㅜ

부탁드립니다^^

___의 이미지

함수형 언어란... ML, Haskell, LISP, Objective Caml 등등의 언어를 말합니다. 파이썬, C++ 은 본격적인 "함수형 언어"라 불리지는 않습니다. 함수형 언어에 대해서는...
http://en.wikipedia.org/wiki/Functional_language
를 참조해보시고, 웹에서 검색하시면 무수히 많은 자료가 쏟아져 나올겁니다.

ghost의 이미지

장점이 있다면 유연성 이라고 할 수 있겠죠

OOP자체가 가지는 선택의 폭이 넓고 수정이 용이하다는 것이 장점이 되겠고요.

단점이라면 유연성이 너무 커서 프로그래머가 조심해야 할게 많다는 것이 겠군요.

예를 들자면 smallalk같은 경우 실시간에 클래스를 수정할 수 있기 때문에

잘못하면 시스템 운영에 심각한 문제를 초래할 수도 있겠죠.

루비는 안 써봐서 잘 모르겠군요.

semmal의 이미지

이 두 종류는 거의 같은 패러다임으로 프로그래밍이 진행됩니다. 즉, 함수형 언어(Haskell이나 ML같은)나 논리형 언어(Prolog나 LambdaProlog같은)와는 큰 차이가 있지만, 이 두 종류는 거의 차이가 없다고 봐도 무방합니다.

Object-Oriented라는게 사실 특별한게 아니라, 이전에 쓰던 함수나 데이터, 모듈의 확장에 불과한 것이죠.

정확히 따지자면, 오브젝트라고 하는 개념은 OO이전에 있었고, 메시지패싱은 Object가 아니라도 쓸 수 있는 기법이라서, 역시 OO가 나오기 전부터 쓰던 기법이고, 데이터 추상이나 캡슐화라고 해봐야 모듈이나 데이터 선언에서 이미 해오던 것이고, 다형성 역시 dynamic typing언어에서는 말할필요조차도 없고, 뭐 질문과는 상관없지만 static typing이라고 하더라도 객체지향보다 오히려 함수형 언어에서 보여주는 것이 더 뛰어나죠. 클래스 상속이라는 것도 더 깊게 파고들어가면 "import 모듈"에 불과한 것이고, 델리게이션이라 해봐야 "Ctrl+C, Ctrl+V"하면 해결되는 것이고, 타입 상속은 static typing에서나 소용있는 것이고, 등등...

즉 이 두 종류는 "문법"이 다릅니다. 속에 들어있는 개념은 매우 비슷합니다. 즉 하나를 제대로 알고있다면, 다른 하나를 아는게 그리 어렵지 않은 것이죠. 심하게 말하자면, 순수객체지향언어니 뭐라고 해도 그냥 손으로 해야할 일을 조금 편하게 할 수 있게 문법을 재구성한것에 불과합니다.

정말 차이가 난다고 생각할 정도라면 역시 함수형 언어나 논리형 언어를 써보면, 무엇이 정말 "차이"인지 알게 될겁니다.

------------------------------
How many legs does a dog have?

prolinko의 이미지

사실 어떤 언어가 더 객체지향적이라는 것이 상대적인 개념이고 객관적인 척도도 없습니다. glib을 보면 C로도 OOP를 훌륭하게 사용하고 있으니까요. 다만 smaltalk 같은 언어는 언어의 많은 요소가 객체의 개념을 이용해서 설계되었을 뿐입니다.

OO라는 것도 문제의 모델링을 쉽게하고 코드의 추상화를 통해서 더욱 프로그래밍을 쉽게하기 위해서 절차적 언어에 제공된 방법론에 지나지 않습니다. 오히려 언어적인 측면에서 봤을 때 C++, Java 같은 언어의 static typing 과 python, ruby 같은 언어의 dynamic typing이 더욱 큰 차이점입니다.

보통 사람은 기존에 자신의 알고있는 범위를 크게 벗어나지 않는 범위 내에서만 사고를 할 수 있기 마련입니다. 프로그래머로서 획기적인 개념의 프래임워크나 라이브러리를 만났을 때 몇%정도 더 사고의 확장이 일어난다면 전혀다른 개념의 새로운 언어를 배웠을 때는 기존의 사고영역에 새로운 차원의 축이 하나더 생겨서 급격하게 사고공간이 늘어나는 것 같은 느낌을 받을 수 있습니다. 그래서 굳이 그 언어를 주 언어로 삼지 않더라도 프로그래밍 전반 많은 도움이 되기 때문에 프로그래머는 새로운 개념의 언어를 여러개 익혀보는 것이 좋습니다.

제가 알고 있는 언어의 범위 내에서는 보통 사용하고 있는 C, C++, Java 같은 언어 외에 python, ruby 같은 dynamic typed script 언어를 하나 익히고, 나아가서 전혀 다른 패러다임인 함수형언어와 논리형 언어도 하나씩 배워 보기를 추천해 드립니다.

비번생각않남의 이미지

너무나 맘에 드는 말입니다..^^

kwak101의 이미지

그런 의미에서(무슨 의미?) prolinko님 팀에서 루비 스터디나 한 번~

prolinko의 이미지

제 글을 보시다니부끄럽습니다. *-_-*

hum4의 이미지

객체지향이라는 것이 추상적인 개념이다 보니, 상대적이고 객관적인 척도가 없는건 사실이만..

더 잘 지원하는 언어(툴)이라는 관점에서 보면 분명한 차이가 있습니다.
C로 OOP를 훌륭하게 적용할 수 있다. 맞습니다. 못하는게 어디있겠습니까.
더 유연하게 잘.. 지원할 수 있느냐 없느냐의 차이일 것이고..
이 유연하게 잘 지원할 수 있느냐 없느냐의 차이는 C로 OOP를 구성해도 아무 문제가 없을 정도의 전문적인 프로그래머라면 상관 없겠지만..
일반적인 개발자의 입장에서는 C로 하느냐 C++로 하느냐 혹은 Java로 하느냐에 따라서 비용에 있어서 차이가 날 수 밖에 없습니다.

prolinko의 이미지

예, 맞는 말씀입니다. 프로그래밍 언어마다 생산성이 다른 것은 당연하지요. 저 같아도 glib같은 잘 만들어진 라이브러리 도움없이 C로 OOP프로그래밍하라 그러면 그냥 포기하고 structual programming으로 때울 겁니다. 그리고 OOP를 언어적으로 많이 지원하고 강제하는 언어일 수록 초보자가 언어를 사용하면서 OO에 빨리 익숙해 지지는 것도 사실이고요.

하지만 제가 말하고 싶은 것은 언어의 생산성의 문제가 아니라 OO말고도 언어가 제공할 수 있는 paradigm은 많고 이것은 생산성에 도움을 줄뿐만 아니라 프로그래머에게 새로운 insight를 준다는 것입니다.

OO라는 것은 프로그래밍 모델링 방법의 하나이고 이것을 언어적인 차원에서 지원하는 것은 프로그래밍 언어의 한부분을 차지하는 작은 요소일 뿐인데, 마치 언어 설계시 OO을 어떻게 지원해야할 것인가가 언어 설계 최종목표이고(물론 OO의 선구자격인 smaltalk는 그랬을 수도 있죠) OO를 얼만큼 유연하게 지원하는냐가 곳 언어의 좋고/나쁨을 판단하는 기준이 되는 듯한 편협한 사고에 메어있는 사람들이 많은 것 같습니다.

실제로 OO의 개념에 기반해서 클래스 별로 기능을 나누고 멤버와 메써드를 정의한 설계를 Java, C++, python, ruby등의 언어로 각각 구현을 해보면 연산자의 모양 같은 사소한 문법차이 정도만 달라지뿐 하나의 언어로 작성된 것을 쉽게 line-by-line으로다른 언어로 옮길 수 있습니다. 이런 식으로 기초적인 OO의 개념만 가진 체 OO에만 집착해서 언어를 바라보고 새로운 언어를 익히게 되면 실제적으로 그 새로운 언어가 제공하고 있는 다른 강력한 패러다임이나 기능을 적절하게 활용하지 못할 수 있습니다.

예를 들자면 C++, Java, C#등에서 지원하는 generic 프로그래밍 기능이나python, ruby같은 언어의 dynamic typing등을 적절하게 사용하면 단순한 OO적인 개념만 가지고는 생각할 수 없었던 혁신적인 설계와 구현이 가능합니다. 이런 여러가지 패러다임 들은 순수한 OO의 개념과 상충되는 부분도 있고 상호 보완적인 부분도 있죠.

더 나아가서 절차적 언어를 벗어나서 함수형 언어나, 논리형 언어를 사용해 보면 이런 논의 조차도 벗어나서 전혀 새로운 차원에서 문제해결에 접근하는 것을 경험해 볼 수 있습니다. 절차적 언어만 알던 시절에 집착했던 많은 문제들이 "왜 이런걸 가지고 고민을 하면서 인생 낭비를 했나" 하고 무의미하게 느껴지기도 하면서, 문제해결 과정에 필요한 안목을 넓혀 줍니다.

steve24l의 이미지

솔직히 모든분들의 말씀을 전부는 이해하지 못했지만
결론적으로 루비나 스몰토크가 단지
객체 지향적인 프로그래밍을 조금 더
쉽게 해줄 수 있을뿐이고(반강제적으로)
OOP라는것 자체가 어차피 프로그램을 설계하는 방법론에 지나지 않으니
객체 지향 프로그래밍 내에서
루비니 파이썬이니 하는것보다는
OOP,함수형언어,논리형언어
이런식으로 전혀 다른 패러다임의 언어들을
배워보면서 사고의 폭을 넓혀가는것이 좋다...
뭐 이런 말씀이시죠???

semmal의 이미지

요즘에 나오는 인기있는 언어는 OO패러다임, 함수형 패러다임정도는 쓸 수 있게 해줍니다. OO가 데이터 중심으로 설계를 해 나간다면, 함수형은 연산(함수) 중심으로 설계가 진행됩니다.
그나마 OO와 함수형은 "문제를 푸는" 방식으로 프로그래밍하지만, 논리형은 "문제를 증명하는" 방식으로 프로그래밍을 하기 때문에 소위 인기있는 언어중에서 논리형 패러다임이 첨가된 언어는 극히 드물지요.
어쨌든 OO와 함수형 패러다임을 같이 지원한다는건 중요한 것인데, OO만 지원하고 함수형 패러다임을 지원하지 않는 언어는 연산에 중점을 둬야하는 문제를 풀어야 하는 상황이 오면 복잡한 꼼수를 써야 해결이 가능합니다. 보통 말하는 "디자인 패턴"이 대부분 이런 경우입니다.
함수형 패러다임도 마찬가지인데 OO가 지원하지 않으면(실제로는 알맞은 이론이 정립되지 않았기때문에 지원하지 않는 경우가 대부분이죠.) 고급의 데이터 추상을 쓰기가 힘듭니다. 즉, 원래의 소스를 고치지 않고 코드를 추가하는게 어렵게 됩니다.
ruby가 세계적으로 각광받는 이유는 순수한 OO라서가 아니라, OO와 함께 함수형 패러다임을 그나마 그럭저럭 지원하는 편이기 때문이라 생각합니다.

------------------------------
How many legs does a dog have?

yuni의 이미지

고급의 데이터 추상,

예전에도 OO에 관한 이야기가 올라왔을때, 언어의 추상화란 용어를 이해를 못하겠더군요.
여기서의 추상은 abstration을 이야기하는 것인가요? 그렇다면 data의 abstration은 무슨 의미 인지 여쭈어 봐도 되겠습니까? 알려 주시면 감사 하겠습니다.

-----------------------------------------------------------------------

안녕하세요? 인간이 덜 영글어서 실수가 많습니다. :-)
=====================
"지금하는 일을 꼭 완수하자."

==========================
부양가족은 많은데, 시절은 왜 이리 꿀꿀할까요?
=====================
"지금하는 일을 꼭 완수하자."

semmal의 이미지

복잡한 걸 간단하게 만드는 기법입니다.
원래 오래전부터 수학에서 써오던 개념을 그저 프로그래밍으로 옮겨놓았다고 생각하시면 됩니다.
프로시저 추상이라는 말이 있는데 이것은 프로그램이 여러 단계(또는 과정;프로세스)를 마치 하나의 프로세스 인냥 만들어서 그 복잡함을 감추는 것이라 생각하면 되겠습니다.
데이터 추상 역시 마찬가지입니다. 복잡한 데이터가 있다고 하더라도 마치 하나의 데이터인 것처럼 다룰 수 있다면 데이터 추상이 되었다고 보면 됩니다.
예를 들어서, 우리가 푸리에변환 같은 프로그램을 짠다고 생각하면 이것은 크게 몇 단계의 추상으로 이루어짐을 알 수 있습니다.
일단 임의의 Real(실수) 형을 표현할 수 있는 모듈이 있다고 칩시다. - 첫번째 추상 단계 입니다. 물론 안으로 들어가면 더 많은 추상이 있을 수 있습니다. 이런 각 모듈은 모두 아시다시피 프로시저와 데이터로 구성이되고, 각 프로시저와 데이터는 어떤 복잡한 것을 표현하는 하나의 추상이 될 수 있습니다.
두 Real 형을 묶은 Complex 형을 표현하는 모듈을 만듭니다. - 두번째 추상 단계입니다. 이 단계에서 Complex를 쓰는 사람은 Real의 속이 어떻게 생겼는지 알 필요 없습니다. 즉, 이런 과정이 프로그래밍을 단순하게 만들어줍니다.
Complex형 끼리 서로 연산하는(사칙연산 등의) 모듈을 만듭니다. - 세번째 추상 단계입니다. 일부 OO언어의 예제에서는 두번째와 세번째 단계가 서로 섞여있는 경우가 있는데 원래 이 두 가지는 엄연히 구분되어야 합니다. 물론 구현상의 이유(속도 등의)로 합치는 것은 몰라도 당연한듯 섞는 것은 문제가 있는 것이지요.
Complex 연산을 할 수 있는 모듈을 가져와서 퓨리에변환하는 모듈을 만듭니다. - 네번째 추상 단계입니다. 물론 세번째와 네번째 사이에도 더 많은 추상 단계가 있을 수 있습니다.
(참고로, 이런 추상 단계는 영어로는 abstraction barrier라고 부릅니다.)
우리가 마침내 퓨리에변환을 하기 위해서 Complex에 관련된 연산을 쓴다고 하면, 우리는 Real이 어떻게 구현이 되어있는지, Complex가 어떻게 구현되어있는지, Complex의 연산이 어떻게 구현되어있는지 신경쓸 필요가 없습니다. 이런 구현을 신경쓸 필요가 없다는 것은 지금 당장 우리가 집중해야 하는 문제의 영역이 크게 줄어든다는 말이고, 프로그래밍이 쉬워진다는 말입니다.
고급의 추상이라고 하면, 이런 추상 단계가 충분히 많아서 우리가 쓰는데 그 구현을 전혀 신경쓰지 않고도, 맘대로 프로그래밍 할 수 있는 수준이라고 말할 수 있습니다. 우리가 차를 달리게 만드는데는 엑셀을 밟고, 핸들을 돌리는 것(간단한 인터페이스)만 알면되지, 엑셀을 밟았을때 어디가 어디로 연결(복잡한 연관관계)이 되는지, 핸들을 돌리면 뭐가 어떻게 동작하는지(복잡한 구현)는 알필요 없는 것이지요.
덧붙여, 윗 글에서 밝힌 "고급의 데이터 추상"은 원래의 소스를 고치지 않고, 기능을 추가하는 그런 기법을 말씀한 것입니다. OO에서 말하는 상속이나 델리게이션이 이런 기법을 쓰기 위한 방법입니다. 이것 역시 이전의 구현이 어떻게 만들어졌는지 신경쓰지 않고, 지금 필요한 데이터를 만드는 것을 의미하는 추상이지요.

------------------------------
How many legs does a dog have?

pok의 이미지

파이썬에서 제일 어려운게 리스트라고 생각했습니다. 왜냐면 리스트를 단지 고급 "자료형"으로만 인식했것든요. 그런데 최근 프롤로그라는 언어를 조금 알게되면서 술어와 리스트, 관계를 알게되었는데, 앗차! 싶었습니다.(응?)

그렇다고 아직 잘 아는것은 아니고 앗차 싶을뿐인데, 왜냐하면, 함수형언어나 술어형언어의 패러다임을 이해하지 못하겠거든요. 쉽게 말해, 그게 어디에 쓸모가 있는지 뇌가 닫혀 있어서 잘 받아들여지지 않네요.

특히나 술어형인경우, 그냥 오토마타를 구현하면 될수 있을것 같거든요. 게다가 현재의 언어가 non-deterministic한것까지 처리해줄만큼 강력하지도 못하고 술어와 리스트와의 관계라는것 자체가 명제함수적으로 처리가 가능하니까 현재의 언어패러다임으로 "라이브러리"로 구축하는게 낫다고 생각하거든요.

그래서 함수형언어나 술어형 언어가 기가막히게 쓰인곳이나, 혹은 잘 쓰일만한 곳을 알고 싶습니다.

semmal의 이미지

함수형 패러다임은 OO패러다임이나 명령형 패러다임과 문제에 접근하는 방법이 틀릴뿐이지 그 외의 대부분은 유사합니다.
단지 람다를 이용한 "증명가능한" 코드를 작성하려할 뿐입니다. 여기서 "증명가능한"이라는 말은 컴파일이 된다면 반드시 동작한다는 말입니다.
OO나 명령형 패러다임의 문제점은 assignment(=연산)를 쓰기때문에 상태가 "알 수 없게" 변한다는 겁니다. 즉, 어느 시점에서 어떤 변수가 어떤 값을 들고 있을지는 일일이 따라가보지 않으면 알 수 없다는 것이지요. 즉, 디버거가 필요한겁니다.
함수형 패러다임은 어느 시점에 어떤 변수가 어떤 값을 들고 있는지 반드시 확인할 수 있습니다. 디버거가 없이도 디버깅이 가능합니다.
하지만 순수한 함수형 패러다임은 상태를 바꿀 수 있는 손쉬운(?) assignment를 포기했기때문에, 그 아래에 있는 시스템콜을 쓰기가 불편합니다. 시스템콜은 대부분 assignment를 써서 구현되어있고, 즉 시스템을 상태로 보고 프로그래밍 해왔기 때문에 함수형 패러다임에 적합한(스트리밍같은) 상태바꾸기는 힘듭니다.
그래도 사람들이 가장 많이 쓰는 함수형 언어인 ML(또는 CaML, OCaML)이나 Lisp(또는 Scheme)같은 언어는 assignment를 쓸 수 있게 만들어져있기때문에 큰 불편함은 없을 정도입니다. 물론 assignment를 쓴 부분을 디버깅하려면 반드시 적당한 디버거가 필요합니다.
함수형 패러다임 언어로 성공한 프로젝트는 이미 너무 많습니다. 가깝게는 야후 쇼핑도 중요한 부분은 모두 Lisp으로 만들어졌습니다. 폴 그래험이 야후 쇼핑의 개발과정에서 밝혔듯 상태가 없이 코딩한다는 것은 아주 큰 장점입니다.
말씀하신 술어형, 제가말하는 논리형 패러다임 언어의 경우에는 보통 연구용으로 많이 쓰입니다. 보통은 공학쪽 연구라기보다는 수학쪽 연구라고 보는게 맞겠지요. 말씀하신 프롤로그의 경우에는 고전적인 논리(classical logic;정확하게 한분야는 아닙니다.)을 기초로 하고 있기때문에 약간 부족합니다만, 요즘의 논리형 패러다임은 선형 논리(linear logic)이라 불리는 영역까지 확장되어 있습니다. 간단한 오토마타는 코드 몇 줄이면 표현할 수 있습니다. 이 선형 논리는 고전 논리와 달리 상태까지 표현할 수 있기때문에 대단한 잠재력을 가지고 있다고 볼 수 있습니다.
어쨌든 논리형 패러다임의 경우에 해당 언어를 직접 쓰는 경우는 드물지만 패러다임은 이미 널리 쓰이고 있습니다. NP문제가 아닌 다음에야 논리형 패러다임은 가장 간단하면서 확실한 해결책을 제시해줍니다.
하지만 pok님이 말씀하신 "특히나 술어형인경우, 그냥 오토마타를 구현하면 될수 있을것 같거든요. 게다가 현재의 언어가 non-deterministic한것까지 처리해줄만큼 강력하지도 못하고 술어와 리스트와의 관계라는것 자체가 명제함수적으로 처리가 가능하니까 현재의 언어패러다임으로 "라이브러리"로 구축하는게 낫다고 생각하거든요."에 대한 제 생각은 부정적입니다.
현재 논리형 패러다임을 쓸 수 있는 라이브러리는 이미 몇가지가 나와있습니다. 하지만 논리형 패러다임은 단지 어떤 알고리즘만을 의미하는 것이 아닙니다. 다른 언어에서는 패턴매칭이나 리스트같은 구조를 적절하게 나타내지 못합니다. 결국 C++같은 언어에서 그런 라이브러리를 쓴다고 하더라도 프롤로그에서 보이는 그런 간결한 모양이 절대 나오지 않습니다.
Leda같은 언어는 기존의 언어형태에 논리형 패러다임을 어떻게 섞어쓸 수 있는지를 약간 보여주고 있지만, 만족할만한 수준은 아닙니다. 빨리 프로그래밍 언어 연구가 발전해서, 그리고 그것을 바탕으로 논리형 패러다임까지 포괄하는 더 좋은 언어가 나오기를 바랄뿐입니다.
-추가 자료
The Forte Formal Verification System (실제로 인텔에서 마이크로프로세서의 오류를 찾기 위해 만든 함수형 언어) : http://web.comlab.ox.ac.uk/oucl/work/tom.melham/res/forte.html
Logic Programming in C++ (C++에서 로직프로그래밍) : http://www-static.cc.gatech.edu/~yannis/lc++/
지금 바빠서 찾아서 나중에 더 올리께요.

------------------------------
How many legs does a dog have?

pok의 이미지

하.. 역시 이바닥은 놀면놀수록 빠져드는군요.
제가 어렴풋이 알고있던 패러다임을 지적해주셔서 감사드립니다.

염치불구하고 질문하나 더 할께요.
상태없이 프로그래밍이 가능하나요? 폰노이만 컴퓨터식 사고방식으로는 이해가 안가는 부분입니다. 특히 제가 C에서 C++로 넘어가면서 가장 흥분했던 부분이 수행에 필요한 변수(상태)를 객체라는것으로 묶은 부분이었거든요. 특히 함수포인터를 이용한 콜백에서는 그에 상응하는 상태(변수)를 콜백 이전에 정의해두고 그의 상태변화를 주시해야했지만, 객체 functor를 이용한 호출에서는 functor에서 상태를 관리해서 무척 편리했습니다. 만일 함수형 언어가 C에서의 함수호출같은 것이라면 역시 따로 상태를 관리해주어야 하니까 C에서의 불편함을 답습하는 것일꺼 같고 C++에서의 functor같은 것이라면 상태없는 프로그래밍이라는 것은 옳은 해석같지 않거든요. 혹은 이 둘과 다른 무엇이라면 힌트좀 주셨으면 합니다.

그리고 함수형이나 논리형 언어의 패러다임에 대해 좀더 공부해 보고 싶은데 추천해줄 사이트나 교제 있나요? 정밀한 증명식 접근보다는 개념적 접근이었으면 더 좋겠습니다.

notpig의 이미지

http://ropas.snu.ac.kr/n/
http://ropas.snu.ac.kr/~kwang/

함수형 언어 공부하신다면 꼭 가봐야할 곳중에 한곳입니다.

semmal의 이미지

상태없는 프로그래밍이란 그렇게 어려운 것이 아닙니다.

haskell에서는 스택을 아래처럼 표현할 수 있습니다.

type Stack a = [a] -- Stack은 a(임의의) 타입의 리스트로 구현된다.

stack :: Stack a -- stack은 빈스택을 만든다.
stack = []

push :: Stack a -> a -> Stack a -- push는 스택과 원소 e를 받아서 그 원소를 스택에 넣는다.
push s e = e:s

pop :: Stack a -> Stack a -- pop은 스택의 맨 윗부분에 있는 원소를 빼버린다.
pop (_:s) = s

top :: Stack a -> a -- top은 스택의 맨 위에 있는 원소를 돌려준다.
top (e:_) = e

size :: Stack a -> Integer -- size는 현재 스택의 크기를 알려준다.
size s =
let size' [] c = c
size' (e:s) c = size' s (c+1)
in size' s 0 -- tail recursion

isElem :: Eq a => Stack a -> a -> Bool -- stack에 원소 e가 있는지 확인한다.
isElem [] e = False
isElem s e = if (top s) == e then True
else isElem (pop s) e

-- Util

mpush :: Stack a -> [a] -> Stack a -- stack에 여러 원소를 차례대로 집어넣는다.
mpush s es = foldl push s es

테스트해보면
> mpush stack [1,2,3,4,5,6] => [6,5,4,3,2,1]
> size ((pop.pop.pop) (mpush stack [1,2,3,4,5,6,7])) => 4

이런 식으로 하면 대부분의 프로그램에서는 함수의 인자로 사용되는 변수 이외에는 필요치 않지요.
즉, 모든 함수가 상태라고 불릴만한 오브젝트를 들고다니면서 바꾸면 됩니다.
그리고 모든 오브젝트는 상수이기때문에 그 자체를 바꾸는 것은 허용되지 않습니다.
즉 맨 처음에 정의한 stack이라는 이름은 프로그램이 끝날때까지 빈스택을 의미합니다.
이런 상태없는 프로그래밍에서의 연산은 데이터를 "바꾸는" 것이 아니라, "이어붙이는" 것이라고 생각하시면 됩니다.
모든 오브젝트는 바뀌지 않기때문에, 이름과 값과 주소는 항상 동일한 오브젝트를 가리킨다는 것을 알 수 있습니다.
즉, C++이나 Java에서 일어나는 "같은 이름을 가진 변수가 실제로는 서로 다른 오브젝트"인 경우는 없습니다.

그리고 함수형 패러다임에서 함수는 call된다기 보다는 substitution된다고 보는게 맞습니다.
함수형 패러다임에서 작성된 프로그램은 결국 단 하나의 함수와 그 함수안의 식만 계산합니다.
우리가 작성하는 자잘한 함수는 그저 프로그래밍을 쉽게 하기 위해서 나눈 것일 뿐입니다.

프로그래밍 공부를 위해서 Structure Interpretation of Computer Programs를 추천합니다.
MIT의 학사1,2년차 교재로 프로그래밍에 등장하는 기본적인 개념과 함께 함수형, OO, 논리형 패러다임의 기본적인 개념이 모두 잘 나와있습니다.
교재니까 당연히 실습과 예제위주로 되어있습니다.
책 내용만 보시지말고 모든 주석을 꼼꼼히 읽어보고 모든 문제를 풀어보시기를 추천합니다.(저도 문제는 조금밖에 못풀어 봤습니다. ^^;)
이 책의 소스는 Lisp의 수정판(보통 방언dialect이라고 부릅니다)인 Scheme을 썼습니다.
http://mitpress.mit.edu/sicp/full-text/book/book.html

Multiparadigm Programming in LEDA라는 책도 있습니다.
역시 교육용으로 Leda언어를 써서 여러 패러다임을 접할 수 있게 만들어졌습니다.
다만 leda의 방식은 정확하게 각각의 패러다임의 표현을 다 끌어내지 못하고 있다고 생각되기때문에 추천하지는 않습니다.

함수형 패러다임을 공부하신다면 Haskell을 공부하시는 게 좋다고 생각합니다.
순수 함수형 언어로 함수형 패러다임만의 독특한 장점과 단점을 알 수 있으리라 생각합니다.
The Haskell School of Expression: Learning Functional Programming through Multimedia http://www.haskell.org/soe
Haskell: The Craft of Functional Programming http://www.cs.ukc.ac.uk/people/staff/sjt/craft2e/
http://www.haskell.org

논리형 패러다임은 언어 자체보다는 논리 자체를 많이 공부해야 성과가 생깁니다만, 저도 논문이나 인터넷으로 찔끔찔끔 공부한 수준이라서 추천까지 해드릴 정도의 지식은 없습니다.
논리와 프롤로그에 대한 한글로된 매우 기초적 설명은 http://www.aistudy.com/program/prolog/prolog.htm에서 찾아볼 수 있습니다.
람다프롤로그 http://www.lix.polytechnique.fr/Labo/Dale.Miller/lProlog/
데일 밀러 교수(현존 최고의 논리학자?)의 홈페이지 http://www.lix.polytechnique.fr/Labo/Dale.Miller/

-- ps. 소스에서 탭 나오게 붙이려면 어떻게 해야합니까? 탭이 안나오니 영 어색하네요.

------------------------------
How many legs does a dog have?

pok의 이미지

추천감사드리구요, 함수형이란게 그런것이었군요.
헤스켈부터 공부해봐야겠네요.

An의 이미지

그것 갖고는 애플리케이션을 만들 수가 없어요. 너무 순수하게 실험적으로 만든 언어라 속도도 너무 순수하게 안나오고 생산성도 순수하게 떨어져요...

semmal의 이미지

이런 말 하기 뭣하지만 써보시기는 하고 말씀을 하시는 건가요?
현재 세계에서 가장 인기있는 언어가 ruby입니다.
뉴스그룹가서 하루에 올라오는 글 수만 비교해보세요. C++의 10배는 그냥 넘습니다.
이 많은 사람들이 다 연구나 실험을 위해서 장난처럼 쓴다고 생각하십니까?
An님이 말씀하신 것중에 맞는 말은 속도가 좀 떨어진다는 것 말고는 다 틀렸군요.
또한 그렇다하더라도 속도도 쓸 수 없을 만큼 나쁘지는 않습니다.
-애플리케이션을 만들 수 없다. => ruby는 프로토타이핑을 만들고 실제 어플리케이션을 만드는 성과에서 perl, python과 경쟁중입니다.
-실험적으로 만든 언어 => ruby는 가장 실용적인 언어중에 하나입니다.
-생산성 떨어짐 => lisp, perl, python과 비교해봐도 차이를 느낄 수 없을 정도고, C나 C++, Java보다는 월등한 생산성을 갖추고 있습니다.
저도 ruby를 딱히 좋아하는 것은 아닙니다만, ruby만큼 쓰기 편하고 좋은 언어가 거의 없다는 건 분명한 사실입니다.
괜히 화나게 만드는 댓글이군요.

------------------------------
How many legs does a dog have?

An의 이미지

님은 딱 보니까 현업에서 프로그램을 짜본 적이 한번도 없거나 초짜인 티가 확 나네요.
뉴스그룹에 올라오는 글이 많은 이유는 최근에 나온 언어니까 잠깐 관심이 많은 것 뿐이에요.
회사 가서 둘러 보세요.
한명이라도 루비로 애플리케이션 짜는 사람이 있기나 있는지 말이에요.
그리고 스몰토크같은 언어는 왜 망했는지 이유나 아세요?

cleol의 이미지

현업 6년차 프로그래머입니다. 주로 자바를 사용하는 프로젝트를 하고 C++ 을 사용하는 프로젝트는 조금 하고, 다른 언어들은 현업에서 쓰지 않지만 관심이 많습니다.
루비가 세상에서 제일 인기 있는 언어인지는 알 수 없는 일이고 말씀하신데로 실제로 사용되는 비율도 적습니다.(통계상으로도 그렇고, 제가 본 것도 그렇고)
하지만 많이 사용되지 않기 때문에 안 좋은 언어인 것은 아닙니다.
그리고 루비의 생산성에 대해서는 많은 사람들이 인정합니다. 그 생산성이 순수 객체 지향에서 오는 것인지는 모르겠습니다만.
특히 rails 프레임워크의 생산성은 현재 가장 많이 쓰이는 언어중에 하나인 자바로 프로그램하는 사람들에게 충격적(?)으로 다가왔을 정도니까요.
(한동안 지나치게 과민 반응했다는 생각이 들기는 하지만 확실히 멋있는 프레임워크입니다.)
스몰토크가 현재 많이 사용되지는 않습니다만 스몰토크가 프로그래밍 언어들에 미친 영향은 제법 큽니다.
MVC 라는 용어도 스몰토크로부터 나왔고, 자바가 받은 영향도 크지요. GOF의 디자인 패턴책은 예제들이 C++과 스몰토크로 제시되어있습니다.
고로 스몰토크 자체는 많이 사용되지 않지만 현업에서 사용하는 기술들에 큰 영향을 미쳤습니다.

순수객체지향언어로 어플리케이션을 못 만든다는 말씀은 분명히 잘못된 말씀입니다.
순수객체지향언어의 특성상 흔히 원시 타입(primitive type)이라고 불리는 데이터 타입을 사용하지 않기 때문에
반복적인 수치 연산이나 문자열처리에서 속도 문제가 있기는 하지만 대부분의 실용 어플리케이션에서 별로 문제가 될만한 소지는 없습니다.
다이나믹 디스패칭 역시 속도를 떨어트리는 요인이지만 역시 대부분의 실용 어플리케이션에서 별로 문제가 될만큼은 아닙니다.

순수객체지향이 실용적인 면에서 큰 잇점을 가지고 있다고는 생각지 않습니다만, 그렇다고 말씀하신 것처럼 문제가 될만한 단점이 되지도 않습니다.

그리고 말씀하시는 태도가 읽는 사람들을 거슬리게 합니다. 예의를 지켜주시는게 좋을 것 같습니다.

semmal의 이미지

스몰토크가 망한 이유가 적당한 라이브러리가 없고, 속도 느려서인 것은 맞습니다.
하지만 그게 언제적인지 알고나 말씀하시는 겁니까?
맥에서 쓰이는 Cocoa Objectiv-C는 실질적인 스몰토크의 계승자입니다.
루비 또한 그렇구요.

저 역시 현업에서 프로그램짠 2~3년 경력은 모두 C/C++과 Java에 치중되어있습니다.
딴거 쓰자고 해도 말 안듣는 사람이 절대 다수라는 것도 겪어봤습니다.

하지만 그렇게 사람들이 안쓴다고 안좋다고 생각한 적은 한번도 없습니다.
컴퓨터 역사에서 보이듯 좋은 것이 잘나간다는 보장이 없기때문이지요.

좋은 것만 현업에서 쓰이고 살아남는다면, os/2, nextstep왜 망했겠습니까?
microsoft는 왜 일등기업이 되었습니까?
activex의 기술이 좋아서 우리나라에 전부 activex를 쓰는 환경이 된 겁니까?

현업에서의 경험이 풍부하신 것 같으니 몇가지만 묻고 싶습니다.
1. 단기간에 블로그나 위키같은 웹어플리케이션을 개발하고 싶을때 무엇을 쓰십겁니까?
2. 구현상의 문제가 여럿있을게 확실한 프로젝트에서 프로토타이핑하는 도구로 무엇을 쓰실겁니까?
3. 복잡한 프로그램의 내부를 스크립트로 제어할 필요가 생겼습니다. 어떤 언어를 스크립트 언어로 선택하실 겁니까?

초짜인 저에 비해서 얼마나 제대로된 분이신지는 알고싶군요.

------------------------------
How many legs does a dog have?

suum의 이미지

순수 객체지향의 장단점을 말하자면, 자료형을 확장해서 쓰기 좋고 다형성을 모든 대상에게 적용할 수 있는게 장점이고, 실행 성능이 떨어지는게 단점이겠죠. 기본적인 정수같은 자료형도 전부 객체인데, 객체에는 가상 테이블이 들어가고 크기가 커집니다. 원래 8바이트인 Double자료형도 16바이트가 되는 거겠죠.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.