@@ -62,7 +62,7 @@ Follow your language's naming conventions
6262-----------------------------------------
6363
6464Every language has its quirks. Some of them get discussed in the later sections.
65- However, there's one thing that should get mentioned at this point:
65+ However, there's one thing that should get mentioned at this point:
6666** make sure to use your language's proposed naming convention, if there exists
6767one.**
6868
@@ -140,9 +140,23 @@ format your code. You don't want to have something like the aforementioned
140140 [ GFM ] : https://help.github.com/articles/github-flavored-markdown/
141141 [ ragged ] : https://en.wikipedia.org/wiki/Typographic_alignment
142142
143+
143144Use the proper types whenever possible
144145--------------------------------------
145146
147+ Types are everywhere. Even if you use dynamic typed languages, you've at
148+ least encountered some quirks of your language, like ` "12345" + 1 ` in
149+ JavaScript, or "xy isn't a ab" in Python or Ruby.
150+
151+ There are basically two things that can go wrong with types: you can
152+ ask the user for the wrong return type, or __ you__ accidentally use
153+ the wrong type in your reference solution.
154+
155+ The second one is a lot harder to notice, so lets keep this for later.
156+ Instead let us look at one often used wrong return type first: the string.
157+
158+ ### The problem with strings
159+
146160Have a look at the following function:
147161
148162``` java
@@ -185,6 +199,78 @@ the argument a string, or the return value. But use those strings with care. If
185199possible, use the proper type and avoid string, unless it leads to convoluted code.
186200
187201
202+ ### The wrong return type
203+
204+ Even if you don't use strings, you can end up with the wrong type. Let us
205+ motivate this with an example.
206+
207+ The Fibonacci sequence is defined as follows
208+
209+ $$
210+ f_n = \begin{cases}
211+ 1 & n = 1\\
212+ 1 & n = 2\\
213+ f_{n-1} + f_{n-2} & \text{otherwise} \\
214+ \end{cases}
215+ $$
216+
217+ Now, lets say you want a user to write a function that returns arbitrary
218+ Fibonacci numbers up to ` N = 100 ` :
219+
220+ ``` c
221+ int32_t fibonacci (int8_t N);
222+ ```
223+
224+ You might already note where I'm going with this, if not, read on.
225+ Lets have a look at $f_{45}$, $f_{46}$ and $f_{47}$:
226+ $1134903170, 1836311903, 2971215073$. And if you're familiar with the bounds
227+ of signed 32bit integer numbers, you should already see the problem.
228+
229+ The number $2971215073$ cannot get represented with 32 bits (if signed integers
230+ are used), since $\log_2 (2971215073) > 31$. If you were to ask the user for
231+ $f_{50}$ (or even $N = 100$), you (and they!) end up with a wrong answer:
232+
233+ ``` c
234+ printf("f 47: %d\n", fibonacci(47));
235+ // prints -1323752223
236+ ```
237+
238+ This indicates that ` int32_t ` isn't enough for your kata. Even ` uint64_t ` isn't,
239+ since $\log_2 (f_ {100}) > 64$,
240+ so you have to switch to your languages ` BigInteger ` variant, e.g. ` BigInt ` ,
241+ ` bignum ` , ` Integer ` .
242+
243+ By the way, this particular error could have been prevented by a test that
244+ checks that every returned number is positive. Also, if you use a dynamic
245+ typed language, make sure to check the return type in one of the first tests:
246+
247+ ``` ruby
248+ Test .expect (fib(0 ) is Bignum , " Your function doesn't return a BigNum" )
249+ ```
250+
251+ ### Wrong internal types
252+
253+ This is usually a mess. Your return type is correct, and you check for the
254+ correct type, but your users complain about invalid results. This indicates
255+ that you accidentally used the wrong type somewhere in your own computation,
256+ for example ` int16_t ` in a helper function. This is __ really__ hard to spot,
257+ so you should add some static test values. More on that in the later sections.
258+
259+ ### Integral vs floating point arithmetic
260+ There's a later section on floating point numbers, but this section is also
261+ fitting for the delicate problem. As you (hopefully) know, floating point
262+ arithmetic isn't exact. The usual double value has 54 bits for its significant,
263+ which is better than ` int32_t ` , but worse than ` int64_t ` . So if you ask for an
264+ __ exact__ solution, you should ask for an integral type and also check
265+ that the user returns an integral type (in dynamic typed languages).
266+
267+ Note that JavaScript doesn't really differ between integral and floating point
268+ numbers. You can force numbers to behave as ` int32 ` (or ` uint32 ` ), but you
269+ cannot help the user with an appropriate error message in this case.
270+
271+ Also, JavaScript doesn't have a large integer class/type, so you need to
272+ improvise a little bit.
273+
188274Use the preloaded section only for helpers or constraints
189275---------------------------------------------------------
190276The preloaded code is both usable by you and the user. It's the perfect place to
0 commit comments