This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-10-21
Channels
- # announcements (10)
- # aws (38)
- # beginners (220)
- # calva (2)
- # cider (26)
- # clj-kondo (194)
- # cljs-dev (4)
- # clojure (190)
- # clojure-dev (7)
- # clojure-europe (3)
- # clojure-italy (6)
- # clojure-nl (4)
- # clojure-uk (8)
- # clojured (1)
- # clojurescript (29)
- # code-reviews (31)
- # community-development (9)
- # core-async (24)
- # cursive (38)
- # data-science (51)
- # datomic (52)
- # dirac (2)
- # emacs (3)
- # events (1)
- # figwheel-main (4)
- # fulcro (49)
- # graphql (13)
- # heroku (1)
- # hoplon (19)
- # immutant (3)
- # leiningen (1)
- # nrepl (59)
- # off-topic (12)
- # onyx (2)
- # pathom (51)
- # reitit (15)
- # shadow-cljs (88)
- # spacemacs (6)
- # sql (3)
- # tools-deps (107)
- # xtdb (11)
Hi. I found hard to quote the fully qualified symbol in macro.
1. To macro I'm passing an arg (symbol "view.core" (name asym))
2. When I do ~arg then I got a symbol: view.core/importer
3. In macro I would like to quote it to 'view.core/importer
I tried something like `(quote ~arg) but the effect is '(symbol "view.core" (name asym))
Any help is greatly appreciated
(defmacro boop [sym]
`'~(symbol "view.core" (name sym)))
(boop beep) => view.core/beep
@karol.wojcik like that?(defmacro qualify
[asym]
`'~asym)
(defmacro resolve*
[module fasym args]
`(when-not core.util/nodejs?
(println "ARGS" ~args)
(println "FASYM" (qualify ~fasym))
(cljs.loader/load ~module
(fn []
(println ~fasym)
;; ((cljs.core/resolve (quote ~fasym)))
))))
Still having (symbol "view.core" (name sym))
(defmacro resolve*
[module fasym args]
(let [qualified-sym (symbol module (name fasym))]
`(when-not core.util/nodejs?
(println "ARGS" ~args)
(println "FASYM" '~qualified-sym)
(cljs.loader/load ~module
(fn []
(println '~qualified-sym))))))
something like that?and (macroexpand '(resolve* "view.core" boop nil))
will have that: (println "FASYM" (quote view.core/boop))
fasym is that (symbol "view.core" "importer")
I want to have (quote view.core/importer)
But (symbol "view.core" "importer") is an argument passed to resolve*
(core.lazy/resolve* module (symbol "view.core" (name asym)) args)
Where module is :view, args are nil, asym is 'importer
not sure it can work that way, when you pass (symbol "view.core" (name asym))
to a macro, it won't receive a symbol, it will receive a list, where first element is symbol symbol
, second is a string "view.core" etc.
well you can eval fasym
arg and store it in let:
(defmacro resolve*
[module fasym args]
`(let [qualified# ~fasym]
(when-not core.util/nodejs?
(println "ARGS" ~args)
(println "FASYM" qualified#)
(cljs.loader/load ~module
(fn []
(println qualified#))))))
it would be great if you described the problem you are trying to solve with this macro. what are args? what should happen at compile time? what should happen at runtime?
Wait @U47G49KHQ. Supposing I'll change it to defn.
(defn resolve*
[module fasym & args]
(println fasym)
(println (quote fasym))
(when-not core.util/nodejs?
(loader/load module
(fn []
(if (> (count args) 0)
(apply (resolve (quote fasym)) args)
((resolve (quote fasym))))))))
Still I have to quote fasym so that resolve will get the quoted symbol.Nono. Resolve will return the function, then I can apply the args. I need the quoted, fully qualified symbol for cljs.core/resolve. Otherwise I got:
src/core/lazy.cljs Assert failed: Argument to resolve must be a quoted symbol
(core/and (seq? quoted-sym) (= (quote quote) (first quoted-sym)))
Indeed if I use the defn I will have:
view.core/importer
symbol bound to fasym. But still I need to quote it for resolve.
it's strange you are able to even call it with apply
, since there you need function value, and you can't take value of a macro
Well. Probably I would not be able to use apply. For now i don't know, because I cannot produce the quoted qualified symbol.
How can I quote fasym in function definition in the way that It will be 'view.core/importer rather than 'fasym?
And then eval it.
I meant just pass it to resolve if you can get value's macro as a value for some reason 😄
Resolve macro expects fully qualified, quoted symbol.
Now It will receive a list. Therefore compilation fails 😞 @U47G49KHQ
that means that you should have fully-qualified symbol during compile, so you can't pass (symbol "view.core" (name asym))
to your macro, it has to be view.core/inspector
Ok thanks! So the helper is useless, because it won't help
not sure what you’re trying to do, but if you want to deploy a CLJS app using require
it probably won’t work
question... if clojure function is given enum class, how can clojure test against it? I mean... (defn whoamI [x] (somehow_test_that_x_is_enum x))
I frequently find myself writing functions and macros lately that really would benefit from being able to know what name it’s being bound to
that is bad, get a rubber band and put in on your wrist and snap it everytime you find yourself doing that
for example, when generating CSS classes:
(def my-styles (styles/css {:color "red"})) ;; would like to add the namespace/var-name to the classname generated by this
(defn my-component []
(let [isolated-styles (styles/css {:color "blue"})] ;; would like to add the namespace and function it was generated in
...))
there are many other examples I’ve actually ran across lately. mainly building out abstractions to help build applications
what I find is that this leads to proliferation of def<thing>
macros which I distaste
the problem with using things like the namespace and def'ed name as names in things like css is it makes it annoying to call a given function more then once and compose the css you get from it, since the names can collide
but when I’m staring at a classname that looks like css-1def489
, it’s a bit harder to figure out where that class comes from
this is just an example, too. there’s other things that you want to parameterize but still be able to relate to the name it was defined
e.g. re-frame does this itself, but using keywords, which means that jump-to-definition and whatnot doesn’t work
Cursive has find-usages for keywords which works quite well with namespaced keywords
yes, it works OK. it just means that you have to add your own var system essentially (what re-frame does) and you can’t treat the thing as a first-class value
proliferation of defcss
, defsub
, deffx
, etc. gets tedious and also as someone new to a framework, scary
well they shouldn't hold any secrets. the macro should litereally just (def my-styles (styles/css {:color “blue”} ::my-styles))
but out of (defcss my-styles {...})
yeah I know ... it sucks. the JS world does it completely without names too though. maybe not actually a problem worth solving in the end
well there are babel plugins that do this. but babel allows slightly more power w.r.t. whole-program processing I believe
could write a macro record
that knows about the various different types of “things” you create in your codebase and records a mapping of thing-identifier->source_file:line_no
ive written a def macro that made a record type and specializations for some multimethods and protocols
quick question: is anyone here using REBL? the cognitect REPL UI thing? if so: do you use tap>
at all?
how to you tap? just the value or do you "decorate" it in any way? like add some other context?
i've just dumped into a rotating list of the last ten forms, i've made a spy tap macro that puts the form its tapping, i've made some that return tuple style like you said
which ever one is nearest at hand or already written is what i use. probably wouldn't care too much between them
@thheller I’ve definitely gotten in the habit of (tap> [:something-to-searhc-for the-actual-val])
the tool I built for REBLy CLJS support primarily uses tap>
right now to communicate
I think I want to eventually have it export a macro that provides the form being sent just like REBLs inspect
but yeah some structure to "label" values would be nice for the UI. maybe even something that controls where it goes or is handled {:stream :something :keep-latest true}
(to only keep the latest values)
maybe just some convention on the actual value, like using a map with some namespaced identifier keys
your tap handler can get the meta out of the val and pass it along to your REBL app
no. the above doesn't work since it applies meta to the some-val
symbol, not the actual value
(tap> ^:foo [42])
-> the metadata is lost in the way REBL renders tap output so when you browse tap output it ends up just being [42]
(and, yeah, I use REBL all-day, every-day so I'm happy to answer Qs about it)
I tend to use (tap> [:tag val])
or (tap> {:tag val})
if I want to track where the value came from.
we were talking about the case of ^:foo bar
which does not attach meta to the value
@U04V70XH6 do you know how REBL handles the tap history? does it just store the last X entries or something more sophisticated?
my objective right now is to build a UI that can display the shadow-cljs build state remotely
I'm not sure what REBL's limit is on taps. I've run tests with thousands of tap>
calls and REBL seems to just store them all until you "clear" the list.
But I think also there is a semantic difference between viewing a tap to value in the current state of process or resource
but the original value is always in the runtime and the tool can request "fragments" of it
Biggest value is the app-db of our 40k line re-frame app, which isn't in the magnitude of 100s of mb
hehe yeah it is kind of unusual. but I'm building it to solve my problem in shadow-cljs in that I can never really look at the actual build-state at any point
but it still needs to access old tapped values if you select and nav into them yeah?
Ha. I was just thinking about that and then making sure it’s not there on prod builds and a nice warning when found
@thheller with tap> in rebl, you accumulate multiple things before clicking the browse button -- so you can tap> a keyword to use as a fake label, no?
Ohh, could you datafy the value? So it’s a bunch of keyword “topics” and you get the value by nav’ing to them
would a tap-fn that destructures [:label value] and then calls submit with the pieces work?
perhaps it would be nicer if rebl's ui provided a text field for labeling what was tapped in the tap pane
@sogaiu Not sure how that helps if you have 1,000 tapped values?
don't know that i would use that for a 1000 tapped values, but once i tap something, to get it to appear somewhere useful i click on the browse button -- but typically the value shows up in the browse pane with no label
I clear the taps before a specific test run. Run the "test". Browse the taps. That shows up as :rebl/taps
with an array of all the tapped values as its corresponding value, so you navigate (->) into that and then scroll up and down (^ / v).
So you're only looking at the tapped values for a single test run that way. If you need to identify the tap>
locations, use [:tag val]
or {:tag val}
as the value you tap>
so the tag is unique.
Comparing across multiple sets of :rebl/taps
?
You mean the def
as...?
The code and the value.
True, you could...
So you'd want a way to swap out the generic :rebl/taps
for a specific name you provide?