Andre Merzky wrote:
Quoting [John Shalf] (Nov 02 2005):
Q5) Any comments to 4a1, 4a2 or 4a3? (not part of the Strawman!)
I prefer 4a1 because it is more readable and the
implementation would
be quite straightforward.
You favour 4a1. We think that implementation is very straight forward for all three versions. Readability seems not much different to me, and might largely be a matter of taste.
4a1 is a plain match of some flat API onto the C++ language. It bloats the exposed object surface (every function has to be there 3 or 4 times).
It is also a familiar paradigm for any MPI programmers and anyone who has played with various proprietary Async I/O implementations. (its a very familiar and conventional approach)
Well, these are C-API's. Is there a C++ binding for MPI, and does it look the same?
Frankly, I'm not a specialist here. But from what I can tell from the MPI specs the C++ bindings are more or less a complete copy of the underlying C API, which is not object oriented (but please correct me if I'm wrong).
I kind of like 4a2 as well from the standpoint of a C++ programmer (even with Andre's syntax corrections). However, the resulting bindings will not be very consistent with the approach we would take for Fortran or C bindings (eg. those would likely look more like 4a1).
But, well, that is the idea of the language binding! I agree that C and Fortran would look more like 4a1, of course. But that is no reason that C++ should look like that as well, or Java, Perl etc.
4a2 is good from the standpoint of a C++ language binding but infers non-needed objects in the interface (the sync, async and task subobjects) additionally for every API object there have to be constructed, initialised and destructed these three subobjects. I know, that performance is not an issue in the SAGA context, but I think we should avoid premature pessimisation (i.e. building on top of a obviously non-optimal solution).
It is not really much more readable than 4a1. Therefore, I'm uncertain if it is worth fragmenting our approach to bindings in different languages when there is not a clear benefit in terms of readability or implementation complexity.
I think that 4a2/4a3 actually allow nicer implementations, as it allows to have the different async parts somewhat separate from the sync parts. We think its nicer :-)
4a3 the only implementation in a C++ like manner I can think of, which provides: - an interface which conforms to modern C++ concepts pushed by Boost et.al. - it avoids not needed overhead if some of the features are not needed/used (this gets optimised away by any decent C++ compiler) - it allows for using the SAGA API classes in a generic programming context using the execution model as a (template) parameter (I can elaborate on this further if needed) - minimises the exposed interface
I do a lot of C++ programming, but I find the 4a3 option a bit obscure both in terms of readability and any advantages it might confer in terms of implementation.
Hehe - I thought the same :-) Hartmut likes that version very much. To me it appealed after pondering over it for a couple of days. Now I think it is cute, and quite expressive.
It's not a matter of cuteness, I guess. It's simply a matter of efficiency, maintainability and minimization of the exposed interface.
It would certainly be easier to create multi-language bindings for a single code base if we stick with something more conventional like 4a1.
I think that C and Fortran bindings for this part are straight forward anyway, there is no need to reflect that in C++...
Agreed. Fortran and C bindings probably will end up to be very similar. In C++ we should conform to the main C++ language paradigm (i.e. don't pay for anything you're not going to use etc.)?
Each approach is equally readable to me (less so for 4a3). I'm certainly open to any additional information on how the 4a2 and 4a3 approaches could simplify implementation.
The main point really is that the object itself has only the sync method calls, and the async calls can be put into separate header/sources easily, and build (by default) on top of the sync calls. Of course, you can do that with all three versions, but its not as obvious in 4a1.
It's not a matter of simplifying the implementation, it's a matter of simplifying the exposed interface. I even would go for a more complex implementation if the interface gets simpler. And from my experience the templated syntax isn't counterintuitive if you're used to programming in C++.
If the other approaches can offer some implementation benefits, then maybe I'd give them extra consideration, but otherwise, I would prefer a more conventional approach like 4a1.
I would vote for 4a2 or 4a3 (in that order), but 4a1 would be ok if the majority likes that most, of course. Basically its a matter of taste I think. I am happy that the general point seems accaptable to all so far: having sync, async, and task versions of the calls, w/o explicit task factory.
I kind of agree, but would prefer 4a3 because of the benfits it provides. Regards Hartmut