On this page:
7.11.1 What is an effect?
7.11.2 Rolling your own effects
7.11.3 The effect primitivity restriction
7.11.4 Rolling your own effect combinators

7.11 Getting into deep waters

The other sections under About effects and transitions describe how to use primitive effects and combine them to create complex compositions. This section is about how the effect combinators work. We’ll be stepping into the rabbit hole.

TODO: ShowTime needs more documentation.

To gain a full understanding of the innards of the effect combinators, you need to understand some basics of ShowTime and Shows.

7.11.1 What is an effect?

An effect may be defined as an operator that works on a given set of input Shows over a time interval to produce a modified Show. In conventional editing literature, the term effect is usually used to refer to one-input effects and the term transition is used for two-input effects. For the purpose of this section, we’ll simply use the term effect to mean either kind .. and in fact include more kinds such as the zero-input effect which we otherwise refer to using the term layer.

We need to distinguish between effect specifications and effects in this section for it to make any sense.

Effects are instances of effect specifications. i.e. an effect specification when applied to a set of inputs over a specific time interval yields an effect as a Show.

We directly express the nature of effect specifications as muSE functions that have a specific signature -
(fn (start stop inputs)
    ; Something that produces a Show.
    ....)

All the primitive forms such as (effect ....) and (layers ....) evaluate to effect specifications expressed as functions with the above signature. Having gone through the Primitive effects section, you might recall that a typical primitive effect specification involves an input pattern, for example -
(effect "Translate" (A) ; <- '(A)' is the input pattern.
        ....)
The input pattern is directly used in the function that is generated by such an expression, like so -
(fn (start stop (A))
    ....)

Therefore, the symbols start, stop and A are automatically made available in the body of the effect specification to compute any aspect of the effect.

7.11.2 Rolling your own effects

As of this writing, you cannot create your own primitive effects. However, you can write any function that has the above signature and evaluates to a Show and use it as an effect (almost) anywhere an effect is accepted.

For example, here is a “blank” effect that behaves as though it does nothing on its input -
(define blank (fn (start stop (A))
                  A))
Since A is a Show, blank indeed satisfies the effect signature requirement and might be composed with other effects, say in an effect-stack.

7.11.3 The effect primitivity restriction

The effect primitivity restriction might be removed in the future.

There is only one restriction to keep in mind. When it comes to using an effect at the top level of a

(define muvee-segment-effect ....)

or a

(define muvee-global-effect ....)

The effect must be a primitive effect. Though this seems to be an unacceptable restriction, it is easily satisfied by wrapping your custom effect in a (layers ....) form.

7.11.4 Rolling your own effect combinators

Effect combinators are nothing but functions that create functions with the signature that is expected of an effect. For example, here is an effect combinator that applies effect a for the first half of its interval and b for the second half.
(define (two-part-effect a b)
  (fn (start stop (A))
      (let ((mid-point (math (start + stop) / 2)))
        (b mid-point stop (list (a start mid-point (list A)))))))

We’ll leave the analysis of how that works as an exercise. A hint is to remember that a and b are one-input effect specifications and to go back to the definition of an effect specification above to understand what you get when you apply them to specific time intervals and inputs.

You need to be aware of the The effect primitivity restriction when designing your own effect combinators.