<HTML>
<HEAD>
<TITLE>Re: [vtk-developers] Alternatives to vtkTemplateMacro</TITLE>
</HEAD>
<BODY>
<FONT FACE="Calibri, Verdana, Helvetica, Arial"><SPAN STYLE='font-size:11pt'>Comments from the peanut gallery.<BR>
<BR>
I am perhaps the only person in the world comfortable with using vtkTemplateMacro.  What is nice about it is that you can set up whatever type of call specification you want in the functor.  The definitions here force you into a very specific type of functor.  That is fine, so long as the most common use cases are straightforward to code and read.<BR>
<BR>
The use case I am most worried about, because the use is very common, is a functor that needs to take two arrays that have the same type.  Typically this happens when you take an input array and use that data to construct an output array.  You know they are the same type because you made the output array.  To implement that right now, you have to pass one of the arrays as a field to the functor class, call the functor with the other array, and then do a type cast on the array.  I argue that this is awkward to code and read.  There should be a mechanism to define a functor that takes two typed arrays instead of one.<BR>
<BR>
Now for the difference between the two so far proposed methods (which, for simplicity, I will call Tim’s method and Brad’s method).  As usual, Brad’s solution is so clever that it takes me a long time just to understand all the cool magic things it does under the covers to make my life easier.  If I understand it correctly, the “issue” with Tim’s method is that the functor has to implement every possible type supported by the Apply method.  Even in Tim’s simple examples, the functor has to implement string versions of the function even though they are no-ops because they don’t do anything.  In Brad’s method, you can simply implement the types you feel you need to support.<BR>
<BR>
The thing I don’t like about Brad’s methods is that it adds more steps to the process.  First you have to implement the functor (much like Tim’s method), then you have to create an apply_map and tell the map all the types your functor you support (which you have pretty much already specified when you declared the functor in the first place).  I admit, mostly this is just an annoyance (remember, I like vtkTemplateMacro because all I need to do is define a templated function).  But there is also an increased potential for errors.  If you forget to (or inappropriately) define a type for a functor, then the compiler will give lots of nasty errors.  However, if you forget to specify one of the types for the apply_map, then it will silently fail, perhaps some time later in the future because you forgot to test that type.<BR>
<BR>
I think the issue of having the functor implement types it does not really support could be addressed with Tim’s method by simply offering specialized versions of Apply that only work on some subset of the possible types.  For example, a version of Apply that only downcast to numeric types would probably cover the majority of the cases.<BR>
<BR>
As far as the double dispatch is concerned, I’m not sure why you can’t implement that by having a templated functor with an internal templated functor that worked with the other type.  That is basically how you implement double dispatch with the current vtkTemplateMacro.<BR>
<BR>
-Ken<BR>
<BR>
<BR>
On 9/9/09 1:12 PM, "Brad King" <<a href="brad.king@kitware.com">brad.king@kitware.com</a>> wrote:<BR>
<BR>
</SPAN></FONT><BLOCKQUOTE><FONT FACE="Calibri, Verdana, Helvetica, Arial"><SPAN STYLE='font-size:11pt'>Hi Folks,<BR>
<BR>
The "vtkArray" hierarchy was added to VTK last year to provide<BR>
N-dimensional arrays for InfoVis and other computation.  This<BR>
wiki page describes them:<BR>
<BR>
  <a href="http://www.kitware.com/InfovisWiki/index.php/N-Way_Array_Data_Structures">http://www.kitware.com/InfovisWiki/index.php/N-Way_Array_Data_Structures</a><BR>
<BR>
Several filters already perform computation on vtkArrayData objects<BR>
(pipeline containers for vtkArray instances).<BR>
<BR>
Some filters need to be implemented in terms of vtkTypedArray<>, or<BR>
even vtkDenseArray<> or vtkSparseArray<> to be efficient.  Since the<BR>
vtkTemplateMacro only supports switching on the scalar type with raw<BR>
pointers, it is insufficient for these filters.  Currently they use<BR>
hand-crafted solutions or just work for only one array type.  For<BR>
example, vtkArrayNorm only works with vtkTypedArray<double> input.<BR>
<BR>
Tim Shead has proposed creation of an alternative dispatch mechanism<BR>
that supports more representations than just VTK_TT* raw pointers.<BR>
He also suggests using more modern C++ meta-programming techniques<BR>
(which is easier after dropping VS 6 and other troubled compilers):<BR>
<BR>
  <a href="http://www.kitware.com/InfovisWiki/index.php/N-Way_Array_Casting">http://www.kitware.com/InfovisWiki/index.php/N-Way_Array_Casting</a><BR>
<BR>
Jeff Baumes asked me to review the problem and proposed approach.<BR>
Since any alternative to vtkTemplateMacro will be of general use<BR>
to all VTK filters, we've decided to bring the discussion here to<BR>
the VTK developer's list.<BR>
<BR>
I've attached a sample program that shows one approach for runtime<BR>
dispatching to overloads selected at compile time.  It is different<BR>
than Tim's initial proposal.  An advantage shown is that no central<BR>
place (like vtkArray or vtkTemplateMacro) needs to know all the<BR>
possible types for which specialized filter implementations might<BR>
appear.<BR>
<BR>
A drawback of all above dispatch mechanisms is that they work only<BR>
for one runtime-selected type at a time.  This is a problem when<BR>
both the input and output type of a filter affect the choice of<BR>
implementation.  The problem leads to double dispatch patterns like<BR>
that seen in vtkDeepCopySwitchOnOutput in vtkDataArray.cxx with<BR>
vtkTemplateMacro.<BR>
<BR>
A better approach requires solving the "multiple dispatch", or<BR>
"multimethods" problem:<BR>
<BR>
  <a href="http://en.wikipedia.org/wiki/Multiple_dispatch">http://en.wikipedia.org/wiki/Multiple_dispatch</a><BR>
  <a href="http://www.research.att.com/~bs/multimethods.pdf">http://www.research.att.com/~bs/multimethods.pdf</a><BR>
<BR>
I briefly toyed with some ideas on library-only implementations<BR>
of multimethods in combination with overloading.  My conclusion<BR>
is that it is possible but may not be worth the complexity in<BR>
VTK for the few filters that need it.  However, new InfoVis and<BR>
other N-way array processing filters might enjoy the power.<BR>
<BR>
Comments?<BR>
-Brad<BR>
<BR>
</SPAN></FONT></BLOCKQUOTE><FONT FACE="Calibri, Verdana, Helvetica, Arial"><SPAN STYLE='font-size:11pt'><BR>
</SPAN></FONT><FONT SIZE="1"><FONT FACE="Monaco, Courier New"><SPAN STYLE='font-size:7.5pt'><BR>
   ****      Kenneth Moreland<BR>
    ***      Sandia National Laboratories<BR>
***********  <BR>
*** *** ***  email: <a href="kmorel@sandia.gov">kmorel@sandia.gov</a><BR>
**  ***  **  phone: (505) 844-8919<BR>
    ***      web:   <a href="http://www.cs.unm.edu/~kmorel">http://www.cs.unm.edu/~kmorel</a><BR>
</SPAN></FONT></FONT><FONT FACE="Calibri, Verdana, Helvetica, Arial"><SPAN STYLE='font-size:11pt'><BR>
</SPAN></FONT>
</BODY>
</HTML>