Fork me on GitHub
#clojurescript
<
2020-05-27
>
Micha毛l Salihi08:05:56

@bhauman @thheller Just like that by the way, you both are my heros, I love your work! Thx 馃檪

鉂わ笍 32
craftybones10:05:14

I鈥檇 also like to take a moment to talk about just how awesome @bhauman鈥檚 documentation and getting started tutorials are. No wonder figwheel is popular.

鉂わ笍 4
craftybones10:05:00

And @bhauman鈥檚 awesome presentations with an editor window, reagent and devcards loaded. Killing Keynote, one devcard at a time

DrLj贸tsson13:05:44

Hey. I'm trying to figure out how to dispatch a re-frame event that changes the state in a kee-frame FSM. I can't get it to work. Anyone with experience? @ingesol?

ingesol17:05:08

Hi! Don鈥檛 have too much time right now, but post some more details in the #kee-frame channel and maybe me or someone else can have a look

DrLj贸tsson19:05:37

Thanks, I will!

jsa-aerial15:05:34

@mfikes I'm looking at https://github.com/mfikes/andare and trying to figure out a couple things. First, if I remove good ol' org.clojure/core.async and add andare to my deps, all my current core.async code should still work as before, correct? Second, once up and running my self hosted Cljs, I can require even the go and go-loop macros and any new code I am hacking in the live Cljs editor/repl I am using will be able to use these as well with <! etc and it will 'just work'? Sounds amazing:crossed_fingers:

mfikes16:05:59

