Dotfiles are meant to be stolen from

I wouldn't say dotfiles are meant to be forked but rather you're meant to steal stuff from other's. So in the interest of making your job a bit easier I thought I would talk about some of the things from my dotfiles that I think are worth stealing.

First things is the following aliases:

  • ee: Edit environment file. This is where my $PATH is configured as well as other shell variables.
  • ea: Edit aliases. I keep all my aliases in one file. This command opens that file.
  • ef: Edit functions. As for aliases, I keep all my shell functions in one file. This commands opens that file.

I find these mighty useful. If you're gonna fiddle, might as well make yourself more efficient at it.

The Rails Doctrine

This is a phenomenal piece by DHH about the core values behind Ruby on Rails. I believe everyone should read this, whether or not you're developing with Rails.

A wish for Haskell documentation

I guess that most of the Haskell community are more comfortable with types than typography (self included), but there has to be someone out there. If not, we could have a whip-round and hire someone to make a better design.

I think this is the primary reason people have a hard time learning Haskell. They read Learn You a Haskell for Great Good! and think "this is not too bad" and then they start building a real project only to hit a brick wall that is the lack of beginner friendly documentation.

Data.String.Conversions

When I first started writing bigger projects in Haskell there was one thing that really annoyed me. That is that Haskell has at least 5 different types of strings! In Ruby we have 2 kinds (strings and symbol) but Haskell has 5... And because Haskell is statically typed you constantly have to convert between these different types. I found myself spending more time googling for how to convert between string types than actually getting work done.

The 5 types of strings are:

  • String
  • Strict ByteString
  • Lazy ByteString
  • Strict Text
  • Lazy Text

However a few weeks ago I found this amazing library called string-conversions. This module exposes one function you need to care about and that function is called cs. cs has type cs :: ConvertibleStrings a b => a -> b. You can read that as "it takes a string like thing and converts it into another string like thing". The reason this is so great is that you never need to worry about which type you're converting from and which type you're converting too. The magic of type inference and "dynamic dispatch" figures it out for you.

So whenever you need to convert a string like type you just stick cs in there and the compiler figures out the rest. So great.

Getting started with Haskell development

Some time ago I wrote post about configuring Vim for Haskell development. Two things have changed then that makes the process a little bit, so I thought I would write a follow-up post.

The major changes that have happened is:

  • Neovim is now stable enough to replace Vim.
  • Stack is fixing Haskell's tooling problem and it recently hit 1.0.

The steps I outline below are for people on OS X, but should be simple enough to adapt them to whatever Linux distro you might have.

Installing Neovim

Installing neovim is easy.

$ brew install neovim

I recommend you alias vim to nvim. Putting this in your zshrc/bashrc will do the trick

alias vim='nvim'
alias vi='nvim'

Something that wasn't immediately obvious to me was that Neovim's configuration files aren't "~/.vim" and "~/.vimrc" but rather "~/.config/nvim" and "~/.config/nvim/init.vim". Run these commands if you wanna symlink your old configuration to the new location

mkdir -p $HOME/.config
ln -s $HOME/.vim $HOME/.config/nvim
ln -s $HOME/.vimrc $HOME/.config/nvim/init.vim

Installing Stack

Again super easy:

$ brew install stack
$ cd ~
$ stack setup

Running stack setup will pull down the latest GHC and install it in an isolated location.

When you install packages with stack install and those packages contain executables those executables will be put in "~/.local/bin" so you should add that to your path.

export PATH="$HOME/.local/bin:$PATH"

Be sure to run stack install ... from a directory that isn't a stack project. I recommend just using your home directory. I've read in various GitHub issues that this might prevent weird behaviour.

I also recommend you alias ghc and ghci to use the stack versions. I had some issues with module that couldn't be imported even though they were installed. Doing this fixed the issue.

alias ghc='stack exec -- ghc'
alias ghci='stack exec -- ghci'

The Vim plugins we'll be installing soon depend on a few packages. Go ahead and install them with:

$ stack install hdevtools
$ stack install pointfree
$ stack install hlint
  • Hdevtools delivers super fast type checking.
  • Pointfree allows you get to quickly convert functions to pointfree form. I find is a great way to learn more about how to compose functions. Don't overdo it though.
  • hlint is the best linting tool I've seen for any language.

Installing Vim plugins

The plugins I'm using at moment are:

  • vim2hs, syntax highlighting and converting functions to pointfree.
  • vim-hdevtools, lightning fast type checking
  • neomake, run hdevtools and hlint whenever you save a file and show errors in-line. Much like Syntastic but uses Neovim's async processing features.

These plugins should work pretty much out of the box. To run Neomake whenever you save a Haskell file add the following to your "init.vim".

augroup NeomakeHaskell
  autocmd!
  autocmd! BufWritePost *.hs Neomake
augroup END

Conclusion

Thats pretty much what it would take to recreate my Haskell environment.

I've been really impressed with Stack. Its amazing how much more enjoyable it makes using Haskell. Go ahead and run stack new next-awesome-haskell-thing and let the types lead the way.

Configuring Vim for Haskell

Note: Since I wrote this post a few things have changed in the Haskell/Vim ecosystem. I've written an updated post which can be found here

I've started to get more into Haskell lately and one of the things I really enjoy is the strong tooling built around the language. This tooling mostly relies on the fact that the compiler is very powerful and can do lots of cool things.

I've played around with a few plugins that make writing Haskell in Vim more pleasant.

vim-hdevtools

I use this plugin together with Syntastic to get type errors directly within Vim every time I save a file. It quickly becomes annoying to have to manually compile your files every time you wanna see if you've made some silly mistake Doing it manually also doesn't allow you to look at your code and errors at the same time. It basically tightens the feedback loop, to use TDD terminology.
hdevtools is great because it uses a background server that makes the type checking really really fast. There is only a very small noticeable delay, much smaller than with ghcmod.

I have made the following configurations to Syntastic:

let g:syntastic_mode_map = { "mode": "passive",
                           \ "active_filetypes": [],
                           \ "passive_filetypes": [] }

let g:syntastic_haskell_checkers = ["hdevtools"]
let g:syntastic_haskell_hdevtools_args = "-g -Wall -g -fno-warn-unused-do-bind"
let g:syntastic_mode_map = {
    \ "mode": "passive",
    \ "active_filetypes": ["haskell", "c", "cpp"],
    \ "passive_filetypes": [] }

This will turn on all warnings for GHC except for unused binds in a do expression. It also enables Syntastic only for C, C++ (Vim thinks ".h" files are C++), and of course Haskell.

I also use it sometimes for looking at the types of expressions, for which I've made the following leader mappings:

nnoremap <leader>ht :HdevtoolsType<CR>
nnoremap <leader>hc :HdevtoolsClear<CR>
nnoremap <leader>hi :HdevtoolsInfo<CR>

I have been experiencing some issues where it reported errors with my code, but it compiled just fine. In that case running rm .hdevtools.sock often fixed the issues. One time I had to update the plugin for the false negative to go way.

vim2hs

This plugin does a whole lot of stuff, but I basically only use it for syntax highlighting. I really only have one complaint: If the name of a function includes a single quote (') then the type signature wont be highlighted properly. I might make an issue at some point, or look at the code myself.

vim-spectacular

I haven't yet done that much testing in Haskell so at the moment I've configured vim-spectacular to simply open ghci with the current file. This is useful for doing manual testing which I've found to be sufficient so far.

PS: Should you be curious, my dotfiles are on GitHub.

RSS Feed

You might have noticed that I used to have a broken link on the about page to the RSS feed for this blog. I'm happy to tell you that that has been fixed. That means you can now subscribe to the RSS feed get notified when new posts are published.

You can find the feed here. You can also just paste http://lonelyproton.com into your RSS feed reader and it should discover it. I recommend reeder for both Mac and iOS.

Laziness in Haskell

Recently I've been playing around with Haskell. For those who are not familiar Haskell is a pure, functional and lazy (by default) programming language.

Most programmers nowadays are familiar with functional languages. Pretty much all modern languages have functions like map, reduce, filter, etc. built-in, and those are essentially higher order functions coming from the world of functional programming. Lots of people are also talking about the benefits of immutability, which is also something that comes from the functional world. But I doubt most people are familiar with lazy languages. Thats probably because the only widely adopted lazy languages is Haskell, and not that many people are familiar with Haskell.

However, consider the following piece of Ruby code:

require "benchmark/ips"

a = (1..2000000).to_a

Benchmark.ips do |x|
  x.report("several maps") do
    a
      .map { |x| x + 1 }
      .map { |x| x + 1 }
      .map { |x| x + 1 }
      .map { |x| x + 1 }
      .reduce(0, :+)
  end

  x.report("one map") do
    a
      .map { |x| x + 1 + 1 + 1 + 1 }
      .reduce(0, :+)
  end

  x.compare!
end

Which of these two implementations do you think is faster? Common sense says it should be the last one called "one map". There we are only looping through the array once: One time doing the map and adding four to each element, and a second time to compute the sum. In contrast to the first one where we map across the list four times adding one each time.

If we run this code, Benchmark.ips gives us something like this:

Calculating -------------------------------------
        several maps     1.000  i/100ms
             one map     1.000  i/100ms
-------------------------------------------------
        several maps      1.907  (± 0.0%) i/s -     10.000
             one map      4.314  (± 0.0%) i/s -     22.000

Comparison:
             one map:        4.3 i/s
        several maps:        1.9 i/s - 2.26x slower

It clearly shows that in fact doing several maps is way slower than just doing one. Everything is as we expected.

If we try to do something equivalent in Haskell we get a different result. Here is a piece of Haskell code thats equivalent to the first example where we mapped multiple times:

module Main where

main :: IO ()
main = do
    let x = [1 .. 2000000]
    print $ foldr (+) 0 $ map (+ 1)
                        $ map (+ 1)
                        $ map (+ 1)
                        $ map (+ 1) x

And here is the other version where we map only once:

module Main where

main :: IO ()
main = do
    let x = [1 .. 2000000]
    print $ foldr (+) 0 $ map (\x -> x + 1 + 1 + 1 + 1) x

Lets compile these two programs and look at the time output:

$ ghc -O2 Once

$ ghc -O2 Several

$ time ./once
2000009000000
./once  0.23s user 0.03s system 99% cpu 0.270 total

$ time ./several
2000009000000
./several  0.23s user 0.03s system 99% cpu 0.267 total

To our surprise we see that both versions take the same amount of time. This is because Haskell is a lazy. The execution of the program goes something like this:

  • It sets x equal to the list of integers from 1 to 2000000. However it doesn't actually build the list yet, because its lazy.
  • It prints the sum of the list after mapping, which requires that foldr does its job.
  • Since foldr loops through the values in the list one at a time, it requests the values to be computed one by one, not all at once.
  • The first input value to foldr is the last value in the list after mapping. This value is computed by figuring out what the last element in the list (without evaluating the whole list) and applying the maps to that value. Note that we are only mapping one value, because foldr haven't requested the whole list, just the last element.
  • foldr now adds the initial value and the mapped one, requests the next value and so on until the list is empty.

By doing this its clear that doing four maps or one takes equal amounts of time. Because they're not evaluated before foldr requests the result.

I think this way of programming, when you're working with lists especially, is really great. It allows you to separate the different parts of your algorithm into smaller functions without sacrificing performance because you're iterating the same data structure more than once. Its something I really miss when I'm in Ruby.

Previously

← Archive