메타 프로그래밍이란 정확히 무엇입니까?


128

Java 플랫폼의 ployglot 프로그래밍에 대한 TheServerSide에 대한 기사를 읽고있었습니다 . 이 기사의 일부 의견은 메타 프로그래밍을 코드 생성 기능 (아마도 즉석에서)이라고합니다.

즉석에서 코드를 생성하는 기능을 메타 프로그래밍하거나 런타임에 기존 객체에 메서드와 속성을 주입하는 기능입니까 (예 : Python, Ruby 및 Groovy와 같은 일부 동적 언어가 허용하는 것).


7
당신이 대답에 관심이있을 수 stackoverflow.com/questions/2565572/...
ewernli

@ewernli : 그 대답은 실제로 여기에있는 어떤 대답보다 낫습니다!
JD

답변:


100

메타 프로그래밍은 프로그램이 자신에 대한 지식을 가지고 있거나 스스로를 조작 할 수있는 다양한 방법을 말합니다.

C #과 같은 언어에서 리플렉션은 프로그램이 자체에 대한 정보를 검사 할 수 있기 때문에 메타 프로그래밍의 한 형태입니다. 예를 들어 객체의 모든 속성 목록을 반환합니다.

ActionScript와 같은 언어에서는 런타임에 함수를 평가하여 eval ( "x"+ i)와 같은 새 프로그램을 만들 수 있습니다. DoSomething ()은 i가 1이면 x1, i가 2이면 x2라는 객체에 영향을줍니다.

마지막으로, 메타 프로그래밍의 또 다른 일반적인 형태는 프로그램이 사소하지 않은 방식으로 변경 될 수있는 경우입니다. LISP는 이에 대해 잘 알려져 있으며 약 10 년 전에 Paul Graham이 옹호 한 것입니다. 그의 구체적인 에세이를 좀 찾아봐야 겠어요. 그러나 아이디어는 프로그램이 상태에 따라 프로그램의 다른 부분을 변경한다는 것입니다. 이를 통해 오늘날 대부분의 인기있는 언어에서 매우 어려운 결정을 런타임에 유연하게 내릴 수 있습니다.

또한 직선 어셈블리로 프로그래밍하던 시절에는 런타임에 스스로 변경되는 프로그램이 필요하고 매우 흔하다는 사실도 주목할 가치가 있습니다.

Paul Graham의 에세이 "What Made Lisp Different"에서 발췌 :

많은 언어에는 매크로라는 것이 있습니다. 그러나 Lisp 매크로는 독특합니다. 그리고 믿거 나 말거나, 그들이하는 일은 괄호와 관련이 있습니다. Lisp의 디자이너는 언어에 모든 괄호를 넣지 않았습니다. Blub 프로그래머에게 Lisp 코드는 이상해 보입니다. 그러나 그 괄호에는 이유가 있습니다. 그들은 Lisp와 다른 언어의 근본적인 차이점을 보여주는 외부 증거입니다.

Lisp 코드는 Lisp 데이터 개체로 구성됩니다. 그리고 소스 파일에 문자가 포함되어 있고 문자열이 언어에서 지원하는 데이터 유형 중 하나라는 사소한 의미가 아닙니다. Lisp 코드는 파서가 읽은 후 탐색 할 수있는 데이터 구조로 구성됩니다.

컴파일러가 작동하는 방식을 이해한다면 Lisp에는 구문이 없기 때문에 Lisp가 이상한 구문을 사용하는 것은 아닙니다. 다른 언어가 구문 분석 될 때 컴파일러 내에서 생성되는 구문 분석 트리에 프로그램을 작성합니다. 그러나 이러한 구문 분석 트리는 프로그램에서 완전히 액세스 할 수 있습니다. 그것들을 조작하는 프로그램을 작성할 수 있습니다. Lisp에서는 이러한 프로그램을 매크로라고합니다. 프로그램을 작성하는 프로그램입니다.

프로그램을 작성하는 프로그램? 언제 그렇게하고 싶습니까? Cobol에서 생각하면 자주는 아닙니다. Lisp에서 생각한다면 항상. 강력한 매크로의 예를 들어주고 거기에 말할 수 있다면 여기에서 편리 할 것입니다! 어떻게에 대한? 하지만 내가 그렇게한다면 Lisp를 모르는 사람에게는 횡설수설처럼 보일 것입니다. 그것이 의미하는 바를 이해하기 위해 알아야 할 모든 것을 설명 할 여지가 없습니다. 에서 안시 커먼 리스프 나는 내가 할 수있는 한 빨리 함께 일을 이동하려고, 심지어는 그래서 160 페이지까지 매크로에 도착하지 않았다.

