21 December 2010

Positive About Negative Aberdonian Crusty

NOTE: I edited this a couple of times around 22:16, on 21 December 2010, and the morning of the 22nd.

I wrote a song. Give it a listen!

It's a happy blues song about crust music in Aberdeen.

For the benefit of a couple of friends, here are the tabs:


Positive About Negative Aberdonian Crusty
By John Morrice 2010

This work is licensed under the Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-nd/3.0/ or send a letter to
Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA.

Hi guys!

Tuning is a half step down, Eb Bb Db Gb Bb Eb
Time signature is 6/8 for most of the song, but 4/4 at the end.

Notation:

Next bar: |
Hammer on: h
Pull off: p
Don't play this string: x

Notes:
* I skimp on some work by just saying what chord to play for that part.
* The chords used are given at the end of this file.
* Always listen to the song for the rhythm.
* This tab file does not describe the songs structure, only its riffs.
* I know I wrote the bloody song but these tabs may still not be perfect.

Verse:

Eb|-------------0---------|-------------0-----0-
Bb|---------0h2---2p0-----|---------0h2---2p0---
Gb|-------0---------------|-------0-------------
Db|---0h2-------------2p0-|---0h2---------------
Ab|-0---------------------|-0-------------------
Eb|-----------------------|---------------------

Eb|-------------0---------|-------------------------
Bb|---------0h1---1p0-----|-1p0h1p0h1p0h1p0h1p0h1p0-
Gb|-------0---------------|-------------------------
Db|---0h2-------------2p0-|-------------------------
Ab|-3---------------------|-------------------------
Eb|-----------------------|-------------------------

Eb|-------------0---------|--------------0-----0-
Bb|---------0h2---2p0-----|----------0h2---2p0---
Gb|-------0---------------|--------0-------------
Db|---0h2-------------2p0-|---0h2----------------
Ab|-0---------------------|-0--------------------
Eb|-----------------------|----------------------

For the last two bars, strum Gb6 (see the end of this file)

Chorus rhythm part:

Strum

Ab7
Ab7
Gb6
Cb7

Chorus lead part:

Eb|-9p7---9p7---9p7---9p7---9p7---9p7---9p7---9p7---
Bb|-----8-----8-----8-----8-----8-----8-----8-----8-
Gb|-------------------------------------------------
Db|-------------------------------------------------
Ab|-------------------------------------------------
Eb|-------------------------------------------------

Eb|-----3------3------3------3-
Bb|-3h5----3h5----3h5----3h5---
Gb|----------------------------
Db|----------------------------
Ab|----------------------------
Eb|----------------------------

Back into verse, let ring
Eb|-------------------------|--
Bb|-------------------------|--
Gb|-3p0h3p0h3p0h3p0h3p0h3p0-|-0
Db|-------------------------|--
Ab|-------------------------|--
Eb|-------------------------|--

"Solo", on top of the chorus, goes something a little like:

Eb|-------------------------------------------------
Bb|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-
Gb|-7-7-7-7-7-7-7-7-7-7-7-7-------------------------
Db|-------------------------------------------------
Ab|-------------------------------------------------
Eb|-------------------------------------------------

Eb|-------------------------------------------------
Bb|-------------------------------------------------
Gb|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-
Db|-7-7-7-7-7-7-7-7-7-7-7-7-------------------------
Ab|-------------------------------------------------
Eb|-------------------------------------------------

Eb|-------------------------------------------------
Bb|-------------------------------------------------
Gb|-------------------------------------------------
Db|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-
Ab|-7-7-7-7-7-7-7-7-7-7-7-7-------------------------
Eb|-------------------------------------------------

Eb|-------------------------------------------------
Bb|-------------------------------------------------
Gb|-------------------------------------------------
Db|-------------------------------------------------
Ab|-5-5-5-5-5-5-3-3-3-3-3-3-------------------------
Eb|-------------------------5-5-5-5-5-5-5-5-5-5-5-5-

End part is in 4/4 and goes:

Ab5
Gb5
Cb5
Db5

That's it!

The chords:

Ab7
Eb 0
Bb 2
Gb 0
Db 2
Ab 0
Eb x

Gb6
Eb 0
Bb 3
Gb 0
Db 0
Ab x
Eb 3

(Weird) Cb7
Eb x
Bb x
Gb 3
Db 5
Ab 3
Eb x

Powerchords (Fifths)

Ab5
Eb x
Bb x
Gb x
Db 2
Ab 0
Eb x

Gb5
Eb x
Bb x
Gb x
Db x
Ab 5
Eb 3

Cb5
Eb x
Bb x
Gb x
Db 5
Ab 3
Eb x

Db5

Eb x
Bb x
Gb x
Db 7
Ab 5
Eb x

Have a lot of fun :)

7 December 2010

Wireworld

On my quest for enlightenment, I have completed the Wireworld cellular automaton task on Rosetta code. Smalltalk wasn't on the list, so I gave learning GNU Smalltalk a try, and I experienced some success in this!

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 finding the contour of the graph).

However, my solution is a bit big - in fact, it's written in both Smalltalk and C, and generates animated GIFs.

Wireworld animation

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.

