# Concepts

Mélodium language is organized between four main concepts: treatments, models, connections, and tracks.

## Treatments

Treatments are the main element of the language, they can take parameters. Unlike functions, which list instructions to execute and apply changes on variables, treatments describes flows of operations that applies on data. A sequence of treatments can be seen as a map, on which paths connects from sources to destinations, browsing through different locations with different purposes. Order of declaration has no importance, treatments will run when there are data ready to be processed, and all treatments can be considered as running simultaneously.

Within sequences are treatments, which are basically other sequences or core treatments that will take parameters, inputs, and provide outputs to the hosting sequence. Treatments are declared once within a sequence, and then can be connected as many times as needed.

sequence MySequence(var foo: u64, var bar: f64)
{
TreatmentA(alpha=foo)
TreatmentB(beta=bar, gamma=0.01)

TreatmentA.output --> TreatmentB.input
}


## Models

Models are elements that live through the whole execution of a program. Can be declared and configured, and then instancied in a sequence declaration.

use std/audio/host::AudioOutput

model HostAudioOutput() : AudioOutput
{
early_end = false
}


Reference for AudioOutput

Models are instancied by sequences in their prelude.

sequence PlayAudio(const early_end: bool)
model audioOut: AudioOutput(early_end=early_end)
input signal: Stream<f32>
{
SendAudio[output=audioOut]()

Self.signal -> SendAudio.signal
}


Reference for SendAudio

In most cases, models are instancied internally by sequences and not exposed, user developer can make direct call on model-dependent sequences without instancing its own, just giving required parameters to the sequence. The cases where user may give its own defined model is to configure elements such as external software connections or interfaces.

## Connections

Connections are basically paths data will follow. Connection can connect treatments outputs to inputs, but also refers to the inputs and outputs of the hosting sequence itself. A connection always links an output and an input of the same type.

sequence Demonstration()
input  floating_point_value: Stream<f32>
output positive_increased_value: Stream<u64>
output integer_value: Stream<i64>
{
ToU64()
ToI64()

Self.floating_point_value -> ToU64.value,value -> StaticAdd.value,value -> Self.positive_increased_value
Self.floating_point_value -> ToI64.value,value --------------------------> Self.integer_value
}


Inputs and outputs (and so connections) are either streaming or blocking. A streaming connection Stream<…> is expected to send continuously values from the specified type. A blocking connection Block<…> is expected to send all-at-once. This distinction mainly rely on the core treatments that are used and the intrinsic logic applied on data. What developer should keep in mind is that streaming is the default unless blocking is required.
A specific kind of connection using the data type void exists. It is useful for transmitting information that something happens or should be triggered, schedule events, Block<void>; or to indicate continuation of something that doesn't convey data by itself, Stream<void>.