Skip to content

Commit e751db3

Browse files
committed
Tidy up docs slightly
1 parent 0102653 commit e751db3

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

docs/src/index.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,17 @@ Libtask.TapedTask
77

88
The functions discussed the above docstring (in addition to [`TapedTask`](@ref) itself) form the
99
public interface of Libtask.jl.
10-
They divide neatly into two kinds of functions: those which are used to construct and
11-
manipulate [`TapedTask`](@ref)s, and those which are intended to be used _inside_ a
10+
They divide neatly into two kinds of functions: those which are used to manipulate
11+
[`TapedTask`](@ref)s, and those which are intended to be used _inside_ a
1212
[`TapedTask`](@ref).
13-
1413
First, manipulation of [`TapedTask`](@ref)s:
1514
```@docs; canonical=true
1615
Libtask.consume
1716
Base.copy(::Libtask.TapedTask)
1817
Libtask.set_dynamic_scope!
1918
```
2019

21-
The functions which enable special functionality inside a [`TapedTask`](@ref)s are:
20+
Functions for use inside a [`TapedTask`](@ref)s are:
2221
```@docs; canonical=true
2322
Libtask.produce
2423
Libtask.get_dynamic_scope

src/copyable_task.jl

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ There are three central features of a `TapedTask`, which we demonstrate via thre
5252
5353
## Resumption
5454
55+
The function [`Libtask.produce`](@ref) has a special meaning in Libtask. You can insert it
56+
into regular Julia functions anywhere that you like. For example
5557
```jldoctest tt
5658
julia> function f()
5759
for t in 1:2
@@ -63,60 +65,96 @@ julia> function f()
6365
f (generic function with 1 method)
6466
```
6567
68+
If you construct a `TapedTask` from `f`, and call [`Libtask.consume`](@ref) on it, you'll
69+
see
6670
```jldoctest tt
6771
julia> t = TapedTask(nothing, f);
6872
6973
julia> consume(t)
7074
1
7175
```
76+
The semantics of this are that [`Libtask.consume`](@ref) runs the function `f` until it
77+
reaches the call to [`Libtask.produce`](@ref), at which point it will return the argument
78+
to [`Libtask.produce`](@ref).
7279
80+
Subsequent calls to [`Libtask.produce`](@ref) will _resume_ execution of `f` immediately
81+
after the last [`Libtask.produce`](@ref) statement that was hit.
7382
```jldoctest tt
7483
julia> consume(t)
7584
2
85+
```
7686
87+
When there are no more [`Libtask.produce`](@ref) statements to hit, calling
88+
[`Libtask.consume`](@ref) will return `nothing`:
89+
```jldoctest tt
7790
julia> consume(t)
7891
7992
```
8093
8194
## Copying
8295
96+
[`TapedTask`](@ref)s can be copied. Doing so creates a completely independent object.
97+
For example:
8398
```jldoctest tt
8499
julia> t2 = TapedTask(nothing, f);
85100
86101
julia> consume(t2)
87102
1
88103
```
89104
105+
If we make a copy and advance its state, it produces the same value that the original would
106+
have produced:
90107
```jldoctest tt
91108
julia> t3 = copy(t2);
92109
93110
julia> consume(t3)
94111
2
112+
```
95113
114+
Moreover, advancing the state of the copy has not advanced the state of the original,
115+
because they are completely independent copies:
116+
```jldoctest tt
96117
julia> consume(t2)
97118
2
98119
```
99120
100121
## Scoped Values
101122
102-
```jldoctest
123+
It is often desirable to permit a copy of a task and the original to differ in very specific
124+
ways. For example, in the context of Sequential Monte Carlo, you might want the only
125+
difference between two copies to be their random number generator.
126+
127+
A generic mechanism is available to achieve this. [`Libtask.get_dynamic_scope`](@ref) and
128+
[`Libtask.set_dynamic_scope!`](@ref) let you set and retrieve a variable which is specific
129+
to a given [`Libtask.TapedTask`](@ref). The former can be called inside a function:
130+
```jldoctest sv
103131
julia> function f()
104132
produce(get_dynamic_scope())
105133
produce(get_dynamic_scope())
106134
return nothing
107135
end
108136
f (generic function with 1 method)
137+
```
109138
139+
The first argument to [`Libtask.TapedTask`](@ref) is the value that
140+
[`Libtask.get_dynamic_scope`](@ref) will return:
141+
```jldoctest sv
110142
julia> t = TapedTask(1, f);
111143
112144
julia> consume(t)
113145
1
146+
```
114147
148+
The value that it returns can be changed between [`Libtask.consume`](@ref) calls:
149+
```jldoctest sv
115150
julia> set_dynamic_scope!(t, 2)
116151
117152
julia> consume(t)
118153
2
119154
```
155+
156+
`Int`s have been used here, but it is permissible to set the value returned by
157+
[`Libtask.get_dynamic_scope`](@ref) to anything you like.
120158
"""
121159
function TapedTask(dynamic_scope::Any, fargs...)
122160
mc, count_ref = build_callable(Base.code_ircode_by_type(typeof(fargs))[1][1])

0 commit comments

Comments
 (0)