cherry

2024-08-29T16:08:33.559949Z

Does Cherry support the #html [:div "xxx"] syntax of squint? I'm getting Error: No reader function for tag html.

borkdude 2024-08-29T16:09:25.210479Z

Apparently not yet... issue welcome

👍 1
2024-08-29T19:05:36.280949Z

Can I use defclass from a macro?

(defmacro create-class [class-name] `(defclass ~class-name))                                            

(create-class MyTestClass)
This never creates a class, but rather produces this code:
var create_class = (function (_AMPERSAND_form, _AMPERSAND_env, class_name) {
return cherry_core.sequence.call(null, cherry_core.seq.call(null, cherry_core.concat.call(null, cherry_core.list.call(null, cherry_core.symbol.call(null, "defclass")), cherry_core.list.call(null, class_name))));
});
create_class.call(null, MyTestClass);
Beyond the minimalistic example provided above, my use-case are web components which always have the same definition, all that changes is the render fn, so I'd like to reduce the boilerplate.

2024-08-31T13:48:35.954639Z

No worries, take your time.

borkdude 2024-09-12T07:27:20.892439Z

Thanks for the reminder. Other issues got in the way, sorry. Issue welcome.

borkdude 2024-09-12T07:27:32.200419Z

I might have some time today, hopefully

borkdude 2024-09-12T09:36:55.443949Z

I'm on it now

borkdude 2024-09-12T11:14:13.359979Z

have it working, but need to improve/clean up a little

2024-09-12T12:12:13.594989Z

Thank you very much @borkdude 🙏 It's really appreciated.

borkdude 2024-09-12T12:18:20.685049Z

released in 0.3.20

2024-09-12T12:18:45.708429Z

Thank you. I will check later today, I'm just waking up.

2024-09-12T23:57:17.649289Z

@borkdude oh this is the hiccup. Nice!!! Thank you 🙏

2024-09-12T23:58:05.124459Z

This thread was actually about the macros though. I haven't reported it as an issue (just made the repro you asked for, see above). Do you want me to create an issue with the repro link in it?

2024-09-12T23:59:14.767129Z

But I'm definitely going to use the #html literal, it was me who reported that as you know so I'm very happy about that.

2024-09-13T00:56:10.169829Z

I can confirm it works like a charm, yay!

borkdude 2024-09-13T06:18:08.669039Z

Issue please

borkdude 2024-09-13T12:17:32.748759Z

I'll check out the repro repository now, sorry I fixed the wrong issue :)

borkdude 2024-09-13T13:44:15.178639Z

@jakub.stastny.pt_serv ok, now you should be able to write the macro as:

(ns macros)

(defmacro create-class [class-name & args]
  `(cherry.core/defclass ~class-name ~@args))

borkdude 2024-09-13T13:44:23.304839Z

with 0.3.22

2024-09-13T13:50:59.695779Z

Thank you @borkdude, will check it out shortly.

borkdude 2024-09-13T13:51:59.561469Z

Btw, I wonder if you could have also solved this without a macro using extends or so

2024-09-13T13:54:01.264069Z

It'd be slightly more verbose I think, it'd be class, extends and then WebComponents.define or what's the thing that registers it.

2024-09-13T13:57:11.471379Z

By the way the log message shows squint now rather than cherry:

$ npx cherry compile src/lib/macros.cljs
[squint] Compiling CLJS file: src/lib/macros.cljs

borkdude 2024-09-13T14:10:26.271529Z

lol, let me fix that

borkdude 2024-09-13T14:11:28.185609Z

fixed on cherry main

👍 1
2024-09-13T14:11:36.506069Z

@borkdude I'm having issues with this one actually. So I'm in the repro repository and I have this:

(ns my-footer
  (:require-macros [foo.macros :refer [create-class]]))
