Fork me on GitHub

Finitio

Finitio is a data language. For now, it is limited to a data definition language (DDL). Think "JSON/XML schema", but the right way. Finitio comes with a dedicated type system for defining data and a theory, called information contracts, for interoperability with programming and data exchange languages.

Suppose we want to capture information about a medical diagnosis for some patient. At left, a typical digital document in JSON. At right, the corresponding Finitio schema.

{
  "patient": {
    "id": "27b3ceb0-7e10-0131-c9f1-3c07545ed162",
    "name": "Marcia Delgados",
    "dob": "1975-11-03"
  },
  "symptoms": [
    "Nausea",
    "Fever"
  ],
  "temperature": 39.5
}
Temp = <celsius> Real( f | f >= 33.0 and f <= 45.0 )
{
  patient : {
    id   : Uuid,
    name : String( s | s.size > 0 ),
    dob  : Date( d | alive: d.year > 1890 ),
  },
  symptoms : [ String( s | s.size > 0 ) ],
  temperature : Temp
}

Suppose an invalid document comes in. With Finitio, you properly validate input data and get friendly error messages.

{
  "patient": {
    "id": "27b3ceb0",
    "dob": "1875-11-03"
  },
  "symptoms": [
    "Nausea",
    ""
  ],
  "temperature": 12.5
}

[patient/id] Invalid value `27b3ceb0` for Uuid

[patient/dob] Invalid value `1875-11-03` for Date (not alive)

[symptoms/1] Invalid value "" for String( s | s.size > 0 )

[temperature] Invalid value 12.5 for Temperature (celsius)

Data exchange languages, e.g. JSON, impose a very low data abstraction level: e.g. boolean, string & numbers. Finitio helps raising the level of discourse while navigating up and down in abstraction levels with information contracts:

[
  {
    "where": "Brussels",
    "at": "2014-03-01",
    "temperature": 13.5
  },
  {
    "where": "Paris",
    "at": "2014-02-27",
    "temperature": 12.0
  }
]
Measure = .Measure <info> {
  where: String,
  at: Date,
  temperature: Float( f | f >= -40.0 and f <= 50.0 )
}
[Measure]

Two information contracts here. An implicit one, Date, provided by Finitio itself (see implementations) and another one, Measure that connects a tuple type to a Measure class.

In Finitio-rb for instance, the Ruby binding of Finitio, loading and dressing the JSON data above correctly returns an Array of Measure instances. Dates are automatically coerced too:

[
   #<Measure:0x007fb5d3a1ba40 @where="Brussels", @at=#<Date: 2014-03-01>, @temperature=13.5>,
   #<Measure:0x007fb5d3a16450 @where="Paris", @at=#<Date: 2014-02-27>, @temperature=12.0>
]