For Motoko, the rules can be summarized like this
- A user/frontend can call:
- a
sharedfunction (with consensus and state change), - a
shared queryfunction (without consensus or state change).
- a
- A class constructor can call:
- any local function.
- A shared function (or async expression) can call:
- any local function, and
- any
sharedfunction (with consensus and state change), and - any
shared queryfunction (with consensus but no state change), - and
awaitthe results ofshared(shared query) functions.
- A
shared queryfunction can call:- any local function.
- it cannot call any
sharedorshared queryfunctions, norawaittheir results.
These rules are enforced dynamically on the platform (causing runtime traps when violated) but are checked statically in Motoko, to prevent traps.
On the platform, there is ongoing work to allow shared query functions to call other shared query functions, but we probably won’t expose that in Motoko until the implementation is done and, ideally, free of strange restrictions.