The file src/foo/macros.cljs is there with (ns foo.macros definition. Yet it doesn't work.

borkdude 2024-09-13T14:12:06.699509Z

in the repro repository you only had [macros :refer ...] right?

borkdude 2024-09-13T14:12:13.011699Z

or did you update the repro?

2024-09-13T14:13:08.766519Z

Let me check, I thought this is how it was but let me see.

2024-09-13T14:17:18.162829Z

You're right, but even there I'm getting the same issue.

npx cherry compile src/components/my-footer.cljs
[squint] Compiling CLJS file: src/components/my-footer.cljs

node:internal/process/promises:288
            triggerUncaughtException(err, true /* fromPromise */);
            ^
Error: The "path" argument must be of type string or an instance of Buffer or URL. Received null
This happens on the require-macros line.

2024-09-13T14:18:21.871079Z

Even if the macros file is empty (beyond ns declaration), it still fails. It looks like it cannot find the file at all.

borkdude 2024-09-13T14:18:39.844839Z

lemme try again locally

borkdude 2024-09-13T14:21:17.569509Z

you shouldn't add this to your macro namespace:

(:require [cherry.core :refer [defclass]])

borkdude 2024-09-13T14:21:35.177619Z

instead, write this:

(ns macros)

(defmacro create-class [class-name]
  `(cherry.core/defclass ~class-name))

borkdude 2024-09-13T14:22:19.615289Z

note that the output will still fail due to the absence of a constructor in the defclass

2024-09-13T14:23:17.534709Z

Right!

2024-09-13T14:23:30.229609Z

OK now it compiles, will try on the main project whether it works.

borkdude 2024-09-13T14:28:03.311999Z

you can now also print from the cherry macros

borkdude 2024-09-13T14:28:07.078309Z

which wasn't possible before

borkdude 2024-09-13T14:28:15.720209Z

so if you want to inspect the macro expansion, you can print it before returning it

borkdude 2024-09-13T14:28:48.592729Z

also js interop is possible, so js/console.log etc

2024-09-13T14:42:23.484469Z

Cool!

2024-09-13T15:00:44.295069Z

@borkdude some of the serialisation in macros is broken, it gives me this$.attachShadow([object Object]):

class MyFooter extends HTMLElement {
  constructor() {
super();const self__ = this;
const this$ = this;
this$.attachShadow([object Object])  }
connectedCallback() {
const this$ = this;
const self__ = this;return render.call(null, this$.shadowRoot);
}};
customElements.define("my-footer", MyFooter);
The macro:
(defmacro component [class-name element-name render-fn]
  `(do
     (cherry.core/defclass ~class-name
       (~'extends js/HTMLElement)
       (~'constructor [~'this]
         (~'super)
         (.attachShadow ~'this #js {"mode" "open"}))
       ~'Object
       (~'connectedCallback [~'this]
         (~render-fn (.-shadowRoot ~'this))))
     (js/customElements.define ~element-name ~class-name)))
I will see if I can come up with a workaround and once I'm more familiar with the issue, I will report it to GH issues.

borkdude 2024-09-13T15:02:05.667019Z

you need to quote this: js/HTMLElement

borkdude 2024-09-13T15:02:25.970289Z

no sorry, it's already in syntax-quote

borkdude 2024-09-13T15:02:41.345699Z

what does the macro-expansion look like. before posting an issue, let's just check first if there's nothing wrong here

borkdude 2024-09-13T15:03:15.249539Z

This won't work: #js {"mode" "open"}

2024-09-13T15:03:56.131369Z

That's exactly the problematic line, yes.

borkdude 2024-09-13T15:04:31.337469Z

you can't emit a JS object from a macro, probably best to write (js-obj "mode" "open")

👍 1
2024-09-13T15:06:44.085069Z

OK now it all works. Cool!

👍 1
borkdude 2024-08-30T21:44:56.708299Z

got a little busy, won't be able to check this this weekend, hopefully next week

👍 1
2024-09-12T01:28:12.861499Z

@borkdude Sorry to bother you about this, but is there any update? If it's on the back-burner now, let me know and I will create an issue from the repro so it gets done eventually. In the end I could use Squint for now (although I have to say I very much prefer Cherry).

borkdude 2024-08-29T19:06:56.669829Z

You can't define macros in the same file as cherry code, they have to live in a separate file. Also you need to fully qualify the defclass symbol yourself since it's not a normal symbol that is available in clojure

🙏 1
borkdude 2024-08-29T19:08:01.410149Z

similar as described here: https://github.com/squint-cljs/squint?tab=readme-ov-file#macros

borkdude 2024-08-29T19:08:36.813059Z

squint.edn doesn't exist for cherry though, but the src folder is used by default I believe

2024-08-29T19:09:20.226559Z

Thank you.

borkdude 2024-08-29T19:09:30.335779Z

so just put a src/foo/macros.cljs file in your project

borkdude 2024-08-29T19:10:14.024859Z

then (:require-macros [foo.macros :as m]) or so

2024-08-29T19:24:08.371489Z

@borkdude Also you need to fully qualify the defclass symbol yourself since it's not a normal symbol that is available in clojure This bit I'm not sure about. I had this:

;; src/macros.cljs
(ns macros (:require [cherry.core :refer [defclass]]))

(defmacro create-class [class-name]
  `(defclass ~class-name))
Upon reading about the fully qualified symbol, I changed it to this:
;; src/macros.cljs
(ns macros)

(defmacro create-class [class-name]
  `(cherry.core/defclass ~class-name))
But neither of these work (wouldn't compile with Error: Nothing specified to load).

borkdude 2024-08-29T19:25:50.586349Z

is it possible to make a repro of this? I'll take a look tomorrow

2024-08-29T19:26:02.832879Z

Sure.

2024-08-29T19:26:21.631829Z

Thanks. I'll do it later, will post an issue here.

borkdude 2024-08-29T21:03:58.198809Z

cool, I'll check tomorrow