Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ff241c9
adds Self members to enable contextual dot resolution
christoph-dfinity Sep 15, 2025
f528fa7
update List tests to use contextual dot resolution
christoph-dfinity Sep 15, 2025
596b378
fix typos
christoph-dfinity Sep 25, 2025
fe3bcfc
adds toArray for Map (needs tests and docs)
christoph-dfinity Sep 25, 2025
9c55f80
adds toArray for Set
christoph-dfinity Sep 27, 2025
96fcffb
makes comparison arguments to Map functions implicit
christoph-dfinity Sep 27, 2025
1bb811a
use implicits in tests for Map
christoph-dfinity Sep 27, 2025
a41e33e
make comparison arguments to Set functions implicit
christoph-dfinity Sep 28, 2025
a034d9e
update Set tests to use implicits
christoph-dfinity Sep 28, 2025
ac7db87
remove local bindings, now that we can disambiguate Nat and Int
christoph-dfinity Sep 28, 2025
a704389
make equal arguments implicit
christoph-dfinity Sep 29, 2025
69a21d5
rename internal Map and Set size to size_ to avoid clash with context…
christoph-dfinity Sep 29, 2025
a6ccbc0
Implicit pattern across entire `core` package (#398)
rvanasa Sep 29, 2025
45c0def
rename .size on Queue
christoph-dfinity Sep 29, 2025
122e3a7
add TODO comment
christoph-dfinity Sep 29, 2025
7ba323e
I was using a stale compiler
christoph-dfinity Sep 29, 2025
087daac
updates the toolchain to a pre-release
christoph-dfinity Sep 29, 2025
f6e0364
updated mops to pull down draft branch and adjust tests
crusso Sep 29, 2025
2d4c9f7
updated mops to pull down draft branch and adjust tests (#399)
crusso Sep 29, 2025
8760fb0
Update implicits for RealTimeQueue
rvanasa Sep 30, 2025
0817a02
Merge branch 'main' of https://github.com/dfinity/motoko-core into ch…
rvanasa Sep 30, 2025
ad6fda8
Update implicits for PriorityQueue
rvanasa Sep 30, 2025
359d06e
Update API lockfile
rvanasa Sep 30, 2025
bd8e69e
adds Self member to Blob
christoph-dfinity Oct 6, 2025
1fb424f
Merge branch 'christoph/contextual-dot' into christoph/implicits
christoph-dfinity Oct 6, 2025
2300b9d
Merge branch 'christoph/implicits' into claudio/implicits
crusso Oct 6, 2025
bc9c154
merge with christoph/implicits, update mops
crusso Oct 6, 2025
80b642c
api
crusso Oct 6, 2025
eed89f4
added funcs
P4P5T123 Oct 9, 2025
55c28c3
Apply suggestion from @crusso
crusso Oct 9, 2025
0272f40
Apply suggestion from @crusso
crusso Oct 9, 2025
31b0df3
Apply suggestion from @crusso
crusso Oct 9, 2025
b578c49
update api
crusso Oct 9, 2025
39e2573
fix test (Arity mismatch)
crusso Oct 9, 2025
99380ad
adding VarArray.fromArray/toArray (for symmetry)
crusso Oct 11, 2025
68196a7
feat: support for implicits (#397)
christoph-dfinity Oct 13, 2025
d5c3182
Merge branch 'christoph/contextual-dot' into claudio/implicits
crusso Oct 13, 2025
6ffa1f4
Merge branch 'main' into claudio/implicits
crusso Oct 13, 2025
d90dcc7
refactor: rename size_ -> size
christoph-dfinity Oct 13, 2025
854cdd4
fix List.sort/sortInPlace (acc. to #405) and declare implicits
AStepanov25 Oct 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Add `PriorityQueue` (#392).
* Add support for Weak references (#388).
* Clarify difference between `List` and `pure/List` in doc comments (#386).
* **Breaking:** Rename `sort` to `sortInPlace`, add `sort` (#405).

## 1.0.0

Expand Down
4 changes: 2 additions & 2 deletions mops.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ matchers = "2.1.0"
base-0-14-13 = "https://github.com/dfinity/motoko-base#moc-0.14.13@794174a307975c225cfb26b57f73e38a841c0415"

[requirements]
moc = "0.16.1"
moc = "0.16.3-implicits-6"

[toolchain]
moc = "0.16.1"
moc = "0.16.3-implicits-6"
wasmtime = "35.0.0"
20 changes: 11 additions & 9 deletions src/Array.mo
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import Prim "mo:⛔";

module {

public type Self<T> = [T];

/// Creates an empty array (equivalent to `[]`).
///
/// ```motoko include=import
Expand Down Expand Up @@ -120,7 +122,7 @@ module {
/// Space: O(1)
///
/// *Runtime and space assumes that `equal` runs in O(1) time and space.
public func equal<T>(array1 : [T], array2 : [T], equal : (T, T) -> Bool) : Bool {
public func equal<T>(array1 : [T], array2 : [T], equal : (implicit : (T, T) -> Bool)) : Bool {
let size1 = array1.size();
let size2 = array2.size();
if (size1 != size2) {
Expand Down Expand Up @@ -221,7 +223,7 @@ module {
///
/// Space: O(size)
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func sort<T>(array : [T], compare : (T, T) -> Order.Order) : [T] {
public func sort<T>(array : [T], compare : (implicit : (T, T) -> Order.Order)) : [T] {
let varArray : [var T] = toVarArray(array);
VarArray.sortInPlace(varArray, compare);
fromVarArray(varArray)
Expand Down Expand Up @@ -800,7 +802,7 @@ module {
/// Runtime: O(array.size())
///
/// Space: O(1)
public func indexOf<T>(array : [T], equal : (T, T) -> Bool, element : T) : ?Nat = nextIndexOf<T>(array, equal, element, 0);
public func indexOf<T>(array : [T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat = nextIndexOf<T>(array, equal, element, 0);

/// Returns the index of the next occurence of `element` in the `array` starting from the `from` index (inclusive).
///
Expand All @@ -817,7 +819,7 @@ module {
/// Runtime: O(array.size())
///
/// Space: O(1)
public func nextIndexOf<T>(array : [T], equal : (T, T) -> Bool, element : T, fromInclusive : Nat) : ?Nat {
public func nextIndexOf<T>(array : [T], equal : (implicit : (T, T) -> Bool), element : T, fromInclusive : Nat) : ?Nat {
var index = fromInclusive;
let size = array.size();
while (index < size) {
Expand All @@ -844,7 +846,7 @@ module {
/// Runtime: O(array.size())
///
/// Space: O(1)
public func lastIndexOf<T>(array : [T], equal : (T, T) -> Bool, element : T) : ?Nat = prevIndexOf<T>(array, equal, element, array.size());
public func lastIndexOf<T>(array : [T], equal : (implicit : (T, T) -> Bool), element : T) : ?Nat = prevIndexOf<T>(array, equal, element, array.size());

/// Returns the index of the previous occurence of `element` in the `array` starting from the `from` index (exclusive).
///
Expand All @@ -864,7 +866,7 @@ module {
///
/// Runtime: O(array.size());
/// Space: O(1);
public func prevIndexOf<T>(array : [T], equal : (T, T) -> Bool, element : T, fromExclusive : Nat) : ?Nat {
public func prevIndexOf<T>(array : [T], equal : (implicit : (T, T) -> Bool), element : T, fromExclusive : Nat) : ?Nat {
var i = fromExclusive;
while (i > 0) {
i -= 1;
Expand Down Expand Up @@ -1030,7 +1032,7 @@ module {
/// Space: O(size)
///
/// *Runtime and space assumes that `f` runs in O(1) time and space.
public func toText<T>(array : [T], f : T -> Text) : Text {
public func toText<T>(array : [T], f : (implicit : (toText : T -> Text))) : Text {
let size = array.size();
if (size == 0) { return "[]" };
var text = "[";
Expand Down Expand Up @@ -1074,7 +1076,7 @@ module {
/// Space: O(1)
///
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func compare<T>(array1 : [T], array2 : [T], compare : (T, T) -> Order.Order) : Order.Order {
public func compare<T>(array1 : [T], array2 : [T], compare : (implicit : (T, T) -> Order.Order)) : Order.Order {
let size1 = array1.size();
let size2 = array2.size();
var i = 0;
Expand Down Expand Up @@ -1112,7 +1114,7 @@ module {
/// Space: O(1)
///
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func binarySearch<T>(array : [T], compare : (T, T) -> Order.Order, element : T) : {
public func binarySearch<T>(array : [T], compare : (implicit : (T, T) -> Order.Order), element : T) : {
#found : Nat;
#insertionIndex : Nat
} {
Expand Down
1 change: 1 addition & 0 deletions src/Blob.mo
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import Order "Order";
module {

public type Blob = Prim.Types.Blob;
public type Self = Blob;

/// Returns an empty `Blob` (equivalent to `""`).
///
Expand Down
2 changes: 2 additions & 0 deletions src/Bool.mo
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ module {
/// Booleans with constants `true` and `false`.
public type Bool = Prim.Types.Bool;

public type Self = Bool;

/// Returns `a and b`.
///
/// Example:
Expand Down
2 changes: 2 additions & 0 deletions src/Char.mo
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ module {
/// Characters represented as Unicode code points.
public type Char = Prim.Types.Char;

public type Self = Char;

/// Convert character `char` to a word containing its Unicode scalar value.
///
/// Example:
Expand Down
1 change: 1 addition & 0 deletions src/Error.mo
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ module {

/// Error value resulting from `async` computations
public type Error = Prim.Types.Error;
public type Self = Error;

/// Error code to classify different kinds of user and system errors:
/// ```motoko
Expand Down
1 change: 1 addition & 0 deletions src/Float.mo
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ module {

/// 64-bit floating point number type.
public type Float = Prim.Types.Float;
public type Self = Float;

/// Ratio of the circumference of a circle to its diameter.
/// Note: Limited precision.
Expand Down
1 change: 1 addition & 0 deletions src/Int.mo
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ module {

/// Infinite precision signed integers.
public type Int = Prim.Types.Int;
public type Self = Int;

/// Returns the absolute value of `x`.
///
Expand Down
1 change: 1 addition & 0 deletions src/Int16.mo
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module {

/// 16-bit signed integers.
public type Int16 = Prim.Types.Int16;
public type Self = Int16;

/// Minimum 16-bit integer value, `-2 ** 15`.
///
Expand Down
1 change: 1 addition & 0 deletions src/Int32.mo
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module {

/// 32-bit signed integers.
public type Int32 = Prim.Types.Int32;
public type Self = Int32;

/// Minimum 32-bit integer value, `-2 ** 31`.
///
Expand Down
1 change: 1 addition & 0 deletions src/Int64.mo
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ module {

/// 64-bit signed integers.
public type Int64 = Prim.Types.Int64;
public type Self = Int64;

/// Minimum 64-bit integer value, `-2 ** 63`.
///
Expand Down
1 change: 1 addition & 0 deletions src/Int8.mo
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ module {

/// 8-bit signed integers.
public type Int8 = Prim.Types.Int8;
public type Self = Int8;

/// Minimum 8-bit integer value, `-2 ** 7`.
///
Expand Down
9 changes: 5 additions & 4 deletions src/Iter.mo
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ module {
/// }
/// ```
public type Iter<T> = Types.Iter<T>;
public type Self<T> = Iter<T>;

/// Creates an empty iterator.
///
Expand Down Expand Up @@ -531,7 +532,7 @@ module {
/// let iter = [1, 2, 3, 4].values();
/// assert Iter.contains<Nat>(iter, Nat.equal, 2);
/// ```
public func contains<T>(iter : Iter<T>, equal : (T, T) -> Bool, value : T) : Bool {
public func contains<T>(iter : Iter<T>, equal : (implicit : (T, T) -> Bool), value : T) : Bool {
for (x in iter) {
if (equal(x, value)) return true
};
Expand Down Expand Up @@ -661,7 +662,7 @@ module {
/// let iter = [1, 2, 3].values();
/// assert ?3 == Iter.max<Nat>(iter, Nat.compare);
/// ```
public func max<T>(iter : Iter<T>, compare : (T, T) -> Order.Order) : ?T {
public func max<T>(iter : Iter<T>, compare : (implicit : (T, T) -> Order.Order)) : ?T {
reduce<T>(
iter,
func(a, b) {
Expand All @@ -682,7 +683,7 @@ module {
/// let iter = [1, 2, 3].values();
/// assert ?1 == Iter.min<Nat>(iter, Nat.compare);
/// ```
public func min<T>(iter : Iter<T>, compare : (T, T) -> Order.Order) : ?T {
public func min<T>(iter : Iter<T>, compare : (implicit : (T, T) -> Order.Order)) : ?T {
reduce<T>(
iter,
func(a, b) {
Expand Down Expand Up @@ -803,7 +804,7 @@ module {
};

/// Sorted iterator. Will iterate over *all* elements to sort them, necessarily.
public func sort<T>(iter : Iter<T>, compare : (T, T) -> Order.Order) : Iter<T> {
public func sort<T>(iter : Iter<T>, compare : (implicit : (T, T) -> Order.Order)) : Iter<T> {
let array = toVarArray<T>(iter);
VarArray.sortInPlace<T>(array, compare);
fromVarArray<T>(array)
Expand Down
48 changes: 37 additions & 11 deletions src/List.mo
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module {
///
/// The maximum number of elements in a `List` is 2^32.
public type List<T> = Types.List<T>;
public type Self<T> = List<T>;

let INTERNAL_ERROR = "List: internal error";

Expand Down Expand Up @@ -587,15 +588,15 @@ module {
/// List.add(list, 3);
/// List.add(list, 1);
/// List.add(list, 2);
/// List.sort(list, Nat.compare);
/// List.sortInPlace(list, Nat.compare);
/// assert List.toArray(list) == [1, 2, 3];
/// ```
///
/// Runtime: O(size * log(size))
///
/// Space: O(size)
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func sort<T>(list : List<T>, compare : (T, T) -> Order.Order) {
public func sortInPlace<T>(list : List<T>, compare : (implicit : (T, T) -> Order.Order)) {
if (size(list) < 2) return;
let arr = toVarArray(list);
VarArray.sortInPlace(arr, compare);
Expand All @@ -604,6 +605,31 @@ module {
}
};

/// Sorts the elements in the list according to `compare`.
/// Sort is deterministic, stable, and in-place.
///
/// Example:
/// ```motoko include=import
/// import Nat "mo:core/Nat";
///
/// let list = List.empty<Nat>();
/// List.add(list, 3);
/// List.add(list, 1);
/// List.add(list, 2);
/// let sorted = List.sort(list, Nat.compare);
/// assert List.toArray(sorted) == [1, 2, 3];
/// ```
///
/// Runtime: O(size * log(size))
///
/// Space: O(size)
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func sort<T>(list : List<T>, compare : (implicit : (T, T) -> Types.Order)) : List<T> {
let array = toVarArray(list);
VarArray.sortInPlace(array, compare);
fromVarArray(array)
};

/// Finds the first index of `element` in `list` using equality of elements defined
/// by `equal`. Returns `null` if `element` is not found.
///
Expand All @@ -624,7 +650,7 @@ module {
/// Runtime: `O(size)`
///
/// *Runtime and space assumes that `equal` runs in `O(1)` time and space.
public func indexOf<T>(list : List<T>, equal : (T, T) -> Bool, element : T) : ?Nat {
public func indexOf<T>(list : List<T>, equal : (implicit : (T, T) -> Bool), element : T) : ?Nat {
// inlining would save 10 instructions per entry
findIndex<T>(list, func(x) = equal(element, x))
};
Expand All @@ -645,7 +671,7 @@ module {
/// Runtime: `O(size)`
///
/// *Runtime and space assumes that `equal` runs in `O(1)` time and space.
public func lastIndexOf<T>(list : List<T>, equal : (T, T) -> Bool, element : T) : ?Nat {
public func lastIndexOf<T>(list : List<T>, equal : (implicit : (T, T) -> Bool), element : T) : ?Nat {
// inlining would save 10 instructions per entry
findLastIndex<T>(list, func(x) = equal(element, x))
};
Expand Down Expand Up @@ -784,7 +810,7 @@ module {
/// Space: `O(1)`
///
/// *Runtime and space assumes that `compare` runs in `O(1)` time and space.
public func binarySearch<T>(list : List<T>, compare : (T, T) -> Order.Order, element : T) : {
public func binarySearch<T>(list : List<T>, compare : (implicit : (T, T) -> Order.Order), element : T) : {
#found : Nat;
#insertionIndex : Nat
} {
Expand Down Expand Up @@ -1547,7 +1573,7 @@ module {
/// Space: `O(1)`
///
/// *Runtime and space assumes that `equal` runs in O(1) time and space.
public func contains<T>(list : List<T>, equal : (T, T) -> Bool, element : T) : Bool {
public func contains<T>(list : List<T>, equal : (implicit : (T, T) -> Bool), element : T) : Bool {
Option.isSome(indexOf(list, equal, element))
};

Expand All @@ -1571,7 +1597,7 @@ module {
/// Space: `O(1)`
///
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func max<T>(list : List<T>, compare : (T, T) -> Order.Order) : ?T {
public func max<T>(list : List<T>, compare : (implicit : (T, T) -> Order.Order)) : ?T {
if (isEmpty(list)) return null;

var maxSoFar = at(list, 0);
Expand Down Expand Up @@ -1606,7 +1632,7 @@ module {
/// Space: `O(1)`
///
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func min<T>(list : List<T>, compare : (T, T) -> Order.Order) : ?T {
public func min<T>(list : List<T>, compare : (implicit : (T, T) -> Order.Order)) : ?T {
if (isEmpty(list)) return null;

var minSoFar = at(list, 0);
Expand Down Expand Up @@ -1642,7 +1668,7 @@ module {
/// Space: `O(1)`
///
/// *Runtime and space assumes that `equal` runs in O(1) time and space.
public func equal<T>(list1 : List<T>, list2 : List<T>, equal : (T, T) -> Bool) : Bool {
public func equal<T>(list1 : List<T>, list2 : List<T>, equal : (implicit : (T, T) -> Bool)) : Bool {
let size1 = size(list1);

if (size1 != size(list2)) return false;
Expand Down Expand Up @@ -1680,7 +1706,7 @@ module {
/// Space: `O(1)`
///
/// *Runtime and space assumes that `compare` runs in O(1) time and space.
public func compare<T>(list1 : List<T>, list2 : List<T>, compare : (T, T) -> Order.Order) : Order.Order {
public func compare<T>(list1 : List<T>, list2 : List<T>, compare : (implicit : (T, T) -> Order.Order)) : Order.Order {
let size1 = size(list1);
let size2 = size(list2);
let minSize = if (size1 < size2) { size1 } else { size2 };
Expand Down Expand Up @@ -1716,7 +1742,7 @@ module {
/// Space: `O(size)`
///
/// *Runtime and space assumes that `toText` runs in O(1) time and space.
public func toText<T>(list : List<T>, f : T -> Text) : Text {
public func toText<T>(list : List<T>, f : (implicit : (toText : T -> Text))) : Text {
let vsize : Int = size(list);
let next = values_(list).unsafe_next;
var i = 0;
Expand Down
Loading