This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-09
Channels
- # adventofcode (132)
- # announcements (19)
- # babashka (7)
- # babashka-sci-dev (6)
- # beginners (46)
- # calva (25)
- # chlorine-clover (5)
- # cider (2)
- # clara (17)
- # clj-kondo (93)
- # clojure (2)
- # clojure-dev (4)
- # clojure-europe (12)
- # clojure-losangeles (3)
- # clojure-nl (7)
- # clojure-uk (4)
- # clojurescript (29)
- # conjure (6)
- # core-async (8)
- # cursive (16)
- # data-science (7)
- # datomic (1)
- # exercism (4)
- # figwheel-main (8)
- # fulcro (9)
- # graphql (2)
- # helix (1)
- # introduce-yourself (3)
- # jobs (3)
- # lsp (4)
- # malli (20)
- # minecraft (3)
- # nextjournal (62)
- # off-topic (16)
- # overtone (34)
- # pathom (5)
- # polylith (10)
- # portal (1)
- # re-frame (104)
- # reagent (29)
- # reitit (1)
- # remote-jobs (2)
- # rum (3)
- # shadow-cljs (22)
- # spacemacs (2)
- # sql (10)
- # tools-deps (17)
- # vim (13)
Hello, what is best way to slurp a file in resources for test? I understand I can do a (slurp (io/resources "dummy.edn"))
but my issue is that I'm using lein-modules
so depending on where i start the repl, (io/resources "dummy.edn")
might not work in the repl. Do I need to use the second arity of io/resources
and include a loader
?
io/resource
lets you read a resource/file from the classpath, so as long as your files are on the classpath, that will work. So the solution is: start your REPL somewhere that has the classpath you need.
If you start a REPL in the wrong directory, you will have an incorrect classpath.
I have a directory/project that is for starting the repl in (like a dev folder), where I load the other modules as source-paths
. Is there a way I can do a slurp that doesn't involve using the full path, but still allow me to this code to work in the repl?
All the resource files from your classpath will be available. You could try listing the resources available in io/resource and you'll see what's there:
(-> (io/resource ".")
io/file
file-seq)
If it's something that should work long term/in prod you should figure out the class paths so that the code that uses the file has access to it.
If you only need it for a while you can use plain slurp
from your own filesystem
That didn't really list out the resources but it did help me find out what's my classpath
Is there a way I can include more directories in the class path? Or change the classpath of the repl? Am trying to think of the best ways to work around this, given how my project is set up
I have a scenario where i want to fetch a value, which is updated outside of the system itself. If this value is "In-progress" i will need to repeat fetching and checking the value until the value has changed to another status, maybe even with some delay. Is there a common way to approach this problem in clojure?
@U01GQRC8W30 It probably depends on what you want to do with the value once you've fetched it. You could use a promise so that the caller can block until the fetch returns a non "in-progress" value by using deref
on the returned promise
(let [p (promise)]
(future
(loop []
(let [v (fetch-value)]
(if-not (= v "in-progress")
(deliver p v)
(recur)))))
p))
Alternatively, if you don't want the caller to be blocked, the fetch function could be passed a callback to run on the fetched value once it returns a non "in-progress" value.
(defn fetch-and-doit [doit-fn]
(future
(loop []
(let [v (fetch-value)]
(if-not (= v "in-progress")
(doit-fn v)
(recur)))))
There's also libraries which help with this sort of thing. I like https://github.com/mpenet/auspex
I'd like to add a docstring to a memoized function, presenting the appropriate times to use it vs the non memoized version.
If I only do:
(def f-mem (memoize f))
then there's no docstring.
If I do:
(defn f-mem "docstring" [] (memoize f))
there's a docstring but not the correct argument list
Is there a nice way to do this?
(def f-mem "docstring" (memoize f))
?
docstring is just a metadata attached to the var
I thought you wanted a different docstring for the memoized version but yeah if you want to reuse the one of the original function you have to do what @U04V4KLKC suggested.
Btw, in your defn
example, f-mem
is a 0-arity function, so you have to call it in order to get the memoized version of f
, that's why (f-mem x)
doesn't work but ((f-mem) x)
does. (memoization won't work with the latter though - you'll get a different memoized function every time you call it)
Adding to what has already been suggested, if you want to annotate the arglist of the memoized version you can add the arglists
metadata
^{:arglists '([arg1 arg2])}
Ah interesting, I'm giving it a shot!
due to the length of the comment I also tried the with-meta
, and when I looked at the source code I eventually went with that style of metadata:
(def
^{:arglists '([^clojure.lang.IObj obj m])
:doc "Returns an object of the same type and value as obj, with
map m as its metadata."
:added "1.0"
:static true}
with-meta (fn ^:static with-meta [^clojure.lang.IObj x m]
(. x (withMeta m))))
memoize doesn't provide any control over what it saves, and that just grows and grows, and a def is a global
Mandatory plug for https://github.com/clojure/core.memoize if you do need to do this
a set of maps sounds kinda strange to me. But presumably you can just do (into #{} coll)
and have the result you want
data in form of lazyseq is [{:key1 "value1" :key2 "value2"} {:key1 "value3" :key2 "value4}]
I want to do into #{}
only key1
values
(into #{} (map :key1) [{:key1 "value1" :key2 "value2"} {:key1 "value3" :key2 "value4"}])
#{"value1" "value3"}
Is there a common idiom for: you've got a map shape and a function foo
that processes it, but you want to use the same function name for a collection of those maps?
you typically don't create functions that operate on a collection of the same item since it's usually the same number of characters and less general than (map foo my-maps)
i was trying to avoid keeping track of when i had a single or a collection but, i guess that's a programmer job not a computer job
yea, that's a tempting pattern, but I've found that it usually just leads to unnecessary complexity and hard to find bugs
it's the same trap that you end up in any time you think you want to use flatten
(and I think he has one about "heisenparameters" which covers the case of a parameter which might be a collection or not...)
Oh, haha, yeah, he even links to it in the first line of the redundant map post! https://stuartsierra.com/2015/06/10/clojure-donts-heisenparameter