Anyway, here is the README so you can find out about it, with an additional link to the source added there.


NAME
jwgif - Johnny's Wireworld GIF creator.

ABOUT

jwgif is a simulator for the Wireworld cellular automaton. It renders to an animated GIF,
which it sends to stdout.

REQUIREMENTS

gcc
GNU Plotutils
GNU Smalltalk

COMPILATION

./compile.sh

USAGE

jwgif FILENAME GENERATIONS WIDTH HEIGHT SQUARESIZE

OPTIONS

FILENAME is a path to a Wireworld file - see WIREWORLD FILE FORMAT below.

The following must be positive integers:

GENERATIONS determines the number of frames produced.
WIDTH the width of the output GIF, in pixels.
HEIGHT the height of the output GIF, in pixels.
SQUARESIZE the size of the square cells, in pixels.

EXAMPLE

./jwgif arena/cyc3inhib.ww 200 110 50 10 > 3cycle.gif

WIREWORLD FILE FORMAT

Wireworld is a cellular automaton with some similarities to Conway's Game of Life. It is
capable of doing sophisticated computations (e.g., calculating primeness!) with appropriate
programs, and is much simpler to program for.

A wireworld arena consists of a cartesian grid of cells, each of which can be in one of
four states. All cell transitions happen simultaneously. The cell transition rules are this:

Input State Output State Condition
empty empty
electron head electron tail
electron tail conductor
conductor electron head if 1 or 2 cells in the neighborhood of the cell are in the state “electron head”
conductor conductor otherwise

A Wireworld program can be stored in a file using the following notation:

"H" for an electron head
"t" for a tail
"." for a conductor
space for empty.

Here is an example program, which demonstrates two cycle-3 generators and an inhibit gate:

tH.........
. .
...
. .
Ht.. ......

The output for this program is included with the jwgif distribution, with the file name 3cycle.gif

jwgif uses the following convention for colouring cells in the output GIF:

An electron head is red.
A tail is blue.
A conductor is green.
Empty cells are black.

This section was ripped off from http://rosettacode.org/wiki/Wireworld on 6th December 2010. Thanks guys!

LICENSE

jwgif is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

jwgif is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with jwgif. If not, see <http://www.gnu.org/licenses/

Studying

So I got CARPS text mode stable, and I have plans to create a graphical version.

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:

I suck! Oh god, I suck. There are so many reasons why I suck, and thankfully I have learned some of them.

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 Rosetta Code 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.

11 November 2010

CARPS

Wow, I appear to have finally put out a stable release of CARPS!

From the CARPS README:

CARPS, the Computer Assisted Role-Playing Game System, is a tool for playing pen and paper RPGs over the internet.

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.

CARPS is an extensible system: game rules are provided by ‘mods’.

CARPS supports these mods by providing:

* Text-mode user interfaces for the players and the dungeon master.
* An easy to use probabilistic API which not only rolls the dice, but can report the probability of various game events occurring.
* Automated static character sheet verification, according to a schema defined in YAML. For example, a game might require your strength to be an integer.
* 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.
* 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.

CARPS has other strengths:

* Anyone can play or host a CARPS game! All you need is an email account.
* CARPS is designed to be secure. Multiple email security options are supported, and all CARPS messages are cryptographically signed to prevent spoofing.
* You can instruct CARPS to use your favourite text editor and terminal emulator.
* CARPS is easy to configure because it includes a wizard.

However, CARPS is new and the following features, which you might take for granted, are not yet supported:

* No GUI
* No support for maps
* No chat - all communication goes through the Game Master.
* Games are currently invite only, at the discretion of the Game Master.
* Security mechanisms are not well audited.

Requirements:

For users:

* GNU/Linux
* ruby 1.9
* rubygems
* openssl
* highline

For developing CARPS, you will also need:

* hoe
* rake
* newgem
* cucumber

To Install:


# Install the gem

sudo gem install carps

# Initialize the carps user directory. Run this as your everyday user.

carps_init


Basic Instructions:

Run carps -h for help

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.

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.

You’re also going to need to install a mod to play CARPS. See the example ‘fools’ mod:

* github.com/elginer/fools

Campaigns (For the DM):

When you set up a new game, CARPS will ask for you to enter the name of a campaign.

This allows you to create game resources prior to starting a game.

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

You should create the following directories

the campaign directory:


/home/user/carps/dm/campaigns/foo/bar


the NPCSs directory:


/home/user/carps/dm/campaigns/foo/bar/npcs


the rooms directory:


/home/user/carps/dm/campaigns/foo/bar/rooms


NPCs are defined as YAML files, according to the mod’s schema. Put them in the NPCs directory. They MUST have the .yaml extension.

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.

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 DND D20 mod for it.

25 October 2010

Esperanto X-System fun

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.

It's a it of fun.

Here you go.

There isn't much to it but I am smug at how neat and tidy the html and javascript looks :)

22 September 2010

PROGRAMMER KEYBOARD

EDIT: fixed a bug! Results should be good now :) Damn, why did I forget to run the tests :p


Computer keyboards are fucking stupid, especially for programmers.

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.

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.

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

The solution: design a programmer keyboard!

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:

linux - C
adagide - ada
axiom - c#
django - python
ghc - haskell
go - go
irrlicht - c++
limewire - java
phpbb3 - php
prototype and jquery - javascript
rails - ruby
regexkit - objective c
racket - racket

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.

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.

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.

' ': 0.12601734868442382
'e': 5.672758827442585e-2
't': 4.506425247731305e-2
'i': 3.6282361484752744e-2
'r': 3.5587647133639044e-2
'\t': 3.52634742130502e-2
'\n': 3.45691915152049e-2
'_': 3.438222642926237e-2
's': 3.201379627014596e-2
'n': 3.0954960014858875e-2
'a': 3.058217872499613e-2
'o': 2.6776405034843204e-2
'c': 2.3632039961301494e-2
'd': 2.329124049378265e-2
'l': 1.9319481645750994e-2
'u': 1.761928496254444e-2
'0': 1.737397825253189e-2
'p': 1.6228575776688497e-2
'f': 1.5556196850182672e-2
',': 1.4572080038859849e-2
'*': 1.3460275453084754e-2
'm': 1.2857509828221805e-2
')': 1.2389877996691128e-2
'(': 1.2383996720909098e-2
';': 1.140731013627353e-2
'h': 1.0710680981789305e-2
'-': 1.0232090684508581e-2
'x': 1.0086694597923173e-2
'g': 9.400323788643899e-3
'b': 8.972889667733516e-3
'E': 8.898045202243342e-3
'=': 8.357994322825149e-3
'v': 7.983041606459754e-3
'S': 7.407318795659219e-3
'T': 7.301129459599258e-3
'R': 7.1601262346295165e-3
'/': 7.1380145327522146e-3
'A': 7.117130673860958e-3
'I': 7.099489478546994e-3
'C': 6.66979575805779e-3
'>': 6.316573098911656e-3
'.': 5.726058267571846e-3
'1': 5.685534184968124e-3
'N': 5.413383379318554e-3
'D': 5.24449377399052e-3
'P': 5.0353985619458206e-3
'L': 5.008180717747133e-3
'O': 5.000104327173332e-3
'k': 4.9537792457673745e-3
'w': 4.742584988103445e-3
'y': 4.725471515230428e-3
'2': 4.638324931590688e-3
'M': 4.5006262229531635e-3
'"': 3.800355652024797e-3
'F': 3.764420517430011e-3
'U': 3.1530152471186336e-3
'{': 3.055959062530431e-3
'}': 3.0551233923309254e-3
'B': 3.0211399095564015e-3
'3': 2.9180155749053346e-3
'G': 2.7770136659516554e-3
'4': 2.5617397584948654e-3
'8': 2.3449629606950287e-3
'#': 2.2478633475767726e-3
'&': 2.2210126718594423e-3
'6': 2.162497333669207e-3
':': 1.9414777000847955e-3
'H': 1.8788563917804559e-3
'q': 1.8209240487057808e-3
'<': 1.6977541573950867e-3
'5': 1.6778586265665519e-3
'V': 1.665461755260506e-3
'\\': 1.5621847627462226e-3
'X': 1.4939677541453535e-3
'[': 1.4782940028443977e-3
']': 1.4776491549739134e-3
'+': 1.4496245929290891e-3
'9': 1.3384093915275372e-3
'7': 1.3184046313658388e-3
'W': 1.2953598741004282e-3
'K': 1.2184137309589008e-3
'z': 1.2113717290099994e-3
'\r': 1.143696919026762e-3
'\'': 1.0093106228178275e-3
'Y': 9.986745810030226e-4
'|': 9.358519222411643e-4
'%': 8.897926760797742e-4
'!': 7.546115061692628e-4
'j': 6.665502913662852e-4
'Q': 4.7705713856824653e-4
'Z': 3.924557299928266e-4
'@': 3.550282331834911e-4
'?': 1.816549611314985e-4
'$': 1.7383124564164268e-4
'J': 1.5937875724642036e-4
'~': 1.2080895849508404e-4
'^': 3.6191757726917574e-5
'`': 3.1301442039734356e-5
'\f': 3.8032864197953453e-7
'\ESC': 5.264064248851689e-9
Total characters: 759869145

You suck \ESC. No one loves you!

Note that the total does not reflect the number of characters I ignored ala the last paragraph.

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.

By far the most interesting thing to note is that '(' is more popular than ')'. Don't they come in pairs?

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:

Most people are right handed.
Your index fingers are stronger than your pinkies.

Hence, you're gonna want the most used keys in the middle-right of the keyboard.

The last step is to actually make the bastarding thing.

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.

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.

* The program is split into two parts.

frequency.hs:

-- Copyright John Morrice 2010.
-- Distributed under the terms of the GNU General Public License v 3

