Getting started with ReasonML

I write this as a stumbling fumbling guide for how to actually get started, when all you have is a Javascript and React backgroud with no knowledge of OCaml.

I’m using a combination of Fedora and Ubuntu.

Obviously start here: https://reasonml.github.io/

Installation

I even went off the rails at this point because you need globally installed bsb support and you run into the sudo/not-sudo argument. Lots of people want you to install yarn/npm as non-sudo, but I do it as sudo.

The guide suggests that you do it without sudo and makes no mention of using sudo. So for people like me the documentation goes wrong from the very first step. This makes me sad.

The issue being that because I install npm with the Fedora package manager it’s installed as sudo. So I need to run sudo npm install -g which is all fine and good, but some well meaning people rightly express that this should be avoided if possible, but in the case of Fedora this is unavoidable.

I wrote this all up in an issue #2168, with the most relevant comment I made:

In the npm troubleshooting guide and Grunt getting started guide they have the following advice for global installs:

(You may need to prefix these commands with sudo, especially on Linux, or OS X if you installed Node using its default installer.)

I also hit the same problem with my ubuntu install.

If I run without sudo then the yarn add completes fine, but I get the following error if I try to run bsb:

Command ‘bsb’ not found

So I have to run:

sudo yarn global add bs-platform

However now, you have to run bsb with sudo too. Otherwise you get the following error:

$ bsb -init hello -theme basic-reason
Making directory hello
npm WARN checkPermissions Missing write access to /usr/lib/node_modules
npm ERR! code EACCES
npm ERR! syscall access
npm ERR! path /usr/lib/node_modules
npm ERR! errno -13
npm ERR! Error: EACCES: permission denied, access '/usr/lib/node_modules'
npm ERR!  { [Error: EACCES: permission denied, access '/usr/lib/node_modules']
npm ERR!   stack:
npm ERR!    'Error: EACCES: permission denied, access \'/usr/lib/node_modules\'',
npm ERR!   errno: -13,
npm ERR!   code: 'EACCES',
npm ERR!   syscall: 'access',
npm ERR!   path: '/usr/lib/node_modules' }
npm ERR!
npm ERR! The operation was rejected by your operating system.
npm ERR! It is likely you do not have the permissions to access this file as the current user
npm ERR!
npm ERR! If you believe this might be a permissions issue, please double-check the
npm ERR! permissions of the file and its containing directories, or try running
npm ERR! the command again as root/Administrator.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/channi16/.npm/_logs/2020-05-02T11_56_03_062Z-debug.log
failed to run : npm link bs-platform

So you have to run:

sudo bsb -init hello -theme basic-reason

The problem with this is that it then creates the hello directory and all its contents as root. However you don’t always need to use sudo. It seems like it’s either the first time you use it, or perhaps when you use a new template. However after than you can run bsb -init my-dir -theme basic-reason without sudo. It’s not even when using a new theme, you can init with un-used themes. It appears to be just the first time that you run bsb -init that it requires sudo.

Editor plugins

The advice here is quite simple. Use VS Code unless you’re like me and you want your freedom. In that case, if you use Vim, then you’re in luck. I’ve wasted the 10 hours of time for you trying all the different combinations of plugins. See my previous blog post on Using ReasonML with Vim / Neovim.

Initial coding of the demo project

I started with the demo project, this builds a Demo.re file to a Demo.bs.js file that can be run in node.

React our way up the tree

I wanted to get display into the browser – but the basic demo is node only. I want raw JS.

The react example gives raw JS output – but it has to go through webpack.

Kinda annoying – but I guess the webpack converts the bucklescript node javascript into browser style javascript.

Installing the demo

I ran the following to install the create-react demo:

bsb -theme react -init neural-network-re

Running the demo

This installs a runnable demo. I of course hit an error when running the code:

[ian@localhost neural-network-re]$ npm run webpack

> neural-network-re@0.1.0 webpack /var/www/vhosts/reasonml/neural-network-re
> webpack -w

/var/www/vhosts/reasonml/neural-network-re/node_modules/webpack-cli/bin/config-yargs.js:89
describe: optionsSchema.definitions.output.properties.path.description,
                                           ^

