<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Jean-François Im</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/" />
    <link rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/jeanfrancoisim" />
    <id>tag:jean-francois.im,2008-01-24://1</id>
    <updated>2011-10-19T21:55:47Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.31-en</generator>

<entry>
    <title>Continuations in Scala</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2011/10/continuations-in-scala.html" />
    <id>tag:jean-francois.im,2011://1.67</id>

    <published>2011-10-19T21:16:32Z</published>
    <updated>2011-10-19T21:55:47Z</updated>

    <summary>I&apos;ve been trying to figure out how delimited continuations in Scala work, from a users&apos; perspective, although pretty much all the examples have been written by people who have been working for ages with functional languages. For example, this is...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>I've been trying to figure out how delimited continuations in Scala work, from a users' perspective, although pretty much all the examples have been written by people who have been working for ages with functional languages. For example, this is the description from wikipedia on delimited continuations:</p>

<blockquote><p>In programming languages, a delimited continuation, composable continuation or partial continuation, is a "slice" of a continuation frame that has been reified into a function. Unlike regular continuations, delimited continuations return a value, and thus may be reused and composed.</p></blockquote>

<p>I'm sure it makes sense to someone well versed in functional programming, but to someone coming from a pure, nonfunctional background, it makes no sense at all.</p>]]>
        <![CDATA[<pre><code>shift { k: (Int=&gt;Int) =&gt;
  k(7)
}</code></pre>

<p>This is the archetypical continuation example; it simply returns 7. So far so good, right?</p>

<pre><code>reset {
  shift { k: (Int=&gt;Int) =&gt;
    k(7)
  } + 1
} * 2</code></pre>

<p>This second example returns 16. It still makes sense; (7 + 1) * 2 does indeed equal 16.</p>

<pre><code>reset {
  shift { k: (Int=&gt;Int) =&gt;
    k(k(k(7)))
  } + 1
} * 2</code></pre>

<p>Now this one is a bit funkier, it returns 20. The way to look at it is that you get (7 + 1 + 1 + 1) * 2, which does equal 20. So that would mean that for each "invocation" of k, it does add a "+1" to the equation, which would be the code in the reset block.</p>

<pre><code>def foo() = {
  1 + shift(k =&gt; k(k(k(7))))
}
def bar() = {
  foo() * 2
}
def baz() = {
  reset(bar())
}
baz()</code></pre>

<p>Lastly, we get this one, which is equal to 70. If we look at it, we can't simply do (7 + 1 + 1 + 1) * 2, it's obviously not equal to 70. So what's happening here?</p>

<p>It turns out that to understand continuations, you have to flip the computation inside out; the code that gets executed is the shift block, and the definition of "k" is the code in the reset block.</p>

<p>This would mean that the code is equivalent to</p>

<pre><code>def k(i:Int):Int = {
  (i + 1) * 2
}
k(k(k(7)))</code></pre>

<p>I'm still trying to wrap my head at this point around this one though:</p>

<pre><code>type Monadic[+U, CC[_]] = {
  def flatMap[V](f: U =&gt; CC[V]): CC[V]
}

class Reflective[+A, C[_]](xs: Monadic[A,C]) {
  def reflect[B](): A @cps[C[B], C[B]] = {
    shift { k:(A =&gt; C[B]) =&gt;
      xs.flatMap(k)
    }
  }
}

reset {
  val left = List(&quot;x&quot;,&quot;y&quot;,&quot;z&quot;)
  val right = List(4,5,6)
  
  List(left.reflect[Any] -&gt; right.reflect[Any])
}</code></pre>

<p>This one should return "List[(String, Int)] = List((x,4), (x,5), (x,6), (y,4), (y,5), (y,6), (z,4), (z,5), (z,6)," by the way. Any clues?</p>]]>
    </content>
</entry>

