Fork me on GitHub
#clojurescript
<
2020-03-19
>
JAtkins09:03:05

Is it possible to use some equivalent of `

(if (symbol? symbol-or-data) (-> symbol-or-data resolve var-get) symbol-or-data)
for macro arguments in clojurescript? The macro tests fine for clojure (as expected), but always returns nil for clojurescript (maybe expected as well).

p-himik11:03:11

It is possible but in a very limited use-case. What are you actually trying to do?

JAtkins18:03:38

I'm trying to make a formula generator. The syntax is something like this:

(deff :a)
(deff :b)
(deff :c :function (* :a :b))
(def normal-fn-xyntax [map]
   (let [a (:a map) b (:b map)]
      (assoc map :c (* a b))))
;;               given   required
(def calculation (create-calculation [:a :b] [:c]))

Schpaa14:03:36

Any firebase users here? How do I convert a Timestamp to a date in cljs?

Schpaa15:03:46

(.fromDate js/firebase.firestore.Timestamp (js/Date.))

👍 4
Schpaa15:03:52

that was the right answer

Schpaa15:03:00

already use cljs-time

Michaël Salihi15:03:39

OK I see, in pure JS interop for Firebase.

Drew Verlee18:03:57

is there a thing about shadowing js names? e.g fetch vs js/fetch? Is there a reason this should result in a infinite loop? (let [fetch (fn [] (js/fetch ...))] (fetch))

thheller18:03:18

@drewverlee js/ is special and doesn't shadow anything, so its not protected

Drew Verlee18:03:11

shadowed probably isnt the right word. When you say its not protected what does that mean?

thheller19:03:08

I don't know the right word either

thheller19:03:39

normally the compiler ensures it doesn't produce invalid code but js/ doesn't and may end up creating broken code

p-himik19:03:41

Huh. Can optimizations end up creating a local symbol that shadows a global JS variable, so that something like js/Gx ends up pointing to the local symbol?

Drew Verlee19:03:54

@U2FRKM4TW i assume thats whats happening here.

p-himik19:03:51

@drewverlee Definitely not your case because js/fetch won't be changed by the compiler.

p-himik19:03:27

What I meant is:

// some_file.js
window.Gx = 42

;; some_file.cljs
(let [my-var 1]
  (js/console.log (+ my-var js/Gx)))
In this case, GCC might decide to rename my-var to Gx just as a step in the advanced optimizations. If that's the case, I can end up getting 2 instead of 43 as the result.

Drew Verlee19:03:30

@U2FRKM4TW ah. Then why do you think js/fetch seems to call fetch in the example code i linked. I didnt try that snippet per say, but thats whats happening in the slightly more complex function i modified.

lilactown20:03:03

@U2FRKM4TW yes this is why externs is important for external JS

lilactown20:03:59

@drewverlee it sounds like CLJS-generated code at dev time is shadowing the fetch var

lilactown20:03:24

I put this code into https://app.klipse.tech

(let [foo 1]
  (prn js/foo))
and it emitted:
var foo_22 = (1);
cljs.core.prn.call(null,foo_22);

lilactown20:03:07

I also get this warning: WARNING: js/foo is shadowed by a local at line 2

Drew Verlee20:03:59

intresting. i might have been looking past that warning because the exception was more in my face.

lilactown20:03:36

the warning is in the compiler, not the runtime

p-himik08:03:35

@U4YGF4NGM That was not meant to be an external JS file. And would externs prevent my-var from being renamed to Gx?

thheller08:03:36

externs basically tell the compiler to not use those names and not rename those that use it. so yeah externs for Gx would make closure never use that name and never change it.

p-himik09:03:09

Nice, thanks. And it doesn't matter whether the JS code comes from NPM or from within my own sources directory, right? Still, feels strange that one would have to write externs for something as explicit as a symbol prefixed by js/.

p-himik09:03:33

Or am I wrong, and using js/ does auto infer externs, and that's exactly why that example with fetch is not working, because the CLJS local was not renamed as well?

thheller09:03:01

in shadow-cljs using js/ automatically adds externs for it

👍 4
sova-soars-the-sora19:03:59

So i want to make a bookmarking js for these lesson pages, I think saving the page is easy but saving the precise location on the page is a question mark. What would be a good strategy, would it be legit to somehow save the node's location in the dom tree and then scroll to that somehow?

Lu19:03:42

You generally want to do that with anchor links

sova-soars-the-sora19:03:24

@lucio Aha. Hmm. Like put anchor links in the page and just reference the anchor ?

Lu08:03:59

Yes. It saves you the trouble of having to manually scroll to different points on the page.

sova-soars-the-sora19:03:27

This is a good idea, can i extract the container anchor element on click?

Lu08:03:29

Yes, you can simply look at the href attribute of the clicked a tag node

Lu08:03:56

(-> (js/document.getElemenentById “foo”) .-href)

Lu08:03:01

This gives you the full url + anchor .. if you just want the anchor you need to call (.getAttribute (js/...) “href”)

Lu08:03:20

Or if it’s on click you can get there by using your event target rather than starting from js/document

lilactown20:03:24

I put this code into https://app.klipse.tech

(let [foo 1]
  (prn js/foo))
and it emitted:
var foo_22 = (1);
cljs.core.prn.call(null,foo_22);

lilactown20:03:07

I also get this warning: WARNING: js/foo is shadowed by a local at line 2

Ben Hammond22:03:31

I see Circular dependence detected when trying to build a cljs project

Analyzing resources/public/example-out/cljs/core.cljc
Unexpected error (AssertionError) compiling at (REPL:1).
Assert failed: Circular dependency detected, cljs.core -> cljs.core
(every? (fn* [p1__2062#] (not (contains? *cljs-dep-set* p1__2062#))) deps)
I can also see https://github.com/clojure/clojurescript/blob/ccdc896e1e567c746f42ca760e7d8e843668aaba/src/main/clojure/cljs/core.cljc#L49
(ns cljs.core
...
  #?(:cljs (:require-macros [cljs.core :as core]
which, naively does indeed look like a circular dependency I'm running
user=> *clojure-version*
{:major 1, :minor 10, :incremental 1, :qualifier nil}
on openjdk 11.0.6 2020-01-14 and I cannot explain this; I kind of expect macros to always be in a .clj and to be (:require-macros d from a .cljs and this world of shoe-horning everything into a single .cljc confuses me. Am I barking up the wrong tree? What else could be causing my circular dependency?

ingesol09:03:34

Requiring the corresponding clj macros ns from a cljs ns is a nice trick that enables all users of that ns to get access to macros without having to do refer-macros . So there’s nothing wrong with this one.

p-himik09:03:55

@U21QNFC5C It's in a cljc file though. There's no other core file. Does the same still apply in this case?

p-himik09:03:37

Searched for a bit - apparently, it at least was necessary, and potentially one of the compiler's updates have made that obsolete.

p-himik09:03:42

@U793EL04V Why do you have the cljs/core.cljc file in resources/public/example-out? It looks like it was put there by some compilation step, and that that dir is on the classpath at the same time.

ingesol09:03:03

@U2FRKM4TW Hm, so you’re saying we can now write cljs code with macros in cljc, and not have to do refer-macros from code using that ns?

Ben Hammond09:03:33

its part of someone else figwheel project that I'm trying to run the demo for

p-himik09:03:44

@U21QNFC5C No. I'm saying that if you use just a single cljc file for both CLJ and CLJS code, then require-macros is not needed, maybe.

Ben Hammond09:03:14

I know the self-hosting macros code has been in cljs.core for several years, so it must be fine most of the time

p-himik09:03:29

@U793EL04V Do you have a link? If not, can you try to exclude that directory from the classpath or at least make sure core.cljc does not end in there?

Ben Hammond09:03:31

so this is the main project https://github.com/roman01la/uix/blob/f8e8302bc460ba76fb1db648b4f6ece013fedb5e/core/deps.edn I am trying to run clj -A:dev:example from the uix/core directory

Ben Hammond09:03:16

I'm sure it must be something wonky in my local setup

p-himik09:03:47

Seems like it - that command worked fine for me.

p-himik09:03:36

Maybe you have something in your ~/.clojure/deps.edn?

p-himik09:03:29

Ah, wait. I just reproduced the issue. It was the second time running that command that set it off.

p-himik09:03:05

There's something strange going on. The target directory is on the classpath; the uix/core is being checked out from Git as part of the building process of... uix/core.

p-himik09:03:42

I would definitely file an issue or two. :)

Roman Liutikov11:03:39

that example build build self-hosting cljs, might be something there @U793EL04V is this piece of code important for you to get running? I don't remember if it even works

Ben Hammond11:03:27

no its not important to me

Ben Hammond11:03:47

I'm just in a discovery phase where I'm asking > why? about everything

Ben Hammond11:03:54

and I realised that what I actually wanted to run was

clj -A:dev:rec-front
and that worked fine

Roman Liutikov11:03:08

I'd also clean build artifacts before running another build, to avoid issues with cache