Hacker News new | ask | show | jobs
by bsamuels 3408 days ago
Unit annotation is F#'s secret killer feature.

I did a small video game in F# using unit annotation and was shocked at the number of bugs that unit annotation picks up at compile time.

If you work with a lot of unit conversions (pixels, inches, whatever), I highly recommend giving F# a shot on a small project.

Unit annotation + access to the .NET ecosystem has made this language a personal favorite for any project heavy with numbers.

2 comments

How was your experience with F# and game development? I like F#'s syntax so much more than C#(plus some stuff like pattern matching are so nice). However I feel like FP isn't effective for gamedev.
> However I feel like FP isn't effective for gamedev.

Oddly, in my limited experience, it is very effective.

I can't say it's the right pattern for every game but for the current roguelike I've been working on in my spare time it's been the best thing since sliced bread. I use the Reader and State Transformer monads in a pattern similar to the Elm Architecture that results in my engine being completely deterministic.

This allows me to dump all of the initial state of the game and all of the serialized inputs to it. I can then take that dump and step through that entire game session. This is great for debugging with friends and stuff: when they encounter an error or something they don't like they can just send me the dump file and I can replay their entire session. It's been pretty cool being able to do that.

Another thing I didn't understand at first was that immutability seemed like an egregious waste of resources. It might still be for some applications but it has much better performance characteristics than my intuition had led me to believe... because structural sharing. You can have this big blob of state that looks like it's being copied every where but it's not -- under the hood you're actually sharing 99% of the previous state and not copying anything.

It's not likely you're going to be writing a bleeding-edge rendering engine in a pure FP language on any current generation hardware platforms but you can get quite far with it.

Obligatory prog21 article on that topic:

"A Worst Case for Functional Programming?"

http://prog21.dadgum.com/189.html

Previous HN discussion: https://news.ycombinator.com/item?id=7043644

Can you do a blog post on this?
The biggest gains I saw had to do with the units of measure and state management, with a big emphasis on the latter.

Nearly none of the traditional game-based OOP design patterns map cleanly into F# (or any functional lang for that matter) - I often had to get creative but the results were very interesting.

Take an OOP based game for an example; tracking where your game state is, how it's being mutated, and figuring out exactly what entities have been mutated can be a nightmare. With F# I ended up with a single large data structure to store the game state, and because of F#'s pedantic immutability, it's very easy to find where that game state is modified.

The only issue with the scheme above is that there are some cases where you NEED to store game state as a variable captured by a closure. That might sound really awful, but in practice variables captured by a closure are always read-only, so unless you're replacing that closure, you don't have to worry about some weird mutability sneaking up on you.

Here's my first F# minigame, a mostly-finished breakout clone: https://github.com/bsamuels453/BreakoutFSharp

Here's the second game that uses units of measure - it was supposed to be an asteroids clone but is mostly unfinished: https://github.com/bsamuels453/X81-Prototype

Type declarations for the units of measure/data structures I used: https://github.com/bsamuels453/X81-Prototype/blob/rts/X-81_P...

You can do imperative and object-oriented programming with F# :-) Here's an example with a Windows Forms button which modifies a string variable on click:

    let mutable greeting = ""
    let btn_say_hi = new Button(Text = "Say Hi", Parent = frm_main)

    btn_say_hi.Click.Add(fun _ -> greeting <- "Hi!")
Curious about this also. Last time I took a peek at F# I wanted to make a simple game, but all the compatible tools seemed like C# tools that allegedly work for F# as well. Wound up using Lua/LOVE instead.
Is there a writeup somewhere of this feature?
That actually looks really indispensable when you're working with units! I wonder if functional langs without this feature might be able to implement it via macros somehow which only run at build time...
Scala has a library for units of measure: http://www.squants.com/

I think you can do it in most reasonable statically-typed languages, with a little care. Scala makes automatic conversions a bit easier because it lets users specify them. Like C# actually. You could probably do UoM in C# too.