<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>

		<title><![CDATA[jtolds.com - Research]]></title>
		<link><![CDATA[http://www.jtolds.com/newsletter/category/research]]></link>
		<description><![CDATA[JT Olds' RSS Feed for Research]]></description>

		<language>en-us</language>
		<copyright>Creative Commons Attribution-NonCommercial-ShareAlike 3.0 License</copyright>

<item>
	<title><![CDATA[Thoughts on Go]]></title>
	<author>JT Olds</author>

	<link><![CDATA[http://www.jtolds.com/newsletter/2010/9/3/thoughts-on-go]]></link>

	<guid>1283477196</guid>
	<pubDate>Fri, 3 Sep 2010 01:26:36 +0000</pubDate>
	<description><![CDATA[<p>This is the first post of a new newsletter category entitled <a href="http://www.jtolds.com/newsletter/category/research">Research</a>. I aim to update Thursdays with what will likely end up being only mild regularity.</p>

<p>I'm looking at <a href="http://golang.org/">Go</a> to see what people are currently doing with programming languages to try and make parallel computing easier. I've only spent two days with Go, but here are my most salient impressions.</p>

<ul>
<li>This isn't news, but Go is warty. It feels incredibly inconsistent across almost all aspects of the language. It kinda seems like the language design strategy was to respond to problems with tweaks instead of reconsidering the design. I read countless posts about this initial reaction when Go was first launched, so I won't belabor the point.</li>
<li>Goroutines are a nice idea, but as far as I can tell are simply lightweight threads, maybe more like fibers (who knows if they swap around). They have this explanation saying "goroutines are different than all these other things like coroutines and threads!" but their argument wasn't compelling. The <code>go</code> keyword seems to be equivalent to forking a command to the background in bash (like with &amp;, admittedly in the same address space), but with no job control. You can't say you want to rejoin, wait, block, nothing. To provide constructs to mimic that, Go gives you:</li>
<li>Channels. First-order channels are actually a pretty sweet idea, and certainly the thing I was most excited about (message-passing FTW!). Certainly they got stuff right: any type can be passed across a channel, including other channels. That's pretty sweet. And they do the obvious thing where writing to a channel blocks your goroutine until there's space in the buffer, and reading from a channel blocks until there's stuff to read; but there's a huge caveat that just sort of kills it for me: channels are forever. Once you make a channel, as long as you have any reference to it, it is assumed to be open. Even if no one is writing to the channel you're reading from, your read will block indefinitely. So, that sucks. My suggestion for fixing this problem in a minute.</li>
<li>The <code>defer</code> keyword is pretty cool. I'm not sure I'm sold on its complete replacement of destructors, but I do like the idea. Basically - you can schedule an operation to run at the end of a function call, LIFO. Because this gives you most of the features people typically use destructors for, objects in Go don't have destructors.</li>
<li>The thing I'm far and away most sold on is Go's implementation of interfaces. Go does not have class hierarchies; instead, Go does what amounts to static duck typing. You provide an interface, which is a list of object methods, and if the object you have has implementations of all of the same method signatures, it is considered an object that implements that interface. So, that's pretty sweet for dependency injection and flexibility, without having to worry about inheritance trees (or even multiple inheritance) or any other complications class hierarchies give you, to much the same end.</li>
<li>Now, this is just speculation from my light reading, but it appears you can add methods to library objects in your own code. That's something the Scala designers have always been proud of: basically unsealed method sets on an object. The syntax for adding an object method is done after the object's definition much like a regular function, and a few of the code examples even have code that adds new methods to built-in types. It's unclear to me if you have to typedef the built-in type to some new typename to make use of this behavior though. Either way, if I understand correctly, that's pretty sweet. Being able to add your own methods to objects of some other package definitely eases friction between library developers and library users.</li>
<li>It appears you can assign variables of many types the nil value. This is terrible and gross. Unfortunately, this means that object methods need to check to make sure the object they were called on is not nil it seems (much of the tutorial code involves nil checks in method definitions).</p>
</ul>

<p>So, let's talk about how to fix the channel issue I mentioned up above. I think the knee-jerk reaction to the idea of a channel is to make channels full duplex. This makes some sense in an IPC context (certainly TCP), but the more I think about it, the less sense I think it makes inside of a process. Most of the channel idioms I've seen so far in Go code don't use the bidirectional nature of channels. Channels seem to be used to either write only or read only. So, if we exploit that, then we can very naturally introduce the concept of closing a channel. Instead of <code>make(chan int)</code> (or equivalent) returning just the new channel, it should instead return the input side and the output side of the channel separately. Then, specific sides of the channel can be force-closed or closed when garbage collected, and the other side of the channel can then throw an error. Note that while I realize you can close any single direction of a channel without requiring the two objects instead of one, having a specific channel-in object and a channel-out object allows most of this channel closing maintenance to be handled by the garbage collector.</p>
<p>Allowing for closing channels, or signaling that a channel is over ("I've generated all the data I can, cap'n!") allows for idioms that indefinitely compute some string of values, but only until it's no longer needed. Conversely, you could make channels that return a limited amount of data, and the reader could easily ascertain that the data stream has ended. Right now, if you create a goroutine that continuously fills or reads from a channel, it will do so until the program ends, at which point it is forcibly terminated. Of course, it is currently possible to work around this by providing another control channel to the goroutine, but that seems (like much of the rest of the language) kind of hacky. If they did this right you could simulate lazy lists or delayed computations in a nicely abstracted and parallel way.</p>
<p>I suppose the suggestion of a channel that you're reading from or writing to closing and throwing an error brings up the whole issue of exceptions. Go doesn't have exceptions, and instead sticks with the C idiom of return values indicating error status. Luckily, Go provides multiple return value support so you can do things like <code>rv, ok = call()</code>, and then check the value of <code>ok</code> for success; however, I really think exception throwing would be useful here, mainly in simplifying boiler-plate code. It's not like you can't implement exceptions with goroutines or something.</p>
<p>Anyway, that's my impression. I really wish Go wasn't so warty, because it seems like it could be real cool. On the other hand, I appreciate how much work it leaves to do in this field :).</p>]]></description>
</item>

	</channel>
</rss>