{-# LANGUAGE BangPatterns #-}

module Main
   (freq_test
   ,file_test
   ,main) where

-- | GHC haskell key frequency program

import Control.Monad

import qualified Data.ByteString.Lazy.Char8 as Z

import qualified Data.ByteString.Char8 as B

import Data.Array.MArray
import Data.Array.IO

import Data.List

import System.IO

import System.Posix.Process

import System.Environment

import GHC.Int

main :: IO ()
main = do
   as <- getArgs
   if length as /= 1
      then
         error "Usage: frequency DIR"
      else do
         let dir = head as
         prgs <- find_prgs dir program_exts 
         contents <- fmap Z.concat $ mapM strict_read prgs
         (freq, total) <- frequency contents
         format_frequency freq
         putStrLn $ "Total characters: " ++ show total

strict_read :: FilePath -> IO Z.ByteString
strict_read fp = do
   contents <- B.readFile fp
   return $ Z.fromChunks [contents]

format_frequency :: IOArray Char Double -> IO ()
format_frequency ma = do
   as <- getAssocs ma
   let sorted = reverse $ sortBy (\(_,fr1) (_,fr2) -> fr1 `compare` fr2) as
   mapM_ (\ (ch,fr) -> putStrLn $ (show ch) ++ ": " ++ show fr) sorted

freq_test :: IO Bool
freq_test = do
   d <- freq_data >>= getAssocs
   roccs <- new_occs
   right <- mapArray fromIntegral roccs
   writeArray right 'e' 0.5
   writeArray right 'd' (3/8)
   writeArray right 'a' (1/8)
   rightl <- getAssocs right
   return $ d == rightl

freq_data :: IO (IOArray Char Double)
freq_data =
   fmap fst $ frequency freq_input

freq_input :: Z.ByteString
freq_input = Z.pack "eeeeddda"

file_test :: IO Bool
file_test = do
   files <- fmap sort $ find_prgs "test_files" ["c", "rb"]
   putStrLn "Found:"
   print files
   let expected = sort (actual "test_files/")
   putStrLn "Expected"
   print expected
   return $ files == expected
   where
   actual dir = map (dir ++) ["a.c", "b.c", "c.rb", "d.rb"]

-- | Determine the frequency of characters in a bytestring as a fraction of the whole
frequency :: Z.ByteString -> IO (IOArray Char Double, Int64)
frequency by = do
   fr <- occur by >>= mapArray (\o -> fromIntegral o / fromIntegral total)
   return (fr, total)
   where
   total = Z.length by

new_occs :: IO (IOArray Char Int64)
new_occs =
   newListArray (min_char, max_char) (repeat 0)

min_char :: Char
min_char = '\9'

max_char :: Char
max_char = '\126'

occur :: Z.ByteString -> IO (IOArray Char Int64)
occur bz = do
   occs <- new_occs
   zfoldrM increase occs bz
   where
   increase :: Char -> IOArray Char Int64 -> IO ()
   increase ch oc = 
      if ch >= min_char && ch <= max_char
      then do
         count <- readArray oc ch
         let n = count + 1
         n `seq` writeArray oc ch n
      else
         return ()

zfoldrM :: (Char -> IOArray Char Int64 -> IO ()) -> IOArray Char Int64 -> Z.ByteString -> IO (IOArray Char Int64) 
zfoldrM f ar bz =
   if Z.null bz
      then return ar
      else do
         f (Z.head bz) ar
         zfoldrM f ar (Z.tail bz)

program_exts :: [String]
program_exts = 
   ["bas", -- basic
   "java", -- java
   "hs", -- haskell 
   "rb", -- ruby
   "py", -- python
   "php", -- php
   "m", -- objective c
   "c", "h", -- c
   "cs", -- c#
   "js", -- javascript
   "ads", "adb", -- ada
   "cxx", "cpp", "c++", -- c++
   "scm", -- scheme, racket
   "pas", -- pascal, delphi
   "go" -- go
   ]

-- | A regular expression which matches files with the given extension
extension_regex :: String -> String
extension_regex = (".+\\." ++)

-- | Find program files in the given directory matching the given extensions
find_prgs :: String -> [String] -> IO [String]
find_prgs dir exts = do
   writeFile "result" ""
   mapM_ (find_prg dir) exts
   fmap lines $ readFile "result"

--- | Find program files in the given directory matching the given extension
find_prg :: String -> String -> IO () 
find_prg dir ext = do
   pid <- forkProcess $
      executeFile "./finder.sh" False [dir, "-regex", extension_regex ext] Nothing
   getProcessStatus True True pid
   return ()


-- Source ends with this line


finder.sh

# Source begins with this line
#! /bin/bash

find $* >> result
# Source ends with this line

8 September 2010

JOrbit

I finished my last software engineering assignment today, and I needed to relax, so I wrotekludged a little Orbit clone.

I used to love that game, so this afternoon I murdered it ;)

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)

It's also full of bugs. How many can you find?!

Instructions:

Attempt to hit the target
Move the mouse to aim
Press the left mouse button to charge
Watch the force meter!
Let go to fire
If you get an impossible level just refresh

If you want to see the code, there's the development repository

It's a total hack but I'm still pleased because:

It's written entirely in javascript! I use raphael for rendering and jquery for lots of things

It has proper physics, with gravity and everyfink

I wrote it in an afternoon!

7 September 2010

New look (again)

Just had a look at this on a windows machine and saw how fucked up it looked! MY GOD IT HAD COMIC SANS.

Despite the nasty fonts, my own fault, I'd forgotten how shitty everything looks on windows anyway.

