# ClojureScript is weakly typed!

**URL:** https://clojureverse.org/t/clojurescript-is-weakly-typed/3117
**Category:** Watercooler
**Tags:** clojurescript
**Created:** [November 2, 2018, 7:54am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117 "2018-11-02T07:54:04Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![didibus](https://clojureverse.org/user_avatar/clojureverse.org/didibus/32/951_2.png) [@didibus](https://clojureverse.org/u/didibus)
#### Post date: [November 2, 2018, 7:54am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/1 "2018-11-02T07:54:04Z")

</div>

I just realized ClojureScript is weakly typed, and I’m really disappointed and bummed out.

```
(+ 1 "1")
=> "11"

```

I’ve always considered this the worst part of JavaScript. I find weakly typed languages do in fact create more bugs, and have higher defect rates. While I don’t believe statically checked languages do, the difference between strong and weak is pretty important to me.

Its also a huge difference from Clojure. I’m surprised I never heard of it before. What do other make of this?

Regards

---

<div class="post-metadata">

### Author: ![didibus](https://clojureverse.org/user_avatar/clojureverse.org/didibus/32/951_2.png) [@didibus](https://clojureverse.org/u/didibus)
#### Post date: [November 2, 2018, 8:00am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/2 "2018-11-02T08:00:59Z")

</div>

By the way, this came as a shock to me, because I feel I’ve actually heard many times that ClojureScript was strongly typed, and had it listed as an advantage over JavaScript. Even Eric Normand says so here:

> **[Won't it be hard to debug ClojureScript in my browser?](https://ericnormand.me/mini-guide/debugging-clojurescript)**
>
> Even though ClojureScript adds another layer of abstraction, the tooling makes it easier to debug that plain JavaScript.

> Finally, ClojureScript avoids lots of bugs by virtue of its more functional [semantics](https://purelyfunctional.tv/guide/clojure-collections/#two-layers). ClojureScript is immutable by default. **It is not weakly typed**. And the language is more thought out.

The emphasis is mine, but in fact, ClojureScript is weakly typed.

Does anyone know, is there like a compiler flag to have strong run-time checks be auto-inserted to make it strongly typed?

---

<div class="post-metadata">

### Author: ![vvvvalvalval](https://clojureverse.org/user_avatar/clojureverse.org/vvvvalvalval/32/792_2.png) [@vvvvalvalval](https://clojureverse.org/u/vvvvalvalval)
#### Post date: [November 2, 2018, 10:01am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/3 "2018-11-02T10:01:52Z")

</div>

> [@didibus](#):
>
> I just realized ClojureScript is weakly typed, and I’m really disappointed and bummed out.

To be fair, weak/strong typing is a spectrum rather than a 2-slots classification, nor does it have a unique definition. In my view finding one operation accepting disparately-typed arguments without an error is not enough to definitely classify a language as weakly-typed: there are still plenty of operations in ClojureScript that will yield an error if applied to the wrong types, e.g treating a number as a function.

To me the example you describe is more an instance of “Clojure is written for correct programs” or “Clojure embraces the host platform” or just a bug than proof of weak-typing. Of course, our disagreement may stem from you having a stricter definition of strong typing than I do, but then I would question the relevance of that definition.

---

<div class="post-metadata">

### Author: ![orestis](https://clojureverse.org/user_avatar/clojureverse.org/orestis/32/279_2.png) [@orestis](https://clojureverse.org/u/orestis)
#### Post date: [November 2, 2018, 12:22pm UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/4 "2018-11-02T12:22:17Z")

</div>

Upcoming releases aim to tackle part of this problem though: [https://github.com/clojure/clojurescript-site/blob/news-next/content/news/2018-09-01-release.adoc](https://github.com/clojure/clojurescript-site/blob/news-next/content/news/2018-09-01-release.adoc)

> In general, any inferred types will automatically flow from function bodies outward, such as an inferred numeric type in the following example:

> ```
> (defn foo [x]
> (+ x 3))
> 
> ```

> If foo is used in a context where types are checked, as in

> ```
> (+ (foo 1) "a")
> 
> ```

> you will now see a warning that properly reflects the type:

> ```
> WARNING: cljs.core/+, all arguments must be numbers, got [number string] instead
> 
> ```

> Previously, without a type hint on foo, the compiler would produce a warning that indicates a type of any instead of number.

---

<div class="post-metadata">

### Author: ![GKlijs](https://clojureverse.org/user_avatar/clojureverse.org/gklijs/32/559_2.png) [@GKlijs](https://clojureverse.org/u/GKlijs)
#### Post date: [November 2, 2018, 12:23pm UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/5 "2018-11-02T12:23:58Z")

</div>

Besides strong/weak typing there is static/dynamic typing. [https://hackernoon.com/i-finally-understand-static-vs-dynamic-typing-and-you-will-too-ad0c2bd0acc7](https://hackernoon.com/i-finally-understand-static-vs-dynamic-typing-and-you-will-too-ad0c2bd0acc7) maybe a static typed language like Elm better suits your needs. I really don’t mind your example much, and really like closure for generic functions over sets, compared to java where you have to explicitly type everything, making it much harder to reuse code.

---

<div class="post-metadata">

### Author: ![dnolen](https://clojureverse.org/user_avatar/clojureverse.org/dnolen/32/504_2.png) [@dnolen](https://clojureverse.org/u/dnolen)
#### Post date: [November 2, 2018, 4:24pm UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/6 "2018-11-02T16:24:27Z")

</div>

Writing obviously bad code like that will emit a ClojureScript compiler warning. And `+` is only ever used for numerics, `str` is for string concatenation - which is why probably people rarely encounter this behavior.

In the end, ClojureScript numerics bottom out in JavaScript numerics because of performance and that’s the tradeoff.

---

<div class="post-metadata">

### Author: ![didibus](https://clojureverse.org/user_avatar/clojureverse.org/didibus/32/951_2.png) [@didibus](https://clojureverse.org/u/didibus)
#### Post date: [November 3, 2018, 6:05am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/7 "2018-11-03T06:05:25Z")

</div>

As a reminder for myself and others, here’s all the ClojureScript functions (that I could find) which will do implicit type coercion (aka weak typing) similar to JavaScript:

```auto
+
-
*
/
mod
inc
dec
>
<
<=
>=
bit-and
bit-or
bit-not
bit-xor
bit-and-not
bit-clear
bit-flip
bit-set
bit-test
bit-shift-left
bit-shift-right
unsigned-bit-shift-right
"All JS interop, such as the ones in Math/"

```

Functions which depend on these might also suffer from weak typing.

Equality (=, ==, not, not=, etc.) and logical (and, or, etc.) functions in ClojureScript **are** strongly typed in ClojureScript, as opposed to JavaScript.

Here’s an example of the quirks of weak typing:

```auto
cljs.user=> (< 43 42)
false
cljs.user=> (< ["43"] [42])
true

cljs.user=> (inc "1")
"11"

cljs.user=> (dec "11")
10

cljs.user=> (+ "1" 1)
"11"

cljs.user=> (- "1" 1)
0

```

I’m not dropping the ball on ClojureScript, I still love it, but it seems it being strongly typed similar to Clojure is a myth. I think people should be aware of that, its something to watch out for.

---

<div class="post-metadata">

### Author: ![didibus](https://clojureverse.org/user_avatar/clojureverse.org/didibus/32/951_2.png) [@didibus](https://clojureverse.org/u/didibus)
#### Post date: [November 3, 2018, 6:28am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/8 "2018-11-03T06:28:50Z")

</div>

> [@vvvvalvalval](#):
>
> In my view finding one operation accepting disparately-typed arguments without an error is not enough to definitely classify a language as weakly-typed

I define weak typing as a language which will perform automatic type coercion. I wouldn’t mind `+` having an overload of `(+ "a" "b")` and `(+ 1 2)`, but I mind implicit type coercion rules which will allow `(+ "a" 1)` to work.

> [@vvvvalvalval](#):
>
> To be fair, weak/strong typing is a spectrum rather than a 2-slots classification

I agree, it’s a spectrum, and ClojureScript is better than JavaScript in that regard. That said, some language are 100% on one side of that spectrum, and to my knowledge, Clojure is 100% strongly typed. I don’t know of any implicit type coercion in Clojure core.

> [@orestis](#):
>
> Upcoming releases aim to tackle part of this problem though: [https://github.com/clojure/clojurescript-site/blob/news-next/content/news/2018-09-01-release.adoc](https://github.com/clojure/clojurescript-site/blob/news-next/content/news/2018-09-01-release.adoc)

This would probably be the best solution. Keep the performance, but warn on its usage. The current warning isn’t powerful enough to warn when variables are used, so hopefully this inference flow will cover those edge cases.

> [@GKlijs](#):
>
> Besides strong/weak typing there is static/dynamic typing. [https://hackernoon.com/i-finally-understand-static-vs-dynamic-typing-and-you-will-too-ad0c2bd0acc7](https://hackernoon.com/i-finally-understand-static-vs-dynamic-typing-and-you-will-too-ad0c2bd0acc7) maybe a static typed language like Elm better suits your needs.

Thanks for the suggestion. I have no issue with dynamic typing though. Strong vs Weak is orthogonal to Static vs Dynamic types though. Clojure is strongly typed and dynamically typed. ClojureScript, to my surprise, is weakly typed and dynamically typed. You can read more about it here: [terminology - Static/Dynamic vs Strong/Weak - Stack Overflow](https://stackoverflow.com/a/2351203/172272)

> [@dnolen](#):
>
> In the end, ClojureScript numerics bottom out in JavaScript numerics because of performance and that’s the tradeoff.

Thanks @dnolen for the justification. With more powerful type inference that can flow through variables, I should be satisfied, and the performance will remain. Otherwise, I personally would appreciate a compiler flag to add run-time checks for these, and wouldn’t mind the performance trade off in most cases. Especially when running through my tests, and I could easily turn it off for production.

---

<div class="post-metadata">

### Author: ![didibus](https://clojureverse.org/user_avatar/clojureverse.org/didibus/32/951_2.png) [@didibus](https://clojureverse.org/u/didibus)
#### Post date: [November 3, 2018, 6:38am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/9 "2018-11-03T06:38:14Z")

</div>

@orestis

Hum, actually I’m a little confused. Your link doesn’t work for me. I get a 404. But the example you gave works in my repl, and I get a warning. That said, given:

```auto
(defn foo
  [x]
  (+ x 3))

```

I get a proper warning when running:

```auto
cljs.user=> (+ (foo 1) "a")
            ⬆
WARNING: cljs.core/+, all arguments must be numbers, got [any string] instead. at line 1 
"4a"

```

But not when running:

```auto
cljs.user=> (foo "1")
"13"

```

I’m not sure why the latter scenario is not being warned on, I feel if the former can, the latter should be able to warn also.

EDIT: Hum, I see my warning says [any string]. So I guess I don’t have the “flow” change you mention. Hopefully when that drops, both examples will warn appropriately.

---

<div class="post-metadata">

### Author: ![orestis](https://clojureverse.org/user_avatar/clojureverse.org/orestis/32/279_2.png) [@orestis](https://clojureverse.org/u/orestis)
#### Post date: [November 3, 2018, 9:54am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/10 "2018-11-03T09:54:42Z")

</div>

Seems like the link has changed - to avoid entering another broken link, see the latest news item here: [https://github.com/clojure/clojurescript-site/tree/news-next/content/news](https://github.com/clojure/clojurescript-site/tree/news-next/content/news)

Note, this is an unreleased version, so you have to use master to see this new behavior. No idea if it covers your entire use case though.

---

<div class="post-metadata">

### Author: ![dnolen](https://clojureverse.org/user_avatar/clojureverse.org/dnolen/32/504_2.png) [@dnolen](https://clojureverse.org/u/dnolen)
#### Post date: [November 5, 2018, 9:46pm UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/11 "2018-11-05T21:46:56Z")

</div>

> [@didibus](#):
>
> Otherwise, I personally would appreciate a compiler flag to add run-time checks for these, and wouldn’t mind the performance trade off in most cases.

Unlikely because 1) this isn’t a problem that a significant number of users who are using ClojureScript in production are complaining about 2) the performance impact is bigger than it may seem, persistent data structures rely on fast numerics. There’s also a potential for churn that outsizes the small benefits.

It’s possible we may revisit, but this will remain a low priority thing for the foreseeable future. As usual we have more important fish to fry 🙂

---

<div class="post-metadata">

### Author: ![didibus](https://clojureverse.org/user_avatar/clojureverse.org/didibus/32/951_2.png) [@didibus](https://clojureverse.org/u/didibus)
#### Post date: [November 6, 2018, 4:14am UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/12 "2018-11-06T04:14:05Z")

</div>

> [@dnolen](#):
>
> It’s possible we may revisit, but this will remain a low priority thing for the foreseeable future. As usual we have more important fish to fry

Oh definitly, not even my top item on my wishlist, far from it. It was more of a learning process for me of understanding the difference between Clojure, JavaScript and ClojureScript. This one surprised me quite a bit, and got me curious about the reasons behind it. Though I figured it was most likely performance.

Anyways, thanks for all the explanations and transparency. As much as I love Clojure and ClojureScript for its technical prowess, it’s this transparency and interaction with core members and their friendliness that really set them appart.

---

<div class="post-metadata">

### Author: ![system](https://clojureverse.org/uploads/default/original/2X/5/51079bf9e4b7d9466242c06cf1e43b9f8bd6da14.png) [@system](https://clojureverse.org/u/system)
#### Post date: [May 7, 2019, 4:14pm UTC](https://clojureverse.org/t/clojurescript-is-weakly-typed/3117/13 "2019-05-07T16:14:06Z")

</div>

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