Friday, 31 July 2015

Haskell - playing with Hackage

OK, so you have just finished reading your first Haskell book, you understand most of (if not all!) compilation errors GHC throws at you and you start thinking creatively about the language. If you are at this stage and wondering what's next, welcome to my team! Not so long ago I finished Learn you a Haskell and, while reading The Haskell Road to Logic, Maths and Programming, I decided I was ready to start playing with Hackage. My package of choice was Rasterific - mostly because I wanted to get something on the screen quickly.

In this update I'm going to walk you through installing a package of your choice (+ all its dependencies) in your local cabal sandbox and using it in your own Haskell program. Let's get started!

First of all, let's make sure you have the latest versions of

  • Cabal
  • cabal-install
installed. To do that, simply run the following command from your command line:
cabal install Cabal cabal-install
This will install the latest versions of both packages.

Once it's done, let's update cabal packages using the following command:

cabal update

Now, a special note for the Haskell Platform users: the cabal you are using from the command line might not (and it wasn't in my case) be the one being updated! In my case, the cabal my PATH variable was pointing at was located in the Haskell Platform folder

...\Haskell Platform\2013.2.0.0\lib\Cabal-1.16.0
but executing those commands made the cabal install its latest version in
C:\Users\Piotr\AppData\Roaming\cabal\bin (version
I had to come up with a solution and I ended up changing my PATH variable to use the cabal installed in my AppData.

Once you have the PATH variable pointing at the updated cabal, navigate to the folder you want to place your experimental project in (still using the command line) and type:

cabal sandbox init
This will create a folder-local sandbox environment for packages that could have otherwise damaged your global cabal repository. In case anything goes wrong in the sandbox, you can always delete it and start fresh - no need to modify your global set of packages.

Once you have the local sandbox prepared, you are ready to install your package of choice and its dependencies. Just in case, make the first run dry (just list the required dependencies):

cabal install Rasterific --dry-run
You should see something like this:
Resolving dependencies...
In order, the following would be installed:
base-orphans-0.4.0 (new package)
bytestring- (new version)
Win32- (new version)
binary- (new version)
text- -integer-simple (new version)
hashable- (new version)
nats-1 (reinstall) changes: hashable- ->
time- (new version)
directory- (new version)
FontyFruity- (new package)
mwc-random- (new package)
unordered-containers- (new version)
semigroups- (reinstall) changes: bytestring- ->,
hashable- ->, text- ->,
unordered-containers- ->
bifunctors-5 (new version)
vector-algorithms-0.7 (new package)
void-0.7 (reinstall) changes: hashable- ->
contravariant- (new version)
comonad- (new version)
profunctors-5.1.1 (new version)
semigroupoids- (new version)
free-4.12.1 (new version)
zlib- (new version)
JuicyPixels- (new version)
Rasterific-0.6.1 (new package)
Warning: The following packages are likely to be broken by the reinstalls:
Use --force-reinstalls if you want to install anyway.

Once you're happy with required dependencies, simply run:

cabal install Rasterific

If everything goes well, you are ready to start playing with the package! You can find Rasterific documentation here. I used it to write a small program drawing rectangles into a file:

import Codec.Picture(PixelRGBA8( .. ), writePng)
import Graphics.Rasterific
import Graphics.Rasterific.Texture

main :: IO ()
main = do
    let backgroundColour = PixelRGBA8 234 247 217 255 -- Cilantro Creme
        foregroundColour1 = PixelRGBA8 195 214 170 255 -- Mint Sherbert
        foregroundColour2 = PixelRGBA8 142 168 108 255 -- Pesto Paste
        foregroundColour3 = PixelRGBA8 77 100 45 255 -- Simple Green
        foregroundColour4 = PixelRGBA8 40 58 16 255 -- Dark Water
        image = renderDrawing 400 400 backgroundColour $ do
            withTexture (uniformTexture foregroundColour1) . fill $ rectangle (V2 50 50) 145 145
            withTexture (uniformTexture foregroundColour2) . fill $ rectangle (V2 205 50) 145 145
            withTexture (uniformTexture foregroundColour3) . fill $ rectangle (V2 50 205) 145 145
            withTexture (uniformTexture foregroundColour4) . fill $ rectangle (V2 205 205) 145 145
    writePng "test.png" image

-- palette taken from:
You can also find the code here. To build it, execute the following command (and this is where a local sandbox comes very handy):
ghc -package-db=.cabal-sandbox\i386-windows-ghc-7.6.3-packages.conf.d main.hs
Once the program compiles, you can run it and start drawing. Here is my result:

And that's it! You have just installed your first package and used it in your own program. Please leave a comment if the installation process was different for you or if you experienced some other problems.

Let the adventure with Hackage begin!

Saturday, 25 July 2015

Haskell - the power of type declarations

Haskell - a very interesting functional language, which continuously helps me become a better programmer and a more efficient thinker. One small example (exercise 1.24) I found in the book I'm currently reading (The Haskell Road to Logic, Maths and Programming) made me think: "wow, this is just great". This "wow" moment is something I would like to share with you today. I am going to show you that it's the type declaration and not the actual body of the function that you should consider your best friend while reasoning about the function's job. Haskell, as a strongly and statically typed language lets you do that. If you think it's crazy, please read on!

Let's look at a small program:

add2 :: Integer -> Integer
add2 x = (2 + x)

main = print $ add2 1 -- prints "3"
If you're a Haskell virgin, I hope you can still follow what's happening (if not, take a look at some other examples from e.g. Wikipedia to get a feel of the language). The add2's type declaration (first line) states:

I transform Integers into Integers.

Pretty simple. However, you might come across a slightly different interpretation:

I take one parameter of type Integer and return an Integer.

Which also works in our simple example. You might now ask: "ok, so now how do we write type declarations for functions which take more than one parameter?".
add x y = x + y
I remember asking this question myself and experimenting with constructs like:
add :: Integer Integer -> Integer
add x y = x + y
add :: Integer, Integer -> Integer
add x y = x + y
but none of them worked. At the time I just accepted that the compiler is smart enough to determine that the last "->" denotes the returned type and every other "->" simply chains parameters together. Weeks have passed and I started reading about lambdas, currying, partial application. I never looked back at those failed experiments from the beginning of my journey. Until now.

Let's return to our first function - add2. Exercise 1.24 (or its variant, adapted to fit my add2 example) makes you remove the parameter "x" and see what happens. Haskell allows for (and eagerly supports!) partial application of functions, so in our example, the additon is just partially applied (we only have one out of two parameters: 2). Not a big thing. Let's remove the "x" and look at the code now:

add2 :: Integer -> Integer
add2 = (2 +)

main = print $ add2 1 -- prints "3"
This is when I started connecting the dots. I expected the code to work, but I never thought of this:
  1. If my function (partially applying addition) works without the parameter, it really is nothing more than just an alias for that partial application of addition. This was a very powerful thought as it was always natural to me to associate the assignment operation with some sort of an order for the computer to "run the code on the right to give value to the code on the left". I started asking more questions:
    • If we don't need the "x" now, have we ever really needed it?
    • Is this going to change the way I think about code (not only the functional code)?
    • If so, how will all my programs look from now on?
    I am in the process of looking for answers to these questions and I find it very fresh and exciting.
  2. Let's look at the type declaration again - it hasn't changed! This made me think that my perception of type declarations was not very accurate. I realised that it serves as the promise of what the function is expected to achieve. The body obviously does the heavy lifting and fleshes the type declaration out, but it's the type declaration that helps understand the big picture. In the end, it does not really matter if your function takes one parameter and returns its processesed value or takes zero parameters and returns (or acts as!) a function that does it. What matters is the transformation defined in the type declaration. Implementation is just a set of various operations that should follow the principles outlined in the type declaration.

Learning Haskell (and functional programming in general) is a great experience which I can highly recommend to every software engineer. I plan to continue reading and understanding Haskell as it's a great source of inspiration and ideas. I've been writing some sandbox Haskell code in my free time, which you can find here and contribute if you please.

I hope this makes sense to you and if not (or if so!), please feel free to leave a comment in the section below.

Monday, 13 July 2015

Teensy 3.1 programmer for ATtiny85 chips - going permanent, part 3

This is a continuation of my previous post Teensy 3.1 programmer for ATtiny85 chips - going permanent, part 2 and the last part of the tutorial. After a couple of months of a break, this time, I'm going to connect indicator LEDs and the socket. The board does not look as clean and neat as initially thought it would, but it's my first one afterall.

I took my time finishing the board as after wiring everything up and soldering it together, I introduced a hardware bug and couldn't figure out where it was. After a couple of days of scratching my head I put my unfinished board on the shelf and decided I would get back to it at some stage. I looked at it almost every day for a couple of months saying to myself: "I will fix you some day" and finally, last weekend I decided that this just has to end. I took my trusty yellow multimeter and started debugging.

Finding hardware problems is not as easy as debugging a high level program. There's no IDE, no debugger, no stack trace. There is just your board and your multimeter. And a short circuit somewhere. Debugging a physical circuit is not as easy as "stepping into" your code or whatever term you use (if you've ever debugger a program, that is!). It is a tedious set of checks, one wire after another. One after another, and again and again... Even if you find a bug (minimal or infinitely large resistance), it is not immediately obvious what causes it. It wasn't any different in my case.

I found two short circuits and I had no idea what could have caused them. I almost gave up a couple of times, but after hours and hours of probing, I finally found my mistake. And when I finally did, I was far from happy with what caused it! As it turns out, when you drill a hole in the copper strip to break the connection, you have to be very careful not to leave any residue copper touching the neighbouring strips. Zero, null. If you do (and you might not even see it!), you, my friend, are up for a treat - hours of tedious tests and misery.

Thankfully all ended well and I finally fixed the board. Let me show you the process step by step.

  1. Indicator LEDs connected and working (I decided to stir thing up a bit and assign the red LED to WRITE signal):
  2. Socket connected:
  3. RESET and GND lines connected:
  4. Remaining lines connected:
  5. And finally, the board gets cut:

This is the final part of the tutorial.

A piece of advice for keen fans of electronics: think twice before you buy a stripboard like mine. If you're a beginner, just like me, it will most definitely cost you hours of head-scratching if you make a tiniest mistake. And after it's finished, it will not look pretty.

However, finding a bug and fixing it does give some sort of feeling of accomplishment, so it wasn't all that bad :)

Thanks for reading and happy hardware hacking!