Metaprogrammingisthewritingofcomputerprogramsthatwriteormanipulateotherprograms (orthemselves) astheirdata, orthatdopartoftheworkatcompiletimethatwouldotherwisebedonerecognition
Metaprogramming
Is the writing of computer programs
That write or manipulate other programs (or themselves) as their data,
OrThat do part of the work at compile time
That wocould otherwise be done at runtime
. In some cases, this allows programmers to minimize the number of lines of code to express a solution (hence indexing development time), or it gives programs greater flexibility to efficiently handle new situations without recompilation.
I have never touched on meta programming. I feel that "manipulate other programs (or themselves) as their data" is a bit false. Can I give some exact examples to illustrate the usage of tracing?
In addition, why do LISP and Ruby do better in meta programming than Python? Reply: If you define metaprogramming as a programming for program operations, there seems to be no reason to exclude eval from metaprogramming.
I don't think it really matter whether the compilation or runtime is the case.
Meta-programming obviously provides an abstract level, which is equivalent to allowing you not only to abstract the problem through one level, but also to abstract your problem model through another level. If it is used well, this seems to provide a huge amount of energy. However, this seems to exceed the brain operation rules of most people and is not suitable for large-scale promotion.
As for monad, if you focus on it, you can redefine it. That is, the ability to define the operation sequence can barely be considered a metaprogramming.
Digress:
Some people mentioned the REBOL above, saying that its metaprogramming is not good, and I feel obviously different. Because REBOL uses the simplest syntax as its form, this makes custom dialect very natural and intuitive, so its meta-programming is more natural and more beautiful. The introduction to Ruby metaprogramming is actually quite clear.
I suggest you read this book. I believe you can understand it. The example is good. I have not read this book yet. At hand.
By the way, we all know that "code and Data" is actually like this. The definition of metaprogramming is to write the code. quote in lisp can block the evaluation and use eval when necessary. Then, when running, operating your own code also has another meaning. It can be called dynamic metaprogramming to distinguish between the code generator and the compiler-Based Static metaprogramming. Generate various codes (classes, methods, tests, and so on) in batches to reduce repeated operations during programming. Various DSL, code generator, scalfolding, and project bootstraping all benefit from meta programming. Programming is an abstraction of solutions to certain types of problems.
Meta programming is an abstraction of some solutions.
That is to say, metaprogramming is an abstraction of programming.
As for DSL, I am not sure the same. It is true that there is a flood of DSL in the ruby circle. DSL is created for DSL, and DSL is used for the purpose of dazzle, but these are not the focus. The emergence of DSL is an inevitable result of high abstraction. a DSL that is separated from the abstraction will naturally die.
Here are some examples:
ORM
I have now N entity classes, and I need to store these object classes persistently. So I wrote N DAO. Later, I found that DAO is boring, just a few steps. I created a table based on the object class name, created database fields based on the attributes, and added, deleted, modified, and queried data. (ORM)
To solve these "similar repetitive work", we need a mechanism to convert one of my "meta program" into a specific program. This is the difference between abstract levels.
Basic steps of ORM: Determine the database table name based on the object class name, and determine the database fields based on the object class attribute. The unified insert \ delete \ find \ update method is used, data Recovery and storage are completed based on the correspondence between attributes and database fields. In java, we get the class name and database fields through reflection, and use wildcard + Integration to get insert \ delete \ find \ update and various public methods. The result is that you only need to inherit a parent class to complete DAO operations. (GitHub-satyan/sugar: Insanely easy way to work with Android Database.
Here is an example)
Syntax analysis and lexical analysis
Syntax analysis and lexical analysis are also similar but different. A typical example is lex & yacc (flex & bison), lex is a lexical analyzer, and yacc is a syntax analyzer (the wording of the "analyzer" may be somewhat less rigorous ). For lexical/syntax analysis, lex accepts a. l file, and yacc accepts a. y file. The result is generation of. c code. The use of DSL to generate code is what compilation languages do (c ++ has little knowledge, especially the new c ++ standard introduces many new features,
It is said thatAnalyzer is essentially a finite state machine. The core of a state machine should be State Division. meta programming, we can avoid "repetitive labor" for writing state machines (similar labor should be strictly speaking)
An example in Ruby metaprogramming: repeated code by the butlers
You are an ass cleaner. You take over an old equipment information system, which maintains the device information and price of each computer. The data comes from an old data source ). So you have a bunch of similar:
Ds = DataSource. new
Ds. get_mouse_info (workstation_id)
Ds. get_mouse_price (workstation_id)
Ds. get_keyboard_info (workstation_id)
Ds. get_keyboard_price (workstation_id)
There is another dozen such functions, and every component of the computer has such a function.
To work with the new report system, you need to return an encapsulated object. This object has an independent method for each part to return a string containing the description and price. Obviously, if you don't want to figure out a solution, you will struggle to copy and paste code for a long time in the future.
Every method is similar. Every method named xxx obtains information through ds. get_xxx_info, ds. get_xxx_price obtains the price, and then Concatenates the string...
Solution: for ruby, we can use the dynamic dispatch \ Dynamic Creation method, or even obtain the method of datasource by getting the introspection, and find out which components are available, then create a method for these parts. In return, you do not need to create or maintain a part list. If someone adds a new part to the DS class, your Computer class will automatically support it.
--------------------------------------------------- Discuss ------------------------------------------------------
For javascript programmers, the same mode can still be used, with inner province + dynamic addition of functions.
Py is not used much in this aspect, so it should be similar in theory.
Java is troublesome because you cannot dynamically add methods, so you can only return to the next step. Provide a part list and a String get_info (String component) function. Obtain the part list and call functions through reflection.
In addition to generating code, C seems to have no other path.
ActiveRecord
Everyone who has used it said yes. Many of its tricks and magic are implemented using metaprogramming. In principle, there are two types of Meta Programming that can be seen at present. The first one focuses on re-structuring the syntax, I .e. DSL, Lisp/Scheme, which belongs to this category. Ruby, which has won the highest rank in recent years, also belongs to this group, there are even further but relatively small REBOL languages
The second type focuses on Computing and dispatching during the compilation period to achieve automatic code selection and Optimization for specific scenarios. The C ++ template is like this. The macros of C have both, but their capabilities are weak. According to the situations I have seen, the academic school recognizes the previous one, while the latter adopts C ++ for a wider use.
I think the sentence in the question introduction is C ++, because it emphasizes do part of the work at compile time. However, I have never heard of Python Meta-programming. I have never heard of Python's ability to build a DSL since Python 1.2 was used. Let alone Meta-programming. The culture of the Python community has never been used in grammar. As a result, I checked it and said that it should be the third item: dynamic adjustment of the class structure. In essence, it is reflection ). Refer to this article on DeveloperWorks: Metaclass programming in Python
And this article: Metaprogramming
. It is not hard to see that these two articles talk about another topic. So it seems to me that the so-called Lisp and Ruby are doing better than Python in Meta-programming, because the meaning and extension of Meta-programming are different.
In actual work, no matter which kind of Meta-programming, I have a negative attitude. The reason is different from that of my previous friends. I think Meta-programming breaks a basic principle in communication: the same programming language should have the same communication habits. Constructing DSL too casually makes communication between programmers more difficult. A typical example of this is REBOL, which has obvious differences in some DSL syntaxes. The high cost of re-learning actually contributes to the split tendency of the community. If you have nothing to do, you can do it yourself. If you put it in your work, it will harm you.
As for the Meta Programming of the Lisp/Scheme family, it is not so much better to say that the syntax structure is too simple, so how to change it looks like it is. In this regard, we may wish to compare the similarities in the syntax of several DSL constructed by REBOL. However, for me, the syntax of Lisp/Scheme is actually my favorite Scheme: Compiler designers can spend more energy on runtime and optimization.
Or that sentence, we write a program to solve the problem. Abstraction and expression are means, not purposes. It is a slide in syntax. I usually don't use this thing very much, mainly because meta programming is not very powerful in my favorite language. Why is it better to say that the meta programming of LISP and Ruby is better than Python because they have the ability to "re-read their own code at compilation or runtime and then modify the re-compilation", such as the macro of LISP, for example, the method of DSL in Ruby, for example, computation expression in F #, for example, linq and Expression in C #. For example, the C ++ template (which is far-fetched), and the Haskell monad. No Python hair.
However, I don't think this function is very useful. I don't know what issues should be solved by metaprogramming, but you can talk about the application of Ruby metaprogramming:
1. Rails is fully achieved by Ruby's metaprogramming capabilities.
2. All the excellent tools emerging from the Ruby community have borrowed the power of metaprogramming.
3. In Ruby, metaprogramming is not special. It is programming.
The above is just for those answers that are not useful in Meta programming. The program and data of Lisp are based on the List, so as long as the list structure can be generated, it can be equivalent to generating code, while the real powerful macro mechanism of Lisp, it is the code expansion and evaluation during the runtime.
Almost any slightly larger Lisp program will have some code for defining macros or writing them using macros.
Ruby's metaprogramming inherits from Lisp and Smalltalk. On the one hand, you can use eval to dynamically execute code, and you can use the constructed language closure to open and close the scope. In addition, there is a very simple and introspection/reflection mechanism to judge the running state of the program, and thus assist in code generation.
The function of the template metaprogramming in C ++ is to compile the Code during the compilation period. The template is used to calculate the type and data to generate the code, so there will be a very powerful and general STL (standard template library.
To some extent, Python can still perform metaprogramming (modify metadata/data ?), Only the flexibility is not high enough, so few people use it,
The philosophical attitude of Python determines that this community will try to stay away from metaprogramming..
The exact example is Ruby's ActiveRecord. For more information, see Active Record Query Interface.
And rails/activerecord
.
The vast majority of Ruby DSL applications Metaprogramming techniques, and other books: Ruby Metaprogramming
.
If you study it in depth, the role of metaprogramming is still very great. Abstract capabilities are more than one level higher than simple code. In this case:
In the early stage of the industrial age, this is the case:
Human production machines and machine production products.
Later:
Human production machines, machine production machines, and machine production products.
Obviously, machine production is a remarkable improvement, which has greatly liberated the labor force.
Meta-programming is similar to machine production machines. Simply put, a program can change itself or generate new programs. Of course, this has greatly liberated programmers.
Of course, in fact, before metaprogramming, programmers invented a large number of auxiliary tools to help themselves program, such as IDE or something. Later, programmers thought that IDE was still too weak, so they could find and replace it and jump to reference and apply the template. If the program could make its own production, how nice it would be.
=============================== Completion of science popularization, the following are irresponsible questions =============================
In fact, meta-programming has never been a well-defined concept. It is mainly because the meaning of meta is very vague.
Meta is generally understood as more basic and basic. Meta-programming is a more basic programming than a program, that is, a Program Generation Program. From this perspective, whether it is a C ++ template, a C macro ,. NET Emit and Compiler Provider, JavaScript String concatenation and eval, and even what kind of dynamic network code generator, are all program generation programs.
However, in general, it is still necessary to satisfy certain conditions to be called meta-programming. Of course, because the concept of meta-programming is not well defined, these conditions can only be considered as consensus. The features of this language are considered as meta-programming by A, and B does not think so. The following conditions are just in my opinion:
1. A language capable of metaprogramming must be a language that can generate code in the same programming language, rather than a program that generates code in another language. In this way, the code generator is excluded.
2. Languages capable of meta-programming and program code generated by meta-programming must be capable of lexical analysis. This article excluded the macro of C and the eval of JavaScript.
......
It can be seen that, in terms of meta programming, different restrictions can be used to get different results. When we discuss whether a programming language can be metaprogrammed, condition 1 can basically reach a consensus, and condition 2 has its own views.
In other words, when metaprogramming was first generated, just to reduce the burden on programmers, the C ++ template was initially an extension of the heavy load. Due to the strong type, the C language must write a lot of repeated code for different types, and the overload solves the name pollution of these repeated code, while the generic type begins to solve the duplication of these code. But the C ++ Standards Committee obviously won't stop at generics like Anders,
High-end atmosphereC ++ has always been a relentless pursuit of C ++, so generics have been made into templates. Furthermore, when programmers get up Happy, they have played C ++ template metaprogramming.
Write it here first. metaprogramming is to write code that can generate code. With such an abstraction layer, your program will be more extensible and adapted to more unknown scenarios. Java reflection, STL templates in c ++, and various magical forwarding proxies in ruby are all metaprogramming applications. Rails is successfully built on ruby's powerful metaprogramming, Which is why rails has not chosen other languages.