@jsa-aerial Yes, Andare is designed to be a drop-in replacement. (Having said that, there is a recent issue that cropped up with the very latest release https://github.com/mfikes/andare/issues/12 so if that ends up causing issues, just use the previous release.) Yes, you can use the go and all associated macros live in a self-hosted ClojureScript environment. :)

馃挴 4
馃槷 4
jsa-aerial16:05:55

Out of curiosity, is there a reason org.clojure/core.async doesn't just become this (basically, replace it with Andare)?? What's the downside - the upside is obvious

mfikes17:05:31

@jsa-aerial Andare involved some fairly drastic rearrangements of the core.async codebase. (It would be a lot to expect core.async to take that on, IMHO.)

jsa-aerial19:05:10

@mfikes I still get an error that go doesn't exist. If I explicitly try to require with a refer to go I get this error

Invalid :refer, macro cljs.core.async.macros/go does not exist

jsa-aerial19:05:29

If using Andare must one make sure no org.clojure/core.async is anywhere in the dependency graph?

mfikes19:05:00

@jsa-aerial Does this work for you? (require '[clojure.core.async :refer [go]])

jsa-aerial19:05:11

Get the very same 'invalid refer' msg

mfikes19:05:42

Is this in your own self-hosted ClojureScript setup?

jsa-aerial19:05:46

Oh, -not quite no '.macros' on msg

jsa-aerial19:05:23

Yes - my own

jsa-aerial19:05:52

Stuff like <! and chan are there

jsa-aerial19:05:45

I've tried refer, refer-macros and require-macros all the same

mfikes19:05:52

If you are arranging to have code loaded into your environment, be sure that you deal with :macros (see https://github.com/clojure/clojurescript/blob/master/src/main/cljs/cljs/js.cljs#L80)

mfikes19:05:37

If you are having difficulty getting self-hosted code loading working, one suggestion is to put {:deps {andare {:mvn/version "1.1.587"}}} into deps.edn and then run plk -v and then evaluate the require . You will ultimately see it logging Loading cljs.core.async macros namespace as part of what occurs when evaluating the require.

jsa-aerial19:05:50

Hmmm, I do not have a :macros option in the loader. Is that just a boolean?

mfikes19:05:19

Well, either nil or true IIRC. So, if it is truthy you'd need to try to load a clj or cljc file (in that order).

jsa-aerial19:05:36

If the option is truthy, you cannot have cljs files?

mfikes19:05:18

Indeed. Macros are not loaded from cljs files.

jsa-aerial19:05:50

Riiiigghhht - I recall that now. Hmmm, so the setup is a name space form is being evaluated via cljs.js/eval-str where the loader-fn has {:lang :js :source ""}

jsa-aerial19:05:31

The source is explicitly given to eval-str

jsa-aerial19:05:36

And just to be complete, that ns form has

[cljs.core.async :as async
    :refer [<! >!]
    :refer-macros [go go-loop]]

jsa-aerial19:05:45

as part of the requires

mfikes19:05:35

When that namespace form is evaluated, the dependencies will be loaded as needed, thus triggering calls to your *load-fn* implementation.

mfikes19:05:13

If your *load-fn* calls back with {:lang :js :source ""} when :macros is true, that would likely be the cause of the problem you are seeing.

jsa-aerial19:05:30

I'm sure it does - it returns that unconditionally.

(defn loader-fn [info-map cb]
  (cb  {:lang :js :source ""}))

jsa-aerial19:05:46

and that is passed as the :load option to eval-str. So, I suppose I need to check if :macros is set and then somehow find and return the source to the async.macros source?

mfikes19:05:34

Yes. Otherwise, if you want to "bundle" all of the expected namespaces that can ever be required into your self-hosted environment, you can do so. The {:lang :js :source ""} pattern can be used when doing this. See the stuff about "ambient" namespaces at https://stackoverflow.com/a/51575204

jsa-aerial19:05:08

Yeah, that is what I thought I was doing, which always worked until - wanting macros as well. So, I need to bundle the async.macros as well.

mfikes19:05:14

Your *load-fn* may not even be called if you set things up to be available in an ambient fashion... it's been a while since I've messed with this...

mfikes19:05:36

Yes, you can AoT compile macros namespaces to be included.

mfikes19:05:23

An article on how I've done that in the past by using Planck: https://blog.fikesfarm.com/posts/2016-02-03-planck-macros-aot.html

jsa-aerial19:05:30

Yes, I use the :load option to eval-str so *load-fn* is not even called. I believe...

mfikes19:05:49

In a sense, you can use a dev-time self-hosted compiler to AoT all of the namespaces you might ever want (runtime and macros namespaces), and then arrange to have the resulting JavaScript and analysis cache be available in the target execution environment where the self-hosted compiler is ultimately running.

jsa-aerial19:05:15

That's what I believe I am actually doing (and it all goes into the resulting JAR), but somehow the macros for core.async are not getting in there. Apparently.

jsa-aerial20:05:16

Well, looking through resources/public/js/compiled/out I don't see any core.async in there. I'm not sure how that is, since the rest of it is accessible.

mfikes20:05:03

@jsa-aerial One working example of AoT-compiled core.async (Andare) is Replete. If you (require '[clojure.core.async :refer [go]]) in Replete on your phone, no network calls or made and no compilation is done; it just loads the AoT compiled JavaScript.

馃憤 4
jsa-aerial17:05:57

@mfikes I'm still poking around on this and decided to have a look at Replete. I am using the 'online web' version (not iOS) and I get this:

(require '[clojure.core.async :refer [go]])
Execution error (ExceptionInfo) at (<cljs repl>:1).
No such namespace: cljs.core.async, could not locate cljs/core/async.cljs, cljs/core/async.cljc, or JavaScript source providing "cljs.core.async"

jsa-aerial17:05:28

Is this a cockpit error on my part or maybe the online variant does not have async?

mfikes17:05:56

Yeah, the web version doesn't match the iOS / Android / macOS versions right now with respect to that.

jsa-aerial17:05:41

OK, but if I noodle around in the source, I may stumble over how it does the AoT for async.

jsa-aerial17:05:17

I didn't see where it is done in Plank, but I maybe should root around in there some more as well

mfikes17:05:19

Planck doesn't bundle core.async but it does bundle its own namespaces. Additionally, Planck has a -K flag that will cause it to cache output to disk... you might be interested in that if you are curious to take a peek at AoT artifacts.

jsa-aerial17:05:33

It is strange - the cljs.core.async.js (and cache, etc) is in my bundle and the stuff in there just works but no async.macros

mfikes17:05:38

(`-K` can be used to cache anything you require in Planck.)

jsa-aerial17:05:53

Are any of Plank's 'own namespaces' macro variants?

jsa-aerial21:05:59

@mfikes I've made progress! I now have the async.macros artifacts in the bundle (the macros.js, macros.cljc.cache.json, et. al.) And when I create the name space with the requires there are no longer errors. But when I go to use them, they still error as not being available. Here's a trace of the requires being done:

{:name clojure.string, :macros nil, :path "clojure/string"}
core.cljs?rel=1590690300080:52 {:name cljs.core.async, :macros nil, :path "cljs/core/async"}
core.cljs?rel=1590690300080:52 {:name cljs.core.async.macros, :macros nil, :path "cljs/core/async/macros"}
core.cljs?rel=1590690300080:52 {:name com.rpl.specter, :macros nil, :path "com/rpl/specter"}
core.cljs?rel=1590690300080:52 {:name aerial.hanami.core, :macros nil, :path "aerial/hanami/core"}
core.cljs?rel=1590690300080:52 {:name aerial.hanami.common, :macros nil, :path "aerial/hanami/common"}
core.cljs?rel=1590690300080:52 {:name aerial.hanami.templates, :macros nil, :path "aerial/hanami/templates"}
core.cljs?rel=1590690300080:52 {:name aerial.saite.compiler, :macros nil, :path "aerial/saite/compiler"}
core.cljs?rel=1590690300080:52 {:name aerial.saite.core, :macros nil, :path "aerial/saite/core"}
core.cljs?rel=1590690300080:52 {:name reagent.core, :macros nil, :path "reagent/core"}
core.cljs?rel=1590690300080:52 {:name re-com.core, :macros nil, :path "re_com/core"}
core.cljs?rel=1590690300080:52 {:name cljs.core.async, :macros true, :path "cljs/core/async"}
core.cljs?rel=1590690300080:52 {:name com.rpl.specter, :macros true, :path "com/rpl/specter"}

mfikes21:05:18

@jsa-aerial You may need to make sure the metadata cache is being loaded.

jsa-aerial21:05:09

so, to just take the cljs.core.async and cljs.core.async.macros are there with :macros false and then cljs.core.async shows up again with macros true. Not sure what that means

mfikes21:05:00

I think both are both runtime and macro-time namespaces.

jsa-aerial21:05:10

I use this 'bundle helper macro` that I found in one of your examples:

(defmacro analyzer-state [[_ ns-sym]]
  `'~(get-in @env/*compiler* [:cljs.analyzer/namespaces ns-sym]))
and then call it like so in my 'compiler' namespace load:
(cljs.js/load-analysis-cache!
   state 'cljs.core.async
   (analyzer-state 'cljs.core.async))
  (cljs.js/load-analysis-cache!
   state 'cljs.core.async
   (analyzer-state 'cljs.core.async.macros))

jsa-aerial21:05:19

Hmmmm, this is really odd. If I eval these two:

as/<!
am/go
I get these results:
=> #object[cljs$core$async$_LT__BANG_]
=> #object[cljs$core$async$macros$go]
which sure looks like things are there. But if I try this:
(let [c (sc/timeout 5000)]
  (am/go (as/<! c))
  (hmi/printchan "DONE"))
I get this:
client.cljs?rel=1590690310072:43 WARNING: Use of undeclared Var cljs.core.async/<! at line 2 
Error Error: <! used not in (go ...) block]
which seems to say they are not there?!?

jsa-aerial21:05:53

wow - this also works:

(am/go (hmi/printchan "DONE"))
returns
(cljs.core.async/go)
which does look a bit weird but no errors and "DONE" is printed to the js console.

jsa-aerial20:05:34

@mfikes I hope it is ok to still ask you for some guidance. I have now 'preloaded' the compiler state with the analysis data for cljs.core.async and cljs.core.async.macros. I can inspect it directly in the JS console and the stuff is there and looks correct (as far as I can understand it). Also, inspecting in the JS console again, I see both the cljs.core.async and cljs.core.async.macros 'namespaces' are there and look like they have the correct data in them. In particular the cljs.core.async object has this in its macros attribute:

macros:
go: 茠 cljs$core$async$macros$go(var_args)
go_loop: 茠 cljs$core$async$macros$go_loop(var_args)
alt_BANG_: 茠 cljs$core$async$macros$alt_BANG_(var_args)
__proto__: Object
When I can (require cljs.core.async :as as :refer [<! >! put!]) w/o errors. When I then evaluate some things I see this:
(evaluate 'doc.code "as/go" printchan) => WARNING: Use of undeclared Var cljs.core.async/go at line 1 
(evaluate 'doc.code "cljs.async.core/go" printchan)  => WARNING: No such namespace: cljs.async.core
(evaluate 'doc.code "as/<!" printchan) =>  #object[cljs$core$async$_LT__BANG_
(evaluate 'doc.code "<!" printchan)  => #object[cljs$core$async$_LT__BANG_
(evaluate 'doc.code "cljs.core.async.macros/go" printchan) => #object[cljs$core$async$macros$go
(evaluate 'doc.code "(macroexpand '(as/go (as/>! c 1)))" printchan) => (as/go (as/>! c 1))
(evaluate 'doc.code "(macroexpand '(cljs.core.async.macros/go (>! c 1)))" printchan) => (cljs.core.async.macros/go (>! c 1))
So, it looks like the go macro is there but there is no way to access it to have it run and produce output. Does any of this make any sense?

mfikes04:05:57

Hmm. Not really. Typically when trying to sort this stuff out, I resort to debugging the compiler itself.

jsa-aerial22:06:22

If you ever get an example of Andare working in self-hosted mode on the browser, please ping me here. I have been defeated and am giving up and will need to approach the original issue in a totally different way