11. Type System

11.1. Type inference

  • Static Typing (Java, C++, Swift)
String name = new String("José Jiménez")
  • Dynamic Typing (Python, PHP, Ruby)
# Type inference
name = 'José Jiménez'
name = str('José Jiménez')

11.2. Type Hinting A.K.A. Type Annotation

  • Since Python 3.5
  • SyntaxError in Python before 3.5
  • Two names: type hints and type annotations
  • Types are not required, and never will be (quote from Guido van Rossum, Python BDFL)
  • To check types you have to use IDE or modules like mypy or pyre-check
  • Types are used extensively in system libraries
  • More and more books and documentations use types

11.2.1. Basic types

name: str = 'Pan Twardowski'
age: int = 30
is_adult: bool = True

11.2.2. Collections

my_list: list = list()
my_set: set = set()
my_tuple: tuple = tuple()
my_dict: dict = dict()
my_list: list = []
my_set: set = set()
my_tuple: tuple = ()
my_dict: dict = {}
from typing import List, Tuple, Dict, Set


my_list: List[float] = [5.8, 2.7, 5.1, 1.9]
my_set: Set[int] = {0, 2, 4}
my_tuple: Tuple[str] = ('setosa', 'virginica', 'versicolor')
my_dict: Dict[int, str] = {0: 'setosa', 1: 'virginica': 2: versicolor}

11.2.3. Types do not enforce checking

  • This code will run without any problems
  • Although mypy or pyre-check will throw error
name: int = 'Pan Twardowski'
age: float = 30
is_adult: int = True

11.2.4. More advanced topics

Note

The topic will be continued in chapter: Software Engineering Conventions

11.3. Problematic types

11.3.1. dict vs. set

  • Both set and dict keys must be hashable
  • Both set and dict uses the same { and } braces
  • Despite similar syntax, they are different types
my_data = {}
isinstance(my_data, (set, dict))  # True
isinstance(my_data, dict)         # True
isinstance(my_data, set)          # False

my_data = {1}
isinstance(my_data, (set, dict))  # True
isinstance(my_data, dict)         # False
isinstance(my_data, set)          # True

my_data = {1: 1}
isinstance(my_data, (set, dict))  # True
isinstance(my_data, dict)         # True
isinstance(my_data, set)          # False
{}                # dict
{1}               # set

{1, 2}            # set
{1: 2}            # dict

{1, 2,}           # set
{1: 2,}           # dict

{1: 2, 3: 4}      # dict
{1, 2, 3, 4}      # set

11.3.2. tuple vs. str

what = 'foo'      # str
what = 'foo',     # tuple with str
what = 'foo'.     # SyntaxError: invalid syntax

what = ('foo')    # str
what = ('foo',)   # tuple with str
what = ('foo'.)   # SyntaxError: invalid syntax

11.3.3. tuple vs. float and int

what = 1.2        # float
what = 1,2        # tuple

what = (1.2)      # float
what = (1,2)      # tuple
what = 1.2,       # tuple with float
what = 1,2.3      # tuple with int and float

what = (1.2,)     # tuple with float
what = (1,2.3)    # tuple with int and float
what = 1.         # float
what = .5         # float
what = 1.0        # float
what = 1          # int

what = (1.)       # float
what = (.5)       # float
what = (1.0)      # float
what = (1)        # int
what = 10.5       # float
what = 10,5       # tuple with two ints
what = 10.        # float
what = 10,        # tuple with int
what = 10         # int

what = (10.5)     # float
what = (10,5)     # tuple with two ints
what = (10.)      # float
what = (10,)      # tuple with int
what = (10)       # int
what = 1.,1.      # tuple with two floats
what = .5,.5      # tuple with two floats
what = 1.,.5      # tuple with two floats

what = (1.,1.)    # tuple with two floats
what = (.5,.5)    # tuple with two floats
what = (1.,.5)    # tuple with two floats