an eye-opening comment

Our programming model does not have to match how our computer works. I think one of the biggest intellectual hurdles with functional programming is that we know, deep down, that modern computers don’t work like that. They do have side-effects and changing, carried state. It’s a revelation to realize that the programming model you use to write programs doesn’t have to match how the computations will be physically carried out.

- HN user scott_s in response to Ask HN: Functional Programming Differences

this is a concept i’m still coming to terms with.

a few weeks ago, brian carper wrote an article in which he detailed the process he was going through while writing a final-fantasy-style RPG in clojure, from scratch, despite his oft-repeated assertion that he had “no idea what i’m doing.” one of the things about his writeup that came pretty close to blowing my mind was the way in which the game world was handled in functional-programming-land.

I’m sometimes amazed how far I can get before I need mutable state at all. The vast majority of my functions take a world value (a plain old hash-map) as an argument, and return a new world value after making changes to it. The current state of the world is whatever value is currently in the global WORLD ref. The render loop grabs a snapshot of the world from the ref on each iteration, and then draws it. Thanks to Clojure refs, the snapshot of the world is guaranteed to be consistent (e.g. no NPC objects in the middle of mutating themselves) and persistent (the world value sticks around as long as the renderer needs it, even if the WORLD ref is changing in another thread). Once it’s been drawn, the renderer throws the world snapshot away and it’s garbage-collected later. This all happens around 50-100 times per second in my game, and there’s no noticeable lag. So that’s a good thing.

wait a second. he’s passing the entire game world into most of his functions, and that’s still cool?

what the hell?

i’ve spent most of my past four years at stanford — and, hell, most of my life as a programmer — learning that this is basically the complete opposite of what you’re ever supposed to do, ever, because on the face of it, it looks like you’re wasting more resources than a Goddamned Hummer. i thought it was supposed to be caches all the way down! aren’t you supposed to cache the game world and just make incremental updates to the parts that change? doesn’t throwing away a hundred copies a second waste incredible amounts of memory and put holes in the ozone layer?

but, soft!

Our programming model does not have to match how our computer works.

oh! hm. right. the mother of all abstractions.

i haven’t done any functional programming yet, but thanks to brian and scott, i’m making it a resolution to finally learn me a haskell before the year’s out. or a clojure, or something.

update:

in the comment thread on proggit, user radarsat1 has a really eloquently put take on the situation: