Thread: [pygccxml-development] [FT] small issue
Brought to you by:
mbaas,
roman_yakovenko
From: Roman Y. <rom...@gm...> - 2006-09-24 18:45:44
|
Hi Matthias. Next code is cut-and-paste from creator_t.visit_member_function required_headers = getattr(fwrapper, "get_required_headers", lambda : [])() This code is problematic for next reasons: 1. When we talked about [FT], we thought that user will be able to add custom function transformation, without understanding of code creators, right? I think, that putting "get_required_headers" on code creator is a little bit problematic. 2. There is small design violation: creator_t should not talk to code creators. creator_t is a factory. As such it should ask for required headers from function transformation. 3. I don't "getattr(fwrapper, "get_required_headers", lambda : [])()" this code. In my opinion if you right such code, it means that there is a problem with the design and I think this is true in our case. The solution to the problem is to introduce base class for all transformations and a class that aggregates all these transformations. I don't understand why you don't want to introduce these classes? -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Matthias B. <ba...@ir...> - 2006-09-24 20:50:48
|
Roman Yakovenko wrote: > Hi Matthias. Next code is cut-and-paste from creator_t.visit_member_function > > required_headers = getattr(fwrapper, "get_required_headers", lambda : [])() > > This code is problematic for next reasons: > > 1. When we talked about [FT], we thought that user will be able to add > custom > function transformation, without understanding of code creators, right? > I think, that putting "get_required_headers" on code creator is a > little bit problematic. (This point didn't contain any reason why the above code is problematic, you just say that you think it is problematic...?) > 2. There is small design violation: creator_t should not talk to code > creators. > creator_t is a factory. As such it should ask for required headers from > function transformation. I was asking about that in an earlier mail: Roman Yakovenko wrote: >> The responsibility of a code creator object is to create a piece of C++ >> source code that will be written into one or more output files, right? >> Now my actual question probably boils down to the following question: >> Whose responsibility is it to make sure that the code that was generated >> by a particular code creator object can also be compiled without errors? > > File writer + code creator. File writer answer the question: where to > put the > code, while code creator "what code to put". creator_t defines > "logical" place of the code creator, by placing it in the right place > within the tree. File writers insure that the "logical" > place of code creator is preserved. I interpret this as it is the code creator's responsibility to make sure that the code it generates can be compiled. This means that if the code creator generates code that requires a particular header file it must make sure that this header file gets included. And because there's no way for a code creator to do that directly, I did it indirectly by providing a method that returns the required header files (which then have to be added by whoever is in the position to do so, I decided for the visit_member_function method). Your suggestion to have a transformation group object that returns a list of header files would be less flexible than the above. The transformers only add code to a function but they do not know the entire function and as such they cannot know about the requirements of code that was not added by themselves. Have a look at the current code, the code creator for transformed virtual functions requests the gil guard header file because it may create code that uses this header. This code is not handled by a function transformer, so a transformer group couldn't know about that. So how does the current design deal with the problem that a code creator might generate code that requires a particular header file? - Matthias - |
From: Roman Y. <rom...@gm...> - 2006-09-25 06:16:47
|
On 9/24/06, Matthias Baas <ba...@ir...> wrote: > Roman Yakovenko wrote: > > Hi Matthias. Next code is cut-and-paste from creator_t.visit_member_function > > > > required_headers = getattr(fwrapper, "get_required_headers", lambda : [])() > > > > This code is problematic for next reasons: > > > > 1. When we talked about [FT], we thought that user will be able to add > > custom > > function transformation, without understanding of code creators, right? > > I think, that putting "get_required_headers" on code creator is a > > little bit problematic. > > (This point didn't contain any reason why the above code is problematic, > you just say that you think it is problematic...?) Because when user will try to add new transformation, he will need to understand code creators, this is not what we want. > > 2. There is small design violation: creator_t should not talk to code > > creators. > > creator_t is a factory. As such it should ask for required headers from > > function transformation. > > I was asking about that in an earlier mail: > > Roman Yakovenko wrote: > >> The responsibility of a code creator object is to create a piece of C++ > >> source code that will be written into one or more output files, right? > >> Now my actual question probably boils down to the following question: > >> Whose responsibility is it to make sure that the code that was generated > >> by a particular code creator object can also be compiled without errors? > > > > File writer + code creator. File writer answer the question: where to > > put the > > code, while code creator "what code to put". creator_t defines > > "logical" place of the code creator, by placing it in the right place > > within the tree. File writers insure that the "logical" > > place of code creator is preserved. > > I interpret this as it is the code creator's responsibility to make sure > that the code it generates can be compiled. > This means that if the code > creator generates code that requires a particular header file it must > make sure that this header file gets included. This is a mistake! You are assigning too much responicibilites to code creators. Code creator in only responcible to generate valid code, the one that could be compiled if you put it in a right "environment". > And because there's no > way for a code creator to do that directly, This is by design. > I did it indirectly by > providing a method that returns the required header files (which then > have to be added by whoever is in the position to do so, I decided for > the visit_member_function method). This is a mistake. Factory design pattern does not work this way. > Your suggestion to have a transformation group object that returns a > list of header files would be less flexible than the above. The > transformers only add code to a function but they do not know the entire > function and as such they cannot know about the requirements of code > that was not added by themselves. Yes, but they will report only their parts and "transformation group object" will remove a duplicated items. > Have a look at the current code, the code creator for transformed > virtual functions requests the gil guard header file because it may > create code that uses this header. This code is not handled by a > function transformer, so a transformer group couldn't know about that. This is because you decided that "thread safe" is not function transformation but something else. You did not defined what it is. From my point of view "thread safe" is do function transformation. This is a special case for Py++ and it should deal with it. > So how does the current design deal with the problem that a code creator > might generate code that requires a particular header file? Very very simple - all this information creator_t takes from decl_wrappers classes. I will try to explain the architecture one more time. We are talking about complex code generator. Every class or package share some logic with others, but they don't share the details. Every package defines it's own details: decl_wrappers - does not have details at all. This is because this package is "one big interface" code creators - the details are "how piece of code will look like" For example: decl_wrappers.class_t knows that when user expose some class it could set HeldType, so it has "held_type" property. But this class does not know where the actual held type will be generated. Another example: array member variable. creator_t knows that the way to export array is to use array_1_registrator_t creator. It also knows that in order to use, it have to "include" __array_1.pypp.hpp header. But the creator_t has 0 ( zero ) knowledge how the generated code will look like. I hope this will help you better understand the design. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Matthias B. <ba...@ir...> - 2006-09-25 10:17:14
|
Roman Yakovenko wrote: > Because when user will try to add new transformation, he will need to > understand code creators Why do you think this is the case? It's not. If a transformer creates code that requires a particular header, it has to declare so by calling the require_header() method on the corresponding code manager object. >> So how does the current design deal with the problem that a code creator >> might generate code that requires a particular header file? > > Very very simple - all this information creator_t takes from > decl_wrappers classes. Could you provide an explanation using the following example scenario: A user implements a custom code creator in his generation script. The code creator can be parameterized and can produce slightly different code depending on those parameters. Each code variation has its own set of required header files, some of which are written by the user, some are part of the project he's creating wrappers for and some might be from the Py++ code repository. After the Py++ code creator tree has been built, the user adds several of his custom creators at appropriate places into the tree. Now the question is, what else has to be done to include the required header files and who's actually including them? And where do the decl_wrapper classes come into play here? - Matthias - |
From: Roman Y. <rom...@gm...> - 2006-09-25 10:39:08
|
On 9/25/06, Matthias Baas <ba...@ir...> wrote: > Roman Yakovenko wrote: > > Because when user will try to add new transformation, he will need to > > understand code creators > > Why do you think this is the case? It's not. If a transformer creates > code that requires a particular header, it has to declare so by calling > the require_header() method on the corresponding code manager object. Why creator_t can not ask the code manager required headers? > >> So how does the current design deal with the problem that a code creator > >> might generate code that requires a particular header file? > > > > Very very simple - all this information creator_t takes from > > decl_wrappers classes. > > Could you provide an explanation using the following example scenario: > > A user implements a custom code creator in his generation script. The > code creator can be parameterized and can produce slightly different > code depending on those parameters. Each code variation has its own set > of required header files, some of which are written by the user, some > are part of the project he's creating wrappers for and some might be > from the Py++ code repository. > After the Py++ code creator tree has been built, the user adds several > of his custom creators at appropriate places into the tree. > > Now the question is, what else has to be done to include the required > header files and who's actually including them? User should modify the code creators tree and add "include" creators to it. Now, how he finds out what "include"s are needed is up to him. He is free to implement this as he wants. This is because he implements this functionality "out of the factory". > And where do the > decl_wrapper classes come into play here? decl_wrapper does not come into play here. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |
From: Matthias B. <ba...@ir...> - 2006-09-25 12:19:44
|
Roman Yakovenko wrote: > On 9/25/06, Matthias Baas <ba...@ir...> wrote: >> Roman Yakovenko wrote: >> > Because when user will try to add new transformation, he will need to >> > understand code creators >> >> Why do you think this is the case? It's not. If a transformer creates >> code that requires a particular header, it has to declare so by calling >> the require_header() method on the corresponding code manager object. > > Why creator_t can not ask the code manager required headers? It gets those headers via the code creator object. >> >> So how does the current design deal with the problem that a code >> creator >> >> might generate code that requires a particular header file? >> > >> > Very very simple - all this information creator_t takes from >> > decl_wrappers classes. >> >> Could you provide an explanation using the following example scenario: >> >> A user implements a custom code creator in his generation script. The >> code creator can be parameterized and can produce slightly different >> code depending on those parameters. Each code variation has its own set >> of required header files, some of which are written by the user, some >> are part of the project he's creating wrappers for and some might be >> from the Py++ code repository. >> After the Py++ code creator tree has been built, the user adds several >> of his custom creators at appropriate places into the tree. >> >> Now the question is, what else has to be done to include the required >> header files and who's actually including them? > > User should modify the code creators tree and add "include" creators to it. > Now, how he finds out what "include"s are needed is up to him. He is > free to implement this as he wants. Before, you said I'm violating the design by adding the get_required_headers() method, now you say the design doesn't specify a particular way how to obtain header files and I can do it as I want. Pardon me, but this sounds like a contradiction to me. Besides that, I regard it as a design flaw that the API doesn't handle this properly and that I have to introduce dependencies among seemingly unrelated locations in my code. In my opinion, this makes maintenance more difficult. I would have preferred a truly object-oriented/modular solution where all "information" can be kept in one place and where an object can encapsulate all its implementation details. >> And where do the decl_wrapper classes come into play here? > > decl_wrapper does not come into play here. Sorry, but that's again a contradiction to what you said above ("all this information creator_t takes from decl_wrappers classes.". It's still quoted above). - Matthias - |
From: Roman Y. <rom...@gm...> - 2006-09-25 12:34:21
|
On 9/25/06, Matthias Baas <ba...@ir...> wrote: > Before, you said I'm violating the design by adding the > get_required_headers() method, now you say the design doesn't specify a > particular way how to obtain header files and I can do it as I want. > Pardon me, but this sounds like a contradiction to me. No. User does not run it's code from the factory, you do. So you are not free to do it as you want. > Besides that, I regard it as a design flaw that the API doesn't handle > this properly and that I have to introduce dependencies among seemingly > unrelated locations in my code. This is already built-in in C++ language: #include <iostream> //200 lines bellow using namespace std; //300 lines below cout << "x"; //100 lines below cout << y; >In my opinion, this makes maintenance more difficult. I don't think so. > I would have preferred a truly object-oriented/modular > solution where all "information" can be kept in one place and where an > object can encapsulate all its implementation details. You are welcome: 1. to propose one. 2. to write a constructive critic I am pretty happy with Py++ design. > >> And where do the decl_wrapper classes come into play here? > > > > decl_wrapper does not come into play here. > > Sorry, but that's again a contradiction to what you said above ("all > this information creator_t takes from decl_wrappers classes.". It's > still quoted above). creator_t takes all information from the decl_wrappers classes. User that externally modifies the tree not. I don't see the contradiction. -- Roman Yakovenko C++ Python language binding http://www.language-binding.net/ |