Skip to main content

Writing Transforms

This guide walks through writing a transform between two message types. For background on what a transform is and when to use one, see What Are Transforms?.

Imagine you have a software component that provides a temperature value in Celsius, but another software component in your system accepts Fahrenheit values as input. Here are the Flex specifications for these two messages:

message struct Celsius {
  temp: float64;
}

message struct Fahrenheit {
  temp: float64;
}

Let's define a transform from Celsius to Fahrenheit so that our two components know how to talk to each other:

transform Celsius2Fahrenheit(c: Celsius) -> Fahrenheit =
  Fahrenheit {
    temp = c.temp * 9.0 / 5.0 + 32.0;
  };

A transform starts with the transform keyword followed by the transform name (Celsius2Fahrenheit), parameter list (c: Celsius), return type (Fahrenheit), and the transform body after the = sign.

The transform body is an expression that describes the calculation of the output from the input. Expressions are described in more detail on the Expressions page. The body of Celsius2Fahrenheit contains expressions to access a field in the input struct (c.temp), perform some arithmetic (c.temp * 9.0 / 5.0 + 32.0), and build a Fahrenheit value (Fahrenheit { temp = ...; }). Other expression forms incude conditional evaluation, constructing and indexing arrays, calling other transforms, and more.

The body is placed after an = sign in the transform definition to emphasize the connection between Flex and functional programming languages. However, if the body is a block expression, then the = sign can be omitted to make the transform look more like a function in C++ or Java. Here is Celsius2Fahrenheit written without the = sign:

transform Celsius2Fahrenheit(c: Celsius) -> Fahrenheit {
  Fahrenheit {
    temp = c.temp * 9.0 / 5.0 + 32.0;
  };
}

When a transform needs information that is not present in the input message, use contextual parameters — see Contextual Parameters in the reference.