3.11

Let Expression

When someone else reads our escapeEarth function’s definition, they may wonder what the numbers 11.186 and 7.67 really mean.

escapeEarth myVelocity mySpeed =
    if myVelocity > 11.186 then
        "Godspeed"

    else if mySpeed == 7.67 then
        "Stay in orbit"

    else
        "Come back"

It would be nice if we could give them names. We can do that using a let expression. In src/Playground.elm, modify escapeEarth to this:

escapeEarth myVelocity mySpeed =
    let
        escapeVelocityInKmPerSec =
            11.186

        orbitalSpeedInKmPerSec =
            7.67
    in
    if myVelocity > escapeVelocityInKmPerSec then
        "Godspeed"

    else if mySpeed == orbitalSpeedInKmPerSec then
        "Stay in orbit"

    else
        "Come back"

The let expression creates a local scope.

Scope
A scope is a region in a program where defined constants exist and are accessible. Constants created in a region cannot be accessed outside of that region. As soon as the program execution leaves this region all constants and values created in the region will be destroyed.

Often times, we want to define local constants and functions that we don’t want the rest of the code in our module to know about. We can define them inside a let expression. They won’t be visible outside the scope created by a let expression making them essentially private. No code outside escapeEarth function can access the escapeVelocityInKmPerSec and orbitalSpeedInKmPerSec constants.

Right now if a spaceship’s velocity or speed isn’t fast enough to either escape Earth’s gravity or stay in an orbit we simply tell it to come back to Earth. It would be more helpful if we could tell the spaceship where to land. Let’s create a function for that in the let area.

escapeEarth myVelocity mySpeed fuelStatus =
    let
        escapeVelocityInKmPerSec =
            11.186

        orbitalSpeedInKmPerSec =
            7.67

        whereToLand fuel =
            if fuel == "low" then
                "Land on droneship"

            else
                "Land on launchpad"
    in
    if myVelocity > escapeVelocityInKmPerSec then
        "Godspeed"

    else if mySpeed == orbitalSpeedInKmPerSec then
        "Stay in orbit"

    else
        whereToLand fuelStatus

escapeEarth now takes an additional parameter called fuelStatus. The newly defined private function whereToLand checks the fuel status and tells where to land. This function is not visible outside the let expression. Modify main to apply escapeEarth like this:

main =
    escapeEarth 10 6.7 "low"
        |> Html.text

If you refresh the page at http://localhost:8000/src/Playground.elm, you should see Land on droneship.

Strictly speaking, we didn’t have to define whereToLand as a function. The fuelStatus parameter is directly accessbile inside whereToLand, so there is no need to introduce the fuel parameter. If we remove fuel from whereToLand’s definition, it simply becomes a constant. Go ahead and make that change.

escapeEarth myVelocity mySpeed fuelStatus =
    let
        .
        .
        whereToLand =
            if fuelStatus == "low" then
                "Land on droneship"

            else
                "Land on launchpad"
    in
    .
    .
    else
        whereToLand
Back to top
Close