src/Cdl | ||
README.md |
Cow Description Language (CDL)
In times of the pandemic, it's not easy to get real input data from your cows to demonstrate the functionality of your front end. To be able to test some features of the application, we would like to have scripts that insert fake data points into our database, allowing us how our app would behave in real time, without the need to hook up any collars. These scripts would be tedius to write...
Unless, of course, you have a Domain Specific Language (DSL) for it! Enter CDL. We can describe a cow in a turtle-style imperative language:
squareCow = do
move 10
turn 90
move 10
turn 90
move 10
turn 90
move 10
This DSL is shallowly embedded into Haskell, which means that we can use all of Haskell's abstraction capabilities:
repeat 0 _ = return ()
repeat n thing = do
thing
repeat (n-1) thing
squareCow = repeat 4 $ do
move 10
turn 90
Given a sampling frequency, CDL can generate a Python script that inserts data points into our database each "sample":
from server.fgs.model import *
from server.fgs import db
import datetime
db.session.add(DataPoint(longitude=0.0, latitude=0.0, datetime=datetime.now()))
db.session.commit()
sleep(0.1)
db.session.add(DataPoint(longitude=9.0000094e-7, latitude=0.0, datetime=datetime.now()))
db.session.commit()
sleep(0.1)
db.session.add(DataPoint(longitude=1.8000019e-6, latitude=0.0, datetime=datetime.now()))
db.session.commit()
sleep(0.1)
# ...
To generate scripts, load the program into GHCI and execute as follows:
cd src
ghci
:load Cdl/SampleCows.hs Cdl/Codegen.hs Cdl/Cow.hs
:module Cdl.SampleCows Cdl.Codegen Cdl.Cow
outputCow "test.py" 0.1 (1, 1, Coord 0 0, squareCow)
In outputCow
, the 0.1
is the sampling frequency (how often
the database will receive mock data from the cows), the first 1
is
the collar ID sending the data, the second 1
is the cow's walking speed (in meters/second),
the Coord 0 0
is the initial longitude and latitude of the cow, and squareCow
is
the cow's actions described above.
Note that the script relies on being in the same directory as the server
repository
containing our database model.