I've tried to make it have less of a contrast, as well, for the eye pain.

Anyhoos, I set up a wiki on my local machine, with rails and wagn. It's good because I know ruby pretty well, and I'm planning on modifying the thing ala last post's ideas.

I've put on a boring sort of style - I better check it on windows before I release it to the wild, though!

6 September 2010

carps is nearly done

carps is very nearly done: tonight I shall just about polish it off. Then I have to write a user manual (with snm ;) 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 :)

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.

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 CLiki, because it looks cool and I've been wanting to learn lisp.

The reason that we need such a thing is because a bit of a community built around lepht's blog - 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.

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.

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 joint diagramming library, which I've used before and found to be stable, easy to use, easy to write plugins for and generally shiny.

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!

That would probably do it, as long as everyone is happy.

29 August 2010

CARPS repository

Hi, just putting out a shout about carps: it has a repository now.

Another couple of hacking sessions and it'll be ready for mod writing.

Also, I realized the underlying protocol would be useful for writing other systems which communicate over email. Strategy games come to mind.

23 August 2010

mud

From writing my little projects I've learned one thing:

I cannot do very much.

It's a bit sad really, but it's true. However this knowledge now empowers me!

Ironically, I'm applying the lesson by taking on another project. However, I have structured it around having other people write all the code :)

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.

Game rules and interfaces will be implemented as mods. Hence, initially, I only need to write the lower level software.

I will post the repository soon!

20 August 2010

New look

I made this blog less eye hurty. The existing css frightened me so I deleted most of it and rewrote some.

Thus some things may not work! Especially on *your* browser.

Re the algorithm in last post.

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.

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.

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).

I wrongly stated that the working from one graph can be insert into another. It CANNOT be.

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.

The setInterval function may be useful for implementing the algorithm in javascript - that way we can run a long computation without freezing the browser.

Optimized algorithm later :)

19 August 2010

Fast software lolz

Re the last post, quest for propositional logic validation in O(N)

Firstly, since this post contains algorithms, I'd better say:

The algorithms described in this post, are copyright John Morrice, 2010, under the GNU Free Documentation License. http://www.gnu.org/licenses/gpl.html


.......where were we?
Unfortunately, the input will certainly NOT be well formed.

But I think I have such an algorithm. First, a concrete example.

First, a key.
P->Q
or similar arrows
means P implies Q

That is, Q must be true when P is true.

P-!>Q means P implies not Q. That is, Q must not be true when P is true.

Now the example:
What we will receive is a graph. It's simple, but has enough sophistry.

A-!>C
|   ^
|   |
v   |
B----

So what can we do?
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.

So we find A is not implicated. IMPORTANTLY, this means it has an empty implication set.

We see A->B. And A-!>C. We ALWAYS look at implications first.

B gets A's empty implication set, and adds A to it.

We see B->C. C gets B's implication set, and adds B to it.

Now we try the other path, A-!>B. We see that B has A in its implication set, and note that there is a contradiction.

What just happened?!

The algorithm:
Find unimplicated atoms, As.
For each A in As, validate(A, empty).

Validate(A, implication_set):
Set A.implication_set to a clone of implication_set
Get Is, the atoms implicated by A.
Get NIs, the atoms implicated to not be true by A.
For each I in Is, validate(I, insert A into implication_set)
For each NI in NIs, Contradiction?(NI, A)

Contradiction?(C, A):
if A is member of C.implication_set
then there is a contradiction

Comments:

This algorithm works along sequences of implications. For instance, if we started with:
A-!>B
|   ^
|   |
v   |
C   |
|   |
|   |
v   |
D----

Then when we arrive at C->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.

Also notice, that either C or D above, could imply not B and the contradiction would still be detected.

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.

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.

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.
What I need is a better implementation of it ;)

18 August 2010

Slow software, lolz

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.

I don't think a user would enjoy waiting for that length of time!

Edit:

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!

Then all you need to do is check for sentences of the form

A_0 implies A_1 .... implies A_n implies NOT A_m where m < n

Fast solution.
For any of A_x in A_n:
if A_x == A_m the sentence is invalid

O(N) time, about 2 lines of code....


...a lot better than my 460 line symbolic reasoning engine I wrote in the last three days which runs at O(N^N).....
I am a tool.

Note to self

Work out computational complexity BEFORE implementing new supposedly 'faster' software

10 August 2010

Obelisk

I've been working on the report. 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!

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 :)

8 August 2010

Chomp

I'm working on a website for a friend and I needed to chomp. So I worked out the regex.

Here you go.

Javascript:

EDIT: corrected!

// chomp
function chomp(text)
{
   // Check for empty
   if (text.search(/\S/) === -1)
   {
      return "";
   }
   else
   {
      // Chomp it.
      return text.replace(/^\s*((\S+\s+)*?\S+)\s*$/, "$1");
   }
}

3 August 2010

Obelisk semantics

I'm just a chuftie, been working on the semantics. Trying to be precise without being too verbose in my logic.

I want to share some, because I'm just happy that the snm math plugin is working well.

In English:

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.

The source (I use '.' to separate constraints for readability):

