# LET...IN

**LET...IN evaluates Airscript expressions while using defined temporary values for variables within the expression.**

LET...IN is special Airscript syntax, where the input after LET temporarily defines variables, and the input after IN defines the Airscript expression that will be evaluated given that the variables have the previously-defined values. Using LET...IN makes it easy to locally test how complicated Airscript expressions might behave given various input.

#### Declaration

```javascript
LET var_1 = val_1, var_2 = val_2, ..., var_i = val_i IN airscript_expression -> result
```

#### Parameters

**var\_1** (required, type: `string`) A variable that appears in the **airscript\_expression**.

**val\_1** (required, type: `any`) The value to use in place of **var\_1** when evaluating the **airscript\_expression**.

**var\_n** (optional, type: `string`) A variable that appears in the **airscript\_expression**.

**val\_n** (optional, type: `any`) The value to use in place of **var\_n** when evaluating the **airscript\_expression**.

**airscript\_expression** (required, type: _Airscript Expression_) The Airscript expression that will be evaluated.

#### Return Values

**result** (type: `any`) The result of **airscript\_expression** after it has been evaluated using the defined values for the designated variables.

#### Examples

The following expression evaluates the Airscript expression `x + 2` when the number `3` is used in place of `x`:

```javascript
LET x = 3 IN x + 2 -> 5
```

It's possible to temporarily define multiple variables, and they don't have to be defined in the same order they appear within the Airscript expression. The following example temporarily defines `y` as `4` and `x` as `3` and then correctly evaluates `x + y`, or `3 + 4`:

```javascript
LET y = 4, x = 3 IN x + y -> 7
```

Technically, not all temporarily defined variables need to appear in the Airscript expression in order for it to evaluate properly. The following example temporarily defines `x` as `3` and `y` as `4` and then correctly evaluates `x + 1`, and Airscript expression that does not reference `y` at all:

```javascript
LET x = 3, y = 4 IN x + 1 -> 4
```

Note that while this is technically valid, it is not recommended. There is no need to take the time temporarily defining variables that the Airscript expression does not reference.

Temporarily-defined variables cannot be defined in terms of another temporarily-defined variable. For instance, if we define `x` as `6` and then `y` as `x + 10`, trying to apply this values to evaluate the Airscript expression `y + 4` will result in an error:

```javascript
LET x = 6, y = x + 10 IN y + 4 -> ERROR
```

It is, however, possible to use LET...IN inside of the Airscript expression being evaluated. Doing so makes it possible to effectively define one temporarily-defined variable in terms of another, such as in the following example, which defines `x` as `6` when evaluating an Airscript expression that defines `y` as `x + 10` and then uses that to evaluate `y + 4`:

```javascript
LET x = 6 IN LET y = x + 10 IN y + 4 -> 20
```

LET...IN expressions can reference locally-accessible variables beyond those that are temporarily defined. For instance, say all following expressions have access to `sample_number`, which is defined as follows:

```javascript
sample_number = 4
```

If a LET...IN expression references `sample_number` within the Airscript expression and does not defined a temporary override, then the Airscript expression will value of `sample_number` defined above:

```javascript
LET x = 1 IN x + sample_number -> 5
```

However, if a LET...IN expression _does_ define a temporary value for `sample_number`, the Airscript expression will evaluate using the temporarily-defined value for the variable:

```javascript
LET
  x = 1,
  sample_number = 1
IN x + sample_number -> 2
```

The above examples used number variables for the sake of simplicity, but it should be stressed that the temporarily defined variables can be of _any_ data type. Likewise, the Airscript expressions being evaluated can be arbitrarily complicated, referencing all manner of functions as well as arithmetic operators.

For instance, the following example temporarily defines a variable of the `Date` type,`input_date`, as June 19th, 2022. It compares this `Date` to the current date, and if it does not take place in the future, the expression returns a string indicating that the given function is too old. Otherwise, it returns the string, "This is a valid date."

```javascript
LET
  input_date = {
    "day": 19,
    "month": 6,
    "year": 2022
  }
IN IF(
  input_date < DATE_FROM_DATETIME(NOW()),
  "The date {{
    FORMAT_DATE(input_date, "MM/DD/YYYY")
  }} is too old!",
  "This is a valid date."
) -> "The date 06/19/2022 is too old!"
```

There are many uses for the LET...IN expression, but one of the most common is simplifying repetitive expressions. For instance, say you are [querying a list of complex nested objects](https://docs.airkit.ai/?q=accessing-values-in-lists-and-objects), and the query expression requires calling multiple times on a property that is designated with unavoidably lengthy dot notation. With a LET...IN expression, you can replace each instance of that property with a variable, allowing you to avoid repeating the fully designation multiple times and mitigating the risk of typos.

Say, for instance, that all downstream expressions have access to the following list of objects, `object_list`:

```javascript
object_list = [
  {
    "layer_1": {
      "layer_2": {
        "key_1": "value_1",
        "key_2": "value_2"
      }
    }
  },
  {
    "layer_1": {
      "layer_2": {
        "key_1": "value_3",
        "key_2": "value_4"
      }
    }
  }
]
```

To generate a new list of objects that contain only the values given under the attributes `object_list.layer_1.layer_2.key_1` and `object_list.layer_1.layer_2.key_2`, you can use LET...IN as follows:

```javascript
FROM
  curr
IN
  object_list
SELECT
  LET
    prefix = curr.layer_1.layer_2
  IN {
    "key_one": prefix.key_1,
    "key_two": prefix.key_2
  } 

->
 
[
  {
    "key_one": "value_1",
    "key_two": "value_2"
  },
  {
    "key_one": "value_3",
    "key_two": "value_4"
  }
]
```

This way, "curr.layer\_1.layer\_2" only needs to be typed once.