<entry>
    <title>No Really, How Much Ice Do You Need For Your Drinks?</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2011/07/no-really-how-much-ice-do-you.html" />
    <id>tag:jean-francois.im,2011://1.66</id>

    <published>2011-07-05T03:09:36Z</published>
    <updated>2011-07-05T04:36:50Z</updated>

    <summary>Dot.Physics on Wired recently ran a blog post about How Much Ice Do You Need For Your Drinks? which attempts to determine the amount of ice needed to cool n beers. Unfortunately for Rhett Allain, he might have had a...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>Dot.Physics on Wired recently ran a blog post about <a href="http://www.wired.com/wiredscience/2011/07/how-much-ice-do-you-need-for-your-drinks/">How Much Ice Do You Need For Your Drinks?</a> which attempts to determine the amount of ice needed to cool <i>n</i> beers. Unfortunately for Rhett Allain, he might have had a bit too many beers as his conclusion is incorrect; the first hint at what's going wrong lies in his statement that "If you proceed with this equation, you will find that the final drink temperature will be colder than the initial ice (for significantly large amounts of starting ice)."</p>]]>
        <![CDATA[<p>We'll reuse some of his assumptions, which are:</p>


<ol>
<li>There are <i>n</i> drinks at 22°C, which consist of 355mL of Coors Light — water, essentially — and a 15g can of aluminum</li>
<li>The specific heat of water is 4.18 J/(g °C)</li>
<li>The specific heat of aluminum is 0.904 J/(g °C)</li>
<li>The latent heat of fusion for water is 334 J/g</li>
</ol>



<p>We will also add some assumptions:</p>


<ol>
<li>The cooler prevents all possible heat exchange with the outside world</li>
<li>The ice starts at -10°C, not 0°C</li>
<li>The specific heat of ice is 2.11 J/(g °C)</li>
<li>The beer has a target temperature of 7°C, as according to <a href="http://en.wikipedia.org/wiki/Beer#Temperature">Wikipedia</a> a light beer should be served "well chilled (7 °C/45 °F)"</li>
<li>The cooler contains a negligible amount of air</li>
</ol>



<p>As for our variables, we only have m<sub>ice</sub>, the mass of ice required to cool our system to our target temperature. As Rhett Alain put it, ∆E<sub>drink</sub> + ∆E<sub>ice</sub> = 0, which means that only the drink and ice exchange energy, so all the thermal energy flows from the drink to the ice; in other terms, the drink gets cooler and the ice gets warmer (and eventually melts).</p>

<p>So let's calculate ∆E<sub>drink</sub>, the amount of energy that exits from the drink towards the ice. As we know, our target temperature is 7°C, so ∆T<sub>drink</sub>=7°C-22°C. This means that the amount of energy for one drink is as follows, given that ∆E=mC∆T:</p>

<p>∆E<sub>drink</sub>=m<sub>beer</sub> * C<sub>beer</sub> * (7°C - 22°C) + m<sub>can</sub> * C<sub>can</sub> * (7°C - 22°C) = -21210.2 J</p>

<p>In this case, ∆E<sub>drink</sub> is negative, meaning that the drink's energy level is becoming lower (ie. colder), which means that our ice will absorb the same amount of energy to cool our drink. Now let's calculate ∆E<sub>ice</sub>, which is the amount of energy the ice takes from the drink. However, this one is a bit different, as there are three steps in this case; first, the ice will go from -10°C to 0°C, melt, then go from 0°C to 7°C as a liquid.</p>

<p>∆E<sub>ice</sub> = m<sub>ice</sub> * C<sub>ice</sub> * (0°C - -10°C) + m<sub>ice</sub> * ΔH°f + m<sub>water</sub> * C<sub>water</sub> * (7°C - 0°C)</p>

<p>For one gram of ice, which is also one gram of water, we obtain</p>

<p>∆E<sub>ice</sub>/g = C<sub>ice</sub> * (0°C - -10°C) + ΔH°f + C<sub>water</sub> * (7°C - 0°C) = 384.36J/g</p>

<p>As we've said before, ∆E<sub>drink</sub> + ∆E<sub>ice</sub> = 0, meaning that all the energy transferring from the drink goes into the ice. We can then find m<sub>ice</sub> that solves this equation:</p>

<p>∆E<sub>drink</sub> + ∆E<sub>ice</sub>/g * m<sub>ice</sub> = 0</p>

<p>which gives us m<sub>ice</sub>=55.183g. This means that, given absolutely no inefficiencies, we need at least 55 grams of ice per can and wait until the cooler reaches equilibrium, meaning that the cans of beer are floating in cold water at 7°C. This will, obviously, take a while so packing a lot more than 55 grams of ice does make sense in this case, especially considering the fact that the cooler will leak some of the cold air inside as well as exchange some of the heat with the outside environment.</p>

<p>Alternatively, as the heat exchange between ice cubes and the drink will be sub-optimal due to the low contact area between the ice and the drinks, the best way would be to just put the cans of beer in cold water and then add a bit more than 55 grams of ice per can of beer. To take Rhett Allain's 10lb bag of ice, and assuming we need roughly 100 grams of ice per can and that the water is at roughly 7°C, we could cool 45 cans of beer with his bag of ice. Have fun!</p>]]>
    </content>
</entry>

<entry>
    <title>Automatically Adding SDKs to the PATH Environment Variable</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2011/07/automatically-adding-sdks-to-t.html" />
    <id>tag:jean-francois.im,2011://1.64</id>

    <published>2011-07-03T20:33:12Z</published>
    <updated>2011-07-03T20:56:40Z</updated>

    <summary>When developing on several platforms, environments and languages, one eventually ends having several SDKs that need to be added to the PATH environment variable. An easy way of doing so is to scan a certain directory when starting the shell,...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Howto" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>When developing on several platforms, environments and languages, one eventually ends having several <span class="caps">SDK</span>s that need to be added to the <code>PATH</code> environment variable. An easy way of doing so is to scan a certain directory when starting the shell, so that all subfolders containing a <code>bin</code> directory are automatically added to the <code>PATH</code>. This is what I have in my bash profile:</p>

<pre><code># Where SDKs are installed
SDKS_ROOT=&quot;$HOME/SDKs&quot;</code></pre>

<pre><code># Add any SDKs present to the path
if [ -d $SDKS_ROOT ]; then
	for SDKNAME in `ls $SDKS_ROOT/`
	do
		SDKPATH=&quot;$SDKS_ROOT/$SDKNAME&quot;
		if [ -d &quot;$SDKPATH&quot; ]; then
			export PATH=$PATH:$SDKPATH
			if [ -d $SDKPATH/bin ]; then
				export PATH=$PATH:$SDKPATH/bin
			fi
			if [ -d $SDKPATH/tools ]; then
				export PATH=$PATH:$SDKPATH/tools
			fi
			if [ -d $SDKPATH/platform-tools ]; then
				export PATH=$PATH:$SDKPATH/platform-tools
			fi
			if [ -d $SDKPATH/tools/bin ]; then
				export PATH=$PATH:$SDKPATH/tools/bin
			fi
		fi
	done
fi</code></pre>

<p>This means that upon starting the shell, all subfolders of <code>~/SDKs</code> are treated as an individual <span class="caps">SDK.</span> Installing an <span class="caps">SDK </span>is just a matter of adding a folder there, so that whenever the <a href="http://www.playframework.org/">play framework,</a> <a href="http://www.scala-lang.org/">scala,</a> <a href="http://code.google.com/appengine/">app engine</a> or some other relatively fast moving target releases a new version, upgrading is just a matter of deleting the old <span class="caps">SDK </span>and dropping in the new version. Cool, eh?</p>]]>
        
    </content>
</entry>

<entry>
    <title>5$ LED Lightbulbs in 2014?</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2011/06/5-led-lightbulbs-in-2014.html" />
    <id>tag:jean-francois.im,2011://1.63</id>

    <published>2011-06-02T19:27:36Z</published>
    <updated>2011-06-02T19:27:40Z</updated>

    <summary>IEEE Spectrum wrote that Silicon Is Key to Quest for $5 LED Lightbulb, in which they explain that by changing the substrate on which GaN LEDs are made to a much cheaper one, they are going to be able to...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="led" label="LED" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p><span class="caps">IEEE</span> Spectrum wrote that <a href="http://spectrum.ieee.org/semiconductors/optoelectronics/silicon-is-key-to-quest-for-5-led-lightbulb/?utm_source=techalert&amp;utm_medium=email&amp;utm_campaign=060211">Silicon Is Key to Quest for $5 <span class="caps">LED</span> Lightbulb,</a> in which they explain that by changing the substrate on which GaN <span class="caps">LED</span>s are made to a much cheaper one, they are going to be able to slash costs.</p>

