Skip to content

Commit 9f305fe

Browse files
extending documentation
1 parent 2d5799c commit 9f305fe

File tree

9 files changed

+917
-740
lines changed

9 files changed

+917
-740
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@ Many effects are provided, ranging from `Option`, which can be handled very simp
1616

1717
The package was presented at JuliaCon 2021.
1818
* find the video [at youtube](TODO)
19-
* find the presentation [in this binder](https://mybinder.org/v2/gh/JuliaFunctional/ExtensibleEffects.jl/main?filepath=docs%2Fjupyter%2FMonad2.0%2C%20aka%20Algebraic%20Effects%20-%20ExtensibleEffects.jl.ipynb). The binder link provides you with a Jupyter environment where you can actually run julia code and explore the ExtensibleEffects further. The link will autostart into the presentation itself, clicking the big X on the top left will exit the presentation mode and bring you to a standard Jupyter notebook.
19+
* find the presentation material in this binder [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/JuliaFunctional/ExtensibleEffects.jl/main?filepath=docs%2Fjupyter%2FMonad2.0%2C%20aka%20Algebraic%20Effects%20-%20ExtensibleEffects.jl.ipynb). The binder link provides you with a Jupyter environment where you can actually run julia code and explore the ExtensibleEffects further. The link will autostart into the presentation itself, clicking the big X on the top left will exit the presentation mode and bring you to a standard Jupyter notebook.

docs/make.jl

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ makedocs(;
1515
),
1616
pages=[
1717
"Home" => "index.md",
18-
"Manual" => "manual.md",
18+
"Manual" => [
19+
"Introduction" => "manual-introduction.md",
20+
"Effects" => "manual-effects.md",
21+
"How it works" => "manual-how-it-works.md",
22+
"JuliaCon 2021" => "manual-juliacon.md",
23+
],
1924
"Library" => "library.md",
2025
],
2126
)

docs/src/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ Many effects are provided, ranging from `Option`, which can be handled very simp
1616

