# APL Data-Binding Syntax

**Note:**This public beta release of Alexa Presentation Language (APL) includes the APL documentation, authoring tool, and APL beta forums. Please note that we may improve or change APL as we receive feedback and iterate on the feature.

APL data binding expressions occur inside JSON strings and take the form "`${expression}`

". Any number of expressions may occur inside a string, such as `"${2}+${2} = ${2+2}"`

. Expressions are evaluated within the current data-binding context. The data-binding context is a global dictionary that supports booleans, numbers, strings, arrays, objects, null, and references to defined resources.

- Supported value types
- Truthy and Coercion
- Operators
- Array and Object access
- Function calls
- Data-binding string conversion

## Supported value types

### Identifier

An identifier is a name used to identify a data-binding variable.
Identifiers must follow the C identifier naming convention:
`[a-zA-Z_][a-zA-Z0-9_]*`

. That is, the identifier must start with an
upper or lower-case ASCII letter or underscore and may be followed by
zero or more ASCII letters, numbers, or the underscore:

```
${data}
${_myWord23}
${__AnUgly26_letter__examplE}
```

### String literals

Strings are defined using either single or double quotes. The starting and ending quote must match. Quotes, carriage returns, and line-feeds may be escaped.

```
${"Double-quoted string"}
${'Single-quoted string'}
${"Inner quote: \" or '"}
```

Expressions may be nested inside of a string.

```
${"Two plus two is ${2+2}"}
```

### Numbers

Positive, negative, and floating point numbers are supported. Scientific notation is not supported. In JavaScript, all numbers are doubles.

### Booleans

Boolean values of `true`

and `false`

are supported.

```
${true}
${false}
```

### null

The `null`

constant is supported.

```
${null}
```

### Resources

Resources defined in the data-binding context use the reserved character "@". For example:

```
${@myBlue}
${@isLandscape ? @myWideValue : @myNarrowValue}
```

APL packages define resources exposed in data-binding.

## Truthy and Coercion

Data-binding expressions involve a number of different types. These types may be converted into other types. The following table gives an example of the different conversions (note that this assumes a screen width of 512dp and a dpi of 320):

Object | Example | As Boolean | As Number | As String | As Color | As Dimension |
---|---|---|---|---|---|---|

Null | null | false | 0 | "" | transparent | 0dp |

Boolean | true | true | 1 | "true" | transparent | 0dp |

Boolean | false | false | 0 | "false" | transparent | 0dp |

Number | 23 | true | 23 | "23" | #00000017 | 23dp |

Number | 0 | false | 0 | "0" | transparent | 0dp |

String | "My dog" | true | 0 | "My dog" | transparent | 0dp |

String | "" | false | 0 | "" | transparent | 0dp |

String | "-2.3" | true | -2.3 | "-2.3" | transparent | -2.3dp |

String | "red" | true | 0 | "red" | #ff0000ff | 0dp |

String | "50vw" | true | 50 | "50vw" | transparent | 256dp |

Array | [] | true | 0 | "" | transparent | 0dp |

Map | {} | true | 0 | "" | transparent | 0dp |

Color | red | true | 0 | "#ff0000ff" | #ff0000ff | 0dp |

Dimension | 32px | true | 16 | "16dp" | transparent | 16dp |

Dimension | 0vh | false | 0 | "0dp" | transparent | 0dp |

Dimension | 23% | true | 0.23 | "23%" | transparent | 23% |

Dimension | 0% | false | 0 | "0%" | transparent | 0% |

Dimension | auto | true | 0 | "auto" | transparent | auto |

Anything else | ... | true | 0 | "" | transparent | 0dp |

### Boolean coercion

A **truthy** value is a value that is considered `true`

when evaluated in a boolean context. All values are truthy except for `false`

, `0`

, `""`

, a zero
absolute or relative dimension, and `null`

.

### Number coercion

The Boolean "true" value is converted to the number 1. String values
are converted using the C++ `std::stod`

method (note that this is
influenced by the locale). Absolute dimensions convert to the number of
dp in the absolute dimension; relative dimensions convert to the
percentage value (e.g., 32% -> 0.32). Everything else converts to 0.

### String coercion

Internal types are converted to strings using the rules in the following table:

Object | Example | Result | Description |
---|---|---|---|

Null | null | `''` |
The null value is not displayed. |

Boolean | true false | `'true'` `'false'` |
Boolean true & false are displayed as strings. |

Number | -23 | `'-23'` |
Integers have no decimal places. |

1/3 | `'0.333333'` |
Non-integers have decimal places. | |

String | "My "dog" " | `'My "dog" '` |
String values |

Array | [...] | `''` |
Arrays are not displayed. |

Map | {...} | `''` |
Maps are not displayed |

Color | red | `'#ff0000ff'` |
Colors are shown in #rrggbbaa format. |

Dimension | 23 dp | `'20dp'` |
Absolute dimensions are shown with the suffix 'dp' |

Dimension | 20 % | `'20%'` |
Percentage dimensions are shown with the suffix '%' |

Dimension | auto | `'auto'` |
The auto dimension is shown as 'auto' |

Anything else | `${Math.min}` |
`''` |
Math functions are not shown. |

The specific format of non-integer numbers is not defined, but should
follow closely the C++ standard for `sprintf(buf, "%f", value)`

. It may
change based on the locale.

### Color coercion

Color values are stored internally as 32-bit RGBA values. Numeric values will are treated as unsigned 32-bit integers and converted directly. String values are parsed according to the rules in Data Types - Color.

### Absolute dimension coercion

Numeric values are assumed to be measurements in "dp" and are converted to absolute dimensions. String values are parsed according to the rules in Data Types - Dimension. All other values are 0.

### Relative dimension coercion

Numeric values are assumed to be percentages and are converted directly. For example, 0.5 converts to 50%. Strings are parsed according to the rules in Data Types - Dimension. All other values are 0.

## Operators

APL supports different types of operators: arithmetic, logical, comparison, and ternary.

### Arithmetic operators

The standard arithmetic operations for addition, subtraction, multiplication, division, and remainder are supported:

```
${1+2} // 3
${1-2} // -1
${1*2} // 2
${1/2} // 0.5
${1%2} // 1.
```

Addition and subtraction work for pairs of numbers, absolute dimensions, and relative dimensions. When a number is combined with either an absolute or relative dimension, the number is coerced into the appropriate dimension.

The addition operator also acts as a string-concatenation operator if either the left or right operand is a string.

```
${27+""} // '27'
${1+" dog"} // '1 dog'
${"have "+3} // 'have 3'
```

Multiplication, division, and the remainder operator work for pairs of numbers. Multiplication also works if the one of the operands is a dimension (either relative or absolute) and the other is a number; the result is a dimension. Division also works if the first operand is a dimension (either relative or absolute) and the second is a number; the result is a dimension.

The remainder operator behaves as in JavaScript. That is,

```
${10 % 3} // 1
${-1 % 2} // -1
${3 % -6} // 3
${6.5 % 2} // 0.5
```

### Logical operators

The standard logical and/or/not operators are supported.

```
${true || false} // true
${true && false} // false
${!true} // false
```

The `&&`

returns the first operand if it is not truthy and the second otherwise. The `||`

operator returns the first operand if it is truthy and the second otherwise.

```
${7 && 2} // 2
${null && 3} // null
${7 || 2} // 7
${0 || -16} // -16
```

### Comparison Operators

Comparison operators return boolean values.

```
${1 < 2}
${75 <= 100}
${3 > -1}
${4 >= 4}
${myNullValue == null}
${(2>1) == true}
${1 != 2}
```

The comparison operators do not apply to arrays and objects.

### Null coalescing

The `??`

operator is the null-coalescing operator. It returns the
left-hand operand if the operand is not null; otherwise it returns the
right-hand operand. The null-coalescing operator may be chained:

```
${person.name ?? person.surname ?? 'Hey, you!'}
```

The null-coalescing operator will return the left-hand operand if it is anything but null:

```
${1==2 ?? 'Dog'} // returns false
${1==2 || 'Dog'} // returns 'Dog'
```

### Ternary Operator

The ternary conditional operator `${a ? b : c}`

evaluates the left-hand operand. If it evaluates to true or a truthy value, the middle operand is returned. Otherwise the right-hand operand is returned.

```
${person.rank > 8 ? 'General' : 'Private'}
```

## Array and Object access

### Array

Array access uses the `[]`

operator, where the operand should be an integer. Arrays also support the `.length`

operator to return the length of the array. Accessing an element outside of the array bounds returns `null`

.

```
${myArray[4]} // 5th element in the array (0-indexed)
${myArray.length} // Length of the array
${myArray[-1])} // Last element in the array
${myArray[myArray.length]} // Returns null (out of bounds)
```

Passing a negative index counts backwards through the array.

```
${a[-1] == a[a.length - 1]} // True
```

### Object

Objects support the `.`

operator and the `[]`

array access operator with string values.

```
${myObject.name} // The 'name' property of myObject
${myObject['name']} // The 'name' property of myObject
```

If the property is not defined, `null`

is returned.

Calling the `.`

or `[]`

operator on `null`

returns `null`

.

```
${myNullObject.address.zipcode} // Returns null
```

The right-side operand of the dot operator must be a valid identifier.

## Function calls

Data-binding supports a limited number of built-in functions. Functions are of the form:

```
functionName( arg1, arg2, … )
```

Functions do not have to have arguments. A function returns a single value. Some functional expressions are shown here:

```
${Math.floor(1.1)} // 1
${Math.ceil(1.2)} // 2
${Math.round(1.2)} // 1
${Math.min(1,2,3,4)} // 1
${Math.max(1,2,3,4)} // 4
${String.toUpperCase('Hello')} // HELLO
${String.toLowerCase('Hello')} // hello
${String.slice('Hello', 1, -1)} // ell
```

### Built-in functions

Some mathematical and string functions are built in to APL.

Property | Description | Example |

Math.abs(x) | Return the absolute value of x | ${Math.abs(-2.3)} == 2.3 |

Math.acos(x) | The arccosine of x | ${Math.acos(1)} == 0 |

Math.asin(x) | The arcsine of x | ${Math.asin(0)} == 0 |

Math.atan(x) | The arctangent of x | ${Math.atan(1)} == 0.7853981633974483 |

Math.ceil(x) | Return the smallest integer greater than or equal to x. | ${Math.ceil(2.3)} == 3 |

Math.clamp(x,y,z) | Return x if y<x, z if y>z, and otherwise y. | ${Math.clamp(1, 22.3, 10)} == 10 |

Math.cos(x) | The cosine of x | ${Math.cos(0)} == 1 |

Math.floor(x) | Return the largest integer less than or equal to x. | ${Math.floor(2.3)} = 2 |

Math.max(x1,x2,…) | Return the largest argument | ${Math.max(2,3)} == 3 |

Math.min(x1,x2,…) | Return the smallest argument | ${Math.min(2,3)} == 2 |

Math.PI | The value of PI | 3.141592653589793 |

Math.random() | A random number between 0 and 1 | ${Math.random()} == 0.7113654073137101 (the actual random number returned will be different) |

Math.round(x) | Return the nearest integer to x | ${Math.round(2.3)} == 2 |

Math.sign(x) | The sign of x: -1, 0, or 1 | ${Math.sign(-43.1) == -1} |

Math.sin(x) | The sine of x | ${Math.sin(Math.PI/6)} == 0.5 |

Math.sqrt(x) | The square root of x | ${Math.sqrt(9)} == 3 |

Math.tan(x) | The tangent of x | ${Math.tan(Math.PI/4)} == 0.5 |

String.slice(x,y[,z]) | Return the subset of x starting at index y and extending to but not including index z. If z is omitted, the remainder of the string is returned. If y is a negative number, select from the end of the string. | ${String.slice('berry', 2, 4)} == "rr" ${String.slice('berry', -2)} == "ry" |

String.toLowerCase(x) | Return a lower-case version of x | ${String.toLowerCase('bEn')} == "ben" |

String.toUpperCase(x) | Return an upper-case version of x. | ${String.toUpperCase('bEn')} == "BEN" |

## Data-binding string conversion

Because APL is serialized in JSON, all data-bound expressions are defined inside of a JSON string:

```
{
"MY_EXPRESSION": "${....}"
}
```

If there are no spaces between the quotation marks and the data-binding expression, then the result of the expression is the result of the data-binding evaluation. For example:

```
"${true}" -> Boolean true
"${2+4}" -> Number 6
"${0 <= 1 && 'three'}" -> String 'three'
```

When extra spaces are in the string outside of the data-binding expression or when two data-binding expressions are juxtaposed, the result is a string concatenation:

```
" ${true}" -> String ' true'
"${2+4} " -> String '6 '
"${2+1}${1+2}" -> String '33'
```