This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-15
Channels
- # announcements (10)
- # beginners (113)
- # calva (2)
- # cider (75)
- # clj-kondo (1)
- # cljdoc (2)
- # clojure (142)
- # clojure-europe (11)
- # clojure-gamedev (6)
- # clojure-italy (7)
- # clojure-nl (8)
- # clojure-spec (3)
- # clojure-uk (50)
- # clojurescript (47)
- # cursive (7)
- # data-science (22)
- # datomic (12)
- # dirac (3)
- # events (1)
- # fulcro (114)
- # gorilla (1)
- # jackdaw (5)
- # joker (3)
- # kaocha (10)
- # leiningen (1)
- # liberator (2)
- # mount (6)
- # nrepl (1)
- # off-topic (16)
- # pathom (34)
- # pedestal (3)
- # re-frame (19)
- # reagent (11)
- # remote-jobs (5)
- # shadow-cljs (127)
- # spacemacs (12)
- # test-check (15)
- # tools-deps (8)
- # vim (4)
Any idea how I can achieve this in Compojure:
(def app
(-> (wrap-defaults (get-app-routes handler) site-defaults)
I want to define the routes based on the hostname. The problem of course is handler
above is not defined.I am not missing parens. I just omitted some middleware. get-app-routes looks like this for now:
(defn get-app-routes [handler]
(defroutes app-routes
(GET "/" [] "Hello")))
The idea is to return different app-routes
based on the hostname that I can get from the handler request object
I can’t think of any clear solution for this since I don’t understand the case very well. My last bit of advice is you might be able to get away with just using routes instead of defroutes because it doesn’t seem like you’ll use app-routes directly anyway.
maybe middleware might be the way, maybe just a conditional in the routes themselves. 😅 sorry I can’t be more useful, hope someone else can help.
I finished my results of comparing Clojure, C, Python/Jython/Cython, Ruby/Jruby for the nth term of Fibonacci.
Hi, I have a simple TTL cache built around an (atom {})
the logic that gets a value either finds an entry or gets a new one if the entry was missing or already expired (the loading of the entry involves a short Redis IO op). Dead simple.
Now, I want to improve it and make it thread-safe. It is not not entirely thread safe because 2 threads can find a missing/expired entry and trigger a load (redis call) simultaneously.
How would you recommend locking the IO per key?
1. (locking cache-key ...)
comes to mind but is not so the Clojure way (also, I’ll have to maintain an additional map of locks)
2. maintaining a map of entry as ‘loading’ ref
s where every load from DB is a transaction on the corresponding ref. This also sounds overly complex.
Any more inspirations?
core.cache has composable caches and the ability to define a custom cache. I wonder if you implemented a custom cache that uses redis to back it and then composed it with the built-in ttl cache if that would give what you want https://github.com/clojure/core.cache/wiki/Extending
@rutledgepaulv I wonder where are you aiming at. The core.cache implementation does not ensure that a fetch for a single key is called once. on the contrary:
(defn get-data [key]
(cache/lookup (swap! cache-store
#(if (cache/has? % key)
(cache/hit % key)
(cache/miss % key (retrieve-data key))))
key))
assumes that retrieve-data
can be called multiple times since if multiple threads race on the missing key branch than the atom
implementation will trigger a retry for the ‘loosing’ thread. Since the eviction policy I implemented is very naive (and that is quite okay for me), what I am looking for is just to ensure that retrieve-data
is ensured to be called once per TTL expiry and not more. This is since I want to protect my DB against a flood of requests once the TTL of many object expires. @seancorfield maybe you have some ideas?@ido Check through the open issues on the repo: there's discussion of exactly that issue and an example of how to ensure retrieve-data
is only called exactly once.
@seancorfield no issues on that github page: https://github.com/clojure/core.cache what m i missing?
@seancorfield no issues on that github page: https://github.com/clojure/core.cache what m i missing?
@seancorfield I think I found it here: https://dev.clojure.org/jira/browse/CCACHE-50
Right. I have a notebook with ideas about how to make higher-level usage of the caches easier. There are some gotchas with TTL as well because lookup
can cause cache expiry so the simple, obvious usage can return nil
-- which cache.memoize
has to deal with.
Hello guys, is it possible to overwrite the functionality of default protected java method from clojure?
clojure.lang.PersistentQueue/EMPTY
@ido carmine looks great, but I would need some kind of ui to check the data, as well as retries and such
is there a nicer way to write this:
(defmacro define-multiple [things]
(into []
(for [[k v] things]
`(def ~(symbol (name k)) ~v))))
(define-multiple {:a 3 :b 2})
(defmacro defmany
[definitions]
`(do ~@(for [[k v] definitions]
`(def ~(symbol (name k)) ~v))))
for
returns a list of forms, e.g. ((def a 1) (def b 2))
, so using ~@
splices the outer set of parens away
I don't think that's doing what you want
usually if you're emitting multiple top-level things, it's best to wrap it in a do
if the result of (clojure.java.shell/sh "hostname")
is correct, that would be one way to get it
you could also ensure that it's set in the environment or passed as an arg to -main
the server-name that you get in a ring request is from the value of the client sent Host header, and not your hostname
Yeah, I want to determine the subdomain the request is coming from before creating Ring's handler
It's for a SaaS system using subdomain but the company offers multiple products. For that reason, I need to set a different set of routes based on the subdomain.
I thought I could get it to work like this: (as-> handler x (wrap-defaults (get-routes x) site-defaults)
but it turned out the routes are parsed on the startup only.
It doesn't matter what it is for though, right? You are asking to get the value of the host header, which is sent by clients each request, and can vary, before a request has been sent, which is impossible
I will need to ping the DB to see which app to use for the provided subdomain before creating the routes
You'll need you create a handler, which takes a request, hits the DB, looks up base on the host header, then generates the routes and applies them to the request
Basically stop def'ing routes as global(which is terrible any way), because you need to parameterize them
Def'ing routes as a global value (as seen in lots of docs and tutorials) means 1. Parameterizing your routes doesn't work 2. Your handlers have to globals too
When can I define them if not globally? That's all I saw in the docs like you mentioned.
that's the thing, I use the #()
syntax all the time, and I'm not sure where I should use partial instead
I think people prefer to read the anonymous function version rather than the partial. but partial isn't out of place i don't think
there is no should. I think someone mentioned that had the anonymous version been around earlier in Clojure's life partial
might not have been made
partial
is nice cuz it very plainly says, "i'm returning a function that is just waiting on final input"
#()
to me says, "this is an anonymous function" and requires a different kind of parsing
partial
feels like clojure's version of currying
oh? well, okay then!
which is not to say that people don't, and it's fine that they do, but #()
is imo the Clojure way to do this
just my own opinion and it's ok for others to have their own preferences :)
What feels more "Clojure" to you about #()
?
one thing a partial obscures the remaining calling convention whereas #(func %1 :foo %2)
is clear that it expects two more args. Also, if you refactor the signature of the function partial
might no longer be up to the task leading to needless churn in a diff. For instance, (defn foo [a b c])
you can use (partial foo a b)
but if you change the signature to (defn foo [a c b])
you can no longer partial this application and you would have to switch to #(foo a % b)
instead of just changing the position of the %
and the b
Also #(func 1 2 %)
compiles to a function directly whereas (partial func 1 2)
compiles to a call (to partial
) that returns a function. The performance difference is tiny -- I'm mentioning this more to highlight there is a runtime element to partial
whereas the anonymous function is a compile-time expression.
to add on this, partial
also causes the stacktrace to point at partial$fn<whatever>
instead of making acustom class, which can make debugging way harder
(I'm one of those folks who still tends to use partial
but I admit that I'm moving away from it...)
partial
also captures the var value instead of the var, so it can lead to surprising behavior when using dynamic vars for example
user=> (def ^:dynamic *a*)
#'user/*a*
user=> (def f (partial + *a*))
#'user/f
user=> (def g #(+ *a* %))
#'user/g
user=> (binding [*a* 1] (g 1))
2
user=> (binding [*a* 1] (f 1))
Execution error (ClassCastException) at user$eval164/invokeStatic (REPL:1).
clojure.lang.Var$Unbound cannot be cast to java.lang.Number
@gtzogana if it's convinent, yes, but you should also have the function version for when you want to use it in a higher-order context, or when the value needs to be resolved at runtime
what's the best reaction for "that's a good point i hadn't considered. thanks"
sometimes you need to use the function version when the binding map is built at runtime
to add on this, partial
also causes the stacktrace to point at partial$fn<whatever>
instead of making acustom class, which can make debugging way harder
Interesting points in favor of #()
. Normally I favor partial
because #(% ...)
looks like someone swearing in a comic book
But yeah looks like I should switch
if I have a lazy repeat
in clojure, can I turn it into a lazy vector I can use with assoc
?
what are you trying to achieve. often its best to take a step back and figure out if there's a better way
you could use map-indexed
and something like
(let [index 3]
(map-indexed (fn [i x]
(if (= i index) :replaced-value x))
(range 6)))
(0 1 2 :replaced-value 4 5)
I don't really see how a map makes a better tape model than a vector when the tape is a sequence?
the lazy thing was because I thought doing a lazy tape was elegent and solves the bf interpreter problem of running out of tape
e.g. with a map you can assoc a value in for 1e3 without needing a value in the map for everything between 0 and that
Can you help me understand the difference between these two forms of generating a lazy sequence?
(defn evens-v1
([]
(evens-v1 2))
([n]
(lazy-seq (cons n (evens-v1 (+ n 2))))))
(defn evens-v2
([]
(evens-v2 2))
([n]
(cons n (lazy-seq (evens-v2 (+ n 2))))))
As far as I can tell, these both behave identically. Their return types are LazySeq
.the boundary of laziness is lazy-seq, so you would say evens-v1 is slightly more lazy and evens-v2 is slightly more eager
so with evens-v1, when you call it returns a lazy seq, and when you call first or rest on it, the body of the lazy-seq call is executed and cached, and first or rest is called on it
with even-v2 when you call it, it cons's n on to the unforced lazy seq constructed by lazy-seq and returns that
Ok, so the difference is basically negligible but version 1 is truly lazy since v2 starts creating that sequence (albeit a single element of it) when you call it even before it is realized.
correct, the difference in this case is negligible, but it can be larger, it depends on the amount of computing required to construct that initial element
I am not sure I have come across a case where it mattered a lot, but in general I try and hoist lazy-seq calls up as high as possible so they wrap as much of the function body as possible
can someone help me with a bit complex regex/replace problem. I need anything that matches to be wrapped one way, anything that doesn’t match the other way, e.g.: if given string like: “Donec vitae dolor color or sotamayor” I want to highlight everything that matches “or”, basically I want it to become something like:
[:span "Donec vitae dol"
[:span.h "or"] [:span "col"] [:span.h "or"] [:span " "] [:span.h "or"] [:span "sotamay"] [:span.h "or"]
matching part is relatively easy… but I can’t figure out how to replace things that do not match
@ag I'd be inclined to use the .find
.end
methods, each returns a numeric index you can use with subs
and then use cons and recursive calls (maybe with lazy-seq even)
take string, call .find
get a start index, call .end
get end index, cons two strings, then self-call
https://github.com/ztellman/automat could be useful
string/replace could be possible, but I think the self-call cons approach is easier to think about
so like if I want for example wrap anything that doesn’t match “or” and place it between “^” and “$”… :
(clojure.string/replace
"Donec vitae dolor color sotamayor"
#"(?!or)"
#(str "^" %1 "$"))
except it’s not working as I would like it to ;((let [states {\o {:string :o}
\O {:string :o}
\r {:o :or}
\R {:o :or}}]
(reduce (fn [[acc [state buffer or-buffer]] c]
(let [new-state (get-in states [c state] :string)]
(case new-state
:string [acc [:string (str buffer or-buffer c) ""]]
:o [acc [:o buffer (str c)]]
:or [(conj acc buffer (str or-buffer c)) [:string "" ""]])))
[[] [:string ""]]
"Donec vitae dolor color or sotamayor"))
[["Donec vitae dol" "or" " col" "or" " " "or" " sotamay" "or"]
[:string "" ""]]
but a regex is a kind of finite state automata, and automat is a more flexible way to construct those
I am no regex wiz, but I think your issue is, regex is a character by character scan, and you are trying to say, chunk things in to groups that are not this two character sequence
but a regex would only match the character sequence at a time, so even if it did work, you would get lots of two character slices
egret.run=> (re-split-seq "Donec vitae dolor color or sotamayor" #"or" (fn [x] [:span.h x]) (fn [x] [:span x]))
([:span "Donec vitae dol"] [:span.h "or"] [:span " col"] [:span.h "or"] [:span " "] [:span.h "or"] [:span " sotamay"] [:span.h "or"] [:span ""])
imperfect, but it's a start
(defn re-split-seq
([s re marked unmarked]
(let [matcher (re-matcher re s)]
(re-split-seq s re marked unmarked matcher 0)))
([s re marked unmarked matcher unmatched]
(let [found? (.find matcher)
start (when found? (.start matcher))
end (when found? (.end matcher))]
(if found?
(cons (unmarked (subs s unmatched start))
(cons (marked (subs s start end))
(re-split-seq s re marked unmarked matcher end)))
(list (unmarked (subs s unmatched)))))))
in js you'd want .search
(returns index of start of match) and .lastIndex
and you'd use a RegExp instead of matcher (I assume in cljs #"" is already a RegExp)
sorry guys… I got dragged into fixing an issue in an RC. Thank you all for your suggestions, I will try them! :spock-hand: @noisesmith @hiredman @dpsutton
@rutledgepaulv I wonder where are you aiming at. The core.cache implementation does not ensure that a fetch for a single key is called once. on the contrary:
(defn get-data [key]
(cache/lookup (swap! cache-store
#(if (cache/has? % key)
(cache/hit % key)
(cache/miss % key (retrieve-data key))))
key))
assumes that retrieve-data
can be called multiple times since if multiple threads race on the missing key branch than the atom
implementation will trigger a retry for the ‘loosing’ thread. Since the eviction policy I implemented is very naive (and that is quite okay for me), what I am looking for is just to ensure that retrieve-data
is ensured to be called once per TTL expiry and not more. This is since I want to protect my DB against a flood of requests once the TTL of many object expires. @seancorfield maybe you have some ideas?@seancorfield no issues on that github page: https://github.com/clojure/core.cache what m i missing?