# Truth in clojurescript

## Truth and languages

The title of this paragraph sounds a bit postmodern. But here, we want to discuss the truth in `Clojurescript`

and `javascript`

.

`Javascript`

’s conception of the truth is a bit surprising. See by yourself:

```
Boolean(0) // false
Boolean("0") // true
0 == "0" // true
0 == false // true
"0" == false // true
Boolean("") // false
Boolean([]) // true
Boolean({}) // true
Boolean(Math.sqrt(-1)) // false
```

In any “normal” programming language, `0`

and `""`

should be truthy.
You could argue about `Math.sqrt(-1)`

…

On the opposite, `Clojure`

’s conception of the truth is completly well defined.

It is therefore very interesting to ask:

How

`Clojurescript`

handles the truth?

## Clojurescript: a teacher about truth

Let’s look at some transpiled `javascript`

code with KLIPSE in order to understand how `clojurescript`

checks if something is true:

```
(defn check [x]
(if x "true" "false"))
```

You see in the transpiled `javascript`

code that the `x`

variable has been wrapped into into a call to the `cljs.core.truth_`

function.

Here is the code for `cljs.core.truth_`

:

```
function cljs$core$truth_(x) {
return x != null && x !== false
}
```

This is how

`clojurescript`

teaches`javascript`

what is true and what is not - in its own language!

And indeed, `javascript`

is a good student

```
cljs$core$truth_(true) // true
cljs$core$truth_(false) // false
cljs$core$truth_(0) //true
cljs$core$truth_("") // true
cljs$core$truth_(null) // false
cljs$core$truth_(undefined) // false
cljs$core$truth_(NaN) // true
cljs$core$truth_(Math.sqrt(-1)) // true
```

## Performances

It’s nice to have a truth wrapper. But what if you are in a performance sensitive environment and you want to use the native `javascript`

truth system - in order to move faster?

Well, `clojurescript`

provides a way to let the compiler know that you trust `javascript`

: the `^boolean`

type hint.

Let’s see it in action with KLIPSE:

```
(defn check [^boolean x]
(if x "true" "false"))
```

By using the `^boolean`

type hint, you let the compiler know that `x`

must be a boolean i.e. either `true`

or `false`

. In that case, it’s safe to trust `javascript`

about the truth. There is no need to wrap the hinted variable into `cljs.core.truth_`

.

And the `clojurescript`

compiler is smart: it knows how to propagate type hints i.e. if you assign a hinted variable `x`

into an unhinted variable `y`

, then `y`

is automatically hinted.

Let’s check it with a simple piece of code in KLIPSE:

```
(defn check [^boolean x]
(let [y x]
let(if y "true" "false")))
```

You see that `y`

has not been wrapped.

Cool, isn’t it?

## Dangers

With great power comes great responsibility

Let’s have a look at some interesting edge cases exposed by Mike Fikes involving the `^boolean`

type hint:

```
(defn f [^boolean b]
(loop [x b
n 0]
(cond
(= n 100000) "almost infinite loop"
(not x) (recur 0 (inc n))
:else :done)))
(f false)
```

What’s happened here?

Remember that in `javascript`

, `0`

is falsy.

`b`

is declared as a boolean`x`

is also considered as a boolean because of type propagation:`x`

is not wrapped into`cljs.core.truth_`

`f`

is called with a boolean value:`false`

- So far so good…
- But
`f`

breaks the contract as it assigns a non-boolean value`0`

into`x`

.

Therefore, `x`

is not wrapped, and we are in a non-safe situation: a non-boolean value is handled by the `javascript`

truth system.

Let’s follow, the flow of the loop for the first two iterations:

- First iteration:
`x=false`

and`n=0`

;`false`

is falsy ➠`recur`

with`x=0`

and`n=1`

- Second iteration:
`x=0`

and`n=1`

;`0`

is falsy ➠`recur`

with`x=0`

and`n=2`

- ….
- …

…

## How to get the best of the two worlds?

`Clojurescript`

provides a way to turn off type inference, using the `^any`

type hint.

Let’s add `^any`

to `x`

and see how it solves our problem:

```
(defn f [^boolean b]
(loop [^any x b
n 0]
(cond
(= n 100000) "almost infinite loop"
(not x) (recur 0 (inc n))
:else :done)))
(f false)
```

Hourra! `x`

has been wrapped again and we are safe.

And obviously, it solves the infinite loop issue:

```
(defn f [^boolean b]
(loop [^any x b
n 0]
(cond
(= n 100000) "almost infinite loop"
(not x) (recur 0 (inc n))
:else :done)))
(f false)
```

Clojurescript rocks!