The Azimuth Project
Experiments in the Fay EDSL for Javascript (changes)

Showing changes from revision #5 to #6: Added | Removed | Changed


An attempt at a simplest possible functional programming syntax for simulation model specification using the Fay embedded domain specific language (EDSL) and Javascript compiler.

The following code snippets are under test and might provide a basis for a first FSim.hs. They have mostly been lifted directly from other people’s code in Haskell or ported from other languages.


  • Matrix operations
  • Fourier transform (inverse missing)
  • Euler’s method
  • RK4
  • Crank-Nicholson method
  • Kalman filter
  • Circuits
  • Onsager
  • misc.


  • Ring oscillator
  • Zero-dimension energy balance model (EBM)
  • One-dimensional EBM
  • Kamp advective ocean model
  • Game of Life
  • misc.

RS Latch

Compiled Javascript from a Haskell application.

Bistable climate

Direct port of Nathan Urban’s R code</h1>

q0,c1,c2,m,sigma,tc,kappa :: Double
q0 = 342.5
c1 = 0.15
c2 = 0.7
m = 0.4
sigma = 5.6697e-8
tc = 273
kappa = 0.05

t0 :: (Fractional a, Floating a) => a
t0 = (1.9e-15)**(-1/6) -- correct
-- T0 = (1.9e-15)^(1/6) # ZG10 bug

t :: [Double]
t = [200,300,400]

main :: IO ()
main = do
  let ros = fmap ro t
      ir mu t = ri t mu
      ris = fmap (ir mu) t
  print $ zipWith (-) ros ris

-- incoming radiation
ri :: Double -> Double -> Double
ri t mu = mu * q0 * (1-alpha) where
    alpha = c1 + c2*(1-tanh(kappa*(t-tc)))/2

-- outgoing radiation
ro :: Double -> Double
ro t = sigma * g * t**4 where 
       g = 1 - m*tanh((t/t0)^6)    
-- plot outgoing radation as a function of temperature
-- plot(T, Ro(T),

xRng,yRng :: [Int]
xRng = [150..400] 
yRng = [0..630]

"Zaliapin and Ghil (2010), Fig. 4",

This code plots incoming radiation, for different fractional insolations

-- Output ==>
-- 0.5, 60.55600727363061 34.787581731296   -16.749269353373222
-- 1.0, 159.1940519573757 21.18048301470816 -254.84665487062694
-- 2.0, 725.3039876743584 579.7418534269186 -288.61758493203934

Ring oscillator

Ian Ross’s “Fun with Fay” is a literate blog post using Fay and html5 canvas and a timer to display an animated 5 ring oscillator with dynamic graphs.

This seemed like a good example to start with but is too complicated for describing simple simulations.

The stripped-out user interfaceses html5 Options for parameter values. This avoids the FF non-working html5 slider problem.

Work is in progress on the simulation function (loop step? iterate step?) and graph rendering etc.

He also has another blog post on creating a good-looking jquery slider. Unfortunately this is for the Yesod web framework and needs to be ported to Snap TBD.

Zero-Dimension [Zero-Dimension EBM EBM]

I have no idea where these parameters came from, it’s merely for illustrative purposes.


In the Fay proper subset of Haskell

If the code contains FFI calls then the compiler is usually invoked with:

testCO2 = temp 4.3

fay --package fay-base <yourcode>.hs

temp f = (-f)/totalF whereIf the code has a main function and you want to automatically generate an html file, the syntax is:

lambda0 = 3.2 :: Double -- Plank

fay --html-wrapper <...

totalF = avLambda - lambda0If you want to produce a library then:

avLambda = (maxSumF - minSumF)/2

fay --library

minSumF = foldl (+) 0 (fmap fst lambda)If you want to include a javascript file then:

maxSumF = foldl (+) 0 (fmap snd lambda)

fay --

lambda = [waterVapour,lapseRate,clouds,albedo]I haven’t yet mastered when to use –no-ghc. The usage says:

waterVapour = (1.48,2.14)

"Don't typecheck, specify when not working with files

lapseRate = (-0.41,-1.27)“.

clouds = (0.18,1.18)I find I have to use it under circumstances I don’t quite understand yet to avoid clashes with the ghc Prelude.

albedo = (0.07,0.34)The resulting Javascript in each of these examples can be cut and pasted it into a text editor, saved it as

<filename>.js and run it with node.js,</filename>

The resulting Javascript.


This is supposed to be literate code so you should be able to cut and paste it into a text editor, save it as

<filename>.js and run it with node.js, ie.</filename>

` node <filename>.js

and get an answer of ~1.6 deg. C.