Minimal Object Description Language

MODL (sounds like "doddle") is a compact, plain text data serialisation language for describing objects in as few characters as possible. It's designed to be character efficient when stored or in transport and developer friendly to receive and work with. In this introduction we compare MODL with other data serialisation formats and demonstrate how MODL can store an identical collection of objects using 61% fewer characters than JSON.

Example MODL Object

This is a basic MODL example:

copy to clipboard
## A pair with the key 'car' is assigned a value containing a map car( ## The map is made up of pairs make=Bentley; model=Continental GT;## Comments can be added anywhere styles[ ## A pair with the key 'styles' is assigned a value containing an array, it contains two items fastback; convertible ] )
An example MODL object

MODL can be minified by removing newlines and comments:

copy to clipboard
car(make=Bentley;model=Continental GT;styles[fastback;convertible])
An example MODL object minified

Comparison vs JSON & YAML

Let's compare MODL with the two most popular plain text data serialisation languages: JSON and YAML.

Data Type Comparison

We'll compare JSON, YAML and MODL for assigning each data type to the key x. In all cases, we'll use the most character efficient way to assign a value. We'll show a character count (including new line and space characters) and a percentage reduction for YAML and MODL compared to JSON.

String

JSON
"x": "a"
8 chars
YAML
x: a
4 chars(50% less)
MODL
x=a
3 chars(62% less)

Number

JSON
"x":1
5 chars
YAML
x: 1
4 chars(20% less)
MODL
x=1
3 chars(40% less)

Array

JSON
"x":[1,2,3] 
 
 
11 chars
YAML
x:
 - 1
 - 2
 - 3
17 chars(54% more)
MODL
x=1:2:3 
 
 
7 chars(36% less)

Object / Map

JSON
"x":{"y":"z"} 
13 chars
YAML
x:
 'y': z
10 chars(23% less)
MODL
x(y=z) 
6 chars(53% less)

True

JSON
"x":true
8 chars
YAML
x: y
4 chars(50% less)
MODL
x=01
4 chars(50% less)

False

JSON
"x":false
9 chars
YAML
x: n
4 chars(55% less)
MODL
x=00
4 chars(55% less)

Null

JSON
"x":null
8 chars
YAML
x:
2 chars(75% less)
MODL
x=000
5 chars(37% less)

Single Object Comparison

To compare the three formats for storing a simple object, we'll use the example object from json.org Content on another site.. YAML is the only format with a requirement for spacing, but for comparison each is formatted with 2 space indenting and no extra spacing.

copy to clipboard
glossary( title=example glossary; GlossDiv( title=S; GlossList( GlossEntry( ID=SGML; SortAs=SGML; GlossTerm=Standard Generalized Markup Language; Acronym=SGML; Abbrev=ISO 8879\:1986; GlossDef( para=A meta-markup language, used to create markup languages such as DocBook.; GlossSeeAlso=GML:XML ); GlossSee=markup ) ) ) )
  • JSON (535 chars)
  • YAML (431 chars)
  • MODL (433 chars)

Reduce Repeating Data

One way to make an object more efficient is to reduce the repetition of data. JSON has no facility to do this but YAML can repeat nodes. MODL deals with repeating data with object referencing and the object index. For illustration, we've highlighted the parts that deal with repeating data in YAML and MODL:

copy to clipboard
?=SGML:language; glossary( title=example glossary; GlossDiv( title=S; GlossList( GlossEntry( ID=%0; SortAs=%0; GlossTerm=Standard Generalized Markup %1.i; Acronym=%0; Abbrev=ISO 8879\:1986; GlossDef( para=A meta-markup %1%, used to create markup %1%s such as DocBook.; GlossSeeAlso=GML:XML ); GlossSee=markup ) ) ) )
  • JSON (535 chars)
  • YAML (430 chars)
  • MODL (430 chars)

In the MODL object above you will notice percent prefixed numbers %0, %1 and also the percent encapsulated number %1%, these represent references to the object index. The object index is defined on the first line with the key ?. The reference %1.i instructs the interpreter to run the method i on the second object in the index, which capitalises the first letter of the reference value.

The character efficiency gains in this example are negligible but reducing repeating data can clearly help make larger objects more character efficient.

Minification

It's common practice to minify objects. There are two steps in minification – reducing keys and removing spaces. We've replaced the original keys with 1 or 2 character alternatives and removed all spacing from the JSON and MODL examples. YAML requires spacing for structure so it can't be fully minified:

copy to clipboard
?=SGML:language;g(t=example glossary;d(t=S;l(e(i=%0;s=%0;gt=Standard Generalized Markup %1.i;a=%0;ab=ISO 8879\:1986;gd(p=A meta-markup %1%, used to create markup %1%s such as DocBook.;sa=GML:XML);gs=markup))))
  • JSON (273 chars)
  • YAML (353 chars)
  • MODL (209 chars)

We've had to make significant sacrifices in readability to achieve these character savings. This makes our object difficult for developers to work with. MODL interpreters can automatically unpack this data, returning it to it's original developer friendly state using classes, which we'll come to in a moment.

As a data serialisation format for storing a single object, we've demonstrated that MODL is more character efficient than JSON and YAML – in this example we've seen a 24% reduction when compared to JSON and over 40% reduction compared to YAML.

Storing a Single Object

JSON
273 chars
YAML
353 chars(29% more)
MODL
209 chars(23% less)

Multiple Object Comparison

MODL offers even more efficiency when describing multiple objects of the same type. Using our previous example as inspiration, we'll describe the three languages that we've been comparing: JSON, YAML and MODL. First of all, we'll compare them without using MODL's class functionality:

