This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-04-05
Channels
- # announcements (3)
- # babashka (135)
- # beginners (82)
- # calva (55)
- # chlorine-clover (23)
- # cider (13)
- # clara (1)
- # clj-kondo (39)
- # cljs-dev (1)
- # cljsrn (2)
- # clojure (96)
- # clojure-france (3)
- # clojure-uk (24)
- # clojuredesign-podcast (1)
- # clojurescript (56)
- # conjure (73)
- # core-typed (1)
- # cursive (1)
- # datomic (10)
- # fulcro (57)
- # joker (4)
- # juxt (1)
- # malli (20)
- # meander (2)
- # off-topic (54)
- # re-frame (4)
- # reagent (3)
- # shadow-cljs (11)
- # spacemacs (6)
- # sql (26)
- # tools-deps (7)
@codonnell A ha! that's enlightening
Also, it's idiomatic to use kebab-case in clojure (which would make your event's name :get-tag-value
)
In this case it's an event that deals with a procedure call that happens on a remote, camelCased system, so it kinda makes sense :)
Fair enough! There are exceptions to every rule.
another newbie question: so with compojure you are able to either deconstruct the request or get the whole request. what if i want to do both? in my use case i only want to deconstruct the :id
from the URL and i need the whole request body. is there a way to do this?
ah! got it working by doing this (POST "/:id" [id :as req] (println id) (println req))
from a stackoverflow post but i am not sure why using the :as
keyboard gives me both?
very cool. i think my confusion comes from not fully understanding what is going on under the hood with :as
:as
is a common way of asking for a full value along with the values that have been destructured from it. In Clojure itself it works in let
bindings and function arguments, and probably other places like them I’m forgetting at the moment. https://clojure.org/reference/special_forms#binding-forms
I wonder why doseq doesn't trigger my re-frame event dispatch. I'm trying to do some mass dispatching like this:
(def tags-to-query
(filter #(re-find #"ROBOT_1_" %) config/tag-names))
(defn get-frequency [tag]
(((@re-frame.db/app-db :tag-table) (keyword tag)) :frequency)
)
(defn request-tag [tag]
(re-frame/dispatch [:auto-request-tag tag (get-frequency tag)]))
(doseq [tag tags-to-query] (request-tag tag))
But nothing happens.
Printing the tags works just fine though.
Using doall also works, but I think it spikes my memory and CPU(especially in debug mode) because these are a lot of tags, and I don't see a reason to hold everything in memory.This seems re-frame related. Did you try adding a print inside the doeseq and printing "tag" to make sure that part works?
turns out it was a mix of putting the code in the right place in the file, and getting the syntax right. And I ended up using dorun
(def tags-to-query
(filter #(re-find #"ROBOT_1_" %) config/tag-names))
(defn get-frequency [tag]
(get-in @re-frame.db/app-db [:tag-table (keyword tag) :frequency]))
(defn request-tag [tag]
(re-frame/dispatch [:auto-request-tag tag (get-frequency tag)]))
(dorun (map #(request-tag %) tags-to-query))
Ok, just so you know, doseq
will work just as well as dorun
, your problem most likely had nothing to do with it.
And with your code, you can also use run!
by itself:
(run! #(request-tag %) tags-to-query)
I wonder if there any simple rule or logic on how to define the most efficient thread pool size for java.util.concurrent.Executors/newFixedThreadPool (Executor Service). So far I've found this explanation on how pmap defines how many threads it uses: > * When the sequence is not chunked (for example subvec) the min parallelism is 1 and the max parallelism is (+ 2 N-cores). Example: with 12 cores, (doall (pmap #(Thread/sleep %) (subvec (into [] (range 1000)) 0 999))) keeps 12+2 threads busy. > * In case of chunked sequences (vast majority are size 32), the min parallelism is (min chunk-size (+ 2 n-cores)), while the max amount is equal to (+ chunk-size 2 N-cores). Example: with 12 cores, (doall (pmap #(Thread/sleep %) (range 1000))) keeps 12+2+32 threads busy. Do you think this could be appropriate to use the same rule/logic for defining java.util.concurrent.Executors/newFixedThreadPool pool size? https://purelyfunctional.tv/guide/clojure-concurrency/#executorservice
I've noticed that there are lots of functions like integer?
... they look like they were created to make type queries easier. They look very handy for the user, but not very easy to programmatically reason about. Does anyone know whether there is a declarative interface to these functions? What do I mean?
(defn integer?
"Returns true if n is an integer"
{:added "1.0"
:static true}
[n]
(or (instance? Integer n)
(instance? Long n)
(instance? clojure.lang.BigInt n)
(instance? BigInteger n)
(instance? Short n)
(instance? Byte n)))
The predicate integer?
is intended to identify a set of objects which is the union of the types Inteter
, Long
, ... Byte
. You can only know that by looking at the function or perhaps reading the documentation. However, a program cannot reason about this. Effectively all the objects which answer true to the integer?
form a superclass of Integer
, Long
, clojure.lang.BigInt
, BigInteger
, Short
and Byte
. But since that type is not named, I cannot use it in a call to isa?
.Correct. There’s no way to make such a type as that’s all locked down in Java
Yes, but even if there's no way to make such a type, there could feasibly be a reflective interface to the information in the implementation if integer?
and friends. right?
Of course i could hack my own by reading the source code. How many such functions are there?
For example, the documentation for derive
hints at this.
Establishes a parent/child relationship between parent and
tag. Parent must be a namespace-qualified symbol or keyword and
child can be either a namespace-qualified symbol or keyword or a
class. h must be a hierarchy obtained from make-hierarchy, if not
supplied defaults to, and modifies, the global hierarchy.
Although I admit that I don't understand how derive works, nor what a tag is
derive works with keywords (the tags), not Java types
but the documentation for derive says it also works with class. I.e., the parent can be a class, but the child cannot (apparently)
until now java types seem to be classes. But i'm not a java expert, also I know less than nothing about java.
Another question about types: If I type Integer
into the repl, it evaluates to some object whose printed representation is java.lang.Integer
and whose type is java.lang.Class
. My question is, given the symbol Integer
how can I programmatically get the value java.lang.Integer
? Moreover, I'd hope that such an evaluation wouldn't be confused if the user happens to have a local lexical variable of the same name.
The class object you get has a getName method which returns a String, which you could use or pass to symbol
I dont think you can have a lexical local of that name. Or if you can, you shouldn’t :)
resolve
is a function to resolve Integer symbol programmatically if that’s a step you need
I think resolve
is the function I need. (resolve 'Integer)
returns the value java.lang.integer
(resolve 'Integer)
should be equivalent to Integer
(unlike Integer
, (resolve 'Integer)
will not actually resolve Integer
until the form is evaluated. but Java always has java.lang.Integer
in the runtime, so this doesn’t make much difference)
so to answer your original question (given the symbol Integer
, how can I programmatically get the value java.lang.Integer
?) the answer is: you already have it
I don't find the getName method on java.lang.Long
clojure-rte.core> (type 1) java.lang.Long clojure-rte.core> (getName (type 1)) Syntax error compiling at (clojure-rte:localhost:59681(clj)*:953:19). Unable to resolve symbol: getName in this context
remember to add the .
clojure-rte.core> (.getName (type 1)) "java.lang.Long"
@U010GL90FN0, I don't know what you mean by, "the answer is you already have it"
gascan.core> (.getName Long)
"java.lang.Long"
gascan.core> (.getName (resolve 'Long))
"java.lang.Long"
Long
and (resolve 'Long)
are equivalent
the only difference is that Long
will resolve that reference when the source is parsed and loaded, and (resolve 'Long)
will resolve it at the time (resolve 'Long)
is actually evaluated at runtime
my question was given the symbol Integer, how to get the Integer class. For example.
(defn foo [x]
;; x is the symbol name of some class
(resolve x) ...)
I don't see how I already have it, I have to call resolve
to get it. right?I have to resolve x at run-time, because I don't know its value at load time.
ahh, then yeah. if all you have is a symbol name, then you have to resolve the symbol to find out what it refers to
indeed. thanks.
that applies to any symbol. so your foo
method would also work for map
or type
foo function, sorry. 🙂
In this case, you could eval
at runtime. Though I'd prefer resolve
, as it makes your intent clearer.
user=> (eval 'Integer)
java.lang.Integer
user=> (resolve 'Integer)
java.lang.Integer
Sidenote: I'd love to hear about your experience encountering Clojure, Jim. Not that many (that I'm aware of) come to Clojure from Common Lisp.
I'm not quite understanding the difference between commute
and alter
is commute guaranteed to eventually occur?
AFAICS, the docs basically say that commute
recalculates on commit, and alter
doesn't. My understanding is that it means that alter
causes the transaction to restart if the ref-ed value has changed under it, and commute
doesn't, it just recalculates the new value and commits it.
Thanks. I'm going to think of it like atomic add versus atomic compare and swap. The operation must commute. You mostly do structured data in an atom I guess?
Yeah, something like that. My guess would be that commute
actually does compare-and-set though, but just for the commuted function, not for the whole transaction
Or is it more about order? Commute will happen but I don't care which order?
So I’m trying to understand how to set up a web server from the ground up with all the things lein
seems to do automagically, using tools.deps. Is there a good cookbook/example of how to properly wrap immutant in mount’s lifecycle? (this seems pretty straightfoward through defstate
and calls to web/run(-dmc)
and web/stop
Should I care about mount vs component? Do these differ significantly in their affordances for something like tools.namespaces, which seems just for development namespace reloading? And finally: I’m trying to also set up nrepl and integrate it into tools.deps and Cursive. I have it loading, but it doesn’t load and start the -main
function, which I guess is normal. Is the normal thing to do to define a user
namespace (where? do i specify it or is it convention) and then start the server using defstate
s from mount manually in the repl?
@jtth See whether this example helps https://github.com/seancorfield/usermanager-example/ -- it uses CLI/`deps.edn` with Component and can spin up http-kit or Jetty, but it would be easy enough to spin up Immutant instead.
Whereabouts would I put wrap-reload
in this example? I think it should go in my-middleware
but I’m not sure how, given that it wants a var. Or perhaps somewhere in middleware-stack
, but if I put it in the threading macro it doesn’t seem to do anything, again, I think because it wants a var? But if I wrap it like (-> blah (var) (wrap-reload) (var-get))
it doesn’t seem to work. Any tips are greatly appreciated!
I've never used wrap-reload
. I try to avoid all of the "magic" reload stuff.
That usermanager example already uses vars when constructing middleware so that you can evaluate code into the running app without needing the "reload" stuff.
The way I work (with all our web server processes at work) is that I start them from the REPL via my editor and then I can edit the code and just eval the updated function directly into the running process. No need to save a file. No need for a process that watches for changes and reloads files.
ahhh i see. that’s probably better, even. thanks for the insight. that’s exactly the kind of thing i want to be aware of as an option, a process-wise change rather than blindly looking at some half-understood black box of technology. you’ve been really helpful. thanks!
Here's an example using mount (but http-kit instead of immutant): https://github.com/codonnell/mygiftlist-blog/blob/4bf305045319d923b11c9c7a8bdfd49753a0f110/src/rocks/mygiftlist/server.clj. Should be very similar with immutant.
(I really don't like Mount because of the global singleton state -- I think Component is a more idiomatic Clojure approach)
☝️ I ended up converting that project to integrant for exactly that reason.
You also have mount-lite and systemic which are similar to mount, but allow multiple systems to run more easily (though with some other caveats)
Specifically, I wanted to spin up a separate system of components for dev vs. test, and mount made that really hard.
Ah, okay. I don’t think I understand enough about either to have an informed opinion but I have relied on your work before @seancorfield so I’ll probably just use Component because if you and tonksy use it it’s good enough for me.
About the user
namespace, I think it is common to have it at dev/user.clj
and include :extra-paths ["dev"]
in a :dev
alias in your deps.edn file.
Ahh okay, I’ve seen something like that before but wasn’t sure where or how to express it. Thanks to you both!
The project I linked above does that; you can look at it as an example if you like. Personally, I like to put convenience functions to start/stop/restart/reload my system there.
Also, I don’t really have a reason to be using immutant other than seeing it win some benchmarks and how it has a lot of batteries included. Should I narrow my scope and only worry about ring and jetty then?
We use (embedded) Jetty in production and it's been solid.
I think ring and jetty is a solid choice.
@ericnormand also recommended Jetty a few months ago: https://purelyfunctional.tv/mini-guide/clojure-web-servers/
At work we have a dev
folder with some utilities, like starting a REPL with a Socket REPL and the Cognitect REBL UI, and we add them via aliases, like @codonnell suggests.
does anyone know of any projects that use sparkledriver, so some other web scraping library that opens a browser headless, clicks a button on the page to generate the dynamic HTML, then parses that? I need some real examples I can look at.. I've been through a couple libs, which I later figured out couldn't interact with the page, then I landed on sparkledriver and having issues figuring out a few things and have been googling for hours... any recommendation would be appreciated, either here or DM.. thanks