<blockquote><p>He [Bridgelux's VP of marketing] claims that this outsourcing will cut chip-manufacturing costs by 75 percent and, combined with steady improvements in manufacturing, lead to a $5 <span class="caps">LED </span>bulb as soon as 2014.</p></blockquote>

<p>Considering the only thing holding back <span class="caps">LED </span>lighting currently is the prohibitive cost compared to <span class="caps">CCFL</span>s --- the article mentions a price of over 40$ per 40W lightbulb --- and that <span class="caps">LED </span>lighting is superior in many aspects to <span class="caps">CCFL</span>s, I am looking forwards to such price slashes.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Adding the Mercurial Revision to a Maven Project</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2011/05/adding-the-mercurial-revision.html" />
    <id>tag:jean-francois.im,2011://1.62</id>

    <published>2011-05-09T04:04:44Z</published>
    <updated>2011-05-12T23:25:48Z</updated>

    <summary>In this world, nothing is certain but death, taxes and bug reports from users. While we may not be able to do much about the first two, to address the third one effectively more information is required. The most important...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Howto" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="java" label="Java" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="maven" label="maven" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mercurial" label="mercurial" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>In this world, nothing is certain but death, taxes and bug reports from users. While we may not be able to do much about the first two, to address the third one effectively more information is required. The most important information you can have is, of course, the version of the code they are running. However, if your users are running the latest bleeding edge version of the code, odds are that the version number that they will have is "1.0-SNAPSHOT". That's not terribly helpful, so here's how to add the Mercurial revision --- I assume the same works for git and <span class="caps">SVN </span>--- to your project and read it from your code.</p>]]>
        <![CDATA[<p>It turns out that there is a very helpful maven plugin called <a href="http://mojo.codehaus.org/buildnumber-maven-plugin/">buildnumber-maven-plugin</a> that adds the current revision number as a build property called changeSet. Using that, we can embed the version number in the <span class="caps">JAR </span>manifest by using the maven-jar-plugin, like below:</p>

<pre><code>&lt;plugin&gt;
  &lt;artifactId&gt;maven-jar-plugin&lt;/artifactId&gt;
  &lt;configuration&gt;
    &lt;archive&gt;
      &lt;manifestEntries&gt;
        &lt;Implementation-Title&gt;${pom.artifactId} [${pom.name}]&lt;/Implementation-Title&gt;
        &lt;Implementation-Version&gt;${pom.version}-${changeSet}&lt;/Implementation-Version&gt;
        &lt;Implementation-Vendor-Id&gt;${pom.groupId}&lt;/Implementation-Vendor-Id&gt;
        &lt;Implementation-Vendor&gt;${pom.organization.name}&lt;/Implementation-Vendor&gt;
      &lt;/manifestEntries&gt;
    &lt;/archive&gt;
  &lt;/configuration&gt;
&lt;/plugin&gt;
&lt;plugin&gt;
  &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
  &lt;artifactId&gt;buildnumber-maven-plugin&lt;/artifactId&gt;
  &lt;executions&gt;
    &lt;execution&gt;
      &lt;phase&gt;validate&lt;/phase&gt;
      &lt;goals&gt;
        &lt;goal&gt;hgchangeset&lt;/goal&gt;
      &lt;/goals&gt;
    &lt;/execution&gt;
  &lt;/executions&gt;
&lt;/plugin&gt;</code></pre>

<p>This will put the build number in the <code>Implementation-Vendor-Id</code> <span class="caps">JAR </span>manifest's main attribute, which can then be retrieved by <code>getClass().getPackage().getImplementationVersion()</code> in whatever code you're running.</p>

<p>However, as most applications have multiple modules, it's also helpful to know the version of the other included modules. By asking the class loader to load the <span class="caps">JAR </span>manifests and getting the property, we can also show what other module versions are. (You'll need to change the code below</p>

<pre><code>StringBuilder builder = <span class="category1">new</span> StringBuilder();

<span class="category1">try</span> {
 	<span class="category2">Enumeration</span>&lt;<span class="category2">URL</span>&gt; manifests = getClass().getClassLoader().getResources("<span class="quote">META-INF/MANIFEST.MF</span>");
 	<span class="category1">while</span> (manifests.hasMoreElements()) {
  		<span class="category2">URL</span> url = manifests.nextElement();
  		Manifest manifest = <span class="category1">new</span> Manifest(url.openStream());
  		Attributes attributes = manifest.getMainAttributes();
  		builder.append(attributes.getValue("<span class="quote">Implementation-Title</span>")).append("<span class="quote"> </span>").append(attributes.getValue("<span class="quote">Implementation-Version</span>")).append("<span class="quote">\n</span>");
  	}
} <span class="category1">catch</span> (<span class="category2">IOException</span> e) {
 	logger.warn("<span class="quote">Caught exception while reading manifests</span>", e);
}

System.out.println(builder.toString());</code></pre>

<p>For example, this is what I get when running the code above:</p>

<pre><code>chronolog-log-agent-java [ChronoLog Java Logging Agent] 1.0-SNAPSHOT-47e848d08e49
chronolog-common [ChronoLog Common] 1.0-SNAPSHOT-47e848d08e49
chronolog-logging [Chronolog logging] 1.0-SNAPSHOT-47e848d08e49
chronolog-data-model [ChronoLog Data Model] 1.0-SNAPSHOT-47e848d08e49
chronolog-nativelib-win-javabridge [chronolog-nativelib-win-javabridge] 1.0-SNAPSHOT-47e848d08e49
chronolog-nativelib-win [ChronoLog Native Lib (Windows)] 1.0-SNAPSHOT-5abac83987ad+</code></pre>

<p>This way, you know exactly what code your users were running and if the bug reports received were for things that were already fixed. For example, it is part of the code that we use in <a href="http://www.productivity3.com/">ChronoLog</a> for the support information.</p>]]>
    </content>
