Fork me on GitHub
#clojure-uk
<
2021-08-05
>
dharrigan05:08:34

Good Morning!

thomas07:08:41

mogge 😼

Ben Hammond16:08:59

email from a recruiter > This is a FULLY REMOTE, offering the suitable Java Developer to work a mix of two days in the office and three from home, therefore you must live within a commutable distance to Milton Keynes. Since when did fully remote morph into Half the week in the office ?

Ben Hammond16:08:38

oh I know, these are seperate layers of management arent they

Ben Hammond16:08:53

the actual team say Fully remote

Ben Hammond16:08:08

but HR says "not on your nelly"

Ben Hammond16:08:42

and the recruiter doesn't care and just quotes verbatim

dharrigan19:08:02

That's a bizarre email

thomas08:08:48

I think they try to convey the office culture in this email and make clear that they actually have no sense what they are doing. :thinking_face:

danm11:08:17

The team are fully remote from all the systems, which are in the cloud. Therefore it is a remote role that you can do from anywhere. But we still expect you to come into the office 😉

Ben Hammond17:08:50

Clojurescript syntax - I wish to invoke a function that is declared in an external library. I am using shadow-cljs so I have

(:require ["@emotion/css" :as emotion]
            ))
...
           (.log js/console "Example i)")
           (js/console.log emotion)
           (.log js/console "Example ii)")
           (js/console.log (.-css emotion))
           (.log js/console "Example iii)")
           (js/console.log (. emotion -css))
           (.log js/console "Example iv)")
           (js/console.log js/emotion.css)
           (.log js/console "Example v)")
           (js/console.log emotion.css)
and I see that examples iv) and v) do not work and I am not sure why... does that dot notation only work on the first item in the s-expression?

Ben Hammond17:08:25

If I rewrite the first 2 lines as

(.log js/console "Example i)")
           (js/console.log js/emotion)
then I get
main.js:1552 ReferenceError: emotion is not defined
which also surprises me.... Is that a shadow-cljs thing?

Ben Hammond17:08:12

I can invoke that function like

((.-css emotion) (clj->js css))
but that seems bonkers. Clearly I must be doing something wrong

Ben Hammond17:08:18

I'm also importing a bunch of material-ui libraries that seem much easier to use

Ben Hammond17:08:28

perhaps its an end of the day thing...

Ben Hammond17:08:16

oh I think (:require ["@emotion/css" :as emotion] may be occluding the js/emotion? is that possible?

Ben Hammond17:08:13

nah changing the name of the alias doesnt seem to make any difference

Ed17:08:29

sorry ... I'm very rusty with npm/cljs, but isn't require ["@emotion/css" :as emotion] equivalent to import emotion from '@emotion/css' in js? ... so wouldn't import { css, cx } from '@emotion/css' mean that after the require you'd have an emotion/css function available in your namespace?

Ben Hammond18:08:42

Well that is what I was hoping

Ben Hammond18:08:04

But cannot seem to get working as (emotion/css ...)

Ben Hammond18:08:41

Only as ((.-css emotion) ...)

Ben Hammond18:08:11

Which seems a bit weird

dominicm19:08:44

Couple thoughts here. iv/v don't work because: js/emotion.css is referring to the "global" (which is window in your case most likely) meaning you're actually doing window.emotion.css which probably doesn't exist unless you've injected it there. Not in actuality, but that's the mental model for it you should have. emotion.css doesn't work for the same reason it doesn't in Clojure.

dominicm19:08:11

Lemme read the docs on @emotion/css and get back to you on what you need to do to get this working.

dominicm19:08:03

https://github.com/emotion-js/emotion/blob/main/packages/css/src/index.js looking at this, and at the emotion quickstart, you're doing the right thing as there's no default export

dominicm19:08:54

(emotion/css #js {}) works for me with ClojureScript 844. Are you on the latest version of everything @U793EL04V?

3
👍 3
dominicm19:08:30

And, have you refreshed the page with your devtools open & cache disabled?

dominicm19:08:55

(fwiw, I'm not using shadow so this could be a shadow bug. I know how to get npm+cljs up quicker w/o shadow than with.)

Ben Hammond19:08:41

(emotion/css #js {}) works for me as well now you mention it ...

Ben Hammond19:08:07

perhaps this is my confusion... when to use slash and when to use dot

Ben Hammond19:08:36

emotion is a JS Object that looks like it has css as a member function

Ben Hammond19:08:45

so... why would (emotion/css work and (emotion.css` not work

dominicm19:08:52

If you require then you should use /

dominicm19:08:57

Like any namespace.

dominicm19:08:31

Well, for the same reason in clj this doesn't work:

(ns foo (require [clojure.core :as c]))

(c.inc 1)
It's not valid clojure!

Ben Hammond19:08:35

and why does js/emotion not work at all? because I required?

dominicm19:08:52

js/ looks in the "global" space, which for browsers is the window object.

dominicm19:08:05

It's not local to the namespace (with your requires)

dominicm19:08:18

js/ is a magical place, really.

Ben Hammond19:08:53

but (js/console.log is dot notation

Ben Hammond19:08:08

does the dot notation only work with js/ ?

dominicm19:08:06

Yep! js/ is magical

dominicm19:08:26

Actually, I lied 😄

Ben Hammond19:08:27

so if I didn't do the

["@emotion/css" :as emotion]
would I be able to access the emotion/css using js/?

Ben Hammond19:08:50

because it would need two slashs?

dominicm19:08:51

emotion/css.prototype returns something, so . is just a weird cljs-ism, but it has to follow a namespace alias.

dominicm19:08:35

When you do a require, ClojureScript checks the node_modules folder, and if it's present there it does some magic and makes it available to you in the current namespace. Unless it can statically analyze to know ahead of time to do that, it can't load the namespace.

dominicm19:08:52

Actually, the static part of that isn't required.

dominicm19:08:07

It's like in Clojure, how you can't use a namespace until you've done a require somewhere. Except way more strict.

Ben Hammond19:08:10

but when I do have a namespace alias, I cannot use the dot

dominicm19:08:23

The clojurescript dot stuff has to come after a /

Ben Hammond19:08:23

and I cannot use js/ neither

dominicm19:08:50

js/ is not going to work for you here. That's a shorthand for accessing the global object.

dominicm19:08:11

What's the JVM equivalent of the global object :thinking_face: I guess there isn't one.

Ben Hammond19:08:35

not in the same way

dominicm19:08:37

js/ isn't for "javascript interop" exactly. It isn't aware of your namespace alias scope at all.

Ben Hammond19:08:46

because the browser is all about building one page

dominicm19:08:52

So it runs in a different scope.

dominicm19:08:42

You can technically get at it by doing something horrible like js/my.current.ns.node$module$circa$emotion$css.css but I wouldn't recommend that.

Ben Hammond19:08:08

you answered my question so thankyou very much

dominicm19:08:37

OK 😄 Sorry I don't know how to more clearly explain the js/ thing.

Ben Hammond19:08:11

I had a sort of an idea that all js libraries that were imported were available globally

dominicm19:08:27

Ah, that's incorrect. They get locally assigned.

dominicm19:08:34

I think cljsjs worked like that.

dominicm19:08:04

cljsjs basically did window.emotion = require('@emotion/css') and then ran it through webpack and included that in your javascript build.

dominicm19:08:20

I see where the confusion came from now 😄

Ben Hammond19:08:45

I never understood why cljsjs seemed so magical

Ben Hammond19:08:51

never trusted it really

Ben Hammond20:08:26

thanks that is really helpful