<?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>Sufficiently Small &#187; Robert Smallshire</title>
	<atom:link href="http://www.smallshire.org.uk/sufficientlysmall/author/rob-smallshire/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.smallshire.org.uk/sufficientlysmall</link>
	<description>sin(x) = x</description>
	<lastBuildDate>Sun, 01 Jan 2012 23:29:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>An Atlas of Arduino Ethernet Shields</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2012/01/01/an-atlas-of-arduino-ethernet-shields/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2012/01/01/an-atlas-of-arduino-ethernet-shields/#comments</comments>
		<pubDate>Sun, 01 Jan 2012 19:05:32 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[Arduino]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[arduino]]></category>
		<category><![CDATA[ethernet]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=572</guid>
		<description><![CDATA[Have you ever wanted to find the schematic or PCB layout for your Arduino Ethernet shield, but been frustrated by the lack of version or revision information printed on the shield itself? Have you found the version numbering terminology for Ethernet shields confusing and inconsistent? The Atlas of Arduino Ethernet Shields is here to help! [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2012%2F01%2F01%2Fan-atlas-of-arduino-ethernet-shields%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2012%2F01%2F01%2Fan-atlas-of-arduino-ethernet-shields%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Have you ever wanted to find the schematic or PCB layout for your Arduino Ethernet shield, but been frustrated by the lack of version or revision information printed on the shield itself?  Have you found the version numbering terminology for Ethernet shields confusing and inconsistent?  The Atlas of Arduino Ethernet Shields is here to help!</p>
<p>The folks managing the Arduino website seem to have a penchant for showing pictures of one shield and offering schematics for another right along side or even showing pictures of different shields with incorrect labelling.  This is compounded by that fact that many shields don&#8217;t have useful version or revision information printed on the shield itself. Finally, there seems to be an element of folks in the community second-guessing or inventing shield version numbers (if it came just before 5.0, it must be 4.0, right?) which just makes a bad situation worse. Until the Arduino folks get their change management practices in order, pages like this will be needed to clear up the confusion.  I hope you find it useful!</p>
<p>Any errors below are my own, and I&#8217;ll be happy to correct them if you can provide information with a more reliable provenance than &#8220;off the Internet&#8221;.</p>
<p>This guide includes pictures of the Ethernet shields and links to the corresponding schematics and board layouts.</p>
<p>The following shields are presented, in order of age:<br />
<b>Official Arduino Shields</b></p>
<ul>
<li>Ethernet Shield 01</li>
<li>Ethernet Shield 05 or Ethernet Shield V5</li>
<li>Ethernet Shield 06 or Ethernet Shield V6</li>
<li>Ethernet Shield R3</li>
</ul>
<p><b><i>Unofficial</i> or <i>Impostor</i> &#8220;Arduino&#8221; Shields</b></p>
<p>Regrettably, some shield have been released using the &#8220;Arduino&#8221; name, although they are not offical Arduino designs.  These shields use a different chipset and are not (yet) documented here. This further confuses an already murky picture and is misleading to consumers.</p>
<ul>
<li>Arduino Ethernet Shield V1.0</li>
<li>Arduino Ethernet Shield V1.1</li>
</ul>
<p><span id="more-572"></span></p>
<h1>Ethernet Shield 01</h1>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-01-Top.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-01-Top.jpg" alt="" title="Arduino Ethernet Shield 01 Top Side" width="448" height="340" class="aligncenter size-full wp-image-581" /></a></p>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-01-Bottom.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-01-Bottom.jpg" alt="" title="Arduino-Ethernet-Shield-01-Bottom" width="457" height="349" class="aligncenter size-full wp-image-582" /></a></p>
<p>and with the SD Card socket fitted (although note the text on the label saying &#8220;SD CARD NOT SUPPORTED&#8221;) </p>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/ArduinoEthernetShield.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/ArduinoEthernetShield.jpg" alt="" title="ArduinoEthernetShield" width="320" height="227" class="aligncenter size-full wp-image-595" /></a></p>
<p><b>Also Known As:</b> V1.0, V1, 01, &#8220;Old Version 2009&#8243;, V4.0<br />
<b>Date:</b> 2009<br />
<b>Schematic:</b> <a href='http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/arduino-ethernet-shield-01-schematic.pdf'>arduino-ethernet-shield-01-schematic.pdf</a><br />
<b>Reference design:</b> <a href='http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/arduino-ethernet-shield-reference-design.zip'>arduino-ethernet-shield-reference-design.zip</a><br />
<b>Compatibility:</b>  Arduino Duemilanove form factor. Incompatible with the MEGA without hardware modification.  This shield uses analogue pins A0 and A1 for SD card detection and write protection capabilities.</p>
<p>The Arduino Ethernet Shield 01 (or possibly V1 or V4.0) uses the Wiznet W5100 Ethernet chip and does not have a six pin ISP/ICSP connector to the left underside of the board.  This means that is is not compatible with the Arduino MEGA or Arduino MEGA 2560 without modification.</p>
<h1>Ethernet Shield 05</h1>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-05-Upper-448px1.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-05-Upper-448px1.jpg" alt="" title="Arduino-Ethernet-Shield-05-Upper-448px" width="448" height="362" class="aligncenter size-full wp-image-593" /></a></p>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-05-Under.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-05-Under.jpg" alt="" title="Arduino-Ethernet-Shield-05-Under" width="434" height="322" class="aligncenter size-full wp-image-600" /></a></p>
<p><b>Also Known As:</b> V2.0<br />
<b>Date:</b> 2010<br />
<b>Schematic:</b> <a href='http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/arduino-ethernet-shield-05-schematic.pdf'>arduino-ethernet-shield-05-schematic.pdf</a><br />
<b>Reference design:</b> <a href='http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/arduino-ethernet-shield-05-reference-design.zip'>arduino-ethernet-shield-05-reference-design.zip</a><br />
<b>Compatibility:</b> Compatible with regular Uno and Mega form factors.  The microSD card slot is connected to the Arduino&#8217;s analogue A0 and A1 pins with 10k pull-up resistors, preventing the use of these analogue inputs for other purposes without modifying the Ethernet shield. </p>
<p>The Arduino Ethernet Shield 05 or V5 uses the Wiznet W5100 and includes an microSD card slot. The shield uses the six pin ICSP header for the SPI signals, making it compatible with both the regular Arduino form factor (Duemilanove, Uno) and also the Mega 1280 and Mega 2560 Arduinos. To liberate the A0 and A1 signals from use by this shield cut tracks or remove the pin headers. The microSD functionality can still be used even if such changes are made; the two analogue lines are only used for card detection and write-protect functionality.</p>
<h1>Ethernet Shield 06</h1>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-06-Upper.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-06-Upper.jpg" alt="" title="Arduino-Ethernet-Shield-06-Upper" width="448" height="339" class="aligncenter size-full wp-image-602" /></a></p>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-06-Lower.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-06-Lower.jpg" alt="" title="Arduino-Ethernet-Shield-06-Lower" width="448" height="345" class="aligncenter size-full wp-image-603" /></a></p>
<p><b>Date:</b> 2011<br />
<b>Schematic:</b> <a href='http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/arduino-ethernet-shield-06-schematic.pdf'>arduino-ethernet-shield-06-schematic.pdf</a><br />
<b>EagleCAD reference design:</b> <a href='http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/arduino-ethernet-shield-06-reference-design.zip'>arduino-ethernet-shield-06-reference-design.zip</a><br />
<b>Compatibility:</b> Compatible with regular Uno and Mega form factors. Unlike the 05 shield, the 06 leaves the A0 and A1 pins free for other uses.</p>
<h1>Ethernet Shield R3</h1>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-R3-Top.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/Arduino-Ethernet-Shield-R3-Top.jpg" alt="" title="Arduino-Ethernet-Shield-R3-Top" width="448" height="326" class="aligncenter size-full wp-image-608" /></a></p>
<p><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/ArduinoEthernetShield_R3_Back_450px.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/ArduinoEthernetShield_R3_Back_450px.jpg" alt="" title="ArduinoEthernetShield_R3_Back_450px" width="438" height="320" class="aligncenter size-full wp-image-609" /></a></p>
<p><b>Date:</b> 2011<br />
<b>Schematic:</b>: Not yet available?<br />
<b>Reference design:</b> Not yet available?<br />
<b>Compatibility:</b> Uno R3 or Mega 2560 R3 since this shield has the extra pins in the headers (circled in red on the photograph of the component side of the board) which are only present on R3 Arduinos. This particular header pin configuration is also known as the Arduino 1.0 pinout. I don&#8217;t know if these R3 shields are physcially compatible with pre-R3 Unos or Megas, although they are electrically compatible.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2012/01/01/an-atlas-of-arduino-ethernet-shields/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>My first Printed Circuit Board arrives</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2011/09/10/my-first-printed-circuit-board-arrives/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2011/09/10/my-first-printed-circuit-board-arrives/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 18:16:49 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[Electronics]]></category>
		<category><![CDATA[electronics]]></category>
		<category><![CDATA[pcb]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=554</guid>
		<description><![CDATA[Followed my recently renewed interest in hardware and electronics&#8212;a hobby which has been dormant for about twelve years&#8212; I&#8217;ve had my first printed circuit board (PCB) made commercially. I&#8217;ve always made my own PCBs before, starting with pressing Letraset symbols directly onto copper boards for etching in a ferric chloride solution back in the 1980s. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F09%2F10%2Fmy-first-printed-circuit-board-arrives%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F09%2F10%2Fmy-first-printed-circuit-board-arrives%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Followed my recently renewed interest in hardware and electronics&mdash;a hobby which has been dormant for about twelve years&mdash; I&#8217;ve had my first printed circuit board (PCB) made commercially.  I&#8217;ve always made my own PCBs before, starting with pressing Letraset symbols directly onto copper boards for etching in a ferric chloride solution back in the 1980s.  Later I graduated to photoresist based techniques, which at least meant I could re-use my designs.   Today there is little point in doing this stuff at home when commercial services are available &#8211; you get much better results and you avoid also that messing about with chemistry.</p>
<p>I&#8217;ve been using the free <a href="http://www.cadsoftusa.com/">Eagle CAD</a> to design my PCBs and used <a href="http://www.pcbtrain.co.uk/">PCB Train</a> in the UK for manufacturing. My first design is a bidirectional optoisolator for the <a href="http://en.wikipedia.org/wiki/I%C2%B2C">I²C bus</a>. See below for both the design and the reality.</p>
<p>I obviously still have a something to learn because although the component outlines and some of the labels made it through to the end result the component names did not.  Fortunately there are only a few components!  Also, I notice that my font does not match the manufacturers font.</p>
<div id="attachment_558" class="wp-caption aligncenter" style="width: 474px"><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/i2c_optoisolator_eagle.png"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/i2c_optoisolator_eagle.png" alt="Eagle CAD design for an I2C optoisolator" title="i2c_optoisolator_eagle" width="464" height="493" class="size-full wp-image-558" /></a><p class="wp-caption-text">Eagle CAD design for an I2C optoisolator</p></div>
<div id="attachment_562" class="wp-caption aligncenter" style="width: 474px"><a href="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/i2c_optoisolator_reality1.jpg"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/i2c_optoisolator_reality1.jpg" alt="" title="i2c_optoisolator_reality" width="464" height="500" class="size-full wp-image-562" /></a><p class="wp-caption-text">I2C optoisolator PCB</p></div>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2011/09/10/my-first-printed-circuit-board-arrives/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Nexenta Management View (NMV) with DHCP on NexentaStor</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2011/08/13/using-nexenta-management-view-nmv-with-dhcp-on-nexentastor/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2011/08/13/using-nexenta-management-view-nmv-with-dhcp-on-nexentastor/#comments</comments>
		<pubDate>Sat, 13 Aug 2011 19:46:02 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[dhcp]]></category>
		<category><![CDATA[nas]]></category>
		<category><![CDATA[nexenta]]></category>
		<category><![CDATA[nmv]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=544</guid>
		<description><![CDATA[In a word, don&#8217;t. Or if you do, configure your DHCP server to always lease the same address to your NexentaStor appliance. A week ago I installed NexentaStor CE 3.1 on a new NAS server I have thrown together. Following the install last week, everything in the web-based GUI seemed to be working fine. Following [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F08%2F13%2Fusing-nexenta-management-view-nmv-with-dhcp-on-nexentastor%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F08%2F13%2Fusing-nexenta-management-view-nmv-with-dhcp-on-nexentastor%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>In a word, don&#8217;t. Or if you do, configure your DHCP server to always lease the same address to your NexentaStor appliance.</p>
<p>A week ago I installed <a href="http://www.nexentastor.org/projects/site/wiki/CommunityEdition">NexentaStor CE 3.1</a> on a new NAS server I have thrown together. Following the install last week, everything in the web-based GUI seemed to be working fine. Following the install and a few basic tests I shut down the server, knowing that I wouldn&#8217;t have time to get back to working with it for a while.</p>
<p>Fast forward one week to the next opportunity I get to configure my new server.  Attempts to connect to the server over HTTP on port 2000 are met with a <em>very</em> long wait by the browser &#8211; several minutes are needed to display the main page, which is <code>http://nas:2000/status/general/</code> and once I&#8217;m in there, some pages are dog slow whereas others are quite sprightly.</p>
<p>After much wailing and gnashing of teeth on my part I discovered that the time since I last used the server was long enough for the DHCP lease to expire.  My router duly handed out a new lease, albeit with a different address.  Unfortunately, Nexenta had inserted it&#8217;s own hostname and the original IP address into its <code>/etc/hosts</code> file. Something in the NMV web GUI was causing a look-up here, and of course by this time my router had re-allocated the original Nexenta IP address to my wife&#8217;s iPhone.</p>
<p>The solution was two-fold.  First of all edit <code>/etc/hosts</code> to contain the current IP address of the server, and secondly configure my router&#8217;s DHCP server to always dish out the same IP address to the NAS server.  After a re-start everything is now working fine and it seems now seems possible that I&#8217;ll be able to use NexentaStor.</p>
<p>My faith isn&#8217;t quite restored though &#8211; NexentaStor 3.1 is a brand new release &#8211; and judging from the forums quite a few people have experienced problems with very long browser delays waiting for the NMV to respond.  NexentaStor should work with DHCP out-of-the-box and DHCP lease expiry should be tested if Nexenta are claiming that this is an enterprise grade solution.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2011/08/13/using-nexenta-management-view-nmv-with-dhcp-on-nexentastor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>asq 1.0 released</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2011/06/06/asq-1-0-released/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2011/06/06/asq-1-0-released/#comments</comments>
		<pubDate>Mon, 06 Jun 2011 18:06:31 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[asq]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[LINQ]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=531</guid>
		<description><![CDATA[I&#8217;ve just released asq 1.0 &#8211; a LINQ-inspired API for performing queries over Python objects. The project had been on the unpublished one-day-I&#8217;ll-finish-this back burner for a couple of years now, but recently I found myself wanting it in the course of developing another project. I decided to go public with the incomplete version I [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F06%2F06%2Fasq-1-0-released%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F06%2F06%2Fasq-1-0-released%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;ve just released <a href="http://asq.googlecode.com/"><code>asq 1.0</code></a> &#8211; a LINQ-inspired API for performing queries over Python objects.  The project had been on the unpublished one-day-I&#8217;ll-finish-this back burner for a couple of years now, but recently I found myself wanting it in the course of developing another project.  I decided to go public with the incomplete version I had back in January 2011, calling what I had asq 0.5 and hoping that the harsh glare of publicity would force me to make progress.  I got 18 downloads without any promotional effort and that spurred me on towards a 0.9 release two months later which was feature complete and pretty stable.</p>
<p>Over the course of the next three months, <code>asq 0.9</code> clocked up over 200 downloads.</p>
<p>I decided at this point that I&#8217;d hold back on any actual marketing as such until I could produce a solid 1.0 including comprehensive documentation. Well, <code>asq 1.0</code> isn&#8217;t even 24 hours old yet and it&#8217;s already made 174 downloads.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2011/06/06/asq-1-0-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Specification of rich comparison protocol use by the Python standard library</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2011/03/12/specification-of-rich-comparison-protocol-use-by-the-python-standard-library/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2011/03/12/specification-of-rich-comparison-protocol-use-by-the-python-standard-library/#comments</comments>
		<pubDate>Sat, 12 Mar 2011 19:27:35 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[IronPython]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=508</guid>
		<description><![CDATA[I&#8217;m in the process of writing some code which ideally would work unchanged on CPython 2.x, CPython 3.x IronPython 2.x and Jython 2.x. Given the nature of the code I&#8217;m writing, that seems eminently possible with very few workarounds. One of the changes between Python 2 and Python 3 was the removal of the cmp() [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F03%2F12%2Fspecification-of-rich-comparison-protocol-use-by-the-python-standard-library%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2011%2F03%2F12%2Fspecification-of-rich-comparison-protocol-use-by-the-python-standard-library%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>I&#8217;m in the process of writing some code which ideally would work unchanged on CPython 2.x, CPython 3.x IronPython 2.x and Jython 2.x.  Given the nature of the code I&#8217;m writing, that seems eminently possible with very few workarounds.</p>
<p>One of the changes between Python 2 and Python 3 was the removal of the <code>cmp()</code> function and its corresponding <code>__cmp__()</code> special method.  Python 3 requires the use of the rich comparison operators <code>__lt__()</code>, <code>__gt__()</code>, <code>__ge__()</code>, <code>__le__()</code>, <code>__eq__()</code> and <code>__ne__()</code>.  This change is <a href="http://docs.python.org/release/3.0.1/whatsnew/3.0.html#ordering-comparisons">well publicised</a> and is fine so far as it goes; it&#8217;s usually no problem to modify the code accordingly.  However, the same document goes on to say,</p>
<blockquote><p>Use <code>__lt__()</code> for sorting, <code>__eq__()</code> with <code>__hash__()</code>, and other rich comparisons as needed.</p></blockquote>
<p>This is clear guidance, if not a specification, that sort routines will use <code>__lt__()</code> for sorting.  We don&#8217;t have to look much further for a statement closer to a specification though. In the <a href="http://docs.python.org/howto/sorting.html">Python Sorting HOWTO</a> we can find the following clear declaration:</p>
<blockquote><p>The sort routines are guaranteed to use <code>__lt__()</code> when making comparisons between two objects. So, it is easy to add a standard sort order to a class by defining an <code>__lt__()</code> method.</p></blockquote>
<p>Unfortunately, this fact is not mentioned in the documentation for <code>list.sort()</code> or the <code>sorted()</code> built-in, so it&#8217;s difficult to find. Even more unfortunately for me, the documentation for the standard library <a href="http://docs.python.org/library/heapq.html"><code>heapq</code></a> module does not specify at all what protocols it requires of the objects it will be ordering.</p>
<p>Now all of this became an issue for me today when I implemented an important optimisation which required that I implement an incremental (<em>i.e.</em> lazy) partial sort rather than a complete eager sort of a sequence.  Partial sorts can be efficiently implemented using heaps &#8211; hence my encounter with the <code>heapq</code> module.  My migration from <code>sort()</code> to <code>heapq</code> worked fine on CPython 2.x and CPython 3.x but when I ran my tests with IronPython I got failures for some sorting results.</p>
<p>Soon I determined that the problem was that, as per the documentation for sorting, I&#8217;d implemented <em>only</em> <code>__lt__()</code> and <code>__eq__()</code> rather than the full set of six rich comparison operators.  This worked fine with my original code and with my <code>heapq</code> based sort in CPython because those sort implementation do indeed only call <code>__lt__()</code> and <code>__eq__()</code>.  However, the IronPython implementation of <code>heapq</code> also calls <code>__gt__()</code> and so failed.  Note that IronPython hasn&#8217;t done anything <em>wrong</em> here &#8211; it&#8217;s following the letter of the canonical CPython documentation, if not the spirit. I&#8217;m not sure it&#8217;s fair to consider this a bug in IronPython &#8211; rather it exposes a small but important weakness in the CPython documentation.</p>
<p>There are perhaps two morals to this story: The first is to always implement all or nothing when in comes to the rich comparison operators just like your mother taught you.  The second is that we&#8217;d avoid these sort of difficulties if the Python documentation was a little more explicit about what protocols are expected of objects by its algorithms and containers.</p>
<p>The existence of multiple Python implementations has been extremely effective at defining what it means to be Python as opposed to CPython. Many inconsistencies such as the one noted above have been flushed out over the years. For this reason alone I&#8217;m hesitant to suggest that the folks porting the standard library from CPython to IronPython or Jython should actually read the CPython implementations to ensure compatibility.  I think it&#8217;s much preferable that such things are reimplemented from the documentation and test suite with consequential improvements for both.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2011/03/12/specification-of-rich-comparison-protocol-use-by-the-python-standard-library/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Hindley-Milner type inference implementation in Python</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2010/04/11/a-hindley-milner-type-inference-implementation-in-python/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2010/04/11/a-hindley-milner-type-inference-implementation-in-python/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 19:36:07 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[Functional programming]]></category>
		<category><![CDATA[OWL BASIC]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=474</guid>
		<description><![CDATA[A Python implementation of a Hindley-Milner type inferencing algorithm for a small functional language.]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2010%2F04%2F11%2Fa-hindley-milner-type-inference-implementation-in-python%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2010%2F04%2F11%2Fa-hindley-milner-type-inference-implementation-in-python%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><strong>Before you get too excited this is an implementation of a type inference algorithm that happens to be written in Python; it has nothing to do with the Python language itself!</strong></p>
<p>I&#8217;ve been working on <a href="http://www.smallshire.org.uk/sufficientlysmall/category/computing/software/net/owl-basic/">OWL BASIC</a>, a compiler for <a href="http://en.wikipedia.org/wiki/BBC_BASIC">BBC BASIC</a> for the .NET CLR. The compiler itself is written in IronPython.  One of the challenges of compiling BBC BASIC is to infer the types of functions from the type of their return types. The return value of a BBC BASIC function can be an arbitrary expression, including calls to other functions or recursive calls to itself.  I&#8217;ve implemented a simple type inference scheme which works well in the common cases, but for a fully capable solution my type checker and type inferencer need to be beefed up somewhat.  To that end, I&#8217;ve been investigating standard type systems such as Hindley-Milner and inferencing algorithms such as Damas-Milner, sometimes known as Algorithm W.  These algorithms or derivatives thereof are using in the ML family of languages (Standard ML, Ocaml, F#) and Haskell.</p>
<p>I managed to locate a <a href="http://lucacardelli.name/Papers/BasicTypechecking.pdf#page=19">Modula-2 implementation</a>, a <a href="http://web.archive.org/web/20050911123640/http://www.cs.berkeley.edu/~nikitab/courses/cs263/hm.html">Perl implementation</a> and a <a href="http://dysphoria.net/2009/06/28/hindley-milner-type-inference-in-scala/">Scala implementation</a> of the algorithm, each descended from the previous.  With a view to improving my understanding of the algorithm I set about reimplementing in Python, largely guided by the Scala implementation, making mine the fourth in this sequence.  I also located a <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.65.7733&#038;rep=rep1&#038;type=pdf">Haskell implementation</a> which seems to have independent ancestry.  I&#8217;ve gone back to the companion paper (<a href="http://lucacardelli.name/Papers/BasicTypechecking.pdf">Cardelli 1987</a>) to the original Modula-2 implementation and carried forward some of the code comments which had been omitted from its descendants to assist others who wish to understand the algorithm.</p>
<p>The program implements abstract syntax tree nodes for a small functional language, the type inferencing algorithm and finally exercises the algorithm by inferring the types of some canned expressions in the context of some predefined types. When executed it produces the following output:</p>
<pre class="brush: plain; title: ; notranslate">
&gt; python hindley_milner.py
(letrec factorial = (fn n =&gt; (((cond (zero n)) 1) ((times n) (factorial (pred n))))) in (factorial 5)) :  int
(fn x =&gt; ((pair (x 3)) (x true))) :  Type mismatch: bool != int
((pair (f 4)) (f true)) :  Undefined symbol f
(let f = (fn x =&gt; x) in ((pair (f 4)) (f true))) :  (int * bool)
(fn f =&gt; (f f)) :  recursive unification
(let g = (fn f =&gt; 5) in (g g)) :  int
(fn g =&gt; (let f = (fn x =&gt; g) in ((pair (f 3)) (f true)))) :  (a -&gt; (a * a))
(fn f =&gt; (fn g =&gt; (fn arg =&gt; (g (f arg))))) :  ((b -&gt; c) -&gt; ((c -&gt; d) -&gt; (b -&gt; d)))
</pre>
<p>The Python code is shown below in its entirety or it can be downloaded as <a href="http://www.smallshire.org.uk/downloads/hindley_milner.py">hindley_milner.py</a>. It will run without modification on Python 2.6 or Python 3. </p>
<pre class="brush: python; title: ; notranslate">
#!/usr/bin/env python
'''
.. module:: hindley_milner
   :synopsis: An implementation of the Hindley Milner type checking algorithm
              based on the Scala code by Andrew Forrest, the Perl code by
              Nikita Borisov and the paper &quot;Basic Polymorphic Typechecking&quot;
              by Cardelli.
.. moduleauthor:: Robert Smallshire
'''

from __future__ import print_function

#=======================================================#
# Class definitions for the abstract syntax tree nodes
# which comprise the little language for which types
# will be inferred

class Lambda(object):
    &quot;&quot;&quot;Lambda abstraction&quot;&quot;&quot;

    def __init__(self, v, body):
        self.v = v
        self.body = body

    def __str__(self):
        return &quot;(fn {v} =&gt; {body})&quot;.format(v=self.v, body=self.body)

class Ident(object):
    &quot;&quot;&quot;Identfier&quot;&quot;&quot;

    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.name

class Apply(object):
    &quot;&quot;&quot;Function application&quot;&quot;&quot;

    def __init__(self, fn, arg):
        self.fn = fn
        self.arg = arg

    def __str__(self):
        return &quot;({fn} {arg})&quot;.format(fn=self.fn, arg=self.arg)

class Let(object):
    &quot;&quot;&quot;Let binding&quot;&quot;&quot;

    def __init__(self, v, defn, body):
        self.v = v
        self.defn = defn
        self.body = body

    def __str__(self):
        return &quot;(let {v} = {defn} in {body})&quot;.format(v=self.v, defn=self.defn, body=self.body)

class Letrec(object):
    &quot;&quot;&quot;Letrec binding&quot;&quot;&quot;

    def __init__(self, v, defn, body):
        self.v = v
        self.defn = defn
        self.body = body

    def __str__(self):
        return &quot;(letrec {v} = {defn} in {body})&quot;.format(v=self.v, defn=self.defn, body=self.body)

#=======================================================#
# Exception types

class TypeError(Exception):
    &quot;&quot;&quot;Raised if the type inference algorithm cannot infer types successfully&quot;&quot;&quot;

    def __init__(self, message):
        self.__message = message

    message = property(lambda self: self.__message)

    def __str__(self):
        return str(self.message)

class ParseError(Exception):
    &quot;&quot;&quot;Raised if the type environment supplied for is incomplete&quot;&quot;&quot;
    def __init__(self, message):
        self.__message = message

    message = property(lambda self: self.__message)

    def __str__(self):
        return str(self.message)

#=======================================================#
# Types and type constructors

class TypeVariable(object):
    &quot;&quot;&quot;A type variable standing for an arbitrary type.

    All type variables have a unique id, but names are only assigned lazily,
    when required.
    &quot;&quot;&quot;

    next_variable_id = 0

    def __init__(self):
        self.id = TypeVariable.next_variable_id
        TypeVariable.next_variable_id += 1
        self.instance = None
        self.__name = None

    next_variable_name = 'a'

    def _getName(self):
        &quot;&quot;&quot;Names are allocated to TypeVariables lazily, so that only TypeVariables
        present
        &quot;&quot;&quot;
        if self.__name is None:
            self.__name = TypeVariable.next_variable_name
            TypeVariable.next_variable_name = chr(ord(TypeVariable.next_variable_name) + 1)
        return self.__name

    name = property(_getName)

    def __str__(self):
        if self.instance is not None:
            return str(self.instance)
        else:
            return self.name

    def __repr__(self):
        return &quot;TypeVariable(id = {0})&quot;.format(self.id)

class TypeOperator(object):
    &quot;&quot;&quot;An n-ary type constructor which builds a new type from old&quot;&quot;&quot;

    def __init__(self, name, types):
        self.name = name
        self.types = types

    def __str__(self):
        num_types = len(self.types)
        if num_types == 0:
            return self.name
        elif num_types == 2:
            return &quot;({0} {1} {2})&quot;.format(str(self.types[0]), self.name, str(self.types[1]))
        else:
            return &quot;{0} {1}&quot; % (self.name, ' '.join(self.types))

class Function(TypeOperator):
    &quot;&quot;&quot;A binary type constructor which builds function types&quot;&quot;&quot;

    def __init__(self, from_type, to_type):
        super(Function, self).__init__(&quot;-&gt;&quot;, [from_type, to_type])

# Basic types are constructed with a nullary type constructor
Integer = TypeOperator(&quot;int&quot;, [])  # Basic integer
Bool    = TypeOperator(&quot;bool&quot;, []) # Basic bool

#=======================================================#
# Type inference machinery

def analyse(node, env, non_generic=None):
    &quot;&quot;&quot;Computes the type of the expression given by node.

    The type of the node is computed in the context of the context of the
    supplied type environment env. Data types can be introduced into the
    language simply by having a predefined set of identifiers in the initial
    environment. environment; this way there is no need to change the syntax or, more
    importantly, the type-checking program when extending the language.

    Args:
        node: The root of the abstract syntax tree.
        env: The type environment is a mapping of expression identifier names
            to type assignments.
            to type assignments.
        non_generic: A set of non-generic variables, or None

    Returns:
        The computed type of the expression.

    Raises:
        TypeError: The type of the expression could not be inferred, for example
            if it is not possible to unify two types such as Integer and Bool
        ParseError: The abstract syntax tree rooted at node could not be parsed
    &quot;&quot;&quot;

    if non_generic is None:
        non_generic = set()

    if isinstance(node, Ident):
        return getType(node.name, env, non_generic)
    elif isinstance(node, Apply):
        fun_type = analyse(node.fn, env, non_generic)
        arg_type = analyse(node.arg, env, non_generic)
        result_type = TypeVariable()
        unify(Function(arg_type, result_type), fun_type)
        return result_type
    elif isinstance(node, Lambda):
        arg_type = TypeVariable()
        new_env = env.copy()
        new_env[node.v] = arg_type
        new_non_generic = non_generic.copy()
        new_non_generic.add(arg_type)
        result_type = analyse(node.body, new_env, new_non_generic)
        return Function(arg_type, result_type)
    elif isinstance(node, Let):
        defn_type = analyse(node.defn, env, non_generic)
        new_env = env.copy()
        new_env[node.v] = defn_type
        return analyse(node.body, new_env, non_generic)
    elif isinstance(node, Letrec):
        new_type = TypeVariable()
        new_env = env.copy()
        new_env[node.v] = new_type
        new_non_generic = non_generic.copy()
        new_non_generic.add(new_type)
        defn_type = analyse(node.defn, new_env, new_non_generic)
        unify(new_type, defn_type)
        return analyse(node.body, new_env, non_generic)
    assert 0, &quot;Unhandled syntax node {0}&quot;.format(type(t))

def getType(name, env, non_generic):
    &quot;&quot;&quot;Get the type of identifier name from the type environment env.

    Args:
        name: The identifier name
        env: The type environment mapping from identifier names to types
        non_generic: A set of non-generic TypeVariables

    Raises:
        ParseError: Raised if name is an undefined symbol in the type
            environment.
    &quot;&quot;&quot;
    if name in env:
        return fresh(env[name], non_generic)
    elif isIntegerLiteral(name):
        return Integer
    else:
        raise ParseError(&quot;Undefined symbol {0}&quot;.format(name))

def fresh(t, non_generic):
    &quot;&quot;&quot;Makes a copy of a type expression.

    The type t is copied. The the generic variables are duplicated and the
    non_generic variables are shared.

    Args:
        t: A type to be copied.
        non_generic: A set of non-generic TypeVariables
    &quot;&quot;&quot;
    mappings = {} # A mapping of TypeVariables to TypeVariables

    def freshrec(tp):
        p = prune(tp)
        if isinstance(p, TypeVariable):
            if isGeneric(p, non_generic):
                if p not in mappings:
                    mappings[p] = TypeVariable()
                return mappings[p]
            else:
                return p
        elif isinstance(p, TypeOperator):
            return TypeOperator(p.name, [freshrec(x) for x in p.types])

    return freshrec(t)

def unify(t1, t2):
    &quot;&quot;&quot;Unify the two types t1 and t2.

    Makes the types t1 and t2 the same.

    Args:
        t1: The first type to be made equivalent
        t2: The second type to be be equivalent

    Returns:
        None

    Raises:
        TypeError: Raised if the types cannot be unified.
    &quot;&quot;&quot;

    a = prune(t1)
    b = prune(t2)
    if isinstance(a, TypeVariable):
        if a != b:
            if occursInType(a, b):
                raise TypeError(&quot;recursive unification&quot;)
            a.instance = b
    elif isinstance(a, TypeOperator) and isinstance(b, TypeVariable):
        unify(b, a)
    elif isinstance(a, TypeOperator) and isinstance(b, TypeOperator):
        if (a.name != b.name or len(a.types) != len(b.types)):
            raise TypeError(&quot;Type mismatch: {0} != {1}&quot;.format(str(a), str(b)))
        for p, q in zip(a.types, b.types):
            unify(p, q)
    else:
        assert 0, &quot;Not unified&quot;

def prune(t):
    &quot;&quot;&quot;Returns the currently defining instance of t.

    As a side effect, collapses the list of type instances. The function Prune
    is used whenever a type expression has to be inspected: it will always
    return a type expression which is either an uninstantiated type variable or
    a type operator; i.e. it will skip instantiated variables, and will
    actually prune them from expressions to remove long chains of instantiated
    variables.

    Args:
        t: The type to be pruned

    Returns:
        An uninstantiated TypeVariable or a TypeOperator
    &quot;&quot;&quot;
    if isinstance(t, TypeVariable):
        if t.instance is not None:
            t.instance = prune(t.instance)
            return t.instance
    return t

def isGeneric(v, non_generic):
    &quot;&quot;&quot;Checks whether a given variable occurs in a list of non-generic variables

    Note that a variables in such a list may be instantiated to a type term,
    in which case the variables contained in the type term are considered
    non-generic.

    Note: Must be called with v pre-pruned

    Args:
        v: The TypeVariable to be tested for genericity
        non_generic: A set of non-generic TypeVariables

    Returns:
        True if v is a generic variable, otherwise False
    &quot;&quot;&quot;
    return not occursIn(v, non_generic)

def occursInType(v, type2):
    &quot;&quot;&quot;Checks whether a type variable occurs in a type expression.

    Note: Must be called with v pre-pruned

    Args:
        v:  The TypeVariable to be tested for
        type2: The type in which to search

    Returns:
        True if v occurs in type2, otherwise False
    &quot;&quot;&quot;
    pruned_type2 = prune(type2)
    if pruned_type2 == v:
        return True
    elif isinstance(pruned_type2, TypeOperator):
        return occursIn(v, pruned_type2.types)
    return False

def occursIn(t, types):
    &quot;&quot;&quot;Checks whether a types variable occurs in any other types.

    Args:
        v:  The TypeVariable to be tested for
        types: The sequence of types in which to search

    Returns:
        True if t occurs in any of types, otherwise False
    &quot;&quot;&quot;
    return any(occursInType(t, t2) for t2 in types)

def isIntegerLiteral(name):
    &quot;&quot;&quot;Checks whether name is an integer literal string.

    Args:
        name: The identifier to check

    Returns:
        True if name is an integer literal, otherwise False
    &quot;&quot;&quot;
    result = True
    try:
        int(name)
    except ValueError:
        result = False
    return result

#==================================================================#
# Example code to exercise the above

def tryExp(env, node):
    &quot;&quot;&quot;Try to evaluate a type printing the result or reporting errors.

    Args:
        env: The type environment in which to evaluate the expression.
        node: The root node of the abstract syntax tree of the expression.

    Returns:
        None
    &quot;&quot;&quot;
    print(str(node) + &quot; : &quot;, end=' ')
    try:
        t = analyse(node, env)
        print(str(t))
    except (ParseError, TypeError) as e:
        print(e)

def main():
    &quot;&quot;&quot;The main example program.

    Sets up some predefined types using the type constructors TypeVariable,
    TypeOperator and Function.  Creates a list of example expressions to be
    evaluated. Evaluates the expressions, printing the type or errors arising
    from each.

    Returns:
        None
    &quot;&quot;&quot;

    var1 = TypeVariable()
    var2 = TypeVariable()
    pair_type = TypeOperator(&quot;*&quot;, (var1, var2))

    var3 = TypeVariable()

    my_env = { &quot;pair&quot; : Function(var1, Function(var2, pair_type)),
               &quot;true&quot; : Bool,
               &quot;cond&quot; : Function(Bool, Function(var3, Function(var3, var3))),
               &quot;zero&quot; : Function(Integer, Bool),
               &quot;pred&quot; : Function(Integer, Integer),
               &quot;times&quot;: Function(Integer, Function(Integer, Integer)) }

    pair = Apply(Apply(Ident(&quot;pair&quot;), Apply(Ident(&quot;f&quot;), Ident(&quot;4&quot;))), Apply(Ident(&quot;f&quot;), Ident(&quot;true&quot;)))

    examples = [
            # factorial
            Letrec(&quot;factorial&quot;, # letrec factorial =
                Lambda(&quot;n&quot;,    # fn n =&gt;
                    Apply(
                        Apply(   # cond (zero n) 1
                            Apply(Ident(&quot;cond&quot;),     # cond (zero n)
                                Apply(Ident(&quot;zero&quot;), Ident(&quot;n&quot;))),
                            Ident(&quot;1&quot;)),
                        Apply(    # times n
                            Apply(Ident(&quot;times&quot;), Ident(&quot;n&quot;)),
                            Apply(Ident(&quot;factorial&quot;),
                                Apply(Ident(&quot;pred&quot;), Ident(&quot;n&quot;)))
                        )
                    )
                ),      # in
                Apply(Ident(&quot;factorial&quot;), Ident(&quot;5&quot;))
            ),

            # Should fail:
            # fn x =&gt; (pair(x(3) (x(true)))
            Lambda(&quot;x&quot;,
                Apply(
                    Apply(Ident(&quot;pair&quot;),
                        Apply(Ident(&quot;x&quot;), Ident(&quot;3&quot;))),
                    Apply(Ident(&quot;x&quot;), Ident(&quot;true&quot;)))),

            # pair(f(3), f(true))
            Apply(
                Apply(Ident(&quot;pair&quot;), Apply(Ident(&quot;f&quot;), Ident(&quot;4&quot;))),
                Apply(Ident(&quot;f&quot;), Ident(&quot;true&quot;))),

            # let f = (fn x =&gt; x) in ((pair (f 4)) (f true))
            Let(&quot;f&quot;, Lambda(&quot;x&quot;, Ident(&quot;x&quot;)), pair),

            # fn f =&gt; f f (fail)
            Lambda(&quot;f&quot;, Apply(Ident(&quot;f&quot;), Ident(&quot;f&quot;))),

            # let g = fn f =&gt; 5 in g g
            Let(&quot;g&quot;,
                Lambda(&quot;f&quot;, Ident(&quot;5&quot;)),
                Apply(Ident(&quot;g&quot;), Ident(&quot;g&quot;))),

            # example that demonstrates generic and non-generic variables:
            # fn g =&gt; let f = fn x =&gt; g in pair (f 3, f true)
            Lambda(&quot;g&quot;,
                   Let(&quot;f&quot;,
                       Lambda(&quot;x&quot;, Ident(&quot;g&quot;)),
                       Apply(
                            Apply(Ident(&quot;pair&quot;),
                                  Apply(Ident(&quot;f&quot;), Ident(&quot;3&quot;))
                            ),
                            Apply(Ident(&quot;f&quot;), Ident(&quot;true&quot;))))),

            # Function composition
            # fn f (fn g (fn arg (f g arg)))
            Lambda(&quot;f&quot;, Lambda(&quot;g&quot;, Lambda(&quot;arg&quot;, Apply(Ident(&quot;g&quot;), Apply(Ident(&quot;f&quot;), Ident(&quot;arg&quot;))))))
    ]

    for example in examples:
        tryExp(my_env, example)

if __name__ == '__main__':
    main()
</pre>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2010/04/11/a-hindley-milner-type-inference-implementation-in-python/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Control Flow Graph Linearisation in OWL BASIC</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2010/02/14/control-flow-graph-linearisation-in-owl-basic/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2010/02/14/control-flow-graph-linearisation-in-owl-basic/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 19:27:22 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[OWL BASIC]]></category>
		<category><![CDATA[BBCBASIC]]></category>
		<category><![CDATA[CLR]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=450</guid>
		<description><![CDATA[To compile the code comprising an OWL BASIC procedure, function or main program into CIL, we must linearise the Control Flow Graph (CFG) representing the program statements. The CFG undergoes many transformations during compilation, for example to eliminate unreachable code or convert GOSUB routines into named procedures. Generation of CIL using Reflection.Emit requires that we [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2010%2F02%2F14%2Fcontrol-flow-graph-linearisation-in-owl-basic%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2010%2F02%2F14%2Fcontrol-flow-graph-linearisation-in-owl-basic%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>To compile the code comprising an OWL BASIC procedure, function or main program into CIL, we must linearise the <a href="http://en.wikipedia.org/wiki/Control_flow_graph">Control Flow Graph</a> (CFG) representing the program statements.  The CFG undergoes many transformations during compilation, for example to eliminate unreachable code or convert <code>GOSUB</code> routines into named procedures.  Generation of CIL using Reflection.Emit requires that we can define branch targets in advance of generating branch instructions or marking the target instruction and of course we want to do this in a manner which minimises the number of branches required to represent the code.  The structure of the graph may be quite complex, especially for traditional BASIC spaghetti code which uses GOTO excessively rather than the more structured alternatives such as procedures and functions or the control structures introduced in BBC BASIC V .</p>
<p>Consider the following procedure from Sphinx Adventure.  It contains three loops, one on line 271 formed with a <code>GOTO</code> back to the start of the line, and two <code>REPEAT .. UNTIL</code> loops.</p>
<p>266 DEF PROCL(L)<br />
267 LOCAL I,J:CO=0:CN=0<br />
268 IF L=1 THEN278<br />
269 PRINT&#8217;: RESTORE L: IF O?31&lt;&gt;0 THEN O?31=0:DW=1<br />
270 READ R$,R$:R$=&quot;You are &quot;+R$<br />
271 IF LEN(R$)+ POS&gt;CO-CN+39 THEN R$= FNS(R$,39+CO-CN):CO=CO+39: GOTO271<br />
272 PRINT R$: IFL=136 OR L=15 THEN O?56=L<br />
273 IF L=16 AND FL=1 THEN PRINT&quot;The walls are very hot!&quot; ELSE IF L=16 THEN PRINT &quot;The walls are steaming!&quot;<br />
274 IF L&lt;&gt;3 AND L&lt;&gt;142 AND L&lt;&gt;143 THEN PROCEX(L): IF ABS(L-19)=1 AND CH=1 THEN PRINT ELSE IF ABS(L-42)=1 AND VO=1 THEN PRINT<br />
275 IF CH=1 AND ABS(L-19)=1 THEN PROC R(22): PRINT &quot;chasm.&quot;:O?53=L<br />
276 IF VO=1 AND ABS(L-42)=1 THEN PROCR(22): PRINT&quot;glacier.&quot;:O?53=L<br />
277 IF L=26 OR L=27 THEN O?53=L<br />
278 J=0:I=0:CO=0<br />
279 REPEAT:J=J+1: IF O?J=L  THEN CO=CO+1<br />
280 UNTIL J=52: IF CO=0 AND L=1 THEN PROCR(L): GOTO 284 ELSE IF CO=0 AND L&lt;&gt;1 THEN 284 ELSE PRINT:MAX=CO<br />
281 IF L=1 THEN PROCR(3) ELSE PROCR(4)<br />
282 CN=0:CO=MAX: REPEAT I=I+1: IF O?I=L  THEN PROCOT(I,CO):CO=CO-1<br />
283 UNTIL I=52<br />
284 IF D&lt;&gt;0 THEN O?31=L<br />
285 IF CF=1 AND L=94 THEN PRINT&#8217;&quot;The casket is open.&quot;<br />
286 IF L=24 AND SA=1 THEN PRINT&#8217;&quot;The safe door is open.&quot;<br />
287 PRINT: ENDPROC</p>
<p>The CFG for this code is shown below.  Each program statement is shown as a purple box, with control flow to the following statement(s). Conditionals are shown in diamond boxes.  The numbers in each purple box are source line numbers, where known.</p>
<p>Careful comparison of the source above and the diagram below will reveal some of the transformations that have been applied to the program; for example, <code>READ R$,R$</code> on line 270 has been transformed into two consecutive assignment statements which actually take the form <code>R$ = READ()</code> where <code>READ()</code> is a function not available in the source language.</p>
<p>The <i>statement</i> level CFG has been analysed to identify <a href="http://en.wikipedia.org/wiki/Basic_block">basic-blocks</a>, shown as yellow group nodes, thereby defining a higher level <i>basic-block</i> level CFG.  Each basic block has only one entry point statement; none of the statement within the basic block are destinations of other jump instructions. Furthermore, each block has only one exit point.</p>
<p><i>More text follows this long diagram&#8230;</i></p>
<p><img src="/images/Sphinx_basic_blocks.png" alt="Control Flow Graph for PROC L in Sphinx Adventure" /></p>
<p>Generating the CIL code for a single basic block is straightforward enough &#8211; we can simply iterate through the statements comprising the basic block in order and generate the code for each in turn.  However, there are many possible orders in which the code for the basic block themselves could be representing in the CIL, since we can branch from the end of any block to the next block, although of course we must start at the <i>entry block</i> for the procedure. Although any order starting with the entry block can be made to work, where possible we would like program control to flow smoothly from the end of a block to one of its successors without requiring a branch.</p>
<p>At first sight, some sort of topological ordering would seem to be appropriate, but a topological ordering is only well defined for a <a href="http://en.wikipedia.org/wiki/Directed_acyclic_graph">directed acyclic graph</a> (DAG), and a DAG this program is not.  The key to this conundrum is to reduce the directed graph to a DAG by identifying <a href="http://en.wikipedia.org/wiki/Strongly_connected_components">strongly connected components</a>.  By contracting each SCC to a single node we obtain what is called the <i>condensation</i> of the CFG which <i>will</i> be a DAG. To the resulting DAG we can apply a topological ordering. The ordering of vertices with each SCC is chosen by starting at the vertex with the greatest <a href="http://en.wikipedia.org/wiki/Indegree#Indegree_and_outdegree">in-degree</a>.</p>
<p>In order to identify and contract the SCCs we use an implementation of <a href="http://en.wikipedia.org/wiki/Tarjan's_strongly_connected_components_algorithm">Tarjan&#8217;s algorithm</a> during depth first traversal of the CFG.  The reverse post ordering of the primary depth first traversal is used to generate the topological ordering of the condensed CFG.</p>
<p>The resulting ordering of basic blocks is shown in the diagram by the numeric labels to the top-left of each. This will be the order in which the CIL code for them is generated, and it can be seen that in about half of the cases, fall through from one block to the next (consecutive block numbers) without explicit branching can be exploited.  Future optimisations will focus on further simplifying the generated code by removing vertices, such as block 31, which contain only jumps.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2010/02/14/control-flow-graph-linearisation-in-owl-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OWL BASIC produces its first executable</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2009/08/04/owl-basic-produces-its-first-executable/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2009/08/04/owl-basic-produces-its-first-executable/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 21:45:26 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[IronPython]]></category>
		<category><![CDATA[OWL BASIC]]></category>
		<category><![CDATA[Python]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=394</guid>
		<description><![CDATA[After a long haul, and diversions into other more important projects &#8212; including starting a family &#8212; OWL BASIC today produced its first executable. Its not much. In fact its hardly anything. Just 2048 bytes of Windows PE executable containing the global variable declarations from Acornsoft&#8217;s 1982 Sphinx Adventure. Each file of BASIC source code [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2009%2F08%2F04%2Fowl-basic-produces-its-first-executable%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2009%2F08%2F04%2Fowl-basic-produces-its-first-executable%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>After a long haul, and diversions into other more important projects &#8212; including starting a family &#8212; <a href="http://www.smallshire.org.uk/sufficientlysmall/2007/06/10/writing-a-bbc-basic-compiler-for-the-clr/">OWL BASIC</a> today produced its first executable.  Its not much. In fact its hardly anything. Just 2048 bytes of Windows PE executable containing the global variable declarations from Acornsoft&#8217;s 1982 Sphinx Adventure. Each file of BASIC source code will be converted to a single .NET static class, with the global variables as private static fields.</p>
<div id="attachment_395" class="wp-caption aligncenter" style="width: 538px"><img src="http://www.smallshire.org.uk/sufficientlysmall/wp-content/uploads/sphinx_reflector.png" alt="The first executable produced from OWL BASIC." title="sphinx_reflector" width="528" height="571" class="size-full wp-image-395" /><p class="wp-caption-text">The first executable produced from OWL BASIC.</p></div>
<p>Above you can see the executable loaded up into <a href="http://www.red-gate.com/products/reflector/">.NET Reflector</a>, which can be used to introspect the executable, and in this case attempt to disassemble it into C#.  Now we see what makes .NET such a great platform for compiler construction; below is the <a href="http://www.codeplex.com/IronPython">IronPython</a> source code for the embryonic assembly generation function. It clocks in at fewer than ten lines of code to create an assembly, create a module, create a class, add one private static field to it for each global variable, and save the result as an <code>.exe</code>.</p>
<pre class="brush: python; title: ; notranslate">
def generateAssembly(name, global_symbols):
    domain = Thread.GetDomain()
    assembly_name = AssemblyName(name)
    assembly_builder = domain.DefineDynamicAssembly(assembly_name, AssemblyBuilderAccess.RunAndSave)
    module_builder = assembly_builder.DefineDynamicModule(name + &quot;.exe&quot;)
    type_builder = module_builder.DefineType(name, TypeAttributes.Class | TypeAttributes.Public, object().GetType())

    # Add global variables to the class
    for symbol in global_symbols.symbols.values():
        field_builder = type_builder.DefineField(symbol.name, ctsType(symbol),
                                                 FieldAttributes.Private | FieldAttributes.Static)

    result = type_builder.CreateType()
    assembly_builder.Save(name + &quot;.exe&quot;)
</pre>
<p>where <code>global_symbols</code> is the global symbol table constructed during traversal of the Abstract Syntax Tree and the Control Flow Graph and the <code>ctsType</code> function maps OWL BASIC types to their equivalent <a href="http://en.wikipedia.org/wiki/Common_Type_System">Common Type System</a> types for .NET.  Everything else is provided by <a href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.aspx">Reflection.Emit</a> and other parts of .NET.</p>
<p>Its interesting that no validation was applied to the variable names supplied to <code>Reflection.Emit</code>.  As you can see, the variable names still include the <a href="http://en.wikipedia.org/wiki/Sigil_(computer_programming)">sigil</a> suffixes for variable typing (<i>e.g.</i> $ for string) and Reflector happily dissassembles these into invalid C# identifiers.  For the final version these names will need to be mangled (<a href="http://en.wikipedia.org/wiki/Hungarian_notation">Hungarian notation</a>?), or merely de-sigiled if no conflicts result, for compatibility with other .NET languages and tools.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2009/08/04/owl-basic-produces-its-first-executable/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>In C++ throw is an expression</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/#comments</comments>
		<pubDate>Fri, 31 Jul 2009 11:11:45 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[computing]]></category>
		<category><![CDATA[software]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=384</guid>
		<description><![CDATA[After 15 years programming in C++, I was surprised to discover today that throw in C++ is an expression rather than a statement. As a result, throw may be used as part of larger expressions. The only use I&#8217;ve found for this &#8212; and in fact the speculative attempt by which I discovered it &#8212; [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2009%2F07%2F31%2Fin-c-throw-is-an-expression%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2009%2F07%2F31%2Fin-c-throw-is-an-expression%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>After 15 years programming in C++, I was surprised to discover today that <code>throw</code> in C++ is an expression rather than a statement. As a result, <code>throw</code> may be used as part of larger expressions.</p>
<pre class="brush: cpp; title: ; notranslate">
int x = 5;
int y = x &gt; 4 ? x : throw std::out_of_range;
</pre>
<p>The only use I&#8217;ve found for this &#8212; and in fact the speculative attempt by which I discovered it &#8212; is range checking within constructor initializer lists.</p>
<pre class="brush: cpp; title: ; notranslate">
RangeChecked::RangeChecked(int x) :
    int_member(x &gt; 0 ? x : throw std::out_of_range)
{
}
</pre>
<p>It&#8217;s academic what the <i>type</i> of a throw expression is, since it will never be returned, but for type-checking purposes the compiler seems to be happy to use it in place of any type.</p>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2009/07/31/in-c-throw-is-an-expression/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Installing Eclipse on Windows Vista</title>
		<link>http://www.smallshire.org.uk/sufficientlysmall/2009/07/27/installing-eclipse-on-windows-vista/</link>
		<comments>http://www.smallshire.org.uk/sufficientlysmall/2009/07/27/installing-eclipse-on-windows-vista/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 19:20:30 +0000</pubDate>
		<dc:creator>Robert Smallshire</dc:creator>
				<category><![CDATA[computing]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[eclipse]]></category>
		<category><![CDATA[vista]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.smallshire.org.uk/sufficientlysmall/?p=374</guid>
		<description><![CDATA[Eclipse doesn&#8217;t come with an installer for Windows. As a result of this, installing Eclipse into Program Files is very awkward without getting into a tussle with User Account Control, and virtualisation of the Program Files directory. After far too much effort I have finally found a sequence that Works For Me™ on Windows Vista [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2009%2F07%2F27%2Finstalling-eclipse-on-windows-vista%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.smallshire.org.uk%2Fsufficientlysmall%2F2009%2F07%2F27%2Finstalling-eclipse-on-windows-vista%2F&amp;source=robsmallshire&amp;style=normal&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Eclipse doesn&#8217;t come with an installer for Windows.  As a result of this, installing Eclipse into Program Files is very awkward without getting into a tussle with User Account Control, and virtualisation of the Program Files directory.</p>
<p>After far too much effort I have finally found a sequence that Works For Me™ on Windows Vista Ultimate x64.</p>
<h1>The procedure</h1>
<ol>
<li>Download <code>eclipse-SDK-3.5-win32.zip</code></li>
<li>Extract the zip file into a <strong>temporary</strong> directory.  I used <code>C:\Users\&lt;usename&gt;\Documents\tmp\eclipse</code></li>
<li>Within the temporary directory (important!) edit <code>eclipse.ini</code>, adding the line
<pre class="brush: plain; title: ; notranslate">
-configuration @user.home\.eclipse_35_config
</pre>
<p>My <code>eclipse.ini</code> then looked like this:</p>
<pre class="brush: plain; title: ; notranslate">
-startup
plugins/org.eclipse.equinox.launcher_1.0.200.v20090520.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_1.0.200.v20090519
-showsplash
org.eclipse.platform
-configuration @user.home\.eclipse_35_config
--launcher.XXMaxPermSize
256m
-vmargs
-Xms40m
-Xmx256m
</pre>
</li>
<li>Within the temporary directory create a UTF-8 text file called <code>eclipse.exe.manifest</code> file side-by-side with the <code>eclipse.exe</code> file with the following content:
<pre class="brush: xml; title: ; notranslate">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;yes&quot;?&gt;
&lt;assembly xmlns=&quot;urn:schemas-microsoft-com:asm.v1&quot; manifestVersion=&quot;1.0&quot;&gt;
  &lt;assemblyIdentity version=&quot;1.0.0.0&quot;
     processorArchitecture=&quot;X86&quot;
     name=&quot;eclipse&quot;
     type=&quot;win32&quot;/&gt;
  &lt;description&gt;Eclipse&lt;/description&gt;
  &lt;!-- Identify the application security requirements. --&gt;
  &lt;trustInfo xmlns=&quot;urn:schemas-microsoft-com:asm.v2&quot;&gt;
    &lt;security&gt;
      &lt;requestedPrivileges&gt;
        &lt;requestedExecutionLevel level=&quot;asInvoker&quot; uiAccess=&quot;false&quot;/&gt;
        &lt;/requestedPrivileges&gt;
       &lt;/security&gt;
  &lt;/trustInfo&gt;
&lt;/assembly&gt;
</pre>
</li>
<li>Using drag and drop copy in Explorer, copy the entire <code>eclipse</code> directory from your temporary location to <code>C:\Program Files (x86)\eclipse</code>.  We copy, rather than move simply so you can easily return to this step.
</li>
<li>Right-click on <code>eclipse.exe</code> in Explorer and choose Properties</li>
<li>Click on the Security tab</li>
<li>Click Advanced in the lower right</li>
<li>In the Advanced Security Settings window that pops up, click on the<br />
Owner tab</li>
<li>Click Edit</li>
<li>Click Continue if you get a UAC dialog</li>
<li>Click Other users or groups</li>
<li>Click Advanced in the lower left corner</li>
<li>Click Find Now</li>
<li>Scroll through the results and click on your current user account</li>
<li>Click OK to all of the remaining windows</li>
<li>Right-click the file and select Properties (again)</li>
<li>Click on the Security tab</li>
<li>Click Edit&#8230;</li>
<li>Click on the Users group</li>
<li>Adjust the permissions for your user using the check boxes at the bottom of the dialog. e.g. enable Full Control</li>
<li>Click OK to all of the remaining windows</li>
<li>Right-click the file and select Properties (again!)</li>
<li>Click Unblock and close the dialog</li>
<li>Double click eclipse.exe to run it. You <strong>should not</strong> get an Open File &#8211; Security Warning dialog.</li>
<li>Remove the temporary <code>eclipse</code> directory you created when you unzipped the archive.
</li>
</ol>
<h1>Credit where it is due</h1>
<p>The above post is largely pulled together from various sources I located mixed with a good degree of trial and error.  I found the following particularly useful:</p>
<ul>
<li><a href="http://www.vistaheads.com/forums/microsoft-public-windows-vista-general/30843-open-file-security-warning.html">Open File &#8211; Security Warning on VistaHeads</a></li>
<li><a href="http://www.eclipsezone.com/eclipse/forums/t97323.html">How do you run Eclipse 3.3 on Vista?</a></li>
</ul>
<hr/>Copyright &copy; 2012 <strong><a href="http://www.smallshire.org.uk/sufficientlysmall">Sufficiently Small</a></strong>. This Feed is for personal non-commercial use only. If you are not reading this material in your news aggregator, the site you are looking at is guilty of copyright infringement. Please contact legal@smallshire.org.uk so we can take legal action immediately.<br/><span style="float: right;font-size: 7pt"><a href="http://blog.taragana.com/index.php/archive/wordpress-plugins-provided-by-taraganacom/">Plugin</a> by <a href="http://www.taragana.com/">Taragana</a></span>]]></content:encoded>
			<wfw:commentRss>http://www.smallshire.org.uk/sufficientlysmall/2009/07/27/installing-eclipse-on-windows-vista/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

