Pong in F#

Why make Pong in F#?

Over the past month or so I have been grinding away learning about Functional Programming through the coursera program Programming Languages. It was a fantastic journey getting such a deep insight into the different paradigms and languages, and I highly recommend the course to anyone wanting to learn Functional principles from the ground up. However this is my first kinda large application where I can experience a problem, understand what I need from the solution and applying the solution, and repeat until the whole project is finished. I knew how to build the “outline” of Pong so the major issues will come from understanding the tools rather than the specification of the program.

Where I started

“Boilerplate”

Due to the lack of understand of the core fundamentals of the language I based a large amount of the boilerplate code on a repository by andreasfrom who built a snake game in F#. It was rather handy in that it provided me with ways to draw, movement, the gameloop itself etc.

The tools I used

I used Visual Studio (VS) 2015 to work on and build the project. As a first time VS user, I found it a very useful tool with just a few differences that I was unfamiliar with such as file the file management window (aptly titled the Solution Explorer). The most handy feature on VS was the ability to know the type of the functions with a single hover, as well as the inbuilt REPL where I could run any function independent of the other functions.

What did I learn

The Game “loop”

A very trippy attribute of game developing in F# was the fact that instead of a massive while loop where all of the functions ran, there was a recursive function which took in the ball and players, modified each with the given functions, drew them to the screen and input the newly modified versions back into itself.

Deeper intuition for Types

I had read so much about types, attempting to make sense of why there were so important to many functional developers, for example on one of the podcasts I listened to one of the researchers communicated with the compiler rather than against it using types to portray what they where trying to do. I did not understand what they meant, but I wanted to know.

It wasn’t until I started using them actively in the project did I realise how inherently useful they were. For example, I originally planned to have two distinguishing types of objects within the game, the player object and the ball object, however as I was adding functionality to the ball I realised that if a player was made with the same attributes as the ball, the same functions could be utilised. In order test my observation, I used the functions around the ball I had already built at this point, I built a player as well as some functionality around the player to input up and down commands using the keyboard, and didn’t look at the implementation of the MoveObject function but instead looked at the type it took and returned (eg BallObject -> BallObject) . Of course it did the exact same thing to the player as it did to the ball. However I think the primary benefits I find come from when I have not built the project myself and, when building functionality, I can just glance at the types to know that the function will do what I expect with whatever I put into it.

I am hesitant to leave this section in because it does seem very simplistic, put this in get this out, but it honestly did come as a revelation to me at the time and hope it may benefit someone in the future.

Mutating the Immutable the problem

One of the issues that I had which I discovered was highly relevant to game developing in a functional language was returning the whole item every time I wanted to modify something within. On the bright side, this did make me realise that that is all functional programming is, taking some type of state and morphing it to the prefered state. In this case, once the ball was rolling, the ball and both players were in a new state after every single iteration (recursion?) of the GameLoop.

Reflections

Focus on Functionality

In the future, when doing a personal functional project, I would like to make a primary focus on building something more “functional”. What do I mean by that? Well, I am not entirely sure yet, I do know that there were several impure approaches I made to developing this game such as the morphableDirection variable. I have this in place because I could not think of an alternative, it gave me the chance to check a value and change the state of the function given that value while program was still running. From what I currently understand, there are ways to fix this issue with tools such as the IO monad from Haskell.

Focusing on purity is for a personal benefit of understanding the functional paradigm and not for any practical application as of yet.

Mutating the Immutable the Solution

I did ask if the issue of having to heave around so much every time can be solved, and the solution came from Haskell developers. They told me that this is one of the reasons for lenses ie creating a exact copy of the data with just the information you want changed morphed. This sounds great however the Haskell developers also made sure to tell me that it could not be done in F#.

Greater Modularity

The player and ball acted too much like objects, I think this comes down to how I come from an OO background, I thought of the ball and player as objects rather than functions. To partially remedy this, I will need create more modular interacting functions such as the direction as one function and the position as another an only combine them when necessary, not all of the time.

My Future Project

Because of my want to continue to understand Functional Development, I have now started a new pong project in Haskell. In this way, I am forced to build purity into the game, I will make a blog article later about my experiences with Haskell and a comparison with F# development.