Debugging Type Errors in Functions
Functions can accept different data types as arguments if the function's operations are compatible with those types.
One Function, Several Types
A function is not necessarily restricted to one data type. Its compatibility with an argument depends on the operations performed inside the function. If those operations work with the supplied value, the function can accept that value. A function that prints its argument twice can therefore work with a word, an integer, or a floating-point number.
When debugging a type problem, inspect the function's operations rather than guessing from the argument's type alone.
Tracing the Parameter Binding
Consider a function named print_twice that takes one parameter named arg and prints arg two times. When the function is called with the string 'Spam', that string is bound to arg. The first print operation uses the bound string, and the second print operation uses it again. The function does not need separate behavior for strings and numbers because its operation is simply printing.
Three Calls to the Same Function
Predict what happens when print_twice is called with 'Spam', 17, and math.pi.
String call: The string 'Spam' is bound to arg. The function prints that value twice.
Integer call: The integer 17 is bound to arg. The function performs the same two print operations and prints 17 twice.
Floating-point call: The floating-point value 3.141592653589793 is bound to arg. The function prints that value twice.
All three calls work because printing supports the supplied string, integer, and floating-point values.
Operations Determine Compatibility
The function's behavior is determined by what it does with its argument, not by the argument's data type in isolation. To decide whether a type is compatible, examine every operation in the function and ask whether that operation can handle the value. For print_twice, the relevant operation is printing. Strings, integers, floats, booleans, and many other types can be printed, so they can be used with this function.
Comparing the Three Results
The three calls follow the same execution path: bind the argument to arg, print arg once, and print arg again. What changes is the value being printed. The string call produces the word twice, the integer call produces the integer twice, and the floating-point call produces the value of math.pi twice.
What do you think happens?
What should you expect when the same printing function receives a string, then an integer, then a floating-point number?
Reveal answer
Answer: Each value is printed twice
The function performs the same printing operations for each argument. The data type changes the displayed value, but not the function's behavior.
Finding the Failure Point
A type error in a function is debugged by tracing the argument through the function body. First identify the value bound to the parameter. Then inspect each operation in order. For print_twice, check whether the value can be printed. If it cannot, execution fails at the printing operation rather than because the function name or parameter automatically requires one particular type.
Assuming a function accepts only the type used in one example.
The function's operation is printing, and printing also works with integers and floating-point values.
Fix:
Inspect the operation performed on the argument and test other values that the operation can handle.Deciding compatibility from the parameter name.
The function does not automatically lock the parameter to one type merely because the parameter has a particular name.
Fix:
Trace the value into the function and examine each operation applied to it.Checking only the argument and not the function body.
A function succeeds only when its operations can handle the supplied value.
Fix:
Locate the operation where execution fails and determine what kind of value that operation can use.
Compatibility Practice
Suppose a function receives one argument and performs only a printing operation on that argument. Decide whether a string, an integer, and a floating-point number should pass through successfully. For each value, state what you would check while tracing the function.
Hints
- Identify the operation performed on the argument.
- Check whether the supplied value can be printed.
- The same operation is performed regardless of whether the value is a string, integer, or float.
- Write down the argument supplied by the call.
- Bind that value to the function's parameter.
- Trace each operation in the function body in order.
- Check whether the current operation supports the value.
- If an operation fails, treat that operation as the failure point and inspect its compatibility requirement.
Key Takeaways
- A function can accept multiple data types when its operations are compatible with those types.
- The function's operations, not the argument's type alone, determine its behavior.
- print_twice works with 'Spam', 17, and math.pi because each value can be printed.
- To debug a type error, trace the argument binding and inspect every operation until the incompatible operation is found.
- Testing a function with a particular type and checking whether all operations succeed verifies compatibility.
Key Takeaways
- Function compatibility comes from the operations performed on an argument.
- The same function can process strings, integers, and floats when its operation supports each value.
- Tracing parameter binding and operations reveals where a type error occurs.
- Testing a value and checking every operation is a practical way to verify compatibility.