Topic: Code templates


Author: Michiel.Salters@logicacmg.com (Michiel Salters)
Date: Mon, 19 Apr 2004 17:35:18 +0000 (UTC)
Raw View
pierrebai@hotmail.com (Pierre Baillargeon) wrote in message news:<6df0c6a8.0404150612.3fde33bd@posting.google.com>...
> I don't see why the name lookup would be any different from what it
> already is for other type of templates. There may be a slight
> difference since local variable of enclosing scopes would be visible,
> while other template are shielded from such entity.

The name lookup would be different, since the names in your proposal
would be passed to the template in the {CODE} block. These names
are probably dependent names? They obviously depend on the "template
parameter". Yet such names aren't covered currently by the standard.

I'm afraid I don't understand what you mean by 'local variables of
enclosing scopes' as there are at least three relevant scopes; the
template definition, the scope of the template parameter code, and
finally any scope where this template is instantiated. Of course,
you have an issue if the template meaning depends too closely
on the point of instantiation. Would it be the same class if a name
in the template inds to another variable from the enclosing scope?
If not, you'll run into ODR violations.

> As for your third point, it only covers one example of usage and does
> not work when the context must be accessed or be manipulated. It is
> also annoying to have to write a function for a small code snippet
> that has no reuse value, especially if the code access private member
> variables, requiring a change to the class declaration to add that new
> member function.

You can of course change the context; in the calling context one can
simply pass that context to the called code as a parameter. Use
pass-by-reference, and one can even update it. Templates should
define clear requirements on their arguments - see "concepts" -
and letting arguments access anything by name is rather unacceptable.
This would mean the template author cannot change its implementation,
ever, because the included code can depend on any detail. By using a
well-defined interface, the template author can replace a member
X by a pair getX/setX without forcing a rewrite in the calling code.

> Remember that the goal was to get rid of macros, which are used
> precisely in the case where context is everything, preventing the use
> of a function.

And the problem with macros is exactly that they pull in the context
without specifying which parts they need, and therefore they are very
brittle.

Regards,
Michiel Salters

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pierrebai@hotmail.com (Pierre Baillargeon)
Date: Tue, 20 Apr 2004 20:52:17 +0000 (UTC)
Raw View
For the name dependancy, yes, all names that can leak in or from the
context would be dependant. We *want* to be able to have effects both
ways: the template on the code block, the code block on the enclosing
templates.

My intention was to have the templated code (what I assume you call
the template) *not* be dependant of the instantiation context, but the
code block passed to it obviously is dependant of the context and is,
actually, the way to pass instantion-local data back to the template!
for example:

template<{} CODE> AssignToGlobal
{
   extern int foo;
   CODE // CODE can access and modify foo!
}

As for passing context as a reference to a function used in a
template, I consider this to be kludgey and burdensome to use. How
much code have you ever seen using that? The only code resembling this
I've seen are callbacks for UI or observers. Not for macro-like usage.

Finally, the problems with pre-processor macro the proposal intended
to solve are outlined in the original post. They were:

- Many useful C++ language constructs are not available in macros.
- It doesn't knows about instantiation context, namespace, etc.

The only times I've had problem with macros is when the name they
choose are so general (and scope indepedant) that they wreak havoc in
code, with with error message do to the nature of the pre-processor.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Michiel.Salters@logicacmg.com (Michiel Salters)
Date: Wed, 21 Apr 2004 15:07:02 +0000 (UTC)
Raw View
pierrebai@hotmail.com (Pierre Baillargeon) wrote in message news:<6df0c6a8.0404200945.36b2d591@posting.google.com>...
> For the name dependancy, yes, all names that can leak in or from the
> context would be dependant. We *want* to be able to have effects both
> ways: the template on the code block, the code block on the enclosing
> templates.
>
> My intention was to have the templated code (what I assume you call
> the template) *not* be dependant of the instantiation context, but the
> code block passed to it obviously is dependant of the context and is,
> actually, the way to pass instantion-local data back to the template!

I have to conclude that name lookup unfortunately is not well enough
specified for me to accept this as a future extension. I also note
a lack of interest from other parties, so I suggest to drop this
particular template form.

Regards,
Michiel Salters

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Michiel.Salters@logicacmg.com (Michiel Salters)
Date: Thu, 15 Apr 2004 00:37:50 +0000 (UTC)
Raw View
pierrebai@hotmail.com (Pierre Baillargeon) wrote in message news:<6df0c6a8.0404130612.4547fcf9@posting.google.com>...
[ disadvantages of preprocessor ]
> What would be useful would be code templates. Like other templates, it
> would provide a reusable entity that knwos about contexts. What i have
> in mind is to add  "{}" in addition to "typename", "class", etc to the
> possible template parameter types. Example:
>
> [snippet]
>
> template < {} CODE > ReportAllExceptions
> {
>    try
>    {
>       CODE
>    }
>    catch ( my::exception & ex )
>    {
>       my::report( ex );
>    }
..

The proposal is certainly implementable by current compilers. However,
I have three questions. The first is name lookup. This is already hairy
enough, a viable proposal must detail how the name lookup would happen
-  especially the two-phase lookup. The second is the interaction with
export. The third is what this buys you over

template < void(*FUNC)(void) >
{
    try
    {
       FUNC();
    }
    catch ( my::exception & ex )
    {
       my::report( ex );
    }
..

Regards,
Michiel Salters

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pierrebai@hotmail.com (Pierre Baillargeon)
Date: Thu, 15 Apr 2004 17:10:20 +0000 (UTC)
Raw View
I don't see why the name lookup would be any different from what it
already is for other type of templates. There may be a slight
difference since local variable of enclosing scopes would be visible,
while other template are shielded from such entity.

I don't have experience on export, so I won't comment on it much
further than to say that, as I understand it, the current situation
pretty much requires keeping a pre-parsed tree, which should fit well
with the proposal.

As for your third point, it only covers one example of usage and does
not work when the context must be accessed or be manipulated. It is
also annoying to have to write a function for a small code snippet
that has no reuse value, especially if the code access private member
variables, requiring a change to the class declaration to add that new
member function.

Remember that the goal was to get rid of macros, which are used
precisely in the case where context is everything, preventing the use
of a function.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: pierrebai@hotmail.com (Pierre Baillargeon)
Date: Tue, 13 Apr 2004 15:01:44 +0000 (UTC)
Raw View
One very useful thing still missing in C++ is proper macros. The
current situation with the preprocessor is ugly, dangerous and
error-prone:

- it's a preprocessor entity, meaning that many useful language
constructs are not available.

- It requires line continuations to declare complex macros.

- It doesn't knows about instantiation context, namespace, etc.

- Due to the above and other consideration, it can have unintended
consequences.


What would be useful would be code templates. Like other templates, it
would provide a reusable entity that knwos about contexts. What i have
in mind is to add  "{}" in addition to "typename", "class", etc to the
possible template parameter types. Example:

[snippet]

template < {} CODE > ReportAllExceptions
{
   try
   {
      CODE
   }
   catch ( my::exception & ex )
   {
      my::report( ex );
   }
   catch ( std::exception & ex )
   {
      my::report( ex );
   }
   catch ( ... )
   {
      my::report_bug();
   }
}

[end snippet]

Which would be used like this:

[snippet]

void foo()
{
   ReportAllExceptions
   {
      bar();
   }
}

[end snippet]

Where the {} after the template name enclose the code to be used in
the template. Of course, other template parameter types can be used
with the code type:

[snippet]

template < class EX, {} CODE > ReportException
{
   try
   {
      CODE
   }
   catch ( EX & ex )
   {
      my::report( ex );
   }
}

[end snippet]


Note that any C++ construct would be acceptable, and that code
template could be used anywhere, not just in functions. For example:

[snippet]

template < {} CODE > Initialize
{
   namespace
   {
      ReportAllExceptions
      {
         CODE
      }
   }
}

[end snippet]

Note the usage of the namespace keyword, which makes this template
usable only where an anonymous namespace is used, and the usage of
another template in the template.

One important point: the {} in the code template definition and code
template parameter are only delimiters and are not part of the
instantiated code. This allows more flexibility in the template
definition and template instantiation. Simply using a nested {} pair
in both cases allows scoping if required.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]