clojurescript

martinklepsch 2025-03-25T18:56:16.994709Z

I feel like I should know this but how do I port sth like this to ClojureScript?

p-himik 2025-03-25T18:59:11.400379Z

Do you need for it to also be importable from JS? In other words, do those export also have to be implemented in CLJS? If no, does any of it have to be used from JS? Or is it CLJS-usage only?

martinklepsch 2025-03-25T18:59:27.242319Z

don't need the export

martinklepsch 2025-03-25T18:59:49.046449Z

more just not quite getting a hang of the prototype / this stuff

p-himik 2025-03-25T19:00:59.422439Z

Treat prototype as a plain property, because it essentially is.

(set! (.-prototype Step)
      #js {:areaStart (fn []
                        (this-as this
                          (set! (.-_line this) 0)))
           ...})

p-himik 2025-03-25T19:02:11.543029Z

If you use shadow-cljs, you can also require [shadow.cljs.modern :refer [defclass]] and then

(defclass Step
  (constructor [context t] ...)
  (areaStart [this] ...)
  ...)

p-himik 2025-03-25T19:02:59.730319Z

(I think it will result in functionally the same code. But it will be compiled to a class in JS.)

thheller 2025-03-25T19:03:10.625919Z

(defclass Step
  (field _context)
  (field _t)
  (field _line js/NaN)
  (constructor [this context t]
    (set! _context context)
    (set! _t t))

  Object
  (areaStart [this]
    (set! _line 0))

  (areaEnd [this]
    (set! _line js/NaN))

  ...)

thheller 2025-03-25T19:03:28.848669Z

yeah, functionality is the same. defclass is only available in shadow-cljs though.

martinklepsch 2025-03-25T19:11:37.253299Z

sweet, I think that'll work for me!

martinklepsch 2025-03-25T19:36:29.524869Z

The prototype stuff I sort of understood but I guess it wasn't entirely clear to me how to inject the initial variables into the function. This worked:

martinklepsch 2025-03-27T12:40:59.732019Z

This sort of inspired a blogpost: https://martinklepsch.org/posts/embracing-js-files-in-clojurescript/

👍 1
thheller 2025-03-27T12:48:02.820489Z

> “Leaf nodes” only, meaning you can’t require CLJS from JS and things like that. (Fine for my use cases.)

thheller 2025-03-27T12:48:25.258419Z

import { foo } from "goog:a.cljs.namespace"; gives you a.cljs.namespace/foo

thheller 2025-03-27T12:49:30.945359Z

danger with this is that there is no externs inference done for JS files, so if you do interop with "foreign" code it this it might require manual externs

thheller 2025-03-27T12:50:34.869189Z

otherwise this is exactly what I wrote this feature for. nice post.

❤️ 1
martinklepsch 2025-03-27T12:56:52.032309Z

I half assumed you’d know a way to require both directions 😀

thheller 2025-03-27T12:58:37.518809Z

haven't used it in a long time, so I hope its not broken 😛