</entry>

<entry>
    <title>US Stock Dividends and Canadian Taxes</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2011/03/us-stock-dividends-and-canadia.html" />
    <id>tag:jean-francois.im,2011://1.61</id>

    <published>2011-03-24T10:32:30Z</published>
    <updated>2011-03-24T11:08:34Z</updated>

    <summary>I was about to file my taxes for 2010 when I noticed in my mailbox that I received form 1042-S (Foreign Person&apos;s U.S. Source Income Subject to Withholding) for some dividends paid by a US corporation. As I wasted a...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>I was about to file my taxes for 2010 when I noticed in my mailbox that I received form 1042-S (Foreign Person's <span class="caps">U.S.</span> Source Income Subject to Withholding) for some dividends paid by a US corporation. As I wasted a couple of hours trying to figure if I needed to file in the US or not, I figured I'd save some time for other people by writing about this.</p>]]>
        <![CDATA[<p><b><span class="caps">WARNING</span>! I am not a financial consultant and this should not be construed as advice. Don't blame me if the <span class="caps">CRA </span>or the <span class="caps">IRS </span>send you nasty letters and threaten to seize your house, car, dog, cat and wife. <em>Do</em> check all appropriate tax-related information for both the US and Canadian sides of the border.</b></p>

<p>Assuming you only have US stock dividends, the form 1042-S that you received should indicate 15.00 (15%) in box 5 (tax rate), assuming that you filed form W8-BEN with your stock broker prior to dividends being paid out. If you have no other US-related income than stock dividends and withholding has been claimed at 15% due to the treaty, you do not need to file US taxes as none of the conditions in the "Who Must File" section of the instructions for form 1040NR apply.</p>

<p>If your form 1042-S does not indicate 15% and the form only contains dividends, you need to file a US tax return by filing form 1040NR (not 1040NR-EZ) by following the instructions for form 1040NR. Of particular note is the section "Simplified Procedure for Claiming Certain Refunds."</p>

<p>Now, when filing your Canadian taxes, you will need to file form <span class="caps">T2209 </span>and indicate the amount of tax that was paid to the US government. If withholding was appropriately done, add the form 1042-S to your Canadian tax file, otherwise you will probably need to add a copy of your form 1040NR as well to indicate the amount of taxes that were paid to the US government as "Any amount of tax you paid to a foreign government in excess of the amount you had to pay according to a tax treaty is considered a voluntary contribution and does not qualify as foreign taxes paid." You will also need to <a href="http://www.cra-arc.gc.ca/tx/ndvdls/tpcs/ncm-tx/rtrn/cmpltng/rprtng-ncm/lns101-170/121/frgn-eng.html">report the dividends as income on line 121.</a></p>

<p>Of course, you should double check all of the above information with the appropriate sections of both the Canadian and US tax codes and I hope that this has been helpful.</p>]]>
    </content>
</entry>

<entry>
    <title>Nuclear Plume Path: Coloring and Graphical Integrity</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2011/03/nuclear-plume-path-coloring-and-graphical-integrity.html" />
    <id>tag:jean-francois.im,2011://1.60</id>

    <published>2011-03-17T21:00:02Z</published>
    <updated>2011-03-17T21:53:23Z</updated>

    <summary>The New York Times has an interesting visualization that shows a possible path for the radioactive plume emanating from the Fukushima Daiichi. Unfortunately, there are a couple of data visualization errors that make the chart seem worse than it seems....</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>The New York Times has an interesting visualization that shows <a href="http://www.nytimes.com/interactive/2011/03/16/science/plume-graphic.html?ref=science">a possible path for the radioactive plume emanating from the Fukushima Daiichi.</a> Unfortunately, there are a couple of data visualization errors that make the chart seem worse than it seems.</p>

<p><a href="/assets_c/2011/03/nyt-datavis-77.html" onclick="window.open('/assets_c/2011/03/nyt-datavis-77.html','popup','width=957,height=631,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="/assets_c/2011/03/nyt-datavis-thumb-600x395-77.png" width="600" height="395" alt="nyt-datavis.png" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>]]>
        <![CDATA[<p>The color key in the <span class="caps">NYT'</span>s chart has several errors that can induce the reader to misinterpret all of the data presented. The first glaring error is the usage of a rainbowish color map (see <a href="http://doi.ieeecomputersociety.org/10.1109/MCG.2007.46">Rainbow Color Map (Still) Considered Harmful</a> ) with both ends of the color key having a similar color. One of the problems of rainbow color maps that is present in this chart is that it is not intuitively possible to rank the colors in an appropriate order. For example, without looking at the legend, is pink higher or lower than purple?</p>

<p>Another problem is that, of the seven colors presented in the color key, only four of them are present; the three highest values never actually appear on the map. If one were to recolor their map, it would look like the following picture.</p>

<p><a href="/assets_c/2011/03/nyt-datavis-recolor-log-80.html" onclick="window.open('/assets_c/2011/03/nyt-datavis-recolor-log-80.html','popup','width=957,height=631,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="/assets_c/2011/03/nyt-datavis-recolor-log-thumb-600x395-80.png" width="600" height="395" alt="nyt-datavis-recolor-log.png" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>

<p>Already, this gives a much better idea of what is happening; the cloud is much denser over the ocean than over California. However, the color key has another flaw that can induce in error; it uses a logarithmic scale. In this case, there is a large variability in the range of the data, so the logarithmic scale makes some sense, although it makes things look much worse on the coast of California than it should. Coloring the cloud using linear colors looks like this.</p>

<p><a href="/assets_c/2011/03/nyt-datavis-recolor-83.html" onclick="window.open('/assets_c/2011/03/nyt-datavis-recolor-83.html','popup','width=957,height=631,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="/assets_c/2011/03/nyt-datavis-recolor-thumb-600x395-83.png" width="600" height="395" alt="nyt-datavis-recolor.png" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>

<p>By changing the color key, we can have the same exact data interpreted in wildly different ways, with some highlighting the relatively higher amount of radiation above the ocean and some making things on the coast look much worse. It all boils down to one thing; which one represents reality the best?</p>]]>
    </content>
