<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;C0AGSXc_fip7ImA9WhRVGUQ.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621</id><updated>2012-01-19T08:48:48.946-08:00</updated><category term="2009" /><category term="consumer" /><category term="news" /><category term="movies" /><category term="fujitsu" /><category term="bug" /><category term="bugs" /><category term="macbookpro" /><category term="apple" /><category term="mormonism" /><category term="sony" /><category term="shopping" /><category term="slimtimer" /><category term="storage" /><category term="adobe" /><category term="finder" /><category term="paperless" /><category term="digitization" /><category term="osx" /><category term="dvd" /><category term="freedom" /><category term="3g" /><category term="headphones" /><category term="firefox" /><category term="orbeon" /><category term="dmca" /><category term="audio" /><category term="travel" /><category term="iphone" /><category term="leopard" /><category term="amazon" /><category term="apps" /><category term="macbook" /><category term="motorola" /><category term="review" /><category term="work" /><category term="opera" /><category term="laptop" /><category term="hardware" /><category term="web20" /><category term="paper" /><category term="scanner" /><category term="harddisk" /><category term="i18n" /><category term="orbitz" /><category term="dmv" /><category term="p2p" /><category term="ebooks" /><category term="lifehack" /><category term="java" /><category term="election" /><category term="logic" /><category term="howto" /><category term="music" /><category term="government" /><category term="philosophy" /><category term="pdf" /><category term="tip" /><category term="complaint" /><category term="met" /><category term="kindle" /><category term="french" /><category term="flying" /><category term="bluetooth" /><category term="harddrive" /><category term="web2.0" /><category term="tvhd" /><category term="software" /><category term="drm" /><category term="play" /><category term="mac" /><category term="entertainment" /><category term="flac" /><category term="religion" /><category term="puccini" /><category term="marketing" /><category term="mp3" /><category term="switzerland" /><category term="mozilla" /><category term="fail" /><category term="corruption" /><category term="california" /><category term="itunes" /><category term="suisse" /><category term="scansnap" /><category term="google" /><title>Erik's Ponderings</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>32</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/EriksPondering" /><feedburner:info uri="erikspondering" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry gd:etag="W/&quot;A0EBQH8_eCp7ImA9WhRVGE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-3036986710428869478</id><published>2011-10-15T12:54:00.000-07:00</published><updated>2012-01-17T14:34:11.140-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-17T14:34:11.140-08:00</app:edited><title>Scala partial functions (without a PhD)</title><content type="html">&lt;br /&gt;
If you have done some Scala for a while, you know about pattern matching and &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;match&lt;/span&gt;/&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt;. Things like:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;value match {&lt;br /&gt;
&amp;nbsp; case&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;Some(value)&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;⇒ …&lt;br /&gt;
&amp;nbsp; case&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;None&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;⇒&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;…&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;br /&gt;
}&lt;/span&gt;&lt;/blockquote&gt;
But there is another use of the &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt; keyword, without &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;match&lt;/span&gt;, as in:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;map foreach { case (k, v)&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;⇒ println(k + "&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;→&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;" + v)&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;
The first time I saw this kind of things I was a bit puzzled: in which situations could&amp;nbsp;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;be used without&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;match&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;?&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;Well, it turns out [1] that&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;a block with a bunch of &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt;&amp;nbsp;inside is one way of defining an anonymous function.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;There is nothing new with anonymous functions of course, and Scala has a very compact notation for those that doesn't involve&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;. But this particular way of defining anonymous functions gives you a lot for free, namely all the good things of pattern matching like casting-done-right, guards, and destructuring. The example above, with &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;foreach&lt;/span&gt;, shows how&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;can be used&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;for destructuring the tuples of the map into key and value components.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;But there is more. Consider:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; List(41, "cat") map { case i: Int&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;⇒&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;i + 1 }&lt;br /&gt;
scala.MatchError: cat (of class java.lang.String)&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="background-color: transparent;"&gt;As expected this crashes, because the pattern match doesn't know what to do when the string &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;"cat"&lt;/span&gt; is passed to it.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;On the other hand, this example doesn't crash:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; List(41, "cat") collect { case i: Int&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;⇒&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;i + 1 }&lt;br /&gt;
res1: List[Int] = List(42)&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="background-color: transparent;"&gt;So what's the difference? Does &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;collect&lt;/span&gt; just catch the&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;MatchError&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;and proceed? That would be clumsy and inefficient. In fact, the apparent magic lies in the fact that&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;case blocks define special functions called&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;i style="background-color: transparent;"&gt;partial functions&lt;/i&gt;&lt;span style="background-color: transparent;"&gt;. [2]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now you might wonder, coming from a "normal" programming language background, what that means, for a function to be "partial". Well, &lt;a href="http://en.wikipedia.org/wiki/Partial_function"&gt;it comes from mathematics&lt;/a&gt;, where it's opposed to "total" functions.&lt;br /&gt;
&lt;br /&gt;
But even though it comes from math it's actually simple. Take for example this function:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;def inc(i: Int) = i + 1&lt;/span&gt;&lt;/blockquote&gt;
It is &lt;i&gt;defined&lt;/i&gt; for any &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;Int&lt;/span&gt; input value. That means for that any&amp;nbsp;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Int&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;argument, it produces a resulting&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Int&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;result. [3]&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
A partial function on the other hand is defined only for a &lt;i&gt;subset&lt;/i&gt; of the possible values of its arguments:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;def fraction(d: Int) = 42 / d&lt;/span&gt;&lt;/blockquote&gt;
is not defined for &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;d == 0&lt;/span&gt;&amp;nbsp;and&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;fraction(0)&lt;/span&gt;&amp;nbsp;will throw an exception. Think also of the square root function, which is not defined for negative&amp;nbsp;&lt;span style="background-color: transparent;"&gt;real numbers. Examples abound. And&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;it's true also for the &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;collect&lt;/span&gt; example above, where the anonymous&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;function is only defined for an&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Int&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;argument but not for a &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;String&lt;/span&gt; (or any other) argument&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;So you get &amp;nbsp;the idea about some values not "making sense" as the argument of a function because they can't yield a significant result.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;Now if you think about it you will notice lots of situations like this in your programs, where functions are expected to work properly only for some input values. If the function is called with a disallowed value, it will typically crash, yield a special return value, or&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;throw an exception (and this should better be documented). In short, partial function are very common in real-life programs even if you don't know about it.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
So here&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;fraction&lt;/span&gt;&amp;nbsp;is defined as a regular function, but conceptually it is a partial function. The good thing is that Scala has built-in support for partial functions thanks to the&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;PartialFunction&lt;/span&gt;&amp;nbsp;trait.&amp;nbsp;&lt;span style="background-color: transparent;"&gt;And here is one way of defining such a partial function:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;val fraction = new&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;PartialFunction[Int, Int] {&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;def apply(d: Int) = 42 / d&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;nbsp;def isDefinedAt(d: Int) = d != 0&lt;br /&gt;
}&lt;/span&gt;&lt;/blockquote&gt;
&lt;span style="background-color: transparent;"&gt;A&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;PartialFunction&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;must provides a method&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;isDefinedAt&lt;/span&gt;, which allows &lt;/span&gt;&lt;span style="background-color: transparent;"&gt;the caller of the partial function to know, beforehand, whether the function can return a result for a given input value:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; fraction.isDefinedAt(42)&lt;br /&gt;
res2: Boolean = true&lt;br /&gt;
scala&amp;gt; fraction.isDefinedAt(0)&lt;br /&gt;
res3: Boolean = false&lt;/span&gt;&lt;/blockquote&gt;
And if you call the function:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; fraction(42)&lt;br /&gt;
res4: Int = 1&lt;br /&gt;
scala&amp;gt; fraction(0)&lt;br /&gt;
java.lang.ArithmeticException: / by zero&lt;/span&gt;&lt;/blockquote&gt;
This takes us back to the use of&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt;&amp;nbsp;to define partial functions. The exact same function can be written:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;def fraction: PartialFunction[Int, Int] =&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; { case d: Int if d != 0 ⇒ 42 / d }&lt;/span&gt;&lt;/blockquote&gt;
(Notice that you must specify that the&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;PartialFunction[Int, Int]&lt;/span&gt;&amp;nbsp;type. It would be great if Scala had a syntax to make this even more compact but it doesn't as of Scala 2.9.)&lt;br /&gt;
&lt;br /&gt;
And if you call the function:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; fraction(42)&lt;br /&gt;
res5: Int = 1&lt;br /&gt;
scala&amp;gt; fraction(0)&lt;br /&gt;
scala.MatchError: 0 (of class java.lang.Integer)&lt;/span&gt;&lt;/blockquote&gt;
(Note that there is one visible difference from the outside when you use the &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt; way: you get a&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;MatchError&lt;/span&gt;&amp;nbsp;as you usually do with pattern matching.)&lt;br /&gt;
&lt;br /&gt;
The idea doesn't apply only to numbers. In our &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;collect&lt;/span&gt; example above, the partial function implicitly defined looks like this:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;def incAny: PartialFunction[Any, Int] =&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp; &amp;nbsp; { case i: Int ⇒ i + 1 }&lt;/span&gt;&lt;/blockquote&gt;
The function takes an &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;Any&lt;/span&gt; as parameter because&amp;nbsp;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;List(41, "cat")&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;is a &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;List[Any]&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;But it is only defined for inputs that are of type&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Int&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;incAny&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;(41)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res6: Int = 42&lt;br /&gt;
scala&amp;gt;&amp;nbsp;incAny("cat")&lt;br /&gt;
scala.MatchError: 41 (of class java.lang.String)&lt;/span&gt;&lt;/blockquote&gt;
Passing a String didn't go too well, as expected. But now you can check this before calling the function with:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;incAny&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.isDefinedAt(41)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res7: Boolean = true&lt;br /&gt;
scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;incAny&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.isDefinedAt("cat")&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res8: Boolean = false&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
So we now have the explanation for the difference in behavior between &lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;collect&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;and &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;map&lt;/span&gt;, which is that&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;collect&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;expects a partial function. It&lt;/span&gt;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;asks&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;incAny&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;whether it is defined for&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;41&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;and then&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;"cat"&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;, and so automatically filters out&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;"cat"&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;. Another cool thing here is that the Scala compiler can even infer a clean resulting collection type:&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;List[Int]&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;!&lt;/span&gt;&lt;/div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt;&amp;nbsp;List(41, "cat")&amp;nbsp;collect&amp;nbsp;incAny&lt;br /&gt;
res9: List[Int] = List(42)&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
Also, as you notice, if you define the partial function inline, the compiler knows that it's a partial function and you avoid the explicit&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;PartialFunction&lt;/span&gt;&amp;nbsp;trait.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Notice that partial functions can lie:&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; def liar: PartialFunction[Any, Int] =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ case i: Int ⇒ i; case s: String&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;⇒&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;s.toInt }&lt;br /&gt;
liar: PartialFunction[Any,Int]&lt;br /&gt;
scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;liar&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.isDefinedAt(42)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res10: Boolean = true&lt;br /&gt;
scala&amp;gt;&amp;nbsp;liar.isDefinedAt("cat")&lt;br /&gt;
res11: Boolean = true&lt;br /&gt;
scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;liar&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;("cat")&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;java.lang.NumberFormatException: For input string: "cat"&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
Here&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;liar&lt;/span&gt;&amp;nbsp;says incorrectly that it's defined for &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;"cat"&lt;/span&gt;. It would probably be better to write:&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; def honest: PartialFunction[Any, Int] =&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{ case i: Int&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;⇒&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;i; case s: String if&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;isParsableAsInt&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;(s)&amp;nbsp;&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;⇒&lt;/span&gt;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;&amp;nbsp;s.toInt }&lt;br /&gt;
honest: PartialFunction[Any,Int]&lt;br /&gt;
scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;honest&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.isDefinedAt("cat")&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res12: Boolean = false&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
So now you see how partial functions defined with &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;case&lt;/span&gt; can be used for things like&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;collect&lt;/span&gt;&amp;nbsp;with a super compact &amp;nbsp;notation. You will see them in other places, including &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;catch&lt;/span&gt;&amp;nbsp;expressions.&lt;br /&gt;
&lt;br /&gt;
There is another situation in Scala where partial functions are "just there" and you might not know it. Take the following &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;List&lt;/span&gt;:&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;val pets = List("cat", "dog", "frog")&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
In Scala, any instance of&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;Seq&lt;/span&gt;, &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;Set&lt;/span&gt; or&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;Map&lt;/span&gt; is also a function. So you can write&lt;/div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;pets&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;(0)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res13: java.lang.String = cat&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
But:&lt;/div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt;&amp;nbsp;pets(3)&lt;br /&gt;
java.lang.IndexOutOfBoundsException: 3&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
Wouldn't that mean that the &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;pets&lt;/span&gt; function is, hum, only &lt;i&gt;defined&lt;/i&gt; for values 0, 1, and 2? Sounds familiar? Wouldn't it be cool to look at&amp;nbsp;&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;pets&lt;/span&gt;&amp;nbsp;as a partial function then? Well you can because in Scala&lt;span style="background-color: transparent;"&gt;&amp;nbsp;any instance of&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Seq&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;,&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Set&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;or&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Map&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;is actually a partial function.&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;So you can write:&lt;/span&gt;&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;pets&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.isDefinedAt(0)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res14: Boolean = true&lt;br /&gt;
scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;pets&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.isDefinedAt(3)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res15: Boolean = false&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
And if you had a list of indexes and wanted to safely collect values for these indexes in a new list, you could write:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; Seq(1, 2, 42) collect&amp;nbsp;pets&lt;br /&gt;
res16: Seq[java.lang.String] = List(dog, frog)&lt;/span&gt;&lt;/blockquote&gt;
Here it works well because &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;collect&lt;/span&gt;&amp;nbsp;handles everything for us. But it can be a pain to check &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;isDefinedAt&lt;/span&gt; all over the place. If anything, it feels a bit like a null check, and we hate those in Scala. The good news is that in Scala the &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;PartialFunction&lt;/span&gt; trait supports the &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;lift&lt;/span&gt; method, which converts the&amp;nbsp;&lt;span style="background-color: transparent;"&gt;partial function to a normal function that doesn't crash:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;pets&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;.lift(0)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;res17: Option[java.lang.String] = Some(cat)&lt;br /&gt;
scala&amp;gt; pets.lift(42)&lt;br /&gt;
res18: Option[java.lang.String] = None&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
As you see the &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;lift&lt;/span&gt;&amp;nbsp;returns a function that returns&amp;nbsp;&lt;span style="background-color: transparent;"&gt;an&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Option&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&amp;nbsp;of the value. This allows you to safely process values without null checks and without calling &lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;isDefinedAt&lt;/span&gt;&amp;nbsp;yourself:&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New',Courier,monospace;"&gt;scala&amp;gt; pets.lift(0) map ("I love my " + _) getOrElse ""&lt;br /&gt;
res19: java.lang.String = I love my cat&lt;br /&gt;
scala&amp;gt; pets.lift(42) map ("I love my " + _) getOrElse ""&lt;br /&gt;
res20: java.lang.String = ""&lt;/span&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div&gt;
I hope this helps make some sense of partial functions in Scala.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style="background-color: transparent;"&gt;[1] From The Scala Language Specification: "&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;An anonymous function can be defined by a sequence of cases […]&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;which appear as an expression without a prior match."&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;[2]&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;This is not to be confused with &lt;i&gt;partially applied functions&lt;/i&gt;, which are a completely different topic.&lt;/span&gt;&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;[3] In Scala, it is defined even for&amp;nbsp;&lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Int.MaxValue&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;, as &lt;/span&gt;&lt;span style="background-color: transparent; font-family: 'Courier New',Courier,monospace;"&gt;Int.MaxValue + 1 == Int.MinValue&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;. The result is just plain wrong but it's defined!&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-3036986710428869478?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/3036986710428869478/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=3036986710428869478" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/3036986710428869478?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/3036986710428869478?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2011/10/scala-partial-functions-without-phd.html" title="Scala partial functions (without a PhD)" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>9</thr:total></entry><entry gd:etag="W/&quot;Ak4BSXwycSp7ImA9WhdVE0s.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-7646493105465093357</id><published>2011-09-17T16:15:00.000-07:00</published><updated>2011-09-18T11:02:38.299-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-18T11:02:38.299-07:00</app:edited><title>Continuations in Scala (without a PhD)</title><content type="html">With &lt;a href="http://twitter.com/avernet"&gt;@avernet&lt;/a&gt; we have been thinking lately about &lt;a href="http://en.wikipedia.org/wiki/Continuation"&gt;continuations&lt;/a&gt;, for a few reasons:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Continuations pop up on the web as a concept that could help with&amp;nbsp;event-based programming&lt;/li&gt;
&lt;li&gt;Scala has a continuations plugin, and we're wondering what the deal is with that.&lt;/li&gt;
&lt;li&gt;It just seems like fun to try to understand this (alongside things like monads).&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The main idea of continuations is the ability to interrupt a program, save its control state, and resume it at a later point in time.&lt;br /&gt;
&lt;br /&gt;
One thing to realize is that there are many ways to implement this idea and variations around it. Google a bit and you will find&amp;nbsp;&lt;i&gt;a lot&lt;/i&gt;&amp;nbsp;of material on continuations, some of which goes deep into computer science.&amp;nbsp;Here we don't care about the big picture: we just want to get at least some insight into Scala continuations.&lt;br /&gt;
&lt;br /&gt;
The main source of information on Scala continuations is the &lt;a href="http://lamp.epfl.ch/~rompf/continuations-icfp09.pdf"&gt;EPFL paper&lt;/a&gt; describing how continuations were designed in the Scala compiler.&amp;nbsp;But if you google "scala continuations" and hope to find right away a clear explanation, you might be disappointed. You will find the following example (I am not kidding):&lt;/div&gt;
&lt;div&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset {&lt;br /&gt;&amp;nbsp; shift { k: (Int ⇒ Int) ⇒&lt;br /&gt;&amp;nbsp; &amp;nbsp; k(k(k(7)))&lt;br /&gt;&amp;nbsp; } + 1&lt;br /&gt;} * 2&lt;/span&gt;&lt;/blockquote&gt;
This proudly produces the flamboyant result: 20. As a &lt;a href="http://www.scala-lang.org/node/2096"&gt;commenter says&lt;/a&gt;, "these are convoluted ways of adding numbers and I have no idea what is being gained or accomplished". &lt;a href="http://twitter.com/djspiewak"&gt;@djspiewak&lt;/a&gt;&amp;nbsp;echoes this when &lt;a href="http://assets.en.oreilly.com/1/event/45/High%20Wizardry%20in%20the%20Land%20of%20Scala%20Presentation.pdf"&gt;he says&lt;/a&gt; that&amp;nbsp;continuations in Scala are "powerful&amp;nbsp;...but useless". It's a bit like explaining how a combustion engine works, but not that it could be used to, say, move your car from home to work.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So let's try to look at something concrete. Imagine a &lt;code&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&lt;/code&gt; function which returns a byte from the network:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def read: Byte&lt;/span&gt;&lt;/blockquote&gt;
This is typically the signature of a synchronous (blocking) function. After all, it has a return value and in normal programming languages, that means waiting for that value to be available. A program that reads two bytes in a row and prints them looks like this:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;val byte1 = read&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;println("byte1 = " + byte1)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;val byte2 = read&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;println("byte2 = " + byte2)&lt;/span&gt;&lt;/blockquote&gt;
The issue is that in a web browser or node.js or any other single-threaded, event-driven environment, this is not acceptable: you simply cannot block for a long time, otherwise nothing else can happen in the system. So instead, the&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&amp;nbsp;function is made to take a callback, something like:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def read(callback: Byte =&amp;gt; Unit): Unit&lt;/span&gt;&lt;/blockquote&gt;
You must now write your program like this:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read { byte1&amp;nbsp;⇒&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp;&amp;nbsp;println("byte1 = " + byte1)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; read { byte2 ⇒&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;println("byte2 = " + byte2)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;
The issue here is that you must write in a funny style, even with Scala's lightweight syntax for closures.&amp;nbsp;Note also how each callback typically causes a new level of indentation. Some programmers manage to get used to this style, but it does not represent the control flow in a very natural way, and the issue grows with the size of the program.&lt;br /&gt;
&lt;br /&gt;
Enter Scala continuations:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;import scala.util.continuations._&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; val byte1 = shift(read)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;println("byte1 = " + byte1)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;val byte2 = shift(read)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;println("byte2 = " + byte2)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;
And voilà: you can write the program again in imperative style without callbacks and closures.&lt;br /&gt;
&lt;br /&gt;
You notice the &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt; and &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt; constructs. These terms don't make any sense to a newcomer, but they were introduced a long time ago in an academic paper so are reused in Scala.&amp;nbsp;Basically,&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&amp;nbsp;&lt;i&gt;delimits&lt;/i&gt; the continuation. With full continuations, the entire rest of the program would be under control of the continuation, but here, whatever is before and after the&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&amp;nbsp;block has nothing to do with continuations at all. (Also,&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&amp;nbsp;can return a value, although here we don't care about it.)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;is the construct that does the real magic. Mainly, it smartly hacks around to pass the &lt;i&gt;continuation&lt;/i&gt;, that is a closure containing whatever-code-follow-shift-until-the-end-of-the-reset-block, to its body. If you run that closure, you actually run that code after the shift. If you store that closure somewhere, you gain the ability to decide when to run that code at a later point. This is the general idea of continuations: interrupt, then resume a program. Here it's all done with functions and closures behind the scene.&lt;br /&gt;
&lt;br /&gt;
To see how our example really works, let's look a the control flow. First, how would you go about implementing the non-blocking&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&amp;nbsp;function? Obviously it would have to work hand in hand with an asynchronous framework of some sort. Let's say it's roughly equivalent to something like this:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;var myCallback: Byte ⇒ Unit = null&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def read(callback:&amp;nbsp;Byte&amp;nbsp;⇒ Unit): Unit = myCallback = callback&lt;/span&gt;&lt;/blockquote&gt;
The key here is that&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&amp;nbsp;is passed a callback function.&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&amp;nbsp;just stores the callback in a variable&amp;nbsp;and then returns&amp;nbsp;&lt;i&gt;immediately&lt;/i&gt;. There is just no waiting. This simulates what a real async framework would do.&lt;br /&gt;
&lt;br /&gt;
In our example,&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;calls&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&amp;nbsp;with the continuation as a callback, and as we have seen &amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&amp;nbsp;returns right away.&amp;nbsp;But then what does&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;do? Does it just hang around? No:&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;returns right away as well, and then control continues right after the&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&amp;nbsp;block, and control should then return to the async framework. So it's as if the user program had paused just in the middle of calling &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift(read)&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
Now say that 5 minutes later, a byte (say 42) is available from the network. The async framework figures this out, notices&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;myCallback&lt;/span&gt; is registered, and so calls it with the value 42. The result of calling the callback is to run the continuation, that is the code that follows the first&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;runs, with byte1 set to the value 42. Did you see what happened there? It's as if the user program had resumed. And in effect it has.&lt;br /&gt;
&lt;br /&gt;
What happens next? There is a another&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;, so the scenario repeats: a new continuation is stored into&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;myCallback&lt;/span&gt;. This time, it contains the code after the &lt;i&gt;second&lt;/i&gt;&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;.&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;&amp;nbsp;returns,&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;returns, and control returns to the async framework, this time via the call to the initial callback.&amp;nbsp;When the framework receives another byte from the network, the user program runs up to the end of the&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset&lt;/span&gt;&amp;nbsp;block and has in effect terminated. We are happy because:&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;We never blocked our single thread.&lt;/li&gt;
&lt;li&gt;We wrote the program in a clear, understandable style.&lt;/li&gt;
&lt;li&gt;We actually did something (read and processed bytes from the network)&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
Obviously to make this real you want a framework and a function library with a set of useful asynchronous functions besides&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;read()&lt;/span&gt;. Also, note that you can hide the use of&amp;nbsp;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;from the programmer, and expose the read function like:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;def aRead = shift(read)&lt;/span&gt;&lt;/blockquote&gt;
And the program becomes:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; val byte1 = aRead&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;println("byte1 = " + byte1)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;val byte2 =&amp;nbsp;aRead&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;println("byte2 = " + byte2)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;
By the way, it also works within while loops. With this specific use of continuations where &lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;shift&lt;/span&gt;&amp;nbsp;never calls the continuation directly, control unwinds the stack back to the top, and there is no stack explosion. This is good news:&lt;br /&gt;
&lt;blockquote&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;reset {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; var value = -1&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; while (value != 42) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; value = aRead&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; &amp;nbsp; println(value)&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; }&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&amp;nbsp; println("done")&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;
&lt;div&gt;
So I would say that this at least appears to be a very useful (if not mainstream at this point) use of continuations in Scala. They will become even more useful when used as part of a &lt;a href="http://lamp.epfl.ch/~imaier/pub/DeprecatingObserversTR2010.pdf"&gt;reactive programming DSL&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-7646493105465093357?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/7646493105465093357/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=7646493105465093357" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/7646493105465093357?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/7646493105465093357?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2011/09/continuations-in-scala.html" title="Continuations in Scala (without a PhD)" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEABQ3o7eCp7ImA9WxBWEUg.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-8276001632668675886</id><published>2010-01-31T22:11:00.000-08:00</published><updated>2010-02-02T15:19:12.400-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-02T15:19:12.400-08:00</app:edited><title>48 hours of Nexus One</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_DSqG0J8ANmg/S2Y_sqZ1NkI/AAAAAAAAAVY/oPSujF97UcU/s1600-h/nexus-one.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/_DSqG0J8ANmg/S2Y_sqZ1NkI/AAAAAAAAAVY/oPSujF97UcU/s320/nexus-one.png" width="240" /&gt;&lt;/a&gt;&lt;/div&gt;I just used a &lt;a href="http://www.google.com/phone/"&gt;Nexus One&lt;/a&gt; for 48 hours (thanks Pierre). Here are a few quick notes/thoughts from the perspective of an iPhone 3G user.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Getting started &lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Take the SIM card out of the good old iPhone 3G, put it into the unlocked Nexus One, and voilà, you are done (sans 3G since the Nexus One does not support AT&amp;amp;T's 850 MHz 3G band)!&lt;/li&gt;
&lt;li&gt;The phone asks you to log in with a Google account. Since my contacts were synced with Google already, all that information was transferred right away to the phone.&lt;/li&gt;
&lt;/ul&gt;&lt;b&gt;First impressions&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Build.&lt;/b&gt; The Nexus One looks beautiful and solid.&lt;/li&gt;
&lt;li&gt; &lt;b&gt;Display. &lt;/b&gt;The iPhone's clearly pale in comparison (especially resolution). On the other hand the OLED screen doesn't perform as well in plain  daylight. &lt;/li&gt;
&lt;li&gt;&lt;b&gt;Speed.&lt;/b&gt; The Nexus One is snappy. I don't have an iPhone 3G S, but the Nexus One is definitely way faster than the iPhone 3G (which often feels impossibly sluggish).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Android.&lt;/b&gt; The OS requires some getting used to, but you quickly figure out how to do most operations, especially if you are a bit computer-savvy. The four buttons at the bottom of the screen are not as elegant as the  iPhone's single  button, but they usually make sense and you get used to  them quickly. I had very little difficulty adapting.&lt;/li&gt;
&lt;/ul&gt;&amp;nbsp;&lt;b&gt;The cool stuff&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Multitasking.&lt;/b&gt; A few examples:&lt;/li&gt;

&lt;ul&gt;&lt;li&gt;Upload pictures in  the background.&lt;/li&gt;
&lt;li&gt;Play Pandora while using any other app.&lt;/li&gt;
&lt;li&gt;Switch  between a few open apps in an instant.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;Notification  panel.&lt;/b&gt; It tells you quickly of things like new emails, tweets,  completed downloads, and more. The iPhone needs UI improvements in this  area.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Text completion.&lt;/b&gt; It is different than the iPhone's, and often  better as you can quickly pick words from a list.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Web browser URL completion.&lt;/b&gt; Android seems to use something like Google Suggests to help you enter URLs.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Voice  input.&lt;/b&gt; This works only part of the time, but it's a good start and it's  available in any text field. &lt;/li&gt;
&lt;li&gt;&lt;b&gt;GMail.&lt;/b&gt; It is excellent and supports starring and  conversations, unlike the iPhone's mail app.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Navigation.&lt;/b&gt; I  didn't have time (or 3G) to really try it, but the GPS navigation app  must be quite cool.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Google Voice. &lt;/b&gt;No need to fight with Apple here, Google Voice is fully integrated.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Camera flash. &lt;/b&gt;That seems pretty basic, but it is not a feature of the iPhone so far.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Programming. &lt;/b&gt;I haven't tried to program anything on the Nexus One, but I like the idea of being able to use Java (or even Scala) instead of Objective-C.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Openness.&lt;/b&gt; Open source OS. Multiple hardware vendors. No approval process like Apple's (you can even change the default web browser on Android). This has some appeal.&lt;/li&gt;
&lt;/ul&gt;&lt;b&gt;The OK stuff&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Web browser.&lt;/b&gt; Safari on the iPhone is still better overall.&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;App market.&lt;/b&gt; It is easy to use, but is nothing to call home about.&lt;/li&gt;
&lt;li&gt; &lt;b&gt;Bluetooth.&lt;/b&gt; My Bluetooth stereo headset was setup quickly and usually worked ok, but:&lt;/li&gt;

&lt;ul&gt;&lt;li&gt; I had an issue whereby at some point the sound started coming out of the phone speaker again in spite of the Bluetooth connection being active. Later things started working again.&lt;/li&gt;
&lt;li&gt; My Bluetooth headset suffers from the "jeans pocket" syndrome: if you put your phone in your pocket and start walking, the sounds starts breaking (yeah I know, crazy). This happened more with the Nexus One than with the iPhone 3G. This tells me that the Nexus One's Bluetooth signal might be weaker.&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;b&gt;The not so cool stuff&lt;/b&gt;&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;Apps.&lt;/b&gt; Clearly there are less apps and of lesser quality. A few examples:&lt;/li&gt;

&lt;ul&gt;&lt;li&gt;I missed &lt;a href="http://www.omnigroup.com/applications/omnifocus/iphone/"&gt;OmniFocus&lt;/a&gt;, &lt;a href="http://jott.com/jott/jott-for-iphone.html"&gt;Jott&lt;/a&gt; , and &lt;a href="http://www.instapaper.com/iphone"&gt;Instapaper&lt;/a&gt; / &lt;a href="http://readitlaterlist.com/iphone/"&gt;Read it Later&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The Facebook app (not that I use it much) is still inferior.&lt;/li&gt;
&lt;li&gt;Twitter clients clearly don't beat Tweetie on iPhone (Seesmic was ok though, and I hear that Twitdroid is pretty good but I didn't want to spend money to try it).&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;b&gt;&lt;s&gt;Multitouch.&lt;/s&gt;&lt;/b&gt;&lt;s&gt; There is no multitouch (especially no "pinch"), and the Nexus One screams for  it.&lt;/s&gt; &lt;b&gt;UPDATE:&lt;/b&gt; Google has &lt;a href="http://www.engadget.com/2010/02/02/nexus-one-gets-a-software-update-enables-multitouch/"&gt;just released an update with multitouch&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Copy/paste.&lt;/b&gt; This is pretty bad compared to the iPhone: text selection is difficult and not available everywhere.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Media. &lt;/b&gt;The audio and video players are not as easy to use as the iPhone's. There is no built-in support for podcasts (you can try Google Listen for that or other apps). (I used &lt;a href="http://www.doubletwist.com/"&gt;doubleTwist&lt;/a&gt; to copy some mp3s and videos to the phone and it worked fine.)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Trackball.&lt;/b&gt; The trackball is almost exclusively used to move  inside and between text fields/areas. My feeling is that it does a poor  job at this and Google should just abandon it and use another way of  navigating.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Screenshots.&lt;/b&gt; There is no built-in screenshot capability. The  iPhone does this out of the box. Apparently you have to root your phone to install 3rd-party  screen capture apps. This would have been useful for this post.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Landscape mode.&lt;/b&gt; This is only possible in one direction  instead of two, unlike the iPhone. It took me a while to figure out why  landscape mode worked some times but not others. &lt;/li&gt;
&lt;/ul&gt;&lt;b&gt;Is it better than the iPhone?&lt;/b&gt; &lt;br /&gt;
&lt;br /&gt;
I have no complaints about the hardware except for the trackball (concept and implementation), and the CPU and display give Nexus One the edge until this summer when Apple hopefully releases a new iPhone.&lt;br /&gt;
&lt;br /&gt;
As for the software, it's not easy to determine a winner. Clearly a lot of thoughtful work went into Android, but it doesn't feel as  polished and slick as iPhone OS. Often the phone feels more like a regular desktop computer. This can be good or  bad depending on your perspective.&lt;br /&gt;
&lt;br /&gt;
On the apps side, iPhone still wins hands down, but the Google stack of applications, including GMail, Navigation, and Google Voice, works best on Android, and that might win the hearts of some. Anyway there is little doubt Android will soon have enough good third-party apps that this won't be as much of a problem anymore (except maybe for games).&lt;br /&gt;
&lt;br /&gt;
Most likely my next phone will still be an iPhone because of the apps and ease of use, but this short Android adventure was quite refreshing!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-8276001632668675886?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/8276001632668675886/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=8276001632668675886" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8276001632668675886?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8276001632668675886?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2010/01/48-hours-of-nexus-one.html" title="48 hours of Nexus One" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_DSqG0J8ANmg/S2Y_sqZ1NkI/AAAAAAAAAVY/oPSujF97UcU/s72-c/nexus-one.png" height="72" width="72" /><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;D0UDR3o_cCp7ImA9WxVSE0w.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-5374312355604617569</id><published>2009-01-07T00:00:00.000-08:00</published><updated>2009-01-07T00:01:16.448-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-01-07T00:01:16.448-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="2009" /><category scheme="http://www.blogger.com/atom/ns#" term="web2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="apps" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="iphone" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>2009: Products I Can’t Live Without</title><content type="html">Mike Arrington &lt;a href="http://www.techcrunch.com/2009/01/04/2009-products-i-cant-live-without/"&gt;has just posted his 2009 list of products he can't live without&lt;/a&gt;. After &lt;a href="http://ebruchez.blogspot.com/2008/01/2008-web-20-software-i-use-every-day.html"&gt;my own 2008 list&lt;/a&gt;, here is my update for 2009 as I think it's fun to observe how our computing environment evolves from year to year. First, the new entries:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.omnigroup.com/applications/omnifocus/"&gt;OmniFocus&lt;/a&gt; is the best to-do list application I know of. I use the desktop application daily to handle work and personal tasks. It is worth the whole of its $80. As a pure desktop application without an online counterpart it is a step back, but the benefit is flexibility and speed, both crucial to GTD.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://twitter.com/ebruchez"&gt;Twitter&lt;/a&gt;, which I couldn't figure out at all a year ago, has seen 1,778 personal updates so far, and we &lt;a href="http://twitter.com/orbeon"&gt;use it at Orbeon&lt;/a&gt; too. I use &lt;a href="http://iconfactory.com/software/twitterrific"&gt;Twitterrific&lt;/a&gt; on iPhone and &lt;a href="http://www.twhirl.org/"&gt;twhirl&lt;/a&gt; on the Mac, but I am not married to either of these clients. Beware: Twitter most likely will kill your personal blog (as if it needed that!).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.apple.com/iphone/"&gt;iPhone 3G&lt;/a&gt;: I simply can't imagine switching to anything else before a long time. I use pretty much the whole of it: phone, SMS, web, email, iPod, maps, camera, Yelp, music apps, book readers, dictionaries, you name it. Its biggest flaws are the inability to run more than one application concurrently (e.g. for music apps)  and the lack of background notifications (e.g. Twitter and IM clients). I don't care how Apple does it, but these have to be addressed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.apple.com/safari/"&gt;Safari&lt;/a&gt; has become my second browser of choice after Firefox. WebKit is great (with some quirks), Safari itself not so much. To be really usable, a browser needs: 1) something like the Firefox "awsome bar", 2) an ad blocker and 3) proper tab save/restore. Safari does have some add-ons partly addressing these shortcomings, but Firefox remains the king in this area. So I use Safari for certain specific sites or applications only.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://wiki.orbeon.com/forms/"&gt;Google Sites&lt;/a&gt; handles the new Orbeon Forms wiki. Sites can do better, and it is frustrating that it is incompatible in subtle ways with Google Docs, but it is a start.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The strong values:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt; version 3 for Mac is a winner. It is hard to imagine we had to deal with the quirky version 2 for so long.&lt;/li&gt;&lt;li&gt;&lt;a href="http://mail.google.com/"&gt;GMail&lt;/a&gt;: I still use it mostly through OS X's Mail app through IMAP, but I had to disable the "All mail" folder to make it usable. The big change is that I use it through the iPhone mail application as well. I often process (archive) my incoming email on the go, but rarely write more than one-liners on the phone.&lt;/li&gt;&lt;li&gt;&lt;a href="http://del.icio.us/"&gt;Delicious&lt;/a&gt;: I am now at about 4100 entries (was 1900 entries a year ago). Version 2.0, delivered in July, is a success. I add entries mostly through the Firefox extension.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt;: VoiP, chat, video, SkypeOut, SkypeIn and soon, I hope, usable screen sharing.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/calendar"&gt;Google Calendar&lt;/a&gt; and &lt;a href="http://maps.google.com/"&gt;Google Maps&lt;/a&gt; remain essential.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt; is strong and getting stronger. The new offline support is excellent.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.slimtimer.com/"&gt;SlimTimer&lt;/a&gt;: it is still impossible to live without it at work, although report performance is an issue and development seems to have stalled.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.apple.com/itunes/"&gt;iTunes&lt;/a&gt; is frustrating in many ways but unavoidable if you have an iPhone. The new grid view for albums in version 8 is good, and it is still probably the best podcast client around.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.apple.com/itunes/whatson/"&gt;iTunes Store&lt;/a&gt;: yesterday's announcement of 100% DRM-free music was long due and I may buy again music through iTunes (other than by accident). Movie rentals rock, but the movie selection is appalling.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/MP3-Music-Download/b?ie=UTF8&amp;amp;node=163856011"&gt;Amazon mp3 Store&lt;/a&gt; remains appealing because of price, selection, the ubiquitous mp3 format, and the web-based interface.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://picasa.google.com/mac/"&gt;Picasa&lt;/a&gt; is my favorite photo application. I had been using it recently through CrossOver, but I now use the new native version. I wonder if iPhoto 2009 will displace Picasa for me this year? In particular, the flickr integration is very promising, and Google has less incentive than Apple to promote flickr support.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.flickr.com/"&gt;Flickr&lt;/a&gt; is still my photo site of choice, but improvements have been slow to come this year.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/reader/"&gt;Google Reader&lt;/a&gt; holds about 270 feeds as of now (was 200 a year ago). The recently introduced new look is refreshing. I find myself using it less heavily as lots of news come from Twitter.&lt;/li&gt;&lt;/ul&gt;The disappointments:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.basecamphq.com/"&gt;Basecamp&lt;/a&gt;: we still use it at &lt;a href="http://www.orbeon.com/"&gt;Orbeon&lt;/a&gt; to communicate with our customers. I no longer use it as a personal to-do list as it sucks at that. Basecamp is reliable and cheap, but there are issues with messages, to-do lists, time management, and the writeboards that really don't leave me very satisfied with it at the moment. 37signals is good at rhetoric, but less so at regularly updating their applications (at least Basecamp, which is rumored to represent 60% of 37signals's about $8m revenue for 2009).&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.omnigroup.com/applications/omnifocus/iphone/"&gt;OmniFocus for iPhone&lt;/a&gt; is in some ways a better GTD tool than the desktop version. For example it has a built-in notion of next action, and its relative simplicity is attractive. But stability and performance make it about unusable. It often takes 30 seconds or more to start, and much more after a synchronization. I am &lt;a href="http://twitter.com/avernet/status/1097333931"&gt;not the only one&lt;/a&gt; with this problem. A GTD app must be snappy and reliable, so this is a big letdown.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.jott.com/"&gt;Jott&lt;/a&gt;: I haven't used it as much as I thought, especially since the iPhone app is unable to send notification emails even with the paying plans. If they fix that I will pay $3/month without even thinking.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.adobe.com/products/acrobatconnect/"&gt;Adobe Acrobat Connect&lt;/a&gt; seemed like the best affordable screen sharing application out there, but it can cause browser crashes and handling of screen dimensions is frustrating (try sharing when using a 30" monitor!). Unfortunately, WebEx remains the most stable and powerful solution out there, but it is outrageously priced.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/chrome"&gt;Google Chrome&lt;/a&gt; could replace Safari as my second browser of choice if there was a Mac version. I suppose it is coming soon. Or is it, given that it took Google years to release Picasa for Mac?&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/"&gt;Blogger&lt;/a&gt; hasn't seen a single visible improvement since last year. Frankly, it is not a very good blogging service anymore.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.feedburner.com/"&gt;Feedburner&lt;/a&gt; is not that useful anymore given the general decrease in personal and work blogging activity.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt; has not really moved beyond its lowest common denominator position. I watch videos mostly through iTunes podcasts, iTunes video rentals, or other sources.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Social networks:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I have been going to the &lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt; site more (but not really "using it" more) because many less geeky friends use it. I mostly go to the site when I get an email notification. My guess is that photo sharing and tagging will be the first feature of Facebook I might actually appreciate this year.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I have about 200 connections on &lt;a href="http://www.linkedin.com/"&gt;LinkedIn&lt;/a&gt; (from about 150 a year ago). I still haven't found any actual use for it.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.dopplr.com/"&gt;Dopplr&lt;/a&gt;: I entered a few more trips there but it hasn't been really useful so far.&lt;/li&gt;&lt;/ul&gt;Like last year, I fail to find most social networks either really useful or exciting, Twitter remaining the notable exception.&lt;br /&gt;&lt;br /&gt;See you next year!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-5374312355604617569?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/5374312355604617569/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=5374312355604617569" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/5374312355604617569?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/5374312355604617569?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2009/01/2009-products-i-cant-live-without.html" title="2009: Products I Can’t Live Without" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;DEMAR344eCp7ImA9WxRWEEU.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-1901455506356688540</id><published>2008-10-25T21:30:00.000-07:00</published><updated>2008-10-26T22:47:26.030-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-10-26T22:47:26.030-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="harddisk" /><category scheme="http://www.blogger.com/atom/ns#" term="macbookpro" /><category scheme="http://www.blogger.com/atom/ns#" term="laptop" /><category scheme="http://www.blogger.com/atom/ns#" term="howto" /><category scheme="http://www.blogger.com/atom/ns#" term="mac" /><category scheme="http://www.blogger.com/atom/ns#" term="hardware" /><category scheme="http://www.blogger.com/atom/ns#" term="storage" /><category scheme="http://www.blogger.com/atom/ns#" term="harddrive" /><category scheme="http://www.blogger.com/atom/ns#" term="macbook" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>Upgrading Your 17" MacBook Pro Hard Drive</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_DSqG0J8ANmg/SQPqQ_4jywI/AAAAAAAAANs/hg1k5RZcxl4/s1600-h/IMG_0319.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; height: 250px;" src="http://4.bp.blogspot.com/_DSqG0J8ANmg/SQPqQ_4jywI/AAAAAAAAANs/hg1k5RZcxl4/s400/IMG_0319.JPG" alt="" id="BLOGGER_PHOTO_ID_5261306367446338306" border="0" /&gt;&lt;/a&gt;A few days ago I upgraded my MacBook Pro's hard drive after realizing 320 GB drives sell for USD 110 - which made constantly worrying about disk space ridiculous. This also should extend my old MBP's life a little bit.&lt;br /&gt;&lt;br /&gt;Here are the steps needed to replace the drive:&lt;ul&gt;&lt;li&gt;Buy the new drive ;-) I &lt;a href="http://www.newegg.com/Product/Product.aspx?Item=N82E16822136280"&gt;got mine from Newegg&lt;/a&gt;. I picked a 7200 rpm 320 GB drive instead of a 5400 rpm 500 GB drive hoping that performance will be slightly better.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Backup your system. I use Time Machine and Time Capsule so that part was easy. Just make sure you don't do any significant work after the last backup.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Follow the &lt;a href="http://www.ifixit.com/Guide/Mac/MacBook-Pro-17-Inch-Core-Duo/Hard-Drive-Replacement/87/8/"&gt;ifixit instructions to open the laptop and replace the drive&lt;/a&gt;. Count about 1 hour to go through this, unless like me you have&lt;span&gt; to run to Home Depot to get one of those funny TORX T6 screwdrivers.&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reassemble the laptop.&lt;/li&gt;&lt;/ul&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_DSqG0J8ANmg/SQPlHcRrPII/AAAAAAAAANk/BOY4vpzWi0I/s1600-h/IMG_0321.JPG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; clear: both; cursor: pointer; width: 250px;" src="http://2.bp.blogspot.com/_DSqG0J8ANmg/SQPlHcRrPII/AAAAAAAAANk/BOY4vpzWi0I/s400/IMG_0321.JPG" alt="" id="BLOGGER_PHOTO_ID_5261300705711045762" border="0" /&gt;&lt;/a&gt;Now for the software part:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Boot on the Leopard install DVD.&lt;/li&gt;&lt;li&gt;In the menu, chose &lt;span style="font-style: italic;"&gt;Disk Utility&lt;/span&gt;. Use that to partition and format the new drive.&lt;/li&gt;&lt;li&gt;Make sure the MBP has a way to connect to the network. I connected it by ethernet directly to Time Capsule to shorten the restore time.&lt;/li&gt;&lt;li&gt;Restart the machine. I had to do this or the Time Machine restore wouldn't see the new drive.&lt;/li&gt;&lt;li&gt;This time choose &lt;span style="font-style: italic;"&gt;Restore System from backup&lt;/span&gt;. There you pick a source backup. First, you pick your Time Capsule (if that's what you use), then the backup sparse bundle file, and finally the backup version. For the destination, obviously, choose your newly-installed drive.&lt;/li&gt;&lt;li&gt;The restore tool then spends a lot of time computing the size of the backup to make sure the data fits in the destination. In my case this took between 30 and 60 minutes.&lt;/li&gt;&lt;li&gt;Finally, start the restoration process proper. I let this run overnight so I don't know exactly how long this required, but it took less than 12 hours to restore about 140 GB of data.&lt;/li&gt;&lt;/ul&gt;Et voilà, &lt;span class="entry-content"&gt;174.76 GB of free space! That won't last long...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You may also want to read &lt;a href="http://duncandavidson.com/2008/01/restoring-from-time-machine.html"&gt;this excellent post by James Duncan Davidson&lt;/a&gt;, with much better photos than the ones I took with my iPhone.&lt;br /&gt;&lt;br /&gt;UPDATE: I forgot to mention the following caveats:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Time Machine does not backup the spotlight index, so spotlight will run for a while after your first boot with the new drive.&lt;/li&gt;&lt;li&gt;The same goes for the Mail.app caches when using IMAP: Mail.app takes quite a while resynchronizing all your email folders.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;I had rented a movie from iTunes before upgrading. Guess what: that wasn't backed up either, and I had to pay again for the rental as it doesn't appear you can just download the movie again.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-1901455506356688540?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/1901455506356688540/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=1901455506356688540" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1901455506356688540?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1901455506356688540?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/10/upgrading-your-17-macbook-pro-hard.html" title="Upgrading Your 17&quot; MacBook Pro Hard Drive" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_DSqG0J8ANmg/SQPqQ_4jywI/AAAAAAAAANs/hg1k5RZcxl4/s72-c/IMG_0319.JPG" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;CEQMRn4-fyp7ImA9WxdVEE8.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-52048828396933413</id><published>2008-07-13T17:31:00.001-07:00</published><updated>2008-07-14T00:59:47.057-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-07-14T00:59:47.057-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="shopping" /><category scheme="http://www.blogger.com/atom/ns#" term="marketing" /><category scheme="http://www.blogger.com/atom/ns#" term="3g" /><category scheme="http://www.blogger.com/atom/ns#" term="iphone" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>iPhone 3G Day: the Good Parts</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_DSqG0J8ANmg/SHqlqx29o9I/AAAAAAAAAJM/zkC7S0D8FDw/s1600-h/iphone-3g-trophy.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_DSqG0J8ANmg/SHqlqx29o9I/AAAAAAAAAJM/zkC7S0D8FDw/s400/iphone-3g-trophy.jpg" alt="" id="BLOGGER_PHOTO_ID_5222668872246469586" border="0" /&gt;&lt;/a&gt;Like many, I took the plunge on Friday and bought an iPhone 3G (&lt;a href="http://www.flickr.com/photos/ebruchez/sets/72157606132279444/"&gt;pictures and videos of the saga here&lt;/a&gt;). It was clearly not the most reasonable thing to do to stand in line for hours to get an expensive device associated with an expensive 2-year contract with AT&amp;amp;T (which is not a particularly loved company). But hey, all that was known in advance.&lt;br /&gt;&lt;br /&gt;What in the end amazed me was the quality of the shopping experience at the Palo Alto Apple store. I am not talking about the 6 hours spent standing in line: this was partly due to the activation process, already expected to be extremely slow, and which took a turn for the worse due to Apple and AT&amp;amp;T servers being down. But even that was kind of expected and part of the game.&lt;br /&gt;&lt;br /&gt;The first thing was the quality and professionalism of the Apple store staff:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;On that busy day, the two Apple stores I called actually had somebody available to pick up the phone and kindly answer my questions about stock and expected wait time.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Employees regularly walked up and down the line, offering water and answering questions.&lt;/li&gt;&lt;li&gt;At the end of the line, every buyer was greeted and personally managed. The usual wireless device used at Apple stores allowed for just picking a convenient spot in the store to talk and handle the registration process.&lt;/li&gt;&lt;li&gt;The (tired) employees remained amicable and helpful without being obsequious, providing regular updates, although obviously they couldn't do much about the failing servers.&lt;/li&gt;&lt;li&gt;When the possibility arose that the iPhones could not be activated before the following day and that instead we would get a voucher for the following morning, the store manager individually talked to all the customers affected and shook hands with them.&lt;/li&gt;&lt;/ul&gt;In short everything was designed to make you, the customer, feel treated as well as possible given the circumstances.&lt;br /&gt;&lt;br /&gt;The second amazing thing is the aura that was put around the iPhone: &lt;ul&gt;&lt;li&gt;The iPhone was fetched and brought back to you as if it was a unique jewel, in a nice "iPhone 3G" bag containing the quite beautiful iPhone 3G box.&lt;/li&gt;&lt;li&gt;You were given the opportunity to open the sealed box yourself before proceeding to activation (see the &lt;a href="http://tinyurl.com/5eqq9z"&gt;instructions for the retail employees as &lt;/a&gt;&lt;a href="http://tinyurl.com/5eqq9z"&gt;reported by MacRumors&lt;/a&gt;).&lt;/li&gt;&lt;li&gt;Finally, after all was said and done, the bag was handed back to you like a trophy (and it actually was one in a way given the effort it took to get it).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I know, after all, it's really just a phone ("This phone is that important to you?", said a woman passing by the line, "(Sigh) Different generation..."). But with this masterful &lt;span style="font-style: italic;"&gt;mise en scène&lt;/span&gt;, you really felt that you went through all this for a good reason. Whoever devised this whole process is a marketing genius.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-52048828396933413?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/52048828396933413/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=52048828396933413" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/52048828396933413?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/52048828396933413?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/07/iphone-3g-day-good-parts.html" title="iPhone 3G Day: the Good Parts" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_DSqG0J8ANmg/SHqlqx29o9I/AAAAAAAAAJM/zkC7S0D8FDw/s72-c/iphone-3g-trophy.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkEHSXs4eCp7ImA9WxZbGUs.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-6262898891944349839</id><published>2008-04-22T18:53:00.001-07:00</published><updated>2008-04-23T09:37:18.530-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-23T09:37:18.530-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bluetooth" /><category scheme="http://www.blogger.com/atom/ns#" term="fail" /><category scheme="http://www.blogger.com/atom/ns#" term="motorola" /><category scheme="http://www.blogger.com/atom/ns#" term="audio" /><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><category scheme="http://www.blogger.com/atom/ns#" term="hardware" /><category scheme="http://www.blogger.com/atom/ns#" term="review" /><category scheme="http://www.blogger.com/atom/ns#" term="headphones" /><title>A case of failed technology: Bluetooth headphones</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_DSqG0J8ANmg/SA9hFEob49I/AAAAAAAAAH8/XOZqCdvxwHg/s1600-h/motorola-s9.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_DSqG0J8ANmg/SA9hFEob49I/AAAAAAAAAH8/XOZqCdvxwHg/s400/motorola-s9.jpg" alt="" id="BLOGGER_PHOTO_ID_5192475635152053202" border="0" /&gt;&lt;/a&gt;I've had a fair experience with Bluetooth devices, including headsets, mice, and keyboards. At home, I am now using the Apple Bluetooth keyboard and mouse, and I am quite happy with them.&lt;br /&gt;&lt;br /&gt;Recently, I thought I would look at getting a Bluetooth headphone, especially since the advanced audio profile (&lt;a href="http://en.wikipedia.org/wiki/A2DP#Advanced_Audio_Distribution_Profile_.28A2DP.29"&gt;A2DP&lt;/a&gt;) seems to be getting more widespread, and OS X Leopard finally added support for it. It is just so appealing to go cordless.&lt;br /&gt;&lt;br /&gt;So I ordered the &lt;a href="http://www.amazon.com/Motorola-MOTOROKR-Bluetooth-Headphones-Packaging/dp/B000NKCO5Q"&gt;Motorola MOTOROKR S9&lt;/a&gt;, which had pretty good reviews, and I connected it to my MacBook Pro. Here are the major issues I encountered:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Even when no music is playing, there is a constant background noise. If you adjust the volume optimally and play pop music, you may not notice it so much, but this pretty much kills classical music.&lt;/li&gt;&lt;li&gt;Interferences, which translate with pops and cracks, come up every few seconds or tens of seconds. I tried distances between the headphone and the computer of maybe two to then feet, with the same result.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Background noise and interferences aside, the sound quality is metallic and full of artifacts which remind me of the first mp3 encoders back in the 90s. I guess that this may be due to the use of the low complexity SBC codec instead of decent compression on the wire.&lt;/li&gt;&lt;li&gt;Using the headphone or headset along with a Bluetooth mouse simply doesn't work: the mouse will stop to a crawl.&lt;/li&gt;&lt;li&gt;I got a complete OS crash (kernel panic) in the OS X A2DP driver. This actually happened after my headset was already shipped back.&lt;/li&gt;&lt;/ul&gt;The above I think fully justifies my sending the S9 back to Amazon. There are also smaller issues:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I got into situations where no sound would come out at all when playing from iTunes, and I simply couldn't get things back to work without pairing the device again.&lt;/li&gt;&lt;li&gt;I couldn't get Skype to use the headset microphone as input, but the high-quality A2DP as output.&lt;/li&gt;&lt;li&gt;As a headset, the sound only comes out on the left side.&lt;/li&gt;&lt;/ul&gt;In short I am utterly disappointed because I thought that by now the technology would be ready, and it turns out that there is a lot going on for the S9:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It really looks cool and is almost invisible from the front&lt;/li&gt;&lt;li&gt;The sound quality of the earbuds themselves seems decent&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It is comfortable and lightweight&lt;/li&gt;&lt;li&gt;As a headset connected to an iPhone, it seemed to work quite well&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Hopefully the manufacturers will soon figure out how to really make this work. As it is today, I simply think that it is not useable, certainly not with a Mac.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-6262898891944349839?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/6262898891944349839/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=6262898891944349839" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/6262898891944349839?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/6262898891944349839?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/04/case-of-failed-technology-bluetooth.html" title="A case of failed technology: Bluetooth headphones" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_DSqG0J8ANmg/SA9hFEob49I/AAAAAAAAAH8/XOZqCdvxwHg/s72-c/motorola-s9.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkMHRH4_eSp7ImA9WxZQEko.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-9100334711056580388</id><published>2008-02-17T10:53:00.000-08:00</published><updated>2008-02-17T10:53:55.041-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-02-17T10:53:55.041-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="met" /><category scheme="http://www.blogger.com/atom/ns#" term="tvhd" /><category scheme="http://www.blogger.com/atom/ns#" term="movies" /><category scheme="http://www.blogger.com/atom/ns#" term="music" /><category scheme="http://www.blogger.com/atom/ns#" term="puccini" /><category scheme="http://www.blogger.com/atom/ns#" term="opera" /><title>Met HD broadcasts at movie theaters actually quite good</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_DSqG0J8ANmg/R7iCb8eUGeI/AAAAAAAAAHM/P5oabSpqKGk/s1600-h/met.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp1.blogger.com/_DSqG0J8ANmg/R7iCb8eUGeI/AAAAAAAAAHM/P5oabSpqKGk/s400/met.png" alt="" id="BLOGGER_PHOTO_ID_5168023989008996834" border="0" /&gt;&lt;/a&gt;Saturday morning we went to the local movie theater to watch a &lt;a href="http://www.metoperafamily.org/metopera/broadcast/hd_events.aspx"&gt;Metropolitan Opera's high-definition live broadcast&lt;/a&gt; of Puccini's &lt;span style="font-style: italic;"&gt;Manon Lescaut&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I was curious about how much I would enjoy watching an opera in a movie theater, but it turned out to be quite good in several respects:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I had heard that these broadcasts had been quite successful last year, but somehow I could not really believe it. We joked before entering the theater that maybe we would be the only two people there. But in fact the place was almost packed (mostly with gray or white heads), which was heart-warming.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Half of each of the two intermissions was spent taking the viewer behind the scene. &lt;a href="http://www.reneefleming.com/"&gt;Renée Fleming&lt;/a&gt; interviewed the two protagonists (Karita Mattila and Marcello Giordani), conductor James Levine, the stage manager, and the couple in charge of animals on stage (horses and dog). You also got to see the cast behind the curtain, and all the work needed to change the sets. This is  material which you simply don't get at the opera.&lt;/li&gt;&lt;li&gt;You get to see a lot of the action much better than if you are sitting hundreds of feet away from a stage. You also get to see what was happening in the orchestra pit during orchestral moments.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It costs only $22, it's close from home, there is plenty of parking and and you don't have to dress up.&lt;/li&gt;&lt;li&gt;Picture and sound quality are good, although sitting quite in front of the theater, you can see the pixels. I wonder what's the resolution? 720?1080?&lt;/li&gt;&lt;/ul&gt;Other than that the performance was quite good. I had never seen Puccini's &lt;span style="font-style: italic;"&gt;Manon Lescaut&lt;/span&gt;, performed less often than Massenet's version of &lt;a href="http://en.wikipedia.org/wiki/Antoine_Fran%C3%A7ois_Pr%C3%A9vost"&gt;l'Abbé Prévost's story&lt;/a&gt;. This is not an opera as perfect dramatically as &lt;span style="font-style: italic;"&gt;La Bohème&lt;/span&gt;, but you can understand why this was Puccini's first real success on stage.&lt;br /&gt;&lt;br /&gt;The sets were gorgeous. Karita Mattila, at 47 (as she tells herself during her interview), is old for the role of the youthful Manon, and this appears too well during the close-ups, but she sang and acted wonderfully. Unusually maybe for a modern tenor, Marcello Giordani has a warm and pleasing voice and did quite well in the several quite demanding arias. Conducting was as you could expect from Levine.&lt;br /&gt;&lt;br /&gt;I think we will be tempted by the experience again. Next up are Britten's &lt;span style="font-style: italic;"&gt;Peter Grimes&lt;/span&gt;, Wagner's &lt;span style="font-style: italic;"&gt;Tristan und Isolde&lt;/span&gt;, Puccini's &lt;span style="font-style: italic;"&gt;La Bohème&lt;/span&gt;, and Donzetti's &lt;span style="font-style: italic;"&gt;La Fille du Régiment&lt;/span&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-9100334711056580388?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/9100334711056580388/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=9100334711056580388" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/9100334711056580388?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/9100334711056580388?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/02/met-hd-broadcasts-at-movie-theaters.html" title="Met HD broadcasts at movie theaters actually quite good" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_DSqG0J8ANmg/R7iCb8eUGeI/AAAAAAAAAHM/P5oabSpqKGk/s72-c/met.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEAHSX04cCp7ImA9WxZTGEg.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-4380249458074452818</id><published>2008-01-20T10:10:00.000-08:00</published><updated>2008-01-20T10:12:18.338-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-20T10:12:18.338-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="drm" /><category scheme="http://www.blogger.com/atom/ns#" term="mp3" /><category scheme="http://www.blogger.com/atom/ns#" term="music" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><category scheme="http://www.blogger.com/atom/ns#" term="itunes" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>Even more stuff Steve did not announce</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_DSqG0J8ANmg/R5ONUJ2HsTI/AAAAAAAAAG0/uXfGTLZSllE/s1600-h/itunes.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_DSqG0J8ANmg/R5ONUJ2HsTI/AAAAAAAAAG0/uXfGTLZSllE/s400/itunes.png" alt="" id="BLOGGER_PHOTO_ID_5157621375649165618" border="0" /&gt;&lt;/a&gt;Following-up on &lt;a href="http://avernet.blogspot.com/2008/01/more-features-not-announced-and-20.html"&gt;Alex's&lt;/a&gt; &lt;a href="http://avernet.blogspot.com/2008/01/steve-jobs-keynote-what-apple-did-not.html"&gt;posts&lt;/a&gt;, to me the most glaring hole in the MacWorld announcements was the lack of any update about DRM-free music.&lt;br /&gt;&lt;br /&gt;Apple was a precursor of DRM-free music online with last year's &lt;a href="http://www.apple.com/pr/library/2007/04/02itunes.html"&gt;EMI deal&lt;/a&gt;, but EMI, Warner, Universal, and Sony BMG, that is all the major labels, have since announced &lt;a href="http://www.amazon.com/MP3-Music-Download/b?ie=UTF8&amp;amp;node=163856011"&gt;DRM-free mp3 downloads on Amazon.com&lt;/a&gt; while Apple got nothing new to show. A &lt;a href="http://www.techcrunch.com/2008/01/10/amazon-completes-drm-free-roster-with-sony-bmg/"&gt;TechCrunch post&lt;/a&gt; mentions that "Amazon now has 3.25 million DRM-free tracks in their library, compared to just 2 million at iTunes."&lt;br /&gt;&lt;br /&gt;iTunes must have another 4 million DRM-protected tracks, but I can't imagine any informed person buying any of those now, and that has to mean that people will start shifting towards using Amazon. Of course Apple has the benefit of its installed base, iTunes on every Mac, and consumer inertia (after all they just sold their 4 billionth song).&lt;br /&gt;&lt;br /&gt;Maybe Apple has been simply too busy securing the deals with the movie industry for online video rentals - clearly a potentially quite disruptive move. Still I can't imagine Apple not caring about the situation with music downloads, so this means that Apple is having real trouble with the major labels. Is this the beginning of the end for the supremacy of the iTunes music store?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-4380249458074452818?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/4380249458074452818/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=4380249458074452818" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/4380249458074452818?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/4380249458074452818?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/01/even-more-stuff-steve-did-not-announce.html" title="Even more stuff Steve did not announce" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_DSqG0J8ANmg/R5ONUJ2HsTI/AAAAAAAAAG0/uXfGTLZSllE/s72-c/itunes.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DEEERHkzfCp7ImA9WxZTEUg.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-3358428808204809532</id><published>2008-01-12T08:49:00.000-08:00</published><updated>2008-01-12T08:50:05.784-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-12T08:50:05.784-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="pdf" /><category scheme="http://www.blogger.com/atom/ns#" term="leopard" /><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><category scheme="http://www.blogger.com/atom/ns#" term="adobe" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>PDF support: one of the highlights of OS X Leopard</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_DSqG0J8ANmg/R4jupp2HsSI/AAAAAAAAAGs/lRymJFYhc-4/s1600-h/pdf.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp3.blogger.com/_DSqG0J8ANmg/R4jupp2HsSI/AAAAAAAAAGs/lRymJFYhc-4/s400/pdf.jpg" alt="" id="BLOGGER_PHOTO_ID_5154632172900430114" border="0" /&gt;&lt;/a&gt;Many of my tasks, at &lt;a href="http://www.orbeon.com/"&gt;Orbeon&lt;/a&gt; or personal, involve PDF documents:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Sending invoices to customers (no way we are sending Word or Excel documents!)&lt;/li&gt;&lt;li&gt;Archiving, viewing and searching documents scanned with the &lt;a href="http://ebruchez.blogspot.com/2008/01/paperless-life-with-fujitsu-scansnap.html"&gt;ScanSnap&lt;/a&gt; scanner&lt;/li&gt;&lt;li&gt;Viewing faxes received by email&lt;/li&gt;&lt;li&gt;Saving online articles for reference, further reading or printing (until we get good e-paper I prefer to read long articles on good old dead trees)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I was already using PDF a lot on Windows, but that required installing a free viewing tool (&lt;a href="http://www.adobe.com/products/acrobat/readstep2.html"&gt;Adobe Reader&lt;/a&gt;) and a paying PDF printing tool (Adobe Acrobat).&lt;br /&gt;&lt;br /&gt;When I switched to the Mac back in 2006, I appreciated right away the built-in ability to view and print PDF documents without buying a third-party tool. But Leopard adds even more to the mix:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The new Quick Look feature in the Finder and Mail is not perfect, but excellent nonetheless: just press the space bar (Finder) or a button (Mail) and you have a super-fast preview of almost any document or attachment, including PDF. You can even scroll down multi-page documents and keep the preview open while navigating to other documents. (To be fair, OS X should have had this for years but better late than never.)&lt;/li&gt;&lt;li&gt;The new Preview allows you to insert, delete, rotate, and reorganize pages in a PDF document and save the result.&lt;/li&gt;&lt;li&gt;The much improved Spotlight automatically indexes PDF documents for (almost) instant content search.&lt;/li&gt;&lt;/ul&gt;Windows XP has nothing of the sort built-in. Vista has &lt;a href="http://en.wikipedia.org/wiki/XML_Paper_Specification"&gt;XPS&lt;/a&gt;, which sounds cool but, no matter how good it may be, is today nowhere as widespread as PDF and that alone does not make it a viable option for me at the moment. Leopard definitely wins this one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-3358428808204809532?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/3358428808204809532/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=3358428808204809532" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/3358428808204809532?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/3358428808204809532?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/01/pdf-support-one-of-highlights-of-os-x.html" title="PDF support: one of the highlights of OS X Leopard" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp3.blogger.com/_DSqG0J8ANmg/R4jupp2HsSI/AAAAAAAAAGs/lRymJFYhc-4/s72-c/pdf.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkQERX8ycSp7ImA9WB9aFEk.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-9128775656837117888</id><published>2008-01-04T04:04:00.000-08:00</published><updated>2008-01-04T04:05:04.199-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T04:05:04.199-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scanner" /><category scheme="http://www.blogger.com/atom/ns#" term="tip" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><category scheme="http://www.blogger.com/atom/ns#" term="fujitsu" /><category scheme="http://www.blogger.com/atom/ns#" term="digitization" /><category scheme="http://www.blogger.com/atom/ns#" term="paper" /><category scheme="http://www.blogger.com/atom/ns#" term="scansnap" /><category scheme="http://www.blogger.com/atom/ns#" term="paperless" /><category scheme="http://www.blogger.com/atom/ns#" term="lifehack" /><category scheme="http://www.blogger.com/atom/ns#" term="hardware" /><title>A paperless life with the Fujitsu ScanSnap scanner</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_DSqG0J8ANmg/R34GzJ2HsRI/AAAAAAAAAGk/16nvHud8FeM/s1600-h/scansnap.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp3.blogger.com/_DSqG0J8ANmg/R34GzJ2HsRI/AAAAAAAAAGk/16nvHud8FeM/s400/scansnap.jpg" alt="" id="BLOGGER_PHOTO_ID_5151562499644436754" border="0" /&gt;&lt;/a&gt;I recently bought two &lt;a href="http://scansnap.fujitsu.com/ss_about.html"&gt;Fujitsu ScanSnap&lt;/a&gt; scanners: one for the &lt;a href="http://www.orbeon.com/"&gt;office&lt;/a&gt; (Mac version) and one as a gift for &lt;a href="http://bruchez.blogspot.com/"&gt;my brother&lt;/a&gt; (PC version).&lt;br /&gt;&lt;br /&gt;For as long as I can remember, I have had a strong aversion for paper documents. You know, bank statements, invoices to pay, receipts, leases, you name it. Some of these things can be thrown away, but others should be kept for a while just in case. I also have the notion that in this day and age, we shouldn't need to destroy information.&lt;br /&gt;&lt;br /&gt;The problem is that paper documents just seem to pile up in a disorganized way unless you make some very serious organization efforts involving old-fashioned hardware like staples, folders, binders, and cardboard boxes. In the end this takes a lot of space and you don't even know where the stuff is. I get goosebumps just thinking about it.&lt;br /&gt;&lt;br /&gt;So the obvious solution is to go paperless, which involves scanning those documents which you don't get in electronic form. Going that route with a regular flatbed scanner involves:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Placing a sheet on the scanner&lt;/li&gt;&lt;li&gt;Going to your scanning software and starting the scan&lt;/li&gt;&lt;li&gt;If necessary: turning the page to scan the reverse side&lt;/li&gt;&lt;/ul&gt;Then repeat until you have scanned all the pages. After that, you may be happy with just plain image files, or you may want to fire your PDF-making software and/or your OCR software. If you are really lucky, things will be smooth enough. But in the end the whole process is just hell for any document with more than one page. I think you have to be somewhat superhuman to consistently go this route. I personally tried and failed.&lt;br /&gt;&lt;br /&gt;Enter the ScanSnap:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Put your multi-page front and back document in the tray&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Press the button on the scanner&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Voila: your PDF file is ready&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;The ScanSnap is able to scan in duplex, that is front and back (with an option to automatically remove blank pages). It also comes with OCR software which can create searchable PDF documents as an optional (but computationally intensive) step.&lt;br /&gt;&lt;br /&gt;It's just amazing how fast you can scan piles of year-old documents with this toy. In fact, scanning actually becomes fun. The hardest task is to name the resulting PDF files and move them into folders (although in theory you could skip this step if you are happy with automatically-generated file names and if you plan to rely 100% on content search).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-9128775656837117888?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/9128775656837117888/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=9128775656837117888" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/9128775656837117888?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/9128775656837117888?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/01/paperless-life-with-fujitsu-scansnap.html" title="A paperless life with the Fujitsu ScanSnap scanner" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp3.blogger.com/_DSqG0J8ANmg/R34GzJ2HsRI/AAAAAAAAAGk/16nvHud8FeM/s72-c/scansnap.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0UHRX4-fip7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-8344955427840355685</id><published>2008-01-04T01:00:00.000-08:00</published><updated>2008-01-04T01:33:54.056-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:33:54.056-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="orbitz" /><category scheme="http://www.blogger.com/atom/ns#" term="complaint" /><category scheme="http://www.blogger.com/atom/ns#" term="travel" /><category scheme="http://www.blogger.com/atom/ns#" term="flying" /><category scheme="http://www.blogger.com/atom/ns#" term="consumer" /><title>How can Orbitz and the likes be so dishonest?</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_DSqG0J8ANmg/R31dmp2HsQI/AAAAAAAAAGc/38ZlV7aGMus/s1600-h/orbitz.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_DSqG0J8ANmg/R31dmp2HsQI/AAAAAAAAAGc/38ZlV7aGMus/s400/orbitz.png" alt="" id="BLOGGER_PHOTO_ID_5151376467430977794" border="0" /&gt;&lt;/a&gt;You know, like when all those cheap flights are listed, but Orbitz tells you that the flight is not available when you want to buy it? Systematically, our recent flight searches have come up with this issue. It seems that this is nothing new and has been going on for years.&lt;br /&gt;&lt;br /&gt;This is not only irritating, it also removes a lot of the value Orbitz is meant to provide.&lt;br /&gt;&lt;br /&gt;It's not just that you are out of luck and that the system is temporarily out of sync. After all, even after you check such a flight, it keeps popping up in your searches. And it often does the following day as well.&lt;br /&gt;&lt;br /&gt;There is certainly a solution to that problem if Orbitz and the airline companies actually want to fix this broken behavior. Given the amount of time this has been going on, I can only assume that it is deliberate.&lt;br /&gt;&lt;br /&gt;No matter whose fault it is, I am just wondering: how do we users put up with what only amounts to a permanent lie?&lt;br /&gt;&lt;br /&gt;In the meanwhile, I am trying to book flights directly from the airlines whenever possible. Even though they may be the ones providing the disinformation, I have not hit this issue on their web sites, and I want to send a signal to Orbitz, however small.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-8344955427840355685?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/8344955427840355685/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=8344955427840355685" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8344955427840355685?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8344955427840355685?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/01/how-can-orbitz-and-likes-be-so.html" title="How can Orbitz and the likes be so dishonest?" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_DSqG0J8ANmg/R31dmp2HsQI/AAAAAAAAAGc/38ZlV7aGMus/s72-c/orbitz.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0UBQnw_fyp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-1472023983921270373</id><published>2008-01-03T14:48:00.000-08:00</published><updated>2008-01-04T01:34:13.247-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:34:13.247-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="web20" /><category scheme="http://www.blogger.com/atom/ns#" term="software" /><title>2008: Web 2.0 software I use every day</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_DSqG0J8ANmg/R3zm1Z2HsPI/AAAAAAAAAGU/v8X0EjiHKis/s1600-h/web20.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp2.blogger.com/_DSqG0J8ANmg/R3zm1Z2HsPI/AAAAAAAAAGU/v8X0EjiHKis/s400/web20.png" alt="" id="BLOGGER_PHOTO_ID_5151245878950342898" border="0" /&gt;&lt;/a&gt;Following-up on Michael Arrington's post &lt;a href="http://www.techcrunch.com/2008/01/01/2008-web-20-companies-i-couldnt-live-without/"&gt;"2008: Web 2.0 Companies I Couldn’t Live Without"&lt;/a&gt;, here are the Web 2.0 tools and services I use whenever I am behind the computer (I'll pass on the super-obvious ones like Google Search and Wikipedia which I doubt will be displaced any time soon):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://del.icio.us/"&gt;Delicious&lt;/a&gt;: over 1900 entries and counting&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.slimtimer.com/"&gt;SlimTimer&lt;/a&gt;: impossible to live without it at work&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.basecamphq.com/"&gt;Basecamp&lt;/a&gt;: we use it at &lt;a href="http://www.orbeon.com/"&gt;Orbeon&lt;/a&gt; to communicate with our customers (I even have a personal account for some To-Do lists)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/calendar"&gt;Google Calendar&lt;/a&gt;: all my scheduled activities (including a few shared calendars)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/reader/"&gt;Google Reader&lt;/a&gt;: about 200 feeds as of now (I switched a few months ago after being too frustrated with the reader in Thunderbird)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://mail.google.com/"&gt;GMail&lt;/a&gt;: I currently use it mostly through OS X's Mail app thanks to the recent GMail IMAP support&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.jott.com/"&gt;Jott&lt;/a&gt;: an amazing newcomer (I just keep Jotting myself when in the US)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt;: 'nuf said, using 3.0 beta 2 on Mac OS X at the moment&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt;: VoiP and chat (I use SkypeOut and SkypeIn as well)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.apple.com/itunes/"&gt;iTunes&lt;/a&gt;: music player and podcast platform (but for sure I won't buy any DRM-protected music from the iTunes Music Store)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Here are some other services I use frequently:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://docs.google.com/"&gt;Google Docs&lt;/a&gt;: whenever possible (but there is huge room for improvement in the software)&lt;/li&gt;&lt;li&gt;&lt;a href="http://wordpress.org/"&gt;Wordpress&lt;/a&gt;: whenever I post a work blog entry&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.blogger.com/"&gt;Blogger&lt;/a&gt;: whenever I post a personal blog entry&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.feedburner.com/"&gt;Feedburner&lt;/a&gt;: all my feeds go through it&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://maps.google.com/"&gt;Google Maps&lt;/a&gt;: no comment&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/alerts"&gt;Google Alerts&lt;/a&gt;: mostly for alerts about &lt;a href="http://www.orbeon.com/"&gt;Orbeon&lt;/a&gt;, &lt;a href="http://www.w3.org/MarkUp/Forms/"&gt;XForms&lt;/a&gt; and &lt;a href="http://www.mascagni.org/"&gt;Mascagni&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.flickr.com/"&gt;Flickr&lt;/a&gt;: whenever I post pictures (I have a pro account)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt;: almost every time I watch a video&lt;/li&gt;&lt;/ul&gt;Some tools I like but which I don't use often:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.dopplr.com/"&gt;Dopplr&lt;/a&gt;: I enter my trips there, but it hasn't been really useful to sync up with anybody yet&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.mindmeister.com/"&gt;MindMeister&lt;/a&gt;: just a very cool piece of software&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.amazon.com/MP3-Music-Download/b?ie=UTF8&amp;amp;node=163856011"&gt;Amazon mp3 Store&lt;/a&gt;: I bought a few tracks to try it out, and I liked the smooth experience (just say no to DRM)&lt;/li&gt;&lt;/ul&gt;Incidentally, I have over 150 connections on &lt;a href="http://www.linkedin.com/"&gt;LinkedIn&lt;/a&gt; and I am getting started on &lt;a href="http://www.facebook.com/"&gt;Facebook&lt;/a&gt;. So far I fail to find them either really useful or exciting. I bet I am missing something, but one reason could be that neither provides me with a comprehensive RSS or Atom feed of the last updates: I certainly won't bother visiting these sites every day until that happens.&lt;br /&gt;&lt;br /&gt;I wonder how this landscape will change in one year. Hopefully there will be lots of improvements and good surprises!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-1472023983921270373?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/1472023983921270373/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=1472023983921270373" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1472023983921270373?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1472023983921270373?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2008/01/2008-web-20-software-i-use-every-day.html" title="2008: Web 2.0 software I use every day" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp2.blogger.com/_DSqG0J8ANmg/R3zm1Z2HsPI/AAAAAAAAAGU/v8X0EjiHKis/s72-c/web20.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0EDQXY8eSp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-8552896106321661750</id><published>2007-12-28T13:28:00.000-08:00</published><updated>2008-01-04T01:41:10.871-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:41:10.871-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="switzerland" /><category scheme="http://www.blogger.com/atom/ns#" term="firefox" /><category scheme="http://www.blogger.com/atom/ns#" term="complaint" /><category scheme="http://www.blogger.com/atom/ns#" term="i18n" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><title>Enough about (badly) guessing the user's language</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_DSqG0J8ANmg/R3VoZ52HsNI/AAAAAAAAAGE/EPyDd5nyRjY/s1600-h/firefox-language.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp1.blogger.com/_DSqG0J8ANmg/R3VoZ52HsNI/AAAAAAAAAGE/EPyDd5nyRjY/s400/firefox-language.jpg" alt="" id="BLOGGER_PHOTO_ID_5149136543201865938" border="0" /&gt;&lt;/a&gt;I am in Switzerland for Christmas. I launch a new Firefox install. Firefox loads the Firefox Start page, featuring Google search. The page is in German.&lt;br /&gt;&lt;br /&gt;About 64% of people speak Swiss-German dialects (and German as well), 20% French, 7% Italian, based on geographical boundaries. People in these different areas do not necessarily have a working knowledge of the other languages (even though they should). This means that Switzerland is not a German-speaking country in the same way that Germany is.&lt;br /&gt;&lt;br /&gt;For this reason, it is &lt;span style="font-weight: bold;"&gt;not ok&lt;/span&gt; to present pages in German by default when you believe that the user is located in Switzerland. Even if you think it is ok to make an clearly erroneous guess, then you &lt;span style="font-weight: bold;"&gt;must&lt;/span&gt; provide an easy way to switch to the other national languages as well as English. This ability &lt;span style="font-weight: bold;"&gt;must&lt;/span&gt; be available directly on the home page and &lt;span style="font-weight: bold;"&gt;must&lt;/span&gt; be a one-click operation. This is how Swiss sites typically behave.&lt;br /&gt;&lt;br /&gt;The Firefox home page is particularly badly designed in this respect. You can't switch language directly on the page. In fact, to change the language, you have to know German to go to the advanced search preferences ("Einstellungen", and then find the menu to change the user's language), which does not make any sense. Somebody without a knowledge of basic German or an awful lot of patience will simply not be able to do it at all.&lt;br /&gt;&lt;br /&gt;Other countries are multi-lingual, including but not limited to Belgium and Canada. I think it is time that companies that design localized sites become aware of this issue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-8552896106321661750?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/8552896106321661750/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=8552896106321661750" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8552896106321661750?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8552896106321661750?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/12/enough-about-badly-guessing-users.html" title="Enough about (badly) guessing the user's language" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_DSqG0J8ANmg/R3VoZ52HsNI/AAAAAAAAAGE/EPyDd5nyRjY/s72-c/firefox-language.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0UMRHozcSp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-1059774440058541706</id><published>2007-12-26T12:46:00.000-08:00</published><updated>2008-01-04T01:34:45.489-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:34:45.489-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="firefox" /><category scheme="http://www.blogger.com/atom/ns#" term="orbeon" /><category scheme="http://www.blogger.com/atom/ns#" term="mozilla" /><title>Firefox 3.0 beta 2 a good step forward</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_DSqG0J8ANmg/R3KReZ2HsMI/AAAAAAAAAF8/HLvYepB5YhE/s1600-h/firefox.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_DSqG0J8ANmg/R3KReZ2HsMI/AAAAAAAAAF8/HLvYepB5YhE/s400/firefox.jpg" alt="" id="BLOGGER_PHOTO_ID_5148337275557884098" border="0" /&gt;&lt;/a&gt;At long last, Firefox 3 is coming, with a second beta released just a few days ago.&lt;br /&gt;&lt;br /&gt;Firefox 2 is not too bad, and it is certainly preferable to using Internet Explorer, but it is plagued by memory leaks and gradual performance slowdowns. Firefox 3 is meant to improve a lot on this, thanks to "&lt;a href="http://www.mozilla.com/en-US/firefox/3.0b2/releasenotes/"&gt;nearly 2 million          lines of code changes&lt;/a&gt;" in the new Gecko engine.&lt;br /&gt;&lt;br /&gt;Add to this the fact that Firefox 3 greatly improves Mac OS X support (Firefox 2 on Mac OS X is sub-par compared to its Windows incarnation, with no native widgets and funny UI bugs), and there is no doubt that it will be a necessary upgrade.&lt;br /&gt;&lt;br /&gt;My first impression of 3.0 beta 2 is very good: history back/forward is much snappier, as is switching between tabs. Google Reader seems much faster. I have been using the beta for several days without any major problems, except some oddities in the Download Manager, and missing file names when printing to PDF.&lt;br /&gt;&lt;br /&gt;Compatibility with web sites out there seems excellent, although it is inevitable that issues will arise here or there. In particular, some code in &lt;a href="http://www.orbeon.com/"&gt;Orbeon Forms&lt;/a&gt; had to be fixed due to Firefox 3 fixing &lt;a href="https://bugzilla.mozilla.org/show_bug.cgi?id=206053"&gt;this bug&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There are a few disappointments:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Printing seems as broken as ever. Safari seems to do much better here, and I suspect that even IE does better, which is a real shame.&lt;/li&gt;&lt;li&gt;While OS integration is much improved on the Mac with native widgets, it doesn't seem that 3.0 beta 2 is able to use the native spellchecker  or Keychain.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;In spite of this, Firefox 3 will be a good step forward, and I can't wait for further performance improvements such as the integration of the &lt;a href="http://www.mozilla.org/projects/tamarin/"&gt;Tamarin&lt;/a&gt; VM.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-1059774440058541706?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/1059774440058541706/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=1059774440058541706" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1059774440058541706?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1059774440058541706?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/12/firefox-30-beta-2-good-step-forward.html" title="Firefox 3.0 beta 2 a good step forward" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_DSqG0J8ANmg/R3KReZ2HsMI/AAAAAAAAAF8/HLvYepB5YhE/s72-c/firefox.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0AESXkycCp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-2625947231893942995</id><published>2007-12-25T11:02:00.000-08:00</published><updated>2008-01-04T01:41:48.798-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:41:48.798-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="suisse" /><category scheme="http://www.blogger.com/atom/ns#" term="switzerland" /><category scheme="http://www.blogger.com/atom/ns#" term="complaint" /><category scheme="http://www.blogger.com/atom/ns#" term="movies" /><category scheme="http://www.blogger.com/atom/ns#" term="dmca" /><category scheme="http://www.blogger.com/atom/ns#" term="entertainment" /><category scheme="http://www.blogger.com/atom/ns#" term="corruption" /><category scheme="http://www.blogger.com/atom/ns#" term="dvd" /><category scheme="http://www.blogger.com/atom/ns#" term="freedom" /><title>I can't believe we still have DVD region coding</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_DSqG0J8ANmg/R3F1VZ2HsLI/AAAAAAAAAF0/6MV5pVgvqSM/s1600-h/drm.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp3.blogger.com/_DSqG0J8ANmg/R3F1VZ2HsLI/AAAAAAAAAF0/6MV5pVgvqSM/s400/drm.jpg" alt="" id="BLOGGER_PHOTO_ID_5148024859636773042" border="0" /&gt;&lt;/a&gt;Today I put in my computer a DVD from a &lt;a href="http://en.wikipedia.org/wiki/Blackadder"&gt;Blackadder&lt;/a&gt; set, bought legally for me as a gift a few of years ago.&lt;br /&gt;&lt;br /&gt;I happen to have plugged a European DVD into my US Mac, and you can guess what message I got from the Mac OS X Leopard DVD player. You got it: "The disc region does not match the drive region". Yeah, I can change it 4 times. Thanks, that's so generous.&lt;br /&gt;&lt;br /&gt;This is simply insane. I had forgotten that this even existed as I don't play DVDs very often. Furthermore, in Switzerland where I am at the moment, standalone players are routinely sold region-free (although that may change with the upcoming and particularly crazy &lt;a href="http://ebruchez.blogspot.com/2007/12/contre-le-dmca-suisse.html"&gt;Swiss DMCA&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;What is the sense of this region coding? This is the 21st century. People travel. They use the internet. The world is working hard on removing existing boundaries and I don't think it is permissible to build new, artificial barriers. Governments and industries that attempt to do that should be fought.&lt;br /&gt;&lt;br /&gt;I understand that I am partly at fault because I am using an actual, physical DVD, a quite old media, and I should have ripped my DVDs a long time ago and be free of these issues. But I think it is still important to talk about region coding, because:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Most content sold today is still in region-coded DVD format, while it could be region-free.&lt;/li&gt;&lt;li&gt;Recent formats like Blu-ray support region coding as well.&lt;/li&gt;&lt;li&gt;DRM in general is pervasive for video content online (if you except P2P networks), and kind or region-coded through stores like the iTunes Store which require credit cards registered in a certain country.&lt;/li&gt;&lt;/ul&gt;DRM is &lt;a href="http://ebruchez.blogspot.com/2007/12/deutsche-grammophon-mostly-gets-it.html"&gt;going away for music now&lt;/a&gt;, which is a good first step. There is hope that, as broadband and video-enabled devices become even more widespread, DRM on video will vanish on its own as that will be the only option left to the industry in the face of underground P2P filesharing. Unfortunately, in the meanwhile, as has been the case with music, a lot of harm will be done. I am not sure what we can do about it, except raise the awareness of the issue by talking about it.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;PS: In my particular case, there are workarounds, like using &lt;/span&gt;&lt;a style="font-style: italic;" href="http://www.videolan.org/vlc/"&gt;VLC&lt;/a&gt;&lt;span style="font-style: italic;"&gt; to play the DVD (although VLC seems to crash quite often). My previous laptop, bought 4 years ago, was made region-free right away. However on the Mac,  making the drive region-free is not as mainstream a process. I wonder what non-technical users do in this kind of situation? Change the player's zone until it is finally locked in the wrong zone?&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-2625947231893942995?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/2625947231893942995/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=2625947231893942995" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/2625947231893942995?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/2625947231893942995?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/12/i-cant-believe-we-still-have-dvd-region.html" title="I can't believe we still have DVD region coding" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp3.blogger.com/_DSqG0J8ANmg/R3F1VZ2HsLI/AAAAAAAAAF0/6MV5pVgvqSM/s72-c/drm.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0QNQ3w5eCp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-5196122899806848038</id><published>2007-12-06T23:12:00.001-08:00</published><updated>2008-01-04T01:36:32.220-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:36:32.220-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="election" /><category scheme="http://www.blogger.com/atom/ns#" term="philosophy" /><category scheme="http://www.blogger.com/atom/ns#" term="religion" /><category scheme="http://www.blogger.com/atom/ns#" term="mormonism" /><category scheme="http://www.blogger.com/atom/ns#" term="logic" /><category scheme="http://www.blogger.com/atom/ns#" term="freedom" /><title>Mitt Romney and freedom</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_DSqG0J8ANmg/R1288Vi7HmI/AAAAAAAAAFM/rGV-MODyeew/s1600-h/cross.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp3.blogger.com/_DSqG0J8ANmg/R1288Vi7HmI/AAAAAAAAAFM/rGV-MODyeew/s320/cross.png" alt="" id="BLOGGER_PHOTO_ID_5142474094288772706" border="0" /&gt;&lt;/a&gt;Here is what one of the presidential candidates, Mitt Romney, recently &lt;a href="http://www.cnn.com/2007/POLITICS/12/06/romney.speech/index.html"&gt;professed&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"Freedom requires religion, just as religion requires freedom. Freedom opens the windows of the soul so that man can discover his most profound beliefs and commune with God. Freedom and religion endure together, or perish alone."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This has to be one of the most nonsensical statements I have read in a while, and I can only qualify it, nicely, as blabber.&lt;br /&gt;&lt;br /&gt;Freedom has nothing to do with religion. If anything, religion has hindered, and is still hindering, freedom in many parts of the world. America, the land of the free, was &lt;a href="http://skeptically.org/thinkersonreligion/id9.html"&gt;founded by atheists&lt;/a&gt; (at most Deists) and free-thinkers,  contrary to what too many in America would like you to believe.&lt;br /&gt;&lt;br /&gt;More generally, ethics do not correlate with religion: many religious people behave in a non-ethical way, and many non-religious people behave in an ethical way. There is lot of wishful thinking, but no evidence that I know of showing otherwise.&lt;br /&gt;&lt;br /&gt;It is clear that Romney doesn't like to be asked about his religion (&lt;a href="http://en.wikipedia.org/wiki/Mormonism"&gt;Mormonism&lt;/a&gt;), which is understandable, but talking nonsense is probably not a good solution to that particular problem: it just makes him sound dumb (which, after all, is fine in my book).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-5196122899806848038?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/5196122899806848038/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=5196122899806848038" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/5196122899806848038?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/5196122899806848038?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/12/mitt-romney-and-freedom.html" title="Mitt Romney and freedom" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp3.blogger.com/_DSqG0J8ANmg/R1288Vi7HmI/AAAAAAAAAFM/rGV-MODyeew/s72-c/cross.png" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;D0cFRH0ycCp7ImA9WB9VGU8.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-9197193094075993479</id><published>2007-12-05T22:49:00.000-08:00</published><updated>2007-12-05T23:10:15.398-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2007-12-05T23:10:15.398-08:00</app:edited><title>Deutsche Grammophon mostly gets it</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_DSqG0J8ANmg/R1ecoFi7HlI/AAAAAAAAAFE/sqCuXahZZaM/s1600-h/dg-web-shop.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_DSqG0J8ANmg/R1ecoFi7HlI/AAAAAAAAAFE/sqCuXahZZaM/s320/dg-web-shop.png" alt="" id="BLOGGER_PHOTO_ID_5140749712164068946" border="0" /&gt;&lt;/a&gt;2007 will be remembered as the year the recording industry moved away from &lt;a href="http://www.fsf.org/campaigns/drm.html"&gt;Digital Restrictions Management (DRM)&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The latest positive development in this saga is that a few days ago Deutsche Grammophon (which belongs to Universal / Vivendi), mainly known by classical music and opera afficionados, opened &lt;a href="http://www.deutschegrammophon.com/"&gt;its online music store&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The stores offers the entire DG music catalog in mp3 format encoded at 320 kbps. The web site is reasonably well done for a version 1.0. Search appears to function, album tracks list properly, and the previews are of good quality. My main disappointment is that there is no option to download music in a lossless format such as &lt;a href="http://flac.sourceforge.net/"&gt;FLAC&lt;/a&gt;, but maybe I am expecting too much.&lt;br /&gt;&lt;br /&gt;As the web site says, "Over 600 out-of-print CDs are made available again as downloads in this shop." Finally, somebody realizes that in the internet age, nothing should ever get "out-of-print" again.&lt;br /&gt;&lt;br /&gt;I wish DG much success with this web site, even though it may be too late for the music industry to be rescued, as &lt;a href="http://www.techcrunch.com/2007/10/08/yahoos-ian-rogers-to-music-industry-inconvenience-doesnt-scale/"&gt;"For the last eight years the industry has been doing nothing more than rearranging the deck chairs on its own musical Titanic."&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-9197193094075993479?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/9197193094075993479/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=9197193094075993479" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/9197193094075993479?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/9197193094075993479?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/12/deutsche-grammophon-mostly-gets-it.html" title="Deutsche Grammophon mostly gets it" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_DSqG0J8ANmg/R1ecoFi7HlI/AAAAAAAAAFE/sqCuXahZZaM/s72-c/dg-web-shop.png" height="72" width="72" /><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;A0MFSX88eyp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-338039623826141987</id><published>2007-12-05T08:13:00.000-08:00</published><updated>2008-01-04T01:36:58.173-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:36:58.173-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="suisse" /><category scheme="http://www.blogger.com/atom/ns#" term="switzerland" /><category scheme="http://www.blogger.com/atom/ns#" term="dmca" /><category scheme="http://www.blogger.com/atom/ns#" term="p2p" /><category scheme="http://www.blogger.com/atom/ns#" term="music" /><category scheme="http://www.blogger.com/atom/ns#" term="french" /><category scheme="http://www.blogger.com/atom/ns#" term="freedom" /><title>Contre le DMCA Suisse</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_DSqG0J8ANmg/R1eZkVi7HjI/AAAAAAAAAE0/2w8MBMYYA0E/s1600-h/swiss-flag.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp1.blogger.com/_DSqG0J8ANmg/R1eZkVi7HjI/AAAAAAAAAE0/2w8MBMYYA0E/s320/swiss-flag.png" alt="" id="BLOGGER_PHOTO_ID_5140746349204676146" border="0" /&gt;&lt;/a&gt;On pourrait croire qu'en Suisse, pays champion de la &lt;a href="http://fr.wikipedia.org/wiki/D%C3%A9mocratie_directe"&gt;démocracie directe&lt;/a&gt;, on ne puisse pas facilement passer une loi sans même que les citoyens en aient vent et sans que la presse n'en mentionne quoi que ce soit.&lt;br /&gt;&lt;br /&gt;Pourtant, c'est bien ce qui semble se passer avec le "DMCA" suisse. La &lt;a href="http://www.suisa.ch/home_f.htm"&gt;SUISA&lt;/a&gt; avait déjà réussi récemment à voler au consommateur CHF 80 par lecteur mp3. Ceci était présenté comme la seule façon de garder le droit à la copie privée. Une loi enrageante, mais qui au moins n'entachait pas la liberté des consommateurs.&lt;br /&gt;&lt;br /&gt;Maintenant, une nouvelle loi proposée est bien pire: elle semble même aller plus loin que le DMCA américain par certains aspects. Voir &lt;a href="http://www.no-dmca.ch/index.fr.html"&gt;cet article&lt;/a&gt; pour plus de détails: c'est une vraie folie qu'on essaie d'imposer à des citoyens suisses complètement malinformés ou désinformés. Lisez également ce &lt;a href="http://www.boingboing.net/2007/12/02/swiss-dmca-petition.html"&gt;billet web écrit par Cory Doctorow&lt;/a&gt;. Il appelle cette loi "brutale", et il a raison.&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on down" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Le gouvernement suisse apparait aussi corrompu (au sens "corruption du processus politique" &lt;a href="http://www.lessig.org/blog/2007/06/required_reading_the_next_10_y.html"&gt;proposé par Larry Lessig&lt;/a&gt;) que celui des Etats-Unis ou de la France. Ce n'est guère une vraie surprise, mais j'en reste déçu. Quant à la presse, en particulier en Suisse Romande, on ne peut que la blâmer pour sa médiocrité.&lt;br /&gt;&lt;br /&gt;En attendant, faites passer le mot et signez le référendum.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-338039623826141987?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/338039623826141987/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=338039623826141987" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/338039623826141987?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/338039623826141987?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/12/contre-le-dmca-suisse.html" title="Contre le DMCA Suisse" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_DSqG0J8ANmg/R1eZkVi7HjI/AAAAAAAAAE0/2w8MBMYYA0E/s72-c/swiss-flag.png" height="72" width="72" /><thr:total>5</thr:total></entry><entry gd:etag="W/&quot;A0MHRXc4cSp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-6101433761096135340</id><published>2007-11-28T11:48:00.000-08:00</published><updated>2008-01-04T01:37:14.939-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:37:14.939-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bug" /><category scheme="http://www.blogger.com/atom/ns#" term="leopard" /><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>Leopard Spaces eats windows</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_DSqG0J8ANmg/R04S8Se7MpI/AAAAAAAAAEs/yNfXU5ulmLA/s1600-h/spaces.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp0.blogger.com/_DSqG0J8ANmg/R04S8Se7MpI/AAAAAAAAAEs/yNfXU5ulmLA/s320/spaces.jpg" alt="" id="BLOGGER_PHOTO_ID_5138065051839312530" border="0" /&gt;&lt;/a&gt;And by that, I don't mean that it beats the crap out of Microsoft Windows, I really mean that Mac OS X application windows sometimes disappear when you use Spaces. You can't cmd-tab to them anymore or otherwise see them again. They are not just minimized or hidden, they are in no man's land.&lt;br /&gt;&lt;br /&gt;I hit this over the last few days, and I am not the only one. See this discussion: &lt;a href="http://discussions.apple.com/thread.jspa?threadID=1226451&amp;amp;tstart=0"&gt;Disappearing windows in spaces&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The workaround of disabling Spaces and then re-enabling works for me, but it's quite an annoyance to have to resort to that as you need to move windows to their proper space again for applications which aren't assigned to a particular space.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-6101433761096135340?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/6101433761096135340/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=6101433761096135340" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/6101433761096135340?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/6101433761096135340?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/11/leopard-spaces-eats-windows.html" title="Leopard Spaces eats windows" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp0.blogger.com/_DSqG0J8ANmg/R04S8Se7MpI/AAAAAAAAAEs/yNfXU5ulmLA/s72-c/spaces.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0MBQXw4fyp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-7243853297456047231</id><published>2007-11-24T13:29:00.000-08:00</published><updated>2008-01-04T01:37:30.237-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:37:30.237-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="kindle" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><category scheme="http://www.blogger.com/atom/ns#" term="freedom" /><title>The future of reading</title><content type="html">Following-up on the release of the &lt;a href="http://www.amazon.com/Kindle-Amazons-Wireless-Reading-Device/dp/B000FI73MA"&gt;Amazon Kindle&lt;/a&gt;, you may want to read Mark Pilgrim's &lt;a href="http://diveintomark.org/archives/2007/11/19/the-future-of-reading"&gt;The Future of Reading (A Play in Six Acts)&lt;/a&gt;. Sometimes, you just need to be reminded of certain ideals and go past the lure of the gadgetry. Thank you, &lt;a href="http://en.wikipedia.org/wiki/George_orwell"&gt;George Orwell&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Richard_stallman"&gt;Richard Stallman&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-7243853297456047231?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/7243853297456047231/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=7243853297456047231" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/7243853297456047231?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/7243853297456047231?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/11/future-of-reading.html" title="The future of reading" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0MDRnwycCp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-1460393655619892768</id><published>2007-11-19T09:12:00.000-08:00</published><updated>2008-01-04T01:37:57.298-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:37:57.298-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="sony" /><category scheme="http://www.blogger.com/atom/ns#" term="pdf" /><category scheme="http://www.blogger.com/atom/ns#" term="kindle" /><category scheme="http://www.blogger.com/atom/ns#" term="amazon" /><category scheme="http://www.blogger.com/atom/ns#" term="hardware" /><category scheme="http://www.blogger.com/atom/ns#" term="ebooks" /><title>Amazon Kindle: steps forward, steps backward</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_DSqG0J8ANmg/R0KDNie7MoI/AAAAAAAAAEk/kGWMH5XZnPs/s1600-h/kindle.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp1.blogger.com/_DSqG0J8ANmg/R0KDNie7MoI/AAAAAAAAAEk/kGWMH5XZnPs/s320/kindle.jpg" alt="" id="BLOGGER_PHOTO_ID_5134810793773838978" border="0" /&gt;&lt;/a&gt;Today, Amazon officially announced the Kindle eBook reader and associated services. This has already produced a flurry of &lt;a href="http://www.techcrunch.com/2007/11/19/liveblogging-the-amazon-kindle-e-reader-show-with-jeff-bezos/"&gt;blog posts&lt;/a&gt; &lt;a href="http://www.crunchgear.com/2007/11/19/mini-review-of-the-amazon-kindle/"&gt;all over the place&lt;/a&gt;. The device is not yet available, but it already has &lt;a href="http://www.amazon.com/gp/product/B000FI73MA/"&gt;248 customer reviews on Amazon.com&lt;/a&gt; (mostly negative so far but again almost nobody actually got their hands on it).&lt;br /&gt;&lt;br /&gt;So what did Amazon get right?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The Kindle features an "electronic paper" display from &lt;a href="http://www.eink.com/"&gt;E-Ink&lt;/a&gt;, the same company that makes the &lt;a href="http://en.wikipedia.org/wiki/Sony_Reader"&gt;Sony reader&lt;/a&gt; screen. This means crisp black text on almost-white-but-kind-of-gray background, 180 degree viewing angle, and ability to read in broad daylight. You can take this on the beach or on your mountain hike, but you will need a reading light in the dark.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It doesn't require a PC to synchronize. Instead it uses a Sprint EVDO connection and you buy your books directly from the device. There are no fees for the connection, everything is included when you buy the Kindle.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;About 80,000 books and magazines are available for download from Amazon.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Free wireless access to &lt;a href="http://en.wikipedia.org/"&gt;Wikipedia&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Built-in search and dictionary functionality.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;On the negative side:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;As everybody has pointed out, it is a dead-ugly, uncool, device. Compare it with the beautiful second-generation Sony reader. Amazon should really learn from Sony and Apple.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;If you loose or break the Kindle, USD 400 go down the drain. This today buys you two &lt;a href="http://laptop.org/"&gt;OLPC XO-1 laptops&lt;/a&gt;. I thought that the Sony reader, at USD 300, was already too expensive and beyond what I would pay for such a device.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Your only option to get content seems to be through EVDO and Amazon. There is no Wi-Fi or bluetooth transfer. Besides obvious coverage limitations in the US itself, this also means there is no coverage at all outside the US, which alone makes this a poor choice for a device you may want to carry all over the place.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Free Wikipedia is better than nothing, but what about the thousands of free books from the Gutenberg project or Creative Commons books?&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Apparently, you can email Word documents to the Kindle for 10 cents a pop. There is no mention of PDF support, or other open formats so far. But paying for uploading your own documents to your own device sounds quite ridiculous. Even the Sony reader allows you to load PDF and RTF files (although it seems that the result is less than satisfactory for PDF files).&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I think that some form of electronic book reader is bound to succeed, and that soon enough paper books and magazines will be largely a thing of the past.&lt;br /&gt;&lt;span style="display: block;" id="formatbar_Buttons"&gt;&lt;span class="on down" style="display: block;" id="formatbar_CreateLink" title="Link" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 8);ButtonMouseDown(this);"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;However, I doubt that as is, the Amazon solution will be successful. To succeed, you need a cheap, cool device, and a good degree of openness so that a healthy ecosystem develops.&lt;br /&gt;&lt;br /&gt;So far, the electronic book business has followed the same path as the music industry: strong DRM and no sign of openness. We all know the result: after years of painful struggle, DRM for music is being phased out. It seems that instead of learning from this experience, book publishers want to go through the same process instead of embracing the future right away.&lt;br /&gt;&lt;br /&gt;Anyway, you may want to read what's Amazon founder Jeff Bezos's &lt;a href="http://www.techcrunch.com/2007/11/19/qa-with-bezos-about-the-kindle/"&gt;take on the whole thing&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-1460393655619892768?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/1460393655619892768/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=1460393655619892768" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1460393655619892768?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/1460393655619892768?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/11/amazon-kindle-steps-forward-steps.html" title="Amazon Kindle: steps forward, steps backward" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp1.blogger.com/_DSqG0J8ANmg/R0KDNie7MoI/AAAAAAAAAEk/kGWMH5XZnPs/s72-c/kindle.jpg" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0MNQ3Y8fCp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-2959909085534561537</id><published>2007-11-15T19:10:00.000-08:00</published><updated>2008-01-04T01:38:12.874-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:38:12.874-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="finder" /><category scheme="http://www.blogger.com/atom/ns#" term="leopard" /><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><title>Leopard Finder: the new Path Bar</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_DSqG0J8ANmg/Rz0NoSe7MmI/AAAAAAAAAD8/XfzqMvGO5iY/s1600-h/pathbar1.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp3.blogger.com/_DSqG0J8ANmg/Rz0NoSe7MmI/AAAAAAAAAD8/XfzqMvGO5iY/s320/pathbar1.jpg" alt="" id="BLOGGER_PHOTO_ID_5133274136079708770" border="0" /&gt;&lt;/a&gt;Windows Explorer has long had an option to show the path of the current folder in the title bar of the window. This is a very convenient feature which was lacking in the Finder so far.&lt;br /&gt;&lt;br /&gt;Leopard now has something similar. It's called the "Path Bar". I stumbled upon it by chance when doing a search with Spotlight: the result window had this funny path at the bottom. It turns out that you can enable it for other windows by going to the "View" menu and selecting "Show Path Bar".&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp1.blogger.com/_DSqG0J8ANmg/Rz0Nrye7MnI/AAAAAAAAAEE/BAQHW_Osr2A/s1600-h/pathbar2.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; clear: both; cursor: pointer;" src="http://bp1.blogger.com/_DSqG0J8ANmg/Rz0Nrye7MnI/AAAAAAAAAEE/BAQHW_Osr2A/s320/pathbar2.jpg" alt="" id="BLOGGER_PHOTO_ID_5133274196209250930" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Path Bar may even be better than just showing the raw path in the window title: you see icons and can double click on path elements. So yay for a useful improvement in Leopard!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-2959909085534561537?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/2959909085534561537/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=2959909085534561537" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/2959909085534561537?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/2959909085534561537?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/11/leopard-finder-finally-way-to-see.html" title="Leopard Finder: the new Path Bar" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp3.blogger.com/_DSqG0J8ANmg/Rz0NoSe7MmI/AAAAAAAAAD8/XfzqMvGO5iY/s72-c/pathbar1.jpg" height="72" width="72" /><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;A0IERnYycSp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-8870021660444428464</id><published>2007-11-11T12:16:00.000-08:00</published><updated>2008-01-04T01:38:27.899-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:38:27.899-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="bugs" /><category scheme="http://www.blogger.com/atom/ns#" term="leopard" /><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>Is it me, or is Leopard screen sharing fairly lame?</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_DSqG0J8ANmg/RzgHcjviwpI/AAAAAAAAADo/JCm4mWY0oRU/s1600-h/crash.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp2.blogger.com/_DSqG0J8ANmg/RzgHcjviwpI/AAAAAAAAADo/JCm4mWY0oRU/s320/crash.png" alt="" id="BLOGGER_PHOTO_ID_5131859962601063058" border="0" /&gt;&lt;/a&gt;Here are a few of my issues with it:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It crashed at least once.&lt;/li&gt;&lt;li&gt;It feels quite slow, certainly slower than the Windows Remote Desktop, for example. Maybe because it's based on VNC and sending around pixmaps all the time?&lt;/li&gt;&lt;li&gt;The clipboard is not automatically shared. You have to send it around explicitly. This means that you can't just copy and paste a URL around without going to a menu inbetween (or click on an icon).&lt;/li&gt;&lt;li&gt;I restarted my wireless router with a screen sharing session open. The session just hung and was not able to pick up the connection again. I had to restart the screen sharing session.&lt;/li&gt;&lt;li&gt;The "New..." connection menu entry just opens a dialog with a single text field. There is no way to browse from a visible computer on the network. Annoying if you just had to close the connection (see aforementioned problem) and just want to reopen it. You then have to go back to the finder.&lt;/li&gt;&lt;li&gt;If you show the toolbar (with three miserable icons), you have a "Fit screen in window" option, which it turns out is the same a the "Turn Scaling On/Off" menu entry. Mmmh, did anybody at Apple even looked at this app?&lt;/li&gt;&lt;/ul&gt;I wouldn't say Screen Sharing is useless, but this is a version 1.0 and it shows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-8870021660444428464?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/8870021660444428464/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=8870021660444428464" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8870021660444428464?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8870021660444428464?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/11/is-it-me-or-is-leopard-screen-sharing.html" title="Is it me, or is Leopard screen sharing fairly lame?" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp2.blogger.com/_DSqG0J8ANmg/RzgHcjviwpI/AAAAAAAAADo/JCm4mWY0oRU/s72-c/crash.png" height="72" width="72" /><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;A0UFR3YyeCp7ImA9WB9aFE4.&quot;"><id>tag:blogger.com,1999:blog-2849901641571065621.post-8079837722611074529</id><published>2007-11-10T20:25:00.000-08:00</published><updated>2008-01-04T01:33:36.890-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-01-04T01:33:36.890-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="play" /><category scheme="http://www.blogger.com/atom/ns#" term="flac" /><category scheme="http://www.blogger.com/atom/ns#" term="leopard" /><category scheme="http://www.blogger.com/atom/ns#" term="osx" /><title>Leopard doesn't "Play" (and a plea for FLAC)</title><content type="html">&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_DSqG0J8ANmg/RzaFkDviwoI/AAAAAAAAADg/h27VVJR2AaA/s1600-h/play.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://bp2.blogger.com/_DSqG0J8ANmg/RzaFkDviwoI/AAAAAAAAADg/h27VVJR2AaA/s320/play.png" alt="" id="BLOGGER_PHOTO_ID_5131435679961760386" border="0" /&gt;&lt;/a&gt;Since Apple still doesn't think that supporting a &lt;a href="http://flac.sourceforge.net/"&gt;free, fast, unemcumbered, lossless audio codec&lt;/a&gt; is a good idea, I had been using &lt;a href="http://sbooth.org/Play/"&gt;Play&lt;/a&gt; on Tiger. Unfortunately, it is broken on Leopard. Version 0.2 doesn't start anymore at all. The good news is that the author is &lt;a href="http://sbooth.org/forums/viewtopic.php?f=12&amp;amp;t=1776"&gt;working on it&lt;/a&gt;. In fact, the latest builds (using r1057 at the moment) at least start and seem to, well, play, but I don't seem to be able to import anything into the Play library, for example.&lt;br /&gt;&lt;br /&gt;As good as Play will eventually be on Leopard (and it is likely to remain a much more lightweight alternative to iTunes), Apple really needs to support FLAC. Who needs the &lt;a href="http://en.wikipedia.org/wiki/Apple_Lossless"&gt;Apple Lossless&lt;/a&gt; format anyway? So go Apple, put an engineer on it for a few days and support FLAC already.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2849901641571065621-8079837722611074529?l=ebruchez.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://ebruchez.blogspot.com/feeds/8079837722611074529/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=2849901641571065621&amp;postID=8079837722611074529" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8079837722611074529?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/2849901641571065621/posts/default/8079837722611074529?v=2" /><link rel="alternate" type="text/html" href="http://ebruchez.blogspot.com/2007/11/leopard-doesnt-play-and-plea-for-flac.html" title="Leopard doesn't &quot;Play&quot; (and a plea for FLAC)" /><author><name>Erik Bruchez</name><uri>http://www.blogger.com/profile/16139421434415219182</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://bp2.blogger.com/_DSqG0J8ANmg/RzaFkDviwoI/AAAAAAAAADg/h27VVJR2AaA/s72-c/play.png" height="72" width="72" /><thr:total>0</thr:total></entry></feed>

