This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-30
Channels
- # adventofcode (95)
- # announcements (17)
- # babashka (28)
- # beginners (107)
- # calva (34)
- # clj-kondo (7)
- # cljs-dev (20)
- # cljsrn (1)
- # clojure (95)
- # clojure-europe (41)
- # clojure-italy (3)
- # clojure-nl (5)
- # clojure-spec (7)
- # clojure-uk (4)
- # clojurescript (77)
- # cursive (7)
- # data-science (1)
- # datalog (4)
- # datomic (12)
- # events (3)
- # fulcro (32)
- # graalvm (2)
- # hugsql (19)
- # introduce-yourself (4)
- # jobs (2)
- # lsp (20)
- # membrane-term (19)
- # numerical-computing (1)
- # off-topic (8)
- # pathom (3)
- # polylith (17)
- # portal (42)
- # re-frame (7)
- # reagent (32)
- # remote-jobs (1)
- # shadow-cljs (86)
- # spacemacs (3)
- # tools-deps (52)
- # uncomplicate (1)
- # xtdb (23)
Hey, in cljs I'm trying to iterate over a list of objects (ratom) to generate an error field with gen-field-error
. I want to pass the field object name in a loop, so when I iterate over company-name
I will pass "company-name" as a string.
(def company-name (r/atom ""))
(def company-logo (r/atom ""))
(def required-fields
[company-name
company-logo])
(defn gen-field-error [field]
(-> field
(string/capitalize)
(string/replace #"-" " ")
(str " is required.")))
I tried with
(-> (first required-fields) (var) (meta) :name)
But unsuccessfully due to some problems with var
This wouldn't work in CLJ either. When you wrap a symbol in []
, that symbol no longer exists within []
- only its value does. In order for #'...
or (var ...)
to work, they have to receive the symbol itself, at compile time.
CLJ has run time capabilities for that where you can get a var from a namespace by its name as a string. But CLJS does not - you have to create your own dictionary of names to values and use that.
Okay good to know! At this point I will say or I use ns-interns
and check the type of every value or I can transform required-fields
in a big ratom and simply use keys
on it
Note that in CLJS ns-interns
is a macro that has to receive a symbol, so stuff like *ns*
won't work there.
is it possible to have an optional require in cljs? wrapping a require call in try-catch doesnāt work as it has to be at the top level
actually optional is for data that can be or not there, exception is for flow that will fail (eventually), they seems like different concepts to meā¦
Iām looking for a lightweight DB to drive from node/nbb, could be datalog but Iāll need persistence. Suggestions?
I found lowdb but that doesnāt seem very ergonomic, do you have any particular ones that youāve tried/liked?
i've been out of the node.js world for awhile. prior i would probably just use something like sqlite or redis
i think there are a couple cljs dbs that persist to local storage or something. maybe you could use some duct tape and wire to get those to persist to some durable storage in node.js
I ended up using Google sheets lol
Kind of not what I would have expected as an answer to my question but in the context of what Iām working on I think it makes sense
@domagala.lukas you can probably use a macro and try finding the optional ns on the classpath in the macro
The way I usually do this is to let the consumer of the library pre-require the optional namespace
@U04V15CAJ what do you mean by pre-require?
e.g. for clojure spec alpha, the user has to require clojure.test.check first to use certain features. https://github.com/clojure/clojurescript/blob/6443518850d8e4f1e09be99d4669e8d4a5e893a3/src/main/cljs/cljs/spec/test/alpha.cljc#L258
@U04V15CAJ ah yeah, thats clever, since js doesnāt really care. the two problems are: shadow + clj-kondo really like warning me now, but i guess iāll find a way to make them stop
(def debux-enabled?
(try
(when (exists? debux.common.util/result*)
true)
(catch :default _ false)))
that part only bothers clj-kondo. shadow only complains about:
(if debux-enabled? debux.common.util/result* [])
clj-kondo should support this:
$ clj-kondo --lint - --lang cljs <<< '(exists? foo.bar/az)'
<stdin>:1:10: warning: Unresolved namespace foo.bar. Are you missing a require?
Can you make an issue?i guess i could use a macro to only spit out the debux version if the clj version of the require also exists, but that seems like overkill
iāll make an issue and try to get shadow to not be pissed at me. thanks for the help!
ah btw i have the same clj-kondo problem in clj, do you want it in the same issue?
(def debux-enabled?
(try
(require 'debux.common.util)
(when debux.common.util/result*
true)
(catch Throwable _ false)))
clj versionare you sure? seems to work for me or at least it compiles
ill run it, let me check
works in the repl
iāve stolen the concept from here: https://github.com/dakrone/clj-http/blob/3.x/src/clj_http/client.clj
ah so you mean the require will work but the usage will fail? that makes sense
mhh, seems like a lot of work wrap everything with resolves
@U04V15CAJ thatās great, thanks so much!
may I suggest flipping the entire exists logic? ie. instead of checking if something exists you have that something register itself on load
at runtime you can just check if the thing did register itself without mucking arround in global namespaces and such?
unless my brain is foggy because I just woke up, but wouldnāt I have the same āoptionalā problem in the other direction now?
I made a gist for this basic idea a while ago https://gist.github.com/thheller/fa044450a6470fdd1afdbcf3f37a65e3
and it does something different depending on whether a thing registered itself or not
given that namespaces don't really exist in CLJS anything related to them is icky to say the least
Yeah you can make another optional namespace that you do control and then register something.
if its about debugging and stuff :preloads
is usually the place where you want to load "optional" stuff
ah ok yeah I get your method. thatās how Iād do it if I had a DI container in a different language. my problem is that the optional lib doesnāt know anything about the main lib, so to do the registration iād still have to do some magic
but yeah the final interface would be a little less magic, so thats good at least
no magic needed really since that "adapter" namespace you create can just do whatever and doesn't need to worry about anything conditional
the only problem really with all of this is :advanced
not being able to detect if the conditional thing is actually loaded or not. so the calls to anything optional are not removed as they are not DCE
well, i still need a way to know if i want to load your ābrowserā or the āreact-nativeā ns if we are talking about your gist
and iām fine with breaking advanced compile, itās a dev time lib anyway
but the conditional thing is not loaded so log
doesn't do anything and is technically dead code
well yeah, but that would be pretty tiny + a wasted call to a no op
but is there no decent way to detect if i should do :browser or :react without a config file? thatās what i was trying to avoid
don't know what you are trying to do exactly so can't say much more. conditional require in CLJS is not an option like it is in CLJ
thank you anyway! donāt want to waste too much more of your time, so ill play around with it more by myself for some time. if itās ok Iāll check back in with the final result to see if I did anything too awful ;)