Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ links = InterLinks("Julia" => "https://docs.julialang.org/en/v1/")

PAGES = [
"Getting Started" => "index.md",
"Using Bijections" => "usage.md",
"Usage" => "usage.md",
"Operations" => "operations.md",
"Mutable Objects" => "mutable.md",
"API" => "api.md",
Expand Down
86 changes: 29 additions & 57 deletions docs/src/mutable.md
Original file line number Diff line number Diff line change
@@ -1,85 +1,57 @@
# [Bijections for Mutable Structures](@id mutable)
# [Mutable keys](@id mutable)

## Mutating keys/values can lead to corruption
```@setup example
using Bijections
```

The safest use of a `Bijection` is when the keys and values are immutable.
The safest use of a `Bijection` is when the keys and values are immutable.
If a mutable key or value in a `Bijection` is altered, the bijective property
can be compromised. Here is an example:
```
julia> b = Bijection{Int, Vector{Int}}();

julia> b[1] = [1,2,3]
3-element Vector{Int64}:
1
2
3

julia> b[2] = [1,2,4]
3-element Vector{Int64}:
1
2
4

julia> b[2][3] = 3
3

julia> b
Bijection{Int64, Vector{Int64}, Dict{Int64, Vector{Int64}}, Dict{Vector{Int64}, Int64}} with 2 entries:
2 => [1, 2, 3]
1 => [1, 2, 3]
```@repl example
b = Bijection{Int, Vector{Int}}();
b[1] = [1,2,3]
b[2] = [1,2,4]
b[2][3] = 3
b
```

Notice that `b` contains a repeated value and therefore is not bijective.

Some strategies to avoid this problem include:

* Only use immutable keys and values (such as numbers and strings).
* Use copies of the keys/values in the `Bijection`.
* Don't modify keys/values saved in the `Bijection`.

In case none of these is a viable option, we provide the following additional alternative.


In case none of these is a viable option, you may need to use an `IdDict`.

## Keys/values as objects

The issue in the example presented above is that distinct Julia objects may be equal, but not the same object. For example:
```
julia> v = [1,2,3];

julia> w = [1,2,3];

julia> v==w
true

julia> v===w
false
```@repl example
v = [1,2,3];
w = [1,2,3];
v==w
v===w
```

We may wish to create a `Bijection` in which the keys or values are permitted to be equal, but are distinct objects. Julia's `IdDict` is a variation of `Dict` in which keys/values are considered different if they are distinct object (even if they hold the same data). To replicate this behavior in a `Bijection` use this longer form constructor:
```

```julia
Bijection{K, V, IdDict{K,V}, IdDict{V,K}}()
```

where `K` is the type of the keys and `V` is the type of the values.

For example:
```
julia> b = Bijection{Vector{Int}, String, IdDict{Vector{Int},String}, IdDict{String,Vector{Int}}}();

julia> b[ [1,2,3] ] = "alpha";

julia> b[ [1,2,3] ] = "beta";

julia> b("alpha") == b("beta")
true

julia> b("alpha") === b("beta")
false

julia> keys(b)
KeySet for a IdDict{Vector{Int64}, String} with 2 entries. Keys:
[1, 2, 3]
[1, 2, 3]

julia> Set(keys(b))
Set{Vector{Int64}} with 1 element:
[1, 2, 3]
```@repl example
b = Bijection{Vector{Int}, String, IdDict{Vector{Int},String}, IdDict{String,Vector{Int}}}();
b[ [1,2,3] ] = "alpha";
b[ [1,2,3] ] = "beta";
b("alpha") == b("beta")
b("alpha") === b("beta")
keys(b)
```
2 changes: 1 addition & 1 deletion docs/src/usage.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Using `Bijections`
# Usage

```@setup example
using Bijections
Expand Down
Loading