<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4700531182891501924</id><updated>2012-02-16T23:07:46.489Z</updated><category term='Haskell'/><category term='music'/><category term='Shpider'/><category term='writing'/><category term='biohacking'/><category term='gnu/linux'/><title type='text'>Silly Skynet</title><subtitle type='html'>Programming is fundamentally silly and odd.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>71</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-8151020635421969293</id><published>2011-01-07T19:03:00.003Z</published><updated>2011-01-07T19:31:00.422Z</updated><title type='text'>selfmodifier.org is up</title><content type='html'>&lt;a href="https://selfmodifier.org"&gt;selfmodifier.org is up!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, due to a limitation of redmine, you cannot create projects when you first sign in.&lt;br /&gt;&lt;br /&gt;Email &lt;a href="mailto:admin@selfmodifier.org"&gt;admin@selfmodifier.org&lt;/a&gt; if you have any problems.&lt;br /&gt;&lt;br /&gt;Also, if anyone doesn't like my message in the front page then please suggest improvements.&lt;br /&gt;&lt;br /&gt;Apologies to anyone who tried to email me in the last two days:  it's been rather out of order, what with setting everything up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-8151020635421969293?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/8151020635421969293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-is-up.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8151020635421969293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8151020635421969293'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-is-up.html' title='selfmodifier.org is up'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7734148110922746707</id><published>2011-01-07T15:15:00.002Z</published><updated>2011-01-07T15:17:26.418Z</updated><title type='text'>selfmodifier.org finance</title><content type='html'>I'm going to have to start a blog for this.  That would be a good way to push news updates.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyhoo, I'm going to see about getting charitable status.  That will allow us to receive donations without having to get shafted by paypal, nor pay a business tariff.&lt;br /&gt;&lt;br /&gt;Server is back online.  I'll give you a shout when redmine is up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7734148110922746707?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7734148110922746707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-finance.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7734148110922746707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7734148110922746707'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-finance.html' title='selfmodifier.org finance'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-8416714682539321753</id><published>2011-01-07T13:47:00.003Z</published><updated>2011-01-07T13:48:21.769Z</updated><title type='text'>selfmodifier.org upgrade</title><content type='html'>selfmodifier.org is receiving an upgrade at 15:00, so it can cope with redmine.&lt;br /&gt;&lt;br /&gt;Grand opening should be this evening, at some point.&lt;br /&gt;&lt;br /&gt;In the meantime, I'm going to write a little html frontpage.  And order some electronics :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-8416714682539321753?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/8416714682539321753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-upgrade.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8416714682539321753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8416714682539321753'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-upgrade.html' title='selfmodifier.org upgrade'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7481542873466626053</id><published>2011-01-07T05:25:00.002Z</published><updated>2011-01-07T05:27:17.351Z</updated><title type='text'>redmine is slow</title><content type='html'>I got redmine all set up, but it's &lt;b&gt;really&lt;/b&gt; slow - so slow I've had to take it down out fear the system would become unstable.&lt;br /&gt;&lt;br /&gt;Gonna need to upgrade the server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7481542873466626053?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7481542873466626053/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/redmine-is-slow.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7481542873466626053'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7481542873466626053'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/redmine-is-slow.html' title='redmine is slow'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4628750861397046308</id><published>2011-01-07T01:47:00.004Z</published><updated>2011-01-07T03:25:22.513Z</updated><title type='text'>selfmodifier.org, take 2</title><content type='html'>Since we're going to use redmine, for technical documentation and all projects - assuming that works well (it might not crash until week 3...) - we don't need such a complex site as I thought.  However we're still going to need a simple site that:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Hosts static material: disclaimers, legal things, our mission!&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Publish a news stream - are there currently any technical faults with the site?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Donate/shop, the second if we create anything legit enough to sell.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Other things?&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4628750861397046308?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4628750861397046308/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-take-2.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4628750861397046308'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4628750861397046308'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/selfmodifierorg-take-2.html' title='selfmodifier.org, take 2'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-1901633454167479499</id><published>2011-01-04T11:12:00.021Z</published><updated>2011-01-04T12:29:05.530Z</updated><title type='text'>Sensory augmentation experiment log website, request for comments</title><content type='html'>selfmodifier.org shall be a website designed to support the aims and development of the "scrapyard transhumanism movement".  It will:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Document what exactly is happening, in a neutral manner. This will help explain the situation to outsiders.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Improve safety, for anyone who may be interesting in trying out some of the ideas, by being clear on all methods used.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Carry a disclaimer to show that this isn't medical science; that it's more like a mix of piercing and computer science; even then it isn't recognized by piercers.  "Don't be an idiot."&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Make it easier for users to find information&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Make things easier for &lt;a href="http://sapiensanonym.blogspot.com/"&gt;lepht&lt;/a&gt;, who is the only moderator of a blog which is the centre of a growing movement.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Encourage community development.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;It shall attempt to fulfill these aims, by meeting these specific requirements in software:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;selfmodifier.org shall be a collection of experiment logs on low-cost sensory augmentation.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;The site shall have three classes of user who are capable of modifying the site:&lt;/li&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;registered users&lt;/li&gt;&lt;br /&gt;&lt;li&gt;moderators&lt;/li&gt;&lt;br /&gt;&lt;li&gt;site administrators&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Experiment logs shall only be submitted by registered members and moderators.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;On each log's page, it shall be clearly stated that it is not a safe piercing, or medical procedure.  It shall also state that the work has not been peer reviewed by researchers.  It shall state that it is the log of an experiment by a private individual, and that it is not an instruction manual on how to perform home surgery.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Experiments will be structured as the most plain and simple scientific reports.  Each may have:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Title&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Abstract&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Introduction&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Method&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Results&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Discussion&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Reference list&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Appendices&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;This format shall not be enforced by site design, but it shall be encouraged by the moderators.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;The moderations shall be able to ban users, and edit all experiment logs.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Users may be promoted to moderators, and moderators may be demoted to users, or banned, by the administrators.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;There shall be a comment system, to allow users to encourage good work and discourage poor work.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;There shall be a search engine, and tagging scheme, to enable users to find experiment logs&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Registered members retain copyright of their experiment logs. They shall license them to the users themselves, using the GNU Free Documentation License.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;The site reserves the right to remove content and suspend services at any time.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;The site shall respect, &lt;i&gt;and only respect&lt;/i&gt;, the legal authorities of the United Kingdom.  I.E. the &lt;b&gt;only&lt;/b&gt; people whom the administrators are obliged to obey, are the U.K. police.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Since this is a fairly harmless site about implanting things into your skin, anything that is obviously illegal is also irrelevant content, and shall be deleted.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;All source code shall be made available under the GNU GPL.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-1901633454167479499?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/1901633454167479499/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/sensory-augmentation-experiment-log.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1901633454167479499'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1901633454167479499'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/sensory-augmentation-experiment-log.html' title='Sensory augmentation experiment log website, request for comments'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-85791348566298350</id><published>2011-01-03T23:31:00.007Z</published><updated>2011-01-04T11:45:41.978Z</updated><title type='text'>gory website</title><content type='html'>EDIT:  I have decided these ideas are not great - it just sounds so unscientific, which is exactly what people are complaining about.  See the &lt;a href="http://sillyskynet.blogspot.com/2011/01/sensory-augmentation-experiment-log.html"&gt;next entry for new ideas.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So I've decided to go ahead and make a website to host instructions for sensory augmentation.  It will have several caveats, designed to minimize the site's involvement with Her Majesty's servants:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It shall be clearly stated that the instructions on the site are not safe, and are not condoned by medical professionals nor anyone else.  Readers should not attempt to execute the instructions.  The instructions are only intended to provoke thought about the limits of human sensory perception or abilities.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Users shall not be able to comment nor vote upon the instructions.  Allowing this would imply that the site approves of some instructions.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Articles shall only be submitted by registered members.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;Registered members retain copyright of the instructions.  They shall license them to the users themselves: no instructions shall be the intellectual property of the site.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;The site reserves the right to remove content and suspend services at any time.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;EDIT:  this all looks a bit strict.  Perhaps I better revise my ideas?  After all, some people just post pictures of themselves chopping their own balls off online.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-85791348566298350?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/85791348566298350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/gory-website.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/85791348566298350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/85791348566298350'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/gory-website.html' title='gory website'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-8874611146597560707</id><published>2011-01-03T17:13:00.004Z</published><updated>2011-01-03T17:47:57.931Z</updated><title type='text'>websites with gory content</title><content type='html'>Extreme body modification would benefit from an website where people can share their recipes.  However, it's a thing generally frowned upon, and perhaps illegal in some contexts.&lt;br /&gt;&lt;br /&gt;It's not alone in this.  As certain people found out, publishing instructions to hack into the Bank of America is also going to get you into trouble.&lt;br /&gt;&lt;br /&gt;This puts the publisher in a strange position.  I don't do these things.  I don't condone all (most?) of these things!  But some things that are generally frowned upon are great, and it would be brilliant to see them progress!&lt;br /&gt;&lt;br /&gt;I'm not sure what it needs, but a one-owner, one-responsibility website seems a tad inappropriate.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-8874611146597560707?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/8874611146597560707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/websites-with-gory-content.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8874611146597560707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8874611146597560707'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/websites-with-gory-content.html' title='websites with gory content'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-485915435579948429</id><published>2011-01-01T00:46:00.003Z</published><updated>2011-01-01T20:48:57.033Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='gnu/linux'/><category scheme='http://www.blogger.com/atom/ns#' term='biohacking'/><title type='text'>Cybernetics for the masses repair stream on linux</title><content type='html'>The wmas coming out of the &lt;a href="http://events.ccc.de/congress/2009/wiki/Welcome"&gt;ccc&lt;/a&gt; are fucked atm, so here's a command for GNU/Linux users which simultaneously:&lt;br /&gt;downloads&lt;br /&gt;repairs (though transcribing to mp4)&lt;br /&gt;sensibly renames the video&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;wget -qO- http://c3.ex23.de/saal2-2010-12-30_11-21-43.wmv | ffmpeg -i pipe: cybernetics_for_the_masses1.mp4&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For the questions and answers:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;wget -qO- http://c3.ex23.de/saal2-2010-12-30_13-37-07.wmv | ffmpeg -i pipe: cybernetics_for_the_masses2.mp4&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Obviously you need ffmpeg installed for that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-485915435579948429?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/485915435579948429/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/cybernetics-for-masses-good.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/485915435579948429'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/485915435579948429'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2011/01/cybernetics-for-masses-good.html' title='Cybernetics for the masses repair stream on linux'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-2120490674251618310</id><published>2010-12-21T22:00:00.009Z</published><updated>2010-12-22T10:09:49.483Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Positive About Negative Aberdonian Crusty</title><content type='html'>NOTE: I edited this a couple of times around 22:16, on 21 December 2010, and the morning of the 22nd.&lt;br /&gt;&lt;br /&gt;I wrote a song. &lt;a href="http://sutros.com/songs/10898"&gt;Give it a listen!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's a happy blues song about &lt;a href="http://en.wikipedia.org/wiki/Crusty"&gt;crust music&lt;/a&gt; in Aberdeen.&lt;br /&gt;&lt;br /&gt;For the benefit of a couple of friends, here are the tabs:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Positive About Negative Aberdonian Crusty&lt;br /&gt;By John Morrice 2010&lt;br /&gt;&lt;br /&gt;This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License. &lt;br /&gt;&lt;br /&gt;To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/ or send a letter to &lt;br /&gt;Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.&lt;br /&gt;&lt;br /&gt;Hi guys!&lt;br /&gt;&lt;br /&gt;Tuning is a half step down, Eb Bb Db Gb Bb Eb&lt;br /&gt;Time signature is 6/8 for most of the song, but 4/4 at the end.&lt;br /&gt;&lt;br /&gt;Notation:&lt;br /&gt;&lt;br /&gt;Next bar: |&lt;br /&gt;Hammer on: h&lt;br /&gt;Pull off: p&lt;br /&gt;Don't play this string: x&lt;br /&gt;&lt;br /&gt;Notes:&lt;br /&gt;* I skimp on some work by just saying what chord to play for that part.&lt;br /&gt;* The chords used are given at the end of this file.&lt;br /&gt;* Always listen to the song for the rhythm.  &lt;br /&gt;* This tab file does not describe the songs structure, only its riffs.&lt;br /&gt;* I know I wrote the bloody song but these tabs may still not be perfect.&lt;br /&gt;&lt;br /&gt;Verse:&lt;br /&gt;&lt;br /&gt;Eb|-------------0---------|-------------0-----0-&lt;br /&gt;Bb|---------0h2---2p0-----|---------0h2---2p0---&lt;br /&gt;Gb|-------0---------------|-------0-------------&lt;br /&gt;Db|---0h2-------------2p0-|---0h2---------------&lt;br /&gt;Ab|-0---------------------|-0-------------------&lt;br /&gt;Eb|-----------------------|---------------------&lt;br /&gt;&lt;br /&gt;Eb|-------------0---------|-------------------------&lt;br /&gt;Bb|---------0h1---1p0-----|-1p0h1p0h1p0h1p0h1p0h1p0-&lt;br /&gt;Gb|-------0---------------|-------------------------&lt;br /&gt;Db|---0h2-------------2p0-|-------------------------&lt;br /&gt;Ab|-3---------------------|-------------------------&lt;br /&gt;Eb|-----------------------|-------------------------&lt;br /&gt;&lt;br /&gt;Eb|-------------0---------|--------------0-----0-&lt;br /&gt;Bb|---------0h2---2p0-----|----------0h2---2p0---&lt;br /&gt;Gb|-------0---------------|--------0-------------&lt;br /&gt;Db|---0h2-------------2p0-|---0h2----------------&lt;br /&gt;Ab|-0---------------------|-0--------------------&lt;br /&gt;Eb|-----------------------|----------------------&lt;br /&gt;&lt;br /&gt;For the last two bars, strum Gb6 (see the end of this file)&lt;br /&gt;&lt;br /&gt;Chorus rhythm part:&lt;br /&gt;&lt;br /&gt;Strum&lt;br /&gt;&lt;br /&gt;Ab7&lt;br /&gt;Ab7&lt;br /&gt;Gb6&lt;br /&gt;Cb7&lt;br /&gt;&lt;br /&gt;Chorus lead part:&lt;br /&gt;&lt;br /&gt;Eb|-9p7---9p7---9p7---9p7---9p7---9p7---9p7---9p7---&lt;br /&gt;Bb|-----8-----8-----8-----8-----8-----8-----8-----8-&lt;br /&gt;Gb|-------------------------------------------------&lt;br /&gt;Db|-------------------------------------------------&lt;br /&gt;Ab|-------------------------------------------------&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;&lt;br /&gt;Eb|-----3------3------3------3-&lt;br /&gt;Bb|-3h5----3h5----3h5----3h5---&lt;br /&gt;Gb|----------------------------&lt;br /&gt;Db|----------------------------&lt;br /&gt;Ab|----------------------------&lt;br /&gt;Eb|----------------------------&lt;br /&gt;&lt;br /&gt;                             Back into verse, let ring&lt;br /&gt;Eb|-------------------------|--&lt;br /&gt;Bb|-------------------------|--&lt;br /&gt;Gb|-3p0h3p0h3p0h3p0h3p0h3p0-|-0&lt;br /&gt;Db|-------------------------|--&lt;br /&gt;Ab|-------------------------|--&lt;br /&gt;Eb|-------------------------|--&lt;br /&gt;&lt;br /&gt;"Solo", on top of the chorus, goes something a little like:&lt;br /&gt;&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;Bb|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-&lt;br /&gt;Gb|-7-7-7-7-7-7-7-7-7-7-7-7-------------------------&lt;br /&gt;Db|-------------------------------------------------&lt;br /&gt;Ab|-------------------------------------------------&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;Bb|-------------------------------------------------&lt;br /&gt;Gb|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-&lt;br /&gt;Db|-7-7-7-7-7-7-7-7-7-7-7-7-------------------------&lt;br /&gt;Ab|-------------------------------------------------&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;Bb|-------------------------------------------------&lt;br /&gt;Gb|-------------------------------------------------&lt;br /&gt;Db|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-&lt;br /&gt;Ab|-7-7-7-7-7-7-7-7-7-7-7-7-------------------------&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;&lt;br /&gt;Eb|-------------------------------------------------&lt;br /&gt;Bb|-------------------------------------------------&lt;br /&gt;Gb|-------------------------------------------------&lt;br /&gt;Db|-------------------------------------------------&lt;br /&gt;Ab|-5-5-5-5-5-5-3-3-3-3-3-3-------------------------&lt;br /&gt;Eb|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-&lt;br /&gt;&lt;br /&gt;End part is in 4/4 and goes:&lt;br /&gt;&lt;br /&gt;Ab5&lt;br /&gt;Gb5&lt;br /&gt;Cb5&lt;br /&gt;Db5&lt;br /&gt;&lt;br /&gt;That's it!&lt;br /&gt;&lt;br /&gt;The chords:&lt;br /&gt;&lt;br /&gt;Ab7&lt;br /&gt;Eb 0&lt;br /&gt;Bb 2&lt;br /&gt;Gb 0&lt;br /&gt;Db 2&lt;br /&gt;Ab 0&lt;br /&gt;Eb x&lt;br /&gt;&lt;br /&gt;Gb6&lt;br /&gt;Eb 0&lt;br /&gt;Bb 3&lt;br /&gt;Gb 0&lt;br /&gt;Db 0&lt;br /&gt;Ab x&lt;br /&gt;Eb 3&lt;br /&gt;&lt;br /&gt;(Weird) Cb7&lt;br /&gt;Eb x&lt;br /&gt;Bb x&lt;br /&gt;Gb 3&lt;br /&gt;Db 5&lt;br /&gt;Ab 3&lt;br /&gt;Eb x&lt;br /&gt;&lt;br /&gt;Powerchords (Fifths)&lt;br /&gt;&lt;br /&gt;Ab5&lt;br /&gt;Eb x&lt;br /&gt;Bb x&lt;br /&gt;Gb x&lt;br /&gt;Db 2&lt;br /&gt;Ab 0&lt;br /&gt;Eb x&lt;br /&gt;&lt;br /&gt;Gb5&lt;br /&gt;Eb x&lt;br /&gt;Bb x&lt;br /&gt;Gb x&lt;br /&gt;Db x&lt;br /&gt;Ab 5&lt;br /&gt;Eb 3&lt;br /&gt;&lt;br /&gt;Cb5&lt;br /&gt;Eb x&lt;br /&gt;Bb x&lt;br /&gt;Gb x&lt;br /&gt;Db 5&lt;br /&gt;Ab 3&lt;br /&gt;Eb x&lt;br /&gt;&lt;br /&gt;Db5&lt;br /&gt;&lt;br /&gt;Eb x&lt;br /&gt;Bb x&lt;br /&gt;Gb x&lt;br /&gt;Db 7&lt;br /&gt;Ab 5&lt;br /&gt;Eb x&lt;br /&gt;&lt;br /&gt;Have a lot of fun :)&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-2120490674251618310?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/2120490674251618310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/12/positive-about-negative-aberdonian.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2120490674251618310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2120490674251618310'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/12/positive-about-negative-aberdonian.html' title='Positive About Negative Aberdonian Crusty'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5149463540600271562</id><published>2010-12-07T12:13:00.003Z</published><updated>2010-12-07T12:33:16.752Z</updated><title type='text'>Wireworld</title><content type='html'>On my quest for enlightenment, I have completed the &lt;a href='http://rosettacode.org/wiki/Wireworld'&gt;Wireworld cellular automaton task on Rosetta code&lt;/a&gt;.  Smalltalk wasn't on the list, so I gave learning &lt;a href='http://smalltalk.gnu.org/'&gt;GNU Smalltalk&lt;/a&gt; a try, and I experienced some success in this!&lt;br /&gt;&lt;br /&gt;I find cellular automata fascinating.  It's just the biological nature of it - that it can grow, and where there was previously no life, something suddenly exists!  I digress, but there are interesting applications for more traditional mathematics (like &lt;a href='http://www.thebigblob.com/moore-neighbor-contour-tracing-algorithm-in-c/'&gt;finding the contour of the graph&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;However, my solution is a bit big - in fact, it's written in both Smalltalk and C, and generates animated GIFs.&lt;br /&gt;&lt;br /&gt;&lt;img src='https://github.com/elginer/jwgif/raw/master/3cycle.gif' alt='Wireworld animation' /&gt;&lt;br /&gt;&lt;br /&gt;Also I wanted to write a nice flexible bit of software in Smalltalk, to learn it properly and to find why those in my books rate it so highly, so aye, it grew a bit.&lt;br /&gt;&lt;br /&gt;Anyway, here is the README so you can find out about it, with an additional link to the source added there.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;NAME &lt;br /&gt;   &lt;a href='https://github.com/elginer/jwgif'&gt;jwgif&lt;/a&gt; - Johnny's Wireworld GIF creator.&lt;br /&gt;&lt;br /&gt;ABOUT&lt;br /&gt;&lt;br /&gt;   jwgif is a simulator for the Wireworld cellular automaton.  It renders to an animated GIF,&lt;br /&gt;   which it sends to stdout.&lt;br /&gt;&lt;br /&gt;REQUIREMENTS&lt;br /&gt;&lt;br /&gt;   gcc&lt;br /&gt;   GNU Plotutils&lt;br /&gt;   GNU Smalltalk&lt;br /&gt;&lt;br /&gt;COMPILATION&lt;br /&gt;&lt;br /&gt;   ./compile.sh&lt;br /&gt;&lt;br /&gt;USAGE&lt;br /&gt;   &lt;br /&gt;   jwgif FILENAME GENERATIONS WIDTH HEIGHT SQUARESIZE&lt;br /&gt;&lt;br /&gt;OPTIONS&lt;br /&gt;&lt;br /&gt;   FILENAME is a path to a Wireworld file - see WIREWORLD FILE FORMAT below.&lt;br /&gt;&lt;br /&gt;   The following must be positive integers:&lt;br /&gt;&lt;br /&gt;   GENERATIONS determines the number of frames produced.&lt;br /&gt;   WIDTH the width of the output GIF, in pixels.&lt;br /&gt;   HEIGHT the height of the output GIF, in pixels.&lt;br /&gt;   SQUARESIZE the size of the square cells, in pixels.&lt;br /&gt;&lt;br /&gt;EXAMPLE&lt;br /&gt;&lt;br /&gt;   ./jwgif arena/cyc3inhib.ww 200 110 50 10 &amp;gt; 3cycle.gif&lt;br /&gt;&lt;br /&gt;WIREWORLD FILE FORMAT&lt;br /&gt;&lt;br /&gt;   Wireworld is a cellular automaton with some similarities to Conway's Game of Life. It is &lt;br /&gt;   capable of doing sophisticated computations (e.g., calculating primeness!) with appropriate&lt;br /&gt;   programs, and is much simpler to program for.&lt;br /&gt;&lt;br /&gt;   A wireworld arena consists of a cartesian grid of cells, each of which can be in one of &lt;br /&gt;   four states. All cell transitions happen simultaneously. The cell transition rules are this:&lt;br /&gt;&lt;br /&gt;   Input State       Output State      Condition&lt;br /&gt;   empty             empty  &lt;br /&gt;   electron head     electron tail   &lt;br /&gt;   electron tail     conductor  &lt;br /&gt;   conductor         electron head     if 1 or 2 cells in the neighborhood of the cell are in the state “electron head”&lt;br /&gt;   conductor         conductor         otherwise&lt;br /&gt;&lt;br /&gt;   A Wireworld program can be stored in a file using the following notation:&lt;br /&gt;   &lt;br /&gt;   "H" for an electron head&lt;br /&gt;   "t" for a tail&lt;br /&gt;   "." for a conductor&lt;br /&gt;   space for empty.&lt;br /&gt;   &lt;br /&gt;   Here is an example program, which demonstrates two cycle-3 generators and an inhibit gate:&lt;br /&gt;&lt;br /&gt;   tH.........&lt;br /&gt;   .   .&lt;br /&gt;      ...&lt;br /&gt;   .   .&lt;br /&gt;   Ht.. ......&lt;br /&gt;&lt;br /&gt;   The output for this program is included with the jwgif distribution, with the file name 3cycle.gif&lt;br /&gt;&lt;br /&gt;   jwgif uses the following convention for colouring cells in the output GIF:&lt;br /&gt;&lt;br /&gt;   An electron head is red.&lt;br /&gt;   A tail is blue.&lt;br /&gt;   A conductor is green.&lt;br /&gt;   Empty cells are black.&lt;br /&gt;&lt;br /&gt;   This section was ripped off from &lt;a href="http://rosettacode.org/wiki/Wireworld"&gt;http://rosettacode.org/wiki/Wireworld&lt;/a&gt; on 6th December 2010.  Thanks guys!&lt;br /&gt;&lt;br /&gt;LICENSE&lt;br /&gt;&lt;br /&gt;   jwgif is free software: you can redistribute it and/or modify&lt;br /&gt;   it under the terms of the GNU General Public License as published by&lt;br /&gt;   the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;   (at your option) any later version.&lt;br /&gt;&lt;br /&gt;   jwgif is distributed in the hope that it will be useful,&lt;br /&gt;   but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;   GNU General Public License for more details.&lt;br /&gt;&lt;br /&gt;   You should have received a copy of the GNU General Public License&lt;br /&gt;   along with jwgif.  If not, see &amp;lt;&lt;a href="http://www.gnu.org/licenses/"&gt;http://www.gnu.org/licenses/&lt;/a&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5149463540600271562?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5149463540600271562/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/12/wireworld.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5149463540600271562'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5149463540600271562'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/12/wireworld.html' title='Wireworld'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7820386771399598552</id><published>2010-12-07T12:01:00.005Z</published><updated>2010-12-07T12:13:31.907Z</updated><title type='text'>Studying</title><content type='html'>So I got CARPS text mode stable, and I have plans to create a graphical version.  &lt;br /&gt;&lt;br /&gt;At 10ksloc and with client, server, superserver, use of maths and support for modding, it is the largest and most complex project I've forced to stagger into some sort of fruition.  And I faced so many problems, encountered so many things, and I learned this:&lt;br /&gt;&lt;br /&gt;I suck!  Oh god, I suck.  There are so many reasons why I suck, and thankfully I have learned some of them.&lt;br /&gt;&lt;br /&gt;So I had a bit of a think, and decided that before I do any more development on this, I really need to improve.  I really like the &lt;a href='http://rosettacode.org'&gt;Rosetta Code&lt;/a&gt; website!  It challenges you to solve tasks in a language of your choice. So I'm going to spend my time learning some new languages, and solving some interesting problems.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7820386771399598552?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7820386771399598552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/12/studying-and-wireworld.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7820386771399598552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7820386771399598552'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/12/studying-and-wireworld.html' title='Studying'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7368518601091940369</id><published>2010-11-11T00:33:00.005Z</published><updated>2010-11-11T00:42:30.660Z</updated><title type='text'>CARPS</title><content type='html'>Wow, I appear to have finally put out a stable release of CARPS!&lt;br /&gt;&lt;br /&gt;From the &lt;a href="http://github.com/elginer/carps"&gt;CARPS README&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;CARPS, the Computer Assisted Role-Playing Game System, is a tool for playing pen and paper RPGs over the internet.&lt;br /&gt;&lt;br /&gt;CARPS differs from other such systems because CARPS is not a ‘real-time’ system. It suits people who want to log on once or twice a day, take a turn, and then log out again. While OpenRPG could be described as being similar to a chat-room, CARPS is more similar to an email client.&lt;br /&gt;&lt;br /&gt;CARPS is an extensible system: game rules are provided by ‘mods’.&lt;br /&gt;&lt;br /&gt;CARPS supports these mods by providing:&lt;br /&gt;&lt;br /&gt;    * Text-mode user interfaces for the players and the dungeon master.&lt;br /&gt;    * An easy to use probabilistic API which not only rolls the dice, but can report the probability of various game events occurring.&lt;br /&gt;    * Automated static character sheet verification, according to a schema defined in YAML. For example, a game might require your strength to be an integer.&lt;br /&gt;    * Support for the semantic validation of character sheets according to game rules. For example, a game might require the sum of character’s attributes to be below a certain maximum value.&lt;br /&gt;    * Together the validation features allow a mod writer to encode game rules cleanly, as they do not need to consider the possibility of receiving an invalid sheet.&lt;br /&gt;&lt;br /&gt;CARPS has other strengths:&lt;br /&gt;&lt;br /&gt;    * Anyone can play or host a CARPS game! All you need is an email account.&lt;br /&gt;    * CARPS is designed to be secure. Multiple email security options are supported, and all CARPS messages are cryptographically signed to prevent spoofing.&lt;br /&gt;    * You can instruct CARPS to use your favourite text editor and terminal emulator.&lt;br /&gt;    * CARPS is easy to configure because it includes a wizard.&lt;br /&gt;&lt;br /&gt;However, CARPS is new and the following features, which you might take for granted, are not yet supported:&lt;br /&gt;&lt;br /&gt;    * No GUI&lt;br /&gt;    * No support for maps&lt;br /&gt;    * No chat - all communication goes through the Game Master.&lt;br /&gt;    * Games are currently invite only, at the discretion of the Game Master.&lt;br /&gt;    * Security mechanisms are not well audited.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Requirements:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;For users:&lt;br /&gt;&lt;br /&gt;    * GNU/Linux&lt;br /&gt;    * ruby 1.9&lt;br /&gt;    * rubygems&lt;br /&gt;    * openssl&lt;br /&gt;    * highline&lt;br /&gt;&lt;br /&gt;For developing CARPS, you will also need:&lt;br /&gt;&lt;br /&gt;    * hoe&lt;br /&gt;    * rake&lt;br /&gt;    * newgem&lt;br /&gt;    * cucumber&lt;br /&gt;&lt;br /&gt;&lt;b&gt;To Install:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: white"&gt;&lt;br /&gt;# Install the gem&lt;br /&gt;&lt;br /&gt;sudo gem install carps&lt;br /&gt;&lt;br /&gt;# Initialize the carps user directory. Run this as your everyday user.&lt;br /&gt;&lt;br /&gt;carps_init&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Basic Instructions:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Run carps -h for help&lt;br /&gt;&lt;br /&gt;The first time CARPS is run, it will launch a wizard to help you configure your email settings, and choose a text editor and a terminal emulator.&lt;br /&gt;&lt;br /&gt;It is a good idea to specify a terminal emulator, as then CARPS can launch a mod in a new window (or similar). Then the first CARPS window will act as an email logger, letting you see when you receive mails, without interfering with the text you type into the new window.&lt;br /&gt;&lt;br /&gt;You’re also going to need to install a mod to play CARPS. See the example ‘fools’ mod:&lt;br /&gt;&lt;br /&gt;    * github.com/elginer/fools&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Campaigns (For the DM):&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;When you set up a new game, CARPS will ask for you to enter the name of a campaign.&lt;br /&gt;&lt;br /&gt;This allows you to create game resources prior to starting a game.&lt;br /&gt;&lt;br /&gt;For example, the following applies if your mod is called foo, the campaign is called bar, and your carps user data directory is /home/user/carps&lt;br /&gt;&lt;br /&gt;You should create the following directories&lt;br /&gt;&lt;br /&gt;the campaign directory:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: white"&gt;&lt;br /&gt;/home/user/carps/dm/campaigns/foo/bar&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;the NPCSs directory:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: white"&gt;&lt;br /&gt;/home/user/carps/dm/campaigns/foo/bar/npcs&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;the rooms directory:&lt;br /&gt;&lt;br /&gt;&lt;div style="background-color: white"&gt;&lt;br /&gt;/home/user/carps/dm/campaigns/foo/bar/rooms&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;NPCs are defined as YAML files, according to the mod’s schema. Put them in the NPCs directory. They MUST have the .yaml extension.&lt;br /&gt;&lt;br /&gt;Rooms are defined as text files. These are just predefined pieces of prose that the DM will send to the players when they enter a room, for instance. Put them in the rooms directory. They MUST have the .txt extension. &lt;br /&gt;&lt;br /&gt;I'm gonna spend the next little while trying to organise a play session, working on the windows port, and then trying to create a &lt;a href="http://www.d20srd.org/"&gt;DND D20&lt;/a&gt; mod for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7368518601091940369?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7368518601091940369/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/11/carps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7368518601091940369'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7368518601091940369'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/11/carps.html' title='CARPS'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5595655088707749116</id><published>2010-10-25T19:47:00.003+01:00</published><updated>2010-10-25T19:48:56.551+01:00</updated><title type='text'>Esperanto X-System fun</title><content type='html'>A friend of mine asked me to make a tiny website for them:  it converts between Esperanto X-System in ASCII and the unicode characters.&lt;br /&gt;&lt;br /&gt;It's a it of fun.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://killersmurf.com/xsystem.html"&gt;Here you go.&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There isn't much to it but I am smug at how neat and tidy the html and javascript looks :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5595655088707749116?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5595655088707749116/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/10/esperanto-x-system-fun.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5595655088707749116'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5595655088707749116'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/10/esperanto-x-system-fun.html' title='Esperanto X-System fun'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-6369213254284895619</id><published>2010-09-22T15:30:00.005+01:00</published><updated>2010-09-22T16:00:45.125+01:00</updated><title type='text'>PROGRAMMER KEYBOARD</title><content type='html'>EDIT:  fixed a bug!  Results should be good now :)  Damn, why did I forget to run the tests :p&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Computer keyboards are fucking stupid, especially for programmers.&lt;br /&gt;&lt;br /&gt;They fuck everyone too: QWERTY is so we don't jam the machinery. Even dvorak keyboards have staggered keys so the MECHANICAL arms can reach them.&lt;br /&gt;&lt;br /&gt;However, as programmers, we use all sorts of symbols not in the ken of mere mortals (like *). And for most, you have to press shift just to get at them.&lt;br /&gt;&lt;br /&gt;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA&lt;br /&gt;&lt;br /&gt;The solution: design a programmer keyboard!&lt;br /&gt;&lt;br /&gt;First off, we need some numbers so it can be known which keys are most often pressed. To do this I wrote a key frequency program*. I then used it to find the key frequencies of the source files of a number of different programs, in various languages. These are:&lt;br /&gt;&lt;br /&gt;linux - C&lt;br /&gt;adagide - ada&lt;br /&gt;axiom - c#&lt;br /&gt;django - python&lt;br /&gt;ghc - haskell&lt;br /&gt;go - go&lt;br /&gt;irrlicht - c++&lt;br /&gt;limewire - java&lt;br /&gt;phpbb3 - php&lt;br /&gt;prototype and jquery - javascript&lt;br /&gt;rails - ruby&lt;br /&gt;regexkit - objective c&lt;br /&gt;racket - racket&lt;br /&gt;&lt;br /&gt;To simplify things, I only considered characters ASCII characters between horizontal tab (ASCII 9) and '~' (ASCII 126). These are usually the ones I type, at least.&lt;br /&gt;&lt;br /&gt;My hypothesis is that many symbols are going to be more popular than letters. This would prove a need for these symbols to have their OWN FUCKING KEYS instead of being the hangers on and miscreants of the keyboard world.&lt;br /&gt;&lt;br /&gt;Here are the results of my analysis. The character is on the left, the fraction of the whole is on the right. They are presented in descending order of popularity.&lt;br /&gt;&lt;br /&gt;' ': 0.12601734868442382&lt;br /&gt;'e': 5.672758827442585e-2&lt;br /&gt;'t': 4.506425247731305e-2&lt;br /&gt;'i': 3.6282361484752744e-2&lt;br /&gt;'r': 3.5587647133639044e-2&lt;br /&gt;'\t': 3.52634742130502e-2&lt;br /&gt;'\n': 3.45691915152049e-2&lt;br /&gt;'_': 3.438222642926237e-2&lt;br /&gt;'s': 3.201379627014596e-2&lt;br /&gt;'n': 3.0954960014858875e-2&lt;br /&gt;'a': 3.058217872499613e-2&lt;br /&gt;'o': 2.6776405034843204e-2&lt;br /&gt;'c': 2.3632039961301494e-2&lt;br /&gt;'d': 2.329124049378265e-2&lt;br /&gt;'l': 1.9319481645750994e-2&lt;br /&gt;'u': 1.761928496254444e-2&lt;br /&gt;'0': 1.737397825253189e-2&lt;br /&gt;'p': 1.6228575776688497e-2&lt;br /&gt;'f': 1.5556196850182672e-2&lt;br /&gt;',': 1.4572080038859849e-2&lt;br /&gt;'*': 1.3460275453084754e-2&lt;br /&gt;'m': 1.2857509828221805e-2&lt;br /&gt;')': 1.2389877996691128e-2&lt;br /&gt;'(': 1.2383996720909098e-2&lt;br /&gt;';': 1.140731013627353e-2&lt;br /&gt;'h': 1.0710680981789305e-2&lt;br /&gt;'-': 1.0232090684508581e-2&lt;br /&gt;'x': 1.0086694597923173e-2&lt;br /&gt;'g': 9.400323788643899e-3&lt;br /&gt;'b': 8.972889667733516e-3&lt;br /&gt;'E': 8.898045202243342e-3&lt;br /&gt;'=': 8.357994322825149e-3&lt;br /&gt;'v': 7.983041606459754e-3&lt;br /&gt;'S': 7.407318795659219e-3&lt;br /&gt;'T': 7.301129459599258e-3&lt;br /&gt;'R': 7.1601262346295165e-3&lt;br /&gt;'/': 7.1380145327522146e-3&lt;br /&gt;'A': 7.117130673860958e-3&lt;br /&gt;'I': 7.099489478546994e-3&lt;br /&gt;'C': 6.66979575805779e-3&lt;br /&gt;'&gt;': 6.316573098911656e-3&lt;br /&gt;'.': 5.726058267571846e-3&lt;br /&gt;'1': 5.685534184968124e-3&lt;br /&gt;'N': 5.413383379318554e-3&lt;br /&gt;'D': 5.24449377399052e-3&lt;br /&gt;'P': 5.0353985619458206e-3&lt;br /&gt;'L': 5.008180717747133e-3&lt;br /&gt;'O': 5.000104327173332e-3&lt;br /&gt;'k': 4.9537792457673745e-3&lt;br /&gt;'w': 4.742584988103445e-3&lt;br /&gt;'y': 4.725471515230428e-3&lt;br /&gt;'2': 4.638324931590688e-3&lt;br /&gt;'M': 4.5006262229531635e-3&lt;br /&gt;'"': 3.800355652024797e-3&lt;br /&gt;'F': 3.764420517430011e-3&lt;br /&gt;'U': 3.1530152471186336e-3&lt;br /&gt;'{': 3.055959062530431e-3&lt;br /&gt;'}': 3.0551233923309254e-3&lt;br /&gt;'B': 3.0211399095564015e-3&lt;br /&gt;'3': 2.9180155749053346e-3&lt;br /&gt;'G': 2.7770136659516554e-3&lt;br /&gt;'4': 2.5617397584948654e-3&lt;br /&gt;'8': 2.3449629606950287e-3&lt;br /&gt;'#': 2.2478633475767726e-3&lt;br /&gt;'&amp;': 2.2210126718594423e-3&lt;br /&gt;'6': 2.162497333669207e-3&lt;br /&gt;':': 1.9414777000847955e-3&lt;br /&gt;'H': 1.8788563917804559e-3&lt;br /&gt;'q': 1.8209240487057808e-3&lt;br /&gt;'&lt;': 1.6977541573950867e-3&lt;br /&gt;'5': 1.6778586265665519e-3&lt;br /&gt;'V': 1.665461755260506e-3&lt;br /&gt;'\\': 1.5621847627462226e-3&lt;br /&gt;'X': 1.4939677541453535e-3&lt;br /&gt;'[': 1.4782940028443977e-3&lt;br /&gt;']': 1.4776491549739134e-3&lt;br /&gt;'+': 1.4496245929290891e-3&lt;br /&gt;'9': 1.3384093915275372e-3&lt;br /&gt;'7': 1.3184046313658388e-3&lt;br /&gt;'W': 1.2953598741004282e-3&lt;br /&gt;'K': 1.2184137309589008e-3&lt;br /&gt;'z': 1.2113717290099994e-3&lt;br /&gt;'\r': 1.143696919026762e-3&lt;br /&gt;'\'': 1.0093106228178275e-3&lt;br /&gt;'Y': 9.986745810030226e-4&lt;br /&gt;'|': 9.358519222411643e-4&lt;br /&gt;'%': 8.897926760797742e-4&lt;br /&gt;'!': 7.546115061692628e-4&lt;br /&gt;'j': 6.665502913662852e-4&lt;br /&gt;'Q': 4.7705713856824653e-4&lt;br /&gt;'Z': 3.924557299928266e-4&lt;br /&gt;'@': 3.550282331834911e-4&lt;br /&gt;'?': 1.816549611314985e-4&lt;br /&gt;'$': 1.7383124564164268e-4&lt;br /&gt;'J': 1.5937875724642036e-4&lt;br /&gt;'~': 1.2080895849508404e-4&lt;br /&gt;'^': 3.6191757726917574e-5&lt;br /&gt;'`': 3.1301442039734356e-5&lt;br /&gt;'\f': 3.8032864197953453e-7&lt;br /&gt;'\ESC': 5.264064248851689e-9&lt;br /&gt;Total characters: 759869145&lt;br /&gt;&lt;br /&gt;You suck \ESC.  No one loves you!&lt;br /&gt;&lt;br /&gt;Note that the total does not reflect the number of characters I ignored ala the last paragraph.&lt;br /&gt;&lt;br /&gt;It's interesting to observe that _ is a rather popular character for programmers indeed! Also it is interesting that * and , are both more popular than m.&lt;br /&gt;&lt;br /&gt;By far the most interesting thing to note is that '(' is more popular than ')'. Don't they come in pairs?&lt;br /&gt;&lt;br /&gt;The next step is to design a keyboard layout which makes it easy for people to type the more popular characters. I think I will do this by experimentation - how easy it it to type various phrases? Some research is available on the topic, but a lot of things are easy to get, eg:&lt;br /&gt;&lt;br /&gt;Most people are right handed.&lt;br /&gt;Your index fingers are stronger than your pinkies.&lt;br /&gt;&lt;br /&gt;Hence, you're gonna want the most used keys in the middle-right of the keyboard.&lt;br /&gt;&lt;br /&gt;The last step is to actually make the bastarding thing.&lt;br /&gt;&lt;br /&gt;I'm not exactly sure on the best way to actually create a keyboard. With enough time, I could design a program which would run on a microcontroller, interface with the keyboard matrix and communicate with the pc over PS/2.&lt;br /&gt;&lt;br /&gt;However, that sounds complicated. Perhaps I shall just move the keys around (but how to put enter and tab in the middle?), and see if I can make it work under Xorg and the terminal.&lt;br /&gt;&lt;br /&gt;* The program is split into two parts.&lt;br /&gt;&lt;br /&gt;frequency.hs:&lt;br /&gt;&lt;br /&gt;--&amp;nbsp;Copyright&amp;nbsp;John&amp;nbsp;Morrice&amp;nbsp;2010.&lt;br /&gt;--&amp;nbsp;Distributed&amp;nbsp;under&amp;nbsp;the&amp;nbsp;terms&amp;nbsp;of&amp;nbsp;the&amp;nbsp;GNU&amp;nbsp;General&amp;nbsp;Public&amp;nbsp;License&amp;nbsp;v&amp;nbsp;3&lt;br /&gt;&lt;br /&gt;{-#&amp;nbsp;LANGUAGE&amp;nbsp;BangPatterns&amp;nbsp;#-}&lt;br /&gt;&lt;br /&gt;module&amp;nbsp;Main&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(freq_test&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;,file_test&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;,main)&amp;nbsp;where&lt;br /&gt;&lt;br /&gt;--&amp;nbsp;|&amp;nbsp;GHC&amp;nbsp;haskell&amp;nbsp;key&amp;nbsp;frequency&amp;nbsp;program&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;Control.Monad&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;qualified&amp;nbsp;Data.ByteString.Lazy.Char8&amp;nbsp;as&amp;nbsp;Z&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;qualified&amp;nbsp;Data.ByteString.Char8&amp;nbsp;as&amp;nbsp;B&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;Data.Array.MArray&lt;br /&gt;import&amp;nbsp;Data.Array.IO&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;Data.List&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;System.IO&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;System.Posix.Process&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;System.Environment&lt;br /&gt;&lt;br /&gt;import&amp;nbsp;GHC.Int&lt;br /&gt;&lt;br /&gt;main&amp;nbsp;::&amp;nbsp;IO&amp;nbsp;()&lt;br /&gt;main&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;as&amp;nbsp;&lt;-&amp;nbsp;getArgs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;length&amp;nbsp;as&amp;nbsp;/=&amp;nbsp;1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;error&amp;nbsp;"Usage:&amp;nbsp;frequency&amp;nbsp;DIR"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;dir&amp;nbsp;=&amp;nbsp;head&amp;nbsp;as&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;prgs&amp;nbsp;&lt;-&amp;nbsp;find_prgs&amp;nbsp;dir&amp;nbsp;program_exts&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;contents&amp;nbsp;&lt;-&amp;nbsp;fmap&amp;nbsp;Z.concat&amp;nbsp;$&amp;nbsp;mapM&amp;nbsp;strict_read&amp;nbsp;prgs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(freq,&amp;nbsp;total)&amp;nbsp;&lt;-&amp;nbsp;frequency&amp;nbsp;contents&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;format_frequency&amp;nbsp;freq&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;putStrLn&amp;nbsp;$&amp;nbsp;"Total&amp;nbsp;characters:&amp;nbsp;"&amp;nbsp;++&amp;nbsp;show&amp;nbsp;total&lt;br /&gt;&lt;br /&gt;strict_read&amp;nbsp;::&amp;nbsp;FilePath&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;Z.ByteString&lt;br /&gt;strict_read&amp;nbsp;fp&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;contents&amp;nbsp;&lt;-&amp;nbsp;B.readFile&amp;nbsp;fp&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;$&amp;nbsp;Z.fromChunks&amp;nbsp;[contents]&lt;br /&gt;&lt;br /&gt;format_frequency&amp;nbsp;::&amp;nbsp;IOArray&amp;nbsp;Char&amp;nbsp;Double&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;()&lt;br /&gt;format_frequency&amp;nbsp;ma&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;as&amp;nbsp;&lt;-&amp;nbsp;getAssocs&amp;nbsp;ma&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;sorted&amp;nbsp;=&amp;nbsp;reverse&amp;nbsp;$&amp;nbsp;sortBy&amp;nbsp;(\(_,fr1)&amp;nbsp;(_,fr2)&amp;nbsp;-&gt;&amp;nbsp;fr1&amp;nbsp;`compare`&amp;nbsp;fr2)&amp;nbsp;as&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapM_&amp;nbsp;(\&amp;nbsp;(ch,fr)&amp;nbsp;-&gt;&amp;nbsp;putStrLn&amp;nbsp;$&amp;nbsp;(show&amp;nbsp;ch)&amp;nbsp;++&amp;nbsp;":&amp;nbsp;"&amp;nbsp;++&amp;nbsp;show&amp;nbsp;fr)&amp;nbsp;sorted&lt;br /&gt;&lt;br /&gt;freq_test&amp;nbsp;::&amp;nbsp;IO&amp;nbsp;Bool&lt;br /&gt;freq_test&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;d&amp;nbsp;&lt;-&amp;nbsp;freq_data&amp;nbsp;&gt;&gt;=&amp;nbsp;getAssocs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;roccs&amp;nbsp;&lt;-&amp;nbsp;new_occs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;right&amp;nbsp;&lt;-&amp;nbsp;mapArray&amp;nbsp;fromIntegral&amp;nbsp;roccs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeArray&amp;nbsp;right&amp;nbsp;'e'&amp;nbsp;0.5&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeArray&amp;nbsp;right&amp;nbsp;'d'&amp;nbsp;(3/8)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeArray&amp;nbsp;right&amp;nbsp;'a'&amp;nbsp;(1/8)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;rightl&amp;nbsp;&lt;-&amp;nbsp;getAssocs&amp;nbsp;right&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;$&amp;nbsp;d&amp;nbsp;==&amp;nbsp;rightl&lt;br /&gt;&lt;br /&gt;freq_data&amp;nbsp;::&amp;nbsp;IO&amp;nbsp;(IOArray&amp;nbsp;Char&amp;nbsp;Double)&lt;br /&gt;freq_data&amp;nbsp;=&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmap&amp;nbsp;fst&amp;nbsp;$&amp;nbsp;frequency&amp;nbsp;freq_input&lt;br /&gt;&lt;br /&gt;freq_input&amp;nbsp;::&amp;nbsp;Z.ByteString&lt;br /&gt;freq_input&amp;nbsp;=&amp;nbsp;Z.pack&amp;nbsp;"eeeeddda"&lt;br /&gt;&lt;br /&gt;file_test&amp;nbsp;::&amp;nbsp;IO&amp;nbsp;Bool&lt;br /&gt;file_test&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;files&amp;nbsp;&lt;-&amp;nbsp;fmap&amp;nbsp;sort&amp;nbsp;$&amp;nbsp;find_prgs&amp;nbsp;"test_files"&amp;nbsp;["c",&amp;nbsp;"rb"]&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;putStrLn&amp;nbsp;"Found:"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;files&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;expected&amp;nbsp;=&amp;nbsp;sort&amp;nbsp;(actual&amp;nbsp;"test_files/")&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;putStrLn&amp;nbsp;"Expected"&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;print&amp;nbsp;expected&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;$&amp;nbsp;files&amp;nbsp;==&amp;nbsp;expected&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;where&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;actual&amp;nbsp;dir&amp;nbsp;=&amp;nbsp;map&amp;nbsp;(dir&amp;nbsp;++)&amp;nbsp;["a.c",&amp;nbsp;"b.c",&amp;nbsp;"c.rb",&amp;nbsp;"d.rb"]&lt;br /&gt;&lt;br /&gt;--&amp;nbsp;|&amp;nbsp;Determine&amp;nbsp;the&amp;nbsp;frequency&amp;nbsp;of&amp;nbsp;characters&amp;nbsp;in&amp;nbsp;a&amp;nbsp;bytestring&amp;nbsp;as&amp;nbsp;a&amp;nbsp;fraction&amp;nbsp;of&amp;nbsp;the&amp;nbsp;whole&lt;br /&gt;frequency&amp;nbsp;::&amp;nbsp;Z.ByteString&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;(IOArray&amp;nbsp;Char&amp;nbsp;Double,&amp;nbsp;Int64)&lt;br /&gt;frequency&amp;nbsp;by&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fr&amp;nbsp;&lt;-&amp;nbsp;occur&amp;nbsp;by&amp;nbsp;&gt;&gt;=&amp;nbsp;mapArray&amp;nbsp;(\o&amp;nbsp;-&gt;&amp;nbsp;fromIntegral&amp;nbsp;o&amp;nbsp;/&amp;nbsp;fromIntegral&amp;nbsp;total)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;(fr,&amp;nbsp;total)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;where&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;total&amp;nbsp;=&amp;nbsp;Z.length&amp;nbsp;by&lt;br /&gt;&lt;br /&gt;new_occs&amp;nbsp;::&amp;nbsp;IO&amp;nbsp;(IOArray&amp;nbsp;Char&amp;nbsp;Int64)&lt;br /&gt;new_occs&amp;nbsp;=&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;newListArray&amp;nbsp;(min_char,&amp;nbsp;max_char)&amp;nbsp;(repeat&amp;nbsp;0)&lt;br /&gt;&lt;br /&gt;min_char&amp;nbsp;::&amp;nbsp;Char&lt;br /&gt;min_char&amp;nbsp;=&amp;nbsp;'\9'&lt;br /&gt;&lt;br /&gt;max_char&amp;nbsp;::&amp;nbsp;Char&lt;br /&gt;max_char&amp;nbsp;=&amp;nbsp;'\126'&lt;br /&gt;&lt;br /&gt;occur&amp;nbsp;::&amp;nbsp;Z.ByteString&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;(IOArray&amp;nbsp;Char&amp;nbsp;Int64)&lt;br /&gt;occur&amp;nbsp;bz&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;occs&amp;nbsp;&lt;-&amp;nbsp;new_occs&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;zfoldrM&amp;nbsp;increase&amp;nbsp;occs&amp;nbsp;bz&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;where&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;increase&amp;nbsp;::&amp;nbsp;Char&amp;nbsp;-&gt;&amp;nbsp;IOArray&amp;nbsp;Char&amp;nbsp;Int64&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;increase&amp;nbsp;ch&amp;nbsp;oc&amp;nbsp;=&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;ch&amp;nbsp;&gt;=&amp;nbsp;min_char&amp;nbsp;&amp;&amp;&amp;nbsp;ch&amp;nbsp;&lt;=&amp;nbsp;max_char&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;count&amp;nbsp;&lt;-&amp;nbsp;readArray&amp;nbsp;oc&amp;nbsp;ch&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;let&amp;nbsp;n&amp;nbsp;=&amp;nbsp;count&amp;nbsp;+&amp;nbsp;1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;n&amp;nbsp;`seq`&amp;nbsp;writeArray&amp;nbsp;oc&amp;nbsp;ch&amp;nbsp;n&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;()&lt;br /&gt;&lt;br /&gt;zfoldrM&amp;nbsp;::&amp;nbsp;(Char&amp;nbsp;-&gt;&amp;nbsp;IOArray&amp;nbsp;Char&amp;nbsp;Int64&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;())&amp;nbsp;-&gt;&amp;nbsp;IOArray&amp;nbsp;Char&amp;nbsp;Int64&amp;nbsp;-&gt;&amp;nbsp;Z.ByteString&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;(IOArray&amp;nbsp;Char&amp;nbsp;Int64)&amp;nbsp;&lt;br /&gt;zfoldrM&amp;nbsp;f&amp;nbsp;ar&amp;nbsp;bz&amp;nbsp;=&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;Z.null&amp;nbsp;bz&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then&amp;nbsp;return&amp;nbsp;ar&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;f&amp;nbsp;(Z.head&amp;nbsp;bz)&amp;nbsp;ar&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;zfoldrM&amp;nbsp;f&amp;nbsp;ar&amp;nbsp;(Z.tail&amp;nbsp;bz)&lt;br /&gt;&lt;br /&gt;program_exts&amp;nbsp;::&amp;nbsp;[String]&lt;br /&gt;program_exts&amp;nbsp;=&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;["bas",&amp;nbsp;--&amp;nbsp;basic&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"java",&amp;nbsp;--&amp;nbsp;java&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"hs",&amp;nbsp;--&amp;nbsp;haskell&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"rb",&amp;nbsp;--&amp;nbsp;ruby&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"py",&amp;nbsp;--&amp;nbsp;python&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"php",&amp;nbsp;--&amp;nbsp;php&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"m",&amp;nbsp;--&amp;nbsp;objective&amp;nbsp;c&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"c",&amp;nbsp;"h",&amp;nbsp;--&amp;nbsp;c&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"cs",&amp;nbsp;--&amp;nbsp;c#&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"js",&amp;nbsp;--&amp;nbsp;javascript&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"ads",&amp;nbsp;"adb",&amp;nbsp;--&amp;nbsp;ada&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"cxx",&amp;nbsp;"cpp",&amp;nbsp;"c++",&amp;nbsp;--&amp;nbsp;c++&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"scm",&amp;nbsp;--&amp;nbsp;scheme,&amp;nbsp;racket&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"pas",&amp;nbsp;--&amp;nbsp;pascal,&amp;nbsp;delphi&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;"go"&amp;nbsp;--&amp;nbsp;go&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;]&lt;br /&gt;&lt;br /&gt;--&amp;nbsp;|&amp;nbsp;A&amp;nbsp;regular&amp;nbsp;expression&amp;nbsp;which&amp;nbsp;matches&amp;nbsp;files&amp;nbsp;with&amp;nbsp;the&amp;nbsp;given&amp;nbsp;extension&lt;br /&gt;extension_regex&amp;nbsp;::&amp;nbsp;String&amp;nbsp;-&gt;&amp;nbsp;String&lt;br /&gt;extension_regex&amp;nbsp;=&amp;nbsp;(".+\\."&amp;nbsp;++)&lt;br /&gt;&lt;br /&gt;--&amp;nbsp;|&amp;nbsp;Find&amp;nbsp;program&amp;nbsp;files&amp;nbsp;in&amp;nbsp;the&amp;nbsp;given&amp;nbsp;directory&amp;nbsp;matching&amp;nbsp;the&amp;nbsp;given&amp;nbsp;extensions&lt;br /&gt;find_prgs&amp;nbsp;::&amp;nbsp;String&amp;nbsp;-&gt;&amp;nbsp;[String]&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;[String]&lt;br /&gt;find_prgs&amp;nbsp;dir&amp;nbsp;exts&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeFile&amp;nbsp;"result"&amp;nbsp;""&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;mapM_&amp;nbsp;(find_prg&amp;nbsp;dir)&amp;nbsp;exts&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;fmap&amp;nbsp;lines&amp;nbsp;$&amp;nbsp;readFile&amp;nbsp;"result"&lt;br /&gt;&lt;br /&gt;---&amp;nbsp;|&amp;nbsp;Find&amp;nbsp;program&amp;nbsp;files&amp;nbsp;in&amp;nbsp;the&amp;nbsp;given&amp;nbsp;directory&amp;nbsp;matching&amp;nbsp;the&amp;nbsp;given&amp;nbsp;extension&lt;br /&gt;find_prg&amp;nbsp;::&amp;nbsp;String&amp;nbsp;-&gt;&amp;nbsp;String&amp;nbsp;-&gt;&amp;nbsp;IO&amp;nbsp;()&amp;nbsp;&lt;br /&gt;find_prg&amp;nbsp;dir&amp;nbsp;ext&amp;nbsp;=&amp;nbsp;do&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;pid&amp;nbsp;&lt;-&amp;nbsp;forkProcess&amp;nbsp;$&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;executeFile&amp;nbsp;"./finder.sh"&amp;nbsp;False&amp;nbsp;[dir,&amp;nbsp;"-regex",&amp;nbsp;extension_regex&amp;nbsp;ext]&amp;nbsp;Nothing&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;getProcessStatus&amp;nbsp;True&amp;nbsp;True&amp;nbsp;pid&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;-- Source ends with this line&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;finder.sh&lt;br /&gt;&lt;br /&gt;# Source begins with this line&lt;br /&gt;#! /bin/bash&lt;br /&gt;&lt;br /&gt;find $* &gt;&gt; result&lt;br /&gt;# Source ends with this line&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-6369213254284895619?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/6369213254284895619/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/programmer-keyboard_22.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6369213254284895619'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6369213254284895619'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/programmer-keyboard_22.html' title='PROGRAMMER KEYBOARD'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-6471798684029327130</id><published>2010-09-08T21:09:00.003+01:00</published><updated>2010-09-08T21:18:49.364+01:00</updated><title type='text'>JOrbit</title><content type='html'>I finished my last software engineering assignment today, and I needed to relax, so I &lt;span style="text-decoration: line-through;"&gt;wrote&lt;/span&gt;kludged &lt;a href="http://killersmurf.com/orbit.html"&gt;a little Orbit clone&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I used to love that game, so this afternoon I murdered it ;)&lt;br /&gt;&lt;br /&gt;To the best of my knowledge it only works on firefox! It does _not_ work on IE or opera.  And it has only been tested on firefox3.6 on windows and ubuntu (I don't have my cable on me to check with latest on gentoo)&lt;br /&gt;&lt;br /&gt;It's also full of bugs.  How many can you find?!&lt;br /&gt;&lt;br /&gt;Instructions:&lt;br /&gt;&lt;br /&gt;Attempt to hit the target&lt;br /&gt;Move the mouse to aim&lt;br /&gt;Press the left mouse button to charge&lt;br /&gt;Watch the force meter!&lt;br /&gt;Let go to fire&lt;br /&gt;If you get an impossible level just refresh&lt;br /&gt;&lt;br /&gt;If you want to see the code, there's &lt;a href="http://github.com/elginer/jorbit"&gt;the development repository&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's a total hack but I'm still pleased because:&lt;br /&gt;&lt;br /&gt;It's written entirely in javascript!  I use &lt;a href="http://raphaeljs.com/"&gt;raphael&lt;/a&gt; for rendering and &lt;a href="http://jquery.com/"&gt;jquery&lt;/a&gt; for lots of things&lt;br /&gt;&lt;br /&gt;It has proper physics, with gravity and everyfink&lt;br /&gt;&lt;br /&gt;I wrote it in an afternoon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-6471798684029327130?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/6471798684029327130/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/jorbit-johnnys-orbit-clone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6471798684029327130'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6471798684029327130'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/jorbit-johnnys-orbit-clone.html' title='JOrbit'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5632782378391220716</id><published>2010-09-07T00:58:00.002+01:00</published><updated>2010-09-07T01:02:38.855+01:00</updated><title type='text'>New look (again)</title><content type='html'>Just had a look at this on a windows machine and saw how fucked up it looked!  MY GOD IT HAD COMIC SANS.&lt;br /&gt;&lt;br /&gt;Despite the nasty fonts, my own fault, I'd forgotten how shitty everything looks on windows anyway.&lt;br /&gt;&lt;br /&gt;I've tried to make it have less of a contrast, as well, for the eye pain.&lt;br /&gt;&lt;br /&gt;Anyhoos, I set up a wiki on my local machine, with rails and &lt;a href="http://www.wagn.org/"&gt;wagn&lt;/a&gt;.  It's good because I know ruby pretty well, and I'm planning on modifying the thing ala last post's ideas.&lt;br /&gt;&lt;br /&gt;I've put on a boring sort of style - I better check it on windows before I release it to the wild, though!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5632782378391220716?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5632782378391220716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/new-look-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5632782378391220716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5632782378391220716'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/new-look-again.html' title='New look (again)'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5914477047070094299</id><published>2010-09-06T12:15:00.007+01:00</published><updated>2010-09-06T12:36:48.834+01:00</updated><title type='text'>carps is nearly done</title><content type='html'>carps is very nearly done:  tonight I shall just about polish it off.  Then I have to write a user manual (with &lt;a href="http://github.com/elginer/snm"&gt;snm&lt;/a&gt; ;) and find some time to test it properly over the Internet with a friend.  I'm happy because I've basically done the hard bits :)&lt;br /&gt;&lt;br /&gt;I'm hoping it might get more developer support and users than my other projects - all written in Haskell - because it's written in a more popular programming language - ruby.&lt;br /&gt;&lt;br /&gt;Also, since carps is winding down, I'm taking on another project - a technically minded body modifcation wiki: for discussing electronic implants and such.  I'm thinking about trying out &lt;a href="http://www.cliki.net/CLiki"&gt;CLiki&lt;/a&gt;, because it looks cool and I've been wanting to learn lisp.&lt;br /&gt;&lt;br /&gt;The reason that we need such a thing is because a bit of a community built around &lt;a href="http://sapiensanonym.blogspot.com/2010/09/come-on-in-baudelaires-fine.html"&gt;lepht's blog&lt;/a&gt; - that links to a post about poetry that uh, I instigated into becoming a discussion on implants.  I guess I feel guilty!  But it would be good to have a better forum for this.&lt;br /&gt;&lt;br /&gt;First I will attempt to set up basic wiki functionality - with little metawiki content, because as a group, at the moment, there is only one project we're working on.&lt;br /&gt;&lt;br /&gt;Then, since it sounds very useful, I want to write another page (or whatnot) that functions as a circuit diagram editor.  This is actually MUCH easier than it sounds, because of the existence of the &lt;a href="http://www.jointjs.com"/&gt;joint diagramming library&lt;/a&gt;, which I've used before and found to be stable, easy to use, easy to write plugins for and generally shiny.&lt;br /&gt;&lt;br /&gt;Then I want to write another page (or whatnot) so that we could have a competition to create a nice style sheet for the wiki.  If you're reading this, you can probably tell I'm not a CSS expert!&lt;br /&gt;&lt;br /&gt;That would probably do it, as long as everyone is happy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5914477047070094299?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5914477047070094299/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/carps-is-nearly-done.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5914477047070094299'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5914477047070094299'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/09/carps-is-nearly-done.html' title='carps is nearly done'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5945457006279654467</id><published>2010-08-29T19:50:00.002+01:00</published><updated>2010-08-29T19:52:36.238+01:00</updated><title type='text'>CARPS repository</title><content type='html'>Hi, just putting out a shout about carps: it has &lt;a href="http://github.com/elginer/carps"&gt;a repository now&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Another couple of hacking sessions and it'll be ready for mod writing.&lt;br /&gt;&lt;br /&gt;Also, I realized the underlying protocol would be useful for writing other systems which communicate over email.  Strategy games come to mind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5945457006279654467?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5945457006279654467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/carps-repository.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5945457006279654467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5945457006279654467'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/carps-repository.html' title='CARPS repository'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-8742521252165350096</id><published>2010-08-23T21:40:00.003+01:00</published><updated>2010-08-23T21:58:44.515+01:00</updated><title type='text'>mud</title><content type='html'>From writing my little projects I've learned one thing:&lt;br /&gt;&lt;br /&gt;I cannot do very much.&lt;br /&gt;&lt;br /&gt;It's a bit sad really, but it's true.  However this knowledge now empowers me!&lt;br /&gt;&lt;br /&gt;Ironically, I'm applying the lesson by taking on another project.  However, I have structured it around having other people write all the code :)&lt;br /&gt;&lt;br /&gt;It is: an rpg engine, for dungeon master and players, which uses email as a protocol.  Hence to play, you only need an email address, and no one needs to own a server.&lt;br /&gt;&lt;br /&gt;Game rules and interfaces will be implemented as mods.  Hence, initially, I only need to write the lower level software.&lt;br /&gt;&lt;br /&gt;I will post the repository soon!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-8742521252165350096?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/8742521252165350096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/orphan.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8742521252165350096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8742521252165350096'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/orphan.html' title='mud'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7521692359225065951</id><published>2010-08-20T11:35:00.007+01:00</published><updated>2010-08-20T12:25:56.255+01:00</updated><title type='text'>New look</title><content type='html'>I made this blog less eye hurty.  The existing css frightened me so I deleted most of it and rewrote some.&lt;br /&gt;&lt;br /&gt;Thus some things may not work!  Especially on *your* browser.&lt;br /&gt;&lt;br /&gt;Re the algorithm in last post.&lt;br /&gt;&lt;br /&gt;That the graph contains an 'implies not' relationship is a pre-condition of using the algorithm.  For my application, this is also fairly easy to do.&lt;br /&gt;&lt;br /&gt;There has to be some sort of check to ensure that you're not getting stuck in an infinite loop - this is done by checking you're not redundantly updating the implication_set.&lt;br /&gt;&lt;br /&gt;There will be a finite, and for todays hardware, small number of atoms.  This means the implication_set could be represented as a 1 dimensional array.  Therefore set insertion and lookup can be done in constant time O(1).&lt;br /&gt;&lt;br /&gt;I wrongly stated that the working from one graph can be insert into another.  It CANNOT be.&lt;br /&gt;&lt;br /&gt;The stack need not grow - we could have a data structure to which work could be pooled, and then executed after the stack has shrank again.&lt;br /&gt;&lt;br /&gt;The setInterval function may be useful for implementing the algorithm in javascript - that way we can run a long computation without freezing the browser.&lt;br /&gt;&lt;br /&gt;Optimized algorithm later :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7521692359225065951?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7521692359225065951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/new-look.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7521692359225065951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7521692359225065951'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/new-look.html' title='New look'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7292515089571706958</id><published>2010-08-19T23:14:00.011+01:00</published><updated>2010-08-20T00:26:17.398+01:00</updated><title type='text'>Fast software lolz</title><content type='html'>Re the last post, quest for propositional logic validation in O(N)&lt;br /&gt;&lt;br /&gt;Firstly, since this post contains algorithms, I'd better say:&lt;br /&gt;&lt;br /&gt;The algorithms described in this post, are copyright John Morrice, 2010, under the GNU Free Documentation License. http://www.gnu.org/licenses/gpl.html&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;.......where were we?&lt;br /&gt;Unfortunately, the input will certainly NOT be well formed.&lt;br /&gt;&lt;br /&gt;But I think I have such an algorithm.  First, a concrete example.&lt;br /&gt;&lt;br /&gt;First, a key.&lt;br /&gt;P-&gt;Q &lt;br /&gt;or similar arrows&lt;br /&gt;means P implies Q&lt;br /&gt;&lt;br /&gt;That is, Q must be true when P is true.&lt;br /&gt;&lt;br /&gt;P-!&gt;Q means P implies not Q.  That is, Q must not be true when P is true.&lt;br /&gt;&lt;br /&gt;Now the example:&lt;br /&gt;What we will receive is a graph.  It's simple, but has enough sophistry.&lt;br /&gt;&lt;br /&gt;A-!&gt;C&lt;br /&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;v&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;B----&lt;br /&gt;&lt;br /&gt;So what can we do?&lt;br /&gt;Well first, it's fairly efficient to find which atoms are not implicated.  In my particular application, I reference counting works well, since the graphs are created by user input.  If each atom counts the number of other atoms which implicate it, the overhead of this would be constant.  Which is good.&lt;br /&gt;&lt;br /&gt;So we find A is not implicated.  IMPORTANTLY, this means it has an empty implication set.&lt;br /&gt;&lt;br /&gt;We see A-&gt;B.  And A-!&gt;C.  We ALWAYS look at implications first.&lt;br /&gt;&lt;br /&gt;B gets A's empty implication set, and adds A to it.&lt;br /&gt;&lt;br /&gt;We see B-&gt;C.  C gets B's implication set, and adds B to it.&lt;br /&gt;&lt;br /&gt;Now we try the other path, A-!&gt;B.  We see that B has A in its implication set, and note that there is a contradiction.&lt;br /&gt;&lt;br /&gt;What just happened?!&lt;br /&gt;&lt;br /&gt;The algorithm:&lt;br /&gt;Find unimplicated atoms, As.&lt;br /&gt;For each A in As, validate(A, empty).&lt;br /&gt;&lt;br /&gt;Validate(A, implication_set):&lt;br /&gt;Set A.implication_set to a clone of implication_set&lt;br /&gt;Get Is, the atoms implicated by A.&lt;br /&gt;Get NIs, the atoms implicated to not be true by A.&lt;br /&gt;For each I in Is, validate(I, insert A into implication_set)&lt;br /&gt;For each NI in NIs, Contradiction?(NI, A)&lt;br /&gt;&lt;br /&gt;Contradiction?(C, A):&lt;br /&gt;if A is member of C.implication_set&lt;br /&gt;then there is a contradiction&lt;br /&gt;&lt;br /&gt;Comments:&lt;br /&gt;&lt;br /&gt;This algorithm works along sequences of implications.  For instance, if we started with:&lt;br /&gt;A-!&gt;B&lt;br /&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;^&lt;br /&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;v&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;C&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;|&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;v&amp;nbsp;&amp;nbsp;&amp;nbsp;|&lt;br /&gt;D----&lt;br /&gt;&lt;br /&gt;Then when we arrive at C-&gt;D and D's implication set would be C's implication set, with C added.  Then we arrive at B, and all is as it was before.&lt;br /&gt;&lt;br /&gt;Also notice, that either C or D above, could imply not B and the contradiction would still be detected.&lt;br /&gt;&lt;br /&gt;Furthermore, assigning an implication set to each atom memoizes the result of the computation.  We could take the atoms A B C and D and run them as a part of another graph, without having to recompute the relationships between the atoms A B C and D.&lt;br /&gt;&lt;br /&gt;Also note that as a side affect of the memoization, each relationship only needs to be visited once.  This means that an optimum implementation of this algorithm will run in O(N) time, where N is the number of relationships in the graph.&lt;br /&gt;&lt;br /&gt;However, this algorithm is presented in pseudo code.  If you were to try and visualize how it would run on a stack-based machine, you would find it would grow the stack.&lt;br /&gt;What I need is a better implementation of it ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7292515089571706958?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7292515089571706958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/fast-software-lolz.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7292515089571706958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7292515089571706958'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/fast-software-lolz.html' title='Fast software lolz'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4333382918953432370</id><published>2010-08-18T10:17:00.005+01:00</published><updated>2010-08-18T13:06:39.896+01:00</updated><title type='text'>Slow software, lolz</title><content type='html'>I've been trying to make a fast algorithm to validate propositional logic for our little website. I came up with something that I thought was faster, but I just worked out it would take BILLIONS UPON BILLIONS OF EONS to validate worst case input of only size 100.&lt;br /&gt;&lt;br /&gt;I don't think a user would enjoy waiting for that length of time!&lt;br /&gt;&lt;br /&gt;Edit:&lt;br /&gt;&lt;br /&gt;I was getting such long times because I'd assumed the input would be ill-formed: and even in that case I never thought of converting it into well formed sentences.  Doh!&lt;br /&gt;&lt;br /&gt;Then all you need to do is check for sentences of the form&lt;br /&gt;&lt;br /&gt;A_0 implies A_1 .... implies A_n implies NOT A_m where m &lt; n&lt;br /&gt;&lt;br /&gt;Fast solution.&lt;br /&gt;For any of A_x in A_n:&lt;br /&gt;if A_x == A_m the sentence is invalid&lt;br /&gt;&lt;br /&gt;O(N) time, about 2 lines of code....&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;...a lot better than my 460 line symbolic reasoning engine I wrote in the last three days which runs at O(N^N).....&lt;br /&gt;I am a tool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4333382918953432370?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4333382918953432370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/slow-software-lolz.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4333382918953432370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4333382918953432370'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/slow-software-lolz.html' title='Slow software, lolz'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7808210380815353387</id><published>2010-08-18T02:21:00.001+01:00</published><updated>2010-08-18T02:22:22.344+01:00</updated><title type='text'>Note to self</title><content type='html'>Work out computational complexity BEFORE implementing new supposedly 'faster' software&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7808210380815353387?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7808210380815353387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/note-to-self.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7808210380815353387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7808210380815353387'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/note-to-self.html' title='Note to self'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-439426751026044370</id><published>2010-08-10T01:15:00.004+01:00</published><updated>2010-08-10T01:19:26.903+01:00</updated><title type='text'>Obelisk</title><content type='html'>I've been working &lt;a href="http://github.com/elginer/Obelisk/blob/master/obelisk_report.html"&gt;on the report&lt;/a&gt;.  Type checking and scoping are done for now.  Evaluation will be approached tomorrow.  I think I'm going to follow the structured operational semantics as described in "The Semantics Of Programming Languages" by Mathew Hennessy.  Lots of reading to do!&lt;br /&gt;&lt;br /&gt;I also took some broken modules out of the build tree, so it should build again.  I didn't really care before, because the automated tests still compiled and passed :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-439426751026044370?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/439426751026044370/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/obelisk.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/439426751026044370'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/439426751026044370'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/obelisk.html' title='Obelisk'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-677870816411530220</id><published>2010-08-08T10:34:00.007+01:00</published><updated>2010-08-08T16:05:55.498+01:00</updated><title type='text'>Chomp</title><content type='html'>I'm working on a website for a friend and I needed to chomp.  So I worked out the regex.&lt;br /&gt;&lt;br /&gt;Here you go.&lt;br /&gt;&lt;br /&gt;Javascript:&lt;br /&gt;&lt;br /&gt;EDIT: corrected!&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;chomp&lt;br /&gt;function&amp;nbsp;chomp(text)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Check&amp;nbsp;for&amp;nbsp;empty&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(text.search(/\S/)&amp;nbsp;===&amp;nbsp;-1)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;"";&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Chomp&amp;nbsp;it.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;text.replace(/^\s*((\S+\s+)*?\S+)\s*$/, "$1");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-677870816411530220?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/677870816411530220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/chomp.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/677870816411530220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/677870816411530220'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/chomp.html' title='Chomp'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-3602227944704073759</id><published>2010-08-03T14:33:00.007+01:00</published><updated>2010-08-03T14:47:27.223+01:00</updated><title type='text'>Obelisk semantics</title><content type='html'>I'm just a chuftie, been working on the semantics.  Trying to be precise without being too verbose in my logic.  &lt;br /&gt;&lt;br /&gt;I want to share some, because I'm just happy that the &lt;a href="http://killersmurf.blogspot.com/2010/08/snmmath.html"&gt;snm math plugin&lt;/a&gt; is working well.&lt;br /&gt;&lt;br /&gt;In English:&lt;br /&gt;&lt;br /&gt;A function definition  F only has correct scoping when the set of its where clause constants  Wc have correct scoping and the set of its where clause function definitions  Wf have correct scopping and its block  Fb has correct scoping.&lt;br /&gt;&lt;br /&gt;The source (I use '.' to separate constraints for readability):&lt;br /&gt;&lt;br /&gt;forsome F. &lt;br /&gt;Fb member F. Fb = Block.&lt;br /&gt;Wc member F. Wc = Set. forall C. C member Wc. C = ConstantDefinition.&lt;br /&gt;Wf member F. Wf = Set. forall G. G member Wf. G = FunctionDefinition. &lt;br /&gt;forsome S. forsome Bq. forsome Wcq. forsome Wfq.&lt;br /&gt;new_scope(Fb, S, Bq). new_scope(Wc, S, Wcq). new_scope(Wf, S, Wfq).&lt;br /&gt;scope(F, S) iff scope(Fb, Bq) and scope(Wc, Wcq) and scope(Wf, Wfq)&lt;br /&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;br /&gt;∃ F.  &lt;br /&gt;Fb ∈ F. Fb = Block. &lt;br /&gt;Wc ∈ F. Wc = Set. ∀ C. C ∈ Wc. C = ConstantDefinition. &lt;br /&gt;Wf ∈ F. Wf = Set. ∀ G. G ∈ Wf. G = FunctionDefinition.  &lt;br /&gt;∃ S. ∃ Bq. ∃ Wcq. ∃ Wfq. &lt;br /&gt;new_scope(Fb, S, Bq). new_scope(Wc, S, Wcq). new_scope(Wf, S, Wfq). &lt;br /&gt;scope(F, S) ⇔ scope(Fb, Bq) ∧ scope(Wc, Wcq) ∧ scope(Wf, Wfq)&lt;br /&gt;&lt;br /&gt;Probably doesn't make any sense as I haven't declared what the new_scopes are for the block, where clause elements etc, but I think it looks pretty cool.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-3602227944704073759?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/3602227944704073759/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/obelisk-semantics.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3602227944704073759'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3602227944704073759'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/obelisk-semantics.html' title='Obelisk semantics'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5384574427536865624</id><published>2010-08-03T13:20:00.004+01:00</published><updated>2010-08-03T13:29:24.395+01:00</updated><title type='text'>snm_math</title><content type='html'>I've written a math plugin for &lt;a href="http://github.com/elginer/snm"&gt;snm&lt;/a&gt; called &lt;a href="http://github.com/elginer/snm_math"&gt;snm_math&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It turns this sort of thing:&lt;br /&gt;&lt;br /&gt;forall E. A subset B. E member A implies E member B&lt;br /&gt;&lt;br /&gt;Into this:&lt;br /&gt;&lt;br /&gt;∀ E. A ⊆ B. E ∈ A ⇒ E ∈ B&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And this:&lt;br /&gt;&lt;br /&gt;n member R. m member R. m &gt; 1 iff (n / m) &lt; n&lt;br /&gt;&lt;br /&gt;Into this:&lt;br /&gt;&lt;br /&gt;n ∈ R. m ∈ R. m &gt; 1 ⇔ (n ÷ m) &lt; n&lt;br /&gt;&lt;br /&gt;I'm going to go and work on the redraft of &lt;a href="http://github.com/elginer/Obelisk"&gt;Obelisk's&lt;/a&gt; semantics now, with nice looking math symbols! :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5384574427536865624?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5384574427536865624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/snmmath.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5384574427536865624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5384574427536865624'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/08/snmmath.html' title='snm_math'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-6192214821551034621</id><published>2010-07-30T12:53:00.003+01:00</published><updated>2010-07-30T12:57:25.191+01:00</updated><title type='text'>Grammar</title><content type='html'>Refining Obelisk's Grammar yet more.  Now there is no need for the type terminator #&lt;br /&gt;&lt;br /&gt;So the function from last post would now be written.&lt;br /&gt;&lt;br /&gt;//&amp;nbsp;An&amp;nbsp;accumulating&amp;nbsp;implementation&amp;nbsp;of&amp;nbsp;the&amp;nbsp;factorial&amp;nbsp;function.&amp;nbsp;Tail&amp;nbsp;recursive.&lt;br /&gt;(Int&amp;nbsp;-&gt;&amp;nbsp;Int)&lt;br /&gt;def&amp;nbsp;factorial&amp;nbsp;x&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fact&amp;nbsp;1&amp;nbsp;x)&lt;br /&gt;}&lt;br /&gt;where&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Int&amp;nbsp;-&gt;&amp;nbsp;Int&amp;nbsp;-&gt;&amp;nbsp;Int)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;fact&amp;nbsp;acc&amp;nbsp;i&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(i&amp;nbsp;&gt;&amp;nbsp;0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Recurse&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{(fact&amp;nbsp;(i&amp;nbsp;*&amp;nbsp;acc)&amp;nbsp;(i&amp;nbsp;-&amp;nbsp;1))}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;We've&amp;nbsp;recursed&amp;nbsp;enough.&amp;nbsp;&amp;nbsp;Return.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{acc}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;After so much Haskell Programming, I'm liking the syntax without significant whitespace a lot.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-6192214821551034621?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/6192214821551034621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/grammar.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6192214821551034621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6192214821551034621'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/grammar.html' title='Grammar'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5273618653661226405</id><published>2010-07-27T11:09:00.007+01:00</published><updated>2010-07-27T13:26:44.411+01:00</updated><title type='text'>Obelisk syntax</title><content type='html'>I decided to change &lt;a href="http://github.com/elginer/Obelisk"&gt;Obelisk's&lt;/a&gt; syntax.&lt;br /&gt;&lt;br /&gt;For example, to define a function, you used to do (still the case on the online repository):&lt;br /&gt;&lt;br /&gt;&lt;p style="font-family: monospace; font: arial; font-size: x-large;"&gt;// An accumulating implementation of the factorial function. Tail recursive.&lt;br /&gt;((Int&amp;nbsp;-&gt;&amp;nbsp;Int)&amp;nbsp;#&lt;br /&gt;def&amp;nbsp;factorial&amp;nbsp;x&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;((fact&amp;nbsp;1&amp;nbsp;x))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;where&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;((Int&amp;nbsp;-&gt;&amp;nbsp;Int&amp;nbsp;-&gt;&amp;nbsp;Int&amp;nbsp;#&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;fact&amp;nbsp;acc&amp;nbsp;i&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;((if&amp;nbsp;(i&amp;nbsp;&gt;&amp;nbsp;0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;((fact&amp;nbsp;(i&amp;nbsp;*&amp;nbsp;acc)&amp;nbsp;(i&amp;nbsp;-&amp;nbsp;1)))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(acc))))))&amp;nbsp;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;That was okay because the syntax is unambiguous and was not affected by whitespace.&lt;br /&gt;&lt;br /&gt;However, I thought it would make it clearer whether what you were looking at is a function application or a code block if it were to use curly braces.&lt;br /&gt;&lt;br /&gt;This was especially a problem with where clauses!  Multiple closing parenthesis are very ugly.&lt;br /&gt;&lt;br /&gt;So the above function will now be written as:&lt;br /&gt;&lt;br /&gt;&lt;p style="font-family: monospace; font: arial; font-size: x-large;"&gt;// An accumulating implementation of the factorial function. Tail recursive.&lt;br /&gt;(Int&amp;nbsp;-&gt;&amp;nbsp;Int)&amp;nbsp;#&lt;br /&gt;def&amp;nbsp;factorial&amp;nbsp;x&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(fact&amp;nbsp;1&amp;nbsp;x)&lt;br /&gt;}&lt;br /&gt;where&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Int&amp;nbsp;-&gt;&amp;nbsp;Int&amp;nbsp;-&gt;&amp;nbsp;Int)&amp;nbsp;#&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;def&amp;nbsp;fact&amp;nbsp;acc&amp;nbsp;i&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;(i&amp;nbsp;&gt;&amp;nbsp;0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;Recurse&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{(fact&amp;nbsp;(i&amp;nbsp;*&amp;nbsp;acc)&amp;nbsp;(i&amp;nbsp;-&amp;nbsp;1))}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;We've&amp;nbsp;recursed&amp;nbsp;enough.&amp;nbsp;&amp;nbsp;Return.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{acc}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;It looks much tidier, and still doesn't care about whitespace, which is great.&lt;br /&gt;&lt;br /&gt;Edit:  I'm still not so happy with it.  The if statement looks ugly.  Perhaps ruby style do and end would look nicer.&lt;br /&gt;&lt;br /&gt;Edit2:  Fixed it, removed need for functional application parenthesis around if expression.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5273618653661226405?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5273618653661226405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/obelisk-syntax.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5273618653661226405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5273618653661226405'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/obelisk-syntax.html' title='Obelisk syntax'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-6550381529657709983</id><published>2010-07-27T10:25:00.003+01:00</published><updated>2010-07-28T15:15:52.816+01:00</updated><title type='text'>Language.c</title><content type='html'>Just came across this really cool haskell library for manipulating C&lt;br /&gt;&lt;br /&gt;&lt;a href="http://trac.sivity.net/language_c/"&gt;Language-C&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-6550381529657709983?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/6550381529657709983/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/languagec.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6550381529657709983'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6550381529657709983'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/languagec.html' title='Language.c'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5422116889857252748</id><published>2010-07-27T09:10:00.004+01:00</published><updated>2010-07-27T09:13:24.703+01:00</updated><title type='text'>snm</title><content type='html'>...The Simple Nice-Looking Manual Generator!&lt;br /&gt;&lt;br /&gt;I became annoyed maintaining &lt;a href="http://github.com/elginer/snm"&gt;Obelisk's&lt;/a&gt; long report in xhtml, so I wrote a program to make writing documentation easy.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/elginer/snm"&gt;snm github&lt;/a&gt;&lt;br /&gt;&lt;a href="http://hackage.haskell.org/package/snm"&gt;snm on hackage&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;snm allows you to write clean, web-friendly reports, user guides and manuals without having to edit fickle html.&lt;br /&gt;&lt;br /&gt;snm allows you to structure your document in a modular fashion.&lt;br /&gt;&lt;br /&gt;snm document sections are written in yaml and are easy to write and understand.&lt;br /&gt;&lt;br /&gt;snm is a generator of small, valid xhtml files.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.killersmurf.com/static/snm_help.html"&gt;Read the snm manual online!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5422116889857252748?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5422116889857252748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/snm.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5422116889857252748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5422116889857252748'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/snm.html' title='snm'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-6798090741514397167</id><published>2010-07-23T07:56:00.003+01:00</published><updated>2010-07-23T08:10:39.512+01:00</updated><title type='text'>Code generation and testing</title><content type='html'>Lexing, parsing and type-checking have this in common:  they can succeed or they can fail.&lt;br /&gt;&lt;br /&gt;It is very easy to write tests to confirm the correctness of these stages.  Much more difficult is to write tests for code-generation.&lt;br /&gt;&lt;br /&gt;Even if a formal method is given which proves the correctness of a code-generation pass, it must still be tested for implementation errors.&lt;br /&gt;&lt;br /&gt;Hence, THE PLAN:&lt;br /&gt;&lt;br /&gt;Every code generation phase takes one form of intermediate language and produces the next.&lt;br /&gt;To test &lt;a href="http://github.com/elginer/Obelisk"&gt;Obelisk&lt;/a&gt;, a series of sample programs will be written, which under the semantics will produce a specific output for a specific input.&lt;br /&gt;&lt;br /&gt;Then an interpreter must be written for every intermediate language.  Each interpreter must be tested on all sample programs.&lt;br /&gt;&lt;br /&gt;If an interpreter produces incorrect output when running a sample program, the compiler stage associated with that interpreter has a bug!&lt;br /&gt;&lt;br /&gt;Writing several interpreters sounds like a lot of work, just for testing, but it's going to be easier than having to read through several thousand lines of code-generator every time erroneous behaviour is spotted.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-6798090741514397167?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/6798090741514397167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/code-generation-and-testing.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6798090741514397167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6798090741514397167'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/code-generation-and-testing.html' title='Code generation and testing'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-1025610708131192832</id><published>2010-07-21T12:51:00.013+01:00</published><updated>2010-07-21T13:16:21.539+01:00</updated><title type='text'>Learning basic assembler.</title><content type='html'>&lt;p&gt;I've been learning assembler, so I can write a code generator for Obelisk.  I'm at page 98 of (the PDF version) of &lt;a href="http://www.drpaulcarter.com/pcasm/"&gt;Dr Paul Carter's PC Assembly Language&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So far, I've learned how to call C functions.  I need to do this because the Obelisk runtime is written in C!&lt;br /&gt;&lt;br /&gt;Anyway, it aint much, but here's a 'hello world', written for &lt;a href="http://www.nasm.us/"&gt;NASM, the netwide assembler.&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;hello.asm:&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p style="font-size: large; font-family: monospace; background: black; color: yellow;"&gt;&lt;br /&gt;; Hello world program!&lt;br /&gt;&lt;br /&gt;; The data segment contains data that is always in memory (unlike the stack)&lt;br /&gt;segment .data&lt;br /&gt;format db 'Hello world!', 10, 0 ; The format string for printf&lt;br /&gt;&lt;br /&gt;; The text segment contains the code the machine will execute&lt;br /&gt;segment .text&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;global main ; Main must be global for gcc to find it!&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;extern printf ; We must declare that printf is defined in another object file.&lt;br /&gt;&lt;br /&gt;main: push dword format ; Push the argument to printf on to the stack.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;call printf ; Call printf&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pop eax  ; Remove the argument from the stack&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;This will need to be linked to libc because it uses printf.  I'm using gcc because it's simple.&lt;br /&gt;So, in the shell, assemble and link and run with:&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;p style="font-size: large; font-family: monospace; background: black; color: yellow;"&gt;&lt;br /&gt;$ nasm -f elf hello.asm &amp;&amp; gcc hello.o -o hello &amp;&amp; ./hello&lt;br /&gt;&gt; Hello world!&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;br /&gt;On my computer, the object file hell.o is only 608 bytes long&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-1025610708131192832?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/1025610708131192832/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/learning-basic-assembler.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1025610708131192832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1025610708131192832'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/learning-basic-assembler.html' title='Learning basic assembler.'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4953186615320876404</id><published>2010-07-20T20:08:00.000+01:00</published><updated>2010-07-20T20:09:03.947+01:00</updated><title type='text'>Garbage collection</title><content type='html'>Obelisk has a simple copying garbage collector now :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4953186615320876404?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4953186615320876404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/garbage-collection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4953186615320876404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4953186615320876404'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/garbage-collection.html' title='Garbage collection'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4706157628206168219</id><published>2010-07-18T13:12:00.011+01:00</published><updated>2010-07-18T14:40:18.608+01:00</updated><title type='text'>Obelisk</title><content type='html'>I've started a new programming language project: &lt;b&gt;Obelisk.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Check out what I have so far at&lt;br /&gt;&lt;br /&gt;&lt;a href="http://github.com/elginer/Obelisk"&gt;Obelisk github repository&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;i&gt;That is the place to go if you want to understand the syntax and semantics of Obelisk.&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The rest of this post is to outline the reasons why it's going to work!  Some may consider it a bit of a rant, but I assure you that &lt;a href="http://math.ucr.edu/home/baez/crackpot.html"&gt;I am not a crackpot!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Firstly, about my last programming language project, &lt;a href="http://github.com/elginer/Delve"&gt;Delve&lt;/a&gt;.  It petered out for a number of reasons:&lt;br /&gt;I didn't have a proper lexer.&lt;br /&gt;I wrote my own (buggy) parser.&lt;br /&gt;I was trying to write a type-checker for a language where new methods can be added to an object, or an object can change its class, at any time.&lt;br /&gt;I wrote the runtime in Haskell, which processed high-level bytecodes.  It was very slow.&lt;br /&gt;My approach was a rather chaotic, and I didn't produce very much documentation &lt;i&gt;(thank you beer)&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;On the plus side, I did learn a lot about programming language design, and the process definitely improved my programming skills .&lt;br /&gt;&lt;br /&gt;However, Obelisk is different!&lt;br /&gt;&lt;br /&gt;Obelisk is a strongly typed, systems programming language.  Obelisk is theoretically based on the lambda calculus, but has a class based object system to create its data types. &lt;br /&gt;&lt;br /&gt;Well, it will be and have all these things; and it will work out this time!  I know this because:&lt;br /&gt;&lt;br /&gt;I have a solid lexer, based on &lt;a href="http://hackage.haskell.org/packages/archive/parsec/3.1.0/doc/html/Text-Parsec-Token.html"&gt;Text.Parsec.Token&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The parser is generated by &lt;a href="http://www.haskell.org/happy/"&gt;happy&lt;/a&gt;, which also has the benefit of showing that the grammar is unambiguous.  This is A Good Thing.&lt;br /&gt;&lt;br /&gt;Obelisk's semantics are much simpler, so I already have a type-checker for non-polymorphic non-higher order (lower order?) functions.&lt;br /&gt;&lt;br /&gt;I am writing the run-time in C, and initial tests indicate it should be quite fast.  And because the semantics of Obelisk are again quite simple, I am able to adapt much material in &lt;a href="http://www.amazon.com/Compilers-Principles-Techniques-Alfred-Aho/dp/0201100886"&gt;The Dragon Book&lt;/a&gt; to suit its needs.&lt;br /&gt;&lt;br /&gt;Also my approach is better:&lt;br /&gt;&lt;br /&gt;I have divided development into iterations.  An iteration is a phase of development where a large proportion of the code-base must be changed in order to support new features.  For instance, I am not going to worry about classes and objects, until I have a full working system for compiling simple-functions.  The latter will take place in iteration #1, the former in iteration #2.&lt;br /&gt;&lt;br /&gt;I also have ~1500 words of documentation so far, in &lt;a href="http://github.com/elginer/Obelisk/blob/master/obelisk_report.html"&gt;a html file&lt;/a&gt;.  This doesn't sound like a lot, but since I'm only concerned with iteration #1 objectives (simple functions) there isn't so much needed.  Still, it documents all scoping and type rules, and gives examples.&lt;br /&gt;&lt;br /&gt;So aye, you might say that I'm rather a chufty at this juncture.  That's about all for now.  &lt;a href="http://github.com/elginer/Obelisk/"&gt;Look at the repository for more information!&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4706157628206168219?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4706157628206168219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/obelisk-and-its-runtime.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4706157628206168219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4706157628206168219'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/07/obelisk-and-its-runtime.html' title='Obelisk'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-2079931454990277687</id><published>2010-06-25T12:32:00.003+01:00</published><updated>2010-06-25T12:50:25.807+01:00</updated><title type='text'>Wheee! ....and a small utility</title><content type='html'>"Hello,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;We have received your appeal regarding your blog http://killersmurf.blogspot.com/. Upon further review we have determined that your blog was mistakenly marked as a TOS violator by our automated system and, as such, we have reinstated your blog. We apologise for any inconvenience this may have caused in the meantime and thank you for your patience as we completed our review process.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Thank you for understanding.&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Sincerely,&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;The Blogger Team"&lt;br /&gt;  &lt;br /&gt;ACE.  From reading other's posts on the subject, I was worried I'd never see this blog again.&lt;br /&gt;&lt;br /&gt;I hope they don't see my copy of the email above and think I'm leeching data and spamming it out again!&lt;br /&gt;&lt;br /&gt;Anyway, here's a small utility, in haskell, for creating c/c++ header files, using #define to prevent multiple inclusion:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://killersmurf.com/static/mkheader.tar.gz"&gt;mkheader&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;See the README for details on how to use.&lt;br /&gt;&lt;br /&gt;I wrote it because I realized I did this for every single header file I wrote!  Using this saves a couple of minutes every time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-2079931454990277687?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/2079931454990277687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/06/wheee-and-small-utility.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2079931454990277687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2079931454990277687'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/06/wheee-and-small-utility.html' title='Wheee! ....and a small utility'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5911602140104407908</id><published>2010-06-20T16:00:00.004+01:00</published><updated>2010-06-20T16:00:53.949+01:00</updated><title type='text'>Car wash</title><content type='html'>Bry and Hanner and I took the car through the wash today.&lt;br /&gt;&lt;br /&gt;I've always loved it since I was small: I was fascinated with the whirling brushes, the track that drags your car; every part of the squeaky clean, shiny automated washing process.&lt;br /&gt;&lt;br /&gt;So we laughed at the whooshing brushes and we bonded and the car was cleaned. Then I ran over a dead rabbit on the way out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5911602140104407908?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5911602140104407908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/06/car-wash.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5911602140104407908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5911602140104407908'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/06/car-wash.html' title='Car wash'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4488915354348943553</id><published>2010-06-09T00:39:00.004+01:00</published><updated>2010-06-09T00:45:17.373+01:00</updated><title type='text'>Transcribed some Silly Wizards banter</title><content type='html'>&lt;b&gt;Andy Stewart:&lt;/b&gt;  "Thanks very much indeed.  Och well, you're not as tough as you thought!&lt;br /&gt;&lt;br /&gt;I'm gonna sing you a maybe a different kind of a song.  It's not really a love song as such, maybe it is, I dunno."&lt;br /&gt;&lt;br /&gt;&lt;b&gt;John Cunningham:&lt;/b&gt; "It's kinda, it's like a lust song."&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Andy Stewart:&lt;/b&gt; "That was Johnny Cunningham there.  You'll eh... you'll hear a lot more of him before the night is out, no doubt.&lt;br /&gt;&lt;br /&gt;The song we're gonna sing you right now is, eh, a song from the North of Ireland, and it tells the story about how a young girl decides one day she's gonna go out on a nice, well, one evening infact, she's gonna go out on a nice summers evening and take a walk, down beside the river Bann.&lt;br /&gt;&lt;br /&gt;And um, the first time I heard this song, I thought to myself: now, if this woman has heard any of the other five hundred songs that are all called 'The Banks of the Bann', and she's still going down there, then she's out of her mind, because there's always some young cad there.  You know sorta cutting around and there's always a bit of misbehaviour (well, quite a lot of misbehaviour actually) and tears and recriminations and maybe a kid involved somewhere or...&lt;br /&gt;&lt;br /&gt;It's an age old story but distressing nonetheless.  You know, that's how all these songs tend to go and I just couldn't help thinking: there's tonnes of space, you can go anywhere you... you don't have to go down there.  It's just not worth it."&lt;br /&gt;&lt;br /&gt;Transcribed from the video: &lt;a href="http://www.youtube.com/watch?v=SHH7Lyo707Y"&gt;Silly Wizards Live - Willie Archer and the Banks of the Bann&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4488915354348943553?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4488915354348943553/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/06/transcribed-some-silly-wizards-banter.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4488915354348943553'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4488915354348943553'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/06/transcribed-some-silly-wizards-banter.html' title='Transcribed some Silly Wizards banter'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-561544370223671335</id><published>2010-05-28T09:12:00.012+01:00</published><updated>2010-05-28T09:49:28.418+01:00</updated><title type='text'>A circular ring of electrodes with a power gradient facing North</title><content type='html'>&lt;a href="http://sapiensanonym.blogspot.com/2010/05/haptic-compass-hardware.html"&gt;Lepht wants to know where North is.&lt;/a&gt;  However, instead of buying a compass, she's decided to turn herself into one.  What sort of self-respecting transhumanist wouldn't?&lt;br /&gt;&lt;br /&gt;I have some tcheuchter friends who claim to always know the direction of North, but that may just be because they've never left the Moray coast.&lt;br /&gt;&lt;br /&gt;This post starts with some further ideas for making Lepht's invention run smoothly, and ends with edited comments from Lephts original post, in order to provide a record for them.  If you have no freaking idea what I'm talking about, then it may be an idea to start reading from below the horizontal rule.  Otherwise: onwards!&lt;br /&gt;&lt;br /&gt;If you are going to have some sort of gradient, it may be wise to write a small program which would allow you to see graphically the power output at each electrode.&lt;br /&gt;&lt;br /&gt;Otherwise, you might end up with all sorts of problems.  For example, using my solution you might find that too many electrodes are powered on, which doesn't really indicate north very well.  You might want to vary the steepness of the parabola by multiplying the quadratic term by a constant.  The effect of this would be that electrodes further from North may receive more or less power.&lt;br /&gt;&lt;br /&gt;Writing a small program would allow you to experiment with the variables, until you find something nice, a comfortable time before lots of blood is involved.&lt;br /&gt;&lt;br /&gt;That's my thoughts at least.&lt;br /&gt;&lt;br /&gt;&lt;hr /&gt;&lt;br /&gt;The rest of this post is derived from comments on Lepht's blog, though it isn't a rip-off - I wanted to summarise the thoughts we had so far in its own blog post, so that anyone who wanted to see what we were thinking could do so without looking through comments.&lt;br /&gt;&lt;br /&gt;Lepht proposed the following Microcontroller code:&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: arial;"&gt;&lt;br /&gt;while (poweron)&lt;br /&gt;get north direction from compass module;&lt;br /&gt;cast to a degree out of 360;&lt;br /&gt;figure out which electrode's "domain" that number falls into;&lt;br /&gt;activate that electrode;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;However Max had an idea for improvement:&lt;br /&gt;&lt;br /&gt;&lt;i&gt;"the whole thing could be a lot better if you could get it to produce a gradient of current between electrodes, so that when north is between two electrodes, you have both firing at half power instead of the signal snapping to one of them."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;My comment was a proposed solution:&lt;br /&gt;The sort of function we might use may be a quadratic with a parabolic graph.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: arial;"&gt;y = P - (x - n)^2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Here P is the maximum power, n is north's angle round the leg, and x is the electrodes angle round the leg.  y is the power of the electrode at position x.&lt;br /&gt;&lt;br /&gt;This graph has a maximum at (n, P) which is what we're looking for.&lt;br /&gt;&lt;br /&gt;That then might be a suitable function. y is the power of an electrode at the angle x round your leg. Or in (untested) C&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: arial;"&gt;&lt;i&gt;/* Return the power of an electrode at the angle round your leg 'theta', given that the direction North is at the angle round your leg 'north', and the max power to be emitted by an electrode is 'power' */&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;float&lt;/b&gt; electrode_power(&lt;b&gt;float&lt;/b&gt; theta, &lt;b&gt;float&lt;/b&gt; north, &lt;b&gt;float&lt;/b&gt; power)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;return&lt;/b&gt; power &lt;b&gt;-&lt;/b&gt; (theta &lt;b&gt;-&lt;/b&gt; north)&lt;b&gt;^&lt;/b&gt;2&lt;b&gt;;&lt;/b&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-561544370223671335?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/561544370223671335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/05/circular-ring-of-electrodes-with.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/561544370223671335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/561544370223671335'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/05/circular-ring-of-electrodes-with.html' title='A circular ring of electrodes with a power gradient facing North'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-1980376012510031233</id><published>2010-04-08T22:42:00.019+01:00</published><updated>2010-04-09T00:12:13.079+01:00</updated><title type='text'>Agilish programming and haskell type classes</title><content type='html'>I'm drinking a lovely bottle of wine.  So time to write a little about a little programming technique.  &lt;br /&gt;&lt;br /&gt;By agilish I'm referring to no specific agile development platforms, but to the general idea of "Shall we plan everything out first?  Bloody hell no, let's get cracking!  Also lets value individuals over processes and stuff *hic*".&lt;br /&gt;&lt;br /&gt;An important aspect of some agile development methodologies is to immediately implement what the customer things is most important: these styles encourage the developers simply to work out what the most important feature is (features being stuff the customer can actually see doing something useful, 'seeing' being the important thing), implement it and then repeat: for small projects this is good!&lt;br /&gt;&lt;br /&gt;However the relative lack of planning can cause problems:&lt;br /&gt;&lt;br /&gt;So say you're an object oriented programmer implementing a GUI library, one feature after another. This is a class that you might provide for a widget*:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; Widget:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;Hi!  I'm a class providing a widget. Clicking me executes method clicked!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;method&lt;/b&gt; add:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;Hello there, this is what happens when I'm added to the window!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;method&lt;/b&gt; clicked:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;Hello there, I'm what clicking me does!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;* if you don't study design patterns that is, but this is beside my point&lt;br /&gt;&lt;br /&gt;And then you implement some GUI programs until you realize you need to be able to remove widgets for another particular program, so you alter your code:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; Widget:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;Hi!  I'm a class providing a widget. Clicking me executes method cliked!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;method&lt;/b&gt; add:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;Hello there, this is what happens when I'm added to the window!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;method&lt;/b&gt; clicked:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;Hello there, I'm what clicking me does!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;b&gt;method&lt;/b&gt; remove:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;Hello there, I've been removed!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;To do this they modified existing code which you may also introduce errors into the previously good code (like cliked).  Even a syntactic error wastes development time.  &lt;br /&gt;&lt;br /&gt;I mentioned design patterns above: relying on the work of others (especially for basic examples like this) is very important, but you're always going to encounter new problems, or even old ones you don't recognize.  What you need to do is have a more supportive paradigm for your 'add features one at a time when they are directly required!' style of coding.  Enter type classes.&lt;br /&gt;&lt;br /&gt;First, for the uninitiated, a little explanation.  Type classes describe a selection of functions which can be performed on a data type.  They are a little like java interfaces, except they can contain code.  Similarly, they are like C++ virtual classes, but Haskell, not being an object oriented language has no receiver.&lt;br /&gt;&lt;br /&gt;Importantly, unlike Java interfaces, you can declare a Haskell data type to be an instance of a type class &lt;i&gt;without&lt;/i&gt; having to alter the file containing the new instance.&lt;br /&gt;&lt;br /&gt;Here is a definition of a simple, one function, type class&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; Eq foo &lt;b&gt;where&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(==) &lt;b&gt;::&lt;/b&gt; foo &lt;b&gt;-&gt;&lt;/b&gt; foo &lt;b&gt;-&gt;&lt;/b&gt; Bool&lt;br /&gt;&lt;br /&gt;This describes the class Eq (I call it Equality).  The class has one parameter, foo.  It provides one function (==) which takes two foos and 'returns' a a boolean True or False.  The brackets surround (==) to show it is an infix function: eg 1 == 2, rather than (== 1 2).&lt;br /&gt;&lt;br /&gt;I am not intending to write a Haskell tutorial;  &lt;a href='http://www.realworldhaskell.org/blog/'&gt;there are many good books and tutorials available&lt;/a&gt;; I'm just trying to provide enough information so uninformed readers might see the benefits of programming in this style, not necessarily in Haskell.&lt;br /&gt;&lt;br /&gt;So!  A style I prefer to use with type classes is to implement only one feature with each type class.  For example, compared with the above we might get&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; AddableWidget w &lt;b&gt;where&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;-- Hello, I'm a widget that can be added&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;add_widget &lt;b&gt;::&lt;/b&gt; w &lt;b&gt;-&gt;&lt;/b&gt; IO () &lt;i&gt;-- IO () indicates an input output may be performed during the function, the () shows that there is no result 'returned'.&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;-- I've been added to the GUI!&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; ClickableWidget w &lt;b&gt;where&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;-- Hello, I'm a widget that can be clicked&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;clicked &lt;b&gt;::&lt;/b&gt; (Int, Int) &lt;b&gt;-&gt;&lt;/b&gt; w &lt;b&gt;-&gt;&lt;/b&gt; IO ()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;-- I've been clicked&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;You can keep these as part of one module, and then if you realize you need to remove your widgets then in another module you may add:&lt;br /&gt;&lt;br /&gt;&lt;b&gt;class&lt;/b&gt; RemoveableWidget w &lt;b&gt;where&lt;/b&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;-- Hello, I'm a widget that can be removed&lt;/i&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;remove &lt;b&gt;::&lt;/b&gt; w &lt;b&gt;-&gt;&lt;/b&gt; IO ()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;i&gt;-- I've been removed&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;So you don't have to alter your existing code.  That is something difficult to do with traditional strongly typed classes (difficult at least, without a bit of forethought which I am assuming has not taken place ;)&lt;br /&gt;&lt;br /&gt;Not so difficult in ruby and smalltalk, with their open classes, however the differences between untyped and strongly typed languages are a whole other kettle of fish.&lt;br /&gt;&lt;br /&gt;Maybe tomorrow I might provide an example of how to perform this with a strongly typed object oriented language.&lt;br /&gt;Delve was meant to answer that question.... whenever will I get round to finishing it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-1980376012510031233?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/1980376012510031233/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/04/agilish-programming-and-haskell-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1980376012510031233'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1980376012510031233'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/04/agilish-programming-and-haskell-type.html' title='Agilish programming and haskell type classes'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-8448806508939001860</id><published>2010-04-04T11:39:00.003+01:00</published><updated>2010-04-04T11:42:47.516+01:00</updated><title type='text'>Increased university admission and utlitarianism:  Why I really don't give two craps</title><content type='html'>Inspired by the the &lt;a href="http://afterallitcouldbeworse.blogspot.com/2010/03/new-labour-report-card-1997-2010.html"&gt;political probing of our beloved scumbaggav&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;On University degrees and utilitarianism:  Utilitarianism demands that people be qualified to perform jobs, benefiting everyone, right?  &lt;br /&gt;&lt;br /&gt;Well, with the exception of engineering, most degrees are not vocational: they do not lead directly into a job.&lt;br /&gt;&lt;br /&gt;For example &lt;a href="http://www.cv-library.co.uk/cgi-bin/jdb_view_vacancy.cgi?jobref=113414448&amp;s=100317"&gt;this is a 'graduate' software engineering job&lt;/a&gt;, it demands a 2:2 degree (doesn't mention which subject) but ALSO commercial experience developing .NET languages.  You must have more than just a degree to get this job.  &lt;br /&gt;&lt;br /&gt;Many other jobs are much more specific, some don't even require a degree but vast knowledge of a specific problem domain.&lt;br /&gt;&lt;br /&gt;For one, I think being learned is important, and I'd be extremely happy if 50% of people could understand the weird comp sci or maths I tend to drone on about when pished. &lt;br /&gt;&lt;br /&gt;However, asking me to care about increased Uni entrance is like asking me to care about the personal development of complete strangers.  It's like asking me to care about a complete stranger studying Tai Chi.  "Good on you bud!  Wait, who are you?"&lt;br /&gt;&lt;br /&gt;And we still can't find a fucking roofer for the workshop!  I certainly don't have the roofing skills or tools, neither do any of my (pointedly) academic friends.&lt;br /&gt;&lt;br /&gt;The best thing labour have done in terms of education is to boost the resources of vocational training places, like Moray college.  They have a whole new technical building now where people can become mechanics and sparkies, which is good for the person with the skills, 'cus now they have a good job (likely to lead to being self-employed) and also their skills are actually useful to everyone else.&lt;br /&gt;&lt;br /&gt;Clearly good for all.&lt;br /&gt;&lt;br /&gt;PS: Ahhh, rants on one small issue&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-8448806508939001860?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/8448806508939001860/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/04/increased-university-admission-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8448806508939001860'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8448806508939001860'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/04/increased-university-admission-and.html' title='Increased university admission and utlitarianism:  Why I really don&apos;t give two craps'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-898324092471513766</id><published>2010-03-18T08:58:00.003Z</published><updated>2010-03-18T09:00:40.631Z</updated><title type='text'>Religion must be stopped.</title><content type='html'>I'm starting the think religion is a major threat to our freedom in the UK. We no longer have free speech to criticize someone the grounds of their religions beliefs. To say someone is wrong for believing these dangerous superstitions which, (considering Al-qaeda...) is the source of terrorism and current fear, is religious intolerance and a 'hate crime'.&lt;br /&gt;&lt;br /&gt;Obviously the government is ignorant of the real problem - that people still possess these ignorant and fatal beliefs. Christianity, Islam, Hinduism et al should hence be boycotted. I need to start printing leaflets and campaigning against the missionary scum who spread their lies, starting with the alpha course who attempt to corrupt students at Aberdeen university.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-898324092471513766?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/898324092471513766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/03/religion-must-be-stopped.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/898324092471513766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/898324092471513766'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/03/religion-must-be-stopped.html' title='Religion must be stopped.'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7770516779331181876</id><published>2010-03-02T19:25:00.001Z</published><updated>2010-03-02T19:26:56.981Z</updated><title type='text'>dead server</title><content type='html'>My server is dead; my hosts, &lt;a href="http://linuxvps.org"&gt;linuxvps.org&lt;/a&gt; are no more!&lt;br /&gt;&lt;br /&gt;Someone tracked me down on facebook to ask about the Kolmogorov programming language; which surprised me!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7770516779331181876?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7770516779331181876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/03/dead-server.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7770516779331181876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7770516779331181876'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/03/dead-server.html' title='dead server'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-3289551712521767957</id><published>2010-02-10T01:15:00.005Z</published><updated>2010-02-10T01:28:14.907Z</updated><title type='text'>A nice asynchronous bit of coms</title><content type='html'>In letterscore/createWords I realized that the text input was being laggy: this is because javascript is single threaded and must wait while the synchronous message was being sent.&lt;br /&gt;&lt;br /&gt;Here is my solution:&lt;br /&gt;&lt;br /&gt;The client and server both start out with&lt;br /&gt;&lt;br /&gt;communications_number = 0&lt;br /&gt;&lt;br /&gt;The client sends the request asynchronously to the server, along with its current communications_number&lt;br /&gt;&lt;br /&gt;When the server receives a request, it checks the communications number.&lt;br /&gt;If this number is equal to the current number, then the server increments its communications_number.&lt;br /&gt;Otherwise, it does not.&lt;br /&gt;&lt;br /&gt;Then the server sends the response back with its current communication_number.&lt;br /&gt;&lt;br /&gt;When the client gets the server's communication_number, it checks whether or not this number is greater than its current communication_number.  &lt;br /&gt;&lt;br /&gt;If it isn't greater, then this is an old packet and we skipped a couple of numbers; we have already processed a newer packet!&lt;br /&gt;&lt;br /&gt;If it is greater, then its a new packet, and so we set our communication_number = the server's communication_number.&lt;br /&gt;&lt;br /&gt;In this way the client can arrange the old and new data appropriately; it is easy to see how when you know the ordering of things, quite apart from when you actual received them, that you can reconstruct them into an ordered set.&lt;br /&gt;&lt;br /&gt;Or in other words, we can have sequential behaviour without having to wait for sequential computations to finish! &lt;br /&gt;&lt;br /&gt;I think I might wrap this behaviour up in a javascript prototype object!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-3289551712521767957?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/3289551712521767957/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/02/nice-asynchronous-bit-of-coms.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3289551712521767957'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3289551712521767957'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/02/nice-asynchronous-bit-of-coms.html' title='A nice asynchronous bit of coms'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-8485281194185131048</id><published>2010-02-09T19:54:00.004Z</published><updated>2010-02-09T20:00:41.787Z</updated><title type='text'>Letterscore!</title><content type='html'>&lt;a href="http://letterscore.co.uk"&gt;Letterscore&lt;/a&gt; is a new super fun web game by me!&lt;br /&gt;&lt;br /&gt;Check it out at &lt;a href="http://letterscore.co.uk"&gt;letterscore.co.uk&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;You play against another human player from somewhere on the Internet.  First you choose ten letters; each letter is randomly determined but you decide whether or not it is a vowel or a consonant.&lt;br /&gt;&lt;br /&gt;Then you make a word.&lt;br /&gt;&lt;br /&gt;Then the game tells you whose word is longer, or whose word is not a word!&lt;br /&gt;&lt;br /&gt;The objective is to climb the league.&lt;br /&gt;&lt;br /&gt;It's lots of fun; and has everyone giggling.&lt;br /&gt;&lt;br /&gt;(And is kinda like the television program &lt;a href="http://en.wikipedia.org/wiki/Countdown_%28game_show%29"&gt;countdown&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-8485281194185131048?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/8485281194185131048/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/02/letterscore.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8485281194185131048'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8485281194185131048'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/02/letterscore.html' title='Letterscore!'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-6828263291595639877</id><published>2010-01-26T22:13:00.002Z</published><updated>2010-01-26T22:29:27.641Z</updated><title type='text'>transcendental argument for the existence of god</title><content type='html'>The &lt;a href="http://www.carm.org/transcendental-argument"&gt;transcendental argument for the existence of god&lt;/a&gt; claims that there are logical absolutes, a product of the mind, which are separate from the physical world.  &lt;br /&gt;&lt;br /&gt;If the universe were to end, would the logical value True still be True?  &lt;br /&gt;&lt;br /&gt;Now I'm going to get academic and ask: what the fuck are you on about?  What sort of processes do you imagine will occur when the universe ends?  Maybe it'll fucking be false!  Stop bollocksing on about irrelevant shit.&lt;br /&gt;&lt;br /&gt;When these people talk about True being True, you see it as somehow different from an Alcoholic living in Elgin.&lt;br /&gt;&lt;br /&gt;Ok so maybe you see them both as holy things, but what fucking god do I need to tell me this stuff?  Do I need to have a god to invent these things before I discover them?  Did god need to say there was an alcoholic in Elgin, as well as saying that True is True, prior to their discovery?&lt;br /&gt;&lt;br /&gt;Why, oh why oh why do we need a god to be responsible for creating these dull, boring facts for us?&lt;br /&gt;&lt;br /&gt;Ahhh, their argument is deeply flawed, boring and useless.  And the last two are worse than the first.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-6828263291595639877?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/6828263291595639877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/transcendental-argument-for-existence.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6828263291595639877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6828263291595639877'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/transcendental-argument-for-existence.html' title='transcendental argument for the existence of god'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7356066235910465669</id><published>2010-01-21T00:49:00.013Z</published><updated>2010-01-21T01:20:06.790Z</updated><title type='text'>approach anxiety lolz</title><content type='html'>Maybe it's because I hate women, or, maybe 'cus I hate men.  Perhaps it's because I hate everyone.  You disgust me, you pathetic worms.  But for some reason I find this blog, &lt;a href="http://approachanxiety.com/"&gt;an inspirational guide for meeting women&lt;/a&gt; extremely funny.&lt;br /&gt;&lt;br /&gt;Here's a memorable quote:&lt;br /&gt;&lt;br /&gt;"Based on that, I could ask myself what does the fact that she likes yoga say about her as a person?... She likes to feel good physically.  (I like this because it could be sexual)"&lt;br /&gt;&lt;br /&gt;But what's interesting is that he sells coaching and workshops so people can learn to speak to women at random in public.  I really don't need to comment on why this is funny, surely.  Here's a testament to his business, from the horse's mouth:&lt;br /&gt;&lt;br /&gt;"Now he can progress where it’s most important.  He can get out every day and meet new women.  Everything else is secondary."&lt;br /&gt;&lt;br /&gt;Maybe it's because he learned from the best; from "Cory Sky (the guy who picks up women with eye contact alone)"&lt;br /&gt;&lt;br /&gt;Now some of you may think I'm not taking his business very seriously; but not Mr Disco; who works hard at his game: "Wow, I don’t feel like doing this.  I feel like staying in.  But I head out to meet women anyway."&lt;br /&gt;&lt;br /&gt;Perhaps the real reason I find this funny is because well, it just seems one step off flashing your cock at people in public; but all you're doing is approaching them and asking them out.  But why do I feel that way?&lt;br /&gt;&lt;br /&gt;It's another thing I blame the strict church in this part of the world for; all the kids gathered at School praising the Lord.  And now I'm an athiest, I still can't get a boner for anyone... so worried I am that they're going to rob or kill me, or worse, I to do that to them.&lt;br /&gt;&lt;br /&gt;Then again, maybe it's because the only time I really tried doing that sort of thing was in Aberdeen pubs, where all the women actually do carry chainsaws and bibles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7356066235910465669?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7356066235910465669/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/approach-anxiety-lolz.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7356066235910465669'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7356066235910465669'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/approach-anxiety-lolz.html' title='approach anxiety lolz'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7858157794766192121</id><published>2010-01-16T23:17:00.003Z</published><updated>2010-01-16T23:27:41.266Z</updated><title type='text'>reading philosophy in the pub</title><content type='html'>I have refreshed myself in the company of people from Elgin.  Three things happened:&lt;br /&gt;A lady (who was be-boyfriended) came and sat next to me, so I gave her a look until she went away.&lt;br /&gt;&lt;br /&gt;Also I read Nietzsche in the pub, and decided that the same argument that Nietzsche uses against the logical approach used by Spinoza in his 'Ethics' is well applicable to Sartre's 'Being and Nothingness' - the rub being that it is not merely his theory of man, but a vehicle by which Sartre pushes his own emotional agenda, one of insecurity, one where a man requires a large ontology - a false model by which one can understand or misunderstand reality - to give us what a child knows - that people walk, do and be!  When the truth is stripped away like I have done here then what benefit does his philosophy give to us?!&lt;br /&gt;(tbh I quite it like, I think it's a good read)&lt;br /&gt;&lt;br /&gt;Thirdly, some idiot children attempted to board the bus in hopeman, and were turned away because one had an opened crate of beer, another asked the bus driver for blow-job while holding a pint in a glass, while a third and fourth smoked cigarettes on the bus.&lt;br /&gt;&lt;br /&gt;Would that I was quicker freeing some mobile phone memory, I would have captured it in video format.  Alas.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7858157794766192121?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7858157794766192121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/reading-philosophy-in-pub.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7858157794766192121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7858157794766192121'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/reading-philosophy-in-pub.html' title='reading philosophy in the pub'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4127997133673221416</id><published>2010-01-15T13:45:00.004Z</published><updated>2010-01-16T23:17:11.336Z</updated><title type='text'>Web dev</title><content type='html'>I've come back from Aberdeen with a &lt;a href="http://www.guitarampkeyboard.com/en/kh-202/13081"&gt;lovely &lt;del&gt;new&lt;/del&gt;second hand Guitar!&lt;/a&gt; which I love waaaay too much.&lt;br /&gt;&lt;br /&gt;Anyway, that whole thing rather distracted me from my business plans here, wasting ovar nine thousand man-hours.&lt;br /&gt;&lt;br /&gt;Back to coding though, today: and you know I don't like to make a half-assed job of things (unless I'm hacking in the pub!)&lt;br /&gt;&lt;br /&gt;So I wanted to share this little javascript function of which I'm slightly proud, mostly because I implement half the function haskell list library within it.&lt;br /&gt;&lt;br /&gt;&lt;pre style="background: rgb(255, 255, 255) none repeat scroll 0% 0%; color: rgb(0, 0, 0); -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;"&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;// From a list of lists of two elements&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(105, 105, 105);"&gt;// Create application/x-www-form-urlencoded parameters&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt; params&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;ps&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;if&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;ps &lt;span style="color: rgb(128, 128, 48);"&gt;==&lt;/span&gt; undefined&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;else&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; map &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;f&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; a &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; i&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt; i&lt;span style="color: rgb(128, 128, 48);"&gt;&amp;lt;&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;length&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt; i&lt;span style="color: rgb(128, 128, 48);"&gt;++&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;           a&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; f&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; a&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; fold &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;s&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;f&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; i&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;for&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt; i&lt;span style="color: rgb(128, 128, 48);"&gt;&amp;lt;&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;length&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt; i&lt;span style="color: rgb(128, 128, 48);"&gt;++&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; s &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; f&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;s&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt; l&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; s&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; intersperse &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; f &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;li&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;e&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;           li&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;push&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;i&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;           li&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;push&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;e&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; li&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; l &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; fold&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;f&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        l&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;splice&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; l&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;join&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;ll&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; fold&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;ll&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;o&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; fold&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;l&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;o&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;oo&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;e&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;              oo&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;push&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;e&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;              &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; oo&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;           &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(105, 105, 105);"&gt;// Pair the inputs&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; ps_pairs &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; map&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;ps&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;function&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;p&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; p&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;0&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt; &lt;span style="color: rgb(0, 0, 230);"&gt;"="&lt;/span&gt; &lt;span style="color: rgb(128, 128, 48);"&gt;+&lt;/span&gt; p&lt;span style="color: rgb(128, 128, 48);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(0, 140, 0);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;]&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; amps &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; intersperse&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;"&amp;amp;"&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;,&lt;/span&gt;ps_pairs&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(105, 105, 105);"&gt;// join them together&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;var&lt;/span&gt; joined &lt;span style="color: rgb(128, 128, 48);"&gt;=&lt;/span&gt; &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;join&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;amps&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;.&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;join&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 230);"&gt;""&lt;/span&gt;&lt;span style="color: rgb(128, 128, 48);"&gt;)&lt;/span&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style="color: rgb(128, 0, 0); font-weight: bold;"&gt;return&lt;/span&gt; joined;&lt;br /&gt;  &lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(128, 0, 128);"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Excessive?! No!!! But really what I need to do is to remove the inner functions into an array processing library of their own... I think I might make a couple of medium sizish javascript libraries for various things...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4127997133673221416?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4127997133673221416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/web-dev.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4127997133673221416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4127997133673221416'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/web-dev.html' title='Web dev'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-2852795308142982379</id><published>2010-01-07T15:24:00.002Z</published><updated>2010-01-07T15:32:13.513Z</updated><title type='text'>Facebook apps</title><content type='html'>In December I joined the ranks of facebookers.  Normally I hate that sort of thing but, hey my friends have it and it makes it easy to speak to them.&lt;br /&gt;&lt;br /&gt;However, as you may be aware, there exists on facebook various mechanisms whereby programmers can write apps, which interact with facebook.  After I realized how popular these apps were, my cynicism drive engaged, pound signs filled my eyes, and drool began to pour from my mouth.  I could make some money here, thought I, for I have but tuppence!&lt;br /&gt;&lt;br /&gt;So I have learned how to speak to facebook.  My progress wasn't entirely without mistakes.&lt;br /&gt;&lt;br /&gt;This story applies:&lt;br /&gt;Being a proper nerd, I'm not afraid of fucking around in a library's internals.  So when I realized the haskell client library was out dated, I plunged and made it support some newer methods.&lt;br /&gt;&lt;br /&gt;However, I didn't realize it would be much simpler to just use javascript, until this morning.  So uhhh, yeah, that was a bit of a waste of time.  But still, all good in the process of figuring out the easiest way.&lt;br /&gt;&lt;br /&gt;Anyway, I use &lt;a href="http://www.haskell.org"&gt;haskell&lt;/a&gt; (predictably) and &lt;a href="http://happstack.com/"&gt;happstack&lt;/a&gt;.  I run within an Iframe, and use facebook connect for API calls.&lt;br /&gt;&lt;br /&gt;I think that's the easiest way!&lt;br /&gt;Anyway, this is the really simple word game I made: &lt;a href="http://apps.facebook.com/uncensoredoriginal"&gt;uncensored originality&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now, since I have less to learn, I am going to make a more complex game!  Woohoo!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-2852795308142982379?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/2852795308142982379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/facebook-apps.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2852795308142982379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2852795308142982379'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2010/01/facebook-apps.html' title='Facebook apps'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-6566785569033806655</id><published>2009-11-24T22:18:00.002Z</published><updated>2009-11-24T22:21:50.811Z</updated><title type='text'>typefuck-0.0.2</title><content type='html'>This is a bug fix for typefuck - credit due to Kai Meder for pointing it out.  &lt;br /&gt;I'd forgotten to add a change that I made in development to the gunzip that I put online, so the example didn't work.&lt;br /&gt;Cheers Kai!&lt;br /&gt;&lt;br /&gt;&lt;a href='http://killersmurf.com/static/typefuck-0.0.2.tar.gz'&gt;typefuck-0.0.2&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-6566785569033806655?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/6566785569033806655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/11/typefuck-002.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6566785569033806655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/6566785569033806655'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/11/typefuck-002.html' title='typefuck-0.0.2'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-3962053344743319808</id><published>2009-11-16T16:31:00.015Z</published><updated>2009-12-04T12:55:49.970Z</updated><title type='text'>Typefuck</title><content type='html'>Ah, so lovely to see you again, gentle readers.  It's been a long time - and I have no explanations for my absence - but you must forgive me - after all, long does the mind dwell on mysteries, and long can mysteries dwell unseen.&lt;br /&gt;&lt;br /&gt;But worry not, gentle readers, for I have a gift for you.  As you know I have a fondness for implementing programming languages - it makes me think of kittens, polymorphic types and lockers full of stolen credit cards.  &lt;br /&gt;&lt;br /&gt;Enough to bring a nostalgic tear to anyone's eye.&lt;br /&gt;&lt;br /&gt;Especially those who value esoteric knowledge.&lt;br /&gt;&lt;br /&gt;Secrets await you, fair soul, who may read this code and wonder how much I had to drink.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://killersmurf.com/static/typefuck-0.0.2.tar.gz"&gt;Brainfuck implemented within the Haskell type checker&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;WTF:&lt;/b&gt;&lt;br /&gt;Typefuck is a brainfuck which runs within the Haskell type checker - that is, prior to compilation.  If a rationale is to be sought, it is as another proof that the &lt;a href="http://haskell.org/ghc/"&gt;GHC&lt;/a&gt; type checker is turing complete.&lt;br /&gt;&lt;br /&gt;Here are the type level commands&lt;br /&gt;&lt;br /&gt;-- | Add +&lt;br /&gt;data A = A&lt;br /&gt;   deriving Show&lt;br /&gt;&lt;br /&gt;-- | Minus -&lt;br /&gt;data M = M&lt;br /&gt;   deriving Show&lt;br /&gt;&lt;br /&gt;-- | Right &gt;&lt;br /&gt;data R = R&lt;br /&gt;   deriving Show&lt;br /&gt;&lt;br /&gt;-- | Left &lt;&lt;br /&gt;data L = L&lt;br /&gt;   deriving Show&lt;br /&gt;&lt;br /&gt;-- | Iterate [ ]&lt;br /&gt;data I bf = I bf&lt;br /&gt;   deriving Show&lt;br /&gt;&lt;br /&gt;-- | Put .&lt;br /&gt;data P = P&lt;br /&gt;   deriving Show&lt;br /&gt;&lt;br /&gt;-- | Get ,&lt;br /&gt;data G = G&lt;br /&gt;   deriving Show&lt;br /&gt;&lt;br /&gt;So the simple brainfuck program: ,&gt;,[-&lt;+&gt;]&lt;. &lt;br /&gt;(which adds two numbers)&lt;br /&gt;&lt;br /&gt;is equivalent to the Haskell type&lt;br /&gt;&lt;br /&gt;type Add = &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Cons G &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons R &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons G &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons (I (Cons M &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons L &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons A &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons R Nil)))))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons L&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(Cons P Nil&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;)))))&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Use the Brainfuck type to evaluate.&lt;br /&gt;&lt;br /&gt;The first type parameter represents the program, while the second represents the input.&lt;br /&gt;&lt;br /&gt;Input and output are represented as Cons-ed linked lists of unary integers, constructed from Succ, Zero, and Neg (for negative integers)&lt;br /&gt;&lt;br /&gt;Assert that the function 'show_type' has this type to show a value level solution for the problem (though all working is done within the type checker)&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;br /&gt;spoon@utensil:~/Desktop$ ghci&lt;br /&gt;GHCi, version 6.10.3: http://www.haskell.org/ghc/  :? for help&lt;br /&gt;Loading package ghc-prim ... linking ... done.&lt;br /&gt;Loading package integer ... linking ... done.&lt;br /&gt;Loading package base ... linking ... done.&lt;br /&gt;Prelude&gt; :m +Typefuck&lt;br /&gt;Prelude Typefuck&gt; show_type :: Brainfuck Add (Cons (Succ (Succ (Succ Zero))) (Cons (Succ (Succ Zero)) Nil))&lt;br /&gt;Loading package syb ... linking ... done.&lt;br /&gt;Loading package base-3.0.3.1 ... linking ... done.&lt;br /&gt;Loading package typefuck-0.0.1 ... linking ... done.&lt;br /&gt;Cons (Succ (Succ (Succ (Succ (Succ Zero))))) Nil&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-3962053344743319808?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/3962053344743319808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/11/typefuck.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3962053344743319808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3962053344743319808'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/11/typefuck.html' title='Typefuck'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7908822659566797861</id><published>2009-10-15T13:34:00.010+01:00</published><updated>2009-10-19T11:23:48.726+01:00</updated><title type='text'>Metal music</title><content type='html'>Sometimes I write metal music and record my creations.  This is one of those times!&lt;br /&gt;&lt;br /&gt;I thought human implantation would be a brutal topic for a metal song, so I wrote one.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://killersmurf.com/static/wetware.mp3"&gt;wetware&lt;/a&gt;&lt;br /&gt;&lt;a href="http://killersmurf.com/static/wetware.txt"&gt;lyrics&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I love my &lt;a href="http://www.jimdunlop.com/index.php?page=products/pip&amp;id=269"&gt;cry-baby wah wah pedal&lt;/a&gt;.  Also thanks to the &lt;a href="http://audacity.sourceforge.net/"&gt;audacity&lt;/a&gt; and &lt;a href="http://www.hydrogen-music.org/"&gt;hydrogen&lt;/a&gt; teams.  Go go GNU power!&lt;br /&gt;&lt;br /&gt;Enjoy :)&lt;br /&gt;&lt;br /&gt;EDIT:  This song has been described as a coming together of Ian Curtis, Killing Joke, Machine Head, Muse and the Pet Shop Boys.  Is this complimentary?  &lt;br /&gt;&lt;br /&gt;Anyway, this mix is intended for big bass systems or good head-phones.  I mix not the bass for shitty laptop speakers.  &lt;br /&gt;&lt;br /&gt;It's quite strange I find actually - if the bass is loud it sounds great on laptops, but overwhelming on stereos.  So for more macho systems, the song needs to be more of a pussy as regards bass.  I'm sure there's a paradox in there somewhere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7908822659566797861?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7908822659566797861/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/metal-music.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7908822659566797861'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7908822659566797861'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/metal-music.html' title='Metal music'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5620026985446591977</id><published>2009-10-08T11:40:00.008+01:00</published><updated>2009-10-08T11:54:27.278+01:00</updated><title type='text'>Jason Wright</title><content type='html'>Jason died last week.  We used to hang out in Garmouth and Lhanbryde.  He was a really cool person, was excellent company, and a really funny chap.  He used to roll really long cigarettes; that made me laugh. He liked computers and he was a funky drummer and guitarist.  We made some music once, I still have a cd.  I haven't seen him in a long time but I will still miss him.    So funkiness to you, Jason and goodbye.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5620026985446591977?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5620026985446591977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/jason-died-last-week.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5620026985446591977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5620026985446591977'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/jason-died-last-week.html' title='Jason Wright'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7528764873661353197</id><published>2009-10-06T21:09:00.004+01:00</published><updated>2009-10-06T21:19:59.648+01:00</updated><title type='text'>Wooo</title><content type='html'>Delve type checked a simple polymorphic function today -&lt;br /&gt;Polymorphism in Delve is similar to polymorphism in an untyped language like ruby.&lt;br /&gt;&lt;br /&gt;In Ruby, you can define a method which takes an object and accesses one of its members - even if no such object is in scope.  &lt;br /&gt;&lt;br /&gt;In Delve, such a function can be defined, but constraints are imposed on its arguments.  They must possess that member for the type checker to accept the program.&lt;br /&gt;&lt;br /&gt;This approach differs fundamentally with Haskell.  With Haskell, the function writer must be responsible for writing code that uses a given type class, or function - it must be defined.  &lt;br /&gt;&lt;br /&gt;In Delve all the responsibility is on the function caller, who must ensure his arguments have the appropriate type.  It's strongly typed ruby/python/smalltalk :)&lt;br /&gt;&lt;br /&gt;I've been ranting about it for a while, but now it's really happening!  Wooo! &lt;br /&gt;&lt;br /&gt;Actually I feel really unproductive.  Since August, I've written 6.3K lines of code for the Delve VM and compiler.  The last week I was off to Aberdeen, and now it's just testing, testing, testing.  I'm confirming it works, and fixing little bits when I need to, but I haven't written more than 100 lines in the past two weeks.&lt;br /&gt;&lt;br /&gt;Must work more...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7528764873661353197?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7528764873661353197/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/wooo.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7528764873661353197'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7528764873661353197'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/wooo.html' title='Wooo'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-5255744052224023773</id><published>2009-10-06T10:51:00.011+01:00</published><updated>2009-10-06T11:47:49.345+01:00</updated><title type='text'>hashing within a range</title><content type='html'>It is trivial to define a function which given a range of numbers R and the number of bits in the hash B, produces a hashing algorithm to hash strings which have a length within R into a hash of size B.&lt;br /&gt;&lt;br /&gt;Here is such a trivial function, in pseudocode*:&lt;br /&gt;&lt;br /&gt;make_hash( R , B ) =&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// the longest possible string as input&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Longest = max( R ) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// if the number of bits is greater or equal to the number of bits in the string&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if B &gt;= Longest * 7 then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Compute a hash from the given hash H and the string with first character C, and rest S&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hash( H , C : S) =&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Shift H 7 bits to the left&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Shifted_H = H &lt;&lt; 7&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// recurse, ORing C with the shifted hash&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hash( S , Shifted_H | C ) &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;hash( H , _ ) = H&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Use curried application to give an initial hash of 0&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return hash( 0 )&lt;br /&gt;&lt;br /&gt;What would be nice would be a hashing function which is optimal like this, for values within the range - but when a string has a length that is not in the range, the algorithm has a chance of producing a non unique hash for it.  The further the length of the string is from the range, the lesser the chance of the algorithm producing unique hash, given the string.&lt;br /&gt;&lt;br /&gt;I theorize that it is possible for strings of lengths beyond the range to have a unique hash, in some situations, and not in others.  To take a simple example, in the range [ 1 .. B / 7 ], any value not in the range cannot have a unique hash - there are not enough bits!  However in the range [ 1 .. ( B - 1 ) / 7 ] with  there are some bits left over, so it is possible.&lt;br /&gt;&lt;br /&gt;* That's some weird pseudo-code.  Uppercase variables like Erlang?  Bitwise operators like C?  Guards like Haskell? Curried function application?  Someone implement it!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-5255744052224023773?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/5255744052224023773/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/hashing-within-range.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5255744052224023773'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/5255744052224023773'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/hashing-within-range.html' title='hashing within a range'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-2716494626238450504</id><published>2009-10-05T23:11:00.011+01:00</published><updated>2009-10-05T23:34:00.367+01:00</updated><title type='text'>Hash (algorithms, not the sticky kind)</title><content type='html'>Consider Dan Bernstein's hashing algorithm:&lt;br /&gt;&lt;br /&gt;unsigned long&lt;br /&gt;hash(unsigned char *str)&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;unsigned long hash = 5381;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;int c;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;while (c = *str++)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;hash = ((hash &lt;&lt; 5) + hash) + c;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return hash;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;(I've yanked this from &lt;a href="http://www.cse.yorku.ca/~oz/hash.html"&gt;U of York's CS pages&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;I've often wondered about this algorithm.  It always striked me as strange as to why it shifts left by 5, rather than 8.  I reckon the overlapping allows longer strings to be hashed, at the expense of uniqueness.  This would also be why the hash is added to its shifted sibling.&lt;br /&gt;&lt;br /&gt;However I randomly generated some input strings and hashed each one with this Haskell program, to see how many of the resultant hashes would collide.  The answers surprise me:&lt;br /&gt;&lt;br /&gt;import Data.Bits&lt;br /&gt;import Foreign.C.Types&lt;br /&gt;import Data.List&lt;br /&gt;&lt;br /&gt;chr :: CULong -&gt; Char&lt;br /&gt;chr = toEnum . fromEnum&lt;br /&gt;&lt;br /&gt;ord :: Char -&gt; CULong&lt;br /&gt;ord = toEnum . fromEnum&lt;br /&gt;&lt;br /&gt;bhash :: String -&gt; CULong&lt;br /&gt;bhash = bhash' 5381&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;where&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bhash' hs ( c : s ) = ord c + bhash' ((hs `shiftL` 5) + hs) s&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;bhash' hs _ = hs&lt;br /&gt;&lt;br /&gt;collide :: CULong -&gt; IO ( )&lt;br /&gt;collide n = &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;let l = map bhash $ mk_syms n&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;cols = length l - ( length $ nub l )&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;in&amp;nbsp;&amp;nbsp;print $ "There were " ++ show cols ++ " collisions"&lt;br /&gt;&lt;br /&gt;mk_syms :: CULong -&gt; [ String ]&lt;br /&gt;mk_syms n = map mk_unique_sym [ 0 .. n  ]&lt;br /&gt;&lt;br /&gt;mk_unique_sym :: CULong -&gt; String&lt;br /&gt;mk_unique_sym = mk_unique_sym' [ ]&lt;br /&gt;&lt;br /&gt;mk_unique_sym' :: String -&gt; CULong -&gt; String&lt;br /&gt;mk_unique_sym' acc w =&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if w &gt;= 26&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;then&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;mk_unique_sym' ( c8 : acc ) $ ( w `div` 26 ) - 1&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else ( chr $ 97 + w ) : acc&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;where&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;c8 :: Char&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;c8 =  chr $ ( w `mod` 26 ) + 97&lt;br /&gt;&lt;br /&gt;GHCi, version 6.10.3: http://www.haskell.org/ghc/  :? for help&lt;br /&gt;Loading package ghc-prim ... linking ... done.&lt;br /&gt;Loading package integer ... linking ... done.&lt;br /&gt;Loading package base ... linking ... done.&lt;br /&gt;[1 of 1] Compiling Main             ( dan_hash.hs, interpreted )&lt;br /&gt;Ok, modules loaded: Main.&lt;br /&gt;*Main&gt; collide 100&lt;br /&gt;"There were 48 collisions"&lt;br /&gt;*Main&gt; collide 1000&lt;br /&gt;"There were 888 collisions"&lt;br /&gt;*Main&gt; collide 10000&lt;br /&gt;"There were 9861 collisions"&lt;br /&gt;*Main&gt; collide 100000&lt;br /&gt;"There were 99769 collisions"&lt;br /&gt;&lt;br /&gt;I'm assuming the high number of collisions are a property of my mechanical input, though its not surprising that the number of collisions increase as the input grows.&lt;br /&gt;&lt;br /&gt;Tomorrow I think I might feed the words from the &lt;a href="http://www.isi.edu/natural-language/download/hansard/"&gt;aligned hansards&lt;/a&gt; into it, to see if human speech fares better.&lt;br /&gt;&lt;br /&gt;PS mk_unique_sym is what the Delve compiler uses to make unique names for new variables in intermediate code phase.  &lt;br /&gt;Also - the type checker has type checked a couple of expressions.  I'm very happy - a full release should be soon :)&lt;br /&gt;And then its time to rewrite the VM.... the work goes on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-2716494626238450504?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/2716494626238450504/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/hash-algorithms-not-sticky-kind.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2716494626238450504'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/2716494626238450504'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/hash-algorithms-not-sticky-kind.html' title='Hash (algorithms, not the sticky kind)'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7791726251748945006</id><published>2009-10-03T22:27:00.004+01:00</published><updated>2009-10-03T22:49:50.478+01:00</updated><title type='text'>distraction</title><content type='html'>My my, I've rather been distracted from this whole computer world.  I blame my University course and life in general.  Have at you, life!&lt;br /&gt;&lt;br /&gt;However, I now have a small break - it's quite amusing because I don't think anyone else has a holiday at this time of year.  So to everyone else - na na na na naaa na.&lt;br /&gt;&lt;br /&gt;Have at you, everyone else.&lt;br /&gt;&lt;br /&gt;I'm really embarressed - I've had the amusing complaint that my tagsoup parser handles not some of the xml data types, like our happy friend Mr CDATA.  I've never actually used the thing - it was a half baked solution to the problem of gathering links in shpider. Sorry Mister!  I'll fix it (soon).&lt;br /&gt;&lt;br /&gt;I trekked up to Aberdeen a couple of times in the last few weeks.  Lizzie has been transfered into second year Geography, which is good.  However she lives in Hillhead which is amusing.&lt;br /&gt;&lt;br /&gt;Our sleep was interrupted one night by the tumultuous yobbery of three freshers chanting xenophobic English football songs.  They were followed closely by a throng of international students, whom they had apparently befriend.  Weird as hell.  Also, not a good demonstration of adapting to survive, on the part of the English football fans, considering their proximity to Tillydrone and other lovely places to live.&lt;br /&gt;&lt;br /&gt;Delve delve delve.  I've neglected you so!  But really, it'll get done.  Sooo many bugs, so many tests to pass.&lt;br /&gt;&lt;br /&gt;But I've sworn to make the next release coherent - so I'd rather get it done properly, and let it take a while.&lt;br /&gt;&lt;br /&gt;I visited Rory's flat while at Aberdeen, where I'd left my copy of the &lt;a href="http://en.wikipedia.org/wiki/Dragon_Book_(computer_science)"&gt;dragon book&lt;/a&gt; - so I starded reading the section on code generation and runtime systems again.  I've concluded that it won't be so difficult to compile Delve into machine code.&lt;br /&gt;&lt;br /&gt;However, due to the support for continuations, a lot of data, is going to have to go on the heap rather than stack - I don't want to have to make deep stack copies all the time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7791726251748945006?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7791726251748945006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/distraction.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7791726251748945006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7791726251748945006'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/10/distraction.html' title='distraction'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-1350062082000372166</id><published>2009-09-14T18:30:00.012+01:00</published><updated>2009-09-14T19:29:36.877+01:00</updated><title type='text'>Delve a little late</title><content type='html'>The next release of Delve, with type checker and bug fixes is gonna be maybe another week away - development is going very well and smoothly, but I've decided to create a cool program I've been thinking about for a while - &lt;br /&gt;&lt;br /&gt;See, in a pen and paper RPG, if the players decide to completely ignore the intended quest, for some reason and hang around in a bar instead, the dungeon master (DM) must be able to improvise, either to push them on to the intended quest, or instead to facilitate their mucking around, perhaps by creating a new quest.&lt;br /&gt;&lt;br /&gt;This is something you can never have with &lt;i&gt;World of Warcraft&lt;/i&gt; or &lt;i&gt;Fallout&lt;/i&gt; or any computerized RPG game - well, something you can never have without a lot of artificial intelligence research.&lt;br /&gt;&lt;br /&gt;So I want to develop a computer aided rpg system which allows for the flexibility of pen and paper RPGs as well as the complex rules and speed of a computer system. I'm gonna call it C.A.R.P, or just carp, because it's less of a pain to write that way.  &lt;br /&gt;&lt;br /&gt;There are some computer aided rpgs around - notably &lt;a href="http://www.rpgobjects.com/index.php?c=orpg"&gt;OpenRPG&lt;/a&gt; and &lt;a href="http://www.rpgvirtualtabletop.com/"&gt;RPG virtual table-top&lt;/a&gt;, but carp will differ from them.&lt;br /&gt;&lt;br /&gt;I feel virtual table-top is, from the DM's perspective, too text based.  It covers many things with documents which would be better written as scripts.  Improvisation takes place entirely within a chat window - and then the benefits of programmatic game-play is lost .  We can do better than this!&lt;br /&gt;&lt;br /&gt;For instance, the player should have a panel of buttons which correspond to 'obvious actions' - stuff like the classic "GO NORTH", "CLIMB UP THE ROPE", "SHOOT THE KOBOLDS WITH YOUR GRENADE LAUNCHER".  These are obviously dependent on your location, the current item you have equipped - this is dependent on the game rules, which is dependent on the DM.&lt;br /&gt;&lt;br /&gt;Therefore, the DM needs to be able to add widgets to the player's GUIs at his whim.  The game needs a scripting system, then, which is powerful enough to give the DM this control.&lt;br /&gt;&lt;br /&gt;Also the computer should be able to generate appropriate adversities for the players to fight at any point, this would require statistical analysis, but that's ok.&lt;br /&gt;&lt;br /&gt;Of course, a chat window is mandatory for information.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.erlang.org" &gt;Erlang&lt;/a&gt; is a good choice for development language - because it can evaluate itself as a script and can send data around networks and has really good control over its own processes.&lt;br /&gt;&lt;br /&gt;The power of erlang is such that its easy(ish) to imagine a player using an item in the game world which would cause a whole new game window to open, containing a whole new copy of carp - but one that exists literally inside the players universe - like in the &lt;a href="http://xkcd.com/244/" &gt;xkcd comic&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Features, with the more important features ( those I'm going to implement first ) closer to the top:&lt;br /&gt;&lt;br /&gt;GUI&lt;br /&gt;Network support - can be played over the internet&lt;br /&gt;Run-time scripting so the DM can improvise when needed&lt;br /&gt;Game rules and content, built using the run time scripting mentioned above&lt;br /&gt;Hot-seat mode - so more than one player can share a computer&lt;br /&gt;Support for a mix hot-seat and network play - so say four people can play together with only 3&lt;br /&gt;Tools for statistical analysis of various things in the game - so for instance the DM can generate appropriate adversities for the players&lt;br /&gt;&lt;br /&gt;Features carp will not have:&lt;br /&gt;animation&lt;br /&gt;on-screen maps (print em or draw em, so your players can write on em)&lt;br /&gt;&lt;a href="http://bigzaphod.org/whirl/"&gt;grilled chicken&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also Lizzie notes that I've sunk to new levels of geekiness.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-1350062082000372166?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/1350062082000372166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/delve-little-late.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1350062082000372166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1350062082000372166'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/delve-little-late.html' title='Delve a little late'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7653846994659129357</id><published>2009-09-11T21:01:00.011+01:00</published><updated>2009-09-11T22:11:44.982+01:00</updated><title type='text'>sXe analysis</title><content type='html'>&lt;a href="http://sapiensanonym.blogspot.com/2009/09/choose-personal-control-surrender-it-to.html"&gt;Lepht&lt;/a&gt; got me thinking about the straight edge (also known as sXe).&lt;br /&gt;&lt;br /&gt;I think the most interesting thing about sxers is the phenomenon that they form a community at all.  It is like a monastery, where every member must abstain - and also partake in cabal approved recreation - that is the dancing you will see if you go to a hardcore gig.&lt;br /&gt;&lt;br /&gt;But, as is asked in the faq &lt;a href="http://www.faqs.org/faqs/cultures/straight-edge-faq/section-17.html"&gt;"Why do you need a label to be poison free?"&lt;/a&gt;.  The answers presented do not satisfy me.&lt;br /&gt;&lt;br /&gt;The first: "this label help keep us together and stay strong."&lt;br /&gt;&lt;br /&gt;So you're weak?  That interesting - so a sxer might rely on other sxers to help them fight their own cravings for drugs and drink.  It worries me that a person who doesn't drink or smoke can be so terrified of ruining their life through excess that they need a support group.&lt;br /&gt;&lt;br /&gt;The second answer satisfies me even less: "the label shows you're actually serious about what you're saying and that you're not making any exceptions"&lt;br /&gt;&lt;br /&gt;In what way does a label show that you're serious?  You could be lying and just saying you're sxe!  The only way for a person to know you're serious is a close study of your behaviour over a long period of time.  This answer is, to quote Dr. Sheldon Cooper, demonstrably fallacious.  &lt;br /&gt;&lt;br /&gt;The author goes on to admit that the sXe is corrupted by hypocracy, but is an ideal to be aspired to.  Since others can corrupt the ideal through corrupting their own bodies, and can do this without your knowledge, how then can a person reasonably trust those who share their community?  They cannot.&lt;br /&gt;&lt;br /&gt;The commitment must be taken on word of mouth.  Now I'm moving beyond the world of logical analysis, which is my tool since I have no subjects to interview, but my hypothesis would be that commitment is viewed as the cool factor of a real sXe community - a community which, through members lapsing and then getting control back, over time fades into grey like an animation reel of black then white, rather than the dichotomy of abstinence and corruption.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7653846994659129357?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7653846994659129357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/sxe-analysis.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7653846994659129357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7653846994659129357'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/sxe-analysis.html' title='sXe analysis'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-684485749691205201</id><published>2009-09-11T05:08:00.014+01:00</published><updated>2009-09-11T06:25:08.786+01:00</updated><title type='text'>Government sentimentality</title><content type='html'>I protested against the Iraq war in Glasgow because I hate the pain and the fear and blood that I knew would come with it; it sickens me!  But all this posturing sickens me further.&lt;br /&gt;&lt;br /&gt;I'm so sick of the platitudes voiced by the media and our weak government that I worry that I'm turning into a right wing, highly opinionated, weirdy-beardy geezer.&lt;br /&gt;&lt;br /&gt;Are people really shocked that the CIA torture people?  Have we run out news?  Perhaps people will next complain that the army kill people!  Really, how are they going to get answers out of prisoners? Play the enemy &lt;i&gt;limp bizkit&lt;/i&gt; until they bleed from the eyes?  Ahh but see, they're the not the 'enemy' because this isn't a war - they're evil criminals who are facing justice.  Oh pleeeeese.&lt;br /&gt;&lt;br /&gt;On the subject of evil criminal prisoners:  if people are worried about terrorism, why are they upset about the more peaceful relationship we can have with Libya, now that Megrahi has been transfered?  Surely with peace, the threat they pose to us is diminished.&lt;br /&gt;&lt;br /&gt;Of course, lots of MPs and the US also are making a big stink - hang on a minute - these people are so upset, they would rather irritate a developed foreign power, than transfer a man from a jail here to a jail there.  This is the sort of idiocy which leads to war.  Of course, it's okay if you're the US 'cus you can just bomb them again if you get really pissed off.&lt;br /&gt;&lt;br /&gt;In this case, those who hold the moral high-ground and are not prepared to compromise are the dangerous ones.  Don't they realize the other side think that they have the high-ground too?  Will they instead fight over that ethereal hillock?&lt;br /&gt;&lt;br /&gt;Since we're talking about hypocrisy and deliberately aggravating other nations, western policy on Iran needs a mention.  In fact, I'd say it takes the biscuit. Now I really don't like the stuff their regime does. But why, when you consider other weird/aggressive countries (I'm looking at you, China, Russia, Pakistan and the good ol' U. S. of A. ) do we have such a strong stance against Iran?  Why do we try to interfere with their nuclear program and lay sanctions against them and not China?  &lt;br /&gt;&lt;br /&gt;It's because they're weak.  Our leaders want them to stay weak so they do not threaten us.  It's the truth, but it's the scary truth no-one is ready for, and no-one wants to admit.&lt;br /&gt;&lt;br /&gt;Who're the nasty scary countries again?&lt;br /&gt;&lt;br /&gt;The question is: Why do these powerful men who invaded Iraq and Afghanistan shy away from the war and bloodshed and pain, and hide behind a false chivalry?  Have they learned nothing from Caesar and Ghengis Khan?  Khan achieved not great moral victories but lasting prosperity and safety for his people!&lt;br /&gt;&lt;br /&gt;Also, to perform this false crusade they had to lie to their own people - about having a moral right to fight against some 'axis of evil'.  I think some of the people who are now upset bit the doctrine a little hard, and did not fully comprehend the consequences of a war.  To these people I recommend spending some time looking at bombs, bullets and their local hospital's casualty ward.&lt;br /&gt;&lt;br /&gt;And about the possibility of Cameron being in charge of the next righteous crusade - now this is subjective - however well he might run things, I wouldn't trust him standing next to me with a pistol in his pocket.  He's just some geezer - the sort of people I trust with guns are military types who know what they're for and understand their safe operation and maintenance. &lt;br /&gt;&lt;br /&gt;Did you know the UK has no launch codes for its nuclear weapons?  The submarine captains are in absolute control over world destruction - but no one is worried.  It seems that warriors can be trusted to keep the peace - while politicians arguing amongst themselves spread deceit and death.&lt;br /&gt;&lt;br /&gt;Have a swell day!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-684485749691205201?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/684485749691205201/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/government-sentimentality.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/684485749691205201'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/684485749691205201'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/government-sentimentality.html' title='Government sentimentality'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4897996283903897637</id><published>2009-09-09T15:06:00.007+01:00</published><updated>2009-09-09T16:20:39.551+01:00</updated><title type='text'>Things wot I dun wrong, or how I learned to love compiler development</title><content type='html'>The Delve typechecker is nearly done, a patch should be pushed by the end of the week.  It infers interfaces of objects instead of their concrete types, and so it acts like a strongly typed Smalltalk or Ruby, which was the plan.&lt;br /&gt;&lt;br /&gt;Anyone who has looked at the &lt;a href="http://github.com/elginer/Delve/tree/master"&gt;Delve repository&lt;/a&gt; might have been struck by the absence of automatic unit testing available.  This won't be a problem for the typechecker - I can think up loads of expressions which should typecheck, and loads which shouldn't - then I simply have to look at the results.  The rest of the compiler/VM is not so simple.&lt;br /&gt;&lt;br /&gt;For instance, how is one to automatically check that tail-call optimization is working properly?  We can look at the internals of the virtual machine, but this is a bad idea - I initially debugged the virtual machine with unit tests written in the target VM language - which can take a hundred lines to do something that takes a few in the source language Delve.  Since the machine is very fluid, every time I get a better idea then the machine changes.  Having hundreds of lines of test code which have to change when the machine changes is too much work, especially considering I'm the only person currently hacking on Delve :)&lt;br /&gt;&lt;br /&gt;To solve this problem, I'm gonna add unit tests for tail recursion, coroutines using continuations, mutually recursive routines which I can be sure allocate a large, fixed quantity of memory every recursion.  Then I'd like to use POSIX resource management to see if the limit is exceeded.  &lt;br /&gt;&lt;br /&gt;However, this is POSIX only, and will also require statistical analysis to ensure it works correctly across many systems.  &lt;br /&gt;&lt;br /&gt;I need a better plan... :)&lt;br /&gt;&lt;br /&gt;Also I had made a bit of a silly mistake.  See, the way the Delve in the public repository works is:&lt;br /&gt;String is parsed into Core&lt;br /&gt;Core is VARAPPED into VarCore - a version of core without nested expressions - temporary variables overcome this.&lt;br /&gt;VarCore is RESOLVED into LocalCore - like var core, but local variables are associated with a stack index - since the VM records a stack of local scopes, it's better to pre-compute which local scope is associated with each variable.&lt;br /&gt;LocalCore is then compiled into VM code.&lt;br /&gt;&lt;br /&gt;However, I realized that the RESOLUTION into local core should occur before type checking, and also since VARAPPING a legal program should result in another legal program, that type checking should occur before VARAPP.&lt;br /&gt;&lt;br /&gt;Soo the process is now&lt;br /&gt;&lt;br /&gt;String is parsed into Core&lt;br /&gt;Core is RESOLVED into LocalCore&lt;br /&gt;LocalCore is type-checked.&lt;br /&gt;LocalCore is VARAPPED into VarCore&lt;br /&gt;VarCore is compiled to DCode.&lt;br /&gt;&lt;br /&gt;This is requiring much of the compiler to be changed to support different data-types - an advantage of the small codebase (only now 6.2KSLOC) is that this should only really take an hour or three.  Of course, this is poor software engineering - several solutions spring to mind:&lt;br /&gt;&lt;br /&gt;I was tempted to define an abstract form of core, AbstractCore, which would have kind * -&gt; *.  So it would be AbstractCore md, where md is associated MetaData.  Compilation would proceed by transforming the metadata.&lt;br /&gt;&lt;br /&gt;This has the disadvantage of errors like nested expression occuring in the syntax tree after the varapp phase not being caught at compile time - I would have to check they would be caught at run time.&lt;br /&gt;&lt;br /&gt;Or I could associate each element in the tree with an integer, and just have an IntMap which maps the integer to associated MetaData.  I think this would be easier to manage - since the metadata would be separated from the Tree.&lt;br /&gt;&lt;br /&gt;This still suffers from that disadvantage.&lt;br /&gt;&lt;br /&gt;However, if the various syntax trees are queried through a type-class, then they could be used independently.  Also, this could return various elements in a type-safe manner, for instance, before the VarApp phase, there could be a type class instance for function application, which with multiple parameters would associate the application with arbitrary, possibly nested expressions.  The instance used in the VarApp phase would associate the application with variables only.&lt;br /&gt;&lt;br /&gt;This bit of randomness has turned into an idea!  I think I will try this.  Firstly, I'm just gonna get it working again, though, in the old and simple style - changing it to support new abstract types is going to a be a little bit more work than simply renaming a few things, which is all I have to do now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4897996283903897637?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4897996283903897637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/things-wot-i-dun-wrong-or-how-i-learned.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4897996283903897637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4897996283903897637'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/09/things-wot-i-dun-wrong-or-how-i-learned.html' title='Things wot I dun wrong, or how I learned to love compiler development'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-7573928097164080032</id><published>2009-08-28T15:54:00.006+01:00</published><updated>2009-08-28T16:43:06.512+01:00</updated><title type='text'>Doing and being</title><content type='html'>I've been reading Sartre's &lt;i&gt;Being and Nothingness&lt;/i&gt; again - it's very interesting!  &lt;br /&gt;&lt;br /&gt;I read it last year, but since then, all the ideas have become muddled in my mind - also I have a tendency to jump back and forth between the concepts I am struggling with, rather than read linearly and absorb at the author's intended pace, so I'm attempting to give it a much fuller read this time.&lt;br /&gt;&lt;br /&gt;I just really want to share how cool I think this book is!  Occasionally I get stuck and have to draw out his arguments in predicate logic.  Thinking about it, it would be cool to encode his ontology into prolog maybe - then you could question details of his thought directly.  Also to retrieve quotations.&lt;br /&gt;&lt;br /&gt;Occasionally I find myself in bad faith - I work a lot sometimes to create cool things - and I feel that somehow that makes me cooler, but this is bad faith because I am seeking to escape what I am to be what I am not, and simultaneously to escape what I am not to be what I am.&lt;br /&gt;&lt;br /&gt;So cheers to Sartre for letting me figure that one out :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-7573928097164080032?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/7573928097164080032/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/doing-and-being.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7573928097164080032'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/7573928097164080032'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/doing-and-being.html' title='Doing and being'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-1629140944359950616</id><published>2009-08-26T16:24:00.009+01:00</published><updated>2009-08-26T20:50:09.149+01:00</updated><title type='text'>pointless</title><content type='html'>This post is a literate haskell file.&lt;br /&gt;&lt;br /&gt;I like the pointless style of programming - that is, functions do not mention the variables they act upon explicitly.  While this is very common and cool, it's also a source of amusement - occasionally I find myself distract from a project by a need/desire/delusional whim to re-write various functions as pointless as possible.  So here is a little one, it's nothing special. &lt;br /&gt;&lt;br /&gt;&gt; import Control.Arrow&lt;br /&gt;&lt;br /&gt;&gt; por1 :: (b -&gt; Bool) -&gt; (b -&gt; Bool) -&gt; b -&gt; Bool&lt;br /&gt;&gt; por1 = curry $ curry $ uncurry (||) . (uncurry $ uncurry (&amp;&amp;&amp;))&lt;br /&gt;&lt;br /&gt;That is, por is a function which takes two predicates and input -&lt;br /&gt;each predicate is from a polymorphic type b to a boolean&lt;br /&gt;Apply both the predicates to the input, producing two boolean valies&lt;br /&gt;Apply "Or" to these values to return one result.&lt;br /&gt;&lt;br /&gt;There are automated tools to do this sort of obsfucation with haskell but I find my brain boils attempting to hack out this sort of "write-only" code. (this is a good thing)&lt;br /&gt;&lt;br /&gt;Here is what the &lt;a href="http://hackage.haskell.org/package/pointfree"&gt;pointfree&lt;/a&gt; took makes of a pointful version* of the above:&lt;br /&gt;&lt;br /&gt;&gt; por2 = ((uncurry (||) .) .) . flip (&amp;&amp;&amp;)&lt;br /&gt;&lt;br /&gt;I like that, though the flip, in this case, is semantically irrelevant.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://haskell.org/haskellwiki/Pointfree"&gt;More about the pointless style&lt;/a&gt;&lt;br /&gt;also &lt;a href="http://www.vex.net/~trebla/weblog/pointfree.html"&gt;comparison to unix pipelines&lt;/a&gt;&lt;br /&gt;The question is: how to implement uncurry in bash?  Next post, possibly.  Hobgoblin has had the better of me tonight! :)&lt;br /&gt;&lt;br /&gt;* the pointful version: &lt;br /&gt;&lt;br /&gt;&gt; por3 p q = uncurry (||) . (q &amp;&amp;&amp; p)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-1629140944359950616?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/1629140944359950616/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/pointless-one-liner.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1629140944359950616'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1629140944359950616'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/pointless-one-liner.html' title='pointless'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-8114498225225624425</id><published>2009-08-22T14:46:00.002+01:00</published><updated>2009-08-22T14:52:02.604+01:00</updated><title type='text'>Delve tutorial</title><content type='html'>It occured to me that readers would be unable to decipher the last post without reading the tutorial, so I'll link that here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.killersmurf.com/static/TUTORIAL"&gt;Tutorial on the untyped delve core&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-8114498225225624425?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/8114498225225624425/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/delve-tutorial.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8114498225225624425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/8114498225225624425'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/delve-tutorial.html' title='Delve tutorial'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-3832448103657345716</id><published>2009-08-21T14:36:00.004+01:00</published><updated>2009-08-26T14:45:29.315+01:00</updated><title type='text'>The Delve Type System</title><content type='html'>(EDIT: bogus logic fixed)&lt;br /&gt;&lt;br /&gt;I've been working on the type system for Delve.  Here lie the innovative features of the language.&lt;br /&gt;&lt;br /&gt;It would be nice to infer the interface of objects, rather than an exact name.  This is a much more Smalltalkish approach - an untyped language considers only the interface - the names are irrelevant. Consider this example:  ( Warning, I haven't actually tested the examples - it's of little importance to the thought really )&lt;br /&gt;&lt;br /&gt;In Haskell, consider the silly ADT&lt;br /&gt;&lt;br /&gt;data Tree = Branch { tree :: Tree }&lt;br /&gt;&lt;br /&gt;And the Haskell function, bound to the variable f:&lt;br /&gt;&lt;br /&gt;let f = \ b -&gt; tree b&lt;br /&gt;&lt;br /&gt;Now say we have a Delve object corrosponding to the Tree adt.  &lt;br /&gt;&lt;br /&gt;(: Tree (Object.new))&lt;br /&gt;(: Tree.tree&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(me ()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(self)))&lt;br /&gt;&lt;br /&gt;See here * for an example which constructs a class using the meta-object model.&lt;br /&gt;&lt;br /&gt;And the corresponding Delve function, bound to the variable f:&lt;br /&gt;&lt;br /&gt;(: f (fu (b) ((b.tree))))&lt;br /&gt;&lt;br /&gt;Now with Haskell, the type checker will say: what is the type of 'tree'?  It's 'Tree -&gt; Tree'.  Therefore f is of type 'Tree -&gt; Tree'&lt;br /&gt;&lt;br /&gt;Now what I'm trying to do with Delve is for Delve to say "b is a new mutant object of which I know nothing.  However, it must have the method tree.  Therefore, the type of f is 'Mutant with method tree, where tree is of type a -&gt; a'&lt;br /&gt;&lt;br /&gt;I think that's pretty cool.&lt;br /&gt;&lt;br /&gt;To get this magic to work however, I have given Delve four type constructs.  Firstly to explain the key concepts of unification and domination.&lt;br /&gt;&lt;br /&gt;In Delve, a type is unified with another type if one type can be used in the place of another.  This is a separate notion from equality - equality is a subset of unification.&lt;br /&gt;&lt;br /&gt;Domination is where one type, (a type which is more concretely defined) actually replaces the other type in the type system.  What seems to the type-checker as  an initially polymorphic variable can be dominated into becoming a concrete variable in this manner.&lt;br /&gt;&lt;br /&gt;So this is a first attempt at describing the various types.&lt;br /&gt;&lt;br /&gt;An object:  an object is a value of indisputable type.&lt;br /&gt;&lt;br /&gt;For unification with another type, the two types must be objects, the objects must have the same name, and the types of both objects members must all be the same ( recursively considering these types ).&lt;br /&gt;&lt;br /&gt;A mutant: a mutant is a value of disputable type.&lt;br /&gt;&lt;br /&gt;A mutant can be unified with another mutant if the members of the first mutant are a subset of the second mutant of the same name - in that they set of the names of the first mutant is a subset of the second, all also that each of the intersection of the two sets of members unify.&lt;br /&gt;&lt;br /&gt;A mutant also unifies with an object, if the above restrictions are met, but an object will dominate a mutant - that is, an object can be used as a function argument where a mutant is expected, but if an object is assigned to a mutant variable - the variable will become an object.&lt;br /&gt;&lt;br /&gt;Mutants which unify can be merged, by safely putting the member types of both mutants into one new mutant.  The changes must be propagated to any mutants which unified with the old type.&lt;br /&gt;&lt;br /&gt;A function: Delve is strict and does not support curried function application, therefore a function can be simply represented by a list of types.&lt;br /&gt;&lt;br /&gt;A function unifies with another function only if each of their types unify.&lt;br /&gt;&lt;br /&gt;A polymorph: a polymorph will unify with any type, will be dominated by any other type.&lt;br /&gt;&lt;br /&gt;The types arranged then in order of concreteness&lt;br /&gt;&lt;br /&gt;Object, Function&lt;br /&gt;Mutant&lt;br /&gt;Polymorph&lt;br /&gt;&lt;br /&gt;Now for an example, back back to our function:&lt;br /&gt;&lt;br /&gt;(: f (fu (b) ((b.tree))))&lt;br /&gt;&lt;br /&gt;The type checker will then type check this as follows – try to imagine you are the Delve type checker – this will be your thought process.&lt;br /&gt;&lt;br /&gt;A function will be assigned to the variable f.&lt;br /&gt;&lt;br /&gt;f will have the type of this function.&lt;br /&gt;&lt;br /&gt;Since this function has one argument, the initial type which we will consider will be “Polymorph called a → Polymorph called b” (to use a Haskelly sort of notification”&lt;br /&gt;&lt;br /&gt;So open a new scope, and let b be a new polymorph called a.&lt;br /&gt;&lt;br /&gt;Now look at the code for this function.&lt;br /&gt;&lt;br /&gt;A member of b, called tree, is being called.&lt;br /&gt;&lt;br /&gt;So the type of b might be a “Mutant with with a member tree, where tree is a Polymorph called x”&lt;br /&gt;&lt;br /&gt;This is ok, because this new type unifies with b's old type, since everything unifies with a polymorph.&lt;br /&gt;&lt;br /&gt;Also, this type dominates b's old type.  So b's new type is “Mutant with member tree, where tree is a Polymorph called x”&lt;br /&gt;&lt;br /&gt;Tree is called of b, which is a polymoph called x.&lt;br /&gt;&lt;br /&gt;So the return type of this function is a polymorph called x.&lt;br /&gt;&lt;br /&gt;So the type of this function is 'Mutant with member tree, where tree is a polymorph called x → x'&lt;br /&gt;&lt;br /&gt;So the type of f is 'Mutant with member tree, where tree is a polymorph called x → x'&lt;br /&gt;&lt;br /&gt;Which is what we want.  I think this is cool – but it has some problems.  First, the rules for assignment and application will be formalized – this is useful – also it reveals the problems.&lt;br /&gt;&lt;br /&gt;Assignment – assignment assigns a result to a variable.  Assignment is correct if the type of the result unifies with the type of the variable.  The type of the variable is always dominated by the type of the result.  This means a polymorphic variable will be erased if say, an object is assigned to its place.&lt;br /&gt;&lt;br /&gt;Application – actual arguments are applied to a function.  The types of the functions formal arguments have already been decided and are not changed in a global sense..  The types of the actual arguments must unify with the types of the formal arguments.  However, if the type of an actual argument dominates a polymorphic type in the formal arguments, all occurrences of the polymorphic type in the resultant type (local to this computation) are changed into the dominating type.&lt;br /&gt;&lt;br /&gt;Say for our example, where f is 'Mutant with member tree, where tree is a polymorph called x → x'&lt;br /&gt;&lt;br /&gt;If f is applied to a “Mutant with a member tree, where tree is of type Tree”, then locally, the type of f will become “Mutant with a member tree, where tree is of type Tree → Tree”.  The result will then be of type “Tree”.  However, when f is next used, its type will still be 'Mutant with member tree, where tree is a polymorph called x → x'.&lt;br /&gt;&lt;br /&gt;Member lookup – looking up a member of a polymorph dominates the polymorph with a mutant type which possesses this member, and gives the member a new polymorphic type.  Looking up a member of a mutant succeeds with the unification of the mutant with a new mutant as before.  Looking up the member of an object succeeds if the object has this member.  The resultant type, ie, the type of the member lookup, is the type of the member, once the appropriate unification (and perhaps domination ) has been applied.&lt;br /&gt;&lt;br /&gt;Function creation – polymorphic arguments are introduced to represent each formal argument.  Each formal argument is then dominated by the statements making up the body of the function.  The return type is the type of the last statement in the function's body.&lt;br /&gt;&lt;br /&gt;Method creation – same as function creation – exception the method imposes domination on the “self” - it can be only be assigned to an object, or within the local scope of that object, where the object unifies with this self.&lt;br /&gt;&lt;br /&gt;*Delve has no class macro yet, so here is code which manipulates the meta-object model, allowing for the silly Tree class.&lt;br /&gt;&lt;br /&gt;(: Tree (Object.new))&lt;br /&gt;(: Tree.instance_methods (Object.new))&lt;br /&gt;(: Tree.instance_methods.tree&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(me ()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;((Tree.new))))&lt;br /&gt;(: Tree.new&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;(me ()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;((: instance (Object.new))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(: instance.class self))))&lt;br /&gt;&lt;br /&gt;Either that or just use an object&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hmm, I must write a HTML pretty printer for delve...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-3832448103657345716?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/3832448103657345716/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/delve-type-system.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3832448103657345716'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3832448103657345716'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/delve-type-system.html' title='The Delve Type System'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-3503314708165740016</id><published>2009-08-20T21:28:00.001+01:00</published><updated>2009-08-20T21:41:46.381+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='writing'/><title type='text'>Writing</title><content type='html'>I am a semi-being.  Not of thought, of drooling adrenaline.  I exist for others, and they exist for me, and I see myself through them.  But I would exist otherwise, without them but unable to see myself, like a book unwritten, a reality unfurled, a potential undiscovered.  And these others, they are books unwritten too, for I cannot see them even now they can see me - but better unwritten, for finality is a tragedy, whether of books or for the dead.  And I do hate a morbid party.&lt;br /&gt;&lt;br /&gt;Today I saw a brown butterfly against a white wall but for a second it was a white butterfly against a brown wall.  I wonder whether I should be taking sanity pills again!&lt;br /&gt;&lt;br /&gt;Also I drank beer today, for the first time since the weekend.  That was probably the longest I've gone without drink in months.&lt;br /&gt;&lt;br /&gt;I started writing a story too.  I used to get really flustered with trying to make every paragraph perfect, until I'd re-worked it so much that it was entirely unreadable.  I've decided instead to hammer ahead, trying to write something which entertains, rather than worrying about little things like the quality of the prose :)&lt;br /&gt;&lt;br /&gt;I'm always amazed by how much shit people talk.  Really it's all in the perception.  The other day, Lizzie and I were observing the new tap ( we have a new tap ).  It is a tubalar breed, and I observed that while dispensing water it wobbles.  It was fun watching it wobble.  And not only this, it was about as concrete and solid an event as ever has been - it definitely wobbled, there was no question - and it wasn't a bizarre or surprising event.  Predictable, deterministic, perfectly causal.  Yet it was so funny and trippy and far out.  How can such an event occur to two (mostly) sane individuals?&lt;br /&gt;&lt;br /&gt;Anyway thinking about such things has prompted this small spate of writing which may continue wearily like the characters within.  The other tragic thing, rather than just endings, is that in interesting books, people tend to die, shit, piss, puke ( well those three probably make enjoyable reading ), get raped, burned, stabbed, shot etc.  It's such a shame!  It's why I like cheesy horror films - mostly you want that sort of shit to happen to the annoying characters contained.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-3503314708165740016?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/3503314708165740016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/i-am-semi-being.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3503314708165740016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/3503314708165740016'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/i-am-semi-being.html' title='Writing'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-480062558404072872</id><published>2009-08-13T20:01:00.000+01:00</published><updated>2009-08-13T20:02:51.056+01:00</updated><title type='text'>Categorical joke</title><content type='html'>I thought up a joke about category theory,&lt;br /&gt;though it's extremely bad!&lt;br /&gt;&lt;br /&gt;There once was a poor endofunctor called Endo.  Endo was so poor he&lt;br /&gt;couldn't afford to undertake any more natural transformations, so he had&lt;br /&gt;to borrow money from a loan shark.  &lt;br /&gt;&lt;br /&gt;But poor old Endo was sooo poor, he couldn't pay the money back!  He got&lt;br /&gt;more and more in debt to the loan shark until one day the loan shark&lt;br /&gt;came over to his house to demand his dues.&lt;br /&gt;&lt;br /&gt;So the loan-shark banged on the door and shouted "Hey you FUNCTOR!  Give&lt;br /&gt;me back my cash!".&lt;br /&gt;&lt;br /&gt;"But I can't!  I can't give you anything back!", cried the poor&lt;br /&gt;endofunctor, from the upstairs window.&lt;br /&gt;&lt;br /&gt;"And why not? You'd better give me the money" the loan shark asked.&lt;br /&gt;&lt;br /&gt;"But I can't give you anything" moaned Endo, as he began to weep,&lt;br /&gt;"Because I'm not co-pointed!"&lt;br /&gt;&lt;br /&gt;(However, at this point in the joke, the loan shark was no longer needed&lt;br /&gt;so he was garbage collected and Endo lived happily ever after.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-480062558404072872?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/480062558404072872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/categorical-joke.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/480062558404072872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/480062558404072872'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/categorical-joke.html' title='Categorical joke'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-1283997293764644637</id><published>2009-08-11T13:49:00.000+01:00</published><updated>2009-08-11T14:54:26.212+01:00</updated><title type='text'>Delve core</title><content type='html'>(Posted to the Haskell-Cafe mailing list)&lt;br /&gt;&lt;br /&gt;Delve is a new programming language intended to bring the benefits of static type checking and functional programming to object-oriented design and development.   It is an impure, eager language (Yes I can hear the groans of woe and cries for sanity already!)&lt;br /&gt;&lt;br /&gt;Currently Delve supports:&lt;br /&gt;&lt;br /&gt;Higher-order functions/first class functions&lt;br /&gt;Anonymous functions&lt;br /&gt;Lexical closures&lt;br /&gt;First class continuations&lt;br /&gt;Tail-call optimization&lt;br /&gt;A meta-object model (classes are objects)&lt;br /&gt;S-Expression based syntax.&lt;br /&gt;Embedded Haskell expressions within Delve.&lt;br /&gt;&lt;br /&gt;What it doesn't have:&lt;br /&gt;Lots and lots!&lt;br /&gt;Basically what I have is an de-sugared, untyped core language.  An analogy could be made with Haskell core files.&lt;br /&gt;I'm going to be working on the type system for next little while (I have a stack of paper and a pen right here!).  Once that is implemented we'll see where to go.&lt;br /&gt;&lt;br /&gt;Please see the TUTORIAL file included in the source for a brief outlook on Delve's syntax, semantics and planned type system.&lt;br /&gt;&lt;br /&gt;However!  If you're looking for a new project, and especially if you are an undergraduate, then I think Delve would be a good choice for these reasons:&lt;br /&gt;&lt;br /&gt;It's written in a hybrid of Haskell and itself.&lt;br /&gt;It's currently undergoing active development (by me and some pals).  You're not going to be lonely!&lt;br /&gt;It's quite powerful already, without too many lines of code (it's now just about 5.5KLOC - it's no goliath! )&lt;br /&gt;It's a programming language: name a compiler which isn't a cool piece of tech!  Ok, maybe you can but still, it's a chance to work on something non-trivial and interesting.&lt;br /&gt;Quite honestly, I'm a bit of a fool - I am a math undergrad!  So don't you feel foolish about getting involved if you're not a professorial chap!  If you feel like it, get involved in the design, and push me the patches :)&lt;br /&gt;&lt;br /&gt;It does require lots of love though!  It was all hacked out rather quickly :)&lt;br /&gt;&lt;br /&gt;Executables which Delve provides:&lt;br /&gt;&lt;br /&gt;edc -- The Elgin Delve Compiler&lt;br /&gt;&lt;br /&gt;The Elgin Delve Compiler currently supports two backends - the first to a bytecode format for execution on edvm, and the second is to a Haskell source code representation of Delve bytecode.  This allows Haskell to be embedded within Delve, for the express purpose of extending and building edvm.  edc is written in Haskell (GHC).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;edvm -- The Elgin Delve Virtual Machine&lt;br /&gt;The Elgin Delve Virtual Machine executes Delve bytecode files (.dcode format).  Since part of the VM is actually driven by Delve bytecode, edvm can be considered a hybrid of Delve and Haskell (again GHC).&lt;br /&gt;&lt;br /&gt;Delve continues the grand tradition of naming compilers after Scottish Cities (no, Elgin does not have a university).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Delve is released under the terms of the GNU GPLv3.&lt;br /&gt;&lt;br /&gt;For more information on Delve, check my blog at http://killersmurf.blogspot.com/ and the Delve repository at http://github.com/elginer/Delve/&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-1283997293764644637?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/1283997293764644637/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/delve-core.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1283997293764644637'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/1283997293764644637'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/delve-core.html' title='Delve core'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4700531182891501924.post-4915992400401817010</id><published>2009-08-06T17:38:00.000+01:00</published><updated>2009-08-06T17:54:06.368+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Shpider'/><category scheme='http://www.blogger.com/atom/ns#' term='Haskell'/><title type='text'>Maintenance</title><content type='html'>Today I received two emails.  The first one asked for a much needed feature in &lt;a href="http://hackage.haskell.org/package/tagsoup-parsec"&gt;tagsoup-parsec&lt;/a&gt; - allowing user-supplied state, which I added.&lt;br /&gt;&lt;br /&gt;However, the other email reported the fact that &lt;a href="http://hackage.haskell.org/package/shpider"&gt;shpider&lt;/a&gt; no longer worked.&lt;br /&gt;&lt;br /&gt;Shpider uses curl for a backend.  The funny thing about curl is that it only writes cookies to a file when its cleanup function is called, rather than when it recieves them.  However, in the original curl-bindings, this function was only called on garbage collection, through a foreign pointer finalizer.  This resulted in some weird behaviour, like cookies being written at unexpected times.  This is crippling if your program logs in to a website and then expects a cookie to be written to hold the session key.&lt;br /&gt;&lt;br /&gt;So I forked the library to work on a solution.  The obvious one is to call the finalizer manually, which worked before, but seems to crash now ( new GHC? ), so now I have to handle my own garbage collection, in order to get deterministic behaviour.&lt;br /&gt;&lt;br /&gt;I really should put shpider in a git repository, to let others peer at it more effectively.&lt;br /&gt;&lt;br /&gt;In other news, I hope in a couple of days I shall be able to publish the first component of a cool new piece of tech.... ooooh, the suspense.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4700531182891501924-4915992400401817010?l=sillyskynet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://sillyskynet.blogspot.com/feeds/4915992400401817010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/maintenance.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4915992400401817010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4700531182891501924/posts/default/4915992400401817010'/><link rel='alternate' type='text/html' href='http://sillyskynet.blogspot.com/2009/08/maintenance.html' title='Maintenance'/><author><name>spoon</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='19' height='32' src='http://2.bp.blogspot.com/-sqg0U1cPepU/TcqetoKPnRI/AAAAAAAAACg/UZbJIQLwJfg/s220/me_at_lizzies1.jpg'/></author><thr:total>0</thr:total></entry></feed>
