Releases: dfinity/motoko
0.8.5
0.8.4
-
motoko (
moc
)-
Performance improvement: UTF-8 coding and validation is now properly tail recursive (#3842).
-
Performance improvement: eliminated bounds checking for certain array accesses (thanks to nomeata) (#3853).
-
Performance improvement: optimized
{array, blob, text}.size()
operations (thanks to nomeata) (#3863). -
Performance improvement: efficient tuple results in
switch
statements (thanks to nomeata) (#3865). -
Performance improvement: more efficient untagging operation (#3873).
-
bugfix: restored a grammar regression caused by
let-else
(#3869).
-
-
motoko-base
-
Add
Array.subArray
function (dfinity/motoko-base#445). -
BREAKING CHANGE (Minor)
Optimized
AssocList.{replace, find}
to avoid unnecessary allocation (dfinity/motoko-base#535, dfinity/motoko-base#539).
Note: this subtly changes the order in which the key-value pairs occur after replacement. May affect other containers that useAssocList
. -
Performance improvement: Optimized deletion for
Trie
/TrieMap
(dfinity/motoko-base#525).
-
0.8.3
-
motoko (
moc
)-
new 'let-else' construct for handling pattern-match failure (#3836).
This is a frequently asked-for feature that allows to change the control-flow
of programs when pattern-match failure occurs, thus providing a means against
the famous "pyramid of doom" issue. A common example is look-ups:shared func getUser(user : Text) : async Id { let ?id = Map.get(users, user) else { throw Error.reject("no such user") }; id }
Similarly, an expression like
(label v : Bool { let <pat> = <exp> else break v false; true })
evaluates to a
Bool
, signifying whether<pat>
matches<exp>
. -
Improve recursive deserialization capacity to match recursive serialization capacity by reducing
Wasm stack consumption (#3809).
Because of the bounds on recursion depth imposed by fixed-size stack, the
advice remains the same: avoid deeply nested recursive data structures.
Think "shallow trees good, very long lists bad". -
bugfix: stack overflow in UTF-8 encode/decode for
moc.js
(#3825).
-
-
motoko-base
- add missing
unshare : Tree<K, V> -> ()
method to classRBTree<K, V>
to restore objects from saved state (dfinity/motoko-base#532).
- add missing
0.8.2
-
motoko (
moc
)-
Add compiler flag
--rts-stack-pages <n>
to override default number of
pages dedicated to fixed runtime system stack. Now defaults to 32 pages
(2MiB) (up from previous 2 pages/128KiB) (#3782).
In emergencies, increasing this setting may improve your ability to deserialize
deeply nested Candid or stable variable data. -
Add stack overflow detection utilising reserved page (#3793).
-
Performance improvement: heap allocator speedup (#3090, #3790).
-
bugfix: avoid more heap-out-bounds errors during deserialization of stable variables
by increasing default runtime system stack from 128KiB to 2MiB (#3782).
Note: this is a partial fix, as issues with stack growth remain.
-
-
motoko-base
- bugfix: non-leaky deletion for
RBTree
(dfinity/motoko-base#524).
- bugfix: non-leaky deletion for
0.8.1
0.8.0
-
motoko (
moc
)-
BREAKING CHANGE
Motoko now implements Candid 1.4 (dfinity/candid#311).
In particular, when deserializing an actor or function reference,
Motoko will now first check that the type of the deserialized reference
is a subtype of the expected type and act accordingly.Very few users should be affected by this change in behaviour.
-
BREAKING CHANGE
Failure to send a message no longer traps but, instead, throws a catchable
Error
with new error code#call_error
(#3630).On the IC, the act of making a call to a canister function can fail, so that the call cannot (and will not be) performed.
This can happen due to a lack of canister resources, typically because the local message queue for the destination canister is full,
or because performing the call would reduce the current cycle balance of the calling canister to a level below its freezing threshold.
Such call failures are now reported by throwing anError
with newErrorCode
#call_error { err_code = n }
,
wheren
is the non-zeroerr_code
value returned by the IC.
Like other errors, call errors can be caught and handled usingtry ... catch ...
expressions, if desired.The constructs that now throw call errors, instead of trapping as with previous version of Motoko are:
- calls to
shared
functions (including oneway functions that return()
).
These involve sending a message to another canister, and can fail when the queue for the destination canister is full. - calls to local functions with return type
async
. These involve sending a message to self, and can fail when the local queue for sends to self is full. async
expressions. These involve sending a message to self, and can fail when the local queue for sends to self is full.await
expressions. These can fail on awaiting an already completed future, which requires sending a message to self to suspend and commit state.
(On the other hand,
async*
(being delayed) cannot throw, and evaluatingawait*
will at most propagate an error from its argument but not, in itself, throw.)Note that exiting a function call via an uncaught throw, rather than a trap, will commit any state changes and currently queued messages.
The previous behaviour of trapping would, instead, discard, such changes.To appreciate the change in semantics, consider the following example:
actor { var count = 0; public func inc() : async () { count += 1; }; public func repeat() : async () { loop { ignore inc(); } }; public func repeatUntil() : async () { try { loop { ignore inc(); } } catch (e) { } }; }
In previous releases of Motoko, calling
repeat()
andrepeatUntil()
would trap, leavingcount
at0
, because
each infinite loop would eventually exhaust the message queue and issue a trap, rolling back the effects of each call.
With this release of Motoko, callingrepeat()
will enqueue severalinc()
messages (around 500), thenthrow
anError
and exit with the error result, incrementing thecount
several times (asynchronously).
CallingrepeatUntil()
will also enqueue severalinc()
messages (around 500) but the error is caught so the call returns,
still incrementingcount
several times (asynchronously).The previous semantics of trapping on call errors can be enabled with compiler option
--trap-on-call-error
, if desired,
or selectively emulated by forcing a trap (e.g.assert false
) when an error is caught.For example,
public func allOrNothing() : async () { try { loop { ignore inc(); } } catch (e) { assert false; // trap! } };
Calling
allOrNothing()
will not send any messages: the loop exits with an error on queue full,
the error is caught, butassert false
traps so all queuedinc()
messages are aborted. - calls to
-
bugfix: system method
inspect
involving message with single tuple argument no longer crashes the compiler (#3732, #3733).
-
0.7.6
-
motoko (
moc
)-
Added support for
ManagementCanister.raw_rand
in interpreters (#3693). -
Added preliminary Viper support for
old
expressions in specifications and calls to private methods (#3675). -
bugfix: in the default timer mechanism
cancelTimer
sometimes wouldn't actually stop a recurring timer (#3695). -
bugfix: zero negation for floating point numbers in compiled code (#3676).
-
-
motoko-base
-
Add user-facing timer functionality (dfinity/motoko-base#474).
-
Add
Array.size
(dfinity/motoko-base#486, dfinity/motoko-base#494). -
Add
TrieSet
methodsisEmpty
,isSubset
(dfinity/motoko-base#503). -
BREAKING CHANGES (Minor):
- renamed
Float.neq
toFloat.neg
(this was a misspelling) - renamed
Nat.neq
toNat.neg
(this was a misspelling) - removed second argument from
bitnot
(this was an oversight)
- renamed
-
bugfix:
Random.Finite.coin
didn't use entropy correctly (dfinity/motoko-base#500). -
bugfix:
Trie.mergeDisjoint
(dfinity/motoko-base#505). -
bugfix:
TrieSet.equals
(dfinity/motoko-base#503). -
Various documentation fixes and API usage examples.
-
0.7.5
-
motoko (
moc
)-
Add new primitives for a default timer mechanism (#3542). These are
setTimer : (delayNanos : Nat64, recurring : Bool, job : () -> async ()) -> (id : Nat) cancelTimer : (id : Nat) -> ()
By defining a
system func timer
the default mechanism can now be overridden by a custom
implementation. Additionally by supplying the command-line flag-no-timer
all aspects
of timers can be suppressed, e.g. for space- or security-sensitive purposes, thus effectively
reverting canisters to the pre-timers era. -
bugfix: silence bogus cascading errors in stable compatibility check (#3645).
-
0.7.4
-
motoko (
moc
)-
Add new keywords
async*
andawait*
(note the*
) for efficient abstraction of asynchronous code (#3609).<typ> ::= ... async* <typ> delayed, asynchronous computation <exp> ::= ... async* <block-or-exp> delay an asynchronous computation await* <block-or-exp> execute a delayed computation (only in async, async*)
This avoids the resource consumption and latency of
async
/await
by only committing state and suspending execution
when necessary in theawait*
-ed computation, not necessarily at theawait*
itself.WARNING: Unlike
async
/await
:- an
async*
value has no effect unlessawait*
-ed; - each
await*
of the sameasync*
value repeats its effects.
This feature is experimental and may evolve in future. Use with discretion.
See the manual for details. - an
-
Suppress GC during IC
canister_heartbeat
, deferring any GC to the scheduled Motokoheartbeat
system
method (#3623).
This is a temporary workaround, to be removed once DTS is supported forcanister_heartbeat
itself (#3622). -
Add a new generational GC, enabled with new moc flag
--generational-gc
(#3495).
The generational garbage collector optimizes for fast reclamation of short-lived objects.
New objects are allocated in a young generation that is more frequently collected than the older objects
that have already survived a GC run.For many cases, the generational GC is more efficient than the existing compacting GC and copying GCs:
- Lower runtimes: Less number of executed instructions on average.
- Shorter interruptions: Young generation collection entails shorter program interruptions.
To activate the generational GC under
dfx
, the following command-line argument needs to be specified indfx.json
:... "type" : "motoko" ... "args" : "--generational-gc" ...
-
moc.js
: add trampoline and step limiter to interpreter, avoiding (some) stackoverflows and
hangs (#3618, #3541).
Enables execution of larger examples on web pages. -
BREAKING CHANGE (Minor):
Consider records with mutable fields as non-static (#3586).
Consequently, an imported library declaring a mutable record is now
rejected, not accepted, to be consistent with the declarations of
mutable fields and mutable objects. -
Experimental Viper integration by compiling a very narrow subset of
Motoko to the verification intermediate language. Seesrc/viper/README.md
and the PR for details. (#3477).
-
-
motoko-base
-
Unit tests for Trie and fix for
disj
(dfinity/motoko-base#438). -
Respect Trie structure in
filter
(dfinity/motoko-base#431, dfinity/motoko-base#438). -
Array module reimplementation, tests and documentation (dfinity/motoko-base#425,dfinity/motoko-base#432).
-
0.7.3
-
motoko (
moc
) -
motoko-base
-
Add some examples to
Buffer
library documentation (dfinity/motoko-base#420). -
Fix another bug in
Buffer
library affectingfilterEntries
(dfinity/motoko-base#422).
-