Lichen

Annotated docs/wiki/Builtins

939:8a70350be7b0
2021-06-29 Paul Boddie Merged changes from the default branch. trailing-data
paul@810 1
= Built-Ins =
paul@810 2
paul@861 3
The "built-ins" are a collection of special names that do not need to be
paul@861 4
explicitly imported. For example:
paul@810 5
paul@810 6
{{{#!python numbers=disable
paul@810 7
biggest = max([23, 19, 27]) # max is a built-in function
paul@810 8
}}}
paul@810 9
paul@861 10
Such names are always available as if they were defined in the current module.
paul@861 11
However, they are provided by a package hierarchy that seeks to divide them
paul@861 12
into isolated areas of functionality that can be included or excluded
paul@861 13
depending on the facilities employed by each program. For example, complex
paul@861 14
numbers are provided in the `__builtins__.complex` module, but for any program
paul@861 15
not employing complex numbers, this module will be excluded and its
paul@861 16
functionality not appear in the final program. (The exclusion of modules is
paul@861 17
achieved using the hidden module functionality provided by the
paul@861 18
[[../Imports|import mechanism]].)
paul@810 19
paul@861 20
The principal, "top-level" module providing built-ins is the `__builtins__`
paul@861 21
module whose only role is to expose the actual built-in names. It does so by
paul@861 22
importing names directly from the different submodules, such as
paul@861 23
`__builtins__.complex`, so that attempts to import names from `__builtins__`
paul@861 24
may provide such attempts with the named objects. The `__builtins__` module
paul@861 25
looks like this in such cases:
paul@810 26
paul@810 27
{{{#!python numbers=disable
paul@810 28
from __builtins__.complex import complex
paul@810 29
}}}
paul@810 30
paul@861 31
Accesses to built-in names use the same technique of importing a name
paul@861 32
(`complex`) rather than the module providing it (`__builtins__`). It is as if
paul@861 33
the following code would appear before usage of a built-in name:
paul@810 34
paul@810 35
{{{#!python numbers=disable
paul@810 36
from __builtins__ import complex
paul@810 37
}}}
paul@810 38
paul@861 39
Since it is the specific name that is being referenced, not the module, the
paul@861 40
other contents of the module can be ignored and the reference to the named
paul@861 41
object followed to its actual definition location. Thus, usage of `complex`
paul@861 42
causes `__builtins__.complex` to be included in the program so that it may
paul@861 43
provide the `complex` type.
paul@810 44
paul@861 45
Thus, it becomes possible to keep a module like `__builtins__` out of the
paul@861 46
program since its only role would be to hold references to other modules'
paul@861 47
objects, but such specific imports permit the module to be bypassed by just
paul@861 48
following the declared import relationships. However, consider the
paul@861 49
consequences of `__builtins__` being imported as follows:
paul@810 50
paul@810 51
{{{#!python numbers=disable
paul@810 52
import __builtins__
paul@810 53
}}}
paul@810 54
paul@861 55
Its entire contents would then need to be exposed because it would then be
paul@861 56
possible to access any name provided by the module via the module. This was
paul@861 57
not the case with a specific name import because there was no way of
paul@861 58
referencing the module itself as a result of such an import.
paul@810 59
paul@861 60
This would then cause all of the referenced modules to be imported because it
paul@861 61
would no longer be possible to readily identify the modules that would
paul@861 62
actually be needed by the program. For example:
paul@810 63
paul@810 64
{{{#!python numbers=disable
paul@810 65
def get_things(obj):
paul@810 66
    obj.complex
paul@810 67
    obj.function
paul@810 68
    obj.list
paul@810 69
paul@810 70
get_things(__builtins__)
paul@810 71
}}}
paul@810 72
paul@861 73
Of course, no module in a program should be referencing the `__builtins__`
paul@861 74
module by explicitly importing it, anyway. Given that all the names provided
paul@861 75
by that module are already available without any need to perform an import
paul@861 76
operation, such an import operation would have rather limited additional
paul@861 77
benefits.