A programmer argues that Python is 'type-unsafe' because it doesn't check types before the program runs. A classmate disagrees. Who is correct, and why?
AThe first programmer is right — without compile-time checking, there is no meaningful type safety
BThe classmate is right — Python performs type checking at runtime, which still prevents invalid operations and provides genuine type safety
CBoth are partially right — Python is type-safe only for built-in types, not user-defined ones
DThe question is moot because Python's type system is functionally identical to Java's, just triggered at a different moment
Python is dynamically typed, not untyped. When your program reaches an operation involving incompatible types, Python raises a TypeError, preventing the invalid operation from proceeding. This is genuine type safety — it means a program won't silently perform nonsensical operations on wrong-type values. Static type checking (Java, TypeScript) catches errors before running; dynamic type checking (Python, JavaScript) catches them as they're encountered. Both prevent type errors; they differ in timing. The misconception equates 'type safety' with 'compile-time checking.'
Question 2 Multiple Choice
In a statically typed language, a function is declared to return an integer. You store its result in a variable and then try to call .toUpperCase() on it (a string method). What happens?
AThe program executes the call and produces undefined or garbage output
BThe runtime silently converts the integer to a string so the method can proceed
CThe compiler refuses to build the program, because the type system knows the variable holds an integer and string methods are not valid on integers
DThe function detects how its return value will be used and adjusts its return type accordingly
Static type checking means the compiler verifies type validity before the program runs. It knows the variable holds an integer (from the function's declared return type) and knows that .toUpperCase() is a string method. It flags this as a type error and refuses to compile. This is the practical benefit of static typing: you discover the mistake during development, not when the code executes in production. Option B describes implicit coercion, which some languages do but which is not what static typing provides.
Question 3 True / False
Type safety is a property unique to statically typed languages, since dynamically typed languages mainly check types at runtime where errors can still cause crashes.
TTrue
FFalse
Answer: False
Type safety means a program will not perform an invalid operation on a value of the wrong type — not that errors are caught at compile time. Dynamically typed languages provide runtime type safety: when a type mismatch occurs, they raise an error rather than silently proceeding with a nonsensical operation. The distinction between static and dynamic typing is about *when* checking happens, not whether type safety exists. A program that crashes with a TypeError is safer than one that silently produces wrong output, and both static and dynamic systems prevent the latter.
Question 4 True / False
In a statically typed language, knowing the declared type of a variable tells you what operations you can safely perform on it before the program ever runs.
TTrue
FFalse
Answer: True
This is the core benefit of static typing — it provides upfront guarantees that enable reasoning about program correctness without running the code. If a variable is declared as an integer, you know arithmetic is valid on it. If it's declared as a boolean, you know it fits in an if condition. These guarantees are what enable IDE features like autocomplete and type-error highlighting: the type is known at edit time, so the tool can tell you what operations are valid before you compile or run anything.
Question 5 Short Answer
What does a type system fundamentally do, and why does it matter whether type checking happens at compile time or at runtime?
Think about your answer, then reveal below.
Model answer: A type system defines which operations are valid on each kind of data and enforces those rules throughout the program. Whether checking happens at compile time (static) or runtime (dynamic) determines when errors are caught: compile-time errors prevent invalid programs from running at all; runtime errors interrupt execution when the problematic operation is actually reached.
The practical difference is when you discover problems. In statically typed languages, type errors surface during development, before deployment — you can't ship a program with a type error. In dynamically typed languages, type errors can stay hidden until a specific code path executes, which might only happen in an edge case you haven't tested. This is not a judgment that one is better: static typing requires more annotation and is less flexible; dynamic typing is more concise but defers error discovery. Understanding the distinction helps you know what guarantees your code has and where to direct your testing effort.