TypeError: Cannot read property 'properties' of undefined
    at module.exports (/var/www/vhosts/reasonml/neural-network-re/node_modules/webpack-cli/bin/config-yargs.js:89:48)
    at /var/www/vhosts/reasonml/neural-network-re/node_modules/webpack-cli/bin/webpack.js:60:27
    at Object.<anonymous> (/var/www/vhosts/reasonml/neural-network-re/node_modules/webpack-cli/bin/webpack.js:515:3)
    at Module._compile (module.js:653:30)
    at Object.Module._extensions..js (module.js:664:10)
    at Module.load (module.js:566:32)
    at tryModuleLoad (module.js:506:12)
    at Function.Module._load (module.js:498:3)
    at Module.require (module.js:597:17)
    at require (internal/module.js:11:18)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! neural-network-re@0.1.0 webpack: `webpack -w`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the neural-network-re@0.1.0 webpack script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/ian/.npm/_logs/2018-11-26T22_05_12_616Z-debug.log

It’s so frustrating when things don’t ‘just work’. Anyway it turns out to be a webpack error that they fixed in the project back in October, the fix is to upgrade the webpack-cli version in the package.json.

Also it looks like I’m running an old version of bsb as it appears to install an old version of the project. My version has the stupid idea of trying to get hot reloading running first, rather than a simple build.

It looks like in the new version they simplify it and just run the regular build. At least then it’s obvious that it’s a webpack error rather than some weird compilation error. It’s now just:

npm install
npm run build
npm run webpack

Then open src/index.html

That is pretty sweet! Got me a lovely simple index.html page up and running.

Hot reloading

Now we can attempt the hot reloading.

npm run start

Then in a separate terminal:

npm run webpack

This then hot reloads the code – but it doesn’t auto refresh the webpage – but at least I understand it.

Steps towards a Neural Network

My reasons for doing all this is to convert a simple Neural Network I wrote in JavaScript into ReasonML.

Now the first thing I want to try and do is get some SVG displaying, this isn’t so simple because you need to do it in JSX that gets output to god knows what that eventually produces an SVG.

However via a forum post there is a link for how to display a basic SVG. The slightly cryptic thing in there is that it doesn’t display anything to the screen, it just creates the SVG in a variable.

I made some modifications to the demo code to it to output a simple SVG circle and then got the SVG displaying to the screen too

let m =
  <svg
    width="200"
    height="200"
    viewBox="0 0 200 200"
    xmlns="http://www.w3.org/2000/svg">
    <circle
      cx="5"
      cy="5"
      r="5"
      style=(ReactDOMRe.Style.make(~fill="black", ()))
      xmlns="http://www.w3.org/2000/svg"
    />
  </svg>;

ReactDOMRe.renderToElementWithId(m, "target");

