Skip to content

Commit a039ecc

Browse files
authored
More sub-headings in README.md.
1 parent a648810 commit a039ecc

File tree

1 file changed

+46
-2
lines changed

1 file changed

+46
-2
lines changed

README.md

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ const { tuple } = require("immutable-tuple");
3030
const tuple = require("immutable-tuple").tuple;
3131
```
3232

33+
### Constructing `tuple`s
34+
3335
The `tuple` function takes any number of arguments and returns a unique, immutable object that inherits from `tuple.prototype` and is guaranteed to be `===` any other `tuple` object created from the same sequence of arguments:
3436

3537
```js
@@ -43,6 +45,8 @@ assert.strictEqual(t1 === t2, true);
4345
assert.strictEqual(t1, t2);
4446
```
4547

48+
### Own `tuple` properties
49+
4650
The `tuple` object has a fixed numeric `.length` property, and its elements may be accessed using array index notation:
4751

4852
```js
@@ -52,6 +56,8 @@ t1.forEach((x, i) => {
5256
});
5357
```
5458

59+
### Nested `tuple`s
60+
5561
Since `tuple` objects are just another kind of JavaScript object, naturally `tuple`s can contain other `tuple`s:
5662

5763
```js
@@ -68,6 +74,8 @@ assert.strictEqual(
6874

6975
However, because tuples are immutable and always distinct from any of their arguments, it is not possible for a `tuple` to contain itself, nor to contain another `tuple` that contains the original `tuple`, and so forth.
7076

77+
### Constant time `===` equality
78+
7179
Since `tuple` objects are identical when (and only when) their elements are identical, any two tuples can be compared for equality in constant time, regardless of how many elements they contain.
7280

7381
This behavior also makes `tuple` objects useful as keys in a `Map`, or elements in a `Set`, without any extra hashing or equality logic:
@@ -87,6 +95,8 @@ if (info) {
8795
}
8896
```
8997

98+
### `Array` methods
99+
90100
Every non-destructive method of `Array.prototype` is supported by `tuple.prototype`, including `sort` and `reverse`, which return a modified copy of the `tuple` without altering the original:
91101

92102
```js
@@ -106,6 +116,8 @@ assert.strictEqual(
106116
);
107117
```
108118

119+
### Shallow immutability
120+
109121
While the identity, number, and order of elements in a `tuple` is fixed, please note that the contents of the individual elements are not frozen in any way:
110122

111123
```js
@@ -114,11 +126,41 @@ tuple(1, "asdf", obj)[2].asdf = "oyez";
114126
assert.strictEqual(obj.asdf, "oyez");
115127
```
116128

117-
## How it works
129+
### Iterability
130+
131+
Every `tuple` object is array-like and iterable, so `...` spreading and destructuring work as they should:
132+
133+
```js
134+
func(...tuple(a, b));
135+
func.apply(this, tuple(c, d, e));
136+
137+
assert.deepEqual(
138+
[1, ...tuple(2, 3), 4],
139+
[1, 2, 3, 4]
140+
);
141+
142+
assert.strictEqual(
143+
tuple(1, ...tuple(2, 3), 4),
144+
tuple(1, 2, 3, 4)
145+
);
146+
147+
const [a, [_, b]] = tuple(1, tuple(2, 3), 4);
148+
assert.strictEqual(a, 1);
149+
assert.strictEqual(b, 3);
150+
```
151+
152+
### `tuple.isTuple(value)`
153+
154+
Since the `immutable-tuple` package could be installed multiple times in an application, there is no guarantee that the `tuple` constructor or `tuple.prototype` will be unique, so `value instanceof tuple` is unreliable. Instead, to test if a value is a `tuple`, you should use `tuple.isTuple(value)`.
155+
156+
Fortunately, even if your application uses multiple different `tuple` constructors from different copies of this library, the resulting `tuple` instances will still be `===` each other when their elements are the same. This is especially convenient given that this library provides both a CommonJS bundle and an ECMAScript module bundle, and some module systems might accidentally load those bundles simultaneously.
157+
158+
159+
## Implementation details
118160

119161
Thanks to [Docco](http://ashkenas.com/docco/), you can read my implementation comments side-by-side with the actual code by visiting [the GitHub pages site](https://benjamn.github.io/immutable-tuple/) for this repository.
120162

121-
### Garbage collection
163+
### Instance pooling (internalization)
122164

123165
Any data structure that guarantees `===` equality based on structural equality must maintain some sort of internal pool of previously encountered instances.
124166

@@ -148,6 +190,8 @@ function tuple(...items) {
148190

149191
This implementation is pretty good, because it requires only linear time (_O_(`items.length`)) to determine if a `tuple` has been created previously for the given `items`, and you can't do better than linear time (asymptotically speaking) because you have to look at all the items. This code is also useful as an illustration of exactly how the `tuple` constructor behaves, in case you weren't satisfied by my examples in the previous section.
150192

193+
### Garbage collection
194+
151195
However, this simple implementation has a serious problem: in a garbage-collected language like JavaScript, the `pool` itself will retain references to all `tuple` objects ever created, which prevents `tuple` objects and their elements (which may be very large objects) from ever being reclaimed by the garbage collector, even after they become unreachable by any other means. In other words, storing objects in this kind of `tuple` would inevitably cause **memory leaks**.
152196

153197
To solve this problem, it's tempting to try changing `Map` to [`WeakMap`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap) here:

0 commit comments

Comments
 (0)