-
Notifications
You must be signed in to change notification settings - Fork 2
/
atom.xml
436 lines (328 loc) · 69.8 KB
/
atom.xml
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
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Uncountably Many</title>
<link href="http://uncountablymany.com/atom.xml" rel="self"/>
<link href="http://uncountablymany.com/"/>
<updated>2010-12-31T01:06:03-06:00</updated>
<id>http://uncountablymany.com/</id>
<author>
<name>Jorge Ortiz</name>
<email>jorge.ortiz@gmail.com</email>
</author>
<entry>
<title>Feeds and Flows</title>
<link href="http://uncountablymany.com/2010/12/28/feeds-and-flows.html"/>
<updated>2010-12-28T00:00:00-06:00</updated>
<id>http://uncountablymany.com/2010/12/28/feeds-and-flows</id>
<content type="html"><p>Feeds are everywhere these days. The most famous feeds are Twitter's Timeline and Facebook's News Feed, but every new social or real-time app includes one or more feeds as key parts of their product. Feeds might seem like a new trend, but they've actually been around for a while. I'd argue that chat rooms, IM conversations, and email inboxes are all examples of feeds that predate Facebook or Twitter. Despite their popularity and importance, I've yet to see any attempts to classify different feeds or even to develop a common vocabulary about the characteristics of feeds. I'll attempt this below, by classifying feeds based on two characteristics: <em>source</em> and <em>focus</em>.</p>
<h2>Source and Focus</h2>
<p>A feed's <em>source</em> is where new content appears when it is published to the feed. A <em>top-sourced</em> feed publishes new content at the top of the feed, whereas a <em>bottom-sourced</em> one publishes it at the bottom of the feed. When new content is published to a feed, the feed must decide where in the feed to <em>focus</em> on given the new content. In a <em>top-focused</em> feed, focus stays at the top of the feed (regardless of where new content is published), whereas a <em>bottom-focused</em> feed keeps focus on the bottom of the feed (also regardless of where new content is published). Together, the source and the focus determine the <em>flow</em> of the feed.</p>
<h2>Flows</h2>
<p>The most famous flow&mdash;<em>reverse chronological</em> or <em><strong>reverse chron</strong></em>&mdash;is a top-sourced and top-focused flow. It is top-sourced because new content appears at the top of the feed, and it is top-focused because when new content appears (typically by refreshing the page), focus stays at the top of the feed. Reverse chron is the standard flow for blog home pages, the standard Timeline View on twitter.com, the Facebook News Feed, most email inboxes, and SMS interfaces on at least some phones (old Nokia phones come to mind).</p>
<p>Another common flow&mdash;which I'll call <em><strong>chat flow</strong></em> for lack of a better name&mdash;is the bottom-sourced and bottom-focused flow. In this flow, new content appears at the bottom of the feed, where focus also stays. This is the flow typically used for chat rooms, IM conversations, the Unix <code>tail -f </code> command, and SMS interfaces on at least some phones (most notably the iPhone and Blackberry Messenger).</p>
<p>Less common&mdash;and as-yet unnamed, but I'll call it the <em><strong>third flow</strong></em>&mdash;is the top-sourced, bottom-focused flow, where content appears at the top, but focus stays at the bottom. Notable examples of this flow are the Tweetie for Mac and Twitter for iPhone (née Tweetie for iPhone) apps. In these apps, focus stays on the last tweet you read (roughly, the "bottom" of the feed) and new tweets appear at the top of the feed, without moving the focus.</p>
<p>The last flow&mdash;which I can probably call <em>chronological</em> or <em><strong>chron</strong></em> for symmetry&mdash;is the bottom-sourced, top-focused flow. This flow is probably the one that has been in use the longest (think of a standard list of historical events), but isn't commonly used in social/real-time apps. The one example I can think of is the Facebook Birthday Feed.</p>
<h2>Observations</h2>
<p>Despite being a very primitive way to classify feeds, this gives us a vocabulary to talk about them and a framework to think about them. For example, flows where the source and the focus are the same (reverse chron and chat flow) give importance to recent content at the possible expense of missing older content, whereas flows where the source and focus are different (chron and third flow) prioritize reading all the content at the expense of not being immediately aware of when new content is published.</p>
<p>Given that they both emphasize recency, why choose reverse chron over chat flow or vice versa? Chat flow has the advantage of presenting content in chronological order, so if several entries in the feed are related their order makes it natural to read them in top-down languages like English. Reverse chron, on the other hand, discourages reading related items in chronological order. This discouragement is probably fine for unrelated blog posts, but contributes to the awkwardness of reading conversations on Twitter. So why do blogs, Twitter, and Facebook choose reverse chron over chat flow? I suspect the nature of the web discourages the use of chat flow; it's unnatural to make content flow upward in HTML. (Indeed, the examples of chat flow that I can think of are all native apps, or web apps trying to mimic native apps.) Twitter might also have been mimicking the SMS interfaces of the time.</p>
<p>What about reverse chron versus third flow? <a href="http://twitter.com/#!/CodyBrown/status/26369114875">Proponents</a> of reverse chron like its focus on recency, but all of us who lack the discipline of Inbox Zero have had the experience of losing track of an important email because it fell too far down our inbox feed. Tweetie seems to have chosen third flow as a direct response to the weaknesses of reverse chron, making it much easier to read every Tweet. Depending on your <a href="http://twitterisntemail.com/">approach to Twitter</a>, this is either a boon or a mistake.</p>
<p>Likewise, Facebook seems to have found reverse chron to be inadequate for its Birthday Feed. From a technical standpoint, it would have been easier for them to insert birthdays into the regular News Feed, but from a product standpoint it would have been a mistake. If N days before a birthday Facebook inserted a birthday notification into the News Feed, it would fall down the feed (become less prominent) as time passed and the birthday got closer. They could conceivably bump birthday notifications the top of the feed with every passing day, but then they would be trying to swim upstream, which seems unnatural. Chron flow solves these problems: new items (birthdays N days away) appear at the bottom of the feed (least prominent), and as birthdays get closer they rise up the feed (becoming more prominent).</p>
<h2>Open Questions</h2>
<p>This discussion focused solely on vertical time-based feeds. Are there non-vertical feeds? Are there feeds that aren't organized based on time? What other characteristics of feeds should we pay attention to? (Some that come to mind: When do items get added to a feed? When do items get removed from a feed?) Are there more nuanced differences between reverse chron and chat flow? Does anyone else use third flow? Did I miss any prominent examples of the other flows?</p>
<p>If you have answers to any of these questions, <a href="mailto:jorge.ortiz@gmail.com">let me know</a>.</p>
<!-- <p>This post arose out of a series of conversations with <a href="http://twitter.com/lehrblogger">Steven Lehrburger</a>.</p> -->
</content>
<author>
<name>Jorge Ortiz</name>
<uri>http://uncountablymany.com</uri>
</author>
</entry>
<entry>
<title>Does pattern matching break encapsulation?</title>
<link href="http://uncountablymany.com/2009/07/24/pattern-matching-encapsulation.html"/>
<updated>2009-07-24T00:00:00-05:00</updated>
<id>http://uncountablymany.com/2009/07/24/pattern-matching-encapsulation</id>
<content type="html"><p>Scala attempts to unify functional and object-oriented programming. One of the concepts that Scala borrows from functional programming is <em>pattern matching</em>.</p>
<p>Pattern matching can be used anywhere you might use <code>switch/case</code>:</p>
<pre>
<span class="keyword">def</span> <a title="(Int)Int" id="7276">fib</a>(<a title="Int" id="7278">n</a>: <span title="Int">Int</span>): <span title="Int">Int</span> = <a href="#7278" title="Int">n</a> <span title="Int" class="keyword">match</span> {
<span title="Int(0)" class="keyword">case</span> <span title="Int(0)" class="int">0</span> =&gt; <span title="Int(0)" class="int">0</span>
<span title="Int(1)" class="keyword">case</span> <span title="Int(1)" class="int">1</span> =&gt; <span title="Int(1)" class="int">1</span>
<span title="Int" class="keyword">case</span> <a title="Int" id="7279">n</a> =&gt; <a href="#7276" title="(Int)Int">fib</a>(<a href="#7279" title="Int">n</a><span title="(Int)Int">-</span><span title="Int(1)" class="int">1</span>) <a title="(Int)Int" id="3111">+</a> <a href="#7276" title="(Int)Int">fib</a>(<a href="#7279" title="Int">n</a><span title="(Int)Int">-</span><span title="Int(2)" class="int">2</span>)
}
</pre>
<p>You can also use pattern matching to "break open" case classes and access the parameters that were used to construct it:</p>
<pre>
<span class="keyword">trait</span> <a title="trait Point extends java.lang.Object" id="8516">Point</a>
<span class="keyword">case</span> <span class="keyword">class</span> <a title="class CartesianPoint extends java.lang.Object with PatternMatchingEncapsulation.ex2.Point with ScalaObject with Product" id="8593">CartesianPoint</a>(<a title="Double" id="8665">x</a>: <span title="Double">Double</span>, <a title="Double" id="8666">y</a>: <span title="Double">Double</span>) <span class="keyword">extends</span> <a href="#8516" title="PatternMatchingEncapsulation.ex2.Point">Point</a>
<span class="keyword">def</span> <a title="(PatternMatchingEncapsulation.ex2.Point)Boolean" id="8520">isSpecial</a>(<a title="PatternMatchingEncapsulation.ex2.Point" id="8639">point</a>: <a href="#8516" title="PatternMatchingEncapsulation.ex2.Point">Point</a>): <span title="Boolean">Boolean</span> = <a href="#8639" title="PatternMatchingEncapsulation.ex2.Point">point</a> <span title="Boolean" class="keyword">match</span> {
<span title="Boolean(true)" class="keyword">case</span> CartesianPoint(<a title="Double" id="8658">x</a>, <a title="Double" id="8659">y</a>) <span class="keyword">if</span> <a href="#8658" title="Double">x</a><span title="(Double)Double">*</span><a href="#8658" title="Double">x</a> <span title="(Double)Double">+</span> <a href="#8659" title="Double">y</a><span title="(Double)Double">*</span><a href="#8659" title="Double">y</a> <span title="(Double)Boolean">&gt;</span> <span title="Double(25.0)" class="double">25.0</span> =&gt; <span title="Boolean(true)" class="keyword">true</span>
<span title="Boolean(false)" class="keyword">case</span> _ =&gt; <span title="Boolean(false)" class="keyword">false</span>
}
</pre>
<p>One criticism of pattern matching is that it violates <em>encapsulation</em>, the object-oriented principle that says the interface of a class should be independent of its implementation details. If we change the implementation details of <code>CartesianPoint</code>, we'll break the pattern matching statements that depended on those details.</p>
<h2>Extractors</h2>
<p>Scala relies on extractors to make pattern matching more object-oriented. Extractors define a "view" on a particular kind of object. This allows Scala code that uses pattern matching to maintain encapsulation: just provide a "view" into your new implementation that matches the old one.</p>
<p>Suppose we wanted to implement Points in terms of polar coordinates instead of Cartesian coordinates:</p>
<pre>
<span class="keyword">trait</span> <a title="trait Point extends java.lang.Object" id="8670">Point</a>
<span class="keyword">case</span> <span class="keyword">class</span> <a title="class PolarPoint extends java.lang.Object with PatternMatchingEncapsulation.ex3.Point with ScalaObject with Product" id="8696">PolarPoint</a>(<a title="Double" id="8886">radius</a>: <span title="Double">Double</span>, <a title="Double" id="8887">theta</a>: <span title="Double">Double</span>) <span class="keyword">extends</span> <a href="#8670" title="PatternMatchingEncapsulation.ex3.Point">Point</a>
<span class="keyword">object</span> <a title="object PatternMatchingEncapsulation.ex3.CartesianPoint" id="8674">CartesianPoint</a> {
<span class="keyword">def</span> <a title="(Double,Double)PatternMatchingEncapsulation.ex3.Point" id="8713">apply</a>(<a title="Double" id="8716">x</a>: <span title="Double">Double</span>, <a title="Double" id="8717">y</a>: <span title="Double">Double</span>): <a href="#8670" title="PatternMatchingEncapsulation.ex3.Point">Point</a> = {
<span class="keyword">val</span> <a title="Double" id="8718">radius</a> = <span title="object Math">Math</span>.<a title="(Double)Double" id="8780">sqrt</a>(<a href="#8716" title="Double">x</a><span title="(Double)Double">*</span><a href="#8716" title="Double">x</a> <span title="(Double)Double">+</span> <a href="#8717" title="Double">y</a><span title="(Double)Double">*</span><a href="#8717" title="Double">y</a>)
<span class="keyword">val</span> <a title="Double" id="8719">theta</a> =
<span title="Double" class="keyword">if</span> (<a href="#8716" title="Double">x</a> <span title="(Double)Boolean">==</span> <span title="Double(0.0)" class="double">0.0</span> <span title="(Boolean)Boolean">&amp;&amp;</span> <a href="#8717" title="Double">y</a> <span title="(Double)Boolean">==</span> <span title="Double(0.0)" class="double">0.0</span>) <span title="Double(0.0)" class="double">0.0</span>
<span class="keyword">else</span> <span title="Double" class="keyword">if</span> (<a href="#8716" title="Double">x</a> <span title="(Double)Boolean">==</span> <span title="Double(0.0)" class="double">0.0</span> <span title="(Boolean)Boolean">&amp;&amp;</span> <a href="#8717" title="Double">y</a> <span title="(Double)Boolean">&gt;</span> <span title="Double(0.0)" class="double">0.0</span>) <span title="object Math">Math</span>.<span title="=&gt; Double">Pi</span><span title="(Int)Double">/</span><span title="Int(2)" class="int">2</span>
<span class="keyword">else</span> <span title="Double" class="keyword">if</span> (<a href="#8716" title="Double">x</a> <span title="(Double)Boolean">==</span> <span title="Double(0.0)" class="double">0.0</span> <span title="(Boolean)Boolean">&amp;&amp;</span> <a href="#8717" title="Double">y</a> <span title="(Double)Boolean">&lt;</span> <span title="Double(0.0)" class="double">0.0</span>) <span title="Int(3)" class="int">3</span><span title="(Double)Double">*</span><span title="object Math">Math</span>.<span title="=&gt; Double">Pi</span><span title="(Int)Double">/</span><span title="Int(2)" class="int">2</span>
<span class="keyword">else</span> <span title="Double" class="keyword">if</span> (<a href="#8716" title="Double">x</a> <span title="(Int)Boolean">&gt;</span> <span title="Int(0)" class="int">0</span> <span title="(Boolean)Boolean">&amp;&amp;</span> <a href="#8717" title="Double">y</a> <a title="(Double)Boolean" id="3432">&gt;=</a> <span title="Double(0.0)" class="double">0.0</span>) <span title="object Math">Math</span>.<span title="(Double)Double">atan</span>(<a href="#8717" title="Double">y</a><span title="(Double)Double">/</span><a href="#8716" title="Double">x</a>)
<span class="keyword">else</span> <span title="Double" class="keyword">if</span> (<a href="#8716" title="Double">x</a> <span title="(Int)Boolean">&gt;</span> <span title="Int(0)" class="int">0</span> <span title="(Boolean)Boolean">&amp;&amp;</span> <a href="#8717" title="Double">y</a> <span title="(Double)Boolean">&lt;</span> <span title="Double(0.0)" class="double">0.0</span>) <span title="object Math">Math</span>.<span title="(Double)Double">atan</span>(<a href="#8717" title="Double">y</a><span title="(Double)Double">/</span><a href="#8716" title="Double">x</a>) <span title="(Double)Double">+</span> <span title="Int(2)" class="int">2</span><span title="(Double)Double">*</span><span title="object Math">Math</span>.<span title="=&gt; Double">Pi</span>
<span class="keyword">else</span> <span title="object Math">Math</span>.<span title="(Double)Double">atan</span>(<a href="#8717" title="Double">y</a><span title="(Double)Double">/</span><a href="#8716" title="Double">x</a>) <span title="(Double)Double">+</span> <span title="object Math">Math</span>.<span title="=&gt; Double">Pi</span>
<a href="#8696" title="(Double,Double)PatternMatchingEncapsulation.ex3.PolarPoint">PolarPoint</a>(<a href="#8718" title="Double">radius</a>, <a href="#8719" title="Double">theta</a>)
}
<span class="keyword">def</span> <a title="(PatternMatchingEncapsulation.ex3.Point)Option[(Double, Double)]" id="8714">unapply</a>(<a title="PatternMatchingEncapsulation.ex3.Point" id="8888">point</a>: <a href="#8670" title="PatternMatchingEncapsulation.ex3.Point">Point</a>) = <a href="#8888" title="PatternMatchingEncapsulation.ex3.Point">point</a> <span title="Option[(Double, Double)]" class="keyword">match</span> {
<span title="Some[(Double, Double)]" class="keyword">case</span> PolarPoint(<a title="Double" id="8890">r</a>, <a title="Double" id="8891">th</a>) =&gt;
<span title="((Double, Double))Some[(Double, Double)]">Some</span>(<span title="(Double,Double)(Double, Double)">(</span><a href="#8890" title="Double">r</a><span title="(Double)Double">*</span><span title="object Math">Math</span>.<a title="(Double)Double" id="8771">cos</a>(<a href="#8891" title="Double">th</a>), <a href="#8890" title="Double">r</a><span title="(Double)Double">*</span><span title="object Math">Math</span>.<a title="(Double)Double" id="8770">sin</a>(<a href="#8891" title="Double">th</a>)))
<span title="None.type" class="keyword">case</span> _ =&gt;
<span title="object None">None</span>
}
}
</pre>
<p>The <code>apply</code> method on <code>CartesianPoint</code> specifies how to construct a <code>PolarPoint</code> from a pair of (x, y) coordinates. Likewise, the <code>unapply</code> method specifies how to construct a pair of (x, y) coordinates from a <code>PolarPoint</code>. It is this second method which is the extractor. It lets us pattern match on <code>PolarPoint</code>s as if they were <code>CartesianPoint</code>s. In particular, the <code>isSpecial</code> method, defined above, can be used unchanged with our new, polar, implementation of points. Extractors let us keep encapsulation even when using pattern matching.</p>
<h2>A catch (or two)</h2>
<p>Is that the end of the story of pattern matching and encapsulation? Unfortunately, no. There are two ways in which pattern matching can break encapsulation. The first is through <code>sealed</code> classes, the second is through singletons.</p>
<p>A sealed class can only be subclassed within the same file, so the compiler knows statically all the possible subclasses of that class. This lets the Scala compiler check whether a pattern match on a sealed type is <em>exhaustive</em>. If you forget to check one of the possible subclasses, the Scala compiler will warn you that your match is not exhaustive. Consider the <code>List</code> class. <code>List</code> has two subclasses, <code>::</code> (pronounced "cons") and <code>Nil</code>. Cons represents the non-empty <code>List</code>, with a head and a tail, while <code>Nil</code> represents the empty List, with no head and no tail. If we try to define a method that matches on a <code>List</code> but forgets to match the <code>Nil</code> case:</p>
<pre>
<span class="keyword">def</span> <a title="[T](List[T])T" id="8952">head</a>[<a title="&gt;: Nothing &lt;: Any" id="8954">T</a>](<a title="List[T]" id="8956">xs</a>: <span title="List[T]">List</span>[T]): <a href="#8954" title="T">T</a> = <a href="#8956" title="List[T]">xs</a> <span title="T" class="keyword">match</span> {
<span title="T" class="keyword">case</span> <a title="T" id="8983">hd</a> :: <a title="List[T]" id="8984">tl</a> =&gt; <a href="#8983" title="T">hd</a>
}
</pre>
<p>Then we get a reprimand from the compiler: <code>warning: match is not exhaustive! missing combination Nil</code>.</p>
<p>If we define our own "cons" extractor, we don't get the same warning:</p>
<pre>
<span class="keyword">object</span> <a title="object PatternMatchingEncapsulation.ex5.:/:" id="8986">:/:</a> {
<span class="keyword">def</span> <a title="[T](List[T])Option[(T, List[T])]" id="8993">unapply</a>[<a title="&gt;: Nothing &lt;: Any" id="8995">T</a>](<a title="List[T]" id="8997">xs</a>: <span title="List[T]">List</span>[T]) =
<span title="Option[(T, List[T])]" class="keyword">if</span> (<a href="#8997" title="List[T]">xs</a>.<span title="=&gt; Boolean">isEmpty</span>) <span title="object None">None</span>
<span class="keyword">else</span> <span title="((T, List[T]))Some[(T, List[T])]">Some</span>(<a href="#8997" title="List[T]">xs</a>.<a title="=&gt; T" id="6770">head</a>, <a href="#8997" title="List[T]">xs</a>.<a title="=&gt; List[T]" id="6772">tail</a>)
}
<span class="keyword">def</span> <a title="[T](List[T])T" id="8988">customHead</a>[<a title="&gt;: Nothing &lt;: Any" id="8990">T</a>](<a title="List[T]" id="9024">xs</a>: <span title="List[T]">List</span>[T]): <a href="#8990" title="T">T</a> = <a href="#9024" title="List[T]">xs</a> <span title="T" class="keyword">match</span> {
<span title="T" class="keyword">case</span> <a title="T" id="9028">hd</a> <a href="#8993" title="(List[T])Option[(T, List[T])]">:/:</a> <a title="List[T]" id="9029">tl</a> =&gt; <a href="#9028" title="T">hd</a>
}
</pre>
<p>Now, this is a relatively minor problem. The warning is nice to have, but it's not essential. The bigger problem is matching on singletons. The empty <code>List</code>, <code>Nil</code>, is an implementation detail we can never change. We can simulate the <code>::</code> case class with an extractor (as above with <code>:/:</code>, but there is simply no way we can simulate Nil with an extractor. The best we can do requires us to match on <code>MyNil()</code>, because matching on <code>MyNil</code> would match on the object, not it's <code>unapply</code> method.</p>
<pre>
<span class="keyword">object</span> <a title="object PatternMatchingEncapsulation.ex6.MyNil" id="9031">MyNil</a> {
<span class="keyword">def</span> <a title="[T](List[T])Boolean" id="9038">unapply</a>[<a title="&gt;: Nothing &lt;: Any" id="9040">T</a>](<a title="List[T]" id="9042">xs</a>: <span title="List[T]">List</span>[T]): <span title="Boolean">Boolean</span> =
<span title="Boolean" class="keyword">if</span> (<a href="#9042" title="List[T]">xs</a>.<span title="=&gt; Boolean">isEmpty</span>) <span title="Boolean(true)" class="keyword">true</span>
<span class="keyword">else</span> <span title="Boolean(false)" class="keyword">false</span>
}
<span class="keyword">def</span> <a title="[T](List[T])Boolean" id="9033">empty</a>[<a title="&gt;: Nothing &lt;: Any" id="9035">T</a>](<a title="List[T]" id="9043">xs</a>: <span title="List[T]">List</span>[T]): <span title="Boolean">Boolean</span> = <a href="#9043" title="List[T]">xs</a> <span title="Boolean" class="keyword">match</span> {
<span title="Boolean(true)" class="keyword">case</span> <a href="#9038" title="(List[T])Boolean">MyNil</a>() =&gt; <span title="Boolean(true)" class="keyword">true</span>
<span title="Boolean(false)" class="keyword">case</span> _ =&gt; <span title="Boolean(false)" class="keyword">false</span>
}
</pre>
<h2>Conclusion</h2>
<p>I don't want people to get me wrong: I love pattern matching. Practically every day I'm grateful that Scala has it. It makes certain kinds of programming problems much easier to solve. (I discuss the kinds of problems that benefit from pattern matching vs OO-style inheritance and virtual method dispatch in a StackOverflow <a href="http://stackoverflow.com/questions/563369/does-scalas-pattern-matching-violate-the-open-closed-principle">question</a>.) However, library designers should be conscious of the implementation details they might be exposing if they're letting their users pattern match on sealed classes or singletons. Pattern matching can be very powerful, but as with many things in Scala: with great power comes great responsibility.</p></content>
<author>
<name>Jorge Ortiz</name>
<uri>http://uncountablymany.com</uri>
</author>
</entry>
<entry>
<title>Pimp My Lock: A case study in Scala API design</title>
<link href="http://uncountablymany.com/2009/07/07/pimp-my-lock.html"/>
<updated>2009-07-07T00:00:00-05:00</updated>
<id>http://uncountablymany.com/2009/07/07/pimp-my-lock</id>
<content type="html"><p>Josh Cough had an amusing article on <a href="http://jackcoughonsoftware.blogspot.com/2009/06/pimp-vs-just-plain-fix-my-library.html">pimping vs fixing libraries</a>. He ran into an intolerable method in the Java standard libraries and decided to fix it with the <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=179766">Pimp My Library</a> pattern. Today I want to pimp a different Java library: Lock. Scala has higher-level ways of dealing with concurrency than Locks, but every now and then you need to get down with the nitty-gritty and do some manual locking. By Java standards, Lock is a pretty good library, but I wanted to see if Scala could do better.</p>
<h2>Basic Locks</h2>
<p>Here's what the Lock interface looks like in Java:</p>
<div class="highlight"><pre><code class="java"> <span class="kd">interface</span> <span class="nc">Lock</span> <span class="o">{</span>
<span class="kt">void</span> <span class="nf">lock</span><span class="o">();</span>
<span class="kt">void</span> <span class="nf">lockInterruptibly</span><span class="o">();</span>
<span class="n">Condition</span> <span class="nf">newCondition</span><span class="o">();</span>
<span class="kt">boolean</span> <span class="nf">tryLock</span><span class="o">();</span>
<span class="kt">boolean</span> <span class="nf">tryLock</span><span class="o">(</span><span class="kt">long</span> <span class="n">time</span><span class="o">,</span> <span class="n">TimeUnit</span> <span class="n">unit</span><span class="o">);</span>
<span class="kt">void</span> <span class="nf">unlock</span><span class="o">();</span>
<span class="o">}</span>
</code></pre>
</div>
<p>As a first approximation, let's distill the basic features (<code>lock</code>, <code>unlock</code>) into a Scala trait:</p>
<pre>
<span class="keyword">trait</span> <a title="trait Lock extends java.lang.Object" id="7322">Lock</a> {
<span class="keyword">def</span> <a title="()Unit" id="7324">lock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="()Unit" id="7325">unlock</a>(): <span title="Unit">Unit</span>
}
</pre>
<p>Lock was introduced as a better alternative to Java's <code>synchronized</code> keyword, but in the simple case it's actually worse. The recommended idiom for using Lock (straight from the <a =href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Lock.html">JavaDocs</a>) looks like:</p>
<div class="highlight"><pre><code class="java"> <span class="n">Lock</span> <span class="n">l</span> <span class="o">=</span> <span class="o">...</span>
<span class="n">l</span><span class="o">.</span><span class="na">lock</span><span class="o">();</span>
<span class="k">try</span> <span class="o">{</span>
<span class="c1">// access the resource protected by this lock</span>
<span class="o">}</span> <span class="k">finally</span> <span class="o">{</span>
<span class="n">l</span><span class="o">.</span><span class="na">unlock</span><span class="o">();</span>
<span class="o">}</span>
</code></pre>
</div>
<p>Compare this to using <code>synchronized</code> directly in Java:</p>
<div class="highlight"><pre><code class="java"> <span class="n">Object</span> <span class="n">lock</span> <span class="o">=</span> <span class="o">...</span>
<span class="kd">synchronized</span><span class="o">(</span><span class="n">lock</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// access the resource protected by this lock</span>
<span class="o">}</span>
</code></pre>
</div>
<p>What can go wrong when using <code>lock/unlock</code>? You might forget to release a lock, causing deadlock. Or you might forget to release a lock inside a <code>finally</code> clause, causing deadlock in when your code throws exceptions. Neither of these can happen when using <code>synchronized</code>, since the lock is automatically released at the end of the synchronized block, and Java makes sure it's released even if an exception is thrown. With a little bit of Scala, we can fix these potential errors:</p>
<pre>
<span class="keyword">trait</span> <a title="trait Lock extends java.lang.Object with ScalaObject" id="7328">Lock</a> {
<span class="keyword">def</span> <a title="()Unit" id="7331">lock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="()Unit" id="7332">unlock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="[T](=&gt; T)T" id="7333">apply</a>[<a title="&gt;: Nothing &lt;: Any" id="7335">T</a>](<a title="=&gt; T" id="7338">block</a>: =&gt; T): <a href="#7335" title="T">T</a> = {
<a href="#7328" title="Lock.this.type" class="keyword">this</a>.<a href="#7331" title="()Unit">lock</a>()
<span class="keyword">try</span> {
<a href="#7338" title="=&gt; T">block</a>
} <span class="keyword">finally</span> {
<a href="#7328" title="Lock.this.type" class="keyword">this</a>.<a href="#7332" title="()Unit">unlock</a>()
}
}
}
</pre>
<p>In Scala, traits (unlike Java interfaces) can define methods. This means ANY Lock can take advantage of the method we just added, without having to reimplement it. Our <code>apply</code> method is parametrized on type <code>T</code>, which is just whatever type our block returns. The little arrow <code>=></code> next to our <code>block</code> parameter tells Scala to delay evaluation of the block until it is actually used. (This is called a "by-name parameter".) This is critical, because it makes sure the block is only evaluated once we've acquired the lock. We've called our method <code>apply</code> because that's the method Scala looks for when you try to use an object as a function. (In Scala, functions are objects and objects are functions.) Now the recommended usage idiom for Scala looks like this:</p>
<pre>
<span class="keyword">val</span> <a title="PimpMyLock.ex2.Lock" id="7341">lock</a>: <a href="#7328" title="PimpMyLock.ex2.Lock">Lock</a> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<a href="#7333" title="(=&gt; Unit)Unit">lock</a> <span title="Unit">{</span>
<span class="comment">// access the resource protected by this lock</span>
}
</pre>
<p>This looks a lot like Java's baked-in support for synchronization, except we didn't need any language features built specifically for locks. Everything is "Just A Library". We might want to go a little further and add <code>map</code> and <code>foreach</code> methods. Having these methods lets us use locks inside of for-comprehensions, which is useful when we want to compose locks with other classes than can also be used inside for-comprehensions. It turns out that <code>map</code> is slightly more general than <code>apply</code>, so we'll reimplement <code>apply</code> in terms of <code>map</code>:</p>
<pre>
<span class="keyword">trait</span> <a title="trait Lock extends java.lang.Object with ScalaObject" id="7346">Lock</a> {
<span class="keyword">def</span> <a title="()Unit" id="7349">lock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="()Unit" id="7350">unlock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="[T]((Lock.this.type) =&gt; T)T" id="7351">map</a>[<a title="&gt;: Nothing &lt;: Any" id="7353">T</a>](<a title="(Lock.this.type) =&gt; T" id="7360">f</a>: <span class="keyword">this</span>.<span class="keyword">type</span> =&gt; T): <a href="#7353" title="T">T</a> = {
<a href="#7346" title="Lock.this.type" class="keyword">this</a>.<a href="#7349" title="()Unit">lock</a>()
<span class="keyword">try</span> {
<a href="#7360" title="(Lock.this.type)T" id="7230">f</a>(<a href="#7346" title="Lock.this.type" class="keyword">this</a>)
} <span class="keyword">finally</span> {
<a href="#7346" title="Lock.this.type" class="keyword">this</a>.<a href="#7350" title="()Unit">unlock</a>()
}
}
<span class="keyword">def</span> <a title="((Lock.this.type) =&gt; Unit)Unit" id="7354">foreach</a>(<a title="(Lock.this.type) =&gt; Unit" id="7361">f</a>: <span class="keyword">this</span>.<span class="keyword">type</span> =&gt; Unit): <span title="Unit">Unit</span> = <a href="#7351" title="((Lock.this.type) =&gt; Unit)Unit">map</a>(<a href="#7361" title="(Lock.this.type) =&gt; Unit">f</a>)
<span class="keyword">def</span> <a title="[T](=&gt; T)T" id="7355">apply</a>[<a title="&gt;: Nothing &lt;: Any" id="7357">T</a>](<a title="=&gt; T" id="7363">block</a>: =&gt; T): <a href="#7357" title="T">T</a> = <a href="#7351" title="((Lock.this.type) =&gt; T)T">map</a>(<a title="Lock.this.type" id="7373">_</a> =&gt; <a href="#7363" title="=&gt; T">block</a>)
}
</pre>
<p>Now we can use Locks inside for-comprehensions:</p>
<pre>
<span class="keyword">val</span> <a title="PimpMyLock.ex4.Lock" id="7376">lock</a>: <a href="#7346" title="PimpMyLock.ex4.Lock">Lock</a> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<span class="keyword">for</span>(<a href="#7354" title="((PimpMyLock.ex5.lock.type) =&gt; Unit)Unit" id="7380">l</a> &lt;- <a href="#7376" title="=&gt; PimpMyLock.ex4.Lock">lock</a>) <span title="Unit">{</span>
<span class="comment">// access the resource protected by this lock</span>
}
</pre>
<h2>Advanced Locks</h2>
<p>If Java's <code>Lock</code> interface (added in Java 1.5) is worse than the built-in <code>synchronized</code> (since Java 1.0?), then why was it added? The answer is that we've forgotten about all the other methods on Lock, namely:</p>
<div class="highlight"><pre><code class="java"> <span class="kt">void</span> <span class="nf">lockInterruptibly</span><span class="o">();</span>
<span class="kt">boolean</span> <span class="nf">tryLock</span><span class="o">();</span>
<span class="kt">boolean</span> <span class="nf">tryLock</span><span class="o">(</span><span class="kt">long</span> <span class="n">time</span><span class="o">,</span> <span class="n">TimeUnit</span> <span class="n">unit</span><span class="o">);</span>
</code></pre>
</div>
<p>It turns out the <code>synchronized</code> keyword only has one way to acquire a lock: block the thread until you have the lock. This is a pretty forceful way to go about things, since the thread will block forever if the lock can't be acquired. The <code>Lock</code> interface adds three more ways to acquire a lock: non-blocking (<code>tryLock</code>), with a timeout (<code>tryLock(long,TimeUnit)</code>), or interruptible (<code>lockInterruptibly</code>). With all of these methods, lock acquisition can fail. Two of them return false if the lock can't be acquired, and the third throws an <code>InterruptedException</code>.</p>
<p>How can we support these different modes in our Scala Lock trait? We could certainly add the same three methods, just like Java. But then <code>map</code>/<code>foreach</code>/<code>apply</code> are all fixed to use only one kind of acquisition strategy. One approach is to add lots more methods: <ccode>mapInterruptibly</ccode>, <code>foreachInterruptibly</code>, <code>applyInterruptibly</code>, <code>mapTry</code>, <code>foreachTry</code>, <code>applyTry</code>, etc. This quickly becomes a headache, and it defeats much of the point of adding these methods in the first place, which was to integrate with Scala's language features for <code>map</code>/<code>foreach</code>/<code>apply</code>.</p>
<p>Another approach is to allow "toggling" between the different modes. Let's start with <code>lockInterruptibly</code>, which has the same signature as lock. (In Java, the signatures are actually different, because <code>lockInterruptibly</code> throws a checked <code>InterruptedException</code>. In Scala, all exceptions are unchecked so the signatures are actually the same.) We can add a couple of methods to toggle between "interruptible" and "uninterruptible" modes:</p>
<pre>
<span class="keyword">trait</span> <a title="trait Lock extends java.lang.Object with ScalaObject" id="7382">Lock</a> {
<span class="keyword">def</span> <a title="()Unit" id="7385">lock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="()Unit" id="7386">unlock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="[T]((Lock.this.type) =&gt; T)T" id="7387">map</a>[<a title="&gt;: Nothing &lt;: Any" id="7389">T</a>](<a title="(Lock.this.type) =&gt; T" id="7398">f</a>: <span class="keyword">this</span>.<span class="keyword">type</span> =&gt; T): <a href="#7389" title="T">T</a> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<span class="keyword">def</span> <a title="((Lock.this.type) =&gt; Unit)Unit" id="7390">foreach</a>(<a title="(Lock.this.type) =&gt; Unit" id="7399">f</a>: <span class="keyword">this</span>.<span class="keyword">type</span> =&gt; Unit): <span title="Unit">Unit</span> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<span class="keyword">def</span> <a title="[T](=&gt; T)T" id="7391">apply</a>[<a title="&gt;: Nothing &lt;: Any" id="7393">T</a>](<a title="=&gt; T" id="7400">block</a>: =&gt; T): <a href="#7393" title="T">T</a> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<span class="keyword">def</span> <a title="=&gt; PimpMyLock.ex6.Lock" id="7394">interruptible</a>: <a href="#7382" title="PimpMyLock.ex6.Lock">Lock</a>
<span class="keyword">def</span> <a title="=&gt; PimpMyLock.ex6.Lock" id="7395">uninterruptible</a>: <a href="#7382" title="PimpMyLock.ex6.Lock">Lock</a>
}
</pre>
<p>Calling interruptible returns a view of the same underlying Lock, except that lock behaves like lockInterruptibly. Calling uninterruptible returns a Lock with the original default semantics. The benefit of reusing the Lock interface to mean different things (either interruptible or uninterruptible semantics) is that we can reuse the map/foreach/apply methods that we've already implemented for Lock. (Of course, the user still has to deal with catching any exceptions that might be thrown by an interruptible Lock... The Scala compiler won't complain when you've forgotten to catch an Exception, like the Java compiler does.)</p>
<p>But what do we do about the two tryLock methods? They return Boolean, not Unit, so we can't use them as drop-in replacements for lock. One approach is to add an attempt method to Lock that uses tryLock instead of lock:</p>
<div class="highlight"><pre><code class="scala"> <span class="k">def</span> <span class="n">attempt</span><span class="o">[</span><span class="kt">T</span><span class="o">](</span><span class="n">block</span><span class="k">:</span> <span class="o">=&gt;</span> <span class="n">T</span><span class="o">)</span><span class="k">:</span> <span class="kt">???</span> <span class="o">=</span> <span class="o">???</span>
</code></pre>
</div>
<p>The problem here is... what do we return? We'd like to return T, but we can't guarantee that. If tryLock fails, we don't have a T to return since we won't have run the block. We could try returning Unit:</p>
<pre>
<span class="keyword">def</span> <a title="(=&gt; Unit)Unit" id="7404">attempt</a>(<a title="=&gt; Unit" id="7406">block</a>: =&gt; Unit): <span title="Unit">Unit</span> = <a href="#6782" title="=&gt; Nothing">TODO</a>
</pre>
<p>If the lock is acquired successfully, the block is run, otherwise it isn't run. But then we have no idea whether the block ran or not, and no way to run a different block in the case of failure to grab the lock. We could try propagating the Boolean:</p>
<pre>
<span class="keyword">def</span> <a title="(=&gt; Unit)Boolean" id="7408">attempt</a>(<a title="=&gt; Unit" id="7410">block</a>: =&gt; Unit): <span title="Boolean">Boolean</span> = <a href="#6782" title="=&gt; Nothing">TODO</a>
</pre>
<p>Then we can check the result of attempt to see if the block succeeded. If it didn't, we can execute another block. However, this means wrapping our call to attempt inside an if...else statement, which seems ugly. We also have no way to return a result from the block. We could try passing two different blocks:</p>
<pre>
<span class="keyword">def</span> <a title="[T](=&gt; T)(=&gt; T)T" id="7430">attempt</a>[<a title="&gt;: Nothing &lt;: Any" id="7432">T</a>](<a title="=&gt; T" id="7434">block</a>: =&gt; T)(<a title="=&gt; T" id="7435">orElse</a>: =&gt; T): <a href="#7432" title="T">T</a> = <a href="#6782" title="=&gt; Nothing">TODO</a>
</pre>
<p>Now we can pass two blocks to attempt, one that gets called if the lock is acquired successfully, and one that gets called if the lock can't be acquired. Now we can always return a T. This is still kind of ugly though. Passing two different blocks side-by-side doesn't give us any indication of which is which. Also, every time we wanted to do nothing if the lock can't be acquired, we'd have to explicitly pass an empty block. This doesn't seem very clean.</p>
<p>The best approach is to return Option. Option is a class in the Scala standard library. It's commonly used in situation where some action might succeed and return a value, or fail and return nothing. It has two subclasses, Some (which wraps the value when it exists) or None (which indicates the absence of a value). Conveniently, it also has a getOrElse method which returns the wrapped value (if it exists) or executes an alternative block of code (if the value doesn't exist). We can define attempt in terms of Option:</p>
<pre>
<span class="keyword">def</span> <a title="[T](=&gt; T)Option[T]" id="7437">attempt</a>[<a title="&gt;: Nothing &lt;: Any" id="7439">T</a>](<a title="=&gt; T" id="7441">block</a>: =&gt; T): <span title="Option[T]">Option</span>[T] = <a href="#6782" title="=&gt; Nothing">TODO</a>
</pre>
<p>And use it like so:</p>
<pre>
<span class="keyword">val</span> <a title="PimpMyLock.ex11.Lock" id="7474">lock</a>: <a href="#7473" title="PimpMyLock.ex11.Lock">Lock</a> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<a href="#7474" title="=&gt; PimpMyLock.ex11.Lock">lock</a>.<a href="#7437" title="(=&gt; Unit)Option[Unit]">attempt</a> <span title="Unit">{</span>
<span class="comment">// access the resource protected by this lock</span>
} <span title="(=&gt; Unit)Unit">getOrElse</span> <span title="Unit">{</span>
<span class="comment">// execute some block if the lock can't be acquired</span>
}
</pre>
<p>This neatly solves most of the concerns we had. If we don't care about the return value we can ignore it, if we do care we can access it. If we don't care about the "or else" condition, we don't have to include it, if we do care we can. However, we still face the explosion of methods for all the different locking modes. At the very least we'd need an attemptFor method which also takes a duration of time to wait to acquire the lock (using the other version of tryLock). Also, we wouldn't be able to use these locking modes inside for-comprehensions, because map/foreach are hard-wired to use lock (interruptible or uninterruptible versions).</p>
<h2>Better Abstractions</h2>
<p>The frustrating thing is that lock and tryLock are so similar, yet so different. They both try to acquire a lock. One can fail (return false), one can't (always returns (or throws an exception...)). For one, higher-order functions return T. For another, they return Option[T]. They're similar enough that we want the same kinds of abstractions for both, but different enough that we can't use the same abstraction. So why not use a different abstraction?</p>
<pre>
<span class="keyword">trait</span> <a title="trait TryingLock extends java.lang.Object with ScalaObject" id="7508">TryingLock</a> {
<span class="keyword">def</span> <a title="()Boolean" id="7539">lock</a>(): <span title="Boolean">Boolean</span>
<span class="keyword">def</span> <a title="()Unit" id="7540">unlock</a>(): <span title="Unit">Unit</span>
<span class="keyword">def</span> <a title="[T]((TryingLock.this.type) =&gt; T)Option[T]" id="7541">map</a>[<a title="&gt;: Nothing &lt;: Any" id="7543">T</a>](<a title="(TryingLock.this.type) =&gt; T" id="7551">f</a>: <span class="keyword">this</span>.<span class="keyword">type</span> =&gt; T): <span title="Option[T]">Option</span>[T] = <a href="#6782" title="=&gt; Nothing">TODO</a>
<span class="keyword">def</span> <a title="((TryingLock.this.type) =&gt; Unit)Unit" id="7544">foreach</a>(<a title="(TryingLock.this.type) =&gt; Unit" id="7552">f</a>: <span class="keyword">this</span>.<span class="keyword">type</span> =&gt; Unit): <span title="Unit">Unit</span> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<span class="keyword">def</span> <a title="[T](=&gt; T)Option[T]" id="7545">apply</a>[<a title="&gt;: Nothing &lt;: Any" id="7547">T</a>](<a title="=&gt; T" id="7553">block</a>: =&gt; T): <span title="Option[T]">Option</span>[T] = <a href="#6782" title="=&gt; Nothing">TODO</a>
}
</pre>
<p>The differences between Lock and TryingLock reflect the different behaviors that lock modes might have. But they share fundamentally very similar abstractions. Now our attempt and attemptFor methods can both return TryingLocks:</p>
<pre>
<span class="keyword">def</span> <a title="=&gt; PimpMyLock.ex12.TryingLock" id="7528">attempt</a>: <a href="#7508" title="PimpMyLock.ex12.TryingLock">TryingLock</a>
<span class="keyword">def</span> <a title="(PimpMyLock.ex12.Duration)PimpMyLock.ex12.TryingLock" id="7529">attemptFor</a>(<a title="PimpMyLock.ex12.Duration" id="7548">duration</a>: <span title="PimpMyLock.ex12.Duration">Duration</a>): <a href="#7508" title="PimpMyLock.ex12.TryingLock">TryingLock</a>
</pre>
<p>As with our interruptible and uninterruptible toggles, it's critically important that these methods return just views of the same underlying lock. They should merely "toggle" the mode we're using to access the underlying lock. Conveniently, our code example using attempt above works as-is with this newer version of attempt, thanks to TryingLock's apply method.</p>
<h2>The End Result</h2>
<pre>
<span class="keyword">val</span> <a title="PimpMyLock.ex12.Lock" id="7509">lock</a>: <a href="#7507" title="PimpMyLock.ex12.Lock">Lock</a> = <a href="#6782" title="=&gt; Nothing">TODO</a>
<a href="#7523" title="(=&gt; Unit)Unit">lock</a> <span title="Unit">{</span>
<span class="comment">// uninterruptible access to shared resources</span>
}
<a href="#7509" title="=&gt; PimpMyLock.ex12.Lock">lock</a>.<a href="#7523" title="(=&gt; Unit)Unit">interruptible</a> <span title="Unit">{</span>
<span class="comment">// interruptible access to shared resources</span>
}
<a href="#7509" title="=&gt; PimpMyLock.ex12.Lock">lock</a>.<a href="#7545" title="(=&gt; Unit)Option[Unit]">attempt</a> <span title="Unit">{</span>
<span class="comment">// non-blocking attempt at access to shared resources</span>
}
<a href="#7509" title="=&gt; PimpMyLock.ex12.Lock">lock</a>.<a href="#7545" title="(=&gt; Unit)Option[Unit]">attemptFor</a>(<a href="#7504" title="implicit PimpMyLock.ex12.RichInt : (Int)PimpMyLock.ex12.RichInt" class="int">10</a>.<a href="#7513" title="=&gt; PimpMyLock.ex12.Duration">minutes</a>) <span title="Unit">{</span>
<span class="comment">// blocking (with timeout) attempt at access to shared resources</span>
} <span title="(=&gt; Unit)Unit">getOrElse</span> <span title="Unit">{</span>
<span class="comment">// code to execute if attempt fails</span>
}
</pre>
<p>You can get the <a href="http://github.com/joshcough/scala-parallel/tree/master">source</a> on Github. Enjoy!</p>
<h3>Update:</h3>
<p>As Miles Sabin points out, the abstractions I devoloped for Lock are all nested, yet one of the major motivations for Lock was non-nested locking disciplines like hand-over-hand locking and lock downgrading. I didn't want to neglect these use cases when I wrote my Lock trait, which is why the lock and unlock primitives are still available instead of buried as private methods. However, the majority of uses of Lock are probably nested, so in the spirit of making easy things easy and hard things possible, I thought it would be useful to provide nested access to Locks, as well as access to the non-nested lock and unlock primitives.</p></content>
<author>
<name>Jorge Ortiz</name>
<uri>http://uncountablymany.com</uri>
</author>
</entry>
<entry>
<title>Facebook Ads: Fail</title>
<link href="http://uncountablymany.com/2009/01/01/facebook-ads-fail.html"/>
<updated>2009-01-01T00:00:00-06:00</updated>
<id>http://uncountablymany.com/2009/01/01/facebook-ads-fail</id>
<content type="html"><p>One of Facbeook's monetizations strategies has been to imitate Google's very successful AdWords program, which places small, targeted, and unobtrusive text ads next to Google's search results. AdWords accounts for a large part of Google's considerable revenues, but Facebook has not enjoyed similar success with their own ads. There are many reasons why Google's ads work and Facebook's ads fail, but today I just want to mention one particular failure on Facebook's part: Facebook shows me ads when I don't want to see them, and when I do want to see ads Facebook makes it impossible for me to do so.</p>
<p>First, consider Google. When I don't want to see ads, Google makes it easy for me to ignore them. Google's ads are small, text-only, set to one side, and are clearly labeled as advertisements. This empowerment to easily ignore ads keeps me happy as a user and coming back to Google for search. However, for certain search terms (like "flowers" or "divorce lawyer") it's likely that I'm looking for a certain product or service and actually want to see ads. When I want to see ads, Google makes it easy for me to do so: they're right there.</p>
<p>Now consider Facebook. When I don't want to see ads, Facebook makes it just as easy as Google for me to ignore them. Facebook's ads are similarly small, set to one side, and clearly labeled as advertisements. What about when I want to see ads? Facebook doesn't run a general purpose search engine, so they don't know when I'm looking to buy flowers or get a divorce lawyer. (Maybe some day they'll figure out that my mom's birthday is coming up or that my spouse just cheated on me and posted video evidence of the infidelity to Facebook, but they're not quite there yet.) However, there are times when I find myself wanting to look at ads on Facebook: in the split-second after I click a link and I'm waiting for the next page to load, I have nothing better to do so my eyes wander and I glance at the ads that I had previously ignored. Every once in a while I skim an ad that actually piques my interest. I want to know more, but by then it's too late. A new page has loaded, and with it a new ad. Perplexingly, hitting the 'Back' button on my browser shows me the page I was previously on, but not the same ad that was previously on it. Yes, there have been Facebook ads compelling enough to make me interrupt my normal web browsing flow and go back a page on my browser just to give the ad a second look, and maybe even click on it, but Facebook chooses to show me a different ad instead.</p>
<p>Major Fail.</p></content>
<author>
<name>Jorge Ortiz</name>
<uri>http://uncountablymany.com</uri>
</author>
</entry>
</feed>