Search code examples
clojureleiningenclojurescriptlighttable

Clojure console spits out 'unsigned-bit-shift-right' warning on simple HelloWorld


I'm doing my first steps with Clojure today and I encountered the first confusing obstacle right off the bat!

I've built a new Leiningen(2.5.1) project and just want to run the default code, which is:

(ns wavescript.core
  (:gen-class))

(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))

Problem is the Lighttable(0.7.2) console tells:

WARNING: unsigned-bit-shift-right already refers to: #'clojure.core/unsigned-bit-shift-right in namespace: cljs.core, being replaced by: #'cljs.core/unsigned-bit-shift-right

I found some Google entries but none brought me further. What this is about?


Solution

  • This is caused by the symbol unsigned-bit-shift-right being found in the clojure.core namespace as well as a cljs.core. The clojure.core namespace is compiled/loaded before cljs.core, and the introduction of the new symbol is throwing the warning. It looks like, from the namespace, you are writing clojurescript. If you look at this file cljs.core on line 2147, you will see this form:

    (defn unsigned-bit-shift-right
      "Bitwise shift right with zero fill"
      [x n] (cljs.core/unsigned-bit-shift-right x n))
    

    in the cljs.core namespace. So, apparently, lighttable is importing both clojure.core and clj.core.

    Honestly, I am not even sure how the cljs implementation is working, as it is completely self-referential. Additionally, there are uses of unsigned-bit-shift-right starting at line 451 that are not prefixed, so they must be using the clojure.core implementation. Bizarre. The above form appears after all the previous uses. It looks safe to say that symbol can be safely excluded. In fact, this may deserve a patch...

    To resolve this, you might want to try to explicitly state your namespace importations and exclude that import. The refer function affords that.

    So, you would have a namespace that looks like this

    (ns my.namespace.hello-world
      [:require 
        [cljs.core :exclude [unsigned-bit-shift-right]]])
    

    The clojure.core implementation looks like this:

    (defn unsigned-bit-shift-right
      "Bitwise shift right, without sign-extension."
      {:inline (fn [x n] `(. clojure.lang.Numbers (unsignedShiftRight ~x ~n)))
       :added "1.6"}
      [x n] (. clojure.lang.Numbers unsignedShiftRight x n))
    

    Alternately, since they are wrapping the functionality, perhaps cljs.core is designed to not need to expose clojure.core. If that is the case, then exclude clojure.core, and see if you code will function properly.

    In fact, from looking at the cljs.core namespace:

    (ns cljs.core
      (:refer-clojure :exclude [-> ->> .. amap and areduce alength aclone assert binding bound-fn case comment cond condp
                                declare definline definterface defmethod defmulti defn defn- defonce
                                defprotocol defrecord defstruct deftype delay destructure doseq dosync dotimes doto
                                extend-protocol extend-type fn for future gen-class gen-interface
                                if-let if-not import io! lazy-cat lazy-seq let letfn locking loop
                                memfn ns or proxy proxy-super pvalues refer-clojure reify sync time
                                when when-first when-let when-not while with-bindings with-in-str
                                with-loading-context with-local-vars with-open with-out-str with-precision with-redefs
                                satisfies? identical? true? false? number? nil? instance? symbol? keyword? string? str get
                                make-array vector list hash-map array-map hash-set
    
                                aget aset
                                + - * / < <= > >= == zero? pos? neg? inc dec max min mod
                                byte char short int long float double
                                unchecked-byte unchecked-char unchecked-short unchecked-int
                                unchecked-long unchecked-float unchecked-double
                                unchecked-add unchecked-add-int unchecked-dec unchecked-dec-int
                                unchecked-divide unchecked-divide-int unchecked-inc unchecked-inc-int
                                unchecked-multiply unchecked-multiply-int unchecked-negate unchecked-negate-int
                                unchecked-subtract unchecked-subtract-int unchecked-remainder-int
                                unsigned-bit-shift-right
    
                                bit-and bit-and-not bit-clear bit-flip bit-not bit-or bit-set
                                bit-test bit-shift-left bit-shift-right bit-xor
    
                                cond-> cond->> as-> some-> some->>
    
                                if-some when-some test ns-interns var vswap!])
    

    You can see that unsigned-bit-shift-right is supposed to be excluded from the namespace. So, you will want to exclude clojure.core to resolve the problem.