# Functions

Functions have two types of parameters:

1. Positional parameters, which require an argument.
2. Named parameters, which optionally take an argument, otherwise using their default value.

So this function is named `fahrenheit_to_celsius` and has one parameter `temp`:

#### PRQL

``````let fahrenheit_to_celsius = temp -> (temp - 32) / 1.8

from cities
derive temp_c = (fahrenheit_to_celsius temp_f)
``````

#### SQL

``````SELECT
*,
(temp_f - 32) / 1.8 AS temp_c
FROM
cities

``````

This function is named `interp`, and has two positional parameters named `high` and `x`, and one named parameter named `low` which takes a default argument of `0`. It calculates the proportion of the distance that `x` is between `low` and `high`.

#### PRQL

``````let interp = low:0 high x -> (x - low) / (high - low)

from students
derive {
sat_proportion_1 = (interp 1600 sat_score),
sat_proportion_2 = (interp low:0 1600 sat_score),
}
``````

#### SQL

``````SELECT
*,
(sat_score - 0) / (1600 - 0) AS sat_proportion_1,
(sat_score - 0) / (1600 - 0) AS sat_proportion_2
FROM
students

``````

## Piping values into functions

Consistent with the principles of PRQL, it’s possible to pipe values into functions, which makes composing many functions more readable. When piping a value into a function, the value is passed as an argument to the final positional parameter of the function. Here’s the same result as the examples above with an alternative construction:

#### PRQL

``````let interp = low:0 high x -> (x - low) / (high - low)

from students
derive {
sat_proportion_1 = (sat_score | interp 1600),
sat_proportion_2 = (sat_score | interp low:0 1600),
}
``````

#### SQL

``````SELECT
*,
(sat_score - 0) / (1600 - 0) AS sat_proportion_1,
(sat_score - 0) / (1600 - 0) AS sat_proportion_2
FROM
students

``````

and

#### PRQL

``````let fahrenheit_to_celsius = temp -> (temp - 32) / 1.8

from cities
derive temp_c = (temp_f | fahrenheit_to_celsius)
``````

#### SQL

``````SELECT
*,
(temp_f - 32) / 1.8 AS temp_c
FROM
cities

``````

We can combine a chain of functions, which makes logic more readable:

#### PRQL

``````let fahrenheit_to_celsius = temp -> (temp - 32) / 1.8
let interp = low:0 high x -> (x - low) / (high - low)

from kettles
derive boiling_proportion = (temp_c | fahrenheit_to_celsius | interp 100)
``````

#### SQL

``````SELECT
*,
((temp_c - 32) / 1.8 - 0) / (100 - 0) AS boiling_proportion
FROM
kettles

``````

### Late binding

Functions can bind to any variable that is in scope when the function is executed. For example, here `cost_total` refers to the column that’s introduced in the `from`.

#### PRQL

``````let cost_share = cost -> cost / cost_total

from costs
derive {
materials_share = (cost_share materials),
labor_share = (cost_share labor),
}
``````

#### SQL

``````SELECT
materials,
labor,