Confetti Examples

User Settings#

Confetti can be used to store user-specific settings.

Here’s an example with a flat structure:

username JohnDoe
language en-US
theme dark
notifications on

Application Settings#

Confetti can store application specific settings.

This example demonstrates a hierarchical structure.

application {
    version 1.2.3
    auto-update true
    log-level debug
}

display {
    resolution 1920x1080
    full-screen true
}

User Interfaces#

This example demonstrates how Confetti could be used for designing user interfaces. It takes inspiration from QML which is a document markup language developed by the Qt project for designing user interfaces with the Qt framework.

Application {
    VerticalLayout {
        Label {
            text "This application has a single button."
        }

        Button {
            text "Click Me"
            on_click """
function() {
    console.log(`You clicked a button named: ${this.text}`);
}
"""
        }
    }
}

Build Systems#

A programming language could use Confetti for its build system.

The following snippet is an example of a pseudo build script for the C programming language. Here, the arguments for each subdirective of sources are interpreted as a contiguous list of source files.

project Linux
version 6.14
target kernel {
    flags -Wall
    sources {
        init.c fork.c scheduler.c
        interrupt.c
        deadlock.c panic.c
    }
}

AI Training#

Here’s an example of what a Confetti configuration file might look like for an AI model, particularly a machine learning model such as a neural network:

model {
  type "neural_network"
  architecture {
    layers {
      layer { type input; size 784 }
      layer { type dense; units 128; activation "relu" }
      layer { type output; units 10; activation "softmax" }
    }
  }

  training {
    data "/path/to/training/data"
    epochs 20
    early_stopping on
  }
}

Workflow Automation#

The following example demonstrates what a task file might look like. It represents various tasks that you could potentially run via the command line.

build {
    description "Compile the source code"
    command "gcc -o program source.c"
}

clean {
    description "Clean the build directory"
    command "rm -rf build/"
}

test {
    description "Run unit tests"
    command "./tests/run.sh"
    depends_on { build }
}

Document Markup#

The grammar is flexible enough to create a markup language!

chapter "The Raven"
author "Edgar Allan Poe"
section "First Act" {
  paragraph {
    "Once upon a midnight dreary, while I pondered, weak and weary,"
    "Over many a quaint and " bold{"curious"} " volume of forgotten lore-"
  }
  paragraph {
    "While I nodded, nearly napping, suddenly there came a tapping,"
    "As of some one " italic{"gently"} " rapping-rapping at my chamber door."
  }
}

Here, an implementation would process paragraph directives by concatenating all subdirectives together. If it detects the last argument of a directive is bold or italic, it would understand that the subdirectives must be styled as bold or italic.

Command Formats#

You can use Confetti to create a line-based command format where context is implied by the preceding directive. This enables configuration styles where grouping is inferred, not structural — similar to formats like .obj or ffmpeg filter graphs.

Here’s what a media processing pipeline might look like:

step load-video
    input path/to/video.mp4
    format mp4

step apply-filters
    filter grayscale
    filter stabilize
    crop 1920x1080

step export
    codec h264
    bitrate 4000k
    output final.mp4

Each step begins a new logical group. The directives that follow would be interpreted as part of that step, even without braces. Note that line indentation is provided for visual clarity and is insignificant to Confetti.

Domain Specific Languages#

S-expressions are a simple and recursive way of representing both data and code. The classic parentheses with polish notation provides minimalistic syntactic structure. Confetti brings that flexibility to Unix configuration and INI files, except with C-like notation.

This section of examples demonstrates how the Confetti grammar is expressive enough to represent domain specific languages (code) in addition to plain structures (data). As you view these examples, keep in mind Confetti has no keywords or control flow — syntax highlighting is just for show.

Shell Commands#

Confetti directives can be interpreted as shell-like commands. From simple commands:

cat myfile.txt

to batching commands:

do {
  ./webserver -p 8080
  ./database --api-key 123 --data-dir /var/lib/db/
} > output.txt

This example demonstrates how you can express interesting behaviors by combining neighboring directives. In this case, when a directive starts with >, you’d associate it with the previous directive.

Stack-Based Languages#

Confetti can be used to create simple stack-based languages.

push 1
push 2
add     # Pop the top two numbers and push their sum.
pop $x  # Pop the sum and store it in $x.
print "1 + 2 ="
print $x

Subdirectives could be used if you need more complex grouping, like for function declarations. Here, we’ll assume the calling convention is to push function arguments from left-to-right on the stack, which means x and y would be at the top of the stack when the sum function is called:

func sum x y {
    add       # Pop the arguments 'x' and 'y' and push their sum.
    return 1  # One return value is left on the stack.
}

Control Flow#

The Confetti grammar is flexible enough to allow conditionals and other program logic:

# Try sending the user a message about their access level.
set $retry-count to 3
for $i in $retry-count {
    if $is_admin {
        print "Access granted"
        send_email "admin@example.com"
        exit 0 # Success!
    } else {
        sleep 1s # Let's try again after a moment.
    }
}
exit 1 # Failed to confirm admin role.

State Machine#

This example models a basic state machine for an NPC (non-player character) reacting to events in a video game.

villager {
    on player-approach {
        goto greet
    }
    state greet {
        walk-to $player
        say "Hello, traveler."
        wait 1s
        goto idle
    }
    state idle {
        wait 3s
        hum "🎵 doo-dee-doo 🎵"
        repeat
    }
}

Language Extensions#

The Confetti specification defines the core language and its annex includes optional extensions that are compatible with the grammar. This section demonstrates these extensions in action.

Annex A: Comment Syntax Extension#

This extension allows single and multi-line C-style comments in Confetti. That means you can use // for single-line comments and /* and */ for multi-line comments in addition to # comments.

# Confetti style comment.

// C-style single-line comment.

/* C-style multi-
   line comment. */

Annex B: Expression Arguments Extension#

This extension lets you write parentheses enclosed “expressions” wherever an argument is allowed.

With this extension, the first directive in the following example would be interpreted as having two arguments if and x > y. The latter is the expression argument, and it is meant to be evaluated by the user’s application.

if (x > y) {
    print "x is greater than y"
}

Without this extension, the directive would be interpreted as having four arguments: if, (x, >, and y), which is not how it reads to anyone with familiarity with C derived languages!

Annex C: Punctuator Arguments Extension#

This extension lets you take any character that is valid in an argument and treat it as a reserved punctuator. This is useful for defining your own domain-specific punctuators. For example, you might decide that the “equal sign” character is a punctuator which means the following directives would be equivalent:

x = 123
x=123

With this extension, both directives have three arguments: x, =, and 123. Without this extension, if you wanted = to be distinct from x and 123, then the white space would be required.