forsome F.
Fb member F. Fb = Block.
Wc member F. Wc = Set. forall C. C member Wc. C = ConstantDefinition.
Wf member F. Wf = Set. forall G. G member Wf. G = FunctionDefinition.
forsome S. forsome Bq. forsome Wcq. forsome Wfq.
new_scope(Fb, S, Bq). new_scope(Wc, S, Wcq). new_scope(Wf, S, Wfq).
scope(F, S) iff scope(Fb, Bq) and scope(Wc, Wcq) and scope(Wf, Wfq)

Output:

∃ F.
Fb ∈ F. Fb = Block.
Wc ∈ F. Wc = Set. ∀ C. C ∈ Wc. C = ConstantDefinition.
Wf ∈ F. Wf = Set. ∀ G. G ∈ Wf. G = FunctionDefinition.
∃ S. ∃ Bq. ∃ Wcq. ∃ Wfq.
new_scope(Fb, S, Bq). new_scope(Wc, S, Wcq). new_scope(Wf, S, Wfq).
scope(F, S) ⇔ scope(Fb, Bq) ∧ scope(Wc, Wcq) ∧ scope(Wf, Wfq)

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.

snm_math

I've written a math plugin for snm called snm_math

It turns this sort of thing:

forall E. A subset B. E member A implies E member B

Into this:

∀ E. A ⊆ B. E ∈ A ⇒ E ∈ B


And this:

n member R. m member R. m > 1 iff (n / m) < n

Into this:

n ∈ R. m ∈ R. m > 1 ⇔ (n ÷ m) < n

I'm going to go and work on the redraft of Obelisk's semantics now, with nice looking math symbols! :)

30 July 2010

Grammar

Refining Obelisk's Grammar yet more. Now there is no need for the type terminator #

So the function from last post would now be written.

// An accumulating implementation of the factorial function. Tail recursive.
(Int -> Int)
def factorial x
{
   (fact 1 x)
}
where
{
   (Int -> Int -> Int)
   def fact acc i
   {
      if (i > 0)
         // Recurse
         {(fact (i * acc) (i - 1))}
         // We've recursed enough.  Return.
         {acc}
   }
}

After so much Haskell Programming, I'm liking the syntax without significant whitespace a lot.

27 July 2010

Obelisk syntax

I decided to change Obelisk's syntax.

For example, to define a function, you used to do (still the case on the online repository):

// An accumulating implementation of the factorial function. Tail recursive.
((Int -> Int) #
def factorial x
   ((fact 1 x))
   where
   ((Int -> Int -> Int #
   def fact acc i
      ((if (i > 0)
         ((fact (i * acc) (i - 1)))
         (acc)))))) 



That was okay because the syntax is unambiguous and was not affected by whitespace.

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.

This was especially a problem with where clauses! Multiple closing parenthesis are very ugly.

So the above function will now be written as:

// An accumulating implementation of the factorial function. Tail recursive.
(Int -> Int) #
def factorial x
{
   (fact 1 x)
}
where
{
   (Int -> Int -> Int) #
   def fact acc i
   {
      if (i > 0)
         // Recurse
         {(fact (i * acc) (i - 1))}
         // We've recursed enough.  Return.
         {acc}
   }
}



It looks much tidier, and still doesn't care about whitespace, which is great.

Edit: I'm still not so happy with it. The if statement looks ugly. Perhaps ruby style do and end would look nicer.

Edit2: Fixed it, removed need for functional application parenthesis around if expression.

Language.c

Just came across this really cool haskell library for manipulating C

Language-C

snm

...The Simple Nice-Looking Manual Generator!

I became annoyed maintaining Obelisk's long report in xhtml, so I wrote a program to make writing documentation easy.

snm github
snm on hackage

snm allows you to write clean, web-friendly reports, user guides and manuals without having to edit fickle html.

snm allows you to structure your document in a modular fashion.

snm document sections are written in yaml and are easy to write and understand.

snm is a generator of small, valid xhtml files.

Read the snm manual online!

23 July 2010

Code generation and testing

Lexing, parsing and type-checking have this in common: they can succeed or they can fail.

It is very easy to write tests to confirm the correctness of these stages. Much more difficult is to write tests for code-generation.

Even if a formal method is given which proves the correctness of a code-generation pass, it must still be tested for implementation errors.

Hence, THE PLAN:

Every code generation phase takes one form of intermediate language and produces the next.
To test Obelisk, a series of sample programs will be written, which under the semantics will produce a specific output for a specific input.

Then an interpreter must be written for every intermediate language. Each interpreter must be tested on all sample programs.

If an interpreter produces incorrect output when running a sample program, the compiler stage associated with that interpreter has a bug!

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.

21 July 2010

Learning basic assembler.

I've been learning assembler, so I can write a code generator for Obelisk. I'm at page 98 of (the PDF version) of Dr Paul Carter's PC Assembly Language.

So far, I've learned how to call C functions. I need to do this because the Obelisk runtime is written in C!

Anyway, it aint much, but here's a 'hello world', written for NASM, the netwide assembler..

hello.asm:




; Hello world program!

; The data segment contains data that is always in memory (unlike the stack)
segment .data
format db 'Hello world!', 10, 0 ; The format string for printf