The online tool (https://reason.surge.sh) is quite interesting because you get a lot more tooltips than I’m used to (this is because it has the language server plugged in). Also the fun with displaying the style attribute which was actually relatively painless. The ReasonReact Docs for Style gave me the perfect example:

<div style=(
  ReactDOMRe.Style.make(~color="#444444", ~fontSize="68px", ())
)/>

So now I’ve got an SVG circle appearing in the web version and I can use this in my local version without problem.

Dom dom dom…

Ideally for my basic project I didn’t want to use React. I have a simple HTML page that injects a few <p> tags and some <svg> circles. I do this easily enough with pure JavaScript, so I shouldn’t need React.

However trying it was very painful. Every DOM Element in Reason is an Option. So you have to spend your life with this ‘could be null’ chap and handle this could be null at every stage.

Basically it seems like the DOM is a type nightmare and trying to apply correct types to it produces your own personal hell.

  let _ =
    Document.getElementById("root", document)
    ->Belt.Option.map(_, Element.setInnerText(_, "Hello"));
  ();

  let el =
    document
    |> Document.createElement("p")
    |> Element.asHtmlElement
    |> unwrapUnsafely;
  /* let root = Document.getElementById("root", document); */
  document
  |> Document.getElementById("root")
  |> map(Element.appendChild(el));

The above is the equivalent of:

var root = Document.getElementById("root");
root.innerText = "Hello";

var el = Document.createElement("p")
Document.getElementById("root").appendChild(el);

But trying to create and element, set it’s innerText and then append it was beyond me after 8 hours of coding.

This is along with using the experimental (but interesting) library bs-webapi, which is also referred to in a useful book on Web Development with ReasonML.

It’s at this point I figure that ReasonReact seems to handle the Dom interaction better. I was able to get a fairly complex svg element displaying which is the hardest part. So perhaps just better to stick to that.

Hidden pipes

Note that here they use the “reverse-application” operator |>. There’s an excellent description about this in this 2ality blog post on ReasonML functions:

The operator |> is called reverse-application operator or pipe operator. It lets you chain function calls: x |> f is the same as f(x). That may not look like much, but it is quite useful when combining function calls.

In the reason docs they refer to the -> operator instead in the Pipe First section:

-> is a convenient operator that allows you to “flip” your code inside-out. a(b) becomes b->a. It’s a piece of syntax that doesn’t have any runtime cost.

It seems that -> is a subtly different operator from |> as the only reference to |> appears later on that page:

We also cannot use the |> operator here, since the object comes first in the binding. But -> works!

Frustratingly though the reason documentation just includes this mention of |> without actually saying what it is. The operator comes direct from OCaml, see ‘Composition operators’ in the Stdlib documentation.

Note that there is the similarity to the Javascript pipeline operator.

Belt

Also note the use of Belt.Option.map above. The Belt module is a community driven helper module:

A stdlib shipped with BuckleScript This stdlib is still in beta but we encourage you to try it out and give us feedback. Motivation The motivation for creating such library is to provide BuckleScript users a better end-to-end user experience, since the original OCaml stdlib was not written with JS in mind.

Easier DOM

Trying the latest bsb -init my-react-app -theme react-hooks includes the following snippet in src/Index.re:

  [@bs.val] external document: Js.t({..}) = "document";
  
  let title = document##createElement("div");
  title##className #= "containerTitle";
  title##innerText #= text;

which generates:

  var title = document.createElement("div");
  title.className = "containerTitle";
  title.innerText = text;

Now this looks a lot simpler. But of course I’ve no idea what the ## or #= operators do.

That’s as far as I’ve got, but at least now we have code that looks like recognisable JavaScript.

Using ReasonML with Vim / Neovim

Here’s my attempts to get ReasonML working within Vim and the journey it took me on to understand what language servers are. If you’re using Vim this is essentially step 2 of the ‘quick start’ guide for reason: editor plugins.

Warning to all who enter here… this took me 10+ hours to fix. It’s because my setup doesn’t mesh exactly with their expected setup. If you want an easy life just use VS Code. Failing that if you want an easy life with Vim, just use the following setup:

This assumes that you can install the LanguageServer which you have to do for VS Code as well.

Vim support

By default for using linting I have the following setup:

  • Vim 8
  • Vundle
  • ALE (Asynchronous Lint Engine)

This has managed to work ‘OK’ for Javascript with a bit of linting. But I never got fully fledged Language Server Protocol (LSP) integration working, I don’t really know why.

My initial attempts with my default setup were a total failure. Mostly because I find the LSP concept hard to understand. ALE should be a LSP ‘thing’. So it should be able to act as a Language Client and talk to Language Servers.

The repeated issue I come across is that to get LSP working you need the vim-plug Vim plugin manager. I don’t particularly know why, I guess it works better for these more complex plugins.

Looking through my .vimrc file it looks like I tried to get ALE to work as a LSP.

I switched to Neovim as part of this to minimise the number of plugins that I’m installing.

Switching from Vundle to vim-plug

Until now I’ve always used Vundle, it’s a good basic plugin. But I keep hitting plugins that don’t have instructions for Vundle and just vim-plug. vim-plug seems as good as Vundle, so let’s try it and see how much work the conversion is.

It’s actually ridiculously easy, much respect for vim-plug, and probably Vundle for both having very similar and easy to replace syntax. I replaced the Vundle lines at the start:

-filetype off                  " required
-set rtp+=~/.vim/bundle/Vundle.vim
-call vundle#begin()
-
-Plugin 'VundleVim/Vundle.vim'
+call plug#begin('~/.vim/bundle')

Then I replace all Plugin with Plug and then at the end:

-call vundle#end()
-filetype plugin indent on    " required
+call plug#end()

Then I ran :source % and :PlugInstall and it magically installed all my 31 plugins in 10s and they all seem to be magically working. If you use the .vim/bundle installation directory then vim-plug doesn’t even need to install anything.

There’s some useful instructions in the vim-plug wiki on Migrating from Vundle.

Magically also my installation of deoplete worked correctly. So now deoplete pops up all the time as I’m typing – I’m assuming it’s possible to make it less in your face…

if has('nvim')
  Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
else
  Plug 'Shougo/deoplete.nvim'
  Plug 'roxma/nvim-yarp'
  Plug 'roxma/vim-hug-neovim-rpc'
endif

Because I’ve switched to neovim it simplifies that installation as well.

But I’ve now fallen into the neovim only trap. Because my installation for deoplete only works with neovim, then I get an error if I try to use vim now. Perhaps I can just comment the whole block for if deoplete installed out. This works, so now vim-plug just doesn’t use deoplete if I’m in Vim.

Note that Deoplete should start working immediately after you install it and you should start seeing a popup box as you type.

Installing the language server

This was just downloading the zip from the language server releases page and unzipping it to ~/rls-linux.

Figuring out how to get ALE to work with reason-language-server

I’m using ALE rather than the recommended autozimu/LanguageClient-neovim. ALE is also a Language Client and so should also work fine.

Install via:

Plug 'dense-analysis/ale'

ALE needs to know about the existance of the reason-language-server and thankfully that support has been added. You can go to :help ale-reasonml-ols and it tells you the correct config:

  let g:ale_reason_ls_executable = '~/rls-linux/reason-language-server'

After this I expected to restart Vim and it to magically work which it didn’t.

The path has to be absolute (as noted in the config information for the LanguageClient-neovim in the README):

  let g:ale_reason_ls_executable = '/home/ian/rls-linux/reason-language-server'

You can also use the magic of vimscripts expand to handle it for you too:

  let g:ale_reason_ls_executable = expand('~/rls-linux/reason-language-server')

This then showed promise. Completion would work nicely and you get useful information coming up as you type, this also integrated with ALE via:

call deoplete#custom#option('sources', {
\ '_': ['ale'],
\})

It took a while to see if all the functionality was there. It pickedup linting errors which are put into the location list (:lopen) and would give useful info with :ALEHover

I compared it to VS Code, which does manage to implement this better. The error messages get formatted properly, for some reason the line breaks in the Vim error messages don’t get applied. Also you get the ‘Hover’ (equivalent to ALEHover) info showing up as you type in context.

I then tried to format the code. ALE has a :ALEFix command that I know works from eslint. It helpfully suggests that you need to configure the correct ‘fixer’ in .vimrc. However once that has been configured running ALEFix does nothing. I installed VS Code to check that using that along with the reason-language-server does correctly format the code – which it does. So there appears to be some problem with ALE.

Time to try another plugin…

So I can either try the Rust made LanguageClient, or the Typescript COC.

I’ve heard about COC a couple of times and it’s designed to be a VS Code matching ‘LSPy thing’. So you should be able to configure Language Clients almost exactly as they do with VS Code but inside Vim.

But hey, I prefer Rust so let’s try that first…

Trying LanguageClient-neovim instead of ALE

Now that I’ve switched to vim-plug installation of LanguageClient-neovim is easy because it includes the manual install step in the .vimrc code.

Then also the configuration was easy because it’s included in the vim-reason-plus README:

let g:LanguageClient_serverCommands = {
    \ 'reason': ['/absolute/path/to/reason-language-server.exe'],
    \ }

Note again here, that it mentions ‘absolute path’, so you have to use /home/ian instead of ~, although I still just use expand('~/path')

Now once I had installed that and restarted NVim then it all worked pretty smoothly.

Firstly the errors show up in the quickfix list :copen as well as to the right of the code. It’s not quite formatted as nicely with the line breaks as VS Code but is at least a consistent block of text, not spaced out with extra padding where the line breaks should be. I suspect though that using the location list is better as it won’t overwrite any searches that I’ve done.

Interstingly the ‘quickfix list’ is actually supposed to show errors according to :help :copen. So perhaps my searches should be in the location list. This can be changed via:

    let g:LanguageClient_diagnosticsList = 'Location'

The commands for the LanguageClient are more confusing though.

:ALEHover vs call LanguageClient#textDocument_hover()<cr>
:ALEFix vs call LanguageClient#textDocument_formatting()<cr>

But you can fix that through the vimrc mappings, but now happily the formatting did work which is what I want. Shit works without too much hassle.

Try getting it to work using COC

One nice property of COC is that it doesn’t use any advanced features of vim-plug, so this will probably all still work with Vundle. Also it looks like it combines the Auto-completion and LSP in one plugin.

Install nodejs – you can follow the instructions in https://github.com/neoclide/coc.nvim/wiki/Install-coc.nvim.
Remove Deoplete and LanguageClient-neovim and any settings from your .vimrc file. Then add COC:

Plug 'neoclide/coc.nvim', {'branch': 'release'}

Then reload the vimrc with :source % and run :PlugInstall. Warning you’ll get errors if you haven’t cleared all the deoplete settings. You might still need to restart Vim.

Install the reason extension

COC works similarly to VS Code in that it requires you install extensions to get it to work with certain language servers.

Install the reason extension, which is assuming that you are using the reason-language-server rather than the OCaml or Merlin LSP:

:CocInstall coc-reason

I ran this and it froze my Neovim. Closing and re-opening the terminal got it working again, but not good.

Now you’ll need to configure it as you always need to specify the absolute path to the reason-language-server. Handily there is a configuration section for Reason

Run :CocConfig and if it’s empty (because this is the first time of using it), then you first need to insert an empty root object:

{
}

Then put the following config inside the root object:

  "languageserver": {
     "reason": {
      "command": "/absolute/path/to/reason-language-server",
      "filetypes": ["reason"]
     }
  }
Troubleshooting

Don’t forget to put the correct absolute path for the command. Here now you can’t use the vimscript expand, so just use /home/[username].

e.g.: "/home/ian/rls-linux/reason-language-server"

Otherwise you’ll get:

[coc.nvim] Server languageserver.reason failed to start: Command “reason-language-server” of languageserver.reason is not executable
: Error: not found: reason-language-server

As soon as you set the correct path you should immediately start getting auto-completion and LSP goodies in your reason files.

Another possible error you can get is:

[coc.nvim] Server languageserver.reason failed to start: Cannot read property ‘reader’

This is a connected error that means you have the command path wrong. In my case I’d just written "/home/rls-linux/reason-language-server"

Further I tested it on a basic reason file created in an empty directory which gives this error:

[coc.nvim] No root directory found

This appears to be a reason-language-server issue #334. You need to initialise the directory as per the installation page.

The auto-completion seems to work very nicely, but I noticed that the error messages are severely truncted, for example:

src/Index.re|7 col 34 error| [undefined] Error: This expression has type [E]
src/Index.re|7 col 59 error| [undefined] Error: The function applied to this argument has type [E]

Actually you can get the full error, using :call CocAction('diagnosticInfo'), or :call CocAction('diagnosticPreview').

This gives a better error than I got with ALE or LanguageClient-neovim:

[reason] [E] Error: This expression has type
(~message: string) =>
ReasonReact.componentSpec(ReasonReact.stateless,
ReasonReact.stateless,
ReasonReact.noRetainedProps,
ReasonReact.noRetainedProps,
ReasonReact.actionless)
but an expression was expected of type
ReasonReact.component(‘a, ‘b, ‘c) =
ReasonReact.componentSpec(‘a, ‘a, ‘b, ‘b, ‘c)

To get code formatting working you need to run: :call CocAction('format'). So its similar to the LanguageClient-neovim in that you’ll probably want to create a whole bunch of vimrc shortcuts. But at least it does format which is a step up from ALE.

Hover info is through :call CocAction('doHover').

One nice thing about this plugin is that it combines the Complete and LSP plugins and so the Plug config is:

Plug 'neoclide/coc.nvim', {'branch': 'release'}

Instead of:

Plug 'autozimu/LanguageClient-neovim', {
    \ 'branch': 'next',
    \ 'do': 'bash install.sh',
    \ }

" for neovim
if has('nvim')
  Plug 'Shougo/deoplete.nvim', { 'do': ':UpdateRemotePlugins' }
" for vim 8 with python
else
  Plug 'Shougo/deoplete.nvim'
  Plug 'roxma/nvim-yarp'
  Plug 'roxma/vim-hug-neovim-rpc'
  " the path to python3 is obtained through executing `:echo exepath('python3')` in vim
  let g:python3_host_prog = "/absolute/path/to/python3"
endif

So your choices are…

Note these are recommendations, you probably can get Vim/Vundle to work with these, but I’ve simplified my life to match the instructions that maintainers give out.

  1. Neovim, vim-plug, ALE, deoplete: format doesn’t appear to work, error messages are very ugly, deoplete has some nice integrations with fzf
  2. Neovim, vim-plug, LanguageClient-neovim, deoplete: has the most nice touches and seems to work the best with little config, format works, but error messages are still pushed into one long line that can be too long for the location list
  3. Vim/Neovim, vim-plug, COC: simplest plugin setup, but took a while to understand how to configure, doesn’t work so nicely out of the box, format works, appears to give the best formatted error messages – when you look for them. It’s easier if they just appear in the location/quickfix list. However I guess that’s the problem, location/quickfix don’t allow for multiline error messages. Also in this seems the most light weight of the plugins as it doesn’t bundle all possible language server configurations, you install them as extensions.

Futher work with COC

I’ve since had further thoughts with COC. Things that are actually fairly magical.

  1. If you’re a Javascript developer then working with eslint is very common. The coc-eslint plugin magically works with eslint straight off. I had all sorts of problems with eslint and ALE, which required eslint_d and neomake for reasons that I can’t quite remember.
  2. By default the errors in COC don’t show until you switch from insert mode to normal mode. This is actually a better experience in my opinion as it reduces the amount of constant information that you’re getting. There’s no need to display an error just because you haven’t typed something yet.
  3. So it means that I can replace, ALE, Neomake, Deoplete, LanguageServer-neovim with COC. COC requires node to be installed but beyond that there’s no specific vimrc config, so should allow using Vundle – although it does require a specific branch which I don’t think Vundle can handle. Also without Deoplete there’s no difference between using Vim or Neovim which is great.

Installing Haskell ++ Emacs on Windows

Haskell

Firstly install the haskell-stack chocolatey package:

choco install -y haskell-stack

For me that perfectly installed haskell and meant that I could run stack commands and have stack ghci running in a DOS prompt.

Emacs

Chocolatey has an Emacs package:

choco install -y emacs

This puts the emacs binaries into the chocolatey bin directory. Then the .emacs file and the .emacs.d directory go into %APPDATA%.

This installs an Emacs windows program. I wondered if there was a DOS version similar to Vim. There is an Emacs For DOS – but this isn’t part of the Chocolatey package, which comes from the GNU Emacs FTP directory.

Intero

The haskell project have a new integration with Emacs. I have to say this installed remarkably easy. The only problem I had was that I’d put a bad config into %APPDATA%\stack\config.yaml and this created errors – that were well explained in Emacs.

It’s not 100% clear how you get things to work though. Bare in mind I’ve never used Emacs before today.

I have managed to get Haskell setup and working, which came with stack.

Following the Intero guide, the installation of the package was easy enough – just edit the %APPDATA%\emacs.d file. I restarted Emacs and the Intero package installed itself without errors.

Following the guide further I ran the stack new intro-demo command in a directory. This created the intero-demo directory and put everything in it. If you then ‘File > Open Directory’ in Emacs to open the intero-demo directory. Opening Setup.hs had the affect of getting Intero to install itself.

At this point things were actually working – but it wasn’t obvious the the error as you type checking was happening because it was erroring at the very first command of the Setup.hs

However if you open up a new Haskell file in the directory it should start doing error checking on the fly.

Hoping the Brexit vote was a protest vote, not a racist one

The only positive I hope from this is that the Brexit vote was a protest vote.

So I’m hoping the majority of ‘leavers’ aren’t siding with Farage, they don’t care about Boris – they just want to say Fuck You to all politicians and leaders.

This is probably the first and only time that the entire population have been given a protest vote. This is not a choice between one dodgy politician or another politician. This is not choosing between Trump or Clinton.

This is a chance to say fuck you to every single party. This is fuck you to the leaders of both the Conservative and Labour parties.

When this chance comes along – you don’t care about the consequences. You don’t care if the ‘leave’ campaign is spouting lies, you don’t care about the doom spouted by the ‘remain’ campaign. You just want a chance to say fuck you. You know the system is wrong and this is the only tool you’ve got to say so.

I certainly respect the people who protest for what they believe in. Perhaps I’m wrong for thinking all the pensioners don’t care about the consequences. Perhaps they know better than me that the pain of leaving is worth it.

There are some heart felt comments from leavers, not based on the crap spouted by the leave campaign, in this blog post Dear Brexiteer. What we need you to do now.:

“I voted leave , There its out there .. I trusted DC to come back from Brussels with a list of pledges that would let us have some tools to work with to make me feel that improvements could be made to the way we live..
Be it a better NHS ,Schools ,social care services,security. ..
He came back with nothing and nothing was offered .. in fact we were told that it would never change..
So people who have had enough like myself and 17 million others voted with our feet in the only way we know .. a very British revolt ..
Now we are being called racist and xenophobic but this is just so untrue for the masses.. we just need change .
The EU is a broken antique of a monster that isn’t up to listening to the working classes..
We have been called inward looking but again that is not true. . I concider myself Global I want to be able to talk with anyone across the world’s economy. .
Things will never be the same again and for that I feel that my cross mattered.
The first time I think the working class has ever mattered…”

So I hope when all the dust settles that we’re all still willing to tell Farage and Johnson to go fuck themselves (I’m pretty sure not many people care about what Gove says).

Jupyter on Windows with Chocolatey

Install Python

This is a quick post (and will probably be outdated quickly), but it took me a while to get it correct.

I wanted to install Jupyter on Windows. The recommeded route is via Anaconda but I like to use Chocolatey the Windows package manager as much as possible.

I used Chocolatey to install Python package (currently v3.5.1). Assuming you’ve installed Chocolatey already, run as administrator:

choco install -y python

This installs python to C:\Program Files\Python35. It also installs and pip.exe to C:\Program Files\Python35\Scripts.

Add C:\Program Files\Python35 and C:\Program Files\Python35\Scripts to your PATH then you should be able to run python and pip immediately.

Install PIP (hint: it’s already installed)

Note that pip gets automatically installed when you install python – nothing extra is required.

You can get led astray here by an official guide which suggests having to download and run ez_setup.py.

Don’t do this.

There is also confusingly a Chocolatey PIP package. Again don’t install this.

Otherwise you might end up here.

Running PIP packages

Because we’re using Chocolatey, the installation doesn’t follow the recommended installation for Jupyter.

The main thing is that you need to add the python Scripts directory to your PATH, as above.

Install Jupyter

Run as administrator:

pip install jupyter

This will install a jupyter.exe file into the Scripts directory. If that directory is in your PATH, then you should be able to directly run jupyter commands.

Create a Jupyter notebook

Jupyter runs inside the browser but installs files and all the save data in the directory that you run the jupyter command from.

mkdir jupyter
cd jupyter
jupyter notepad

If everything is working that will open up your browser at http://localhost:8888/.

Lock Stock Pomodoros

I give you http://pom.ianchanning.com. Pomodoros with a Lock Stock film quote at the end of each one.

I’m a little obsessive about timers (see bottom) and the other pomodoro timers I’ve tried failed on different counts.

I’ve tried to cram everything I find useful about a timer.

Firstly spacebar to start/stop. The timer should be something that sits in the background and requires minimal attention. So a quick ctrl+tab to get the the pomodoro tab and then hit space and then back to your work.

Secondly the timer appears in the title bar and it appears first. Then you can easily see that it’s running so that you can still see the timer when you have lots of tabs open.

Thirdly there’s a start and stop. Possibly this flies against what a Pomodoro timer should do. However any timer I have I want to be able to start/stop/reset. That’s just what a timer should do, it’s annoying if it doesn’t.

Fourthly the timer has to notify you properly when the pomodoro finishes. This is achieved through a buzzer and a browser notification. Notifications sometimes don’t work or you don’t see them so you need the buzzer backup. Sorry IE folks your browser is still terrible and can’t handle the Javascript Notifications and I can’t be bothered to fix it when it’s just for a personal project.

Fifthly a count of the pomodoros is useful to know how many you cranked out in the day.

Sixthly, a bit of browser responsiveness goes a long way.

And that’s it. No more please.

Well except I needed to put something in the notification so I jazzed things up with quotes from Lock Stock and Two Smoking Barrels. If you can’t take the ‘c’ word at least once then this timer is not for you.

For those who got this far. I started with the most basic timer I could think of that still had a simple start-stop mechanism. Then after staring at the jquery code I’d copied I realised I could make a generic jquery ticker function. So I can tick 25 minutes down and then tick the pomodoro count up 1 each time. The rest is a codged together front end on top of that.

Scrum unsucked

[Photo credit: darkmatter]

I’ve been reading into Scrum closer recently and it just seems like a horrible corruption of an inspirational idea, that could much more easily be integrated into normal project practices.

Agile

I love the agile principles. I’m repeating them here for my own benefit, I like a good list as much as the next.

  1. Customer satisfaction by rapid delivery of useful software
  2. Welcome changing requirements, even late in development
  3. Working software is delivered frequently (weeks rather than months)
  4. Working software is the principal measure of progress
  5. Sustainable development, able to maintain a constant pace
  6. Close, daily cooperation between business people and developers
  7. Face-to-face conversation is the best form of communication (co-location)
  8. Projects are built around motivated individuals, who should be trusted
  9. Continuous attention to technical excellence and good design
  10. Simplicity—the art of maximizing the amount of work not done—is essential
  11. Self-organizing teams
  12. Regular adaptation to changing circumstances

Each principle makes sense, even if, perhaps, it isn’t attainable.

Their manifesto is harder to figure out, but still has a great aspirational feel to it.

We value this Over this
Individuals and interactions Processes and tools
Working software Comprehensive documentation
Customer collaboration Contract negotiation
Responding to change Following a plan

However importantly note that the second column is still valued, but just not as much as the first.

Scrum

Now read the Scrum Guide™ (TM!). Scrum just seems like a conversion of agile concepts into sucky word project management.

I realised I’d already got it wrong with what a sprint was – I thought it was two weeks work. They suggest that it should be a month’s worth of work – which makes sense, but why not just call it a month’s worth of work – or if it’s going to be less just call it an increment.

Anyway I read through the Scrum Guide and here’s my unsucked version of their main concepts.

Scrum Guide™ Unsucked agile guidelines™
The Scrum Team The Team
The Product Owner The Client
The Development Team The Developers
The Scrum Master The Project Manager
The Sprint The Sprint (it isn’t actually that bad a word) / Increment
Sprint Planning Planning
Daily Scrum Talk
Sprint Review Sprint Update
Sprint Retrospective Sprint Review
Scrum Artifacts Documents
Product Backlog Issues
Sprint Backlog Sprint Issues
Increment Completed Issues
Artifact Transparency Simplification
Definition of “Done” Happy Client

Can I have a word…

Scrum style

“Shall we go over the Sprint Review later? I’m not convinced that the Product Backlog contains all that we require for the definition of done. The Daily Scrum this morning wasn’t great as the Scrum Master had to get the Development Team to better explain their progress to The Product Owner. We need to make the Sprint Backlog artifact more transparent as The Product Owner feels we haven’t followed what we agreed at the last Sprint Retrospective.”

vs sane

“Shall we go over the Sprint update later? I’m not convinced that the issues contain all that we require for the client to be happy. The talk this morning wasn’t great as the Project Manager had to get the developers to better explain their progress to the business. We need to simplify the Sprint’s issues as the client feels we haven’t followed what we agreed at the last Sprint review.”

Please let the first type of conversation cease.

Second hand bicycles

In response to a blog post ‘Why I keep fixing my bike‘ about the risks of buying a dodgy second hand bike, I wrote the following comment. It’s something I’m quite passionate about so worth storing on my own blog…

I have bought at least 7 bikes second hand through either ebay or gumtree all without problem. Every bike has been exactly what I was looking for. I wouldn’t buy off an ebay seller with only a small repuatation – and almost all sellers I have seen when searching ebay have 100+ reputation.

I think the chances of getting a lemon are quite small, but you always have to be careful.

With a bicycle you are predominantly paying for a decent frame as the rest can be replaced. Its fairly unlikely that the frame will have been damaged. So buy bikes that have well made frames e.g. Cannondale. I’ve purchased a Specialized, Cannondale, Merkx, Orange, Klein and Marin bikes. Most of the bikes I bought would have had a new value in excess of $1000. I’d be most wary of buying a Specialized bike as they are the most common and the current Specialized bikes I’ve seen have very poor welding on the frames.

Certainly don’t go buying cheap branded bikes new bikes e.g. and shop’s own brand. If you’ve got very little money you can pick up old retro racing bikes for less than $100.

Limit your search to only bikes that are near buy (i.e. 30 minute drive) so that you don’t waste much time.

There are many things you can look for:

  1. Has the bike been stored inside – if you see a photo of it hanging up in a garage on its own rack its a pretty good bet that it has
  2. Buy ‘fixed’ bikes without suspension as the suspension can be expensive to replace
  3. Look at the type of gears that it has
  4. Check how detailed the spec of the bike is – does the person list exactly all the components – this gives an indication of how much the person cares about the bike
  5. Do they state where they bought it from
  6. Do they display high quality images of close ups of the gears, the joins of the frame where cracks appear
  7. What have they been using the bike for
  8. How often do they clean the bike
  9. Ask what year the bike is from as well as the exact make and model – then hopefully you can find a reference to how much the bike was when it was new.
  10. Check the welding on the bike frame – how clean are the welds. You shouldn’t be able to see the welds – as that means it was a cheaply made bike by machines and never finished off.