메타 프로그래밍의 용도는 무엇입니까?
나는 읽었다 :
메타 프로그래밍 / 코드 생성의 목적에 대해 약간의 혼란을 고백합니다.
누구든지 메타 프로그래밍 / 코드 생성을 사용하는 구체적인 예가 있습니까? 대안보다 나은 이유에 대한 설명이 동반되는 것이 더 좋습니다.
편집 : 엉겅퀴 는 메타 프로그래밍으로 간주됩니까?
자동차를 만드는 사람을 상상해보십시오. 컴퓨터를 사용하는 것과 같다고 말해보세요.
어느 시점에서 그는 항상 똑같은 일을하고 있다는 것을 깨닫습니다.
그래서 그는 자동차를 만들기 위해 공장을 짓습니다. 그는 지금 프로그래밍 중입니다!
그럼에도 불구하고 다시 한 번 어느 시점에서 그는 항상 어느 정도는 항상 똑같은 일을하고 있다는 것을 깨닫습니다.
이제 그는 자동차를 만드는 공장을 짓는 공장을 짓기로 결정했습니다. 그것이 메타 프로그래밍입니다.
메타 프로그래밍은 엄청나게 강력하지만 시스템의 한 가지 결함으로 인해 모든 이점이 괴물의 어려움으로 바뀝니다. 그러니 그것을 숙달하고 사용하십시오 ... 아니면 멀리 떨어져!
저는 메타 프로 게밍을 "다른 프로그램을 작성 (또는 수정)하는 프로그램"이라고 생각합니다. (다른 대답은 "공장을 만드는 공장"이라고 말했습니다. 좋은 비유).
사람들은 응용 프로그램 사용자 지정, 상용구 코드 생성, 특수 상황에 대한 프로그램 최적화, DSL 구현, 직교 설계 문제 ( "측면")를 처리하기위한 코드 삽입 등 모든 종류의 용도를 찾습니다.
놀라운 점은 텍스트 템플릿, 매크로, 전 처리기 조건문, 제네릭, C ++ 템플릿, 측면, 반영 등 이러한 단편적인 작업을 수행하기 위해 얼마나 많은 다른 메커니즘이 발명되었는지입니다. 다른 메커니즘을 다른 언어로 변환하고 대부분의 언어는 메타 프로그래밍을 전혀 지원하지 않습니다. 이러한 기능의 분산 형 배포는 제한이있는 한 언어로 일부 종류의 메타 프로그래밍을 수행 할 수 있지만 다른 언어에서는 이러한 종류를 수행 할 수 없음을 의미합니다. 그것은 악화되고 있습니다 :-}
내가이 칼자루를 따라온 관찰 은 프로그램 변환 의 형태 로 모든 언어 와 함께 작동하는 일반적인 메타 프로그래밍 기계를 만들 수 있다는 것 입니다. 프로그램 변환은 매개 변수화 된 패턴입니다. " 이 구문 이 보이면 해당 구문으로 바꾸십시오 ".
하나의 변환 자체는 일반적으로 인상적이지 않지만 수십 또는 수백 개가 코드를 크게 변경할 수 있습니다. (정교한) 프로그램 변환은 사실상 튜링 머신을 시뮬레이션 할 수 있기 때문에 분산 된 모든 포인트 방식 기술을 포함하여 임의의 코드 변경을 수행 할 수 있습니다.
언어 정의를 허용하는 도구입니다. 언어 별 변환을 생성하고 다른 변환을 생성하여 이러한 변환을 적용하는 메타 메타 프로그래밍 도구 : "프로그램을 작성하는 프로그램"을 작성하는 프로그램입니다.
가치는 이러한 도구를 적용하여 임의 코드에 대한 다양한 변경을 수행 할 수 있다는 것입니다. 그리고 특정 종류의 메타 프로그래밍 지원이 필요하다는 것을 깨닫기 위해 언어 디자인위원회가 필요하지 않으며, 오늘 업무를 수행 할 수 있도록 서둘러 제공하십시오.
흥미로운 교훈은 이러한 기계가 코드에서 문제가있는 위치에 집중할 수 있도록 강력한 프로그램 분석 (기호 테이블, 제어 및 데이터 흐름 분석 등) 지원이 필요하므로 메타 프로그래밍 기계가 해당 지점에서 작업을 수행 할 수 있다는 것입니다. 이것의 약한 종류의 예는 "이와 같은 장소에서 변경"이라고 말하는 측면의 포인트 컷 사양입니다).
OP는 메타 프로그래밍이 적용된 구체적인 예를 물었습니다. 우리는 "메타"-메타 프로그래밍 도구 ( DMS 소프트웨어 리엔지니어링 툴킷 )를 사용하여 대규모 코드 기반 에서 다음 작업을 자동으로 수행했습니다.
- 언어 마이그레이션
- 테스트 커버리지 및 프로파일 러 구현
- 클론 감지 구현
- 대규모 아키텍처 리엔지니어링
- 공장 제어를위한 코드 생성
- 임베디드 네트워크 컨트롤러의 SOA 화
- 메인 프레임 소프트웨어를위한 아키텍처 추출
- 배열 계산에서 벡터 SIMD 명령어 생성
- 개념으로 돌아가는 코드 리버스 엔지니어링
Java, C #, C ++, PHP 등 다양한 언어로
OP는 또한 "왜 이것이 대안보다 나은가?"라고 물었다. 대답은 규모, 시간 및 정확성과 관련이 있습니다.
대규모 애플리케이션의 경우 코드베이스의 크기가 너무 커서 이러한 분석이나 변경을 직접 수행 할 수있는 리소스 나 시간이 없습니다.
코드 생성 또는 최적화 작업의 경우 수동으로 수행 할 수 있지만 도구는 훨씬 빠르고 정확하게 수행 할 수 있습니다.
본질적으로 이러한 도구는 인간이 할 수없는 일을합니다.
도구에는 창의성이 없다는 점은 주목할 가치가 있습니다. 예를 들어 작업이 무엇인지 결정하고 (예를 들어 위의 목록 참조) 효과를 달성하기 위해 분석 / 변환을 정의하는 방법을 결정하는 등의 작업을 수행하려면 여전히 사람이 필요합니다. 여전히 메타 프로그래머 가 필요합니다 . 그러나 메타 프로그래머가 올바른 지식으로 이러한 도구를 준비하면 결과 코드는 놀랍도록 빠르고 창의적인 전문 코더가 빌드하는 것처럼 보일 수 있습니다.
저는 서로 다른 API 간의 브리징을 위해 메타 프로그래밍을 가장 많이 사용했습니다.
작동하는 예제는 JavaScript에 노출되는 C ++ 클래스 작성을 용이하게하는 FireBreaths 1 입니다. 노출 될 함수에 대한 등록 기능을 제공함으로써 인수 유형을 검사 할 수 있으며 컴파일시 생성 된 피팅 코드에서 스크립트 API 유형에서 네이티브 C ++ 유형으로 변환 한 후 다시 . 등JSAPIAuto
map
vector
간단한 예로서 add(a, b)
몇 가지 스크립팅 API 유형을 사용 하는 노출 된 함수를 고려하십시오 .
ScriptVariant add(const std::vector<ScriptVariant>& values) {
// have to check argument count
if(values.size() != 2)
throw script_error("wrong number of arguments");
try {
// have to convert from scripting-API types
long a = values[0].convert_cast<long>();
long b = values[0].convert_cast<long>();
return a+b; // potentially need to convert back too
} catch(ScriptVariant::bad_cast& e) {
// need to handle conversion failure
throw script_error("conversion failed :(");
}
}
거기에 묻혀있는 실제 로직은 단 하나의 라인으로, 확인과 변환은 성 가시고 중복됩니다. 이전에 언급 한 등록 기능 (예 : 생성자에서) :
registerMethod("add", make_method(this, &MyClass::add));
이제 간단히 다음과 같이 작성할 수 있습니다.
long add(long a, long b) {
return a+b;
}
... 프레임 워크가 필요한 코드를 생성합니다.
1 : 구현을 조금만 할지라도 ... 더 깨끗하게 ... 다시 시작해야한다면
최근 (지난 6 개월) 코드 생성의 구체적인 예 :
다른 SQL Plus 스크립트를 생성하고 실행하는 SQL Plus 스크립트가 있습니다. 생성 스크립트는 타임 스탬프 필드가있는 일부 테이블에 대해 쿼리를 실행하며 스크립트를 디자인 할 때 선택할 시간 창을 알 수 없었습니다. 따라서 기본 스크립트는 작업을 수행하고 하위 스크립트에 필요한 시간 범위를 파악합니다. 그런 다음 파일에 코드를 작성하고 실제 시작 및 종료 시간을 자리 표시 자로 대체하여 첨자를 생성합니다. 마지막으로 첨자를 실행합니다. 하위 단계의 구조가 이전 단계의 결과에 따라 달라지는 몇 가지 상황에 대해이 트릭을 사용했습니다 (이보다 종종 더 복잡하지만).
한때 XSD에서 데이터베이스의 테이블 열로 요소를 매핑하는 스프레드 시트를 받았습니다. 매크로와 VBA를 사용하여 스프레드 시트에서 XSL 스 니펫을 생성하고 쿼리를 완료 할 수있었습니다. 이러한 스 니펫과 쿼리는이를 실행하고 결과를 처리 한 시스템에 복사하여 붙여 넣었습니다 (대부분 변경이 필요하지 않은 그대로). 좋은 해결책은 아니지만 그것은 확실히 매우 지루한 작업을 훨씬 덜 지루하게 만들었고 그 결과로 생긴 코드는 아마도 일주일 또는 두 주를 모두 손으로 작성하는 것보다 훨씬 일관되게 보입니다.
그래서 메타 프로그래밍의 예 목록 : C ++에서 본 메타 프로그래밍의 가장 멋진 예는 무엇입니까?
I can give my own specific example: I am developing ABSE, which is a meta-programming approach. With ABSE you create a model (actually, a tree) where each item is an "Atom". This Atom represents a "concept" and contains the necessary meta-data for its definition.
In ABSE, the implementation of a concept is actually a "mini-program".
Then, the host modeler (AtomWeaver, developed alongside ABSE) takes the model and "weaves" a generator program out of all its Atoms. That program is then run, generating the desired artifacts (source code, data, etc).
So, the ABSE workflow is:
- Create a discrete concept (a fraction of the meta-metaprogram)
- Reuse that concept in a model (effectively building the metaprogram)
- Host modeler weaves and runs the metaprogram
- The metaprogram generates your final program
At first sight this looks like a lot of redundant, complex work, but it is actually quite straightforward if you grasp the concept.
Advantages of meta-programming (not exclusive to ABSE)?:
- Changing the model and regenerating a complete system (Imagine refactoring features instead of source lines).
- Changing a few definitions in the model can result in distinct programs (a Software Product Family).
- By reusing templates, you can change the template's code, regenerate and get your code changed in dozens, hundreds of places.
- Many others, really
Metaprogramming, code generation, program transformation are new exciting worlds in software development, IMHO. However, metaprogramming requires a new skill: meta-thinking.
We can define meta-thinking as "thinking about how you think about your own development". A kind of class reflection, applied on yourself. In practice, you must find out your own development patterns, isolate them, make them generic, and then turn them into metaprograms using your favorite technique, being it ABSE, DSL's, DSM, etc.
Metaprogramming based libraries/code help write directly explicit and simple code that will generate implementation details code for you, depending on parameters used.
Boost is full of (C++) libraries that demonstrate what can be achieved with metaprogramming. Some good (and maybe hard to understand) examples are Proto that allow implementation of DSL, Spirit that allow to write a compiler using EBNF grammar directly inside the code, and many other blow-minding libraries.
I'll try to explain my concrete example of using meta programming techniques.
I've created a program tool which will generate ASP.NET web page source code from any MS Access data entry form. The technique that I used was to create my own ASP.NET text templates for each type of form control. I simply plugged in the values such as TOP, LEFT, HEIGHT, WIDTH, CONTROLSOURCE from the MS Access form objects meta data. For example, my template for an ASP.NET text box looks like this:
<asp:TextBox ID="**ID**" runat="server" style="z-index: 1; left: **LL**px; top: **TOP**px; position: absolute" Text='<%# Bind("[**CTLSOURCE**]") %>' />
after getting the textbox control meta data values, my program generates the code for the text box
<asp:TextBox ID="txtCustomerID" runat="server" style="z-index: 1; left: 50px; top: 240px; position: absolute" Text='<%# Bind("[CustomerID]") %>' />
My program generates the entire web page source code for one MS Access form in 2-3 seconds.The alternative is to code by hand the ASP.NET web page from scratch; a task that could potentially take hours or even days.
Imagine an MS Access database with 24-35 forms. To hand code each and every form as an ASP.NET web page source code could take weeks if not months. Using a conversion tool with meta programming techniques , in this case, reduces development time for the web pages from weeks and months to hours .
A specific example of where it could be a useful approach.
You have a set of third-party classes, to which you want to add generic behaviour - for example some kind of security/access control, mapping out objects as JSON, etc.
You could write or generate sub-classes for everything, adding wrapper methods to add in access control and call the superclass. With meta-programming, you can do that at runtime, and also your changes will be automatically applied to any additional / changed third party classes.
With the JSON example, by using introspection of the class you should be able to generate the code to serialise an object, and then add this as a method to the class. The other extremes would be generating or writing the code upfront (before compilation) and impacting every time the class changes, or a completely generic approach that used introspection on each individual object, each time you wanted to map it.
Depending on the language and runtime in question, a metaprogamming approach is likely to be faster than the wholly generic/introspective one, but slower that upfront code, as you have reduced a lot of data lookups into code.
Where meta-programming doesn't exist directly in a language, it also seems to me that it is often re-invented through frameworks (i.e. IoC style containers like Spring).
Start your Visual Studio (Eclipse, Netbeans, whatever else). Create a new project. Surprise - you've just used some metaprogramming, by creating a project from a template. Isn't it practical?
You could look at Common Lisp's macros or C++'s templates and see how they're used. Both are metaprogramming in the sense you're using. You'll find that both are used heavily in a lot of code.
Lisp macros are often used to redefine the language. As an example, the last chapter of Paul Graham's On Lisp creates an working object-oriented extension for Common Lisp. Another example is the now-defunct Garnet.
The old Standard Template Library for C++ (mostly incorporated in the standard library) was a way of introducing a large number of containers and algorithms that worked as if they were built into the language, at least in terms of integration and efficiency (not syntactically).
We use meta-programming a lot to create properties in VBA. We have various Excel spreadsheets with many headers on them and we want to define getter/setter properties for each header, allowing us to manipulate cells under that header. Manually doing this would be a nightmare.
The meta programming framework of choice for us was Notepad++ and its find/replace regular expressions capabilities. Here is how we meta-programmed our properties:
- Copy a list of headers from Excel to Notepad++
- Record a Notepad++ macro to clean up the data (remove whitespaces and special characters). At the end of this we have a list of newline separated strings.
- Manually copy the list to another .CSV file and use Excel to generate a list of line numbers. Then copy back to Notepad++.
- Write a regex to convert a property name into a property definition, adding all the whitespace, keywords etc. Use the line number as the column number in our property definition.
At the end of this we have a process that's a mixture of manual steps, recorded macros and a regex that we can re-apply every time we want properties for a sheet. And we did! To great effect.
That's the power of meta-programming. When to use it is a matter of experience/intuition. But I recommend answering this question:
Will if be quicker for me to just code this directly, or can I automate some/all of the process, and speed up my process?
That gives you a line to draw beyond which meta-programming is no longer useful. If you can just code it quicker, even if it's 10 repetitions, just do it! Only if it's hundreds of repetitions, or it's something you expect to reuse many times in future then meta program it.
Another point is that there are degrees here. I once wrote a Java program to create a bunch of files for adding a new IntelliJ inspection to an inspections coding project. That was a fair bit of overhead: creating the Java project and compiling it etc. On the other hand, Notepad++ find/replace is just a tiny step above manually typing stuff yourself. The advice here is to start doing things manually and then automate as you see a need, only up to the point where it makes sense. No need for a Java program when Notepad++ will do. No need for Notepad++ when manually typing it will do.
참고URL : https://stackoverflow.com/questions/3468246/whats-the-use-of-metaprogramming
'program tip' 카테고리의 다른 글
코드 프리젠 테이션에 적합한 글꼴? (0) | 2020.11.04 |
---|---|
System.Drawing.Image를 C # 스트리밍 (0) | 2020.11.04 |
문자열을 여는 파일 경로로 사용하는 C ++ ifstream 오류. (0) | 2020.11.04 |
경로의 대상에 파일을 생성하지 않고 Python에서 경로가 유효한지 확인하십시오. (0) | 2020.11.04 |
commons httpclient-GET / POST 요청에 쿼리 문자열 매개 변수 추가 (0) | 2020.11.04 |