프로그래밍 언어는 처음에는 순차적으로 실행되는 코드 라인 만 사용했기 때문에 첫 번째 추상화 수준 중 하나 인 함수를 포함하도록 발전한 다음 클래스와 객체를 만들어 더 추상화했습니다. 다음 단계의 추상화는 무엇입니까?
클래스보다 더 추상적 인 것이 있거나 아직 있습니까?
프로그래밍 언어는 처음에는 순차적으로 실행되는 코드 라인 만 사용했기 때문에 첫 번째 추상화 수준 중 하나 인 함수를 포함하도록 발전한 다음 클래스와 객체를 만들어 더 추상화했습니다. 다음 단계의 추상화는 무엇입니까?
클래스보다 더 추상적 인 것이 있거나 아직 있습니까?
답변:
컴퓨팅의 역사에 대해 약간의 오해가 있다고 생각합니다.
첫 번째 추상화 (1936 년)는 사실 알론조 교회의 람다 미적분학 (Lamda Calculus)으로, 이는 고차 함수와 그 뒤에 따르는 모든 함수 언어의 개념을위한 기초입니다. 그것은 Lisp (1959 년에 만들어진 두 번째로 높은 수준의 프로그래밍 언어)에 직접적으로 영향을 미쳤으며, ML에서 Haskell 및 Clojure에 이르기까지 모든 것에 영감을주었습니다.
두 번째 추상화는 절차 적 프로그래밍이었습니다. 순차적 인 프로그램이 작성된 폰 노이만 컴퓨터 아키텍처에서 한 번에 한 명령 씩 나왔습니다. FORTRAN (1958 년 가장 오래된 고급 프로그래밍 언어)은 절차 적 패러다임에서 나온 첫 번째 고급 언어였습니다.
세 번째 추상화는 아마도 실제로 선언적 프로그래밍이었을 것인데, 먼저 Absys (1967), 이후 Prolog (1972)에 의해 설명되었습니다. 논리 프로그래밍의 기초이며, 일련의 명령어를 실행하지 않고 일련의 선언 또는 규칙을 일치시켜 식을 평가합니다.
네 번째 추상화는 60 년대에 Lisp 프로그램에 처음 등장한 객체 지향 프로그래밍 이었지만 나중에 1972 년에 스몰 토크에 의해 예증되었습니다. (스몰 토크의 메시지 전달 스타일이 하나의 진정한 객체 지향 추상화입니다. 나는 그것을 만지지 않을 것입니다.)
다른 폰 추상화, 특히 전통적인 폰 노이만 (Von Neumann) 컴퓨터 아키텍처에 대한 모든 추상화는이 네 가지 테마의 변형입니다. 나는 그 네 가지 이상의 다른 추상화가 단순히 그것들의 변형이나 조합이 아니라고 확신하지 않습니다.
그러나 추상화는 본질적으로 알고리즘을 모델링하고 설명하는 방법 일뿐입니다. 알고리즘을 일련의 개별 단계, 일련의 규칙, 수학적 함수 또는 상호 작용하는 객체로 설명 할 수 있습니다. 알고리즘을 설명하거나 모델링하는 다른 방법을 생각하는 것은 매우 어렵습니다.있는 경우에도 유틸리티의 유용성을 확신하지 못합니다.
그러나 양자 컴퓨팅 모델이 있습니다. 양자 컴퓨팅에서는 양자 알고리즘을 모델링하기 위해 새로운 추상화가 필요합니다. 이 분야의 신생 생물이기 때문에 나는 그것에 대해 언급 할 수 없습니다.
현재 이진 프로그래밍 시대의 가장 순수한 코드 추상화 형태는 "고차 함수"입니다. 기본적으로 함수 자체는 데이터로 취급되며 함수의 함수는 피연산자의 결과를 정의하는 연산자와 이러한 연산의 "중첩"을 정의하는 사전 결정된 순서의 연산을 사용하여 수학 방정식에서 볼 수 있듯이 정의됩니다. 수학에는 구조상 "제한 명령"이 거의 없습니다. 내가 생각할 수있는 두 가지 예는 "x가 어떤 값을 가지거나 어떤 제약을 따르는 값이되게하라", 그리고 입력이 출력을 생성하는 데 필요한 표현을 결정하는 "개별 함수"입니다. 이러한 구성은 자체 기능으로 쉽게 표현할 수 있습니다. "function"x는 항상 1을 반환하고 "overloads" 함수형 함수는 객체 지향 과부하가 입력 값을 기반으로 정의 할 수있는 것과 달리 함수형 함수에 전달되는 방식으로 정의됩니다. 자체적으로도 명명 된 함수 그룹을 "조각"평가할 수 있습니다. 따라서 프로그램은 낮은 수준의 명령 개념을 없애고 대신 입력 데이터에 대해 "자체 평가"에 중점을 둡니다.
이러한 고차 함수는 "기능 언어"의 중추를 형성합니다. 프로그램의 기능은 "순수 함수"(하나 이상의 입력, 하나 이상의 출력, 부작용 없음 또는 "숨겨진 상태")로 정의되며, 서로 중첩되어 필요에 따라 평가됩니다. 이러한 경우 대부분의 "제국 논리"는 추상화됩니다. 런타임은 함수의 실제 호출 및 함수의 하나 이상의 과부하를 호출해야하는 모든 조건을 처리합니다. 그러한 프로그램에서 코드는 무언가를 "하고있는"것으로 생각되지 않고, 무언가 "되고있는"것으로 생각되며, 초기 입력이 주어지면 프로그램이 실행될 때 정확하게 결정됩니다.
고차 함수는 이제 많은 명령형 언어의 필수 요소입니다. .NET의 람다 문장은 기본적으로 다른 "함수"에 "익명"기능적 입력을 허용합니다 (필수적으로 구현되었지만 이론적으로 반드시 그럴 필요는 없음). 원하는 결과.
최신 프로그래밍 언어에서 흔히 볼 수있는 또 다른 추상화는 "덕 타이핑 (duck-typing)"개념에 기반한 동적 변수 타이핑입니다. 오리처럼 보이고, 오리처럼 수영하고, 오리처럼 날고 오리처럼 cks 거리면 오리라고 부를 수 있습니다. 실제로 청둥 오리인지 캔버스 백인지는 중요하지 않습니다. 그것은 실제로 거위 또는 백조의 경우 중요하지만 모르지 후 다시 수도 문제가되지 당신이 걱정하는 모두가 수영과 파리, 그리고 그 경우 좀 오리처럼 보인다. 이것은 객체 상속의 궁극적 인 것으로 간주됩니다. 당신은 어떤 상관 없어 되고 , 이름을 지정 제외; 무엇보다 중요한 것은 그것이 무엇을 합니까. 이러한 언어에는 기본적으로 두 가지 유형 만 있습니다. "원자", 정보의 단일 요소 (하나의 "값"; 숫자, 문자, 기능 등) 및 "튜플"은 원자와 튜플의 다른 모든 항목에 대한 "포인터"로 구성됩니다. 런타임에 의해이 유형이 바이너리로 어떻게 구현되는지는 정확히 관련이 없습니다. 이를 사용하면 간단한 값 유형에서 문자열, 컬렉션에 이르기까지 생각할 수있는 거의 모든 유형의 기능을 달성 할 수 있습니다 (값은 "유형"이 다를 수 있으므로 "복합 유형", 즉 "개체"가 가능함).
SQL과 같은 도메인 특정 언어를 더 높은 추상화 순서로 생각할 수 있습니다. SQL은 저장소와 같은 작업을 추상화하고 집합 이론에 따라 더 높은 수준의 기능을 제공하는 매우 대상이 지정된 언어입니다. 또한 오늘날 몇 개의 주류 언어가 특정 아키텍처가 아니라 가상 머신 (예 : JVM 또는 .NET CLR)을 대상으로하는지 고려하십시오. 예를 들어 C #은 기본 런타임 엔진에 의해 해석되는 (또는 더 자주 JIT 's-Just In Time Compiled-- 기본 구현으로) IL로 컴파일됩니다.
작업 프로그램을 작성하는 데 많은 기술적 경험없이 사용할 수있는 매우 높은 수준의 언어를 작성하는 데 사용되는 DSL 개념에 대한 많은 허벌이있었습니다. 누군가가 평범한 영어에 가깝게 자신의 엔티티와 상호 작용을 설명 할 수 있었으며 운영 환경이 간단한 UI 제공부터 데이터베이스에 데이터 저장에 이르기까지 모든 것을 처리했다고 생각하십시오. 이러한 작업이 추상화되면 프로그래밍이 얼마나 어려워 질지 상상할 수 있습니다.
JetBrains MPS (DSL 또는 언어 생성기를 설명하기위한 툴킷) 와 같은 오늘날에도 일부 존재합니다 . Microsoft는 M 언어 (M 언어가 너무 완벽하여 언어가 M로 정의되어 있음 )를 사용 하여이 공간에 짧은 전망 (그리고 매우 유망한)을 가지고있었습니다 .
개념의 비평가들은 프로그램 개발 작업에서 프로그래머를 제거하려는 이전의 실패한 시도를 지적하는데, DSL 워크 벤치와의 차이점 (Fowler가 부르는 것처럼)은 개발자가 도메인 전문가가 표현할 수있는 개념을 체계화하는 데 여전히 관여하고 있다는 점입니다 그들의 도메인의 요구. OS 및 언어 공급 업체가 프로그래밍에 사용하는 도구를 만드는 것처럼 DSL을 사용하여 비즈니스 사용자를위한 도구를 제공합니다. 데이터와 논리를 설명하는 DSL을 상상할 수있는 반면 개발자는 데이터를 저장하고 검색하고 DSL에 표현 된 논리를 적용하는 인터프리터를 만듭니다.
메타 구조, 모듈, 프레임 워크, 플랫폼 및 서비스는 모두 클래스보다 더 높은 기능 그룹입니다. 프로그래밍 시스템 추상화 계층 :
메타 클래스 , 고차 함수 및 제네릭 과 같은 메타 구조는 기본 클래스, 함수, 데이터 유형 및 데이터 인스턴스에 추상화를 명확하게 추가합니다. 특성, 측면 및 데코레이터는 코드 기능을 결합하고 다른 클래스 및 기능을 유사하게 '가속화'하는 새로운 메커니즘입니다.
사전 객체 언어조차도 모듈과 패키지를 가졌으므로 클래스 위에 놓는 것은 논쟁의 여지가 있습니다. Bu에는 클래스와 메타 구조가 포함되어 있으므로 순위가 높습니다.
프레임 워크 는 가장 강력한 해답입니다. 정교한 고급 추상화를 제공하기 위해 여러 클래스, 메타 구조, 모듈, 함수 등을 조율합니다. 그러나 프레임 워크는 여전히 거의 전적으로 프로그래밍 영역에서 작동합니다.
솔루션 스택 또는 플랫폼은 일반적으로 여러 프레임 워크, 하위 시스템 또는 구성 요소를 여러 문제를 해결하기위한 환경으로 결합합니다.
마지막으로, 거기에 서비스 로 배포 --often 웹 또는 네트워크 서비스를 제공합니다. 이들은 완전한 번들로 제공되는 아키텍처, 프레임 워크, 솔루션 스택 또는 애플리케이션 기능입니다. 내부는 종종 불투명하며 주로 관리자, 프로그래밍 및 사용자 인터페이스를 노출시킵니다. PaaS 및 SaaS 가 일반적인 예입니다.
이제이 진행이 몇 가지 이유로 완전히 만족스럽지 않을 수 있습니다. 첫째, 그것은 완벽하게 선형이거나 계층 적이 지 않은 것들의 깔끔한 선형 진행 또는 계층을 만듭니다. "스택"및 서비스와 같은 일부 추상화는 개발자가 완전히 통제 할 수없는 내용을 다룹니다. 그리고 그것은 새로운 마술 픽시 먼지를 놓지 않습니다. (스포일러 : 마법의 요정 가루는 없습니다. )
새로운 추상화 수준 을 찾는 것은 실수라고 생각합니다 . 위에 열거 한 모든 것들이 현재처럼 유명하거나 인기있는 것은 아니지만 몇 년 동안 존재 해 왔습니다 . 그리고 그 기간 동안, 모든 코딩 레벨에서 가능한 추상화가 향상되었습니다. 우리는 이제 배열뿐만 아니라 일반적인 범용 컬렉션을 가지고 있습니다. 인덱스 범위뿐만 아니라 컬렉션을 반복합니다. 우리는리스트 이해와리스트 필터와 맵 오퍼레이션을 가지고 있습니다. 많은 언어의 함수는 가변 개수의 인수 및 / 또는 기본 인수를 가질 수 있습니다. 등등. 우리는 모든 레벨 에서 추상화를 증가시키고 있으므로, 더 많은 레벨을 추가한다고해서 전체 추상화 레벨을 증가시킬 필요는 없습니다.
클래스 다음의 추상화는 메타 클래스 입니다. 그것은 간단합니다;)
인스턴스가 클래스 인 클래스 일반 클래스가 특정 객체의 동작을 정의하는 것처럼 메타 클래스는 특정 클래스 및 해당 인스턴스의 동작을 정의합니다. 모든 객체 지향 프로그래밍 언어가 메타 클래스를 지원하는 것은 아닙니다. 그 중 메타 클래스가 클래스 동작의 특정 측면을 재정의 할 수있는 정도는 다양합니다. 각 언어에는 객체, 클래스 및 메타 클래스의 상호 작용 방식을 제어하는 규칙 세트 인 자체 메타 오브젝트 프로토콜이 있습니다.
Type
반사 기능은 제공하지만 돌연변이는 아닙니다 ( CLOS에서 할 수있는 것처럼 MyType
말하면 새로운 방법을 추가 할 수 없습니다 typeof(MyType).Methods += new Method ( "Foo", (int x)=>x*x )
)
카테고리 이론을 언급 한 사람이 아무도 없습니다.
가장 기본적인 프로그래밍 단위는 유형을 기반으로하는 함수입니다. 함수는 일반적으로 f : A-> B로 표시되며 A와 B는 유형입니다. 내가 타입과 함수를 호출하는 이런 것들을 올바른 방식으로 조합하면 카테고리라는 것을 얻을 수 있습니다. 이 시점에서 멈출 필요는 없습니다.
이러한 것들과 범주를 가져 와서 서로 연관시키는 올바른 방법이 무엇인지 스스로에게 물어보십시오. 제대로하면 두 범주 사이에 있으며 일반적으로 F : C-> B로 표시되는 functor라는 것을 얻습니다. 다시 한 번 중지 할 필요가 없습니다.
모든 펑터를 가져 와서 올바른 방법으로 정리할 수 있습니다. 올바른 작업을 수행하면 두 펑터를 서로 관련시키는 방법이 궁금해집니다. 이 시점에서 자연 변환이라고 불리는 mu : F-> G를 얻습니다. 여기서 F와 G는 functors입니다.
이 시점에서 나의 지식은 희미 해지지 만 계속해서 추상화의 사다리를 계속 올라갈 수 있습니다. 객체와 클래스는 추상화 사다리를 얼마나 높이 올릴 수 있는지 설명하지 않습니다. 위의 개념을 계산적으로 표현할 수있는 많은 언어가 있으며 이러한 언어 중 가장 두드러지는 언어는 Haskell입니다. 따라서 추상화가 실제로 무엇인지 알고 싶다면 Haskell 또는 Agda 또는 HOL 또는 ML을 배우십시오.
액터 모델이 후보 목록에서 누락 된 것 같습니다.
배우가 의미하는 바는 다음과 같습니다.
이 모델은 결정 성있는 Turing 머신을 넘어서는 것이며 동시 프로그램을 볼 때 실제 하드웨어에 더 가깝습니다. 여분의 (비용이 많이 드는) 동기화 단계를 사용하지 않는 한, 요즘 코드가 데이터를 수신 할 때 같은 다이의 다른 쪽 (아마도 같은 코어 내부)에서 해당 값이 이미 변경되었을 수 있습니다.
짧은 토론 / 소개 : http://youtube.com/watch?v=7erJ1DV_Tlo
내가 정확하게 이해한다면, "오름차순 추상화"는 대부분 코드 재사용과 관련된 점점 더 큰 논리 캡슐화로 생각할 수 있습니다.
차례로 실행되는 특정 명령어 에서 함수 / 서브 루틴으로 이동하여 명령어의 논리적 그룹을 단일 요소로 캡슐화하거나 추상화합니다. 그런 다음 특정 논리 엔티티 또는 범주와 관련된 서브 루틴을 캡슐화하는 객체 또는 모듈이 있으므로 String
클래스 아래의 모든 문자열 연산 또는 Math
모듈 아래의 모든 일반적인 수학 연산 (또는 C #과 같은 언어의 정적 클래스)을 그룹화 할 수 있습니다 .
이것이 우리의 진보라면, 다음은 무엇입니까? 글쎄, 난 당신이 다음 단계를 명확하게 잘라 생각하지 않습니다. 다른 사람들이 대답했듯이, 당신의 진보는 명령 적 / 절차 적 프로그래밍 스타일에만 적용되며 다른 패러다임은 당신의 추상화 개념을 공유하지 않습니다. 그러나 은유를 논리적으로 확장 할 수있는 것이 있다면 그것은 서비스 입니다.
서비스는 기능을 제공하는 실체라는 점에서 클래스와 비슷하지만 인스턴스화 한 객체를 사용하는 것보다 우려가 훨씬 더 엄격하게 분리되어 있습니다. 제한된 작업 집합을 노출하고 내부 논리를 숨기고 동일한 컴퓨터에서 실행되고 있지 않아도됩니다.
다시 한 번 미세한 차이가 있습니다. 대부분의 경우 서비스에 대한 프록시 역할을 하는 객체 를 사용하며이 둘은 매우 유사하지만 아키텍처는 두 가지가 다릅니다.
새로운 형태의 추상화는 저수준 작업을 숨 깁니다. 명명 된 절차와 기능은 프로그램 주소를 숨 깁니다. 객체는 동적 메모리 관리 및 일부 유형에 따른 "if 문"을 숨 깁니다.
저수준의 준설을 숨길 다음 단계의 실용적인 추상화는 기능적 반응성 프로그래밍의 것 입니다. 콜백을 숨기고 javascript에서 명시 적으로 관리해야 할 종속성을 업데이트하는 http://elm-lang.org/ 와 같은 "신호"를보십시오 . FRP는 대규모 인터넷 응용 프로그램 및 고성능 병렬 처리에 필요한 복잡한 프로세스 간 및 시스템 간 통신을 숨길 수 있습니다.
나는 이것이 앞으로 5 년 안에 우리 모두가 흥분하게 될 것이라고 확신합니다.