; The text segment contains the code the machine will execute
segment .text
   global main ; Main must be global for gcc to find it!
   extern printf ; We must declare that printf is defined in another object file.

main: push dword format ; Push the argument to printf on to the stack.
      call printf ; Call printf
      pop eax ; Remove the argument from the stack



This will need to be linked to libc because it uses printf. I'm using gcc because it's simple.
So, in the shell, assemble and link and run with:




$ nasm -f elf hello.asm && gcc hello.o -o hello && ./hello
> Hello world!



On my computer, the object file hell.o is only 608 bytes long

20 July 2010

Garbage collection

Obelisk has a simple copying garbage collector now :)

18 July 2010

Obelisk

I've started a new programming language project: Obelisk.

Check out what I have so far at

Obelisk github repository

That is the place to go if you want to understand the syntax and semantics of Obelisk.

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 I am not a crackpot!

Firstly, about my last programming language project, Delve. It petered out for a number of reasons:
I didn't have a proper lexer.
I wrote my own (buggy) parser.
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.
I wrote the runtime in Haskell, which processed high-level bytecodes. It was very slow.
My approach was a rather chaotic, and I didn't produce very much documentation (thank you beer).

On the plus side, I did learn a lot about programming language design, and the process definitely improved my programming skills .

However, Obelisk is different!

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.

Well, it will be and have all these things; and it will work out this time! I know this because:

I have a solid lexer, based on Text.Parsec.Token

The parser is generated by happy, which also has the benefit of showing that the grammar is unambiguous. This is A Good Thing.

Obelisk's semantics are much simpler, so I already have a type-checker for non-polymorphic non-higher order (lower order?) functions.

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 The Dragon Book to suit its needs.

Also my approach is better:

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.

I also have ~1500 words of documentation so far, in a html file. 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.

So aye, you might say that I'm rather a chufty at this juncture. That's about all for now. Look at the repository for more information!

25 June 2010

Wheee! ....and a small utility

"Hello,

      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.

      Thank you for understanding.

      Sincerely,

      The Blogger Team"

ACE. From reading other's posts on the subject, I was worried I'd never see this blog again.

I hope they don't see my copy of the email above and think I'm leeching data and spamming it out again!

Anyway, here's a small utility, in haskell, for creating c/c++ header files, using #define to prevent multiple inclusion:

mkheader

See the README for details on how to use.

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.

20 June 2010

Car wash

Bry and Hanner and I took the car through the wash today.

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.

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.

9 June 2010

Transcribed some Silly Wizards banter

Andy Stewart: "Thanks very much indeed. Och well, you're not as tough as you thought!

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."

John Cunningham: "It's kinda, it's like a lust song."

Andy Stewart: "That was Johnny Cunningham there. You'll eh... you'll hear a lot more of him before the night is out, no doubt.

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.

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...

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."

Transcribed from the video: Silly Wizards Live - Willie Archer and the Banks of the Bann

28 May 2010

A circular ring of electrodes with a power gradient facing North

Lepht wants to know where North is. However, instead of buying a compass, she's decided to turn herself into one. What sort of self-respecting transhumanist wouldn't?

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.

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!

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.

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.

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.

That's my thoughts at least.



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.

Lepht proposed the following Microcontroller code:


while (poweron)
get north direction from compass module;
cast to a degree out of 360;
figure out which electrode's "domain" that number falls into;
activate that electrode;


However Max had an idea for improvement:

"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."

My comment was a proposed solution:
The sort of function we might use may be a quadratic with a parabolic graph.

y = P - (x - n)^2

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.

This graph has a maximum at (n, P) which is what we're looking for.

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

/* 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' */

float electrode_power(float theta, float north, float power)
{
   return power - (theta - north)^2;
}

8 April 2010

Agilish programming and haskell type classes

I'm drinking a lovely bottle of wine. So time to write a little about a little programming technique.

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*".

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!

However the relative lack of planning can cause problems:

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*:

class Widget:
   Hi! I'm a class providing a widget. Clicking me executes method clicked!

   method add:
      Hello there, this is what happens when I'm added to the window!

   method clicked:
      Hello there, I'm what clicking me does!

* if you don't study design patterns that is, but this is beside my point

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:


class Widget:
   Hi! I'm a class providing a widget. Clicking me executes method cliked!

   method add:
      Hello there, this is what happens when I'm added to the window!

   method clicked:
      Hello there, I'm what clicking me does!

   method remove:
      Hello there, I've been removed!

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.

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.

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.

Importantly, unlike Java interfaces, you can declare a Haskell data type to be an instance of a type class without having to alter the file containing the new instance.

Here is a definition of a simple, one function, type class

class Eq foo where
   (==) :: foo -> foo -> Bool

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).

I am not intending to write a Haskell tutorial; there are many good books and tutorials available; I'm just trying to provide enough information so uninformed readers might see the benefits of programming in this style, not necessarily in Haskell.

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

class AddableWidget w where
   -- Hello, I'm a widget that can be added
   add_widget :: w -> IO () -- IO () indicates an input output may be performed during the function, the () shows that there is no result 'returned'.
      -- I've been added to the GUI!