</entry>

<entry>
    <title>Deactivated my Facebook Account</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2010/09/deactivated-my-facebook-accoun.html" />
    <id>tag:jean-francois.im,2010://1.59</id>

    <published>2010-10-01T00:50:15Z</published>
    <updated>2010-10-01T00:52:10Z</updated>

    <summary>We&apos;ll see how long this lasts....</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>We'll see how long this lasts.</p>

<p><img alt="fessebouc.png" src="http://jean-francois.im/2010/09/30/fessebouc.png" width="948" height="118" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></p>]]>
        
    </content>
</entry>

<entry>
    <title>The Uncontrolled US Debt</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2010/04/the-uncontrolled-us-debt.html" />
    <id>tag:jean-francois.im,2010://1.58</id>

    <published>2010-04-08T00:17:31Z</published>
    <updated>2010-04-08T02:05:48Z</updated>

    <summary><![CDATA[Over the last decade, the US debt has soared to levels that have not been seen for over 50 years. While this phenomenon is not constrained to the US &mdash; John Lipsky of the IMF said that they expect that...]]></summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Economy" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>Over the last decade, the US debt has soared to levels that have not been seen for over 50 years. While this phenomenon is not constrained to the US &mdash; John Lipsky of the <span class="caps">IMF </span>said that they <a href="http://www.imf.org/external/np/speeches/2010/032110.htm">expect that all G7 countries except Canada and Germany will have debt-to-GDP ratios close to or exceeding 100 percent by 2014</a> &mdash; it is still preoccupying to see our neighbors to the South get into debt so quickly.</p>]]>
        <![CDATA[<p>While the US debt fell down during the Clinton administration between 1993 and 2001 &mdash; although most of those years were fueled by the tech boom &mdash; it soared up during the Bush and Obama administrations to levels approaching the years following World War <span class="caps">II.</span> There are multiple reasons for such an increase, such as the war in Iraq, the post-depression bailouts and stimulus packages as well as the new health care reforms announced by Barack Obama.</p>

<p><img alt="us-debt-to-gdp-ratio.png" src="http://jean-francois.im/2010/04/07/us-debt-to-gdp-ratio.png" width="551" height="346" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></p>

<p>While Barack Obama's health care reforms have promised to extend health care coverage to most Americans, they do come at a hefty cost; the Congressional Budget Office (CBO), a non-partisan agency, estimates that they will cost taxpayers $940 billion over the next decade. Considering the US already <a href="http://www.globalhealthfacts.org/topic.jsp?i=66">spends more per capita in health expenditures than any other country,</a> it seems quite unwise to increase spending in that area without addressing the underlying causes of the health costs. As the Economist put it: <a href="http://www.economist.com/world/united-states/displaystory.cfm?story_id=15769767">if coverage is the new law’s strong point, cost control is its weakness.</a></p>

<p>As it stands currently, the US debt situation looks quite bleak when compared to other countries. Among G-20 countries, only Japan and Italy fared worse debt-wise than the US according to <a href="http://www.imf.org/external/pubs/ft/spn/2009/spn0925.pdf">data published by the <span class="caps">IMF.</span></a></p>

<p><img alt="debt-to-gdp-ratio.png" src="http://jean-francois.im/2010/04/07/debt-to-gdp-ratio.png" width="537" height="404" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></p>

<p>Ben Bernanke, the Chairman of the Federal Reserve, <a href="http://online.wsj.com/article/SB10001424052702303720604575169970248763974.html?mod=rss_Today's_Most_Popular">claimed that huge <span class="caps">U.S. </span>budget deficits threaten the nation's long-term economic health and should be addressed soon.</a> He is right, such action should be taken as soon as possible by the Obama administration. After all, this is what the Obama administration promised; to hope, act and change.</p>]]>
    </content>
</entry>

<entry>
    <title>Launching a Child JVM Using Ant</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2010/03/launching-a-child-jvm-using-an.html" />
    <id>tag:jean-francois.im,2010://1.57</id>

    <published>2010-03-28T09:51:59Z</published>
    <updated>2010-03-28T10:07:18Z</updated>

    <summary>For one of the projects I am working on, I needed to interact with some native code via JNI which has a strong probability of crashing. As a native code crash causes the entire JVM to abruptly cease working, I...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="ant" label="ant" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="java" label="java" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>For one of the projects I am working on, I needed to interact with some native code via <span class="caps">JNI </span>which has a strong probability of crashing. As a native code crash causes the entire <span class="caps">JVM </span>to abruptly cease working, I wanted to launch a child <span class="caps">JVM </span>to isolate my code from native crashes. Unfortunately, there is no such function in Java to do so, but by adding the ant jars to the classpath, it is possible to use the built-in ant functions to launch another <span class="caps">JVM.</span></p>]]>
        <![CDATA[<p>It turns out that embedding ant within an application is pretty simple. Within a dozen lines, you can create your own "build" environment, complete with a copy of the current classpath and launch an embedded command.</p>

<pre><code><span class="category1">public</span> <span class="category1">class</span> Test {
     <span class="category1">public</span> <span class="category1">static</span> <span class="category1">void</span> main(<span class="category2">String</span>[] args) {
          System.out.println("<span class="quote">Hello world!</span>");
      }
}

<span class="category1">public</span> <span class="category1">class</span> ChildVMLauncher {
     <span class="category1">public</span> <span class="category1">static</span> <span class="category1">int</span> launchChildVM() {
          <span class="linecomment">// Init project</span>
          Project project = <span class="category1">new</span> Project();
          project.init();
  
          <span class="linecomment">// Init logger</span>
          DefaultLogger logger = <span class="category1">new</span> DefaultLogger();
          logger.setOutputPrintStream(System.out);
          logger.setErrorPrintStream(System.err);
          logger.setEmacsMode(<span class="category1">true</span>);
          logger.setMessageOutputLevel(Project.MSG_INFO);
          project.addBuildListener(logger);
  
          <span class="linecomment">// Init ant java task</span>
          Java java = <span class="category1">new</span> Java();
          java.setFork(<span class="category1">true</span>);
          java.setClassname("<span class="quote">Test</span>");
          java.setProject(project);
          java.setClasspath(Path.systemClasspath);
          java.init();
  
          <span class="category1">int</span> returnCode = java.executeJava();
          <span class="category1">return</span> returnCode;
      }
 
     <span class="category1">public</span> <span class="category1">static</span> <span class="category1">void</span> main(<span class="category2">String</span>[] args) {
          launchChildVM();
      }
}</code></pre>

<p>Running the application like this will display "Hello world!" on the console within a child <span class="caps">JVM </span>and without ant adornments(this is what the <code>setEmacsMode(true)</code> call is for). By using PipedInputStream, PipedOutputStream and having the call to executeJava run in another thread, it is also possible to read the output from the child VM on the fly. Have fun with spawning <span class="caps">JVM</span>s!</p>]]>
    </content>
