Skip to content

MON vs. TOML

TOML (Tom’s Obvious, Minimal Language) is a popular choice for configuration files due to its human-friendly syntax and clear mapping to a hash table. It aims to be easy to read and write. However, for projects requiring advanced features like data reusability, integrated schema validation, and a more robust module system, MON (Mycel Object Notation) offers a compelling TOML alternative.

This document outlines the key differences and advantages of MON over TOML.

TOML is designed for readability, especially for simple key-value pairs. However, nested structures can sometimes become verbose with repeated table headers.

config.toml
[user]
name = "Alice"
email = "alice@example.com"
[user.settings]
theme = "dark"
notifications = true

MON maintains readability while offering more flexibility and conciseness for nested data.

{
// Comments are first-class citizens
user: {
name: "Alice",
email: "alice@example.com",
settings: {
theme: "dark",
notifications: on, // Booleans as 'on'/'off' are natural
},
},
}

MON Advantages:

  • Consistent Structure: Uses {} for objects and [] for arrays, providing a clear visual hierarchy without repeated table headers.
  • Comments: Explicit support for single-line // comments.
  • Unquoted Keys: Keys can be unquoted unless they contain special characters or spaces.
  • Flexible Booleans: Uses on/off in addition to true/false.
  • Trailing Commas: Allowed in lists and objects, preventing common copy-paste errors.

TOML has no native features for data reusability or templating. Any repeated configuration blocks or values must be duplicated, which can lead to maintenance overhead.

To reuse data in TOML, you typically rely on external templating engines or duplicate the data.

config.toml
[default_settings]
theme = "dark"
notifications = true
[user_alice]
name = "Alice"
theme = "dark" # Duplicated
notifications = true # Duplicated
[user_bob]
name = "Bob"
theme = "dark" # Duplicated
notifications = false

MON provides powerful first-class features for data reuse, making MON configurations incredibly DRY (Don’t Repeat Yourself) and easy to manage.

{
// Define a reusable template for default settings
&default_settings: {
theme: "dark",
notifications: on,
},
user_alice: {
name: "Alice",
// Spread the default settings
...*default_settings,
},
user_bob: {
name: "Bob",
// Spread the default settings and override notifications
...*default_settings,
notifications: off,
},
}

MON Advantages:

  • Anchors (&): Define reusable data blocks or fragments.
  • Aliases (*): Create independent, deep copies of anchored values.
  • Spreads (...*): Merge and extend anchored objects or arrays, allowing for powerful templating and overriding.
  • Reduced Duplication: Significantly cuts down on verbose, repeated configuration.

TOML does not have a built-in schema definition or validation system. Users often rely on external tools or custom parsers to enforce data integrity.

Requires external validation logic or custom code to ensure configuration correctness.

config.toml
# No native way to define that 'id' must be a number or 'username' a string
[user]
id = 123
username = "alice"

MON integrates schema validation directly into the language, using #struct and #enum to define types and the :: operator for validation. This ensures data integrity at the language level.

{
// Define the schema for a User within the MON file itself
User: #struct {
id(Number),
username(String),
is_active(Boolean) = true,
},
// Validate a user instance against the defined schema
alice :: User = {
id: 1,
username: "alice",
is_active: on,
},
// This instance would fail validation because 'id' is a String, not a Number
// bob :: User = {
// id: "2",
// username: "bob",
// },
}

MON Advantages:

  • First-Class Types: #struct and #enum are part of the core language.
  • Integrated Validation: The :: operator allows direct validation within the MON file.
  • Improved Data Integrity: Catch errors during development, before they reach runtime.
  • Clear Error Messages: MON compiler provides precise error reporting.

TOML’s approach to includes is often limited, typically allowing one file to include another, but without a robust system for sharing types or namespacing. Managing large, multi-file TOML configurations can become complex.

MON offers a straightforward module system for organizing multi-file configurations and sharing types/data across files.

config.mon
// Import definitions from a separate 'schemas.mon' file
import * as schemas from "./schemas.mon"
{
db_config :: schemas.Database = {
host: "localhost",
port: 5432,
},
}

MON Advantages:

  • Native Imports: import statements allow for explicit dependency management.
  • Code Organization: Easily split large configurations into logical, manageable files.
  • Shared Definitions: Share types, templates, and data blocks across your project.

While TOML excels in simplicity for basic configurations, MON provides a more powerful and comprehensive solution for complex and evolving projects. Its superior readability, native data reusability, integrated schema validation, and robust module system make it an excellent TOML alternative for modern configuration languages and data structuring.

Consider adopting MON if your project demands high maintainability, data integrity, and efficient management of complex configurations.