Hi, Matthias!

Thank you for your response, it made me think about my problem from another 
perspective.

I was trying to protect the application for some future ill-conceived changes 
that might cause a calling function to fail from illegal return values. 
Therefore I had "catch-all" branches in conditionals in order to throw 
exceptions in case of illegal values. The original problem was how to test 
these branches (in order to have 100% test coverage). I tried introducing some 
test parameterizations, but that introduced additional unwelcome complexity to 
the code, although it solved my original problem (kudos to Matthew Butterick 
for pointing out this possibility!).

However, as I dissected the code it became clear to me that my implementation 
had been far from clean. One of the problems was that the responsibility for 
checking return values was not in the function returning the value, but in the 
calling function.

The main thing seems to be that I need to check return values for type and also 
for range. After some refactorings I have transferred the responsibility for 
checking these values so that testing became easier. Also, It starts to look 
like typed Racket would be an appropriate solution for making the code more 
robust.

Once again, thanks for your help, it is really nice to know that there is a 
community of true experts willing to help if one stumbles on the long road to 
becoming an expert Racketeer :)

Best regards,

-Mikko

Matthias Felleisen <[email protected]> kirjoitti 11.4.2014 kello 12.44:

> 
> On Apr 3, 2014, at 8:53 PM, Mikko Tiihonen wrote:
> 
>> Hi,
>> 
>> I've spent some time on the following problem, and would like to ask for 
>> your help:
>> 
>> I'm writing a critical piece of an application, and would like to ascertain 
>> in a "belt and suspenders" kind of way that I get a customized exception if 
>> something goes wrong.
>> 
>> The approach I have used is based on independent checks (conditionals) that 
>> might trigger the exception. The problem is that I have not found an elegant 
>> way to test this code, since there should not be such combinations of 
>> parameters that could lead to this branch in the conditional. One way would 
>> be to extract these pieces of code to auxiliary functions and call these 
>> from the tests with those "impossible" parameters that would trigger the 
>> exception. However, this would split the code into ugly, detached pieces.
>> 
>> Simplified example:
>> 
>> (let ((a 2)(b 2))
>> (if (= (+ a b) 4)
>>     #t
>>     (error "impossible!")))
>> 
>> Is there some practical way to access the variable bindings inside a 
>> function from tests (similarly to the "set! <var>" pop-up menu in the 
>> debugger window) in order to inject faults to trigger these exceptions?
> 
> Mikko, I do not understand why you would want to write the code as above. If 
> you specify
> lexical variables and their initial values you don't need to test them and 
> you can prove
> to yourself that (= (+ a b) 4) will always hold. Perhaps you want to 
> construct an example
> that is closer to what you really want. 
> 
> You could pre-process the code with a debugger-like strategy so that 
> third-party code can
> inspect lexically bound variables. But the same pre-processing would expose 
> lexical variables
> for manipulation, defeating a belt-and-suspender approach. 
> 
> -- Matthias

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail

____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to