하지만 저는 설득력있는 주장을 할 수 있다고 생각합니다. Viaweb 편집기의 소스 코드는 약 20-25 %의 매크로였습니다. 매크로는 일반 Lisp 함수보다 작성하기가 더 어렵고 필요하지 않을 때 사용하는 것은 나쁜 스타일로 간주됩니다. 따라서 해당 코드의 모든 매크로가 있어야하므로 거기에 있습니다. 이것이 의미하는 바는이 프로그램에있는 코드의 최소 20-25 %가 다른 언어로는 쉽게 할 수없는 일을하고 있다는 것입니다. 그러나 Blub 프로그래머는 Lisp의 신비한 힘에 대한 나의 주장에 대해 회의적 일 수 있습니다. 우리는 우리 자신의 즐거움을 위해이 코드를 작성하지 않았습니다. 우리는 우리와 경쟁자들 사이에 기술적 장벽을두기 위해 최대한 열심히 프로그래밍하는 작은 스타트 업이었습니다.

의심스러운 사람은 여기에 어떤 상관 관계가 있는지 궁금해 할 수 있습니다. 우리 코드의 큰 덩어리는 다른 언어로하기 매우 어려운 일을하고있었습니다. 결과 소프트웨어는 경쟁 업체의 소프트웨어가 할 수없는 일을했습니다. 어떤 종류의 연결이 있었을 수도 있습니다. 나는 당신이 그 스레드를 따르기를 권장합니다. 목발을 짚고 다니는 노인에게는 눈에 보이는 것보다 더 많은 것이있을 수 있습니다.


6
C ++의 템플릿 메타 프로그래밍을 잊지 마세요. 식을 실행하고 컴파일 타임에 결정을 내리고 결과를 최종 실행 파일로 정적으로 컴파일하는 기능.
Remy Lebeau

1
나는 충격을 받았으며 in order to put technical barriers between us and our competitors이것은 정확합니다.
Evan Hu

4
스스로를 조작하는 프로그램은 모든 메타 프로그램의 하위 집합입니다. 일반적으로 메타 프로그래밍은 프로그램을 조작하는 프로그램을 의미합니다.
JD

55

좋은 질문입니다. 현재 귀하의 질문에 올바르게 답한 답변이 없다는 점에 대해 유감입니다. 제가 도와 드릴까요 ...

메타 프로그래밍의 정의는 매우 간단합니다. 프로그램을 조작하는 프로그램을 의미합니다.

당신의 대답은 스스로를 조작하는 프로그램을 말합니다. 그것들은 실제로 메타 프로그램이지만 모든 메타 프로그램의 하위 집합입니다.

모두:

  • 파서
  • 도메인 특정 언어 (DSL)
  • EDSL (embedded domain specific languages)
  • 컴파일러
  • 통역사
  • 임기 재 작성자
  • 정리 증명

메타 프로그램입니다. 따라서 GCC 컴파일러 는 메타 프로그램, CPython 인터프리터 는 메타 프로그램, Mathematica 컴퓨터 대수 시스템 은 메타 프로그램, Coq 정리 증명자는 메타 프로그램 등입니다.

다른 답변은 메타 프로그램이 다른 프로그램을 생성하는 프로그램이라고 주장했습니다. 그것들은 실제로 메타 프로그램이지만 모든 메타 프로그램의 하위 집합입니다. 푸리에 변환 서방 가장 빠른 (FFTW) 라이브러리 등의 metaprogram의 일례이다. 소스 코드는 대부분 OCaml 로 작성되며 특정 기계에 최적화 된 고성능 고속 푸리에 변환 루틴 을 생성하기 위해 결합 된 C 코드 (코드 렛이라고 함) 비트를 생성 합니다. 이 라이브러리는 실제로 Matlab에서 FFT 루틴을 제공하는 데 사용됩니다. 사람들은 FORTRAN 초기부터 수십 년 동안 수치 방법을 생성하는 프로그램을 작성해 왔습니다 .

메타 프로그래밍 지원을 통합 한 최초의 프로그래밍 언어는 1950 년대 후반 LISt 프로세서 (LISP) 언어였습니다. LISP 1.5 에는 메타 프로그래밍을 더 쉽게 만들어주는 여러 기능이 포함되어 있습니다. 첫째, LISP의 핵심 데이터 유형은 중첩 된 목록입니다. 즉 (a (b c) d), 모든 LISP 코드가 데이터 구조로 기본적으로 표현 될 수 있음을 의미합니다. 이것은 동질성으로 알려져 있습니다. 둘째, QUOTE를 사용하여 LISP 코드를 데이터로 쉽게 변환 할 수 있습니다. 예를 들어 (+ 1 2 3)1 + 2 + 3 (QUOTE (+ 1 2 3))을 더하고 평가할 때 1 + 2 + 3을 더하는 표현식을 만듭니다. 셋째, LISP는 호스트 인터프리터 또는 컴파일러를 사용하여 런타임에 생성 된 LISP 코드를 포함하여 런타임에 LISP 코드를 평가할 수있는 메타 순환 평가기를 제공했습니다. LISP의 후손에는 SchemeClojure가 포함됩니다.. 이러한 모든 언어에서 메타 프로그래밍은 일반적으로 매크로를 사용하여 스스로 수정하는 프로그램의 형태로 가장 흔히 볼 수 있습니다.

