Steven Schveighoffer wrote:
> On Wed, 30 May 2012 11:47:34 -0400, Jens Mueller
> <jens.k.muel...@gmx.de> wrote:
> 
> >Steven Schveighoffer wrote:
> 
> >>case 2:
> >>
> >>int main(string[] args)
> >>{
> >>   writeln(invert(to!double(args[1])); // clearly a catchable error
> >>}
> >
> >This should be
> >int main(string[] args)
> >{
> >   auto arg = to!double(args[1]);
> >   enforce(arg != 0);
> >   writeln(invert(arg));
> >}
> >
> >The enforce is needed because args[1] is user input. If the programmer
> >controlled the value of arg and believes arg != 0 always holds then no
> >enforce would be needed.
> >
> >Doesn't this make sense?
> 
> Yes and no.  Yes, the ultimate result of what you wrote is the
> desired functionality.  But no, I don't think you have properly
> solved the problem.
> 
> Consider that user data, or environment data, can come from
> anywhere, and at any time.  Consider also that you have decoupled
> the function parameter validation from the function itself!
> Ideally, invert should be the one deciding whether the original data
> is valid or not.  In order to write correct code, I must "know" what
> the contents of invert are as the writer of main.  I'd rather do
> something like:
> 
> int main(string[] args)
> {
>    auto argToInvert = to!double(args[1]);
>    validateInvertArgs(argToInvert); // uses enforce
>    invert(argToInvert);
> }
> 
> Note that even *this* isn't ideal, because now the author of invert
> has to write and maintain a separate function for validating its
> arguments, even though invert is *already* validating its arguments.
> 
> It's almost as if, I want to re-use the same code inside invert that
> validates its arguments, but use a different mechanism to flag an
> error, depending on the source of the arguments.
> 
> It can get even more tricky, if say a function has two parameters,
> and one is hard-coded and the other comes from user input.

Why should invert validate its arguments? invert just states if the
input has this and that property, then I will return the inverse of the
argument. And it makes sure that its assumptions actually hold. And
these assumption are that fundamental that failing to verify these is an
error.
Why should it do more than that? Actually, it can't do more than that
because it does not know what to do. Assuming the user passed 0 then
different recovery approaches are possible.

> >PS
> >For the record, I think (like most) that Errors should like Exceptions
> >work with scope, etc. The only arguments against is the theoretical
> >possibility of causing more damage while cleaning up. I say theoretical
> >because there was no practical example given. It seems that it may cause
> >more damage but it does not need to. Of course, if damage happens it's
> >the programmers fault but it's also the programmer's fault if he does
> >not try to do a graceful shutdown, i.e. closing sockets, sending a crash
> >report, or similar.
> 
> Indeed, it's all up to the programmer to handle the situation
> properly.  If an assert occurs, the program may be already in an
> invalid state, and *trying to save* files or close/flush databases
> may corrupt the data.
> 
> My point is, it's impossible for the runtime to know that your code
> is properly handling the error or not, and that running all the
> finally/scope blocks will not be worse than not doing it.

I thought this is the only argument for not executing finally/scope
blocks. Because running these in case of an Error may actually be worse
than not running them. Not that we have an example of such code but
that's the theoretical issue brought up against executing finally/scope
in case of an Error.

Jens

Reply via email to