어떤 종류의 메타 프로그래밍 을 허용하는 언어가 많이 있습니다 . 특히 나는 Lisp 언어 군에 대해 아무런 대답을하지 않은 것에 놀랐습니다 .
Wikipedia에서 :
메타 프로그래밍은 프로그램을 데이터로 취급 할 수있는 컴퓨터 프로그램을 작성하는 것입니다.
나중에 텍스트 :
Lisp는 아마도 역사적 우선 순위와 메타 프로그래밍의 단순성과 힘 때문에 메타 프로그래밍 기능을 갖춘 전형적인 언어 일 것이다.
리스프 언어
다음은 Lisp에 대한 간단한 소개입니다.
코드를 보는 한 가지 방법은 일련의 지침입니다. 이렇게 한 다음 수행하고 다른 작업을 수행하십시오. 이것은 목록입니다! 프로그램이 수행 할 작업 목록입니다. 물론 목록 안에 루프 등을 나타내는 목록을 만들 수도 있습니다.
우리는 리스프 함수 호출처럼 보이는 뭔가 얻을 (ABCD) : 우리는 요소 A, B, C를 포함하는 목록을 나타내는 경우,이 싶습니다 a
기능이며, b
, c
, d
인수가됩니다. 사실이라면 전형적인 "Hello World!" 프로그램은 다음과 같이 작성 될 수 있습니다.(println "Hello World!")
물론 또는 무언가로 평가되는 목록 b
일 수도 있습니다. 다음 : ""추가 할 수 있습니다 : 4 "인쇄합니다.c
d
(println "I can add :" (+ 1 3) )
따라서 프로그램은 중첩 된 목록의 시리즈이며 첫 번째 요소는 함수입니다. 좋은 소식은리스트를 조작 할 수 있다는 것입니다! 따라서 프로그래밍 언어를 조작 할 수 있습니다.
Lisp의 장점
리스프는 프로그래밍 언어를 만들기위한 툴킷만큼 프로그래밍 언어가 아닙니다. 프로그래밍 가능한 프로그래밍 언어.
이것은 Lisps에서 새로운 연산자를 만드는 것이 훨씬 쉬울뿐만 아니라 함수에 전달 될 때 인수가 평가되기 때문에 다른 언어로 일부 연산자를 작성하는 것도 거의 불가능합니다.
예를 들어 C와 같은 언어로 if
다음과 같이 연산자를 직접 작성한다고 가정 해 봅시다 .
my-if(condition, if-true, if-false)
my-if(false, print("I should not be printed"), print("I should be printed"))
이 경우 인수 평가 순서에 따라 두 인수가 모두 평가되고 인쇄됩니다.
Lisps에서 연산자 작성 (매크로라고 함)과 함수 작성은 거의 같은 방식으로 사용됩니다. 가장 큰 차이점은 매크로에 대한 매개 변수가 매크로에 인수로 전달되기 전에 평가 되지 않는다는 것 입니다. if
위와 같이 일부 연산자를 작성할 수 있어야합니다 .
실제 언어
여기서 정확히 범위를 벗어난 정도를 보여 주지만, 한 Lisp에서 프로그래밍을 시도하여 자세히 알아볼 것을 권장합니다. 예를 들어 다음을 살펴볼 수 있습니다.
- 구성표 , 작은 코어를 가진 오래되고, "순수한"리스프
- 공통 Lisp, 잘 통합 된 객체 시스템을 갖춘 더 큰 Lisp 및 많은 구현 (ANSI 표준 임)
- 입력 된 리스프 라켓
- Clojure가 가장 좋아하는 위의 예제는 Clojure 코드였습니다. JVM에서 실행중인 최신 Lisp SO 에도 Clojure 매크로의 예가 있습니다 (그러나 이것이 시작하기에 적합한 장소는 아닙니다. 4clojure , braveclojure 또는 clojure koans 를 먼저 살펴볼 것입니다 ).
그런데 Lisp는 LISt Processing을 의미합니다.
당신의 예에 대하여
아래 Clojure를 사용하여 예를 들어 보겠습니다.
add
Clojure (defn add [a b] ...your-implementation-here... )
에서 함수를 작성할 수 있다면 +
그렇게 이름을 지정할 수 있습니다 (defn + [a b] ...your-implementation-here... )
. 이것은 실제로 실제 구현 에서 수행되는 것입니다 (함수 본문은 조금 더 복잡하지만 정의는 본질적으로 위에서 쓴 것과 동일합니다).
접두사 표기법은 어떻습니까? Well Clojure는 prefix
(또는 폴란드어) 표기법을 사용하므로 infix-to-prefix
접두사가 붙은 코드를 Clojure 코드로 바꾸는 매크로를 만들 수 있습니다. 실제로 놀랍도록 쉽습니다 (실제로 clojure koans 의 매크로 연습 중 하나입니다 )! 야생에서도 볼 수 있습니다 (예 : Incanter $=
macro 참조) .
koans의 가장 간단한 버전은 다음과 같습니다.
(defmacro infix [form]
(list (second form) (first form) (nth form 2)))
;; takes a form (ie. some code) as parameter
;; and returns a list (ie. some other code)
;; where the first element is the second element from the original form
;; and the second element is the first element from the original form
;; and the third element is the third element from the original form (indexes start at 0)
;; example :
;; (infix (9 + 1))
;; will become (+ 9 1) which is valid Clojure code and will be executed to give 10 as a result
요점을 더 높이기 위해 Lisp는 다음과 같이 인용합니다 .
“Lisp의 차별화 된 특징 중 하나는 Lisp가 진화하도록 설계되었다는 것입니다. Lisp를 사용하여 새로운 Lisp 연산자를 정의 할 수 있습니다. 새로운 추상화가 대중화됨에 따라 (예를 들어 객체 지향 프로그래밍) 항상 Lisp에서 쉽게 구현할 수 있습니다. DNA처럼, 그런 언어는 스타일에서 벗어나지 않습니다.”
— Paul Graham, ANSI 공통 리스프
“Lisp에서의 프로그래밍은 우주의 원초적 힘을 가지고 노는 것과 같습니다. 손가락 끝이 번개처럼 느껴집니다. 다른 언어조차 친밀감이 없습니다.”
— Glenn Ehrlich, Lisp로가는 길