Fork me on GitHub
#babashka
<
2022-07-24
>
pinkfrog11:07:18

Does clj-kondo work with .cljc file? Given

(defn epoch-ms
  "Returns ms from epoch."
  []
  (System/currentTimeMillis))
I got

pinkfrog11:07:03

And for

(defmethod print-method Duration
  [v ^java.io.Writer w]
  (.write w (str "#-duration \"" (subs (str v) 2) "\"")))
I have . This only happens for .cljc

borkdude11:07:48

Is this related to making a .cljc file bb compatible?

borkdude11:07:50

In that case you can use: {:cljc {:features #{:clj}}} ^ @UGC0NEP4Y

borkdude11:07:01

Then it will not lint the .cljc file for ClojureScript

pinkfrog11:07:00

> Is this related to making a .cljc file bb compatible? Yes!

pinkfrog11:07:58

Where shall I put the above in the file?

borkdude11:07:09

in .clj-kondo/config.edn

pinkfrog11:07:24

I’d like to limit the only to a certainf ile

borkdude11:07:34

Maybe this macro is a better solution and just use a .clj file:

(defmacro if-bb [then else]
  (if (System/getProperty "babashka.version") then else))

👍 1
pinkfrog12:07:30

Given code

(when-not (System/getProperty "babashka.version")
  (extend-protocol clojure.core/Inst
    Duration
    (inst-ms* [v] (.toMillis ^Duration v))
I got the following error:
Type:     java.lang.NullPointerException
Location: /Users/pinkfrog/clj/src/dev/clj/time.clj:82:3
Phase:    macroexpand

----- Context ------------------------------------------------------------------
78:     ZonedDateTime
79:     (inst-ms* [v] (.toEpochMilli (.toInstant ^ZonedDateTime v)))))
80:
81: (when-not (System/getProperty "babashka.version")
82:   (extend-protocol clojure.core/Inst
      ^---
83:     Duration
84:     (inst-ms* [v] (.toMillis ^Duration v))
85:     OffsetDateTime
86:     (inst-ms* [v] (.toEpochMilli (.toInstant ^OffsetDateTime v)))
87:     ZonedDateTime

----- Stack trace --------------------------------------------------------------
clojure.core/deref-future                 - <built-in>
clojure.core/deref                        - <built-in>
clojure.core/extend-protocol              - <built-in>

pinkfrog12:07:05

Note that I didn’t use the if-bb macro since I don’t want to create an extra abstraction.

pinkfrog12:07:15

I use (when-not) directly.

borkdude13:07:44

This doesn't work, you'll need the macro :)

pinkfrog15:07:26

if-bb does work. But I wonder what makes the difference. So in the case of if-bb, isn’t the compiler expanding the extend-protocol macro?

borkdude15:07:53

yes, that's why it works

pinkfrog15:07:16

you mean expand or not?

borkdude15:07:53

it's not expanded if it's not in bb

pinkfrog15:07:24

But why my

1: (when-not (System/getProperty "babashka.version")
82:   (extend-protocol clojure.core/Inst
above gets expanded?

borkdude15:07:48

because extend-protocol is a macro with side effects

borkdude15:07:39

or another way to put it: you will preserve the reference to the clojure.core/Inst symbol in the generated code, which will then fail

pinkfrog15:07:00

Sorry I haven’t fully caught it. My understanding is, I have the when-not to guard against expanding the extend-protocol in bb. But bb errs still. I wonder what happens. It seems to me extend-protocol is expanded regardless the when-not clause.

borkdude15:07:24

when-not doesn't guard expansion

borkdude15:07:48

Try:

(when (pos? -12) THIS_DOESNT_EXIST 3)

pinkfrog15:07:32

user=> (when (pos? -12) THIS_DOESNT_EXIST 3)
Could not resolve symbol: THIS_DOESNT_EXIST [at <repl>]
What do you want to convey?

borkdude15:07:58

That when or when-not does not prevent you from expanding anything

pinkfrog15:07:03

How do you conclude that from the above example?

borkdude15:07:03

well, the most simple expansion is the identity function

pinkfrog16:07:43

I made a simple example.

(defmacro m1
  [expr]
  (println expr))
(defmacro m2
  [v]
  nil)

;; prints ((m2 4))
;; so `m2` is NOT expanded when calling m1.
(m1 ((m2 4)))

borkdude16:07:27

Macros don't expand their arguments but what they return will be expanded

borkdude16:07:49

And since m1 returns nil, there will be no further expansion

borkdude16:07:15

But when always preserves what you feed as arguments in the expansion

borkdude16:07:33

It doesn't strip anything away at compile time

pinkfrog16:07:59

> Macros don’t expand their arguments but what they return will be expanded That’s my understanding. And that’s why I am confused why extend-protocol is expanded. It is any argument to when-not and due to the condition, the extend-protocol shall not be entered.

borkdude16:07:07

That's not how it works :) Try (macroexpand '(when false 1 2))

borkdude16:07:25

This expands into:

(if false (do 1 2))

borkdude16:07:29

And this has no further expansion

borkdude16:07:53

If you write (when false (extend-type ...)) it expands into (if false (extend-type ..))

borkdude16:07:06

but these symbols in the else branch will still be resolved by the compiler

pinkfrog16:07:11

Thanks. I got it.

pinkfrog16:07:55

btw, when we say compiling. The output is a java class file right? And somehow the clojure, through some jvm mechanims, can load and execute that class fiel?

borkdude16:07:32

macroexpansion happens during compilation. Then after there's nothing to expand, the compiler emits bytecode, correct.

borkdude16:07:52

it's not always bytecode on disk, it happens in memory, unless you call compile