절차 / 함수 프로그래밍은 튜링 인수 (내 언어가 튜링 파워를 가지고 있고 다른 언어로 할 수있는 일을 할 수 있음)에 들어 가지 않아도 OOP보다 약하지 않습니다. 실제로 객체 지향 기술은 기본적으로 내장되어 있지 않은 언어로 실험되었습니다. 이런 의미에서 OO 프로그래밍은 절차 적 프로그래밍의 특정 스타일 일뿐 입니다. 그러나 프로그램 이해 및 유지 관리에 필수적인 모듈화, 추상화 및 정보 숨기기와 같은 특정 분야를 시행하는 데 도움이됩니다 .
일부 프로그래밍 패러다임은 이론적 인 계산 비전에서 발전합니다. 리스프 (Lisp)와 같은 언어는 람다 미적분과 언어 의 메타 순환 개념 (자연 언어의 반사와 유사) 에서 발전했습니다 . 혼절은 프롤로그 및 구속 조건 프로그래밍의 아버지가되었습니다. Algol 가족은 또한 람다 미적분학에 기인하지만 반사 기능이 내장되어 있지 않습니다.
Lisp는 많은 프로그래밍 언어 혁신의 테스트 베드가 되었기 때문에 흥미로운 예입니다. 이는 이중 유전자 유산으로 추적 할 수 있습니다.
그러나 언어는 종종 새로운 이름으로 발전합니다. 진화의 주요 요소는 프로그래밍 연습입니다. 사용자는 가독성, 유지 보수성, 정확성의 입증과 같은 프로그램의 속성을 향상시키는 프로그래밍 방법을 식별합니다. 그런 다음 프로그램의 품질을 향상시키기 위해 이러한 관행을 지원하고 때로는 시행 할 언어 기능 또는 제약 조건에 추가하려고합니다.
이것은 구식 프로그래밍 언어에서 이러한 관행이 이미 가능하지만이를 사용하려면 이해와 훈련이 필요하다는 의미입니다. 특정 구문을 사용하여 주요 언어로 새로운 언어로 이들 언어를 통합하면 특히 덜 복잡한 사용자 (예 : 대다수)에게 이러한 관행을보다 쉽게 사용하고 쉽게 이해할 수 있습니다. 또한 정교한 사용자에게는 삶이 조금 더 쉬워집니다.
어떤 방식으로, 그것은 서브 프로그램 / 기능 / 프로 시저가 프로그램에 대한 언어 디자인입니다. 유용한 개념이 식별되면 이름과 구문이 주어 지므로 해당 언어로 개발 된 모든 프로그램에서 쉽게 사용할 수 있습니다. 그리고 성공하면 미래 언어에도 통합 될 것입니다.
예 : 객체 방향 재 작성
이제 예를 들어 설명하려고합니다 (시간이 주어지면 더 연마 될 수 있습니다). 이 예제의 목적은 객체 지향 프로그램이 절차 적 프로그래밍 스타일로 작성 될 수 있음을 보여주기위한 것이 아니며, 아마도 책임과 유지 관리 성을 희생합니다. 차라리 OO 기능이없는 일부 언어는 실제로 고차원 함수와 데이터 구조를 사용하여 실제로 객체 지향을 효과적으로 모방하는 수단을 만들어 모듈화, 추상화 및 정보 숨기기를 포함한 프로그램 구성과 관련된 품질의 이점을 얻을 수 있음을 보여 주려고 노력합니다. .
내가 말했듯이, Lisp는 OO 패러다임을 포함하여 많은 언어 진화의 시험대였습니다. Lisp은 매우 간단하며 기본 인터프리터의 코드는 페이지보다 작습니다. 그러나 Lisp에서 OO 프로그래밍을 할 수 있습니다. 고차 함수 만 있으면됩니다.
나는 표현을 단순화하기 위해 난해한 Lisp 구문 대신 의사 코드를 사용합니다. 그리고 정보 숨기기 와 모듈화 라는 간단한 필수 문제를 고려할 것 입니다. 사용자가 구현에 대부분 액세스하지 못하도록하면서 객체 클래스를 정의합니다.
벡터 추가, 벡터 크기 및 병렬 처리와 같은 메서드를 사용하여 2 차원 벡터를 나타내는 vector라는 클래스를 만들고 싶다고 가정합니다.
function vectorrec () {
function createrec(x,y) { return [x,y] }
function xcoordrec(v) { return v[0] }
function ycoordrec(v) { return v[1] }
function plusrec (u,v) { return [u[0]+v[0], u[1]+v[1]] }
function sizerec(v) { return sqrt(v[0]*v[0]+v[1]*v[1]) }
function parallelrec(u,v) { return u[0]*v[1]==u[1]*v[0]] }
return [createrec, xcoordrec, ycoordrec, plusrec, sizerec, parallelrec]
}
그런 다음 생성 된 벡터를 사용할 실제 함수 이름에 할당 할 수 있습니다.
[벡터, xcoord, ycoord, vplus, vsize, vparallel] = vectorclass ()
왜 그렇게 복잡합니까? 함수에서 vectorrec 매개체 구성을 정의 할 수 있기 때문에 모듈화를 유지하기 위해 나머지 프로그램에서 볼 수 없도록하고 싶습니다.
극좌표로 다른 컬렉션을 만들 수 있습니다
function vectorpol () {
...
function pluspol (u,v) { ... }
function sizepol (v) { return v[0] }
...
return [createpol, xcoordpol, ycoordpol, pluspol, sizepol, parallelpol]
}
그러나 두 구현을 모두 무관심하게 사용하고 싶을 수도 있습니다. 한 가지 방법은 모든 값에 유형 구성 요소를 추가하여 동일한 환경에서 위의 모든 함수를 정의하는 것입니다. 그런 다음 반환 된 각 함수를 정의하여 좌표 유형을 먼저 테스트 한 다음 특정 함수를 적용 할 수 있습니다 그것을 위해.
function vector () {
...
function plusrec (u,v) { ... }
...
function pluspol (u,v) { ... }
...
function plus (u,v) { if u[2]='rec' and v[2]='rec'
then return plusrec (u,v) ... }
return [ ..., plus, ...]
}
내가 얻은 것 : 특정 함수는 (로컬 식별자 범위 지정으로 인해) 보이지 않고 남아 있으며 프로그램의 나머지는 vectorclass 호출로 반환 된 가장 추상적 인 함수 만 사용할 수 있습니다.
한 가지 반대 의견은 프로그램에서 각 추상 함수를 직접 정의하고 좌표 유형 종속 함수의 정의를 그대로 둘 수 있다는 것입니다. 그러면 숨겨 질 것입니다. 사실이지만 각 좌표 유형의 코드는 프로그램 전체에 걸쳐 작은 조각으로 잘립니다.
실제로, 나는 그들에게 이름을 줄 필요조차 없으며, 유형과 함수 이름을 나타내는 문자열에 의해 색인 된 데이터 구조에 익명의 기능 값을 유지할 수 있습니다. 함수 벡터에 국한되는이 구조는 프로그램의 나머지 부분에서는 보이지 않습니다.
사용을 단순화하기 위해 함수 목록을 반환하는 대신 apply라는 단일 함수를 명시 적으로 형식 값과 문자열을 인수로 사용하여 적절한 형식과 이름으로 함수를 적용 할 수 있습니다. 이것은 OO 클래스의 메소드를 호출하는 것과 매우 유사합니다.
객체 지향 기능의이 재구성에서 여기서 멈추겠습니다.
내가하려고했던 것은 상속 및 기타 기능을 포함하여 충분히 강력한 언어로 사용 가능한 객체 방향을 만드는 것이 너무 어렵지 않다는 것을 보여주는 것입니다. 통역사의 metacircularity는 도움이 될 수 있지만, 대부분 문법 수준에서 여전히 무시할 수있는 수준입니다.
객체 지향의 첫 사용자는 이러한 방식으로 개념을 실험했습니다. 그리고 그것은 프로그래밍 언어에 대한 많은 개선에서 일반적으로 적용됩니다. 물론 이론적 분석도 중요한 역할을하며 이러한 개념을 이해하거나 개선하는 데 도움이되었습니다.
그러나 일부 프로젝트에서 OO 기능이없는 언어가 실패 할 것이라는 생각은 단순히 보증되지 않습니다. 필요한 경우 이러한 기능의 구현을 매우 효과적으로 모방 할 수 있습니다. 많은 언어는 객체 지향이 내장되어 있지 않더라도 객체 지향을 매우 효과적으로 수행 할 수있는 구문 및 의미 론적 힘을 가지고 있습니다. 그리고 그것은 튜링 논쟁 이상의 것입니다.
OOP는 다른 언어의 제한 사항을 다루지 않지만 더 나은 프로그램을 작성하는 데 도움이되는 프로그래밍 방법론 을 지원하거나 시행 하므로 경험이 적은 사용자가 더 많은 고급 프로그래머가 해당 지원없이 사용하고 개발 한 모범 사례를 따르는 데 도움이됩니다.
이 모든 것을 이해하기위한 좋은 책은 Abelson & Sussman : 컴퓨터 프로그램의 구조와 해석 일 것입니다 .