aboutsummaryrefslogtreecommitdiff
path: root/src/carboxyl/lib.rs.html
blob: 912fa0d491e4574d78d6fb542018c6e343ac617e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta name="generator" content="rustdoc">
    <meta name="description" content="Source to the Rust file `/home/travis/.cargo/registry/src/github.com-0a35038f75765ae4/carboxyl-0.1.1/src/lib.rs`.">
    <meta name="keywords" content="rust, rustlang, rust-lang">

    <title>lib.rs.html -- source</title>

    <link rel="stylesheet" type="text/css" href="../../main.css">

    
    
</head>
<body class="rustdoc">
    <!--[if lte IE 8]>
    <div class="warning">
        This old browser is unsupported and will most likely display funky
        things.
    </div>
    <![endif]-->

    

    <section class="sidebar">
        
        
    </section>

    <nav class="sub">
        <form class="search-form js-only">
            <div class="search-container">
                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Click or press 'S' to search, '?' for more options..."
                       type="search">
            </div>
        </form>
    </nav>

    <section id='main' class="content source"><pre class="line-numbers"><span id="1">  1</span>
<span id="2">  2</span>
<span id="3">  3</span>
<span id="4">  4</span>
<span id="5">  5</span>
<span id="6">  6</span>
<span id="7">  7</span>
<span id="8">  8</span>
<span id="9">  9</span>
<span id="10"> 10</span>
<span id="11"> 11</span>
<span id="12"> 12</span>
<span id="13"> 13</span>
<span id="14"> 14</span>
<span id="15"> 15</span>
<span id="16"> 16</span>
<span id="17"> 17</span>
<span id="18"> 18</span>
<span id="19"> 19</span>
<span id="20"> 20</span>
<span id="21"> 21</span>
<span id="22"> 22</span>
<span id="23"> 23</span>
<span id="24"> 24</span>
<span id="25"> 25</span>
<span id="26"> 26</span>
<span id="27"> 27</span>
<span id="28"> 28</span>
<span id="29"> 29</span>
<span id="30"> 30</span>
<span id="31"> 31</span>
<span id="32"> 32</span>
<span id="33"> 33</span>
<span id="34"> 34</span>
<span id="35"> 35</span>
<span id="36"> 36</span>
<span id="37"> 37</span>
<span id="38"> 38</span>
<span id="39"> 39</span>
<span id="40"> 40</span>
<span id="41"> 41</span>
<span id="42"> 42</span>
<span id="43"> 43</span>
<span id="44"> 44</span>
<span id="45"> 45</span>
<span id="46"> 46</span>
<span id="47"> 47</span>
<span id="48"> 48</span>
<span id="49"> 49</span>
<span id="50"> 50</span>
<span id="51"> 51</span>
<span id="52"> 52</span>
<span id="53"> 53</span>
<span id="54"> 54</span>
<span id="55"> 55</span>
<span id="56"> 56</span>
<span id="57"> 57</span>
<span id="58"> 58</span>
<span id="59"> 59</span>
<span id="60"> 60</span>
<span id="61"> 61</span>
<span id="62"> 62</span>
<span id="63"> 63</span>
<span id="64"> 64</span>
<span id="65"> 65</span>
<span id="66"> 66</span>
<span id="67"> 67</span>
<span id="68"> 68</span>
<span id="69"> 69</span>
<span id="70"> 70</span>
<span id="71"> 71</span>
<span id="72"> 72</span>
<span id="73"> 73</span>
<span id="74"> 74</span>
<span id="75"> 75</span>
<span id="76"> 76</span>
<span id="77"> 77</span>
<span id="78"> 78</span>
<span id="79"> 79</span>
<span id="80"> 80</span>
<span id="81"> 81</span>
<span id="82"> 82</span>
<span id="83"> 83</span>
<span id="84"> 84</span>
<span id="85"> 85</span>
<span id="86"> 86</span>
<span id="87"> 87</span>
<span id="88"> 88</span>
<span id="89"> 89</span>
<span id="90"> 90</span>
<span id="91"> 91</span>
<span id="92"> 92</span>
<span id="93"> 93</span>
<span id="94"> 94</span>
<span id="95"> 95</span>
<span id="96"> 96</span>
<span id="97"> 97</span>
<span id="98"> 98</span>
<span id="99"> 99</span>
<span id="100">100</span>
<span id="101">101</span>
<span id="102">102</span>
<span id="103">103</span>
<span id="104">104</span>
<span id="105">105</span>
<span id="106">106</span>
<span id="107">107</span>
<span id="108">108</span>
<span id="109">109</span>
<span id="110">110</span>
<span id="111">111</span>
<span id="112">112</span>
<span id="113">113</span>
<span id="114">114</span>
<span id="115">115</span>
<span id="116">116</span>
<span id="117">117</span>
<span id="118">118</span>
<span id="119">119</span>
<span id="120">120</span>
<span id="121">121</span>
<span id="122">122</span>
<span id="123">123</span>
<span id="124">124</span>
<span id="125">125</span>
<span id="126">126</span>
<span id="127">127</span>
<span id="128">128</span>
<span id="129">129</span>
<span id="130">130</span>
<span id="131">131</span>
<span id="132">132</span>
<span id="133">133</span>
<span id="134">134</span>
<span id="135">135</span>
<span id="136">136</span>
<span id="137">137</span>
<span id="138">138</span>
<span id="139">139</span>
<span id="140">140</span>
<span id="141">141</span>
<span id="142">142</span>
<span id="143">143</span>
<span id="144">144</span>
<span id="145">145</span>
<span id="146">146</span>
<span id="147">147</span>
<span id="148">148</span>
<span id="149">149</span>
<span id="150">150</span>
<span id="151">151</span>
<span id="152">152</span>
<span id="153">153</span>
<span id="154">154</span>
<span id="155">155</span>
<span id="156">156</span>
<span id="157">157</span>
<span id="158">158</span>
<span id="159">159</span>
<span id="160">160</span>
<span id="161">161</span>
</pre><pre class='rust '>
<span class='doccomment'>//! *Carboxyl* provides primitives for functional reactive programming in Rust.</span>
<span class='doccomment'>//! It draws inspiration from the [Sodium][sodium] libraries and Push-Pull FRP,</span>
<span class='doccomment'>//! as described by [Elliott (2009)][elliott_push_pull].</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! [sodium]: https://github.com/SodiumFRP/sodium/</span>
<span class='doccomment'>//! [elliott_push_pull]: http://conal.net/papers/push-pull-frp/push-pull-frp.pdf</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! # Overview</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! Functional reactive programming (FRP) is a composable and modular</span>
<span class='doccomment'>//! abstraction for creating dynamic and reactive systems. In its most general</span>
<span class='doccomment'>//! form it models these systems as a composition of two basic primitives:</span>
<span class='doccomment'>//! *streams* are a series of singular events and *signals* are continuously</span>
<span class='doccomment'>//! changing values.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! *Carboxyl* is an imperative, hybrid push- and pull-based implementation of</span>
<span class='doccomment'>//! FRP. Streams and the discrete components of signals are data-driven, i.e.</span>
<span class='doccomment'>//! whenever an event occurs the resulting changes are propagated to everything</span>
<span class='doccomment'>//! that depends on it.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! However, the continuous components of signals are demand-driven. Internally,</span>
<span class='doccomment'>//! *Carboxyl* stores the state of a signal as a function. This function has to</span>
<span class='doccomment'>//! be evaluated by consumers of a signal to obtain a concrete value.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! Nonetheless, *Carboxyl* has no explicit notion of time. Its signals are</span>
<span class='doccomment'>//! functions that can be evaluated at any time, but they do not carry any</span>
<span class='doccomment'>//! inherent notion of time. Synchronization and atomicity is achieved by a</span>
<span class='doccomment'>//! transaction system.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! # Functional reactive primitives</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! This library provides two basic types: `Stream` and `Signal`. A stream is a</span>
<span class='doccomment'>//! discrete sequence of events, a signal is a container for values that change</span>
<span class='doccomment'>//! (discretely) over time.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! The FRP primitives are mostly implemented as methods of the basic types to</span>
<span class='doccomment'>//! ease method chaining, except for the various lifting functions, as they do</span>
<span class='doccomment'>//! not really belong to any type in particular.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! In addition, the `Sink` type allows one to create a stream of events by</span>
<span class='doccomment'>//! sending values into it. It is the only way to create a stream from scratch,</span>
<span class='doccomment'>//! i.e. without using any of the other primitives.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! # Usage example</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! Here is a simple example of how you can use the primitives provided by</span>
<span class='doccomment'>//! *Carboxyl*. First of all, events can be sent into a *sink*. From a sink one</span>
<span class='doccomment'>//! can create a *stream* of events. Streams can also be filtered, mapped and</span>
<span class='doccomment'>//! merged. One can e.g. hold the last event from a stream as a signal.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//! use carboxyl::Sink;</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! let sink = Sink::new();</span>
<span class='doccomment'>//! let stream = sink.stream();</span>
<span class='doccomment'>//! let signal = stream.hold(3);</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! // The current value of the signal is initially 3</span>
<span class='doccomment'>//! assert_eq!(signal.sample(), 3);</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! // When we fire an event, the signal get updated accordingly</span>
<span class='doccomment'>//! sink.send(5);</span>
<span class='doccomment'>//! assert_eq!(signal.sample(), 5);</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! One can also directly iterate over the stream instead of holding it in a</span>
<span class='doccomment'>//! signal:</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//! # use carboxyl::Sink;</span>
<span class='doccomment'>//! # let sink = Sink::new();</span>
<span class='doccomment'>//! # let stream = sink.stream();</span>
<span class='doccomment'>//! let mut events = stream.events();</span>
<span class='doccomment'>//! sink.send(4);</span>
<span class='doccomment'>//! assert_eq!(events.next(), Some(4));</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! Streams and signals can be combined using various primitives. We can map a</span>
<span class='doccomment'>//! stream to another stream using a function:</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//! # use carboxyl::Sink;</span>
<span class='doccomment'>//! # let sink: Sink&lt;i32&gt; = Sink::new();</span>
<span class='doccomment'>//! # let stream = sink.stream();</span>
<span class='doccomment'>//! let squares = stream.map(|x| x * x).hold(0);</span>
<span class='doccomment'>//! sink.send(4);</span>
<span class='doccomment'>//! assert_eq!(squares.sample(), 16);</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! Or we can filter a stream to create a new one that only contains events that</span>
<span class='doccomment'>//! satisfy a certain predicate:</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//! # use carboxyl::Sink;</span>
<span class='doccomment'>//! # let sink: Sink&lt;i32&gt; = Sink::new();</span>
<span class='doccomment'>//! # let stream = sink.stream();</span>
<span class='doccomment'>//! let negatives = stream.filter(|&amp;x| x &lt; 0).hold(0);</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! // This won&#39;t arrive at the signal.</span>
<span class='doccomment'>//! sink.send(4);</span>
<span class='doccomment'>//! assert_eq!(negatives.sample(), 0);</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! // But this will!</span>
<span class='doccomment'>//! sink.send(-3);</span>
<span class='doccomment'>//! assert_eq!(negatives.sample(), -3);</span>
<span class='doccomment'>//! ```</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! There are some other methods on streams and signals, that you can find in</span>
<span class='doccomment'>//! their respective APIs.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! Note that all these objects are `Send + Sync + Clone`. This means you can</span>
<span class='doccomment'>//! easily pass them around in your code, make clones, give them to another</span>
<span class='doccomment'>//! thread, and they will still be updated correctly.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! You may have noticed that certain primitives take a function as an argument.</span>
<span class='doccomment'>//! There is a limitation on what kind of functions can and should be used here.</span>
<span class='doccomment'>//! In general, as FRP provides an abstraction around mutable state, they should</span>
<span class='doccomment'>//! be pure functions (i.e. free of side effects).</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! For the most part this is guaranteed by Rust&#39;s type system. A static</span>
<span class='doccomment'>//! function with a matching signature always works. A closure though is very</span>
<span class='doccomment'>//! restricted: it must not borrow its environment, as it is impossible to</span>
<span class='doccomment'>//! satisfy the lifetime requirements for that. So you can only move stuff into</span>
<span class='doccomment'>//! it from the environment. However, the moved contents of the closure may also</span>
<span class='doccomment'>//! not be altered, which is guaranteed by the `Fn(…) -&gt; …)` trait bound.</span>
<span class='doccomment'>//!</span>
<span class='doccomment'>//! However, both closures and functions could still have side effects such as</span>
<span class='doccomment'>//! I/O, changing mutable state via `Mutex` or `RefCell`, etc. While Rust&#39;s type</span>
<span class='doccomment'>//! system cannot prevent this, you should generally not pass such functions to</span>
<span class='doccomment'>//! the FRP primitives, as they break the benefits you get from using FRP.</span>
<span class='doccomment'>//! (An exception here is debugging output.)</span>

