feat: progress up to this point
This commit is contained in:
+104
-3
@@ -1,5 +1,14 @@
|
||||
# Designing an Idiomatic API Interface
|
||||
|
||||
- [Designing an Idiomatic API Interface](#designing-an-idiomatic-api-interface)
|
||||
- [Current State](#current-state)
|
||||
- [Interface of the Built-in Map](#interface-of-the-built-in-map)
|
||||
- [Interface of `go-cuckoo`](#interface-of-go-cuckoo)
|
||||
- [Determining Congruency](#determining-congruency)
|
||||
- [Determining Familiarity](#determining-familiarity)
|
||||
- [Target State](#target-state)
|
||||
- [Solving Congruency](#solving-congruency)
|
||||
|
||||
We (the maintainers) built `go-cuckoo`'s API interface without design intent.
|
||||
Up until now, we paid more attention implementing the underlying functionality of the cuckoo hashing.
|
||||
|
||||
@@ -15,7 +24,7 @@ It should align closer to the following principles:
|
||||
|
||||
## Current State
|
||||
|
||||
### Interface of the built-in Map
|
||||
### Interface of the Built-in Map
|
||||
|
||||
Listed below is every interface provided by Go to the built-in map object.
|
||||
Also included, are the functions from the package `maps` in the standard library.
|
||||
@@ -23,7 +32,7 @@ Also included, are the functions from the package `maps` in the standard library
|
||||
<details>
|
||||
<summary>Interfaces</summary>
|
||||
|
||||
| # | built-in Interface | Description |
|
||||
| # | Built-in Interface | Description |
|
||||
| --- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1 | `m := make(map[K]V)` | Returns an empty map using the built-in `make()` function. |
|
||||
| 2 | `m := make(map[K]V, hint)` | Returns an empty map using `make()`, with a capacity 'hint'. This hint is how many items the map expects to hold, _not_ a measure of how large it is. |
|
||||
@@ -56,7 +65,7 @@ On the other hand, here is the current contract for `go-cuckoo`.
|
||||
<details>
|
||||
<summary>Interfaces</summary>
|
||||
|
||||
| # | built-in Interface | Description |
|
||||
| # | `go-cuckoo` Interface | Description |
|
||||
| --- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1 | `m := New(opts...)` | Creates a table using the default hash and equal function. The options configure its behavior. Confined to comparable keys. |
|
||||
| 2 | `m := NewBy(keyFunc, opts...)` | Like #1, but allows any key type. A `keyFunc` is used to derive a comparable key. |
|
||||
@@ -307,6 +316,98 @@ There is no analog.
|
||||
|
||||
</details>
|
||||
|
||||
### Determining Familiarity
|
||||
|
||||
We can categorize all existing table functionality by each interface's familiarity:
|
||||
|
||||
- ✅ Idiomatic: is clear, intuitive, and easily understood.
|
||||
- ❌ Non-idiomatic: is misleading; addressed in [Target State](#solving-congruency).
|
||||
|
||||
<details>
|
||||
<summary>✅ <code>m := New(opts...)</code></summary>
|
||||
|
||||
Criteria:
|
||||
|
||||
Noun/adjective form — Go constructors use NewX where X is a noun or adjective, not a verb or past participle (NewReaderSize, not NewSized)
|
||||
Names what the user provides — the suffix should hint at the distinguishing parameter (NewBufferString tells you it takes a string)
|
||||
Progression is readable — the three names together should imply simple → intermediate → advanced
|
||||
Not misleadingly generic — NewWith or NewConfig could mean anything
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>m := NewBy(keyFunc, opts...)</code></summary>
|
||||
|
||||
- Use `NewKeyed()`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>m := NewCustom(hashA, hashB, equalFunc, opts...)</code></summary>
|
||||
|
||||
- Use `NewHashed()`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>❌ <code>seq := m.Entries()</code></summary>
|
||||
|
||||
- Call it `All()`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>v := m.Find(k)</code></summary>
|
||||
|
||||
- Call it `m.Lookup()`. The name `m.Find` implies a search algorithm.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>v, ok := m.Get(k)</code></summary>
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>ok := m.Has(k)</code></summary>
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>❌ <code>err := m.Put(k, v)</code></summary>
|
||||
|
||||
- Call it `Set()`.
|
||||
- No built-in library consensus, but 3rd party packages prefer `Set()`.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>❌ <code>n := m.Size()</code></summary>
|
||||
|
||||
- Call it `Len()`.
|
||||
- Size is a Java idiom.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>✅ <code>str := m.String()</code></summary>
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>❌ <code>cap := m.TotalCapacity()</code></summary>
|
||||
|
||||
- Remove. This is an implementation detail.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>❌ <code>ok := m.Drop(k)</code></summary>
|
||||
|
||||
- Call it `Delete()`.
|
||||
|
||||
</details>
|
||||
|
||||
## Target State
|
||||
|
||||
### Solving Congruency
|
||||
|
||||
Reference in New Issue
Block a user