Welcome! Please see the About page for a little more info on how this works.

+2 votes
in ClojureScript by
edited by

This this expression in a clojurescript repl:

(let [{:keys [a-b a_b]} {:a-b 0 :a_b 1}] [a-b a_b])

will surprisingly return:

[1 1]

I did some further investigation by creating a clean project like in Clojurescript official guide:

(ns helloworld.core)

;; two identical code blocks

;; first one is at top level
(let [{:keys [a-b a_b]} {:a-b 0 :a_b 1}] [a-b a_b])
;; second one nested inside a function call
(println (let [{:keys [a-b a_b]} {:a-b 0 :a_b 1}] [a-b a_b]))

and compiled with:

clj -M --main cljs.main --compile helloworld.core

here's the js file:

// Compiled by ClojureScript 1.10.866 {:optimizations :none}
goog.provide('helloworld.core');
goog.require('cljs.core');
var map__528_529 = new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"a-b","a-b",-1660985764),(0),new cljs.core.Keyword(null,"a_b","a_b",-1795286609),(1)], null);
var map__528_530__$1 = cljs.core.__destructure_map.call(null,map__528_529);
var a_b_531 = cljs.core.get.call(null,map__528_530__$1,new cljs.core.Keyword(null,"a-b","a-b",-1660985764));
var a_b_532 = cljs.core.get.call(null,map__528_530__$1,new cljs.core.Keyword(null,"a_b","a_b",-1795286609));
new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [a_b_531,a_b_532], null);
cljs.core.println.call(null,(function (){var map__533 = new cljs.core.PersistentArrayMap(null, 2, [new cljs.core.Keyword(null,"a-b","a-b",-1660985764),(0),new cljs.core.Keyword(null,"a_b","a_b",-1795286609),(1)], null);
var map__533__$1 = cljs.core.__destructure_map.call(null,map__533);
var a_b = cljs.core.get.call(null,map__533__$1,new cljs.core.Keyword(null,"a-b","a-b",-1660985764));
var a_b = cljs.core.get.call(null,map__533__$1,new cljs.core.Keyword(null,"a_b","a_b",-1795286609));
return new cljs.core.PersistentVector(null, 2, 5, cljs.core.PersistentVector.EMPTY_NODE, [a_b,a_b], null);
})());

//# sourceMappingURL=core.js.map

as you can see:

  • the a-b and a_b symbols in first block ended up as var a_b_531 and var a_b_532.
  • in the second block they both ended up as var a_b, therefore their values collided.

I also get the same result with macroexpanded version using cljs.core/let*

(let* [m {:a-b 0, :a_b 1}
       a-b
       (cljs.core/get m :a-b)
       a_b
       (cljs.core/get m :a_b)]
  [a-b a_b])

(println 
 (let* [m {:a-b 0, :a_b 1}
        a-b
        (cljs.core/get m :a-b)
        a_b
        (cljs.core/get m :a_b)]
   [a-b a_b]))

so we can eliminate the case that something is wrong with cljs.core/let macro

Please log in or register to answer this question.

...