We start with Exercise 1.3
Define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.
Let’s write a test that will check the easiest case. We use three zeroes as arguments. The solution should be zero.
The quickest way to pass this test would be to let the function return a hardcoded zero.
Now we enter the refactoring phase. The specified function signature already breaks a clean code principle. We should avoid having more than two arguments for a function. If these three arguments all belong to each other to warrant the need to be passed together then they should be put into another construct. We will choose a list and refactor the code as follows
To get rid of the hardcoded zero we add another test.
One of the quickest ways to get the correct solution would be to just return the max value of the passed list.
apply
calls max
with the elements of the following list as arguments.
As we continue with the refactoring phase we can spot duplication in the tests. We can probably extract the following into another function
The following addition to our test-code will help us in removing the duplication, shortening the assertions and making the test more readable.
The assertions should now look as follows:
The fastest way to fail the next test now would be to pass a value whose square is not itself.
We now have to use the square
function
Now lets improve our tests. We can improve their readability and remove duplication.
I’d suggest replacing the next zero to get a failing test
The quickest way to get it to pass is just to add the second number to the solution.
There is nothing to refactor so lets write a new failing test.
Now lets sort the list by size and add the squares of the first two values.
I dislike the fact that we’re now sorting the list twice. Let’s fix it by introducing a local variable, which can be achieved with let
.
I can’t think of a test which would fail using our current implementation. We’re done.
With respect to the book you could say we have cheated, as the concept of lists, sorting or local variables is not known at this point in the book, yet. We have also not respected what the exercise, or the customer, asked for. Our function does not take three arguments. It takes one. It’s the way the tests and clean code principles have guided us.
To still achieve the requested function signature we can build a wrapper function as follows
Let’s review the finished code
If you want you can compare the solution with others.
By using the test driven approach we have covered a lot of ground which should provide you a basic understanding of Scheme.