Prose

Prose is a small language for describing systems as a field guide.

It names what exists, describes it in plain language, and shows how things relate. It does not execute or enforce behavior. It simply makes a world visible.

Below is a complete universe. You can read it top to bottom.

A universe

universe ClockworkVillage {
  describe {
    A quiet village where time passes only when you act.
  }
}

dimension timeOfDay {
  describe {
    A day is separated by distinct times.
  }

  relationship follows and isFollowedBy {
    describe {
      Times of day move forward in sequence.
    }
  }
}

timeOfDay Morning { }
timeOfDay Afternoon { }
timeOfDay Evening { }
timeOfDay Night { }

concept Chicken {
  describe {
    Chickens wander the village and lay eggs.
  }
}

concept ChickenCoop {
  describe {
    A small wooden structure where chickens sleep at night.
  }
}

concept Fox {
  describe {
    Foxes are quiet predators that hunt when the village is dark.
  }
}

relationship canOccurDuring and canBeWhile { }
relationship canOccurWhere and canBeWhere { }
relationship canOccurWith and canParticipateIn { }

concept ChickenRaid {
  describe {
    A fox enters a chicken coop and eats the chickens inside.
  }

  relationships {
    canOccurDuring {
      Evening
      Night
    }

    canOccurWhere { ChickenCoop }
    canOccurWith  { Fox }
  }
}

A universe describes a world.

It names things. It describes them. It shows how they relate.


Where declarations live

A universe is declared once.

universe ClockworkVillage {
  describe {
    A quiet village where time passes only when you act.
  }
}

Everything else is written beside it.

concept Well { }

Well is ClockworkVillage.Well. A repository describes one world, so a declaration written on its own belongs to it. You never say which.

To put something inside something else, nest it.

concept ChickenCoop {
  concept NestingBox { }
}

NestingBox is ClockworkVillage.ChickenCoop.NestingBox.

Nesting is the only hierarchy. Where a declaration sits is where it lives.

A universe can be split across as many .prose files as it needs. Every file joins the same world, so no file repeats its name.

Older prose named the parent with an in clause.

concept Well in ClockworkVillage { }

That still compiles, with a warning, and will be removed in the next minor release. Drop the in clause, or nest the declaration inside the concept it belongs to.


Describe

describe {
  A small wooden structure where chickens sleep at night.
}

Everything can be described.

Descriptions are the meaning of the world.


Concept

concept Chicken { }

A concept names something that exists.

Concepts can be nested.

concept Well {
  concept Rope { }
}

Dimension

dimension timeOfDay { }

timeOfDay Evening { }
timeOfDay Night   { }

A dimension groups related concepts.

Dimensions are lowercase. Concepts are named.

The word in front of a concept names its dimension. That dimension must already be declared, either in the same scope or in one that encloses it.

dimension food  { }
dimension place { }

food Berry { }

place Bakery {
  food Bread { }
}

Berry and Bread are both in ClockworkVillage.food. Where a concept sits does not change which dimension it belongs to.

Use concept when an idea has no dimension yet.

A dimension name cannot be declared again inside its own scope chain. Two separate branches may each have a cleanliness, but a nested one would quietly change what the word means for everything below it.


Relationship

relationship follows and isFollowedBy { }

A relationship can be used to describe how things connect.


Relationships

relationships {
  occursAt   { Well }
  occursWith { Fox }
}

Relationships describe how something connects to others.

You only need to declare one side. The other is always available.

A target may be a concept or a dimension. Naming a dimension is one fact about that kind, not about every concept that belongs to it. isAssociatedWith { vendor } and isAssociatedWith { Vendor1 } are different sentences.

A dimension may also declare instance edges in its own relationships { } block.


Scope

When you point at something, a name beside you is enough.

This works:

concept ChickenCoop {
  concept NestingBox { }

  concept FoxVisit {
    relationships {
      canOccurWhere { NestingBox }
    }
  }
}

NestingBox is right there.

To point at something further away, start from a name you are already inside.

This works:

concept ChickenCoop {
  concept NestingBox {
    relationships {
      canOccurWhere { ChickenCoop.Perch }
    }
  }

  concept Perch { }
}

This does not:

concept ChickenCoop {
  concept NestingBox {
    relationships {
      canOccurWhere { Perch }
    }
  }

  concept Perch { }
}

Perch is not inside NestingBox.

Do not give a concept and a dimension the same name in the same place. A path would not know which you meant.

This does not:

dimension vendor { }

concept vendor { }

The word for a connection is a name too. Say it once.

This works:

dimension timeOfDay {
  relationship follows and isFollowedBy { }
}

timeOfDay Morning {
  relationships {
    follows { Afternoon }
  }
}

Morning is a timeOfDay, so follows is already there. You can put follows on the universe instead, for everyone. The opening ChickenRaid does that with canOccurDuring.

This does not:

relationship follows and isFollowedBy { }

dimension timeOfDay {
  relationship follows and isFollowedBy { }
}

Two declarations would be two different follows. Keep one.

Two kinds may each have their own follows. That is fine. They are not hiding each other.

This works:

dimension timeOfDay {
  relationship follows and isFollowedBy { }
}

dimension season {
  relationship follows and isFollowedBy { }
}

Relates

A relates block is a pairing. It can carry its own description, and it can use a relationship you already named. Either side may be a concept or a dimension.

relates Morning and Afternoon {
  relationships {
    follows { Afternoon }
  }
}

follows is the one on timeOfDay. You do not name it again here.


What prose is

Prose is a field guide.

It describes a world. It does not run it.


Continue

  • Read sprig to see how systems participate
  • Read docs to see the documentation home

Prose describes a world. Sprig shows how systems respond to it.