|
Boost : |
From: Jonathan Turkanis (technews_at_[hidden])
Date: 2004-09-03 21:27:42
"Rob Stewart" <stewart_at_[hidden]> wrote in message:
> From: "Jonathan Turkanis" <technews_at_[hidden]>
> > "Rob Stewart" <stewart_at_[hidden]> wrote in message
I'm sorry if I sounded argumentative in my last post.
> > > I agree with Thorsten that some means of ensuring that parts
> > > aren't assembled in the wrong order would be helpful. Whether
> > > that means separate functions, or detection of the type of object
> > > being pushed, it seems like preventing misuse should be a bigger
> > > priority than "a major simplification of the interface."
> >
> > I'm not sure I follow. You already get a runtime error if you try to add a
> > filter or resource to a chain that is already complete. This is mention in
the
> > specification for push (see http://tinyurl.com/49j6u) E.g.,
> >
> > filtering_ostream out;
> > out.push(zlib_compressor());
> > out.push(file_sink("hello.z"));
> > out.push(base64_encoder()); // error !!
> > out.push(tcp_sink(www.microsoft.com, 80)); // error !!
> >
> > Isn't this enough? (Maybe it should be an assertion failure instead of an
> > exception.)
>
> Oh, right. That's good, and is flexible for runtime assembly of
> the filters and resource.
Good.
> > Perhaps you would like a compile-time error instead. Note that having
separate
>
> Where possible, that's certainly preferable.
Agreed.
> > functions for pushing filters and resources would not help in that case. To
> > generate a compile-time error would require that the types of all the
filters
> > and resources be encoded into the type of the filtering stream. This was
> > suggested last year by Larry Evans and recently by Robert Ramey (if I
understood
> > hime correctly.)
> >
> > The problems are:
Here I summarized a bunch of stuff that wasn't directly relevant to your point.
Sorry.
> >
> > - much more complex interface
>
> This is a subjective judgment I can't evaluate due to lack of
> information.
>
> > - less flexible a runtime
>
> I can see that is a problem and I can imagine determining the
> filters to assemble at runtime, so this would be an issue.
>
> > - neglible gain in efficiency, since most filtering operations aren't
inlineable
> > Finally, it's already the programmer's responsibility to ensure that the
filters
> > are added in the right order -- no amount of template magic will guarantee
> > this -- so making sure to add the resource at the end is not much of an
extra
> > burden.
>
> You're right, and I already acknowledged (quoted below) that
> there are many places in which a programmer can hang himself.
> The flexibility of what you have in place increases runtime
> possibilities, and can be wrapped to make it safer as discussed
> below.
Okay.
> > > There are plenty of places where one can misuse existing
> > > libraries, including the Standard Library, so perhaps requiring
> > > that protection from this library is misguided. So, here's
> > > another approach: perhaps you could create a set of overloaded
> > > make_* functions that take a varying number of filter arguments
> > > followed by an optional (via overloading) resource argument.
> > > Then, those functions can ensure that if there is a resource, it
> > > is push()'d last.
Did I misunderstand you the first time around -- you're not saying the arguments
would be automatically reordered if a resource is in the middle, are you? It
would just produce an error, right?
> > Yes, that would work. There are two versions I can think of:
> >
> > 1. Orginally I had a function link(...) which created an inline chain of
filters
> > and resources, but I eliminated it to make the library smaller. It didn't
occur
> > to me to add a compile-time check that the last element was a resource; in
fact,
> > I thought it would also be useful for chaining filters alone. However, this
> > might be a good reason to restore the function link, with the added check.
>
> This is rather like using smart pointers. You can always call
> new and delete, and work with raw pointers, but it's up to you to
> guard against errors, including in the face of exceptions. When
> using smart pointers, which are wrappers around raw pointers, you
> gain safety.
So link would just be a programmer-imposed check.
> This should in no way be considered a prerequisite to acceptance
> of the library.
Good.
> > 2. Dietmar Kuehl mentioned a piping syntax originall proposed by JC van
Winkel.
> > E.g.,
> >
> > filtering_stream
> > out( base64_encoder() | zlib_compressor() | file_sink("file") );
> >
> > This syntax, too, could be modified to do a compile-time check that the last
> > item in the chain is a resource.
>
> Does it have to be a resource? Is the check actually to ensure
> that no filter follows a resource?
I guess the check should be that nothing follows a resource.
> > I like both of these ideas as a syntactic convenience but not as a way to
> > enforce at compile time that resources are added last. For this enforcement
to
> > have teeth, it would be necessary to remove the stack interface, which would
be
> > considered 'unsafe'. But the stack interface is natural and convenient, and
> > essential for some purposes.
>
> Don't do that; keep things as they are.
Good.
> > I sort of feel like I'm beating a dead horse :-) Is a runtime error (or
> > assertion failure) sufficient, or do you feel strongly that there needs to
be a
> > compile-time check?
>
> I think that what you have is fine, but that a safer means built
> atop what exists is a better approach and can be added later as
> time permits.
Got it.
Best Regards,
Jonathan
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk