Functional programming at code clubs

In my tech mentoring at Coder Dojo and Code Clubs I'm always on the look out for new things that broaden the mind, offer alternative approaches and get people thinking differently. So what about functional programming? How would that work at a code club? Is it even possible in Scratch?

Functional programming enables you to:
  • Write functions that take input and produce output with no side-effects, which makes them easy to reason about and test in isolation, and easy to share across projects
  • Use recursion to process lists of things, avoiding the work of loops and loop counters
  • Write higher-order functions that take other functions or blocks as input, making it possible to write custom logic or iteration blocks, such as for-each, map, filter or fold.
In addition, the functional programming approach helps you to think differently about algorithms, often resulting in a more concise, elegant solution to a programming challenge. Indeed, many mainstream languages have adopted functional features to bring these benefits to the programmer, see examples in Python and JavaScript.

MIT Scratch is the most popular programming language we use at code clubs and I've explored it to see if I can demonstrate functional programming. Unfortunately it's not possible to create blocks that return values (Reporter blocks -- Stack Overflow post) so I need another tool.

Snap looks like the answer. It's a extended reimplementation of Scratch that allows you to build your own blocks with many more options than Scratch. In the creator's words it is Scratch + the power of Scheme.

Modelling a flock of animals

To explore functional programming, we need an interesting app to create, how about Boids? Boids simulate the flocking behaviour of animals, such as birds or sheep. There are 3 simple to state rules:
  1. separation: steer to avoid crowding local flockmates
  2. alignment: steer towards the average heading of local flockmates
  3. cohesion: steer to move toward the average position (center of mass) of local flockmates
These are simple to state but harder to program! Here are some initial versions, click a title to see the code running in Snap.

Sheep Boids zero 

Let's start with a very simple version: here our sheep are moving randomly with no concern for each other. This has one new block (and nothing functional yet): if-on-edge-wrap — and nothing Scratch can't do:

Here our sheep are moving randomly, but they know when they are near another boid and flash. This has a new control block for-each:

So for every other clone we check the distance and switch costume if it's less than 60. The new for-each block makes it easy to do things to every element of the list, without having to do the usual loop work in Scratch. 

Here's the definition of the block, it takes a list and a code-block as parameters and uses recursion to work through the items of the list:

Sheep Boids 2 mouse

Now our sheep like the mouse pointer and move towards it. There are several new functions mostly to calculate the force applied to each sheep from the mouse, see them in the Operators section.

To do...

There's lots left to do:
  • The sheep move too fast, maybe they should have a maximum speed?
  • While we've shown how the sheep react to the mouse pointer, they don't react to each other yet —version 1d has a starting point for this behaviour
  • ...TBC
I'll add more as I explore at the code clubs...

A photo bank on your Raspberry Pi

I've been taking photos for years and now have many thousands, in fact too many to store on my laptop. My family take photos too, and we all like to share them.

None of us are particularly happy with Facebook or other online photo sharing sites, and anyway most of these are geared towards individual photographers, not a family of photo sharers.

As I'm a programmer I like to know how things work and strongly favour a solution where I can see and test the photo and metadata storage, so that I know that everything is safe. (And OK, yes, as a programmer I'm much more motivated to create my own solution rather than use an existing one!)

So how do we store and share our photos? Our solution: a Home Photo Bank. It's a safe place to store and share your family photos on your home network.

If you've got a spare Raspberry Pi around (or indeed any Linux or Mac computer), then follow this blog post to get your own photo bank up and running.

As well as photo storage and sharing, there are also tagging features so that you can categorise and discover related photos.

You can read a bit more about the photo bank on its GitHub page:

What you need:

  • A Raspberry Pi, model 2 or 3, running Raspbian
  • A router to plug it into, or use wifi
  • Some familiarity with the linux command line.

The set up:

Here's what we'll cover:
  • Set a hostname on your Pi so that your family can access it
  • Install packages: oracle-java8-jdk and mongodb
  • Install the application
  • Create cron 'reboot' entry to run the photo bank
  • Add a photo-uploader user, SSH keys and local scripts to make it easy to import files
  • Test that it works.

Set a hostname

Your family and friends (and anyone else on your home network) need to be able to access the photo bank. Set the Pi's hostname by editing /etc/hostname and then share the link http://photobank.local:3000/ - replace "photobank" with whatever hostname you gave your pi.

Install packages

Use apt-get to install the required packages: Java JDK for the runtime, and MongoDB for the data store and git to get the app itself.

sudo apt-get install oracle-java8-jdk mongodb git

Install the Photo Bank

There are five parts to the install:
  1. Install the build tool Leiningen
  2. Get the app source code
  3. Make media directories
  4. Set database credentials
  5. Run the app to download dependencies and start up the photo bank
To get Leiningen:

chmod +x lein

To get the app source code run: 

git clone

The photo bank stores photos in media directories. Create these before you run the app:

cd home-photo-bank/media
mkdir _import _process _failed

The media and database credentials are stored in the file profiles.clj -- create this file and add these lines:

    {:media-path "media"
     :database-url "mongodb://localhost/photo-bank" }}}

Now run the app, this will download all dependencies on the first run:

cd home-photo-bank
lein run

Now you should be able to browse to http://photobank.local:3000/

Check back soon for the rest of the detail...