diff --git a/adr/001_interface_design.md b/adr/001_interface_design.md
index 3004d5a..6568244 100644
--- a/adr/001_interface_design.md
+++ b/adr/001_interface_design.md
@@ -6,7 +6,10 @@ More attention was paid to implementing the underlying functionality of the cuck
With the fundamentals of the algorithm built, our API contract should be revisited.
It should align closer to the following principles:
-- **Similarity to the builtin map.**
+- **Congruency to the builtin map.**
+ Our cuckoo table should have the same core functionality as Go's built-in map.
+
+- **Familiarity to the builtin map.**
If our cuckoo table behaves similarly to Go's standard map, our user will intuitively know how to use it.
This lowers the cognitive load our developers must carry.
@@ -70,15 +73,19 @@ On the other hand, here is the current contract for `go-cuckoo`.
-### Determining Similarity
+### Determining Congruency
-So, how do the two relate?
-Listed below is an analysis of every built-in interface.
-Each is compared against what `go-cuckoo` offers, and if any changes seem necessary.
+So, how does the core functionality compare?
+Listed below is an analysis of every interface in Go's standard map.
+Each is compared against what `go-cuckoo` offers, and categorized into the following groups:
+
+- ✅ Covered: an analog exists.
+- ⚠️ Partial: workaround available.
+- ❌ Gap: no analog yet; addressed in [Target State](#solving-congruency).
Specifically, here we are checking for functionality.
Is there functionality that this offers which `go-cuckoo` does not?
-This check will check accessibility, but not discoverability.
+We are checking accessibility, but not discoverability.
The latter will be considered later.
@@ -89,9 +96,9 @@ The analog is `m := New()`.
-❌ m := make(map[K]V, hint)
+⚠️ m := make(map[K]V, hint)
-This has no analog.
+This has no simple analog.
It is close to `m := New(Capacity(hint))`, but it assigns starting capacity, not expected size.
For the built-in map, these are two separate things.
@@ -129,88 +136,223 @@ The analog is `var m Table[K, V]`.
-m[k] := v
+✅ m[k] := v
+
+The analog is `err := m.Put(k, v)`.
-v := m[k]
+✅ v := m[k]
+
+The analog is `v := m.Find(k)`.
-v, ok := m[k]
+✅ v, ok := m[k]
+
+The analog is `v, ok := m.Get(k)`.
-for k, v := range m
+✅ for k, v := range m
+
+The analog is `for k, v := range m.Entries()`.
-delete(m, k)
+✅ delete(m, k)
+
+The analog is `ok := m.Drop(k)`.
-clear(m)
+❌ clear(m)
+
+There is no analog.
+
+The easiest may to do this is to delete all items individually:
+
+```go
+for k := range m.Entries() {
+ m.Drop(k)
+}
+```
-n := len(m)
+✅ n := len(m)
+
+The analog is `n := m.Size()`.
-m2 := maps.Clone(m)
+❌ m2 := maps.Clone(m)
+
+There is no analog.
+
+The easiest way to do this currently is to make a new map, and manually add the items.
+
+```go
+m2 := cuckoo.Table[K, V]()
+
+for k, v := range m.Entries() {
+ m2.Put(k, v)
+}
+```
+
+This gets complicated by the various options available to the user.
+Furthermore, any custom `EqualFunc`, `keyFunc` or `Hash` is not transferred.
-maps.Copy(dst, src)
+❌ maps.Copy(dst, src)
+
+There is no analog.
+
+The simplest way to do this is with a for-loop.
+
+```go
+for k, v := range src.Entries() {
+ dst.Put(k, v)
+}
+```
+
+
+
+
+❌ ok := maps.Equal(m1, m2)
+
+There is no analog.
+
+Users have to manually check the key-value pairs to determine equality.
+
+
+
+
+❌ ok := maps.EqualFunc(m1, m2, fn)
+
+There is no analog.
+
+Users have to manually check the key-value pairs to determine equality.
+
+
+
+
+❌ maps.DeleteFunc(m, fn)
+
+There is no analog.
+
+Users have to manually delete keys.
+
+
+
+
+✅ it2 := maps.All(m)
+
+The analog is `it2 := m.Entries()`.
+
+
+
+
+⚠️ it := maps.Keys(m)
+
+There is no simple analog.
+
+A close neighbor is `it2 := m.Entries()`.
+Users can use this in a for-loop, and pick out just the keys:
+
+```go
+for k := range m.Entries() {
+ // ...
+}
+```
+
+
+
+
+⚠️ it := maps.Values(m)
+
+There is no simple analog.
+
+A close neighbor is `it2 := m.Entries()`.
+Users can use this in a for-loop, and pick out just the values:
+
+```go
+for _, v := range m.Entries() {
+ // ...
+}
+```
+
+
+
+
+❌ m := maps.Collect(seq)
+
+There is no analog.
+
+
+
+
+❌ maps.Insert(m, seq)
+
+There is no analog.
+
+
+
+## Target State
+
+### Solving Congruency
+
+The following changes will be made to accomodate for congruency:
+
+
+ok := maps.EqualFunc(m1, m2, fn)
+
+To solve this, we need a new function:
+
+```go
+func EqualFunc[K, V1, V2 any](t1 *Table[K, V1], t2 *Table[K, V2], eq func(V1, V2) bool) bool
+```
+
+This function is free, and not bound as a receiver function.
+(It is called `cuckoo.Equal(t1, t2)`, not `t1.Equals(t2)`.)
+The latter implies `t1` has authority, when in fact neither do.
+
+Equality will be defined as:
+
+1. Neither table has a key the other doesn't.
+2. Each key has the same value in each table.
+ Parameter `eq` determines this equality.
+
+Custom `EqualFunc`'s complicate this, as they modulate key identity in tables.
+If two tables may differ on whether two keys are different, this function might break.
+So, we must assume that:
+
+- Both tables have `EqualFunc`'s which 'agree' on the identity of the keys present in the tables.
+ Agreement is defined as: if two keys are distinct in one table, they are distinct in the other.
ok := maps.Equal(m1, m2)
-
+The addition of `cuckoo.EqualFunc` makes an implementation trivial:
-
-ok := maps.EqualFunc(m1, m2, fn)
+```go
+func Equal[K any, V comparable](t1, t2 *Table[K, V]) bool {
+ return EqualFunc(t1, t2, DefaultEqualFunc[V])
+}
+```
+
+To conform with the standard library, a new function should be added.
+Once again, the function is free because it is symmetric.
-
-
-maps.DeleteFunc(m, fn)
-
-
-
-
-it2 := maps.All(m)
-
-
-
-
-it := maps.Keys(m)
-
-
-
-
-it := maps.Values(m)
-
-
-
-
-m := maps.Collect(seq)
-
-
-
-
-maps.Insert(m, seq)
-
-
-
-## Target State