</entry>

<entry>
    <title>Working on BitIO v0.2</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2010/03/working-on-bitio-v02.html" />
    <id>tag:jean-francois.im,2010://1.56</id>

    <published>2010-03-13T21:15:29Z</published>
    <updated>2010-03-13T21:27:07Z</updated>

    <summary>A frequent problem when reading data from files is that it involves duplication of both the encoding and decoding part, which is redundant, error prone and poorly documents the actual file format. Considering we have annotations in Java, here is...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="bitio" label="bitio" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="java" label="java" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>A frequent problem when reading data from files is that it involves duplication of both the encoding and decoding part, which is redundant, error prone and poorly documents the actual file format. Considering we have annotations in Java, here is what I am working on for BitIO v0.2.</p>]]>
        <![CDATA[<p>A new class I am adding to BitIO 0.2 is a structure reader, which reads data structures from an InputStream. Annotating a type with the appropriate annotations will allow automatically reading objects from an input stream with proper deserialization without much fuss. Here's a simple example:</p>

<pre><code><span class="category1">public</span> <span class="category1">class</span> SimpleStructure {
     @Bound
     <span class="category1">public</span> <span class="category1">int</span> foo;
 
     @Bound(bitLength = 1)
     <span class="category1">public</span> <span class="category1">long</span> bar;
 
     @Bound(bitLength = 7)
     <span class="category1">private</span> <span class="category1">short</span> baz;
 
     <span class="category1">public</span> <span class="category1">short</span> getBaz() {
          <span class="category1">return</span> baz;
      }
}

<span class="category1">public</span> <span class="category1">class</span> ReadSimpleStructureTest {
     @Test
     <span class="category1">public</span> <span class="category1">void</span> testReadSimpleStructure() <span class="category1">throws</span> <span class="category2">Exception</span> {
          <span class="category1">byte</span>[] data = { (<span class="category1">byte</span>)42, (<span class="category1">byte</span>)130 };
  
          StructureReader reader = <span class="category1">new</span> StructureReader(<span class="category1">new</span> <span class="category2">ByteArrayInputStream</span>(data));
          SimpleStructure simpleStructure = reader.readStructure(SimpleStructure.class);
  
          assertThat(simpleStructure.foo, is(42));
          assertThat(simpleStructure.bar, is(1l));
          assertThat(simpleStructure.getBaz(), is((<span class="category1">short</span>) 2));
      }
}</code></pre>

<p>As you can see, the code above reads the structure directly from the input stream, filling fields as expected. However, it frequently happens that we want to read hierarchies of structures. For example, when packets are received, they often have different structures that are differentiated by an identifier field. We can read those as below:</p>

<pre><code><span class="category1">public</span> <span class="category1">class</span> Parent {
     @Bound
     @Subtype(identifiers = {
              @TypeIdentifier(value = 0, type = ChildA.class),
              @TypeIdentifier(value = 1, type = ChildB.class)
      })
     <span class="category1">int</span> id;
}

<span class="category1">public</span> <span class="category1">class</span> ChildA <span class="category1">extends</span> Parent {
     @Bound
     <span class="category1">int</span> a;
}

<span class="category1">public</span> <span class="category1">class</span> ChildB <span class="category1">extends</span> Parent {
     @Bound
     <span class="category1">int</span> b;
}

<span class="category1">public</span> <span class="category1">class</span> ReadSubclassTest {
     @Test
     <span class="category1">public</span> <span class="category1">void</span> testReadSubclasses() <span class="category1">throws</span> <span class="category2">Exception</span> {
          <span class="category1">byte</span>[] dataA = { (<span class="category1">byte</span>)0, (<span class="category1">byte</span>)42 };
          <span class="category1">byte</span>[] dataB = { (<span class="category1">byte</span>)1, (<span class="category1">byte</span>)69 };
  
          StructureReader reader = <span class="category1">new</span> StructureReader(<span class="category1">new</span> <span class="category2">ByteArrayInputStream</span>(dataA));
          Parent childA = reader.readStructure(Parent.class);
          assertThat(childA.id, is(0));
          assertTrue(childA <span class="category1">instanceof</span> ChildA);
          assertThat(((ChildA)childA).a, is(42));
  
          reader = <span class="category1">new</span> StructureReader(<span class="category1">new</span> <span class="category2">ByteArrayInputStream</span>(dataB));
          Parent childB = reader.readStructure(Parent.class);
          assertThat(childB.id, is(1));
          assertTrue(childB <span class="category1">instanceof</span> ChildB);
          assertThat(((ChildB)childB).b, is(69));
      }
}</code></pre>

<p>The appropriate subtype is instantiated and appropriately filled, with no special magic required on the developper's side. This makes parsing data streams easy and easily extensible to accomodate new types. I'll be releasing this library soon, check this spot for more news!</p>]]>
    </content>
</entry>

<entry>
    <title>BitIO v0.1</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2010/02/bitio-v01.html" />
    <id>tag:jean-francois.im,2010://1.55</id>

    <published>2010-02-24T18:02:40Z</published>
    <updated>2010-02-24T18:11:30Z</updated>

    <summary>I just released BitIO v0.1, which is a small Java library to read and write bits directly from I/O streams. As the standard Java library only allows for whole bytes to be written and it is somewhat cumbersome to rewrite...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>I just released <a href="/software/bitio.html">BitIO v0.1,</a> which is a small Java library to read and write bits directly from I/O streams. As the standard Java library only allows for whole bytes to be written and it is somewhat cumbersome to rewrite this piece of functionality for every project that requires bitwise streams in Java, you can use this <span class="caps">LGPL</span> 3 library.</p>

<p>It also has been optimized using bitmasking to greatly outperform naïve implementations that use loops and bit rotations to write the data one bit at a time. There are also utility functions to read and write Rice-Goldman values as well as unary-coded values to make writing bitstreams for codecs as easy as possible.</p>]]>
        
    </content>
</entry>

<entry>
    <title>Trying Out Google Wave</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2009/10/trying-out-google-wave.html" />
    <id>tag:jean-francois.im,2009://1.53</id>

    <published>2009-10-03T18:16:59Z</published>
    <updated>2009-10-03T18:59:13Z</updated>

    <summary><![CDATA[I recently got invited to Google Wave &mdash; thanks Alex! &mdash; and surprisingly, another of my friends also made the cut, so we've been trying out Google Wave. Here are my thoughts on how it works....]]></summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="googlewave" label="google wave" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>I recently got invited to Google Wave &mdash; thanks Alex! &mdash; and surprisingly, another of my friends also made the cut, so we've been trying out Google Wave. Here are my thoughts on how it works.</p>]]>
        <![CDATA[<p>The first thing you see when you log onto Google Wave are two waves in your Inbox: one to introduce you to Google Wave and one to invite friends and colleagues to Google Wave. Clicking on the introduction wave presents you with Dr. Wave from Google Labs who gives <a href="http://www.youtube.com/watch?v=YiGdUmvPRy8">a brief introduction to the layout,</a> along with a couple of introductory videos that explain how to use some of the features as well as some example waves.</p>

<p><a href="http://jean-francois.im/assets_c/2009/10/drwave-60.html" onclick="window.open('http://jean-francois.im/assets_c/2009/10/drwave-60.html','popup','width=1288,height=992,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://jean-francois.im/assets_c/2009/10/drwave-thumb-600x462-60.jpg" width="600" height="462" alt="drwave.jpg" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>

<p>David then created a couple of waves to which he invited me. A wave is essentially a document where you can add replies, which are essentially inline comments with a discussion feature, and add some widgets through the extensions feature. For example, one of the demo waves has a couple of participants planning a <span class="caps">BBQ </span>and they added a yes/no/maybe widget to see who could make it to the <span class="caps">BBQ.</span></p>

<p><a href="http://jean-francois.im/assets_c/2009/10/wavingwithgouff-63.html" onclick="window.open('http://jean-francois.im/assets_c/2009/10/wavingwithgouff-63.html','popup','width=1276,height=978,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://jean-francois.im/assets_c/2009/10/wavingwithgouff-thumb-600x459-63.jpg" width="600" height="459" alt="wavingwithgouff.jpg" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>

<p><a href="http://jean-francois.im/assets_c/2009/10/wavebbq-66.html" onclick="window.open('http://jean-francois.im/assets_c/2009/10/wavebbq-66.html','popup','width=1288,height=992,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://jean-francois.im/assets_c/2009/10/wavebbq-thumb-600x462-66.jpg" width="600" height="462" alt="wavebbq.jpg" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>

<p>Another cool feature is the history control, which is very reminiscent of the <a href="http://blogs.sun.com/erwann/entry/zfs_on_the_desktop_zfs">time slider in OpenSolaris,</a> which allows moving through the history of a document.</p>

<p><a href="http://jean-francois.im/assets_c/2009/10/waveslider-69.html" onclick="window.open('http://jean-francois.im/assets_c/2009/10/waveslider-69.html','popup','width=1288,height=992,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://jean-francois.im/assets_c/2009/10/waveslider-thumb-600x462-69.jpg" width="600" height="462" alt="waveslider.jpg" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></p>

<p>So far, it seems pretty promising and for a lot of things, it beats having a wiki &mdash; especially the horrible wiki implementation in <span class="caps">TRAC </span>&mdash; since there are inline comments and no weird markup language to learn. Heck, even my friend who's in mechanical engineering was able to figure it out, so it's pretty easy to use too!</p>]]>
    </content>
</entry>

<entry>
    <title>Using Keepass with Google Chrome</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2009/04/using-keepass-with-google-chro.html" />
    <id>tag:jean-francois.im,2009://1.52</id>

    <published>2009-04-05T06:02:08Z</published>
    <updated>2010-03-31T14:25:26Z</updated>

    <summary><![CDATA[Edit: I released a chrome extension that does the same thing as the script below. Install it, put the domain &mdash; login.live.com for example &mdash; in the Title in Keepass and it will work. Have fun! I recently downloaded Google...]]></summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Howto" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="chrome" label="chrome" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="greasemonkey" label="greasemonkey" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p><b>Edit: I released a <a href="https://chrome.google.com/extensions/detail/bodphonkppglbgndfcladhogaciihdhb">chrome extension</a> that does the same thing as the script below. Install it, put the domain &mdash; login.live.com for example &mdash; in the Title in Keepass and it will work. Have fun!</b></p>

