# How to reason about code to avoid equality checks

**URL:** https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183
**Category:** Learn
**Created:** [February 15, 2020, 6:23am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183 "2020-02-15T06:23:55Z")
**Posts on this page:** 14
**Page:** 1

<div class="post-metadata">

### Author: ![codepadawan](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@codepadawan](https://discourse.elm-lang.org/u/codepadawan)
#### Post date: [February 15, 2020, 6:23am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/1 "2020-02-15T06:23:56Z")

</div>

I’m currently working through the Elm Guide.

On completing the Forms section, I wrote this [code](https://github.com/codepadawanelm/elm-guide/blob/master/Password%20Form.elm).

I then read this [post](https://discourse.elm-lang.org/t/performance-optimization/5105) and realised that I seem to be approaching elm incorrectly.

Elm-format makes the code difficult to read, see lines 109 to 118, which again leads me to the same conclusion.

Please advise how to reason through the code to avoid all the equality checks.

---

<div class="post-metadata">

### Author: ![jfmengels](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/jfmengels/32/3124_2.png) [@jfmengels](https://discourse.elm-lang.org/u/jfmengels)
#### Post date: [February 15, 2020, 7:11am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/2 "2020-02-15T07:11:03Z")

</div>

You don’t need equality checks for booleans, so you can simplify

```
model.password
        == model.passwordAgain
        && pwLength model.password
        == True
        && pwIsUpper model.password
        == True
        && pwIsLower model.password
        == True
        && pwIsDigit model.password
        == True

```

By

```
model.password
        == model.passwordAgain
        && pwLength model.password
        && pwIsUpper model.password
        && pwIsLower model.password
        && pwIsDigit model.password

```

If you need a boolean to equal false, then you can use the`not` function.

I wouldn’t worry about the discussion in the post you linked to. In their case, they were working on an editor and I think the function was called thousands of times when the user wrote a text of thousands of lines long.

In your and almost every use case, Elm (or rather the underlying JS code) is fast enough and you won’t need to worry too much about performance. Start worrying about it when you do an operation thousands of times per second, but especially if you notice slowness in your application.

---

<div class="post-metadata">

### Author: ![lydell](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lydell/32/178_2.png) [@lydell](https://discourse.elm-lang.org/u/lydell)
#### Post date: [February 15, 2020, 7:45am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/3 "2020-02-15T07:45:36Z")

</div>

In addition to @jfmengels’ answer, the workaround to elm-formats quirky formatting is to add parentheses:

```auto
vSubmitButton : Model -> Html msg
vSubmitButton model =
    if
        (model.password == model.passwordAgain)
            && (pwLength model.password == True)
            && (pwIsUpper model.password == True)
            && (pwIsLower model.password == True)
            && (pwIsDigit model.password == True)
    then
        button [disabled False] [text "Submit"]

    else
        button [disabled True] [text "Submit"]

```

But in this case it is even better to remove the `== True` parts, as mentioned.

---

<div class="post-metadata">

### Author: ![codepadawan](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@codepadawan](https://discourse.elm-lang.org/u/codepadawan)
#### Post date: [February 15, 2020, 8:09am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/4 "2020-02-15T08:09:22Z")

</div>

Thank you very much.

Is there any way to use the Elm syntax to shorten this code, as all four functions call the same argument?

```auto
model.password
        == model.passwordAgain
        && pwLength model.password
        && pwIsUpper model.password
        && pwIsLower model.password
        && pwIsDigit model.password

```

---

<div class="post-metadata">

### Author: ![codepadawan](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@codepadawan](https://discourse.elm-lang.org/u/codepadawan)
#### Post date: [February 15, 2020, 8:12am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/5 "2020-02-15T08:12:21Z")

</div>

Thank you for the suggestion.

---

<div class="post-metadata">

### Author: ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)
#### Post date: [February 15, 2020, 8:19am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/6 "2020-02-15T08:19:48Z")

</div>

> [@codepadawan](#):
>
> Is there any way to use the Elm syntax to shorten this code, as all four functions call the same argument?

You can write it as `List.all ((|>) model.password) [(==) model.passwordAgain, pwLength, pwIsUpper, pwIsLower, pwIsDigit]`  
You can read that code as “check if all the functions in this list of functions produce `True` when you give them the argument `model.password`”

This code is using some infix functions in their regular function syntax. Another way to write it is:

`List.all (\f -> f model.password) [(==) model.passwordAgain, pwLength, pwIsUpper, pwIsLower, pwIsDigit]`

and

`List.all (\f -> f model.password) [\p -> p == model.passwordAgain, pwLength, pwIsUpper, pwIsLower, pwIsDigit]`

---

<div class="post-metadata">

### Author: ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)
#### Post date: [February 15, 2020, 8:24am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/7 "2020-02-15T08:24:27Z")

</div>

The best way to handle this however is to have the functions that check the password return a `List String` and concatenate them. In the view, you can check for the result of the error check and if it is different than `[]` display the error messages.

Check the validation in [elm-spa-example](https://github.com/rtfeldman/elm-spa-example/blob/master/src/Page/Article/Editor.elm#L469-L499) for inspiration on how to do this.

---

<div class="post-metadata">

### Author: ![codepadawan](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@codepadawan](https://discourse.elm-lang.org/u/codepadawan)
#### Post date: [February 15, 2020, 10:31am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/8 "2020-02-15T10:31:26Z")

</div>

Thank you very much.

---

<div class="post-metadata">

### Author: ![codepadawan](https://avatars.discourse-cdn.com/v4/letter/c/a4c791/32.png) [@codepadawan](https://discourse.elm-lang.org/u/codepadawan)
#### Post date: [February 15, 2020, 10:43am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/9 "2020-02-15T10:43:48Z")

</div>

One last question on this thread:

How would I use the Elm syntax to shorten the following code, as the same function calls two different arguments:

```auto
if pwIsLower model.password || pwIsLower model.passwordAgain then

```

---

<div class="post-metadata">

### Author: ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)
#### Post date: [February 15, 2020, 10:46am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/10 "2020-02-15T10:46:29Z")

</div>

`List.any pwIsLower [model.password, model.passwordAgain]`

---

<div class="post-metadata">

### Author: ![cwhy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/cwhy/32/558_2.png) [@cwhy](https://discourse.elm-lang.org/u/cwhy)
#### Post date: [February 16, 2020, 9:08am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/11 "2020-02-16T09:08:53Z")

</div>

@pdamoc AFAIK `&&` will stop if the previous one is False, but `List.all` does not.

---

<div class="post-metadata">

### Author: ![pdamoc](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/pdamoc/32/36_2.png) [@pdamoc](https://discourse.elm-lang.org/u/pdamoc)
#### Post date: [February 16, 2020, 9:19am UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/12 "2020-02-16T09:19:55Z")

</div>

Looking at the [implementation](https://github.com/elm/core/blob/master/src/List.elm#L280-L303), `List.all` will exit as soon as it will encounter a `False` value.

In any case, I would use `if pwIsLower model.password || pwIsLower model.passwordAgain then` because I like the simple nature of it. Performance wise, I doubt that it will make all that much of a difference unless this is in a tight loop of some logic.

---

<div class="post-metadata">

### Author: ![cwhy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/cwhy/32/558_2.png) [@cwhy](https://discourse.elm-lang.org/u/cwhy)
#### Post date: [February 16, 2020, 1:43pm UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/14 "2020-02-16T13:43:40Z")

</div>

Ah… You are right. It makes sense to do so as well. I was not expecting the laziness here.

---

<div class="post-metadata">

### Author: ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)
#### Post date: [February 26, 2020, 1:43pm UTC](https://discourse.elm-lang.org/t/how-to-reason-about-code-to-avoid-equality-checks/5183/15 "2020-02-26T13:43:41Z")

</div>

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
