<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Notes (beta)</title>
	<atom:link href="http://notes.ericjiang.com/feed" rel="self" type="application/rss+xml" />
	<link>http://notes.ericjiang.com</link>
	<description>Eric Jiang</description>
	<lastBuildDate>Sun, 05 Feb 2012 17:25:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Using the Chez Scheme debugger</title>
		<link>http://notes.ericjiang.com/posts/363</link>
		<comments>http://notes.ericjiang.com/posts/363#comments</comments>
		<pubDate>Sun, 29 Jan 2012 19:09:13 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=363</guid>
		<description><![CDATA[Achtung! Chez Scheme and Petite Chez Scheme do not give the same debugging information. Petite Chez Scheme is often much less helpful than Chez Scheme, and is probably half the reason why nobody actually tries debugging programs in Chez Scheme. I don&#8217;t have a good explanation for why, but that&#8217;s the awful reality. Here&#8217;s a [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Achtung!</strong> Chez Scheme and Petite Chez Scheme do <strong>not</strong> give the same debugging information. Petite Chez Scheme is often much less helpful than Chez Scheme, and is probably half the reason why nobody actually tries debugging programs in Chez Scheme. I don&#8217;t have a good explanation for why, but that&#8217;s the awful reality.</p>
<p>Here&#8217;s a sample, buggy program:</p>
<pre class="brush: scheme; title: ; notranslate">(define myreverse
  (lambda (ls)
    (if (null? ls)
      '()
      (append (myreverse (cdr ls)) (cons (car ls) '())))))

(define mylist (cons 1 (cons 2  (cons 3 (cons 4 5)))))

(display (myreverse mylist))</pre>
<p>Let&#8217;s try loading it in Chez Scheme.</p>
<pre class="terminal">$ scheme
Chez Scheme Version 8.0
Copyright (c) 1985-2010 Cadence Research Systems

&gt; (load "example.ss")
Exception in car: 5 is not a pair
Type (debug) to enter the debugger.
&gt;
</pre>
<p>Obviously, <code>(debug)</code> invokes the debugger. Once we get in there, however, it&#8217;s fairly cryptic.</p>
<pre class="terminal">debug&gt; ?
Type i  to inspect the raise continuation (if available)
     s  to display the condition
     c  to inspect the condition
     e  or eof to exit the debugger, retaining error continuation
     q  to exit the debugger, discarding error continuation
debug&gt;</pre>
<p>Usually, <strong>i</strong>nspecting the continuation is the most helpful thing to do, because once we&#8217;re in there, we can get a stack trace to find out <em>where</em> the error occurred. The command to print out the stack frames is <strong>sf</strong>.</p>
<pre class="terminal">debug&gt; i
#&lt;continuation in myreverse&gt;                                      : sf
  0: #&lt;continuation in myreverse&gt;
  1: #&lt;continuation in myreverse&gt;
  2: #&lt;continuation in myreverse&gt;
  3: #&lt;continuation in myreverse&gt;
  4: #&lt;continuation in myreverse&gt;
  5: #&lt;system continuation in map&gt;
  6: #&lt;system continuation in compile&gt;
  7: #&lt;system continuation&gt;
  8: #&lt;system continuation&gt;
  9: #&lt;system continuation in dynamic-wind&gt;
  10: #&lt;system continuation in dynamic-wind&gt;
  11: #&lt;system continuation in $reset-protect&gt;
  12: #&lt;system continuation in new-cafe&gt;
#&lt;continuation in myreverse&gt;                                      : </pre>
<p>Knowing the stack trace, we can move down the stack frames using <strong>d</strong>own, which is important if the debugger drops you in an error handler under the actual source of the problem. This information is often enough to debug your program. From here, we know that the error occurred when we were five instances deep in <code>myreverse</code>, so the problem was with the end of the list. But if you wanted more specifics, you can type <strong>s</strong> for <strong>s</strong>how:</p>
<pre class="terminal">#&lt;continuation in myreverse&gt;                                      : s
  continuation:          #&lt;continuation in myreverse&gt;
  procedure code:        (lambda (ls) (if (null? ls) (quote ()) ...))
  call code:             (cdr ls)
  free variables:
  0. ls:                 5</pre>
<p>Now we know for certain that we <em>attempted</em> <code>(cdr ls)</code> but <code>ls</code> was actually 5, and <code>(cdr 5)</code> is wrong.</p>
<p>Let&#8217;s try example2.ss:</p>
<pre class="brush: scheme; title: ; notranslate">(define pass-me-a-closure
  (lambda (thunk)
    (break)
    (thunk)))

(pass-me-a-closure
  (lambda ()
    (let loop ((x 5)
               (a 1))
      (if (zero? x)
        a
        (loop (sub1 x) (* a x))))))</pre>
<p>Notice that we&#8217;ve set a breakpoint in the code using <code>(break)</code>. This triggers the debugger, but only if we&#8217;re running Scheme interactively. If you try running <code>scheme example2.ss</code> directly, it will exit when it hits the breakpoint.</p>
<p>At the break point, we do the usual <strong>i</strong>nspect and <strong>sf</strong>ow frames.</p>
<pre class="terminal">[erjiang@silo ~]$ scheme
Chez Scheme Version 8.4
Copyright (c) 1985-2011 Cadence Research Systems

&gt; (load "example2.ss")
break&gt; i
#&lt;continuation in pass-me-a-closure&gt;                              : sf
  0: #&lt;continuation in pass-me-a-closure&gt;
  1: #&lt;system continuation&gt;
  2: #&lt;system continuation&gt;
  3: #&lt;system continuation in dynamic-wind&gt;
  4: #&lt;system continuation in dynamic-wind&gt;
  5: #&lt;system continuation in $reset-protect&gt;
  6: #&lt;system continuation in new-cafe&gt;
#&lt;continuation in pass-me-a-closure&gt;                              : s
  continuation:          #&lt;system continuation&gt;
  procedure code:        (lambda (thunk) (break) (display (thunk)))
  call code:             (break)
  free variables:
  0. thunk:              #&lt;procedure&gt;
#&lt;continuation in pass-me-a-closure&gt;                              :
</pre>
<p>Right now, it doesn&#8217;t actually tell us what <code>thunk</code> is besides just <span style="white-space:nowrap;">#&lt;procedure&gt;</span>. We need to <strong>r</strong>nspect that particular free variable by its number or name by issuing <code>r 0</code> or <code>r thunk</code> and then printing the <strong>c</strong>ode.</p>
<pre class="terminal">#&lt;continuation in pass-me-a-closure&gt;                              : r 0
#&lt;procedure&gt;                                                      : c
(lambda () ((letrec ((loop (lambda (...) (...)))) loop) 5 1))     :</pre>
<p>Notice that the let-loop form has been expanded (remember, the macro expander has already run) and on top of that, the part we actually care about has been elided. Also, the current object is now the code, instead of <span style="white-space:nowrap;">#&lt;procedure&gt;</span>. Because of that, we can <strong>p</strong>retty-print the current object, and it will pretty-print the entire object.</p>
<pre class="terminal">(lambda () ((letrec ((loop (lambda (...) (...)))) loop) 5 1))     : p

(lambda ()
  ((letrec ([loop (lambda (x a)
                    (if (zero? x) a (loop (sub1 x) (* a x))))])
     loop)
    5
    1))</pre>
<p>You can always go back <strong>up</strong> to the parent object from here.</p>
<p>In Chez Scheme, <strong>inspect</strong> is also available as a procedure that will launch the debugger and inspect whatever is passed to it. For example, writing <code>(inspect thunk)</code> into the above code would immediately launch the debugger on <code>thunk</code>. Likewise, doing <code>(call/cc inspect)</code> will launch the debugger and inspect the current continuation (which you can then trace).</p>
<p>Now you should know how to enter the debugger, inspect the stack frames, and inspect variables inside the stack frames, including the procedure code and call code. When in doubt, randomly hit keys or ask for help<strong>?</strong> Expect a pop quiz over this.</p>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/363/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arrow Endianness: How GNOME got sorting backwards</title>
		<link>http://notes.ericjiang.com/posts/456</link>
		<comments>http://notes.ericjiang.com/posts/456#comments</comments>
		<pubDate>Sat, 21 Jan 2012 22:38:40 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Standards]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=456</guid>
		<description><![CDATA[Conventions are important, even when it seems like it doesn&#8217;t matter one way or the other. Just look at all the people who complain about the nerve of Steve Jobs to place the close-window button on the left. There&#8217;s no reason why the left side is better than the right side. Convention, however, says that [...]]]></description>
			<content:encoded><![CDATA[<p>Conventions are important, even when it seems like it doesn&#8217;t matter one way or the other. Just look at all the people who complain about <em>the nerve</em> of Steve Jobs to place the <a href="http://en.wikipedia.org/wiki/File:Windows_3.11_workspace.png">close-window button on the <em>left</em></a>.</p>
<p>There&#8217;s no reason why the left side is better than the right side. Convention, however, says that you must choose one way and live with it, or else you&#8217;ll be forever forced to constantly convert between left-handed and right-handed traditions. Just ask anyone who&#8217;s ever had to write low-level networking code. When sending an integer, it doesn&#8217;t matter whether the big end or little end goes first, but if you don&#8217;t agree with the other party, your message will come out garbled.</p>
<p>So imagine my discomfort when I have to sort files in Nautilus or sort processes in System Monitor.</p>
<p><span id="more-456"></span></p>
<p><a href="http://notes.ericjiang.com/wp-content/uploads/2012/01/nautilus.png"><img src="http://notes.ericjiang.com/wp-content/uploads/2012/01/nautilus.png" alt="" title="GNOME" width="338" height="230" class="aligncenter size-full wp-image-457" /></a></p>
<p>For comparison:</p>
<p><a href="http://notes.ericjiang.com/wp-content/uploads/2012/01/explorer_sort1.png"><img src="http://notes.ericjiang.com/wp-content/uploads/2012/01/explorer_sort1.png" alt="" title="Windows Explorer" width="283" height="243" class="aligncenter size-full wp-image-470" /></a><br />
<a href="http://notes.ericjiang.com/wp-content/uploads/2012/01/explorer_sort2.png"><img src="http://notes.ericjiang.com/wp-content/uploads/2012/01/explorer_sort2.png" alt="" title="Windows Explorer" width="291" height="254" class="aligncenter size-full wp-image-471" /></a></p>
<p>and Wikipedia:</p>
<p><a href="http://notes.ericjiang.com/wp-content/uploads/2012/01/wikipedia_sort.png"><img src="http://notes.ericjiang.com/wp-content/uploads/2012/01/wikipedia_sort.png" alt="" title="Wikipedia" width="305" height="172" class="aligncenter size-full wp-image-467" /></a></p>
<p>Why don&#8217;t I just look at the files to see if they&#8217;re the way I want them? Because the whole point of having that little arrow there is to quickly indicate to me which way things are sorted. I&#8217;d rather have no indicator than a confusing indicator, and besides, if you had to look at your window&#8217;s title bar every time you wanted to close a window, you would be frustrated too.</p>
<p>If you had files sorted by name is ascending order, you would get the first one first.</p>
<p>Alpha.txt<br />
Beta.txt<br />
Gamma.txt</p>
<p>Everybody else uses △ up arrow, but GNOME represents this sort with a ▽ down arrow. If you&#8217;ve ever written SQL, you&#8217;ll know that this alphabetical sort is what you&#8217;d get if you said <q>ORDER BY filename ASC</q>. Ascending is △ upwards. Like an elevator.</p>
<p>There are more ways to look at it. If you&#8217;re sorting numbers in ascending order, you would get</p>
<p>1<br />
2<br />
3<br />
⋮</p>
<p>The <strong>biggest</strong> number is at the bottom. With the △ up arrow, the <strong>biggest</strong> end is at the bottom. This is like when you learned about the numerical comparison operators in preschool: 1 < 3, 9 > 7, or 5 ▷ 3 and 2 ◁ 4.</p>
<p>Score 0 for GNOME, score 2 for everybody else?</p>
<p>Some GNOME defenders point out that using a ▽ down arrow for ascending sort can make sense if you interpret it as an arrow pointing in the direction in which things are ascending. (e.g. in &#8220;1, 2, 3, 4,&#8221; the numbers are &#8220;going&#8221; ▷ right). The <a href="http://developer.gnome.org/hig-book/stable/controls-lists.html.en#controls-lists-sortable">GNOME Human Interface Guidelines</a>, however, don&#8217;t even justify their decision. They simply say that the &#8220;Natural&#8221; order is ▽ down arrow and the &#8220;Reverse&#8221; order is △ up arrow. There&#8217;s nothing supporting the connection between &#8220;Natural&#8221; and ▽ down arrow.</p>
<p><strong>We&#8217;re not doomed forever though.</strong> This was raised as an <a href="https://bugzilla.gnome.org/show_bug.cgi?id=305277">issue in the GNOME bug tracker</a>, and people generally support changing the guidelines to follow the general convention. Just give them another year or two or six and they&#8217;ll bring GNOME in-line with our expectations for how sorting should be indicated.</p>
<p><strong>The real lesson</strong> here is that, when the choice between two things is essentially arbitrary, do some research and consider how everybody else does it. <a href="http://www.ietf.org/rfc/ien/ien137.txt" title="ON HOLY WARS AND A PLEA FOR PEACE">As Danny Cohen wrote (about network endianess)</a>,</p>
<blockquote><p>It may be interesting to notice that  the  point  which  Jonathan  Swift<br />
tried  to  convey  in  Gulliver&#8217;s Travels in exactly the opposite of the<br />
point of this note.</p>
<p>Swift&#8217;s point is that the difference between breaking  the  egg  at  the<br />
little-end  and  breaking  it  at the big-end is trivial.  Therefore, he<br />
suggests, that everyone does it in his own preferred way.</p>
<p>We agree that the difference between sending eggs with  the  little-  or<br />
the  big-end first is trivial, but we insist that everyone must do it in<br />
the same way, to avoid anarchy.  Since the difference is trivial we  may<br />
choose either way, but a decision must be made.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/456/feed</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>Venturer HPS9308 GPS navigation system</title>
		<link>http://notes.ericjiang.com/posts/445</link>
		<comments>http://notes.ericjiang.com/posts/445#comments</comments>
		<pubDate>Thu, 19 Jan 2012 04:11:32 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Personal notes]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=445</guid>
		<description><![CDATA[If you ever want to modify or upgrade your Venturer HPS9308 GPS navigation system, you can easily do so by modifying or replacing the software on the SD Card. However, there are some settings that aren&#8217;t obvious and aren&#8217;t directly modifiable, so you have to follow a couple things. It seems like the default Venturer [...]]]></description>
			<content:encoded><![CDATA[<p>If you ever want to modify or upgrade your Venturer HPS9308 GPS navigation system, you can easily do so by modifying or replacing the software on the SD Card. However, there are some settings that aren&#8217;t obvious and aren&#8217;t directly modifiable, so you have to follow a couple things.</p>
<p>It seems like the default Venturer shell, when you choose &#8220;Navigation&#8221;, looks for SDCard\MobileNavigator\MobileNavigator.exe and runs it. Thus, if you want to replace the software that gets run, you should place the executable at that path. In addition, the GPS device is on port 1 with a baud rate of 4800, at least according to a working config file I found. For reference, that was in SDCard\MobileNavigator\sys.txt with the section<br />
<code>[gps]<br />
port="1"<br />
baud="4800"</code></p>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/445/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gaming hasn&#8217;t changed</title>
		<link>http://notes.ericjiang.com/posts/435</link>
		<comments>http://notes.ericjiang.com/posts/435#comments</comments>
		<pubDate>Thu, 05 Jan 2012 20:16:38 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Gaming]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=435</guid>
		<description><![CDATA[This is about an essay I wrote a couple years back about gaming, under the theme of work and play, and it&#8217;s about how video games are just a subset of gaming, and how they conceptually fit within philosophical frameworks established in the mid-20th century. Among other things, it goes into why World of Warcraft [...]]]></description>
			<content:encoded><![CDATA[<p>This is about an essay I wrote a couple years back about gaming, under the theme of <q>work and play,</q> and it&#8217;s about how video games are just a subset of gaming, and how they conceptually fit within philosophical frameworks established in the mid-20th century. Among other things, it goes into why <em>World of Warcraft</em> directly maps onto the four categories of games set forth by Roger Caillois in 1958: <em>Agôn</em>, <em>alea</em>, <em>mimicry</em>, and <em>ilinx</em>, which could be described as competition, chance, role-playing, and thrill.</p>
<p>It&#8217;s not a perfect paper and gamers might roll their eyes at reading a description of what an MMO is. There are surely some things that I would revise if I had the chance, but the version presented here is untouched from my original, save for formatting. It&#8217;s not a journal paper nor is it a book review, but I hope that some find it interesting. There is a lot that has been written on this subject, and there is much more that could be written. This is just a piece towards the theory that the core components of a <q>fun</q> game are readily identifiable and, with that knowledge, anybody can assemble a fun game.</p>
<p>Some quotes from the paper<br />
<a href='http://notes.ericjiang.com/wp-content/uploads/2012/01/mmo.pdf'>Profit Versus Play: Business and Gaming in MMOs</a> (application/pdf, 87 KB):</p>
<p>On whether MMOs qualify as <q>games</q> in a traditional sense:</p>
<blockquote><p>David Golumbia, who is incidentally among such de-<br />
tractors, could not examine this issue without first defin-<br />
ing the French word jeu in the context of Jacques Der-<br />
rida’s deconstruction of “play.” Fundamentally, Golumbia<br />
establishes jeu as both “play” and “games” (and not con-<br />
trivances like “freeplay”) and this paper will assume the<br />
same: that “games” and “play” are merely different parts<br />
of speech referring to the same concept without carry-<br />
ing any intrinsic differences. And, as we’ll see, MMOs<br />
like Ultima Online and EverQuest are certainly games in<br />
the traditional sense as they fit like clockwork into Roger<br />
Caillois’ categorization of games.</p></blockquote>
<p>On the never-perfect divide between game and real:</p>
<blockquote><p>This “contagion of reality” that plagues MMOs has<br />
been and will continue to be money. “The minute you<br />
hardwire constraints into a virtual world, an economy<br />
emerges,” explained Castronova to Wired. “One-trillionth<br />
of a second later, that economy starts interacting with<br />
ours.”</p></blockquote>
<p>And on harnessing Nietzschean behaviors:</p>
<blockquote><p>It’s this type of accumulating points system that<br />
Golumbia described as an exploitation of Machtelgust, or<br />
the “lust for power” from Nietzsche’s writings. Golumbia<br />
colored computer games in general as being deceptively<br />
simplistic and degenerate. A single-player first-person<br />
shooter (FPS) like the classic sci-fi game Half-life, while<br />
appearing to offer freedom and a story to the player, is re-<br />
ally a very rigid, pre-scripted experience of just shooting<br />
anything that moves with a superficial and shallow plot<br />
tacked on. Likewise, he wrote, MMORPGs are mostly<br />
single-player experiences, despite the name, filled with<br />
repetitive quests in a “surprisingly rigid, uncompromis-<br />
ing, and even authoritarian” world.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/435/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML &lt;legend&gt; tag is broken in WebKit</title>
		<link>http://notes.ericjiang.com/posts/425</link>
		<comments>http://notes.ericjiang.com/posts/425#comments</comments>
		<pubDate>Wed, 04 Jan 2012 00:36:16 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Internets]]></category>
		<category><![CDATA[Standards]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=425</guid>
		<description><![CDATA[All I wanted was for a legend tag to fill up its box horizontally, much like an h1 or div does by default. Apparently, legend tags are special and don&#8217;t follow the same rules as other tags in WebKit, and what I wanted to do was simply impossible. Since I wasn&#8217;t the one to choose [...]]]></description>
			<content:encoded><![CDATA[<p>All I wanted was for a legend tag to fill up its box horizontally, much like an h1 or div does by default. Apparently, legend tags are special and don&#8217;t follow the same rules as other tags in WebKit, and what I wanted to do was simply impossible. Since I wasn&#8217;t the one to choose to use the legend tag (it&#8217;s a CakePHP default), I simply replaced all instances of it with <code>&lt;div class="legend"&gt;</code> and went on with life.</p>
<p>Here&#8217;s an example in which the same <code>display: block</code> style is applied to an h3, a span, and a legend tag, each sitting in identical divs.</p>
<p>Gecko renders the legend tag as a block element correctly, and it fills up the div.</p>
<p><a href="http://notes.ericjiang.com/wp-content/uploads/2012/01/legend-gecko.png"><img src="http://notes.ericjiang.com/wp-content/uploads/2012/01/legend-gecko.png" alt="" title="Gecko" width="382" height="146" class="aligncenter size-full wp-image-428" /></a></p>
<p>WebKit does something special about the width, and so it fails to fill up the div.</p>
<p><a href="http://notes.ericjiang.com/wp-content/uploads/2012/01/legend-webkit.png"><img src="http://notes.ericjiang.com/wp-content/uploads/2012/01/legend-webkit.png" alt="" title="WebKit" width="422" height="146" class="aligncenter size-full wp-image-426" /></a></p>
<p>Given WebKit&#8217;s lineage, it&#8217;s not surprising that KHTML does even worse at the exercise.</p>
<p><a href="http://notes.ericjiang.com/wp-content/uploads/2012/01/legend-khtml.png"><img src="http://notes.ericjiang.com/wp-content/uploads/2012/01/legend-khtml.png" alt="" title="KHTML" width="445" height="131" class="aligncenter size-full wp-image-427" /></a></p>
<p>Try it for yourself: <a href="http://jsfiddle.net/yGCQa/3/">legend width js-fiddle</a>. Other people have had similar issues as well: <a href="http://stackoverflow.com/questions/2568591/cannot-add-margin-to-legend-element-in-safari-chrome">StackOverflow: Cannot add margin to Legend element in Safari &#038; Chrome</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/425/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Dial up</title>
		<link>http://notes.ericjiang.com/posts/416</link>
		<comments>http://notes.ericjiang.com/posts/416#comments</comments>
		<pubDate>Mon, 19 Dec 2011 00:43:51 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Internets]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=416</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><iframe width="560" height="315" src="http://www.youtube.com/embed/GSRG0TqxLWc" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/416/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Parallel Map</title>
		<link>http://notes.ericjiang.com/posts/389</link>
		<comments>http://notes.ericjiang.com/posts/389#comments</comments>
		<pubDate>Thu, 08 Dec 2011 04:32:33 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Internets]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=389</guid>
		<description><![CDATA[&#8230; in JavaScript. A number of events and coincidences have reminded me about functional programming and parallelism lately, especially an example I saw of Clojure&#8217;s pmap: pmap function Usage: (pmap f coll) &#160;&#160;&#160;&#160;&#160;&#160;&#160;(pmap f coll &#038; colls) Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230; in JavaScript.</p>
<p>A number of events and coincidences have reminded me about functional programming and parallelism lately, especially an example I saw of <a href="http://clojure.github.com/clojure/clojure.core-api.html#clojure.core/pmap">Clojure&#8217;s pmap</a>:</p>
<blockquote><p><strong>pmap</strong><br />
<code>function<br />
Usage: (pmap f coll)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(pmap f coll &#038; colls)</code><br />
Like map, except f is applied in parallel. Semi-lazy in that the parallel computation stays ahead of the consumption, but doesn&#8217;t realize the entire result unless required. Only useful for computationally intensive functions where the time of f dominates the coordination overhead.</p></blockquote>
<p>I&#8217;ve heard, for a long time, the argument that functional programming offers a programming style better suited for parallelism. After all, MapReduce is perhaps the ultimate form of famous-brand massive parallelization. In a typical map operation, you don&#8217;t have to worry so much about all the nasty little parallelism problems since your code, by convention, is side-effect free.</p>
<h2>parallelmap</h2>
<p>So, as my contribution to the world of JavaScript hackery, here&#8217;s parallel map in JavaScript:</p>
<p><code>parallelmap(proc, tasks, callback)</code></p>
<p>where <code>proc</code> is a function that takes one argument, <code>tasks</code> is an array of things, and <code>callback</code> is a function that will be called with the results when processing has completed. The computation will occur in parallel and show dramatic speedups on processing-intensive tasks.</p>
<p><span id="more-389"></span></p>
<p>You can try the jspmap.js benchmark for yourself (if you have a recent build of Chrome) in <a href="http://ericjiang.com/jspmap.html" target="_blank">a little test runner</a> that I put together. If the test runner says &#8220;This isn&#8217;t going to work on your browser&#8221;, then it isn&#8217;t going to work on your browser. Sorry. There are a lot of details in the standards that haven&#8217;t been completely worked out yet, so I have to count on vendor-specific implementations to do what I want them to do.</p>
<p>My completely artificial benchmark shows close to a quadruple speedup on my quad-core machine.</p>
<pre class="brush: jscript; title: ; notranslate">
var fun = function(x) {
    var q = 3;
    for(i = 0; i &lt; x*300000; i++) {
        q *= 3.1;
        q = q % 10000000;
    }
    return q;
}
var list = [];
for(var i = 0; i &lt; 50; i++) {
    list.push(i);
}
map(fun, list); // a lot of milliseconds
parallelmap(fun, list, alert); // a lot fewer milliseconds
</pre>
<p>Time to publish? Just don&#8217;t let anyone see the downsides:</p>
<ul>
<li>High overhead</li>
<li>Relies on not-yet-standardized behaviors</li>
<li>Relies on unintended usage (some would call it abuse) of not-yet-standardized behaviors</li>
<li><code>proc</code> must be serializable</li>
<li><code>proc</code> can&#8217;t use browser&#8217;s native functions</li>
<li><code>proc</code> can&#8217;t refer to variables outside of itself</li>
<li>List items and result items must be serializable</li>
<li>Insane</li>
</ul>
<h2>parallelworkers</h2>
<p>The <code>parallelmap</code> function is admittedly a hack, but there&#8217;s also a more practical function included called <code>parallelworkers(url, list, callback)</code> that creates a Web Worker in the more natural way of specifying an external script to run. There&#8217;s the overhead of fetching another object, but it&#8217;s a lot more practical for writing complex scripts and parallelizing them, and it has the same freedoms and limitations as regular Web Workers.</p>
<pre class="brush: jscript; title: ; notranslate">
parallelworkers(&quot;modulo.js&quot;, [1,2,3,4,5], alert);
</pre>
<h2>How it works</h2>
<p>The thing works by using Web Workers that only process one thing. A trivial  that squares a number might look like:</p>
<pre class="brush: jscript; title: ; notranslate">
self.onmessage = function(event) {
    self.postMessage( event.data * event.data )
}
</pre>
<p>The test runner simply tests multiplication, so each worker multiplies one number and returns the result. The <q>main thread</q> (browser thread) handles assigning work and collecting the results. Note that we don&#8217;t have to worry about the typical problems associated with concurrency—no need for locks or mutexes or similar tricky stuff. The implementation handles the gory message-passing details, and the main thread is just a single thread anyways. The architecture of web workers also means there is zero resource sharing—no object references get shared and the workers have no access to the main thread&#8217;s data.</p>
<p>Being able to pass in a function to <code>parallelmap</code> is just a dirty illusion, however. Browsers will happily convert a function to a string for you, and even pretty-print it in the process. Thus, attempting to do the following won&#8217;t work:</p>
<pre class="brush: jscript; title: ; notranslate">
Math.sqrt.toString()
// function sqrt() { [native code] }
parallelmap(Math.sqrt,
    [1,2,3,4,5],
    alert)
// SyntaxError: Unexpected identifier

var x = 5
var fun = function(y) { return x*y }
fun.toString()
// function (y) { return x*y }
parallelmap(fun,
    [1,2,3,4,5],
    alert)
// ReferenceError: x not defined
</pre>
<p>Because Web Workers can only be created with a URL that points to the JavaScript to run, we have to look at special URLs to get around this. In <code>parallelmap</code>, we create a &#8220;blob&#8221; object with the (serialized) code. Blobs let us store arbitrary binary data client-side like this:</p>
<pre class="brush: jscript; title: ; notranslate">
var bb = new BlobBuilder()
bb.append(&quot;Hello world!&quot;)
var url = window.URL.createObjectURL(bb.getBlob())
</pre>
<p>We&#8217;re given an identifier that looks like <code>blob:http://notes.ericjiang.com/733d29b6-65ce-4318-9d41-9b6c893c2c6a</code>. That satisfies the requirement for Web Workers (at least in Chrome), but other browsers may have a different idea of what constitutes <a href="https://developer.mozilla.org/En/Using_web_workers">&#8220;same-origin&#8221; for a Web Worker</a>, and might refuse to play along with this stunt. The <code>parallelworkers</code> function is more practical, if you don&#8217;t mind the overhead of fetching another resource over the network (more overhead!).</p>
<h2>Source code</h2>
<p><strong>If you&#8217;re still reading, <a href="https://github.com/erjiang/jspmap" target="_blank">the jspmap.js code can be found on GitHub</a>.</strong> It provides <code>map</code>, <code>parallelmap</code>, and <code>parallelworkers</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/389/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Ants on the brain</title>
		<link>http://notes.ericjiang.com/posts/383</link>
		<comments>http://notes.ericjiang.com/posts/383#comments</comments>
		<pubDate>Wed, 09 Nov 2011 19:16:50 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=383</guid>
		<description><![CDATA[Google AI Challenge—Week 2: I think my ants are losing faith in me, as I haven&#8217;t uploaded a new version of my AI to the official server for a couple days now. New things are still in the pipeline, but I&#8217;ve lost my last 3 matches (though my opponents were ranked higher than me and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://aichallenge.org/">Google AI Challenge</a>—Week 2:</p>
<p>I think my ants are losing faith in me, as I haven&#8217;t uploaded a new version of my AI to the official server for a couple days now. New things are still in the pipeline, but I&#8217;ve lost my <a href="http://aichallenge.org/profile.php?user=8471">last 3 matches</a> (though my opponents were ranked higher than me and probably deserve it too).</p>
<p>IU now has more than 5 people with active submissions, but the upcoming <a href="http://www.facebook.com/l.php?u=https%3A%2F%2Fdocs.google.com%2Fa%2Fumail.iu.edu%2Fspreadsheet%2Fviewform%3Fformkey%3DdFpGSFllMVZSNjFMQmpBaWtrVGJnclE6MQ&#038;h=EAQFvv4XAAQHn9HR_KS75HFat1ZkM1vMRJ83cW-4QuEx3NA">CS Club Hackathon</a> will change that! I&#8217;m excited to co-organize the hackathon, which will consist of an all-day coding party dedicated to writing an ants AI. Dustin and I, as organizers, will be running matches and generally running things, and since we already have entries in the competition, we&#8217;ll be helping other aspiring antlords to get their own AI up and running.</p>
<p>Thanks to the school, we should have a competition server up and running soon, as opposed to running an unofficial TCP server. Prizes will also be offered to our hackathon winners, so I hope to see some creative strategies. I expect that there will be somebody wanting to use Haskell or JavaScript, but we&#8217;ll see how far they get.</p>
<p>Of course, I&#8217;ve been thinking about people&#8217;s choices of languages in the competition. The top-ranking bots are mostly &#8220;industry&#8221; languages like C++, Java, and Python, but there are a couple bots written in Go, OCaml, and Pascal up there. There&#8217;s definitely a trade-off between compiled languages like C and C++ and higher-level languages like Java and Python. In this competition, time is becoming a sticking point on many bots—you simply can&#8217;t run A* on as many ants in Java as you can in C. On the other hand, the time I&#8217;ve spent <a href="https://github.com/flagcapper/GoogleAI-Ants-Starter-Pack/issues/2">debugging memory errors</a> could have probably been spent on improving my AI strategies.</p>
<p>Language designers are working to pull together this gap between productivity and speed: Google&#8217;s Go combines garbage collection and better concurrency models with the spirit of C, and Rust is another interesting but young language out of Mozilla. In the meantime, Java bot writers in the competition are just making do with timers to keep track of when to stop their calculations.</p>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/383/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some interesting sorting algorithms</title>
		<link>http://notes.ericjiang.com/posts/374</link>
		<comments>http://notes.ericjiang.com/posts/374#comments</comments>
		<pubDate>Wed, 12 Oct 2011 01:28:32 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=374</guid>
		<description><![CDATA[Walking back from Falafels today with CS majors, we somehow began discussing strange sorting algorithms. A good sort to know (not really) is bead sort. Imagine you have a bunch of beads on rods, like an abacus, and cross-wise they represent numbers. If you simply tilt the whole thing over, then gravity will let them [...]]]></description>
			<content:encoded><![CDATA[<p>Walking back from <a href="http://www.falafelsonline.com/Falafels/www.FalafelsOnline.com_1.html">Falafels</a> today with CS majors, we somehow began discussing strange sorting algorithms.</p>
<p>A good sort to know (not really) is bead sort. Imagine you have a bunch of beads on rods, like an abacus, and cross-wise they represent numbers. If you simply tilt the whole thing over, then gravity will let them all fall and they&#8217;ll sort themselves. For example, we have the numbers 3, 2, 4, and 2 read horizontally. When they fall, we get 2, 2, 3, 4. Easy!</p>
<p><img src="http://notes.ericjiang.com/wp-content/uploads/2011/10/beadsort.png" alt="" title="" width="378" height="167" class="aligncenter size-full wp-image-377" /></p>
<p>Another sort, &#8220;random sort,&#8221; &#8220;shuffle sort,&#8221; or the more common name &#8220;bogosort&#8221; was suggested as a good example of an <em>O</em>(∞) algorithm. But, as people have pointed out, if the <a href="http://en.wikipedia.org/wiki/Many-worlds_interpretation">quantum many-worlds theory</a> holds, then you could sort in <em>O</em>(<em>n</em>) time: Use true quantum randomness to randomize the list and if the list is not sorted, then destroy the universe. The only universe that remains will have a sorted list.</p>
<p>Finally, Graham showed me the wonders of sleep sort. I&#8217;ll just leave the bash source code here:</p>
<pre class="brush: bash; title: ; notranslate">
seq=&quot;1 9 2 3 5 6 4 7&quot;
for i in $seq; do
    (sleep $i;echo $i)&amp;false;
done
</pre>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/374/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>git-dude, meet hg-dude</title>
		<link>http://notes.ericjiang.com/posts/365</link>
		<comments>http://notes.ericjiang.com/posts/365#comments</comments>
		<pubDate>Tue, 11 Oct 2011 22:31:57 +0000</pubDate>
		<dc:creator>eric</dc:creator>
				<category><![CDATA[Internets]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://notes.ericjiang.com/?p=365</guid>
		<description><![CDATA[Git-dude is a cool little thing. Given a directory of git repos, it continually fetches updates and displays a popup if you get any new commits. When I first saw it on Google Plus, somebody inexplicably commented, &#8220;This is a neat thing and I dont [sic] think there is a mercurial equivalent.&#8221; Given that Git [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/sickill/git-dude">Git-dude</a> is a cool little thing. Given a directory of git repos, it continually fetches updates and displays a popup if you get any new commits. When I first saw it on Google Plus, somebody inexplicably commented, &#8220;This is a neat thing and I dont <em>[sic]</em> think there is a mercurial equivalent.&#8221;</p>
<p><img src="http://notes.ericjiang.com/wp-content/uploads/2011/10/gnomedialog.png" alt="" title="hg-dude example" width="374" height="106" class="aligncenter size-full wp-image-366" /></p>
<p>Given that Git and Mercurial are isometric for most intents and purposes, this baffled me. Clearly, this could not be some special Git-exclusive functionality. I dug into the git-dude source code and found out it was little more than a <a href="https://github.com/sickill/git-dude/blob/master/git-dude">single bash script</a> that pipes some git commands through sed and awk.</p>
<p>A few minutes later, I made <a href="https://github.com/erjiang/hg-dude">hg-dude</a>, which offers similar functionality for Mercurial.  There&#8217;s a couple things that aren&#8217;t supported. Git-dude offered special notifications for tags and branches, and I didn&#8217;t translate them to Mercurial because the concepts, even though they have similar names, don&#8217;t quite match up. Regardless, it is still as useful as git-dude for commit notifications, which I expect is the primary usage.</p>
<p>Some may notice the irony of hosting a Mercurial tool on Github, but that was the easiest way to preserve <a href="https://github.com/erjiang/hg-dude/commits/master/">its history from its git-dude days</a>. Bitbucket fans can check out <a href="https://bitbucket.org/erjiang/hg-dude">hg-dude&#8217;s Bitbucket repo</a>.</p>
<p><a href="https://github.com/erjiang/hg-dude"><strong>Get hg-dude</strong> at Github</a> or <a href="https://bitbucket.org/erjiang/hg-dude">Bitbucket</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://notes.ericjiang.com/posts/365/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