<p>I recently downloaded Google Chrome, but unfortunately I was unable to use Keepass with it, as it does not put the website's domain in the title bar, pretty much like Opera did. Luckily, Chrome supports Greasemonkey scripts, so I wrote a quick one to add the domain info in the page's title, allowing me to use my list of website passwords.</p>]]>
        <![CDATA[<p>First of all, to enable Chrome support, you have to edit the properties of the Chrome shortcut by right-clicking the Chrome icon, clicking Properties, clicking the Shortcut tab and append --enable-greasemoney to the Target property(making sure that there is a space between chrome.exe and --enable-greasemonkey).</p>

<p>Next, you need to create a folder C:\scripts and place this javascript code, saving it as urlintitle.user.js.</p>

<pre><code><span class="linecomment">// UserScript</span>
<span class="linecomment">// @name                URL in title</span>
<span class="linecomment">// @namespace	        http://jean-francois.im/</span>
<span class="linecomment">// @description	        Script that changes pages' titles to include their domain</span>
<span class="linecomment">// @include		*</span>
<span class="linecomment">// /UserScript</span>


function changeTitle() {
 	var protoDelimIndex = document.URL.indexOf("<span class="quote">://</span>");
 	<span class="category1">if</span>(protoDelimIndex != -1) {
  		var domainDelimIndex = document.URL.indexOf("<span class="quote">/</span>", protoDelimIndex + 4);
  		<span class="category1">if</span>(domainDelimIndex != -1) {
   			document.title=document.title + ' [' + document.URL.slice(0, domainDelimIndex + 1) + ']';
   		}
  	}
}

setTimeout("<span class="quote">changeTitle()</span>", 100);</code></pre>

<p>If everything goes well, Google should be titled "Google [http://www.google.com/]", allowing you to use Keepass. Have fun!</p>]]>
    </content>
</entry>

<entry>
    <title>Multimodule and Multiplatform C++ Builds Using Boost.Build v2</title>
    <link rel="alternate" type="text/html" href="http://jean-francois.im/2009/03/multimodule-and-multiplatform.html" />
    <id>tag:jean-francois.im,2009://1.51</id>

    <published>2009-03-31T01:02:54Z</published>
    <updated>2009-03-31T02:34:50Z</updated>

    <summary>While it is relatively easy to compile simple C++ projets on a single platform, it quickly becomes tedious to maintain multiple makefiles for various platforms and compiler combinations. Boost.Build offers a simple declarative approach to build projects instead of specifying...</summary>
    <author>
        <name>Jean-François Im</name>
        <uri>http://blog.jean-francois.im/</uri>
    </author>
    
        <category term="Tech" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="boostbuild" label="Boost.Build" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://jean-francois.im/">
        <![CDATA[<p>While it is relatively easy to compile simple C++ projets on a single platform, it quickly becomes tedious to maintain multiple makefiles for various platforms and compiler combinations. Boost.Build offers a simple declarative approach to build projects instead of specifying compiler commandlines, which saves on your sanity for multiplatform builds. Unfortunately, its documentation is a bit spotty, so I wrote this entry to show a non-trivial multimodule build using Boost.Build v2.</p>]]>
        <![CDATA[<p>For this example, I wrote the typical "Hello world!" application with a twist; the main method consists of a call to sayHello, which is defined in libhello. The application's file structure is as follows:</p>

<pre><code>C:.
|   Jamroot
|
+---bin
+---libhello
|   |   Jamfile
|   |
|   \---src
|           talk.cpp
|           talk.h
|
\---src
        hello.cpp</code></pre>

<p>Boost.Build uses a single file called Jamroot as well as multiple files called Jamfile. Both contain instructions to build particular targets, but the Jamroot file marks the root of the project, so that Boost.Build knows when to stop moving upwards in the filesystem if you were to invoke a build from the libhello directory, for example.</p>

<p>The contents of Jamroot is as follows:</p>

<pre><code>use-project /libhello : libhello ;

exe hello :
	[ glob src/*.cpp ]
	/libhello//hello
;

install dist : hello : &lt;install-dependencies&gt;on &lt;install-type&gt;EXE &lt;install-type&gt;LIB ;</code></pre>

<p>The first line (use-project) tells Boost.Build that there is another project in the libhello directory and that it can be referred to with the symbolic name <tt>/libhello</tt>. The line with exe tells Boost.Build that you would like to create an executable called hello and the install line tells Boost.Build that it should copy the build output to a directory called dist. As you can see, the hello executable depends on two things: the source code in src and the target called "hello" in libhello.</p>

<p>As for libhello, the contents of Jamfile is as follows:</p>

<pre><code>project : usage-requirements &lt;include&gt;src ;

lib hello :
	[ glob src/*.cpp src/win32/*.cpp ]
	:
	&lt;toolset&gt;msvc
	&lt;target-os&gt;windows
	&lt;define&gt;WIN32
	&lt;define&gt;BUILDING_LIB_HELLO
;

lib hello :
	[ glob src/*.cpp : src/win32/*.cpp ]
	:
	&lt;toolset&gt;gcc
	&lt;define&gt;BUILDING_LIB_HELLO
;</code></pre>

<p>The first line specifies that projects depending on this project should add libhello's source directory to their include path. This saves us from having to add a directive similar to <code>&lt;include&gt;libhello/src</code> in the exe rule. The other two goals define a library called hello. However, when building using gcc, it will exclude the directory src/win32 (which doesn't exist in our example) while building with <span class="caps">MSVC </span>on Windows will define <code>WIN32</code> as a constant.</p>

<p>With those two files, we can simply call <code>bjam</code> to build the project:</p>

<pre><code>C:\Users\jfim\Desktop\boost-build-test&gt;bjam
...found 24 targets...
...updating 15 targets...
MkDir1 dist
MkDir1 bin
MkDir1 bin\msvc
MkDir1 bin\msvc\debug
compile-c-c++ bin\msvc\debug\hello.obj
hello.cpp
MkDir1 libhello\bin
MkDir1 libhello\bin\msvc
MkDir1 libhello\bin\msvc\debug
compile-c-c++ libhello\bin\msvc\debug\talk.obj
talk.cpp
msvc.link.dll libhello\bin\msvc\debug\hello.dll
   Creating library libhello\bin\msvc\debug\hello.lib and object libhello\bin\msvc\debug\hello.exp
msvc.link bin\msvc\debug\hello.exe
common.copy dist\hello.exe
        1 file(s) copied.
common.copy dist\hello.dll
        1 file(s) copied.
common.copy dist\hello.lib
        1 file(s) copied.
...updated 15 targets...</code></pre>

<p>Our executable along with the library are now placed in dist, ready to be used. Alternatively, we could use bjam clean and bjam release to build a release version. This only scratches the surface of Boost.Build, but it should be a solid starting point for a lot of projects out there. Have fun!</p>]]>
    </content>
</entry>

</feed>