copy to clipboard
[ language( name=JSON; full_name=JavaScript Object Notation; launch_year=2001; requires_spacing=false; spec_url="https://www.json.org"; structures=[object;array]; primitives=[string;number;boolean;"null"] ); language( name=YAML; full_name=YAML Ain't Markup Language; launch_year=2001; requires_spacing=true; spec_url="https://www.yaml.org"; structures=[mappings;sequences]; primitives=[string;number;date;boolean;"null"] ); language( name=MODL; full_name=Minimal Object Description Language; launch_year=2018; requires_spacing=false; spec_url="https://www.modl.uk"; structures=[pair;map;array;conditional]; primitives=[string;number;boolean;"null"] ) ]
  • JSON (938 chars)
  • YAML (845 chars)
  • MODL (748 chars)

Classes

MODL classes allow us to define an object type, which an interpreter will use for all instances of it. Here's a class for our language object:

copy to clipboard
*class( *id=l; *name=language; *superclass=map; *assign[ [name;full_name;launch_year;requires_spacing;spec_url;structures;primitives] ] )
A MODL class

In MODL, asterisk prefixed keys provide instructions to the interpreter and never appear in the output object. In the class above, we're instructing the interpreter to create a new class with the id=l and name=language. We're telling it that this class is a child of the map class. We're also telling it how to assign values that are passed to it by an array.

Now we can describe our languages like this:

copy to clipboard
*class( *id=l; *name=language; *superclass=map; *assign[ [name;full_name;launch_year;requires_spacing;spec_url;structures;primitives] ] ); [ l=JSON:JavaScript Object Notation:2001:false:"https://www.json.org":[object;array]:[string;number;boolean;"null"]; l=YAML:YAML Ain't Markup Language:2001:true:"https://www.yaml.org":[mappings;sequences]:[string;number;date;boolean;"null"]; l=MODL:Minimal Object Description Language:2018:false:"https://www.modl.uk":[pair;map;array;conditional]:[string;number;boolean;"null"] ]
Describing our objects using MODL classes
Minifying Classes

Classes can be minified too. Interpreters recognise *c as well *class, *i as well as *id, *n as well as *name, *s as well as *superclass and *a as well as *assign. Here is our class minified:

copy to clipboard
*c(*i=l;*n=language;*s=map;*a=[[name;full_name;launch_year;requires_spacing;spec_url;structures;primitives]])
A MODL class minified
Loading a Class File

We've seen how to instruct the interpreter to create a class, we can also instruct the interpreter to load another MODL file using the key *load or *l. In this example, we're defining our classes in a separate file so we can easily re-use them. We'll call our file c.modl, we can import it simply using *l=c since the interpreter automatically uses the .modl extension if one hasn't been provided.

Let's compare the JSON and YAML minified objects with MODL using an imported class and object referencing to reduce repetition of data:

copy to clipboard
*l=c;?=object:array:string:number:boolean:language;[l=JSON:JavaScript %0.i Notation:2001:false:"https://www.json.org":[%0;%1]:[%2;%3;%4;"null"];l=YAML:YAML Ain't Markup %5.i:2001:true:"http://www.yaml.org":[mappings;sequences]:[%2;%3;date;%4;"null"];l=MODL:Minimal %0.i Description %5.i:2018:false:"http://www.modl.uk":[pair;map;%1;conditional]:[%2;%3;%4;"null"]]
  • JSON (530 chars)
  • YAML (629 chars)
  • MODL (363 chars)

Storing Multiple Objects

JSON
530 chars
YAML
629 chars(18% more)
MODL
363 chars(31% less)

Minified and Developer Friendly

In the section above, we looked at how classes can make objects more efficient, they also make output developer friendly. MODL interpreters can output unpacked MODL (pretty printed with original keys) but can also output JSON. To round up, let's look at an input object and an output object.

MODL Input

As we saw above, the MODL input to describe our three languages is 363 characters with an imported MODL class file. It's 468 characters to include the class definition in the file itself. Here it is using the import:

copy to clipboard
*l=c;?=object:array:string:number:boolean:language;[l=JSON:JavaScript %0.i Notation:2001:false:"https://www.json.org":[%0;%1]:[%2;%3;%4;"null"];l=YAML:YAML Ain't Markup %5.i:2001:true:"http://www.yaml.org":[mappings;sequences]:[%2;%3;date;%4;"null"];l=MODL:Minimal %0.i Description %5.i:2018:false:"http://www.modl.uk":[pair;map;%1;conditional]:[%2;%3;%4;"null"]]
MODL Input (363 characters)

After being processed by the MODL interpreter, the output object is unpacked and developer friendly.

Developer Friendly Objects

JSON
938 chars
YAML
845 chars(9% less)
MODL
363 chars(61% less)

 

MODL / JSON Output

After being processed by the MODL interpreter, the output object is unpacked and developer friendly.

copy to clipboard
[ language( name=JSON; full_name=JavaScript Object Notation; launch_year=2001; requires_spacing=false; spec_url="https://www.json.org"; structures=[object;array]; primitives=[string;number;boolean;"null"] ); language( name=YAML; full_name=YAML Ain't Markup Language; launch_year=2001; requires_spacing=true; spec_url="https://www.yaml.org"; structures=[mappings;sequences]; primitives=[string;number;date;boolean;"null"] ); language( name=MODL; full_name=Minimal Object Description Language; launch_year=2018; requires_spacing=false; spec_url="https://www.modl.uk"; structures=[pair;map;array;conditional]; primitives=[string;number;boolean;"null"] ) ]
  • JSON (938 chars)
  • MODL (748 chars)

Added Functionality

MODL offers extra functionality that typical data serialisation formats don't, including the ability to describe an object conditionally. For detailed information about how MODL works, read the Technical Specification. To get started on your own project take a look at the Developer Libraries.