<?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>Dodgeball Cannon &#187; Uncategorized</title>
	<atom:link href="http://www.johntantalo.com/blog/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.johntantalo.com/blog</link>
	<description>It's not so much a time machine as it is my blog.</description>
	<lastBuildDate>Sun, 22 Jan 2012 14:10:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Go-flavored JavaScript</title>
		<link>http://www.johntantalo.com/blog/go-flavored-javascript/</link>
		<comments>http://www.johntantalo.com/blog/go-flavored-javascript/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 08:20:09 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=203</guid>
		<description><![CDATA[This week I learned a little bit of Go. I was fascinated by the power and simplicity goroutines and channels. With these ideas fresh in my mind, I decided to reproduce Mark C. Chu-Carroll&#8217;s Go prime sieve in JavaScript with goroutines and channels as my toolset instead of conventional JavaScript idioms. Find my translation on [...]]]></description>
			<content:encoded><![CDATA[<p>This week I learned a little bit of <a href="http://en.wikipedia.org/wiki/Go_(programming_language)">Go</a>. I was fascinated by the power and simplicity goroutines and channels.</p>
<p>With these ideas fresh in my mind, I decided to reproduce Mark C. Chu-Carroll&#8217;s <a href="http://scienceblogs.com/goodmath/2009/11/the_go_i_forgot_concurrency_an.php">Go prime sieve</a> in JavaScript with goroutines and channels as my toolset instead of conventional JavaScript idioms. <strong><a href="https://github.com/tantalor/gojs">Find my translation on GitHub.</a></strong></p>
<p>I chose JavaScript because it shares many traits with Go, such as multiple threads of control, but doesn&#8217;t have a notion of channels.</p>
<h2>Background: goroutines and channels</h2>
<p>A <em>goroutine</em> is an independent concurrent thread of control.</p>
<p>A <em>channel</em> is a mechanism for two concurrently executing functions to communicate by passing a value. A channel has two methods, <em>read</em> and <em>write</em>, which are synchronous by default. That is, a <em>write</em> blocks until there is a <em>read</em> to consume it, and a <em>read</em> blocks until there is a <em>write</em> to consume.</p>
<h2>JavaScript implementation</h2>
<p>Goroutines are rather trivial to implement, a simple <em>setTimeout</em> will schedule an independent thread of control.</p>
<blockquote><pre><code>function go (fn) {
  setTimeout(fn, 0);
};</code></pre>
</blockquote>
<p>Synchronous channels will require a queue of <em>reader</em> and <em>writer</em> callbacks. I decided to call the reader callbacks before the writers, but I don&#8217;t think it matters.</p>
<blockquote><pre><code>var chan = function () {
  this.readers = []; // [cb, ...]
  this.writers = []; // [[value, cb], ...]
};

chan.prototype.read = function (cb) {
  if (this.writers.length) {
    // consume a writer
    var writer = this.writers.shift();
    cb(writer[0]);
    writer[1](writer[0]);
  } else {
    // queue the reader
    this.readers.push(cb);
  }
};

chan.prototype.write = function (value, cb) {
  if (this.readers.length) {
    // consumer a reader
    var reader = this.readers.shift();
    reader(value);
    cb(value);
  } else {
    // queue the writer
    this.writers.push([value, cb]);
  }
};</code></pre>
</blockquote>
<p>I also pass the writer&#8217;s value to its callback because it could be useful.</p>
<h2>The prime sieve</h2>
<p>Mark&#8217;s Go sieve begins with an integer generator.</p>
<blockquote><pre><code>func generate_integers() chan int {
    ch := make(chan int);
    go func(){
        for i := 2; ; i++ {
            ch <- i;
        }
     }();
    return ch;
}</code></pre>
</blockquote>
<p>The problem here is that the channel write (<code>ch <- i</code>) blocks inside of a loop. In JavaScript, we "block" by passing a callback that is called once the procedure can continue. Here, the <em>producer</em> function passes itself as the callback to <em>write</em>.</p>
<blockquote><pre><code>function integers () {
  var ch = new chan();
  go(function () {
    var producer = function (i) {
      ch.write(i + 1, producer);
    };
    ch.write(2, producer);
  });
  return ch;
};</code></pre>
</blockquote>
<p>This Go function excludes multiples of a given prime from the given channel.</p>
<blockquote><pre><code>func filter_multiples(in chan int, prime int) chan int {
   out := make(chan int);
   go func() {
      for {
         if i := <- in; i % prime != 0 {
             out <- i;
         }
      }
    }();
   return out;
}
</code></pre>
</blockquote>
<p>We can rewrite this with another recursive callback, but this time we only have to block when we do a write.</p>
<blockquote><pre><code>function filter_multiples (ch, prime) {
  var out = new chan();
  go(function () {
      var consumer = function (i) {
        if (i % prime != 0) {
          out.write(i, function () {
            ch.read(consumer);
          });
        } else {
          ch.read(consumer);
        }
      }
      ch.read(consumer);
  });
  return out;
};
</code></pre>
</blockquote>
<p>The sieve in Go will chain a series of channels to exclude multiples of all the primes we have seen.</p>
<blockquote><pre><code>func sieve() chan int {
   out := make(chan int);
   go func() {
      ch := generate_integers();
      for {
	     prime := <- ch;
	     out <- prime;
	     ch = filter_multiples(ch, prime);
      }
   }();
   return out;
}</code></pre>
</blockquote>
<p>We achieve the same in JavaScript with another recursive callback.</p>
<blockquote><pre><code>function sieve () {
   var out = new chan();
   go(function () {
      var ch = integers();
      function iteration () {
        ch.read(function (prime) {
          out.write(prime, function () {
            ch = filter_multiples(ch, prime);
            iteration();
          });
        });
      };
      iteration();
   });
   return out;
};</code></pre>
</blockquote>
<p>Mark's program simply reads from the sieve channel and prints out each prime number.</p>
<blockquote><pre><code>func main() {
  primes := sieve();
  for {
    fmt.Println(<-primes);
  }
}</code></pre>
</blockquote>
<p>Mine uses another recursive callback to do the same.</p>
<blockquote><pre><code>function main () {
  var primes = sieve();
  function iteration() {
    primes.read(function (i) {
      sys.puts(i);
      iteration();
    });
  };
  iteration();
}

main();</code></pre>
</blockquote>
<h2>Demo</h2>
<p><a href="http://github.johntantalo.com/gojs/">Go-flavored JavaScript: Prime Sieve</a></p>
<h2>Discussion</h2>
<p>Note that the call to <em>main()</em> returns (practically) immediately, since the goroutine in <em>sieve()</em>, which hasn't executed, has not yet written anything to the channel, so the <em>read</em> inside <em>iteration</em> just pushes the callback onto a read queue and returns. Once the main thread of control stops, the event loop begins running the goroutines, which drive the rest of the program. (Please correct me if I'm wrong.)</p>
<p>That functions return quickly is generally desirable, in JavaScript or Go, because a caller should not have to wait for a function to do some "hard work" before it returns. Instead, the hard work should occur in a separate thread of control and passed back to the caller by some layer of indirection.</p>
<p>JavaScript programmers typically solve this problem with callbacks which receive result of the hard work. The Go language offers synchronous channels between independent threads of control as a more sophisticated solution. These tools are easily ported to idiomatic JavaScript based on callbacks. Although unconventional, these tools are simple and may be very powerful when composed.</p>
<p>I hope this toy example borrowed from Go inspires JavaScript programmers to consider the unconventional.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/go-flavored-javascript/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>My screen workflow</title>
		<link>http://www.johntantalo.com/blog/my-screen-workflow/</link>
		<comments>http://www.johntantalo.com/blog/my-screen-workflow/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 17:34:13 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[screen]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=105</guid>
		<description><![CDATA[I use GNU Screen to keep a few terminal windows open over a shared set of screen windows logged into a large number of other machines. Wrapper screen I log in to the machine that will host my screens and start the wrapper screen. screen -S wrapper -c .screenrc_wrapper The wrapper screen&#8217;s configuration just specifies [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.johntantalo.com/blog/wp-content/uploads/2010/08/screen.png"><img src="http://www.johntantalo.com/blog/wp-content/uploads/2010/08/screen.png" alt="" title="screen" width="125" height="456" class="alignright size-full wp-image-136" /></a>I use <a href="http://www.gnu.org/software/screen/">GNU Screen</a> to keep a few terminal windows open over a shared set of screen windows logged into a large number of other machines.</p>
<h2>Wrapper screen</h2>
<p>I log in to the machine that will host my screens and start the <code>wrapper</code> screen.</p>
<p><code>
<pre>  screen -S wrapper -c .screenrc_wrapper
</pre>
<p></code></p>
<p>The <code>wrapper</code> screen&#8217;s configuration just specifies the interrupt key.</p>
<p><code>
<pre>  escape ^Ww
</pre>
<p></code></p>
<p>I create a screen window in <code>wrapper</code> for each terminal window I want to use, as many as four. Each terminal window will run one of the <code>wrapper</code> windows.</p>
<h2>SSH agent</h2>
<p>I use <a href="http://unixwiz.net/techtips/ssh-agent-forwarding.html">SSH agent forwarding</a> to log in to my screen host, but if you don&#8217;t then you might need to run <code>ssh-agent</code> inside the <code>wrapper</code> screen before starting the <code>ssh</code> screen.</p>
<p><code>
<pre>  exec ssh-agent bash
  ssh-add
</pre>
<p></code></p>
<p>This is necessary for the next step where I <code>ssh</code> into a bunch of other machines. I have already <a href="http://pkeck.myweb.uga.edu/ssh/">installed my public key</a> on the destination machines.</p>
<h2>SSH screen</h2>
<p>I start the <code>ssh</code> screen from inside the <code>wrapper</code> screen.</p>
<p><code>
<pre>  screen -S ssh -c .screenrc_ssh
</pre>
<p></code></p>
<p>The <code>ssh</code> screen&#8217;s configuration creates a bunch of windows that <code>ssh</code> into other machines I want to work on. I like to have at least two windows for each machine.</p>
<p><code>
<pre>  escape `` 

  screen -t "host 1" ssh host1
  screen -t "host 1" ssh host1

  screen -t "host 2" ssh host2
  screen -t "host 2" ssh host2

  screen -t "host 3" ssh host3
  screen -t "host 3" ssh host3

  select 0
</pre>
<p></code></p>
<p>Inside the other <code>wrapper</code> windows, I attach to the running <code>ssh</code> screen.</p>
<p><code>
<pre>  screen -x ssh
</pre>
<p></code></p>
<p>At the start of the day, I open up a few terminal windows, log in into the screen server, and attach to the running <code>wrapper</code> screen. This is simplified with an alias.</p>
<p><code>
<pre>  alias wrapper='screen -x wrapper'
</pre>
<p></code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/my-screen-workflow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Can Haz Wallet?</title>
		<link>http://www.johntantalo.com/blog/can-haz-wallet/</link>
		<comments>http://www.johntantalo.com/blog/can-haz-wallet/#comments</comments>
		<pubDate>Mon, 04 Aug 2008 02:13:36 +0000</pubDate>
		<dc:creator>John Tantalo</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.johntantalo.com/blog/?p=24</guid>
		<description><![CDATA[I found this today on University between 10th and Vermont in San Diego.]]></description>
			<content:encoded><![CDATA[<p>I found this today on University between 10th and Vermont in San Diego.</p>
<p><a href='http://www.johntantalo.com/blog/wp-content/uploads/2008/08/canhaswallet.jpg'><img src="http://www.johntantalo.com/blog/wp-content/uploads/2008/08/canhaswallet-300x225.jpg" alt="" title="canhaswallet" width="300" height="225" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.johntantalo.com/blog/can-haz-wallet/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