1970 년대에 Robin Milner 는 Standard MLOCaml 을 포함 하고 HaskellF #에 큰 영향을 미치는 프로그래밍 언어의 ML 제품군으로 발전한 MetaLanguage (ML)를 개발했습니다 . 이러한 언어를 사용하면 다른 언어를 쉽게 표현할 수 있습니다. 이러한 언어에서 메타 프로그램은 렉서, 파서, 인터프리터 및 컴파일러의 형태로 가장 일반적으로 표시됩니다.

1994 년 Erwin Unruh는 C ++ 템플릿 시스템이 튜링이 완료되었고 컴파일 타임에 임의의 프로그램을 실행하는 데 사용될 수 있음을 발견했습니다 . C ++ 템플릿 메타 프로그래밍은 (ab) Blitz ++ 라이브러리 에서 수치 방법을 생성하는 것을 포함하여 많은 다른 일에 메타 프로그래밍을 사용했던 사람들에게 메타 프로그래밍을 가져 왔습니다 .


33

음, 메타 프로그래밍은 단지 프로그래밍이지만 기본적으로 "코드를 작성하는 코드 작성" 입니다.

프로그램이 자체 구조와 동작을 관찰하고 수정할 수있을 때 언급 한 기능을 리플렉션이라고하며 메타 프로그래밍의 한 유형입니다.

동적 형식의 언어는 이러한 언어의 해석 된 특성으로 인해 가능한 강력한 런타임 반영 기능을 가지고 있습니다.

정적 유형 언어는 또한 강력한 메타 프로그래밍 기술을 가지고 있습니다. 예를 들어 C ++ 템플릿 메타 프로그래밍 ...


14

이것은 아마도 메타 프로그래밍의 가장 자유로운 정의 일 것입니다.

다음을 포함한다고 생각합니다.

  1. 코드 생성 또는 런타임 코드 생성 (또는 둘 다) 컴파일
  2. 측면 지향적 사고 또는 측면 지향 프로그래밍
  3. DRY 생각

이 중 하나를 조합하여 사용할 수 있다고 생각합니다.

  1. 반사
  2. DSL (도메인 특정 언어)
  3. 속성 (.NET) 또는 주석 (Java)
  4. 제네릭 (.NET / Java)
  5. 템플릿 (C ++)
  6. method_missing (Ruby)
  7. 클로저 / 퍼스트 클래스 함수 / 델리게이트
  8. AOP-측면 지향 프로그래밍

매우 간결하고 사려 깊은 답변입니다. 조사 할 좋은 메뉴를주었습니다. 감사합니다!
swyx

6

메타 프로그래밍은 다른 프로그램을 출력하는 프로그램을 작성하는 것입니다. 이것은 Lisp와 같은 언어가 정말 잘하는 것입니다. Ruby, Lisp, Scheme 등과 같은 실제 매크로 (C ++ 매크로가 아니라 출력되는 코드를 조작 할 수있는 매크로)를 지원하는 언어에서 Java와 같은 언어에서 수행하는 것이 훨씬 쉽습니다.

한 가지 구현은 특정 작업을 수행하기 위해 프로그래밍 언어를 향상시키는 방법 인 "도메인 특정 언어"를 만드는 것입니다. 올바르게 수행하면 매우 강력 할 수 있습니다. Ruby on Rails는 이런 종류의 프로그래밍의 좋은 예입니다.

이 방법을 탐구하는 데 관심이 있다면 주제를 다루는 중요한 책 중 하나 인 컴퓨터 프로그램구조와 해석을 확인하십시오 .


5

메타 프로그래밍은 다른 프로그램 (또는 자체)을 데이터로 작성하거나 조작하는 컴퓨터 프로그램을 작성하는 것 또는 그렇지 않으면 컴파일 타임에 수행되는 작업의 일부를 런타임에 수행하는 것입니다. 대부분의 경우이를 통해 프로그래머는 모든 코드를 수동으로 작성하는 데 걸리는 시간과 동일한 시간에 더 많은 작업을 수행 할 수 있습니다. 또는 재 컴파일없이 새로운 상황을 효율적으로 처리 할 수있는 더 큰 유연성을 프로그램에 제공합니다. ( 출처 .)

기본적으로 더 많은 코드를 출력하는 코드를 작성하는 것이며, 이는 목표를 달성하기 위해 실행됩니다. 이것은 일반적으로 동일한 언어 내에서 수행되거나 (javascript를 사용하여 javascript 문자열을 생성 한 다음 eval이를 사용) 다른 언어를 방출 (.NET을 사용하여 Windows 배치 파일 생성)합니다.


4

wikipedia 에는 주제에 대한 좋은 기사가 있습니다. 메타 프로그래밍으로 규정하기 위해 런타임 수정을 할 필요가 없습니다. 예를 들어, 많은 사람들이 C ++ 템플릿을 사용하여 컴파일 타임에 메타 프로그래밍을 수행합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.