micropython

docs/rationale.txt

234:77038806cb40
2009-06-01 Paul Boddie Moved context verification back into the invocation code, as opposed to residing in the function body code. This is required because keyword arguments need to operate on adjusted frames, and such adjustments must therefore occur because keyword arguments are stored in their invocation frames. Renamed CheckClassContext to the more general CheckClass instruction. Made AdjustFrame operate on invocation frames again. Introduced explicit tests for class invocation since instantiators require an extra slot for each new instance. Fixed the "if" statement to employ conversion of expression results to boolean values. Split and improved test programs.
     1 Micropython: A minimal implementation of Python for constrained devices
     2 
     3   * "Full strength" Python:
     4     * Introspection, interactivity, PEP/reference-compliance
     5     * CPython, Jython, IronPython, PyPy, CLPython, etc.
     6   * "Reduced strength" Python:
     7     * Remove "luxury" semantics
     8     * Shed Skin, RPython, etc.
     9 
    10 Motivations
    11 
    12   * Run Python programs in "small" devices
    13   * Small programs plus few executed instructions
    14     * Avoid expensive library code
    15       (small footprint, lots of executed instructions)
    16 
    17 Python's flexibility comes at a cost
    18 
    19   * Modules, classes, instances are all objects
    20   * Freedom to modify most objects at any time
    21   * Difficult to predict eventual behaviour before execution
    22   * Difficult to generate optimisations when compiling
    23 
    24 Not all things are dynamic/equal in Python
    25 
    26   * Locals, modules and classes are special in some way
    27     * Locals don't tend to change unilaterally
    28     * Parameter lists don't tend to change if fully specified
    29     * Modules usually retain their identity
    30     * Classes differ from objects (despite metaclasses)
    31 
    32 Attribute access
    33 
    34   * Must do a full lookup every time:
    35     * Check instance dictionary
    36     * Check class, superclasses
    37   * Potentially lots of code
    38   * Lots of executed instructions
    39 
    40 Improving attribute access performance
    41 
    42   * Achieve faster access using a different representation
    43   * Must define attributes of objects in advance
    44   * Restriction: modules, classes, instances are "closed"
    45   * Evaluate the limitations: are they too disruptive?
    46 
    47 Consequences of revised attribute access
    48 
    49   * Cannot extend the range of attributes on objects of existing classes
    50   * Further optimisations:
    51     * Restriction: attempt to control modification of attributes
    52     * Result: further optimisation of accesses
    53 
    54 Invocations
    55 
    56   * Target checking
    57   * Number of arguments vs. number of parameters
    58   * Keyword parameter resolution
    59   * Defaults
    60 
    61 Other costly operations
    62 
    63   * Binary operators
    64   * Comparisons
    65 
    66 Examples of rarely used/unnecessary flexibility
    67 
    68   * Can subclass dynamically:
    69 
    70     for cls in A, B:
    71         class C(cls):
    72             pass
    73 
    74   * Yet most people would relate to "class C"
    75   * Not "the class currently known as C"
    76 
    77 Examples of occasionally used flexibility
    78 
    79   * Can evaluate classes and functions in dynamic contexts:
    80 
    81     if platform == 'posix':
    82         class C:
    83             ...
    84     else:
    85         class C:
    86             ...
    87 
    88   * Seen quite often in the standard library with functions
    89   * Dynamism used for configuration purposes
    90 
    91 Distinguish between "good" and "bad" dynamism
    92 
    93   * Dynamic class preparation
    94   * Run-time choice of classes
    95   * Assigning attributes to modules
    96 
    97 Run-time configuration
    98 
    99   * The source of a lot of "bad" dynamism
   100   * Comparable to, but more robust than...
   101     * Class loading tricks in Java
   102     * Dynamic library loading magic in C/C++
   103   * Has a place, but perhaps not in compiled, embedded programs
   104 
   105 Micropython modules
   106 
   107   * Modules contain attributes as with normal Python
   108   * Inside the module:
   109     * Attributes can be accessed and set as globals
   110     * Classes and functions define module attributes
   111   * Outside the module:
   112     * Attributes can be accessed but not set
   113   * Definition from within means more predictable content
   114 
   115 Micropython classes
   116 
   117   * Classes contain attributes and expose superclass attributes
   118   * Inside the class:
   119     * Attributes can be accessed and set in the class scope
   120     * Functions define methods
   121   * Outside the class:
   122     * Attributes can be accessed but not set
   123   * Definition from within means more predictable content
   124 
   125 Micropython instances
   126 
   127   * Instances contain attributes and expose class attributes
   128   * Instance attributes must not shadow class attributes
   129   * The set of attributes is detected by scanning the __init__ method
   130 
   131 Rationale for restrictions
   132 
   133   * Construct efficient run-time representations
   134   * Predictable content means that access can be optimised
   135   * No shadowing means that only a single lookup is necessary
   136 
   137 References, attributes and values
   138 
   139   * Almost everything can be considered as a kind of attribute:
   140     * Module, class, instance
   141     * Local variable is the exception
   142   * Acquired attributes are "values":
   143     * An object being manipulated
   144     * Its context
   145   * Most kinds of values have no real context:
   146     * Module and class attributes, locals
   147   * The exception:
   148     * Instance attributes