Source Code | Tickets | Trello | Twitter | Patreon | © Michael DeHaan, 2020

# Evaluators

## Evaluators

Evaluators are expressions that are valid for any value in a Slot. They can be used to achieve controllable per-step randomness, pull values for a Data Pools or pull notes from one track into another.

Use of evaluators allows Warp to produce expressive, highly evolving compositions full of emergent behavior, operating off a very small amount of data, and often zero custom programming. As the UI in Warp is built, evaluators will be fully exposed to the user interface, and not remain exclusively a programming feature.

## Probability#

In the example below, the 4th note has a 40% chance of being silenced:
``````
Slot(degree=1),
Slot(degree=2),
Slot(degree=3),
Slot(degree=4, rest=Probability(0.4,True,False)
])
``````
In the example below, there is a 40% chance of an octave shift:
``````
Slot(degree=1),
Slot(degree=2),
Slot(degree=3),
Slot(degree=4, octave_shift=Probability(0.4,-2,0)
])
``````

## RandomChoice#

In the example below, the note is chosen from a limited set of possible notes:
``````
Slot(degree=RandomChoice(1,2,4,7),
Slot(degree=4),
Slot(degree=5)
])
``````

## RandomRange#

In the example below, the velocity is selected within a narrow range, implementing humanization
``````
Slot(degree=1, velocity=RandomRange(80,90),
Slot(degree=2, velocity=RandomRange(80,95),
Slot(degree=3, velocity=RandomRange(85,95),
])
``````

Variables are global and can be shared between tracks. As a result, one pattern, perhaps even playing on a muted track, can influence another. Here is a trivial self-contained example:

``````
Slot(degree=1, variables=dict(a=1, b=2)),
Slot(degree=2),
])
``````

## TrackGrab#

Track Grab listens to what note is playing on another track and replaces the current note with that value. See this hocket example.

``````
Slot(track_grab='conductor')
])
``````

## DataGrab#

Somewhat like a TrackGrab, a Data Grab pulls the next value from a Data Pool. This could be a fun way to interlace one melody into another. J.S. Bach, here we come!

``````
Slot(degree=DataGrab('some_pool'),
Slot(degree=4),
Slot(degree=5),
Slot(degree=DataGrab('some_pool'),
])
``````

## Negate#

If you need to negate the value from a DataGrab you can't use the minus sign because a DataGrab is some kind of magical timey-whimey object. You need to use Negate

``````
Slot(octave_shift=1),
Slot(octave_shift=Negate(DataGrab('mcelligots_pool')),
Slot(octave_shift=1),
])
``````

This is a preview of this next thing...

## Nesting Evaluators#

Technically you can nest Evaluators at infinite level. If you need to randomly decide to use a DataGrab or a constant, for example:

``````
Slot(octave_shift=1),
Slot(octave_shift=Probability(0.5, DataGrab('the_deep_end'), 2),
Slot(octave_shift=1),
])
``````

Any parameter to any evaluator can be subject to nesting.

## Suggestions & Tips#

• Per-step controllable randomness is often more interesting than lots of randomness throughout a track
• Using DataGrab may sometimes be more interesting than randomness

## In Context#

Reading the following API examples is recommended for understanding this section:

## Next Steps#

This is already pretty far into the Warp feature set. Be sure to read about Data Pools which are used with DataGrab.