<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>feature</span>(<span class='ident'>arc_weak</span>, <span class='ident'>fnbox</span>)]</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>cfg_attr</span>(<span class='ident'>test</span>, <span class='ident'>feature</span>(<span class='ident'>test</span>, <span class='ident'>scoped</span>))]</span>
<span class='attribute'>#<span class='op'>!</span>[<span class='ident'>warn</span>(<span class='ident'>missing_docs</span>)]</span>

<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>test</span>;
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>rand</span>;
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>quickcheck</span>;
<span class='attribute'>#[<span class='ident'>macro_use</span>(<span class='ident'>lazy_static</span>)]</span>
<span class='kw'>extern</span> <span class='kw'>crate</span> <span class='ident'>lazy_static</span>;

<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>stream</span>::{ <span class='ident'>Sink</span>, <span class='ident'>Stream</span> };
<span class='kw'>pub</span> <span class='kw'>use</span> <span class='ident'>signal</span>::{ <span class='ident'>Signal</span>, <span class='ident'>SignalMut</span> };

<span class='kw'>mod</span> <span class='ident'>transaction</span>;
<span class='kw'>mod</span> <span class='ident'>source</span>;
<span class='kw'>mod</span> <span class='ident'>pending</span>;
<span class='kw'>mod</span> <span class='ident'>readonly</span>;
<span class='kw'>mod</span> <span class='ident'>stream</span>;
<span class='kw'>mod</span> <span class='ident'>signal</span>;
<span class='attribute'>#[<span class='ident'>macro_use</span>]</span>
<span class='kw'>pub</span> <span class='kw'>mod</span> <span class='ident'>lift</span>;
<span class='attribute'>#[<span class='ident'>cfg</span>(<span class='ident'>test</span>)]</span>
<span class='kw'>mod</span> <span class='ident'>testing</span>;
</pre>
</section>
    <section id='search' class="content hidden"></section>

    <section class="footer"></section>

    <div id="help" class="hidden">
        <div class="shortcuts">
            <h1>Keyboard shortcuts</h1>
            <dl>
                <dt>?</dt>
                <dd>Show this help dialog</dd>
                <dt>S</dt>
                <dd>Focus the search field</dd>
                <dt>&larrb;</dt>
                <dd>Move up in search results</dd>
                <dt>&rarrb;</dt>
                <dd>Move down in search results</dd>
                <dt>&#9166;</dt>
                <dd>Go to active search result</dd>
            </dl>
        </div>
        <div class="infos">
            <h1>Search tricks</h1>
            <p>
                Prefix searches with a type followed by a colon (e.g.
                <code>fn:</code>) to restrict the search to a given type.
            </p>
            <p>
                Accepted types are: <code>fn</code>, <code>mod</code>,
                <code>struct</code>, <code>enum</code>,
                <code>trait</code>, <code>typedef</code> (or
                <code>tdef</code>).
            </p>
            <p>
                Search functions by type signature (e.g.
                <code>vec -> usize</code>)
            </p>
        </div>
    </div>

    

    <script>
        window.rootPath = "../../";
        window.currentCrate = "carboxyl";
        window.playgroundUrl = "";
    </script>
    <script src="../../jquery.js"></script>
    <script src="../../main.js"></script>
    
    <script async src="../../search-index.js"></script>
</body>
</html>