all Codit insights

Rewarding Predictions of the 2022 FIFA World Cup with F#

Using functional components to calculate the match predictions for the 2022 FIFA World Cup ensures a stricter domain and a safe developer environment.

Match-point prediction calculation

Our FIFA application lets users register their predictions for upcoming matches in the 2022 tournament. They can predict a winner, a draw, and goals scored. Behind the scenes, the application keeps an eye on the played matches and assigns points based on how correct the user’s prediction was. A perfect prediction — the user predicted the correct winner and the number of goals scored in the entire match — is worth 10 points. If the user predicted a draw correctly but not the right number of goals, they earn 5 points, and so on.

This calculation logic itself is fairly straightforward but was implemented in a complex if/else structure in the first round. Calculating points for the user is a critical part of the FIFA application, as wrongly implemented functionality could affect the entire application. It gave us the opportunity to look for a better way.

F# to the rescue

One of the great advantages of the FIFA app was that we were able to experiment with new technologies and practices. Unlike client projects, we are freer to look for new and better ways without the burden of budget. The FIFA application is built by many people within Codit who all bring different skills to the table, making this a very diverse project.

F# was chosen as the technology to calculate the user prediction points. The calculation logic is pure and has a strict input/output scheme, so was the perfect place to experiment with the functional F# programming language. F# brings a lot of added value to the table in terms of purity, immutability and correctness. As the point calculation is a critical part, F# was the way to go.

Instead of complicated if/else structures, we used pattern matching and active patterns to check and match the user’s prediction. Active patterns are a great way to extract complexity and leave the implementation clean and simple. F# has the advantage of being very readable and simple to grasp, reading almost like a regular sentence. The added value here is that it is also easier to extend and adapt than if/else structures. An extra active pattern could be added and a single line moved with ease.

💡 Note that the [<CompiledName>] attribute was added for a static function with a Pascal case name that we can expose to non-F# environments. In the C# Azure Functions where this functionality was being used, developers could call the `Game.Calculate` like any other static function. This is a good example of how both C# and F# can work together and bring their own advantages to the table. For more info on interoperability between these two languages, see this post.

Property-based testing

We did not stop there. Testing this kind of logic is as important as the production code. In the first round, we worked with simple data-driven tests to flesh out the important code flows, but after that, we looked at a more stable and correct approach: property-based testing.

Property-based testing is an excellent match for this kind of behavior, as there is a strong relationship between the input and the output that never changes. As we are in our FIFA app and are free to experiment, we also decided to do this testing in F#. Here are some of these tests:

  1. The calculated points result is based on the equality of the two inputs, not the order of the input, so we could write a commutative test property.
  2. Sending the exact same values to the calculation always results in the points for a correct score.
  3. The same number of goals in both the prediction and actual result always gets the points for a draw.

⚡ Note that we do not explicitly state any input or output. We do not know what the concrete input/output will be. It could be 1, 6, 9 or any other kind of number, but we can draw conclusions based on the relationship. This way of testing makes our calculation logic safe to use.

🚩 More info on property-based testing.
🚩 More info on the Expecto library.
🚩 More info on the FsCheck library.

Conclusion

This was one of the first F# contributions to a real Codit project. The FIFA application is more than just play: the technologies we use and the lessons we learn are very valuable. They even result in new client opportunities. We can show this project as a strong use case for our talent and know-how in integration and quality code. Using F# in the 2022 FIFA app is a nice addition to this.

Thanks for reading!

Plus: good luck to the remaining Codit country in the tournament, Codit France! ⚽️

Stijn

Subscribe to our RSS feed

Thanks, we've sent the link to your inbox

Invalid email address

Submit

Your download should start shortly!

Stay in Touch - Subscribe to Our Newsletter

Keep up to date with industry trends, events and the latest customer stories

Invalid email address

Submit

Great you’re on the list!