1717
The package was presented at JuliaCon 2021.
1818
* find the video [at youtube](TODO)
19-
* find the presentation [in this binder](https://mybinder.org/v2/gh/JuliaFunctional/ExtensibleEffects.jl/main?filepath=docs%2Fjupyter%2FMonad2.0%2C%20aka%20Algebraic%20Effects%20-%20ExtensibleEffects.jl.ipynb). The binder link provides you with a Jupyter environment where you can actually run julia code and explore the ExtensibleEffects further. The link will autostart into the presentation itself, clicking the big X on the top left will exit the presentation mode and bring you to a standard Jupyter notebook.
19+
* find the presentation in this binder [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/JuliaFunctional/ExtensibleEffects.jl/main?filepath=docs%2Fjupyter%2FMonad2.0%2C%20aka%20Algebraic%20Effects%20-%20ExtensibleEffects.jl.ipynb). The binder link provides you with a Jupyter environment where you can actually run julia code and explore the ExtensibleEffects further. The link will autostart into the presentation itself, clicking the big X on the top left will exit the presentation mode and bring you to a standard Jupyter notebook.
2020

2121
## Manual Outline
2222

2323
```@contents
24-
Pages = ["manual.md"]
24+
Pages = ["manual-introduction.md", "manual-effects.md", "manual-how-it-works.md", "manual-juliacon.md"]
2525
```
2626

2727
## [Library Index](@id main-index)

docs/src/library.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,8 @@ autorun
9292
NoAutoRun
9393
```
9494

95-
other
95+
runlast
9696
```@docs
97-
runhandler
9897
runlast
9998
runlast_ifpossible
10099
```

docs/src/manual-effects.md

Lines changed: 402 additions & 0 deletions
Large diffs are not rendered by default.

docs/src/manual-how-it-works.md

Lines changed: 346 additions & 0 deletions
Large diffs are not rendered by default.

docs/src/manual-introduction.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
```@meta
2+
CurrentModule = ExtensibleEffects
3+
DocTestSetup = quote
4+
using ExtensibleEffects
5+
end
6+
```
7+
8+
# Introduction
9+
10+
Welcome to `ExtensibleEffects.jl`. This package provides an implementation of Extensible Effects. We follow the approach presented in the paper [Freer Monads, More Extensible Effects](http://okmij.org/ftp/Haskell/extensible/more.pdf) which already has an [Haskell implementation](https://hackage.haskell.org/package/freer-effects) as well as a [Scala implementation](https://github.com/atnos-org/eff).
11+
12+
This Julia implementation is massively simplified, and hence can also serve as a good introduction to get to know the details behind Extensible Effects.
13+
14+
Many effects are provided, ranging from `Option`, which can be handled very simple, to the very limit of what can be supported by ExtensibleEffects - the `State` effect. Still, all the implementations are short and easy to follow, so look into the `instances.jl` file to see how to write your own Effect handlings.
15+
16+
## Installation
17+
18+
```julia
19+
using Pkg
20+
pkg"add ExtensibleEffects"
21+
```
22+
23+
Use it like
24+
25+
```julia
26+
using ExtensibleEffects
27+
```
28+
29+
## Usage
30+
31+
The power of ExtensibleEffects.jl is to combine multiple different contexts into one *composable* super context abstraction. Its key macro is
32+
```julia
33+
@syntax_eff begin
34+
a = an_effect
35+
b = another_effect
36+
@pure a, b
37+
end
38+
```
39+
which provides a syntax similar to `TypeClasses.@syntax_flatmap` for working seamlessly with effects. See its documentation [`@syntax_eff`](@ref) for more details.
40+
41+
There is another version of the key macro called [`@syntax_eff_noautorun`](@ref), which as the name indicates disables the autorun feature of `@syntax_eff`. You may need this in case you don't want to execute your effects immediately, but staying in the meta-monad `ExtensibleEffects.Eff` for further composition with other effectful algorithms. [Effects](@ref) and [How does it actually work?](@ref) also provide some examples of using `@syntax_eff_noautorun` for explanation purposes.
42+
43+
You can also specifically disable the autorun feature for individual effects only by using the [`noautorun`](@ref) function like
44+
```julia
45+
@syntax_eff noautorun(Vector) begin
46+
...
47+
end
48+
```
49+
which in this case would not handle the `Vector` effect.
50+
51+
----------------------
52+
53+
In addition to `@syntax_eff`, `@syntax_eff_noautorun` and `@syntax_eff noautorun(effect1, effect2, ...)` the package reexports all **data types** from [`DataTypesBasic.jl`](https://github.com/JuliaFunctional/DataTypesBasic.jl) and [`TypeClasses.jl`](https://github.com/JuliaFunctional/TypeClasses.jl)
54+
55+
For the more complicated effects `Writer`, `Callable`, `ContextManager` and `State` extra handlers and further helper macros are provided. Take a look at [Example](@ref) and [Effects](@ref) for further details.
56+
57+
58+
## Example
59+
60+
To start small, you can use `ExtensibleEffects.@syntax_eff` instead of `TypeClasses.@syntax_flatmap`.
61+
62+
```jldoctest
63+
julia> @syntax_eff begin
64+
a = [1, 2]
65+
b = ["one", "two"]
66+
@pure a, b
67+
end
68+
4-element Vector{Tuple{Int64, String}}:
69+
(1, "one")
70+
(1, "two")
71+
(2, "one")
72+
(2, "two")
73+
74+
julia> option_example(n) = @syntax_eff begin
75+
a = Option(n)
76+
b = @Try isodd(a) ? error("fail") : a+1
77+
@pure a, b
78+
end
79+
option_example (generic function with 1 method)
80+
81+
julia> option_example(nothing)
82+
Const(nothing)
83+
84+
julia> option_example(41)
85+
Const(Thrown(ErrorException("fail")))
86+
87+
julia> option_example(42)
88+
Identity((42, 43))
89+
```
90+
91+
Some monads of TypeClasses need a bit more work to translate them into effects. They need little extra wrappers, but nothing fancy, just use their respective `@run...` macro.
92+
93+
Let's directly jump to super complicated interactions of many effects at once. Please experiment with this little example. Take effects out, reorder them, etc.
94+
95+
```jldoctest
96+
julia> # simple ContextManager for example purposes
97+
create_context(x) = @ContextManager continuation -> begin
98+
println("before $x")
99+
result = continuation(x)
100+
println("after $x")
101+
result
102+
end
103+
create_context (generic function with 1 method)
104+
105+
julia> contextmanager_callable_state = @runcontextmanager @runcallable @runstate @syntax_eff begin
106+
co = create_context(4)
107+
ve = collect(1:co)
108+
st = State(s -> (ve+s, 2s))
109+
op = isodd(st) ? Option(100) : Option()
110+
ca = Callable(x -> "x = $x, st = $st, op = $op")
111+
@pure [co, ve, st, op, ca]
112+
end;
113+
114+
julia> # running the contextmanager
115+
result, nextstate = run(contextmanager_callable_state) do value
116+
@show value
117+
end |>
118+
# calling the callable
119+
callable_state -> callable_state("hello") |>
120+
# providing initial state for the state
121+
state -> run(state, 11);
122+
before 4
123+
value = (Option{Vector{Any}}[Const(nothing), Const(nothing), Identity(Any[4, 3, 47, 100, "x = hello, st = 47, op = 100"]), Const(nothing)], 176)
124+
after 4
125+
126+
julia> result
127+
4-element Vector{Option{Vector{Any}}}:
128+
Const(nothing)
129+
Const(nothing)
130+
Identity(Any[4, 3, 47, 100, "x = hello, st = 47, op = 100"])
131+
Const(nothing)
132+
133+
julia> nextstate
134+
176
135+
```
136+
137+
Welcome to fully composable effects. [Effects](@ref) and [How does it actually work?](@ref) can provide you more details.
138+
139+
140+
## Core Interface `eff_applies`, `eff_pure`, `eff_flatmap`
141+
142+
All effects and effect handlers need to overwrite the three core functions. We specify them by using `Vector` as an example:
143+
144+
145+
| core function | default | description |
146+
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
147+
| `eff_applies(handler::Type{<:Vector}, effectful::Vector) = true` | there is no default | specify on which values the handler applies (the handler Vector applies to Vector of course) |
148+
| `eff_pure(handler::Type{<:Vector}, value) = [value]` | defaulting to `TypeClasses.pure` (enough for Vector) | wrap a plain value into the Monad of the handler, here Vector. |
149+
| `eff_flatmap(continuation, effectful::Vector)` | defaults to using `map`, `flatmap`, and `flip_types` from `TypeClasses` (this is enough for `Vector`) | apply a continuation to the current effect (here again Vector as an example). The key difference to plain`TypeClasses.flatmap` is that `continuation` does not return a plain `Vector`, but a `Eff{Vector}`. Applying this `continuation` with a plain `map` would lead `Vector{Eff{Vector}}`. However, `eff_flatmap` needs to return an `Eff{Vector}` instead. |
150+
151+
152+
## Future Work
153+
154+
Julia's type-inference seems to have quite some trouble inferring through the core algorithms of ExtensibleEffects. Hence in case type-inference and speed is crucial to your effectful/monadic code, we recommend to use [`TypeClasses.jl`](https://github.com/JuliaFunctional/TypeClasses.jl) as of now. The monads of TypeClasses.jl do not compose that well as the effects in ExtensibleEffects.jl, but type-inference is much simpler.

docs/src/manual-juliacon.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Presentation at JuliaCon 2021
2+
3+
The package was presented at JuliaCon 2021.
4+
* find the video [at youtube](TODO)
5+
* find the presentation in this binder [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/JuliaFunctional/ExtensibleEffects.jl/main?filepath=docs%2Fjupyter%2FMonad2.0%2C%20aka%20Algebraic%20Effects%20-%20ExtensibleEffects.jl.ipynb). The binder link provides you with a Jupyter environment where you can actually run julia code and explore the ExtensibleEffects further. The link will autostart into the presentation itself, clicking the big X on the top left will exit the presentation mode and bring you to a standard Jupyter notebook.

0 commit comments

Comments
 (0)