Usually implemented when we want objects to support and interact with fundamental elements of the language, as:
- Collections
- Attribute access
- Iteration (including async for)
- Operator overloading
- invoking functions and methods
- representation and string formatting
- async programing using await
- creation and destruction of objects