DEV Community

Cover image for JSON That Thinks: A Programming Language Inside JSON
Osama Alghanmi
Osama Alghanmi

Posted on

JSON That Thinks: A Programming Language Inside JSON

What if JSON wasn't just a data format?

What if it was a programming language?

We built a Turing-complete language that is a strict subset of JSON.
No new syntax. No custom parser. Every program is valid JSON.

This is Almadar.


The Core Idea

In 1958, John McCarthy introduced S-expressions in Lisp:

(+ 1 2)
(if (> x 10) "big" "small")
Enter fullscreen mode Exit fullscreen mode

S-expressions are nested lists where the first element is the operator.

JSON arrays are nested lists.

["+", 1, 2]
["if", [">", "x", 10], "big", "small"]
Enter fullscreen mode Exit fullscreen mode

That's it.

S-expressions already fit perfectly inside JSON arrays.
Instead of inventing new syntax, we interpret what JSON already expresses.


What an Almadar Program Looks Like

An Almadar program is composed of Orbitals — the basic building blocks of the system.

Each Orbital encapsulates three core elements:

  • Entity — the data model
  • Trait — the behavior
  • Page — the UI

Entity — The Data Model

The Entity defines the structure of data.
It declares fields, types, and constraints.

It is:

  • The schema
  • The memory
  • The state container

It holds the data the system operates on.


Trait — The Behavior

A Trait defines behavior.

Technically, a Trait is a reusable state machine linked to an Entity.

It contains:

  • States
  • Transitions
  • Guards (conditions written as S-expressions)
  • Effects (actions like set, emit, etc.)

Traits encapsulate logic and can be reused across orbitals.
They are the computational core of the system.


Page — The UI

A Page defines the user interface.

It describes:

  • Layout
  • Components
  • Bindings to entity fields
  • Event triggers

Pages react to entity state and dispatch events that drive Traits.


Example

{
  "name": "ApprovalWorkflow",
  "orbitals": [{
    "entity": {
      "name": "Request",
      "fields": [
        { "name": "amount", "type": "number" },
        { "name": "status", "type": "enum", "values": ["pending", "approved", "rejected"] }
      ]
    },
    "traits": [{
      "name": "ApprovalTrait",
      "linkedEntity": "Request",
      "stateMachine": {
        "states": [
          { "name": "Pending", "isInitial": true },
          { "name": "Approved" },
          { "name": "Rejected" }
        ],
        "transitions": [{
          "from": "Pending",
          "to": "Approved",
          "event": "APPROVE",
          "guard": ["and",
            [">=", "@user.roleLevel", 3],
            ["<", "@entity.amount", 10000]
          ],
          "effects": [
            ["set", "@entity.status", "approved"],
            ["emit", "REQUEST_APPROVED"]
          ]
        }]
      }
    }]
  }]
}
Enter fullscreen mode Exit fullscreen mode

Structure is JSON.
Logic is JSON arrays.
Execution is deterministic and recursive.


What Is a Guard?

A guard is a conditional expression that determines whether a state transition is allowed to execute.

A transition only fires if its guard evaluates to true.
If the guard evaluates to false, the transition is blocked.

Guards are pure expressions — they have no side effects.


Guard Example

{
  "from": "Pending",
  "to": "Approved",
  "event": "APPROVE",
  "guard": ["and",
    [">=", "@user.roleLevel", 3],
    ["<", "@entity.amount", 10000]
  ],
  "effects": [
    ["set", "@entity.status", "approved"]
  ]
}
Enter fullscreen mode Exit fullscreen mode

This transition runs only if:

  • The user's role level is at least 3
  • The request amount is less than 10,000

If either condition fails, the transition does nothing.


Guard Evaluation

Guards are evaluated recursively:

["and",
  [">=", "@user.roleLevel", 3],
  ["<", "@entity.amount", 10000]
]
Enter fullscreen mode Exit fullscreen mode

Evaluation steps:

  1. Resolve bindings (@user.roleLevel, @entity.amount)
  2. Evaluate inner expressions
  3. Evaluate the outer operator

The result must be a boolean.

Guards can use:

  • Logical operators: and, or, not
  • Comparisons: =, !=, <, >, <=, >=
  • Arithmetic
  • Nested expressions
  • References to @entity, @user, or @payload

Conceptually, a guard is the equivalent of an if condition for a transition.


Why This Is a Programming Language

Almadar is Turing-complete because it provides:

  • Mutable state (entity fields)
  • Deterministic state machines
  • Conditional logic
  • Effects (set, emit)
  • Self-transitions (loops)
  • Event-driven communication

A self-transition with a guard and state updates is equivalent to a while loop:

{
  "from": "Computing",
  "to": "Computing",
  "event": "TICK",
  "guard": [">", "@entity.counter", 0],
  "effects": [
    ["set", "@entity.counter", ["-", "@entity.counter", 1]],
    ["emit", "TICK"]
  ]
}
Enter fullscreen mode Exit fullscreen mode

State = memory.
Transitions = control flow.
Expressions = computation.

That's a complete computational model.


The Proposal

Almadar proposes a simple shift:

  • Keep JSON.
  • Interpret arrays as S-expressions.
  • Combine them with state machines for control flow.
  • Treat structured data and executable logic as one system.

No new grammar.
No new syntax rules.
Just structured computation inside the world's most universal data format.

JSON already won.

Now it can think.

Top comments (0)