This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-02-12
Channels
- # aleph (22)
- # aws (7)
- # babashka (17)
- # beginners (69)
- # chlorine-clover (9)
- # cider (2)
- # clj-kondo (3)
- # cljdoc (30)
- # clojure (113)
- # clojure-dev (30)
- # clojure-europe (11)
- # clojure-italy (2)
- # clojure-nl (16)
- # clojure-spec (1)
- # clojure-sweden (3)
- # clojure-uk (17)
- # clojurescript (77)
- # cryogen (12)
- # data-science (5)
- # datomic (27)
- # duct (2)
- # emacs (37)
- # fulcro (24)
- # graphql (2)
- # kaocha (1)
- # lambdaisland (27)
- # leiningen (4)
- # off-topic (15)
- # onyx (1)
- # other-lisps (3)
- # re-frame (94)
- # reagent (2)
- # reitit (20)
- # ring (1)
- # shadow-cljs (66)
- # spacemacs (5)
- # sql (59)
- # tools-deps (140)
- # vim (1)
- # xtdb (17)
this makes me sad, but it works - is there a more reliable way to provide properties as args with spaces that don't get broken by the shell?
repl_arg () {
if [ "$REPL_PORT" != "0" ]
then
printf '-Dclojure.server.repl={:address,"0.0.0.0",:port,%d,:accept,clojure.core.server/repl}' $REPL_PORT
fi
}
It seems to be the best workaround that I've heard works reliably.
One level of shell quoting/escaping is bad enough. Multiple levels is enough to drive people to weep in despair. Especially multiple levels and variables that can have spaces in their values.
It seems perhaps possible that someone could write clj
/ clojure
shell scripts that avoid the desire to do this, but I suspect it is made significantly more difficult by the variety of versions of bash/sh deployed on various systems.
I'm looking at the implementation of the transducer arity of partition-all
(which I'll put in a thread), and I'm having trouble figuring out why it calls unreduced
in the single-arity body of the reducing function. I haven't been able to get partition-all
to behave differently without this unreduced
call despite trying various compositions of transducers and a "base" reducing function that uses reduced
. Does anyone have any insight into why unreduced
is included?
partition-all
definition:
(defn partition-all*
"Returns a lazy sequence of lists like partition, but may include
partitions with fewer than n items at the end. Returns a stateful
transducer when no collection is provided."
{:added "1.2"
:static true}
([^long n]
(fn [rf]
(let [a (java.util.ArrayList. n)]
(fn
([] (rf))
([result]
(let [result (if (.isEmpty a)
result
(let [v (vec (.toArray a))]
;;clear first!
(.clear a)
(unreduced (rf result v))))]
(rf result)))
([result input]
(.add a input)
(if (= n (.size a))
(let [v (vec (.toArray a))]
(.clear a)
(rf result v))
result))))))
([n coll]
(partition-all n n coll))
([n step coll]
(lazy-seq
(when-let [s (seq coll)]
(let [seg (doall (take n s))]
(cons seg (partition-all n step (nthrest s step))))))))
user=> (doc unreduced)
-------------------------
clojure.core/unreduced
([x])
If x is reduced?, returns (deref x), else returns x
nil
I'm sure you looked at this already, but including here for reference
so thinking out loud, it needs to override some other step's reduced
setting for the result
and this needs to result in propagating a partial result at end of input
Found an example in clojure core tests!
(transduce (comp (take 1) (partition-all 3) (take 1)) conj [] (range 15))
Now to puzzle through exactly why this behaves differently. I'm sure you're right at a high level about why it's needed; I just need to dive in a little more to wrap my head around the exact mechanics at play.Without the unreduced
, this returns a Reduced
.
that's a good clue - it could be that the way it handles "flushing" for a partial partition is going into internals somewhat, so it might circumvent the part of transducing that normally unwraps and short circuits when a reduced is found?
I think it is because it's calling the 2-arity version of rf
from its 1-arity body.
In the example above, the right-most (take 1)
returns a Reduced
when partition-all
calls it in its 1-arity "finalization" step. I'm guessing that it's okay to return a Reduced
in the 2-arity case because (trans|re)duce
will unwrap it and then call the 1-arity version of the reducing function.
But perhaps (trans|re)-duce
do not expect a Reduced
as a result in the 1-arity case since the reduction is already finished and just doing cleanup.
So basically, exactly what you said but in language my brain understands 😉
Thanks!
glad I could help
also consider that for correctness it should only unwrap reduced values in one place - otherwise it can't be used to create a reduced value for some consumer up the stack, so since you've circumvented that path, you need to unwrap it by hand(?)
Thank you for clojure cli (deps.edn) It's really great! deps.edn + calva = great for learning.
@i We use Component and read in the config from EDN files at startup and then pass (parts of) the component as arguments.
I haven’t used component yet (only mount). Can another component refer to the config component?
@i other mount states should be able to refer to the config mount state. We use mount at work and read the config into a mount state. Other states can depend on the config state in their :start
forms.
@jysandy yes. that’s what makes me feel uncomfortable. because in that approach, the config state is a global variable whose location is hardcoded and then imported inside other modules.
It is global, but it isn’t a variable in the traditional sense. It can only be mutated through start
and stop
.
Global mutable state is bad, but when the mutation is controlled or limited, I think it’s fine. It’s really not very different from having a singleton object in an OOP language IMO.
Mount has a lot of problems that Component solves.
With Mount you are tied to namespace-level globals. With Component, you have no globals, just lifecycle and then pass through the argument chain.
Components can depend on other components so, yes @i, your config can be referred to by other components.
I really don't understand people's enthusiasm for Mount... sorry, but I just don't.
i have a bottle here floating in the ocean of a developer with 20 years of commercial experience and 30 years of overall coding experience, it has a single note written in it "globals are bad."
Where is positions
? I find these traces of it here https://clojure.github.io/clojure-contrib/seq-utils-api.html, but I do not understand the instructions on where it has actually moved...
I do not believe it has moved into any current Clojure contrib library, at least not one I am aware of. There are several current 'utility function' libraries that are used by many people, but not sure if positions is in any of them. medley, plumbing, useful
If you find source code for something you want in one of those old contrib libraries, there should be no problem copying and pasting it into your own code if you want.
But, while at it. How would go about this today? https://www.mail-archive.com/[email protected]/msg34159.html
No preview, I notice, but anyway, it is Stuart Halloway advicing to lazily find all indexes and then pick the first one if one wants to find the position of something when it first appears in a vector.
This looks like it might be a correct implementation of positions
:
(defn positions [pred coll]
(keep-indexed (fn [idx item] (if (pred item) idx)) coll))
It is a lazy implementation, because keep-indexed
is lazy
Does anyone here has familiarity with monger library?
@i mount
’s take on its differences from component
is probably also a good read. https://github.com/tolitius/mount/blob/master/doc/differences-from-component.md#differences-from-component
You could also perhaps look at https://github.com/weavejester/integrant
Hello all, how do I convert this
List<MatOfPoint> contours = new ArrayList<>();
to Clojure?Be aware that contours will permanently be the empty array as Clojure vector is not mutable. It is unlikely that you really want an empty array like above.
the trouble is, target type is not
an array, but List<MatOfPoint>
... so I guess the nearest thing is (def contours (java.util.ArrayList.))
I would suggest to stick to clojure vector if mutability is not required, that depends on the use case
good morning...having an issue with looping through a db query result within a for loop
I keep getting java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to clojure.lang.Named
Please use backticks (`) around the code to format it. As for the error, it must be at some other place. What's the stacktrace? What's at the line in your code that the stacktrace points at?
Here's a resource for what question "replyers" normally need to provide a good answer: https://stackoverflow.com/help/minimal-reproducible-example
I'm using the for loop within a clj-pdf call to create more cells in a [:table]
...after a bit of investigation the for loop itself (when evaluated outside of the clj-pdf call) works just fine...the issue is then inserting this structure into :table
and having it resolve properly...I'll try [:pdf-table]
maybe that will work
You're just stumbling around in the dark, while you have a well-defined path on how to proceed. Step 1 on that path: post the actual stacktrace here. Use triple backticks to insert code blocks.
similar to errors created in project.clj files where there are elements intended to be in the dependencies but are actually outside of it because of a misplaced ]
There is a #datomic channel.
Hey friends, I'm getting nondeterministic indentation from cljfmt on (as-> var v
threading macros. My question is this, am I writing confusing code that is hard to format, or is there maybe a bug involved. Thanks! Here's the first part of the form, in case that matters. I keep getting an additional space added or removed from the cond form's indentation
(as->
this t
(cond
PS I did see the cljfmt channel but it seemed dead
I usually inline the first two args and haven't seen issues with that:
(as-> this t
(cond ...))
But I'm not sure why it would matter 🤷Well that would be easier then going for a bug hunt! I'll give that a shot
> PS I did see the cljfmt channel but it seemed dead you can check whether the author belongs to that channel... although for that matter one can create a GH issue as well - sometimes questions are appreciated for improving documention I second Daniel's suggestion btw!
Thanks! I feel bad asking people to fix it when I could just as well do it myself but you're right, a github issue is better than doing nothing 😁
can anyone help me with this? https://stackoverflow.com/questions/60191811/clojure-core-map-behaving-in-a-very-surprising-manner
What libraries are people using for interacting with PostgreSQL?
Check #sql but jdbc and jdbc.next are good
We use https://github.com/jkk/honeysql and https://github.com/seancorfield/next-jdbc - both working ok for us.
Thanks everyone. Looks quite diverse on the choices people have made
I'm looking for some advice on how to test code that makes changes to an atom which is bound to a global var. I can think of multiple ways, none of them sound too great to me.
First idea: I simply call my function, then go check to see if the atom holds what I expect.
have you considered not having a global var :)
somewhere up the chain you will need to pass it in, but the further you push that off the better
well, in principle, yes, but the context is a reagent cljs app and the atom in question holds the global app state, so I would have to hand this around quite a bit
jokes aside: passing the atom or using re-frame for events/subs should make it somewhat more testable
Yes, I can see how to handle this in re-frame. That's currently unfortunately not what I'm using.
I'm assuming you're relying on a ratom in your component? Technically passing it in as an argument, and derefing it inside of your component code should work, right? I've only worked with re-frame and "raw" react in JS so I might be missing some details - I think folks in #clojurescript or #reagent will have better answers/suggestions
(def n (atom 0))
(defn incs [] (swap! n inc))
;; VS
(def n (atom 0))
(defn inc-count [count-obj]
(swap! count-obj inc))
so, am I interpreting this right that the best practice in a reagent app would be to pass the global state around between components? Just asking, because that's not what I see in the docs or in the examples. I guess this could also lead to unwanted re-rendering of components, if not handled carefully.