@@ -62,7 +62,7 @@ Follow your language's naming conventions
62
62
-----------------------------------------
63
63
64
64
Every 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:
66
66
** make sure to use your language's proposed naming convention, if there exists
67
67
one.**
68
68
@@ -140,9 +140,23 @@ format your code. You don't want to have something like the aforementioned
140
140
[ GFM ] : https://help.github.com/articles/github-flavored-markdown/
141
141
[ ragged ] : https://en.wikipedia.org/wiki/Typographic_alignment
142
142
143
+
143
144
Use the proper types whenever possible
144
145
--------------------------------------
145
146
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
+
146
160
Have a look at the following function:
147
161
148
162
``` java
@@ -185,6 +199,78 @@ the argument a string, or the return value. But use those strings with care. If
185
199
possible, use the proper type and avoid string, unless it leads to convoluted code.
186
200
187
201
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
+
188
274
Use the preloaded section only for helpers or constraints
189
275
---------------------------------------------------------
190
276
The preloaded code is both usable by you and the user. It's the perfect place to
0 commit comments