Skip to content

Instantly share code, notes, and snippets.


Why F#?

I got inspired to answer the questions posed to F# experts on "Why F#?". I have no claims to be an F# expert but I thought the questions were interesting.

How and when did you get started programming in F#?

I believe I started to look at F# around 2008. I am a language-curious person and was at the time working as a .NET developer so I naturally was excited when discovering F#.

How long did it take before you could code real world apps as much or more productively as in C#?

mrange /
Last active May 2, 2021
The Computer Language Benchmarks Game - Mandelbrot

The Computer Language Benchmarks Game - Mandelbrot

Source code:

  1. Update 2017-06-25 - Decided I could do a bit better with F# so I added an improved F# program that uses the .NET SSE
  2. Update 2017-07-01 - Reduced the overhead of bitmap allocation saving 9ms for 16000x16000 bitmaps
  3. Update 2017-07-06 - Improved the fast F# program by removing overy redundancy

Recently I discovered The Computer Language Benchmarks Game which intrigued me, especially the mandelbrot version.

View .zshrc
# If you come from bash you might have to change your $PATH.
# export PATH=$HOME/bin:/usr/local/bin:$PATH
# Path to your oh-my-zsh installation.
export ZSH="/home/mrange/.oh-my-zsh"
# Set name of the theme to load --- if set to "random", it will
# load a random theme each time oh-my-zsh is loaded, in which case,
# to know which specific one was loaded, run: echo $RANDOM_THEME
# See
View settings.json
"editor.fontSize": 40,
"editor.fontLigatures": false,
"editor.tabSize": 2,
"editor.renderWhitespace": "all",
"files.trimTrailingWhitespace": true,
"editor.codeLens": false,
"editor.rulers": [
mrange /
Created Mar 18, 2017
Railway Oriented Programming and F# Result

Railway Oriented Programming and F# Result

Full source:

Option<_> is great for ROP (Railway Oriented Programming) but we get no info on what went wrong (the failure value is None which carries no info).

With the introduction F# 4.1 we got Result<_, _> a "smarter" Option<_> as it allows us to pass a failure value.

However, when one inspects the signature of Result.bind one sees a potential issue for ROP:

View trampoline.fs
type Next<'T> =
| Done of 'T
| Jump of Trampoline<'T>
and Trampoline<'T> = unit -> Next<'T>
module Trampoline =
let Return v : Trampoline<'T> =
fun () ->
Done v
mrange / experiment.glsl
Last active Mar 21, 2021
View experiment.glsl
#define RESOLUTION resolution
#define SCA(x) vec2(sin(x), cos(x))
#define PI pi
#define TAU tau
#define TIME time
#define TTIME (TAU*TIME)
#define RESOLUTION resolution
#define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
#define PSIN(a) (0.5+0.5*sin(a))
#define L2(x) dot(x, x)
mrange / parser.fs
Last active Mar 18, 2021
F# simple and slow parser combinators
View parser.fs
// Inspired by:
// A Parser is a function that given a string and an index into that string
// produces a parsed value and the index of the first unparsed character in the string
type Parser<'T> = P of (string -> int -> ('T*int) option)
module Parser =
open System
// Runs the parser on a string
View amiga1.glsl
#define TOLERANCE 0.0001
#define NORM_OFF 0.001
#define MAX_RAY_LENGTH 12.0
#define MAX_RAY_MARCHES 65
#define PI 3.141592654
#define TAU (2.0*PI)
#define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
#define TIME iTime
View atari.glsl
// License CC0: Tribute to my old Atari
// That's where it started for me
#define TIME iTime
#define RESOLUTION iResolution
#define PI 3.141592654
#define TAU (2.0*PI)
#define L2(x) dot(x, x)
#define ROT(a) mat2(cos(a), sin(a), -sin(a), cos(a))
#define TTIME (TAU*TIME)