sci

borkdude 2022-04-16T08:01:33.745959Z

I found some information here: https://stackoverflow.com/questions/3871731/dynamic-object-construction-in-javascript Looks quite complicated. Is it possible to define the constructor in JS and then bind that to your SCI options?

borkdude 2022-04-16T08:05:48.041329Z

Hmm, wait, this seems to work, like @lilactown said:

user=> (defn foo [] #js {:a (fn [] :hello)})
#'user/foo
user=> (new foo)
#js {:a #object[Function]}

borkdude 2022-04-16T08:08:58.946629Z

> perhaps it only does not work because the function is not exported to js by sci. @hoertlehner you can "export" this function by setting it on the global object:

user=> (set! (.-foo js/globalThis) foo)
nil
user=> js/foo
#object[Function]

awb99 2022-04-16T21:15:55.341569Z

@borkdude. I did execute your example above in sci in the browser. Then I enter the following into the devtools in the browser in Javascript:

var x = new foo()
x.a

awb99 2022-04-16T21:17:30.416349Z

{"meta": null,
  "Ba": 2,
  "qa": [
    {
      "fd": null,
      "name": "line",
      "za": "line",
      "_hash": 212345235,
      "la": 2153775105,
      "sa": 4096
    },
    1,
    {
      "fd": null,
      "name": "column",
      "za": "column",
      "_hash": 2078222095,
      "la": 2153775105,
      "sa": 4096
    },
    22
  ],
  "ea": null,
  "la": 16647951,
  "sa": 139268
}

awb99 2022-04-16T21:18:23.738419Z

When I try to call x.a () I get the following error: Uncaught TypeError: x.a is not a function

borkdude 2022-04-16T21:19:06.270049Z

@hoertlehner This is a Clojure hashmap being printed. Can you make a repro like this in #nbb for example? Which is also a SCI-based Clojure env on JS.

Welcome to nbb v0.3.7!
user=> (defn foo [] #js {:a 1})
#'user/foo
user=> (set! (.-foo js/globalThis) foo))
nil
user=> (js/eval "new foo().a")
1

borkdude 2022-04-16T21:21:15.703269Z

It could also be that you're returning a function which contains metadata. Which version of SCI are you using btw?

borkdude 2022-04-16T21:21:59.585369Z

user=> (defn foo [] #js {:a (fn [] "hello")})
#'user/foo
user=> (set! (.-foo js/globalThis) foo))
nil
user=> (js/eval "new foo().a()")
"hello"

awb99 2022-04-16T21:24:10.611239Z

This is the repro:

(defn afn [] "hello")
(defn foo [] #js {:a afn})
(set! (.-foo js/globalThis) foo)
(js/eval "new foo().a")

awb99 2022-04-16T21:24:19.397069Z

The output of this is "afn"

borkdude 2022-04-16T21:25:14.197029Z

user=> (js/eval "new foo().a")
#object[Function]
user=> (js/eval "new foo().a()")
"hello"

awb99 2022-04-16T21:25:21.956339Z

But since I use this from javascript, it should return a js function

awb99 2022-04-16T21:25:23.207629Z

borkdude/sci {:mvn/version "0.2.7"}

borkdude 2022-04-16T21:25:49.802319Z

you might want to try 0.3.4 or so

borkdude 2022-04-16T21:26:03.453089Z

since I can't repro this with the newest SCI

awb99 2022-04-16T21:26:15.821949Z

ok. great.

awb99 2022-04-16T21:26:22.165539Z

Thanks a lot @borkdude!

awb99 2022-04-16T21:27:03.944909Z

I did believe that I integrated sci quite recently (a few months ago). You are pushing out new versions at an amazing speed!

borkdude 2022-04-16T21:27:31.748669Z

Note that newer versions of SCI are available under org.babashka/sci , no longer under borkdude/sci

borkdude 2022-04-16T21:30:45.440619Z

@hoertlehner Indeed, with 0.2.7 I was able to reproduce your issue, but not with 0.3.4

awb99 2022-04-16T21:40:52.637999Z

Thanks a lot!

lilactown 2022-04-16T02:02:48.914499Z

(defn user-class
  []
  #js {:a (fn [x]) :b (fn [y])})
@hoertlehner JS classes are fundamentally functions that return objects. there might still be some caveats, but try that and see if it works

awb99 2022-04-16T03:35:49.299029Z

Thanks @lilactown unfortunately it does not work. I tried that earlier. But now that you said it .. perhaps it only does not work because the function is not exported to js by sci.

borkdude 2022-04-16T04:22:30.417419Z

SCI function are just normal JS functions unless you attach metadata to them

borkdude 2022-04-16T04:24:08.441799Z

Perhaps you can use js/eval to construct the constructor or js/Reflect

borkdude 2022-04-16T04:32:43.026319Z

Note that hyphens do not work in names in JS. Please be as exact as you possible can and make an exact repro of the problem which we can try locally.

borkdude 2022-04-16T04:34:04.435979Z

You could maybe also set the constructor property manually using interop