/ home / Programming / Python /

'switch'

Using a given value to direct the flow of program execution.

Python Qt/Cpp
  1. from dataclasses import dataclass
  2. @dataclass
  3. class C:
  4. m_c: int
  5. isLetter : bool = False
  6. isNonCharacter : bool = False
  7. isNull : bool = False
  8. isNumber : bool = False
  9. isPrintable : bool = True
  10. isSpace : bool = False
  11. isUpper : bool = False
  12. c = C(88)
  13. match c:
  14. case C(0):
  15. c.isNull = True
  16. case C( m_c = x ) if x in range(1, 32) or x == 127:
  17. c.isNonCharacter = True
  18. c.isPrintable = False
  19. case C(" "):
  20. c.isSpace = True
  21. case C(x) if x in range( ord("A"), ord("Z") + 1 ):
  22. c.isUpper = True
  23. c.isLetter = True
  24. case C(x) if x in range( ord("a"), ord("z") + 1 ):
  25. c.isUpper = False
  26. c.isLetter = True
  27. case C(x) if x in range( ord("0"), ord("9") + 1 ):
  28. c.isNumber = True
  29. case _:
  30. pass
  1. qint8 c(88);
  2. bool isLetter (false);
  3. bool isNonCharacter(false);
  4. bool isNull (false);
  5. bool isNumber (false);
  6. bool isPrintable (true );
  7. bool isSpace (false);
  8. bool isUpper (false);
  9. switch (c) {
  10. default: break;
  11. case 0 :
  12. isNull = true;
  13. [[fallthrough]];
  14. case 1 ... 31:
  15. case 127 : // Delete
  16. isNonCharacter = true;
  17. isPrintable = false;
  18. break;
  19. case ' ':
  20. isSpace = true;
  21. break;
  22. case 'A' ... 'Z':
  23. isUpper = true;
  24. [[fallthrough]];
  25. case 'a' ... 'z':
  26. isLetter = true;
  27. break;
  28. case '0' ... '9':
  29. isNumber = true;
  30. break;
  31. }

Read as:
  • 'match 'c [ a character dataclass ] where if:
  • under case [ dataclass ] C(0)
  • isNull equals true
  • under case [ dataclass ] c is an instance of [ dataclass ] C which has an attribute m_c
  • it will evaluate as true when we assign m_c to x and if x is in the range of 1 to 32 or is equal to 127,
  • isNonCharacter equals true
  • isPrintable equals false
  • Under case [ dataclass ] C( space )
  • isSpace equals true
  • under case [ dataclass ] C( x [ which is a copy of the first attribute of C, m_c ] ) if x is in the range of A to Z,'
  • isUpper equals true
  • isLetter equals true
  • under case [ dataclass ] C( x [ which is a copy of the first attribute of C, m_c ] ) if x is in the range of a to z,'
  • isUpper equals false
  • isLetter equals true
  • under case [ dataclass ] C( x [ which is a copy of the first attribute of C, m_c ] ) if x is in the range of 0 to 9,'
  • isNumber equals true
  • under case underscore [ Which is a wildcard pattern, taking any argument ]
  • pass [ and do nothing ]
  • 'switch' c [ 'c' implying character value ]
  • by default, 'break' [ out of the 'switch' ].
  • Under case 0:
  • isNull equals true.
  • Fallthrough [ to the next case's code ]
  • Under case from 1 to 31:
  • Under case 127:
  • isNonCharacter equals true.
  • isPrintable equals false
  • 'break' [ out of the 'switch' ]
  • under case space character
  • isSpace equals true.
  • 'break' [ out of the 'switch' ]
  • Under case from A to Z:
  • isUpper equals true.
  • Fallthrough [ to the next case's code ]
  • Under case from a to z:
  • isLetter equals true.
  • 'break' [ out of the 'switch' ]
  • Under case from 0 to 9:
  • isNumber equals true.
  • 'break' [ out of the 'switch' ]

Benefits:
  • Cases support conditional triggers.
  • A 'switch' here is transformed into a jump or lookup table for potential massive performance gains.
  • In order to achieve this, the compiler guarantees that all case values are unique numeric values.
  • Because of the unique value nature, the order of the case statements is more or less immaterial unless one plans to make fallthrough code
  • Code can fallthrough allowing for subtle optimization.
  • Offers excellent readability if working in tandem with enumerators

Drawbacks:
  • Extremely unintuitive syntax.
  • No fallthrough.
  • Performatively poor, due to the fact that no jump is executed.
  • Cases are not guaranteed unique.
  • Two cases may evaluate as true, however only the first will execute
  • Value has to be translateable to an interger form
  • [[fallthrough]] is optional, and absent this, it may be easy to not realize that no 'break'is occurring.
  • '0' has a different value than 0. Although this remains true in python as well in similar contexts.

Final Thoughts