Files
markitect-quarkdown/wiki/QuarkdownFunctionLanguage.md

4.6 KiB
Raw Blame History

This is one of Quarkdowns most interesting ideas. It is not just “Markdown plus directives”; it is closer to a small document programming language embedded in Markdown.

Core Idea

In Quarkdown, function calls are the central extension mechanism. They use a dot-prefixed syntax:

.sum {26} {16}

Arguments can be positional or named:

.multiply {6} by:{3}

They can be inline, block-level, nested, chained, or given an indented body argument. Quarkdown explicitly presents functions as its key feature and groups them across layout, utility views, math/logical operations, control flow, file data, and document metadata. Source: Quarkdown function-call syntax.

What Makes It Rich

  1. Functions produce document content, not just scalar values

A function may return text, Markdown content, layout structures, booleans, numbers, tables, etc. This is crucial: document generation and computation live in the same language.

.if {.isadult age:{20}}
    You're an adult!

User-defined functions are declared with .function, and their body is a lambda-like block:

.function {greet}
    to from:
    **Hello, .to** from .from!

Source: Declaring functions.

  1. Block arguments make functions feel Markdown-native

Instead of forcing everything into parenthesized expressions, Quarkdown lets the final argument be an indented block:

.box {Example}
    This is the content of the example.

That is a very elegant move. It keeps prose readable while making structured composition possible.

  1. Chaining gives it pipeline ergonomics

This:

.pow {3} {2}::subtract {1}::sum {2}

is transformed conceptually into nested calls where each result becomes the first argument of the next call. That gives Quarkdown a pleasant Unix-pipe / method-chain feel without turning the surface language into JavaScript. Source: Chaining calls.

  1. Variables are functions too

Variables are defined with .var, then accessed like zero-argument functions:

.var {name} {Quarkdown}

Hello, .name!

They can hold simple values or block/layout content. There is also .let for scoped temporary variables. Sources: Variables and Let.

  1. It has real control flow

Quarkdown has conditional functions like .if and .ifnot, plus loops like .foreach and .repeat:

.foreach {1..3}
    n:
    The number is **.n**

The loop returns an iterable of evaluated results, so it behaves more like map than a pure side-effect loop. Source: Loops.

  1. It has higher-order behavior

Lambdas show up in custom functions, let, foreach, sorting, filtering, and table operations. Inline lambdas can be passed as arguments, for example in table filtering:

.tablefilter {2} {@lambda x: .x::isgreater {20}}
    ...

Source: Table manipulation.

  1. It includes typed-ish document values

The docs list value types such as string, number, Markdown content, boolean, none, iterable, dictionary, range, lambda, size, color, and dynamic values. It is weak/dynamic enough to remain author-friendly, but structured enough to support meaningful diagnostics and reusable functions.

Why This Matters For Markitect

For Markitect, the lesson is not necessarily “copy Quarkdown syntax.” The deeper lesson is this:

Quarkdown treats document operations as composable functions with Markdown-native block bodies.

That maps beautifully to our direction:

  • Markitect contracts could define allowed/expected processors as named document functions.
  • Our fenced-block processors could grow into a function registry with capability metadata.
  • Our dataflow pipelines could benefit from function chaining semantics.
  • Our template/generation layer could distinguish pure deterministic functions, context-bound functions, LLM-backed functions, and unsafe external functions.
  • Our diagnostics could be stronger than Quarkdowns if every function call has provenance, declared inputs, permissions, and expected output type.

My take: Quarkdowns function language is a very good inspiration for a future Markitect “document function layer,” especially if we keep it optional, markdown-close, typed enough for contracts, and integrated with our provenance/cache/access-control fabric.