Skip to content

3. Specification structure, layers and viewpoints

Contents of DISL 0.1

3.1 Top-level object

Property Type Req. Layer Description
$schema string – – URI of the DISL JSON Schema.
disl string ✓ – Targeted DISL version, "0.1".
language Language ✓ – Identity, version, locales and limits (3.2).
imports Import[] – – Reused specifications and libraries (3.3).
functions map → Function – – Reusable CEL functions (3.4).
metamodel Metamodel ✓ 1 What can exist (section 4).
coordinates Coordinates – 2 Axes, coordinate systems, snapping (section 5). Default: one free cartesian pixel system without snapping.
notation Notation – 3 How things look (section 6). Default: every node a labelled rectangle, every relation a straight line with an arrow.
toolbox Toolbox – 4 Palette and context tools (7.1–7.4). Default: one tool per concrete type.
forms map → Form – 4 Property and embedded forms (7.5). Default: generated from attributes.
constraints Constraints – 5 Rules (section 8).
behavior Behavior – 6 Hooks, operations, deletion and clipboard policy (section 9).
layout Layout – 7 Automatic layout (section 10). Default: none.
persistence Persistence – 8 Storage (section 11). Default: single JSON file, UUIDv7 ids.
viewpoints map → Viewpoint – – Several diagram kinds over one model (3.5).
plugins map → Plugin – – Declared extensions (section 13).
doc Doc – – Documentation of the language as a whole.
x-* any – – Extensions.

Only disl, language and metamodel are required. Every other layer has a documented default, so specifications can start tiny and grow.

{
  "disl": "0.1",
  "language": { "id": "org.example.mindmap", "version": "0.1.0", "label": "Mind map" },
  "metamodel": {
    "types": { "Idea": { "attributes": { "text": { "type": "string", "required": true } } } },
    "relations": { "Branch": { "source": "Idea", "target": "Idea" } }
  }
}

This five-line language already yields a usable diagram type: a palette with an Idea tool and a Branch tool, rectangles labelled with text (the first string attribute is the default label), arrows, a generated property form, and JSON persistence.

3.2 Language

Property Type Req. Description
id qualified identifier ✓ Globally unique language id; reverse-DNS style is RECOMMENDED. Recorded in every DID definition.
version SemVer string ✓ Version of this language.
label LocalizedText – Display name ("State machine").
doc Doc – Language documentation, shown in the runtime's help view.
defaultLocale BCP 47 tag – Default "en".
locales string[] – Locales for which all LocalizedTexts SHOULD provide translations; validators MAY warn about gaps.
authors {name, email, url}[] – Maintainers (tool engineers).
license SPDX expression – License of the specification.
homepage URI – Project page.
icon IconRef – Icon of the language (file type icon, window title).
fileExtension string – Preferred extension of stored diagrams without dot, for example "sm.json".
limits object – celCost (per-expression cost limit), maxElements (soft limit, runtimes SHOULD warn beyond it), maxDocumentBytes.
requires object – conformance: minimum runtime conformance level ("core", "standard", "full"); features: list of optional feature ids (Appendix B.8) the specification relies on.

3.3 Imports

Specifications may import other specifications or libraries — specifications that contain only notation, forms, functions or data types and whose metamodel may be empty.

Property Type Req. Description
from URI or relative path ✓ Location of the imported specification.
as simple identifier ✓ Alias; imported names are referenced as alias.Name.
version SemVer range – Acceptable versions of the imported language (for example "^2.1.0").
integrity string – Subresource-integrity hash ("sha256-…"). Runtimes MUST verify it when present and SHOULD require it for remote URIs.
include string[] – Layers to import: any of "metamodel", "notation", "forms", "functions", "constraints", "toolbox". Default: all.
doc Doc – Why the import exists.

Imported types may be extended ("extends": "base.Element"), imported styles, shapes and markers referenced, and imported constraints are active unless the import lists include without "constraints". Import cycles are a specification error. Names are never merged implicitly: a local State and lib.State are different types.

The DISL standard library is always available under the reserved alias std without an import (Appendix B): std.roundedRect, std.arrowFilled, std.grid10, and so on. Built-in names MAY also be referenced without the std. prefix when no local name shadows them.

3.4 Functions

User-defined functions make repeated CEL logic reusable and documented.

