This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-09-27
Channels
- # announcements (1)
- # aws (8)
- # babashka (77)
- # babashka-sci-dev (8)
- # beginners (29)
- # biff (2)
- # calva (13)
- # cljs-dev (1)
- # clojure (42)
- # clojure-europe (205)
- # clojure-nl (1)
- # clojure-norway (5)
- # clojure-uk (4)
- # clojurescript (58)
- # conjure (9)
- # data-science (7)
- # datalevin (19)
- # datomic (3)
- # emacs (7)
- # fulcro (15)
- # gratitude (8)
- # lsp (52)
- # meander (3)
- # membrane (92)
- # off-topic (12)
- # re-frame (16)
- # reagent (4)
- # reitit (15)
- # releases (1)
- # sci (30)
- # shadow-cljs (34)
- # tools-deps (5)
- # xtdb (17)
alright what am I doing wrong here (clojurescript environment)
(ns demo.sidecar
(:require [cljs.core.async :as a]
[cljs.core.async.interop :as ai]
[sci.core :as sci]))
(def ctx (sci/init {:classes {'js goog/global}
:namespaces
{'cljs.core.async
(sci/copy-ns
cljs.core.async
(sci/create-ns 'cljs.core.async))
'cljs.core.async.interop
(sci/copy-ns
cljs.core.async.interop
(sci/create-ns 'cljs.core.async.interop))}}))
(sci/eval-string*
ctx
(apply str
'((ns gogosci.core
(:require [cljs.core.async :as a]
[cljs.core.async.interop :as ai]))
(a/go))))
;;=>
#error
{:cause #error
{:data {:column nil,
:file nil,
:line nil,
:phase "analysis",
:type :sci/error},
:message "Could not resolve symbol: a/go"},
:data
{:column 86,
:file nil,
:line 1,
:message "Could not resolve symbol: a/go",
:phase "analysis",
:sci.impl/callstack
#object
[cljs.core.Volatile
{:val ({:column 86,
:file nil,
:line 1,
:ns #object [sci.lang.Namespace]})}],
:type :sci/error},
:message "Could not resolve symbol: a/go"}
the rest of core.async works, it's just not happy about the channels
ok think I have a workaround
I have the most horrible hack
For CLJS, I usually recommend using the platform's promises in combination with promesa https://github.com/funcool/promesa There is a configuration here which you can directly use: https://github.com/babashka/sci.configs#funcoolpromesa
using promesa would be the right thing. But why would you do the right thing when you could do something horrible like this:
(defmacro make-sci-macro-fn
"makes a function with multi arrity dispatch and returns it.
used to make a macro for sci
expands to:
(do (defn fn-name
([a] (sym a))
([a b] (sym a b))
([a ... z] (sym a ... z))
...)
fn-name)"
[fn-name sym]
(let [fn-name# `~fn-name
multi-dispatch-decl# (let [alpha "abcdefghijklmnopqrstuvwxyz"]
[]
(loop [n (dec (count alpha))
res []]
(if (zero? n)
res
(let [args (mapv #(symbol (str %)) (drop-last n alpha))
go-form (list* sym args)]
(recur (dec n)
(conj res
(list args go-form)))))))]
`(do
(def ^:sci/macro ~fn-name# (fn ~@multi-dispatch-decl#))
~fn-name#)))
It expands to this:
(do (defn ^:sci/macro fn-name
([a] (sym a))
([a b] (sym a b))
([a ... z] (sym a ... z))
...)
fn-name)
which I used in the sci macro machinerySo I made a context
(def ctx (sci/init {:classes {'js goog/global}
:namespaces
{'cljs.core.async
(merge (sci/copy-ns
cljs.core.async
(sci/create-ns 'cljs.core.async))
{'go (make-sci-macro-fn go a/go)})}}))
then tried it out:
(a/go
(def data
(a/<!
(sci/eval-string*
ctx
(apply str
'((ns gogosci.core
(:require [cljs.core.async :as a]))
(a/go 1 2 3 4)))))))
and data resolves to 4
I'm not gonna pretend it's elegant 😅
I just don't want to have to write thousands of lines of core.async code to promesa
ah sadly this does not actually work
it breaks down when a/<!
gets involved. That's alright, it will be a useful constraint
yeah promesa was a great recommendation, the switch is rather painless
holy crap @U04V15CAJ thank you 😮 https://github.com/babashka/sci.configs/blob/main/src/sci/configs/funcool/promesa.cljs#L1
that's a lot of work!!
@U04V15CAJ but it should be possible and not hard to get core.async working with sci, right?
might need a lot of copying I guess so more annoying work rather than being complicated, right?
@U5H74UNSF it should be possible, but I don't think it's worth doing so. you need to basically include a CLJS version of tools.analyzer at runtime, etc.