---
title: Expressions
description: Expressions
---

Expressions are a powerful way to declare relationships and connections in your
user interface. They´re typically used to combine basic arithmetic with access
to properties of other elements. When these properties change, the expression
is automatically re-evaluated and a new value is assigned to the property the
expression is associated with:

```slint
export component Example {
    // declare a property of type int
    in-out property<int> my-property;

    // This accesses the property
    width: root.my-property * 20px;

}
```

When `my-property` changes, the width changes automatically, too.

Arithmetic in expression with numbers works like in most programming languages with the operators `*`, `+`, `-`, `/`:

```slint
export component Example {
    in-out property <int> p: 1 * 2 + 3 * 4; // same as (1 * 2) + (3 * 4)
}
```

Concatenate strings with `+`.

The operators `&&` and `||` express logical _and_ and _or_ between
boolean values. The operators `==`, `!=`, `>`, `<`, `>=` and `<=` compare
values of the same type.

Access an element's properties by using its name, followed by a
`.` and the property name:

```slint
export component Example {
    foo := Rectangle {
        x: 42px;
    }
    x: foo.x;
}
```

The ternary operator `... ? ... : ...` is also supported, like in C or JavaScript:

```slint
export component Example inherits Window {
    preferred-width: 100px;
    preferred-height: 100px;

    Rectangle {
        touch := TouchArea {}
        background: touch.pressed ? #111 : #eee;
        border-width: 5px;
        border-color: !touch.enabled ? #888
            : touch.pressed ? #aaa
            : #555;
    }
}
```

## Statements

### Let statements (local variables)
The `let` keyword can be used to create local variables. Local variables are immutable and cannot be redeclared
(even in other scopes). They optionally have a type annotation.
```slint no-test
clicked => {
    let foo = "hello world"; // no type annotation, inferred type
    debug(foo); // prints "hello world"

    let bar: int = 2; // explicit type annotation
    debug(bar); // prints "2"
}
```

### Assignment

```slint no-test
clicked => { some-property = 42; }
```

### Self-assignment with `+=` `-=` `*=` `/=`

```slint no-test
clicked => { some-property += 42; }
```

### Calling a callback

```slint no-test
clicked => { root.some-callback(); }
```

### Conditional statements

```slint no-test
clicked => {
    if (condition) {
        foo = 42;
    } else if (other-condition) {
        bar = 28;
    } else {
        foo = 4;
    }
}
```

### Empty expression

```slint no-test
clicked => { }
// or
clicked => { ; }
```

