Tuesday 22 November 2011

Functional Programming in Haskell

Wow, I have submitted my assignment for the Functional Programming in Haskell course.

I am really tired.

The period allotted to the assignment is six weeks. I have put in over 60 hours and taken two days leave. Yeah, I know, they said about 25 hours should do it, but it takes as long as it takes.

I have known that Functional Programming was the missing element of my experience for a long while. I asked for and was given this course by work - yay work! It is an expensive course and I could not have afforded the 7 days holiday it would have taken without their support.

These seven weeks started much earlier: This year I have written some R code, which is a sorta functional language. I tried to do some prestudy: I bought the course book and read chapter 1 twice (once on holiday). I read through the prestudy material. Very little of this cohered, but it was just enough to enable me to keep my balance during the course.

The course was great! The lecturer served on the Haskell committee. The SoftEng department at Oxford is smart in every sense. The lunches at Kellogg College were great. The other students were really bright. I just about kept up, contributing more than most and not being wrong as often as some. On Thursday I caught myself gurning during the lecture: it was all so elegant!

Immediately the course ended, I had hopes of Friday afternoon but it was not until the evening, I started organising myself. Reading the questions repeatedly, I tried chipping away at them.

Things soon went pretty horribly wrong: I could not be sure I understood the meaning of the questions, what level of completeness was expected or what shape the answers were meant to have. The assignment centred upon producers, which we had hardly touched upon and which did not feature in the course documents, consumers being the main focus. So I continued to erect a structure of yak hair: we would need a test harness, Latex processing, bibliography.

I did manage to get an answer, thought it was right, was elated. Read in Bird that my answer was wrong (though, infuriatingly the answer was 'left as an exercise'), was pretty disconsolate. Researched further and discovered that the answer was that the number of trees that can be generated from n leaves is the Catalan number for n-1.

Managed to write the generator and tests. Yay!

In between the ups and downs I had managed to pick off list, length etc.

Managed to do some pretty solid work around higher order functions, though was running out of time. I managed to finish Part I, but now only had a week for Part II and Part III.

Part II did fall out pretty easily, but it was still probably 12 hours. The tests were in place when I started to embellish with nice-to-haves, which helped.

Part II

If all tests pass then the page is written to the file system.
output :: IO ()
output = do
writeFile "fpr.xhtml" (charSequToString (showXHTMLPage testPage))
The resulting xhtml  file can be seen at [output] and is shown valid at [W3C Validator].

Part III (the essay - mine ended up as something like Discuss the Influence of FP on Java) got significantly squeezed, as I kept returning to polish Part II.

At 11.30pm I spotted a mistake in Part I - in the length function and its test.

Submitted the thing at 12.40am. Have printed it out but resisted the temptation to read it. Am feeling like a zombie.

After the deadline had passed I added a missing line break to the output, just to show that this is for me, not just for the marker.

Monday 7 November 2011

Specify InnoDb as default table type in JDBC

One of the recurrent gotchas with MySQL is that the default table type is MyISAM, whereas you almost definitely need InnoDB, if you want transactions, indexing or anything else that would make MySQL a useful database.

Set default table type for all databases

In /etc/mysql/my.cnf add: [mysqld]
default-storage-engine=InnoDB
But this requires that you have root access to the server and that you want all tables to use InnoDB.

Specify default on JDBC url

database.url=jdbc\:mysql\://localhost\:3306/chassis_studies?autoReconnect=true&sessionVariables=storage_engine=InnoDB You could of course use a real database!

Friday 14 October 2011

cvs to github

Following How to export revision history from mercurial or git to cvs?

On hanuman

I created an id file git_authors mapping cvs ids to github name, email format for all contributors:
timp=Tim Pizey<timp@paneris.org>
then create a repository on github (melati in this example, I already have uploaded my ssh public key for this machine)
git cvsimport -d /usr/cvsroot -C melati -r cvs -k -A ../../git_authors melati
cd melati
echo A jdbc to java object relational mapping system. 1999-2011 > README.txt
git add README.txt
git commit -m "Initial" README.txt
git remote add origin git@github.com:timp21337/melati.git
git push -u origin master
See https://github.com/timp21337/melati.

Sunday 9 October 2011

Installing lhs2TeX on Ubuntu

lhs2TeX is a processor for literate Haskell code whose output is laTeX. The following worked for me on Unbuntu 11.04, though this was not the path I travelled, that is I discovered that, for example, libghc6-zlib-dev was a prerequisite the hard way.
sudo apt-get install ghc
sudo apt-get install libghc6-zlib-dev
sudo apt-get install cabal-install
cabal update
cabal install cabal-install
sudo apt-get install texlive
cabal install lhs2tex
logout  or 
export PATH=$PATH:~/.cabal/bin
lhs2TeX -o t.tex t.lhs 
pdflatex t.tex

