Boost logo

Boost :

From: Jake Voytko (jakevoytko_at_[hidden])
Date: 2007-07-04 10:05:35


On 7/4/07, Phil Endecott <spam_from_boost_dev_at_[hidden]> wrote:
>
> Jake Voytko wrote:
> > plot_range(my_plot, data.begin(), data.end(),
> > default_functor, human_age,
> > circle,
> > orange, red,
> > 3, 10);
>
> It would be great to be able to write just 'data' in place of
> 'data.begin(), data.end()'. Is there anything stopping this?

The STL algorithm functions are used as the basis here, and it carries all
of the same benefits. First, you can select a small subset of your data if
you'd like that to be plotted (for example, plotting a single year out of
100 years of data). Second, the interface itself almost completely weeds out
noncompliant functions, as functions without iterator support won't compile,
and the error message will (usually) show on the line in the user's code
where the error is.

A minor benefit is also location of compiler errors. Looking at:

   plot(my_plot, data, ...);

Instead of giving a compiler error at the call for plot(), it would report
the error inside of plot(). That's a minor issue, as it's still relatively
clear why the error is occuring, but the line of the error is still not at
the location of the error. And granted, the iterator interface doesn't ward
this off altogether (as it's possible for functions to have a begin() and
end() that returns the same data type, but not support a ++() operator.

I hope that in typical usage it will automatically choose a plot style
> (and I would vote for allocating colours in 'resistor colour code
> order', though starting with brown is not often a popular choice).

Absolutely.. this is a worst case example, a perfectionist user who wants to
customize everything. Defaults is one of the things that I am working on
this week, and it does drastically cut down what the user has to specify.
Defaults would also be a benefit of named parameters.. users don't have to
specify values they don't want to specify.

Presumably the two functors are to extract the X and Y values from the
> object. Having 'x' and 'y' in the names would make this clear, if this
> is the case.

Noted.. I was having trouble coming up with a clear name

I would be interested to see how the various lambda
> techniques could be used to write these functors inline.

That's a good idea.

  Presumably in
> the case where the data is a sequence of numeric values the functor is
> unnecessary.

That is correct. The functors (which aren't even supported yet) are/will not
be necessary unless the user wants to do something like plot a pair<double,
human>.

  In particular, I would hope that a sequence<numeric>
> would use the index as X (starting at 0 or 1?), and the value as Y, and
> container<std::pair<numeric,numeric>> would use pair.first as X and
> pair.second as Y. Right?

The pair< , > part was correct, and I will soon support sequence containers
in the same fashion (I only started 2D support in the past week, so its
feature set is still underdeveloped)

 (There are plenty of C++ users (though not
> on this list) who would be put off by the concept of functors, and who
> would benefit from having it 'just work').

These people have the ability to just use the numeric clauses. Functor
conversion is a feature that has been suggested by a few people, so I know
that there is at least minimal demand. I included them in this example in
order to highlight another potential problem with the plot_range()
function.. needing to convert the second value of a pair< , >, but not the
first

So hopefully in many cases it reduces to:
>
> plot_range(my_plot, data);

The current signature is

  plot_range(my_plot, data.begin(), data.end(), series_title, fill_color);

but this is using the monolithic approach. I'm examining my options for the
best way to expand the utility of this function, which is why I started this
thread :). I think that at minimum, we need my_plot, data, and series_title,
because if the user wants a legend, each series has to be called something,
and requiring the user to go back and change the labels after they add a
function would be awkward.

When you do need to use more non-default parameters, I think that I
> would use a style object like this:
>
> plot_range(my_plot, data, plot_style(red, circle));
>
> Since the types for the colours and point shapes are distinct you can
> save the user from having to remember a correct order by providing
> plot_style constructors with both parameter orderings. This can extend
> to the stroke width. But there is a problem with the fill colour; what
> is that? Is it for the area under the curve? Why would you want it to
> be different from the stroke colour? - and also for the 'size'; what
> is that?, because they are not distinct.

To use a square as an example, the outline of the square is the stroke, and
the inside of the square is the fill. These elements apply to most SVG
visual objects, so I stuck with the SVG naming convention. The difference of
why you'd want it to be different than the stroke color is so that it'll
show up easier.. you can have a background color of white, a stroke color of
black, and a fill color of white, and get empty circles that represent your
data point.

Boost.Parameter does a good job when large numbers of parameters are
> unavoidable. Do check on the comprehensibility of error messages and
> the compile time increase, as these are the most common problems (IMO)
> with 'advanced' things like Boost.Parameter.

Good thinking!

Jake


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk