神刀安全网

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 

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 withKLIPSE in order to understand how clojurescript checks if something is true:

You see in the transpiled javascript code that the x variable has been wrapped into into a call to th 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!

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 withKLIPSE:

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 inKLIPSE:

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:

What’s happened here?

Remember that in javascript , 0 is falsy.

b is a boolean and x is also considered as a boolean because of type propagations.

f is called with a boolean value: false .

But f breaks the contract as it assigned a non-boolean value 0 into x .

And then the javascript truth system makes troubles: 0 is falsy, so we get into the loop almost forever.

Clojurescript provides a way to turn off type inference, using the ^any type hint.

So let’s add ^any to x and see what happens:

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » Truth in clojurescript

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
分享按钮