Trainerflow Docs trainerflow.com
The language › Feedback

The language

Feedback

What an exec call gives back once the athlete is done, and how to read both what they did and what they were asked to do.

Feedback values are special in Coach because you cannot write one yourself. A feedback value is what a call to an exec returns: it holds the measurements the athlete reported together with the specification they were given. Feedback is what turns a fixed plan into a program that listens, so this page is worth reading carefully.

Getting feedback

To use the feedback of an exec, store the result of the call under a name:

action Squat [title: "Back squat"]
output:number reps []
input:number reps []
output:|kg| weight []

exec squat(w) {
    specify:Squat reps 5, weight w
    measure reps
}

let fdb = squat(80|kg|)

When the program reaches squat(80|kg|) it halts. The athlete sees 5 reps of back squat at 80 kg, does the set, enters how many reps they actually managed and continues. Only then does the call return, and fdb holds what happened.

Measured inputs

The inputs the exec asked the athlete to measure are read with the usual dot notation:

action Squat [title: "Back squat"]
output:number reps []
input:number reps []
output:|kg| weight []
input:|kg| weight []

exec squat(w) {
    specify:Squat reps 5, weight w
    measure reps, weight
}

let fdb = squat(80|kg|)
let done = fdb.reps      // e.g. 4
let lifted = fdb.weight  // e.g. 80|kg|

An input the exec did not measure reads as nil, and so does an optional input the athlete left blank.

Specified outputs

The feedback also remembers what the athlete was asked to do. To read it, put the spec operator & in front of the feedback, followed by the action and the output:

action Squat [title: "Back squat"]
output:number reps []
input:number reps []
output:|kg| weight []

exec squat(w) {
    specify:Squat reps 5, weight w
    measure reps
}

let fdb = squat(80|kg|)
let asked = &fdb.Squat.reps   // 5
let missed = &fdb.Squat.reps - fdb.reps

When a specify leaves out the action, there is no action to go through either, and the output is read straight from the feedback:

output:number reps []
input:number reps []

exec max_pushups() {
    specify reps 20
    measure reps
}

let fdb = max_pushups()
let asked = &fdb.reps   // 20

You can use this information however you like. One way is to see whether the athlete fell short of what they were asked to do:

action Squat [title: "Back squat"]
output:number reps []
input:number reps []
output:|kg| weight []

exec squat(w) {
    specify:Squat reps 5, weight w
    measure reps
}

let fdb = squat(80|kg|)
let failed = fdb.reps < &fdb.Squat.reps

Putting it to work

Generally, feedback values are very important whenever a program has to make decisions based on what the athlete did. They are the backbone of automatic, intelligent athletic programming! Here is a squat that only gets heavier when the athlete makes all their reps:

import "coach/common/rest.cl"

action Squat [title: "Back squat"]
output:number reps []
input:number reps []
output:|kg| weight []

exec squat(w) {
    specify:Squat reps 5, weight w
    measure reps
}

let load = 80|kg|

repeat 12 {
    let fdb = squat(load)
    if (fdb.reps >= &fdb.Squat.reps) {
        load = load + 2.5|kg|
    }
    rest(2|day|)
}

Feedback from the standard library

The exercises of the standard library return feedback too, and the measured inputs read exactly the same way:

import "coach/strength/squat.cl"

let s = squat([weight: 100|kg|, reps: 5], [reps: true], [location: true])
let made_it = s.reps >= 5

Each exercise specifies against an action of its own, named after the exercise, which is why &s.Squat.reps gives back the 5 above. The simplest habit, though, is to keep what you prescribe in a variable and compare against that, as the Starting Strength example does.

What does not return feedback

Only execs produce feedback. Calling a group runs everything inside it, but the call itself gives back nothing worth reading. To act on how a session went, collect what you need from the exec calls inside the group, for example in a variable declared outside it.

Ask is different again: it does not return feedback but the measured value itself, so ask body_weight is simply a weight.