This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-02-15
Channels
- # announcements (8)
- # architecture (9)
- # autochrome-github (1)
- # babashka (48)
- # beginners (55)
- # calva (36)
- # cider (16)
- # clj-commons (1)
- # clj-kondo (38)
- # cljs-dev (44)
- # cljsrn (1)
- # clojure (164)
- # clojure-europe (35)
- # clojure-nl (2)
- # clojure-norway (10)
- # clojure-uk (23)
- # clojurescript (50)
- # conjure (24)
- # core-async (1)
- # cryogen (2)
- # cursive (38)
- # datalevin (11)
- # datascript (2)
- # datomic (13)
- # duct (1)
- # emacs (16)
- # events (12)
- # exercism (3)
- # figwheel-main (7)
- # fulcro (26)
- # honeysql (5)
- # integrant (1)
- # jobs (3)
- # kaocha (6)
- # lsp (72)
- # malli (22)
- # nextjournal (35)
- # nrepl (1)
- # off-topic (34)
- # pathom (5)
- # polylith (8)
- # portal (40)
- # re-frame (14)
- # reagent (42)
- # reitit (1)
- # releases (1)
- # remote-jobs (1)
- # reveal (9)
- # sci (2)
- # shadow-cljs (13)
- # sql (3)
- # tools-deps (33)
- # vim (25)
With Reagent, say one has a large number of props which al have a default value, how would that translate to ClojureScript? Would they just be function parameters initialized with a default value?
Okay, cool.
Specifically it can be helpful to take those function parameters as a map - that gives you a place to put defaults
@U3JH98J4R for the map is it a 1
or :a 1
?
I have a question about state management. It seems to me that a tree or map of atoms, e.g (atom {:west-office {:sales-calls (atom []) :salespersons (atom [])} :east-office {..etc}}
makes sense as then top-level keys can be added dynamically, and your west-office etc components can be made to update only when those atoms change. Is this viable/intelligent/common?
the way atoms work is via CAS, which doesn't really make sense if any of the contents stored and updated within are mutable
its not super important in the context of cljs actually - i don't even think its the mechanism there so maybe ignore me on that
And when you start using a global atom, it might be a good time to check out re-frame. ;)
Ok. I’ve been poring over re-frame. It looks cool. But going over it I feel this question nagging at me: how far off is this from cljs-flavored react/redux ?
Last time I had to deal with redux was ages ago and in someone else's project so I might be wrong. But it's not that far off. Both are a way to organize your data into a global storage, both are done in a similar model where you trigger events and receive data changes. It's likely that there are significant differences, but I'm not in a position to tell.
ok, thanks
I'm starting to use re-frame as a SPA framework and am having issues getting a small example running. There doesn't seem to be a re-frame channel on this Slack. Is this the proper place to ask questions, or is there somewhere more appropriate for this discussion?
That's odd - I searched specifically for that in the channel list and it didn't seem to find anything. I'll try again.
I’ve got a question about some differences I am seeing between macros in clojurescript vs clojure. First, this is a bit of an odd case where I am defining a macro inside of a macro. The background for this is that I am migrating a .clj
namespace to .cljc
. The original clj code is a wrapper for defrecord
which both creates the record and creates another macro which enforces some compile time restrictions on creation of the record for performance reasons.
I am seeing a case where the inner macro used in clojuresript appears to gobble the first two arguments passed to it. The same code works fine in clojure, and if I use a defn
instead of a defmacro
as the inner “create record” operation, it works as expected in clojurescript.
Given that it appears to be possible to have a defmacro inside a defmacro for cljs (I wasn’t sure initially), and that some of the arguments make it as expected, I’m confused where the other two arguments are going.
Code example in the thread.
macro definition:
#?(:clj
(defmacro myrecord
[record-name fields]
(let [record-name (symbol (str "custom-record-" record-name))
macro-maker-name (symbol (str "macro-make-" record-name))
fn-maker-name (symbol (str "fn-make-" record-name))]
`(do
(defrecord ~record-name ~fields)
(defmacro ~macro-maker-name
[& key-values#]
;; compile-time validation elided here
`[:args '~key-values#])
;; this following fn is for comparison, not part of the original solution
(defn ~fn-maker-name
[& key-values#]
[:args key-values#])))))
When I call this from clojure, we can see that all the args are passed through:
=> (myrecord clj [a b])
=> (macro-make-custom-record-clj :a 2 :b 5)
[:args (:a 2 :b 5)]
=> (fn-make-custom-record-clj :a 2 :b 5)
[:args (:a 2 :b 5)]
When I call it from clojurescript (via a test, using olical/cljs-test-runner
, if that is important), we can see that the macro version appears to gobble the first two arguments:
(myrecord cljs [a b])
(deftest mytest
(println (macro-make-custom-record-cljs :a 1 :b 2))
(println (fn-make-custom-record-cljs :a 1 :b 2)))
-- (output) ---
[:args (quote (:b 2))]
[:args (:a 1 :b 2)]
Notice that the :a 1
appears to get gobbled up somehow in the macro-make-custom-record-cljs
version, but not the fn-make-custom-record-cljs
version.
Is this expected?My guess is that it has something to do with the implicit &form
and &env
macro arguments, although no idea why CLJS behaves differently here. Seems to be relevant: https://clojure.atlassian.net/browse/CLJS-1958
Is there a basic tutorial describing how to include a google closure compatible javascript in a clojurescript project? I have read whatever I can find (e.g., https://funcool.github.io/clojurescript-unraveled/#external-dependencies) and think I understand the principles. I have saved (what I believe is!) a closure compatible js file mylib.js (with header goog.provide('ab')
) in my project's src/js directory, and include :libs "src/js/mylib.js"
in my dev.cljs.edn file. I get no errors on the repl, until I try to call functions from the ab
namespace from my main cljs file. The following error is thrown: #object[ReferenceError ReferenceError: ab is not defined]. Any pointers or useful resources would be great, thanks!
If you have exported a function like
ab.Foo = function(...) {...}
You would call it from Clojurescript as (ab.Foo ...)
Is that how you are doing it? If not, how are you exporting the function, and how are you calling it?
hi @U08JKUHA9 thanks for the response! I was not calling as (ab.Foo ...)
but rather trying (.Foo ab ...)
. Unfortunately neither working!
To export the function, I have used goog.provides('ab')
and defined as you've listed as ab.Foo = function (...){...}
It is actually a class with methods I am trying to import. It is a pseudo random number generator (sfc32) which needs to be right, and so I don't want to reimplement in clojurescript and risk errors in the implementation.
Fantastic @U05224H0W thanks!!
@micheal.ocathain for Closure compatible things you don't need to anything other than place the file on the classpath - no configuration required
Thanks @U050B88UR! Is there any good resource on writing Closure compatible javascript? Apologies for the super-basic question!!
There's a Google Closure book there still lots of relevant stuff. Other than that reading the Google Closure Library sources is probably the best way to understand the conventions
Can I double check I am understanding correctly - regarding no configuration being required? Is this for latest clojurescript versions? I am have removed the :libs key value pair from my dev.cljs.edn and now get an error: No such namespace: ab, could \
not locate ab.cljs, ab.cljc, or JavaScript source providing "ab" in\
file /home/ubuntu/cljs/jslibtest2/src/simplyonmyway/jslibtest2.clj\
s
. I'm using clojurescript v 1.10.773,
the location and the namespace of the JS file must be the same - like ClojureScript source files
Fantastic - thanks so much I will study the Transit projects
The location and namespace being the same was catching me out. I have a basic Closure function working now!