(I'm speaking as one of the CircuitPython core devs)
I think both naming schemes have advantages and disadvantages. This describes our naming philosophy: https://circuitpython.readthedocs.io/en/3.x/#modules
- No module aliasing. (uos and utime are not available as os and time respectively.) Instead os, time, and random are CPython compatible.
- New storage module which manages file system mounts. (Functionality from uos in MicroPython.)
- Modules with a CPython counterpart, such as time, os and random, are strict subsets of their CPython version. Therefore, code from CircuitPython is runnable on CPython but not necessarily the reverse.
- tick count is available as time.monotonic()
In MicroPython, the `u` modules are not necessarily strict subsets. They may include additional non-CPython functionality. `utime` is a good example: it has a number of extra functions that are not in `time`, such as, say, `sleep_ms()`. So if you `import utime as time`, functions will show up that are not in CPython `time`. Our philosophy has been to move the extra functionality into another non-CPython module name. As mentioned above, "code from CircuitPython is runnable on CPython but not necessarily the reverse."
This paragraph from the MicroPython doc is of note: http://docs.micropython.org/en/latest/l ... -libraries
On some embedded platforms, where it may be cumbersome to add Python-level wrapper modules to achieve naming compatibility with CPython, micro-modules are available both by their u-name, and also by their non-u-name. The non-u-name can be overridden by a file of that name in your library path (sys.path). For example, import json will first search for a file json.py (or package directory json) and load that module if it is found. If nothing is found, it will fallback to loading the built-in ujson module.
I think our strict subsetting is in some ways like upward compatibility from Python 3.x to 3.y (x < y). There are dilemmas either way. For example, `time.monotonic _ns()` was added to CPython recently. We added it to our `time` module , except
for ports that don't have longints for space reasons. So code for those ports can't use that function, unfortunately. But we have decided that all ports have floats, so we can always do `time.sleep()`.
Another reason for our choice is that we've written wrapper libraries for Raspberry Pi and similar platforms with pin I/O support. The wrappers re-implement (in CPython) the native pin I/O functionality (like I2C) provided in CircuitPython. This allows the existing CircuitPython libraries for our breakout boards, etc., to run without change on RPi and the like. And the user code that calls those libraries can also be run without change, without having to do module name aliasing like `import uxyz as xyz`.
MicroPython and CircuitPython have different but overlapping goals and audiences. MPy has provided a fantastic base for expanding physical computing to a larger, non-professional audience. We are extremely grateful to Damien and the rest of the MPy contributors. I usually explain that CPy is a "friendly fork". We merge from upstream regularly, and try to contribute back as appropriate.