class ClickableWidget w where
   -- Hello, I'm a widget that can be clicked
   clicked :: (Int, Int) -> w -> IO ()
      -- I've been clicked

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:

class RemoveableWidget w where
   -- Hello, I'm a widget that can be removed
   remove :: w -> IO ()
      -- I've been removed

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 ;)

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.

Maybe tomorrow I might provide an example of how to perform this with a strongly typed object oriented language.
Delve was meant to answer that question.... whenever will I get round to finishing it.

4 April 2010

Increased university admission and utlitarianism: Why I really don't give two craps

Inspired by the the political probing of our beloved scumbaggav

On University degrees and utilitarianism: Utilitarianism demands that people be qualified to perform jobs, benefiting everyone, right?

Well, with the exception of engineering, most degrees are not vocational: they do not lead directly into a job.

For example this is a 'graduate' software engineering job, 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.

Many other jobs are much more specific, some don't even require a degree but vast knowledge of a specific problem domain.

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.

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?"

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.

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.

Clearly good for all.

PS: Ahhh, rants on one small issue

18 March 2010

Religion must be stopped.

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'.

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.

2 March 2010

dead server

My server is dead; my hosts, linuxvps.org are no more!

Someone tracked me down on facebook to ask about the Kolmogorov programming language; which surprised me!

10 February 2010

A nice asynchronous bit of coms

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.

Here is my solution:

The client and server both start out with

communications_number = 0

The client sends the request asynchronously to the server, along with its current communications_number

When the server receives a request, it checks the communications number.
If this number is equal to the current number, then the server increments its communications_number.
Otherwise, it does not.

Then the server sends the response back with its current communication_number.

When the client gets the server's communication_number, it checks whether or not this number is greater than its current communication_number.

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!

If it is greater, then its a new packet, and so we set our communication_number = the server's communication_number.

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.

Or in other words, we can have sequential behaviour without having to wait for sequential computations to finish!

I think I might wrap this behaviour up in a javascript prototype object!

9 February 2010

Letterscore!

Letterscore is a new super fun web game by me!

Check it out at letterscore.co.uk!

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.

Then you make a word.

Then the game tells you whose word is longer, or whose word is not a word!

The objective is to climb the league.

It's lots of fun; and has everyone giggling.

(And is kinda like the television program countdown)

26 January 2010

transcendental argument for the existence of god

The transcendental argument for the existence of god claims that there are logical absolutes, a product of the mind, which are separate from the physical world.

If the universe were to end, would the logical value True still be True?

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.

When these people talk about True being True, you see it as somehow different from an Alcoholic living in Elgin.

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?

Why, oh why oh why do we need a god to be responsible for creating these dull, boring facts for us?

Ahhh, their argument is deeply flawed, boring and useless. And the last two are worse than the first.

21 January 2010

approach anxiety lolz

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, an inspirational guide for meeting women extremely funny.

Here's a memorable quote:

"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)"

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:

"Now he can progress where it’s most important. He can get out every day and meet new women. Everything else is secondary."

Maybe it's because he learned from the best; from "Cory Sky (the guy who picks up women with eye contact alone)"

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."

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?

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.

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.

16 January 2010

reading philosophy in the pub

I have refreshed myself in the company of people from Elgin. Three things happened:
A lady (who was be-boyfriended) came and sat next to me, so I gave her a look until she went away.

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?!
(tbh I quite it like, I think it's a good read)

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.

Would that I was quicker freeing some mobile phone memory, I would have captured it in video format. Alas.

15 January 2010

Web dev

I've come back from Aberdeen with a lovely newsecond hand Guitar! which I love waaaay too much.

Anyway, that whole thing rather distracted me from my business plans here, wasting ovar nine thousand man-hours.

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!)

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.

// From a list of lists of two elements
// Create application/x-www-form-urlencoded parameters
function params(ps)
{
if (ps == undefined)
{
return "";
}
else
{
var map = function(l,f)
{
var a = [];
var i;
for(i=0; i<l.length; i++)
{
a[i] = f(l[i]);
}
return a;
};
var fold = function(l,s,f)
{
var i;
for(i=0; i<l.length; i++)
{
var s = f(s, l[i]);
}
return s;
}
var intersperse = function(i,l)
{
var f = function(li,e)
{
li.push(i);
li.push(e);
return li;
}
var l = fold(l,[],f);
l.splice(0,1);
return l;
}
var join = function(ll)
{
return fold(ll,[],function(o,l)
{
return fold(l,o,function(oo,e)
{
oo.push(e);
return oo;
});
});
}
// Pair the inputs
var ps_pairs = map(ps,function(p)
{
return p[0] + "=" + p[1]
});
var amps = intersperse("&",ps_pairs);
// join them together
var joined = join(amps).join("");
return joined;
}
}


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...

7 January 2010

Facebook apps

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.

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!

So I have learned how to speak to facebook. My progress wasn't entirely without mistakes.

This story applies:
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.

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.

Anyway, I use haskell (predictably) and happstack. I run within an Iframe, and use facebook connect for API calls.

I think that's the easiest way!
Anyway, this is the really simple word game I made: uncensored originality

Now, since I have less to learn, I am going to make a more complex game! Woohoo!