Wednesday 5 October 2011

Haskell - parse error in pattern: n + 1

Should you get the following error from Haskell
Parse error in pattern: n + 1
this maybe because you are using the n+1 pattern, which is no longer included by default eg
> power :: Double -> Int -> Double
> power x 0         = 1
> power x (n + 1)   = x * power x n
the fix is to include
> {-# LANGUAGE NPlusKPatterns #-}
Hope this helps.

Wednesday 17 August 2011

Proxying from apache2 to application server (eg tomcat, jetty)

It is often convenient to proxy an application server, such as Jetty or Tomcat, as these tend to be mounted on ports other than port 80. The following steps worked in an Ubuntu setup.

Enable mod_proxy
a2enmod proxy
a2enmod proxy_http

Edit sites-enabled/default to add your proxying rule, eg:
ProxyPass /alfresco http://localhost:8080/alfresco
ProxyPassReverse /alfresco http://localhost:8080/alfresco
<Proxy http://localhost:8080/alfresco*>
Order deny,allow
Allow from all
</Proxy>

/etc/init.d/apache2 restart

You should now see your application server content on your default url ie http://localhost/alfresco will contain the same content as
http://localhost:8080/alfresco.

Tuesday 16 August 2011

Alfresco setup

Alfresco is AMAZING - it does not follow the Unix way, or even the Java way, but rather the bloatware way. This is a very bad smell (as is their constant pimping of the paid version).

Alfresco comes with ITS OWN COPY of Java, MySQL and Tomcat.
As I have copies of all these systems on my own box I have chosen to insulate my system and to play fair with Alfreco, and install on a fresh Ubuntu VirtualBox VM, with nothing other than OpenSSH installed.

VM Setup: I also enabled the VirtualBox Guest Additions, on my MacBookPro host, and found that the default bidirectional Copy/Paste functionality did not work.
Stop the VM and change Settings>>Advanced Shared Clipboards to Host To Guest

This vm (called alfresco) is on a virtual network, setup with help from Mr Sysadmin:

Add a Host only network in virtualbox >> preferences >> network

Add an adapter2 to vm >> settings >> network
attached to Host-only adapter

Add to /etc/hosts on host machine
192.168.56.10 alfresco

On vm add to /etc/network/interfaces
auto eth1
iface eth1 inet static
        address 192.168.56.10
        netmask 255.255.255.0
/etc/init.d/networking restart

Install alfresco (NOTE The x32 versions also works)
wget http://dl.alfresco.com/release/community/build-3370/alfresco-community-3.4.d-installer-linux-x64.bin
sudo su
chmod u+x alfresco-community-3.4.d-installer-linux-x64.bin
./alfresco-community-3.4.d-installer-linux-x64.bin 

Take defaults, specify a password for mysql root and Alfresco admin.
/etc/init.d/alfresco start


Now the url http://alfresco:8080/alfresco/ should work.

Monday 15 August 2011

Dual repositories: Subversion and Git

Git and SVN

I have not got a completely pain free git/svn integration,
this seems to be because casutils started life as a git project.

Install git svn integration
sudo apt-get install git-core git-svn

I have two checkouts: local/casutils and workspace/casutils
workspace/casutils was created in the normal way with
git init casutils
local/casutils was created with
git svn clone https://tim.pizey@dsn-chassis.googlecode.com/svn/trunk/casutils
I work in workspace/casutils, when all is committed and pushed to master I switch to local/casutils
git pull -s recursive -Xtheirs ../../workspace/casutils
git svn dcommit

this pushes the changes, with their git commit messages, to svn.

Tuesday 21 June 2011

Cretan Opinel

On our holiday to Paleochora, Crete we spent a day on the East Beach. The sun was pretty hot, so we spent a lot of time under a tamarisk tree. I built a little wall.
On the way back I found an Opinel knife
which has cleaned up quite well. Note the change in the branding: no France and the Main Coroné has moved. This would indicate that it is quite a few years old. (I could not discover when this change occurred).

[Thanks to Laurent in the comments: it was made between 1986 and 1990.]

A button from Tom's Farm

Really quite a long time ago, maybe sixteen years ago, I went to Tom's Farm, on Black Alder Road and walking up the Green Lane found this button. I rediscovered it recently and put it in some silvo, which seemed to show up a bit of silver, now black.
Will give it back to Tom, can't think why I ever took it away, except perhaps I was younger.

Thursday 9 June 2011

My first functional java class

I have known about this particular hammer for ten years. It is a technique widely used in Melati, as William was mostly 'translating on the fly from OCAML' at the time, however I have never recognised a situation where it was the correct approach.

To a commercial programmer on the long journey from BASIC to lisp, via perl and java, even when you know of the functional hammer the world does not appear to have any functional nails in it.

Last night I did recognise such a situation. I wanted to reuse a bit of code:
if (lock()) {
  try {
    body();
  } catch (Exception e) {
    throw new RuntimeException(e); 
  } finally {
    unlock();
  }
} else {
  throw new RuntimeException("Lock file " + LOCK_FILE_NAME + " exists.");
}

The only way to reuse this, for a body2() function, would have been to cut'n'paste, which I will go to some lengths to avoid.

I extracted this to its own abstract class ExclusiveFunction
import java.io.File;
import java.io.IOException;

/**
 * @author timp
 * @since 2011/06/07 22:00:01
 *
 */
public abstract class ExclusiveFunction {
  final static String LOCK_FILE_NAME = "/tmp/EXCLUSIVE_LOCK";

  abstract void body() throws Exception;
  
  public void invoke() { 
    if (lock()) {
      try {
        body();
      } catch (Exception e) {
        throw new RuntimeException(e); 
      } finally {
        unlock();
      }
    } else {
      throw new RuntimeException("Lock file " + LOCK_FILE_NAME + " exists.");
    }
  }
  
  private boolean lock() {
    File lockFile = new File(LOCK_FILE_NAME);
    if (!lockFile.exists()) {
      try {
        lockFile.createNewFile();
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
      return true;
    }
    return false;
  }

  private void unlock() {
    new File(LOCK_FILE_NAME).delete();
  }

}


which is then invoked with:

new ExclusiveFunction() {

      @Override
      void body() throws IOException {
        body2();
      }
    }.invoke();


I think the world is soon going to appear to have a lot more nails in it.

Thursday 14 April 2011

Scala and Java

HelloWorldScala.scala
package net.pizey.scala.toy

class HelloWorldScala {
  def m(message: String) {
    println(message + " - from scala")
  }
}

object HellowWorld {
  def main(args: Array[String]) {
    val s = new HelloWorldScala()
    val j = new HelloWorldJava()
    s.m("Hello world")
    j.m("Hello world")
  }
}

HelloWorldJava.java
package net.pizey.scala.toy;

public class HelloWorldJava {

  public void m(String message) {
    System.out.println(message + " - from java");
  }

  public static void main(String[] args) {
    HelloWorldScala s = new HelloWorldScala();
    HelloWorldJava j = new HelloWorldJava();
    s.m("Hello world");
    j.m("Hello World");
  }
}

Both output
Hello world - from scala
Hello World - from java

Monday 14 March 2011

Ubuntu setup


apt-get install emacs23-nox
apt-get install cvs
apt-get install git-base

#setup apt-get 

deb http://switch.dl.sourceforge.net/project/jedit /

apt-get install jedit


wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -

emacs /etc/apt/sources.list

# Google software repository
deb http://dl.google.com/linux/deb/ stable non-free main

apt-get install google-chrome-unstable



cvs -d :ext:timp@paneris.net:/usr/cvsroot co timp
mv timp/.* .

Tuesday 1 March 2011

Installing packages in R


sudo R
install.packages('Rcmdr')
q()


Monday 28 February 2011

Dropbox setup for work and home

I instinctively created two Dropbox accounts, but soon found that Dropbox expects you only to have one Dropbox account per user account.

Googling revealed this setup for work and personal Dropbox files from Samuel D. :
My solution is to have a paid personal account with all the storage I need, and a free work account. The entire contents of my work account are shared with the personal account. I just have my work account set up on my work computer, and my personal one on my personal computer.

This means I can
- Access all my work and personal files on my personal computer
- Access ONLY my work files on my work computer, and even if the system admin figured out the password they would only have access to my work data, not my personal stuff.

Everything syncs fluidly between both computers, I don't have to unlink and relink Dropbox as I only have one account set up with each computer. This works very well.
looks like this is the way to go.

Wednesday 23 February 2011

Window 7 Setup

A new Windows 7 machine is setup by work admin team to have Endnote, VPN and Anti-Virus installed. Oh and Microsoft Visual Studio 2005.

Installation list

The following are my list of initial installs.

Firefox
Chrome
VirtualBox

Cygwin

zip
unzip
CVS
git
git-completion
git-gui
gitk
make
ocaml*
svn
emacs
nano
vim
graphicsmagick
imagemagick
clisp
python
ruby
openssl
openssh
rsynch
perl
lyx
tetex
chere
catdoc
lynx
wget

java - set JAVA_HOME
jEdit
quassel
maven - set M2_HOME
WinMerge
IntelliJ
checkout all projects
Eclipse
Spotify
Dropbox
Visual Studio 2010 Professional
7-zip
git
R
TortoiseSVN
Skype

TODO

SPSS
Stata
StatTransfer
Talend

Thursday 17 February 2011

rrun - a bash R wrapper

rrun - A script to wrap around R, passing some variables.

First some motivation, what is the problem?

The default command line interface for R is a bit idiosyncratic, and there are no defaults:

~$ R
Fatal error: you must specify '--save', '--no-save' or '-vanilla'


someone went out of their way to deliberately make it behave that way! This is a language which is taking no prisoners.


~/r$ r --help
Usage: C:\Program Files\R\R-2.12.1\bin\r.exe [command args]

where 'command args' can be

  --arch n   for n=i386, x64, 32 or 64
  any other arguments listed by C:\Program Files\R\R-2.12.1\bin\r.exe --arch i386 --help

Its rude to point and stare!

~$ r --arch i386 --help
Usage: Rterm [options] [< infile] [> outfile] [EnvVars]

Start R, a system for statistical computation and graphics, with the
specified options

EnvVars: Environmental variables can be set by NAME=value strings

Options:
  -h, --help            Print usage message and exit
  --version             Print version info and exit
  --encoding=enc        Specify encoding to be used for stdin
  --encoding enc        ditto
  --save                Do save workspace at the end of the session
  --no-save             Don't save it
  --no-environ          Don't read the site and user environment files
  --no-site-file        Don't read the site-wide Rprofile
  --no-init-file        Don't read the .Rprofile or ~/.Rprofile files
  --restore             Do restore previously saved objects at startup
  --no-restore-data     Don't restore previously saved objects
  --no-restore-history  Don't restore the R history file
  --no-restore          Don't restore anything
  --vanilla             Combine --no-save, --no-restore, --no-site-file,
                          --no-init-file and --no-environ
  --min-vsize=N         Set vector heap min to N bytes; '4M' = 4 MegaB
  --max-vsize=N         Set vector heap max to N bytes;
  --min-nsize=N         Set min number of cons cells to N
  --max-nsize=N         Set max number of cons cells to N
  --max-mem-size=N      Set limit for memory to be used by R
  --max-ppsize=N        Set max size of protect stack to N
  -q, --quiet           Don't print startup message
  --silent              Same as --quiet
  --slave               Make R run as quietly as possible
  --verbose             Print more information about progress
  --internet2           Use Internet Explorer for proxies etc.
  --args                Skip the rest of the command line
  --ess                 Don't use getline for command-line editing
                          and assert interactive use
  -f file               Take input from 'file'
  --file=file           ditto
  -e expression         Use 'expression' as input

One or more -e options can be used, but not together with -f or --file

An argument ending in .RData (in any case) is taken as the path
to the workspace to be restored (and implies --restore)



Or: R CMD command args

where 'command' is one of:
  INSTALL  Install add-on packages
  REMOVE   Remove add-on packages
  SHLIB    Make a DLL for use with dynload
  BATCH    Run R in batch mode
  build    Build add-on packages
  check    Check add-on packages
  Rprof    Post process R profiling files
  Rdconv   Convert Rd format to various other formats
  Rdiff    difference R output files
  Rd2dvi   Convert Rd format to DVI
  Rd2pdf   Convert Rd format to PDF
  Rd2txt   Convert Rd format to pretty text
  Sd2Rd    Convert S documentation to Rd format
  Stangle  Extract S/R code from Sweave documentation
  Sweave   Process Sweave documentation
  config   Obtain configuration information about R
  open     Open a file via Windows file associations
  texify   Process a latex file

Use
  R CMD command --help
for usage information for each command.

I think we may need some help here.

A simple interface

rrun is intended to simplify the above, or at least be a handy place for my defaults and to enable me to pass parameters to R in addition to an input file of R commands.

sorry about the escaping

rrun s=\"nice\" f=1 s.R


Where s.R contains

print(s)
print(f)

The result:

~/r$ rrun s=\"nice\" f=1 ls.R
> # Temporary file generated by rrun
> # Date: Thu Feb 17 21:11:26 GMTST 2011
> # Command: rrun s="nice" f=1 ls.R
> #
> s="nice"
> f=1
> print(s)
[1] "nice"
> print(f)
[1] 1
> warnings()
NULL
>
~/r$

Wednesday 16 February 2011

Gygwin setup for Debianistas

An on-going log of the tweeks needed to make Cygwin more intuitive to those of use who use Debian based systems when given a choice.

cygwin is not Ubuntu, you may have noticed :)

Allow customisation

To end of /etc/profile add

. $HOME/.bashrc


A little welcome

Add to your .bashrc

if [[ $(uname -o) == Cygwin ]]
then
echo "Usable Windows"
echo `uname -a`
fi


Simplicity rules

To the Cygwin specific block created above add

alias more=less