{
  "functions": {
    "displayName": {
      "params": [{ "name": "e", "type": "Element" }],
      "returns": "string",
      "cel": "has(e.name) && e.name != '' ? e.name : e.type + ' ' + e.id.substring(0, 4)",
      "doc": "The human-readable name of an element, falling back to type and short id."
    },
    "workingDaysBetween": {
      "params": [{ "name": "a", "type": "timestamp" }, { "name": "b", "type": "timestamp" }],
      "returns": "int",
      "cel": "workingDays(a, b, 'project')"
    }
  }
}
Property Type Req. Description
params {name, type, doc}[] ✓ Positional parameters; type is a CEL type name or a metamodel type name.
returns string ✓ CEL result type.
cel string ✓ Body; may reference parameters, globally available variables of the calling context are not visible (functions are pure over their parameters, plus diagram and env when declared in uses).
uses string[] – Context variables the function may read: "diagram", "env".
doc Doc – Documentation.

Functions are called as displayName(self). A function MAY call functions declared before it in the specification order; recursion (direct or indirect) is a specification error. This preserves CEL's termination guarantee.

3.5 Viewpoints

A language may offer several diagram kinds over the same model — for example a structure diagram and a timeline of the same project. Each viewpoint selects which types appear, which coordinate system and layout apply, and which toolbox groups are offered. If viewpoints is absent, a single implicit viewpoint main shows everything.

Property Type Description
label, doc, icon Display name, documentation, icon.
coordinateSystem name Coordinate system of diagrams of this kind (section 5).
include TypeRef[] Types shown. Default: all.
exclude TypeRef[] Types hidden.
toolbox string[] Toolbox group ids offered. Default: all groups.
layout name or LayoutConfig Layout used (section 10).
notation object Per-viewpoint notation overrides: nodes, edges, styles maps merged over the global notation.
canvas Canvas Background, bounds and page settings (6.13).
default boolean The viewpoint used for new diagrams. Exactly one viewpoint SHOULD be default.

Elements appear in a view only if their type is included; model elements not shown in any view still exist in the model and are still validated.

3.6 Layer overview (informative)

Layer overview. The eight DISL layers from top to bottom. Layer 1, metamodel, says what exists. Layer 2, coordinates, where it can be. Layer 3, notation, how it looks. Layer 4, toolbox and forms, how it is created and edited. Layer 5, constraints, what is allowed. Layer 6, behavior, what happens. Layer 7, layout, how it is arranged. Layer 8, persistence, how it is stored. Cutting across all layers are doc on everything, CEL everywhere, functions, plugins and viewpoints.
Diagram as text (Mermaid)
---
config:
  flowchart:
    wrappingWidth: 400
    rankSpacing: 12
---
flowchart TB
  accTitle: Layer overview
  accDescr: The eight DISL layers from top to bottom. Layer 1, metamodel, says what exists. Layer 2, coordinates, where it can be. Layer 3, notation, how it looks. Layer 4, toolbox and forms, how it is created and edited. Layer 5, constraints, what is allowed. Layer 6, behavior, what happens. Layer 7, layout, how it is arranged. Layer 8, persistence, how it is stored. Cutting across all layers are doc on everything, CEL everywhere, functions, plugins and viewpoints.
  L1["<b>Layer 1 · metamodel</b><br/>types · relations · attributes<br/><i>what exists</i>"]
  L2["<b>Layer 2 · coordinates</b><br/>axes · systems · placement · snap<br/><i>where it can be</i>"]
  L3["<b>Layer 3 · notation</b><br/>theme · styles · shapes · markers<br/>nodes · edges · labels · ports<br/><i>how it looks</i>"]
  L4["<b>Layer 4 · toolbox · forms</b><br/><i>how it is created/edited</i>"]
  L5["<b>Layer 5 · constraints</b><br/><i>what is allowed</i>"]
  L6["<b>Layer 6 · behavior</b><br/>hooks · operations · policies<br/><i>what happens</i>"]
  L7["<b>Layer 7 · layout</b><br/><i>how it is arranged</i>"]
  L8["<b>Layer 8 · persistence</b><br/><i>how it is stored</i>"]
  X["<b>cross-cutting</b><br/>doc on everything · CEL everywhere<br/>functions · plugins · viewpoints"]
  L1 ~~~ L2 ~~~ L3 ~~~ L4 ~~~ L5 ~~~ L6 ~~~ L7 ~~~ L8 ~~~ X
  classDef crossCutting stroke-dasharray:4 4
  class X crossCutting

Dependencies only point upward: notation refers to metamodel types, constraints to metamodel and coordinates, persistence to metamodel and coordinates — never the reverse. A headless validator therefore only needs layers 1, 2, 5 and 8.

Referenced from