Fork me on GitHub
#clojurescript
<
2023-12-03
>
p-himik11:12:35

Hasn't happened yet, yes. However, if you're using shadow-cljs then you can use shadow.cljs.modern/defclass.

Pepijn de Vos11:12:27

I am but have since learned that for a typescript "implements" I don't actually need a subclass and in that case deftype probably works fine

wei02:12:13

what's the recommended way to translate something like this to cljs? it's consumed by a JS library so it has to work the same way. would deftype still work?

import { ParagraphNode } from "lexical";

export class CustomParagraphNode extends ParagraphNode {
  static getType() {
    return "custom-paragraph";
  }

  static clone(node) {
    return new CustomParagraphNode(node.__key);
  }

  createDOM(config) {
    const dom = super.createDOM(config);
    dom.style = "background: green";
    return dom;
  }
}
context: https://codesandbox.io/p/sandbox/ecstatic-maxwell-kw5utu?file=%2Fsrc%2Fnodes%2FCustomParagraphNode.js%3A10%2C4

wei02:12:13

I tried to follow this example: https://stackoverflow.com/questions/61891349/implementing-static-properties-in-clojurescript but got lost in the details (e.g. not sure how to translate super.createDOM(config)). i also looked at shadow.cljs.modern/defclass but it doesn't seem to support static methods

thheller08:12:12

static methods can just be added outside the defclass, they are nothing special. the issue is that super isn't supported currently https://github.com/thheller/shadow-cljs/issues/1137

🙏 1
thheller08:12:46

FWIW for static just (set! CustomParagraphNode -clone (fn [node] ....))

👍 1
thheller08:12:20

Same as writing CustomParagraphNode.clone = function(node) { ... }; in JS, not much different to just static

p-himik08:12:15

How would that work if something extends CustomParagraphNode and tries to call clone on the extending class?

thheller08:12:53

hmm? they are given CustomParagraphNode as thing and call thing.clone(whatever)?

p-himik08:12:14

I mean if they're given class X extends CustomParagraphNode and then something calls X.clone. But I just tested - seems to be working fine:

class A {}
A.f = () => { console.log('f'); }

class B extends A {}
B.f()
=> f

thheller08:12:49

of course, why wouldn't it 😛

p-himik08:12:23

I'm no exposed to JS that much, so seeing something being called from an inherited class but without prototype feels wrong. :)

thheller08:12:38

the only different is that this is in the scope of that function, which you could achieve via bind if needed

thheller08:12:07

well thats the point. static puts its on the class, not its prototype

👍 1
wei00:12:49

Thanks for this, and it looks like there's a workaround for super too, although it emits an inference warning. Is there a good way to suppress the warning?

thheller07:12:05

what is the workaround? I haven't found any yet?

wei10:12:41

You mentioned it in the GitHub issue:

(.. A -prototype -whatever (call this a b))

wei13:01:56

actually i take that back. as far as i understand there's no workaround for calling the super constructor. am i stuck implementing this in JS?

p-himik13:01:09

shadow.cljs.modern/defclass does support super, I'm pretty sure, but specifically only for constructurs.

👀 1
thheller13:01:25

yeah no clue how to get the super equivalent, kinda hard to search for. It is probably possible, I just haven't found it

wei14:01:04

@U2FRKM4TW i see! does it support multiple arity?

thheller14:01:38

you don't want to use it in the constructor, at least the example above doesn't. so what he said doesn't matter

wei14:01:55

the example doesn't define a constructor, but looks like i need to define a constructor using defclass, otherwise i get

AssertionError: Assert failed: contructor requires at least one argument name for this

thheller14:01:44

you can just add an empty constructor

thheller14:01:54

(defclass Foo (constructor [this] (super)))

👍 1
wei14:01:17

the example calls the constructor with an argument:

CustomParagraphNode(node.__key);
which makes me think it's inheriting a multiple-arity constructor from its parent class (TBH I'm pretty fuzzy on JS class mechanics)

thheller14:01:20

pretty sure it just inherits the extended constructor

thheller14:01:40

(defclass Foo (constructor [this key] (super key)))

wei14:01:54

gotcha, thanks

thheller14:01:16

I guess I could make constructor optional. I just never had the case where I didn't want a constructor myself

wei14:01:08

no worries it was more a JS confusion. i got tripped up because there were other callsites where the same example constructor is called with no arguments. your answer helped me realize that it's legal in JS and it's just undefined.

wei14:01:09

also for posterity I needed to add :compiler-options {:output-feature-set :es6} to shadow-cljs.edn otherwise i got all sorts of errors nvmd

thheller14:01:36

for example? :es6 is downgrading the default, so not sure what that would help?

wei14:01:42

ah, i must have made other changes. i got it from this article https://clojureverse.org/t/modern-js-with-cljs-class-and-template-literals/7450 but it's outdated

thheller15:01:10

yeah that default has been bumped a while ago

stagmoose12:12:55

I was watching https://youtu.be/w5CCZQBNFSc?feature=shared&amp;t=1453 and I am blown away by the usage of $0 in the video (I have linked to the exact moment of the video) to gain access to an obj could anyone explain what does $0 meaning, like something like *1 in the repl?

p-himik12:12:21

> Published on Friday, March 22, 2019 • Updated on Wednesday, April 22, 2015 Heh, bloody time travelers.

😆 1
stagmoose12:12:52

wow this trick is so cool! thanks for your quick reply~

👍 1
wei02:12:13

what's the recommended way to translate something like this to cljs? it's consumed by a JS library so it has to work the same way. would deftype still work?

import { ParagraphNode } from "lexical";

export class CustomParagraphNode extends ParagraphNode {
  static getType() {
    return "custom-paragraph";
  }

  static clone(node) {
    return new CustomParagraphNode(node.__key);
  }

  createDOM(config) {
    const dom = super.createDOM(config);
    dom.style = "background: green";
    return dom;
  }
}
context: https://codesandbox.io/p/sandbox/ecstatic-maxwell-kw5utu?file=%2Fsrc%2Fnodes%2FCustomParagraphNode.js%3A10%2C4