Fork me on GitHub

Hi, trying to upgrade an old project to clojurescript 1.9.946 and make use of the ability to import javascript modules but although it installs the proper libs when I run fig wheel (1.5.14 ) just running [jayson :as jayson-rpc] gives me

base.js:1357 Uncaught Error: Undefined nameToPath for jayson
    at visitNode (base.js:1357)
    at visitNode (base.js:1355)
    at (base.js:1369)
    at (base.js:706)
    at (index):2
I am not sure how to import javascript. I am using lein if I ["jayso" :as jayson-rpc] I get
Assert failed: cljs.analyzer/foreign-dep? expected symbol got "jayson"
is there something I am not doing?


Is this expected behaviour when overwriting cljs.core function

;;;;;;; file a ;;;;;;
(ns file.a)
(defn + [& vals]
  (prn "Called!")
  (apply cljs.core/+ vals))
;;;;;;;;;; file b;;;;;
(ns file.b
  (:require [file.a :refer [+]]))
(+ 1 2 ) ;; Doesn't print "Called!"
(file.a/+ 1 2) ;; Prints "Called!"
(`+ 1 2) ;; Prints "Called!"
I'd expect if I refer a symbol, given the overwrite warning, that it would really overwrite the cljs.core function.


from namespace file.b

`+   => file.a/+
`file.a/+ => file.a/+
doesn't seem right.


@hlolli I have a hunch that this might be b/c + is also a macro which is picked up here. but just a guess. So: Does the same happen with --e.g-- map?


@rauh no, doesn't happen with map


ok probably worth an issue. Try to search in case it already exists.


ok, I'll look in the jira, good chances I wouldn't find it if it was there, let's see


Yeah, @hlolli you'd have to also define a + macro. For example

;;;; a.clj ;;;
(ns file.a)
(defmacro + [a b]
  `(do (println "macro called!")
       (+ ~a ~b)))
;;; a.cljs ;;;
(ns file.a
  (:require-macros file.a))
(defn + [& vals]
  (prn "Called!")
  (apply cljs.core/+ vals))
;;; b.cljs ;;;
(ns file.b
  (:require [file.a :refer [+]]))
(+ 1 2 ) ;; Prints "macro called!"
(file.a/+ 1 2) ;; Prints "macro called!"
(`+ 1 2) ;; Doesn't print anything but returns 2
Then, in a REPL, you will see both being overwritten:
cljs.user=>  (require 'file.b)
WARNING: + already refers to: #'clojure.core/+ in namespace: file.a, being replaced by: #'file.a/+
WARNING: + already refers to: cljs.core/+ being replaced by: file.a/+ at line 3 /Users/mfikes/Desktop/src/file/a.cljs
macro called!
macro called!
It is very intersting that your last expression
(`+ 1 2)
prints "Called" for you. This shouldn't happen—I'd recheck your original test. This is essentially applying a symbol to a value which will look it up and if failing, should return the not-found value 2. For example
(`blah 34 77)
will return 77, no matter what else is defined.


If that last bit didn't make sense, consider that

(`blah {`blah 100} 77)
returns 100.


ah yes @mfikes yes you're right, I got confused, because when the plus fails I get "[object Object][object Object]" because I'm attempting to use the plus sign to do more than it should. But with the syntax quote, I just get the return value of the expression, which is the return value I was expecting from this operation, and that confused me, the print statement is not called.


I wish I could edit my jira ticket, to remove this part, and the formatting 🙂 But as you say, rewriting the macro is maybe a must @mfikes do you see this as a bug, or is the macro replacement just something that I'd have to do?


FWIW, if you change that to

(#'+ 1 2)
this would instead force it to go through the var, thus printing "Called!"


I don't see it as a bug, in that things are working as intended. Perhaps it warrants a warning. Hrm.


I assume if you replaced (+ x y) with (apply + [x y]) that would also force the non-macro version


One thing that could happen is that you could overwrite some core function, and then later if a core macro were introduced for performance reasons, it would be a breaking change. That would not be bueno.


Yes @noisesmith then + is higher-order


having one symbol bound to a macro and also a function seems like it was asking for trouble in the first place?


unless we take the principled position that one should never replace things in cljs.core / clojure.core I guess

Alex Miller (Clojure team)21:12:25

We should not take that position


Perhaps the symbol resolution mechanics in CloureScript could be revised so that it doesn't greedily do macroexpansion in that case. Hmm.


I think those core macros are only there for performance, and their existence is intended to be transparent.


isn't this problem essentially a cljs.analyzer problem with the namespace? If a symbol is rewritten, in my case with a function, then for that namespace all pointers to the + as macro should be removed?


I could see that position being taken.


@hlolli One workaround is to (:refer-clojure :exclude [+]) in every file you either define or refer a non-core version of +.


@mfikes nice. What I'm attempting to do, will make purists grown. But I'd like to use this + symbol for a transpiler I'm working on, the target language uses + extensivly (throwing warning is a good thing therefore). I think I'll end up with some ugly hack to simplify it in the end 🙂