This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-10-07
Channels
- # announcements (10)
- # architecture (25)
- # babashka (5)
- # beginners (95)
- # calva (1)
- # cider (3)
- # clerk (16)
- # clj-on-windows (41)
- # clojure (64)
- # clojure-europe (7)
- # clojurescript (9)
- # deps-new (2)
- # graalvm (25)
- # honeysql (3)
- # hyperfiddle (19)
- # malli (1)
- # meander (5)
- # music (1)
- # nbb (1)
- # off-topic (54)
- # rdf (10)
- # releases (2)
- # shadow-cljs (12)
- # tools-deps (41)
I'm wondering how, when calling Java methods, to deal with the fact that Java dispatches on argument type, and it seems like Clojure maybe only dispatches on arity? Example to follow in the thread
(import '(java.nio.file Paths Files))
(let [path "src/foo.clj"]
(Files/readAllBytes (Paths/get path)))
fails with:
java.lang.ClassCastException: java.lang.String cannot be cast to java.net.URI
even though Paths.get takes both strings and URI objsI then tried something like:
(import '(java.nio.file Paths))
(let [path #^String "src/foo.clj"]
(Paths/get path))
but that fails with:
Metadata can not be applied to "src/foo.clj". Metadata can only be applied to IMetas.
(let [path ^String "src/foo.clj"]
(Paths/get path))
gives
; (err) : java.lang.String cannot be cast to clojure.lang.IObj foo
Paths/get
is defined as: https://docs.oracle.com/javase/8/docs/api/java/nio/file/Paths.html#get-java.lang.String-java.lang.String...-(https://docs.oracle.com/javase/8/docs/api/java/lang/String.html first, https://docs.oracle.com/javase/8/docs/api/java/lang/String.html... more), so you have to do: (Files/readAllBytes (Paths/get "src/foo.clj" (into-array String [])))
I was going to link to https://docs.oracle.com/en/java/javase/20/docs/api/java.base/java/nio/file/Paths.html but Martin beat me to the explanation...
oh... ok thanks
I mean, I know the signature. But since in Java Paths.get("mypath") works, I didn't think that I needed a vector arg the second array of String arg.
Varargs in Java is tricky from other languages because of the implicit array argument. Some of the changes coming in Clojure 1.12 may improve that in some cases, and more work on varargs is planned for 1.13.
Thanks so much for the help both of you.
hi! I have a couple programs I'd like to implement in clojure, but they all currently have a hot loop in which the "state of the world" is updated. it's the bottleneck of the whole program - it takes the world state and updates it on an every tick. imagine an emulator that has to take the user input & the state, update it, and render a frame. is there any good way of doing that in clojure, without creating a ton of garbage while updating the big "state of the world" map in a tight loop?
there are volatiles (scroll down a bit on https://github.com/clojure/clojure/blob/master/changes.md#21-transducers or see https://clojuredocs.org/clojure.core/volatile!) but i would recommend first trying to implement it without them to see if the jvm can handle the garbage produced from normal swap!
with e.g. assoc
sorry, I'm a bit zonked — https://clojure.org/reference/transients would be another option between those two
volatiles look interesting, thanks! I've never actually used transients, but to me it seems like you need to "freeze" the value after constructing it, is that correct? I need to continuously modify the same value and observe it between modifications, I'm not sure if transients support that
There are transducers, which emit less garbage than sequences. And a Clojure program may use Java arrays, arraylists, maps, and sets if you feel they're faster than immutable persistent collections. But keep in mind that short-lived garbage doesn't cost much in the JVM, and "Premature optimization is the root of all evil" (Donald Knuth).
oh, transients aren't write-only even before they're made persistent - cool! and yeah, I agree - I should stop overthinking and just write the code & profile. if I can't make it fast enough I'll pester you guys again 😉 thank you!
;; a.clj
(ns A)
(def animal "whale")
;; b.clj
(ns B)
(println A/animal)
I was expecting failure when I eval’d the last statement in B
at the repl because I haven’t required A
, but it worked. I am perplexed!Once a namespace has been loaded/defined, it’s symbols can be resolved
I have a function that thread-firsts 9 update
calls, each updating a different key and none of the updates rely on the work of the previous calls. Some of the calls are expensive, but they’re all pure functions. Is there any benefit to parallelizing the calls? Is there an existing method of performing such parallel updates? Reducers seemed focused on sequences
you'd need to benchmark it to see the benefit, but if all you're doing is setting independent keys, you can mutate your map in-place as a https://clojure.org/reference/transients, distributing the work across a (managed) thread pool using parallel future
:
(defn expensive-op1 [m a]
(assoc! m :a a))
(defn expensive-op2 [m k v]
(conj! m [k v]))
(let [m (transient {})
updates [[expensive-op1 "A"]
[expensive-op2 :b "B"]]
updated (doall (map deref (for [[f & args] updates]
(future
(apply f m args)))))]
(persistent! m))
Each (future ...)
call returns immediately while work is performed concurrently on a different thread. The map deref
causes it to block until all (future ...)
calls have finished, and the doall
forces eagerness since map
is lazy by default.
Based on: https://levelup.gitconnected.com/back-to-the-future-in-clojure-934b85a3d08eIs that safe? Transients still need their results to be used.
hmmm I guess not > Transients require thread isolation
my bad
I think this is a silly question but I don't understand why this doesn't work as I hope it to.
(map #(int (.charAt % 0)) '("A" "B")) => (65 66)
(let [A "A" B "B"] (map #(int (.charAt % 0)) '(A B)))
=> Error printing return value (IllegalArgumentException) at clojure.lang.Reflector/invokeMatchingMethod (Reflector.java:127). No matching method charAt found taking 1 args for class clojure.lang.Symbol
It looks like it's taking A
and B
as symbols instead of evaluating them, but I can't switch '(A B)
to (A B)
because then it tries to evaluate the list. Is there some other syntax I'm missing here?'(A B)
means (quote (A B))
so there's no evaluation and you get a literal list with two symbols.
In the same way that '(+ 1 2)
produces a list of the symbol '+
and the literals 1
and 2
-- again with no evaluation.
Folks normally use a vector for this purpose tho':
(let [a "A" b "B"] (map .. [a b]))
since map
calls seq
on its argument.Thank you, I misunderstood how quote
worked. I was just thinking of it as a way to let me write a list literal and not treat the first element as a function but which would have its elements evaluated, expecting '(1 (+ 1 2)) => (1 3)
but I see it's more serious than that.
Yeah, quote
means "Here's a literal symbolic form as a data structure!"
You can think of '(...)
as "distributing" quote
over all the elements so '(+ 1 2)
is the same as (list '+ '1 '2)
-- and so '(A B)
is the same as (list 'A 'B)
.
just for another option for building lists you can also do :
(let [A "A" B "B"] (map #(int (.charAt % 0)) `(~A ~B)))
(65 66)

I have to iterate a loop till I see a particular entry. How can I do that the best in clojure ?
I try to figure out how to do this challenge : https://github.com/exercism/clojure/blob/main/exercises/practice/protein-translation/.docs/instructions.md
some
will stop at the first match.
Returns the first logical true value of (pred x) for any x in coll,
else nil.
filter
would keep going.
loop
itself might be overkill: https://clojuredocs.org/clojure.core/loopfor example...
(take-while (complement #{"stop"}) ["a" "b" "stop" "c" "d"])
;; => ("a" "b")
take-while
! I never saw that before. 🙏
Let's say I need a classic OOP-style observer/observable type of thing to notify of property change. For example, in Java, I might have a Person
on which I could addListener
and register a callback that would be invoked when the person's name
changes.
In Clojure, I assume I would represent the person entity as a map, like {:name "Jason"}
. Now I can update the name with assoc
or update
, but where do I put the callbacks? If I put my person in an atom, I can add a watch, but say I don't want an atom. Do I just add the callbacks to the entity map too, under their own key? That makes the map more than "data" since it's got functions in it (can't send that around as edn for example)
Or as another example, think dynamic validation that can be added à la carte to an entity and has the chance to veto an update. Where do I register these validators for a specific entity?
> but say I don't want an atom why not? > Where do I register these validators for a specific entity? You can look at https://clojure.org/guides/spec and https://github.com/metosin/malli for inspiration. The key idea is that whether or not some information is valid depends on the context and use case. The simplest version of that is have a function that lives "near" (eg. same namespace) that returns whether some info constitutes a valid person (for a specific use case).
You don't want to couple validation to an entity, but instead, add validation as part of a process.
Maybe some context has expectations about what it thinks a user should be, but it's an architectural mistake to try and restrict all contexts from even describing or representing a Person in any particular way.
From what I understand, an atom could be my application state, but I wouldn't have one for each individual entity. Another issue with watches is they don't allow vetoing. A common type of listener in GUI components is something that can see if what's been entered in the field is valid, and if not, the change isn't persisted and any listeners that want to know of the change won't be called. I'm kind of curious how this kind of thing works in Clojure.
Right, you would have some process that updates the atom and that process would be responsible for validating that the updates to the atom have valid data.
You can think of your GUI state as an in-memory database. Do you control the rendering or is it a web gui?
I know that doesn't sound like a straight answer, but there are lots of options that make sense depending on the context. One way to do it would be to have a validate function checks the data before it is committed (either to an atom via swap!
or a local db or otherwise).
Hmm I see. I don't have any concrete examples, so I'm just using GUI as an analogy because they're a pretty OO model (even the browser is all about registering event handlers to elements that have properties). I'm trying to build up a mental model for how problems I'm used to tackling in Java land translate over. Having and object that emits events to zero or more interested parties is a pretty common pattern, so I'm just trying to get a sense of what kinds of analogs are available.
@U013JFLRFS8 yeah, but my understanding is that they either accept or throw, not veto which causes the update to be rolled back
Ah, right. So a channel is a sort of listener port, and anything connected to the other end is a listener
That makes sense. Queues are a common enough pattern too. And that's basically what channels are I think
a pubsub style implementation would have unidirectional channels for listeners. The publisher pushes messages onto them
So would my person map hold on to a channel?
If different persons need different registered listeners?
Right, cool. That's been one of the trickier parts learning: a lot of patterns and designs I'm familiar with kind of get turned inside out
Thanks 👍:skin-tone-2:
> So would my person map hold on to a channel? It would not. The person map does do anything. It just describes things. Separately, you have a process that uses information to make decisions (think of a flow diagram).
Just to go back to the GUI example. I actually think Model, View, Update (which was popularized by Elm) does a good job of describing the architecture of what a functional UI program looks like: As you can imagine, the update function can end up doing a lot, but what makes it tractable is that the "large" update function is composed of separate, smaller update functions. It can also be composed with validation.
Based on how complicated UI programming tends to be, it might seem like this process diagram is too small or leaving things out, but you can actually build "sophisticated" UIs with this simple process model.
Even with Elm though, isn't there registered callbacks? Like the view has say two buttons: one button registers an onClick to fire a Decrement message and the other button registers an onClick to fire an Increment message. They're both just "button" entities, but they have different event listeners to send different messages. I do like the separation though. It seems quite clean.
Even with Elm though, isn't there registered callbacks?That's not Elm's fault. That's the price of building on top of HTML.
I guess I'm just having a hard time imagining how you'd represent a button without it being an "object"
Like if HTML wasn't a constraint, how would you handle onClick in a more functional way? Does that even make sense as a question?
It's a great question.
I wish more people would ask it.
I've tried my best to give an explanation on my blog, https://blog.phronemophobic.com/what-is-a-user-interface.html, but I still think the explanation could be improved.
I'll try to give a short answer. Basically, a button is just some data that describes a button. For example:
(ui/button "Click me"
(fn []
;; return some data about what should happen
[[::click]]))
Most of the time, the data is just a title and a function that returns the user's intents for when the button is clicked.
I also recently gave a talk trying to outline how UIs could be more functional and solve some of the complexities from building on top of OO paradigms, https://www.youtube.com/watch?v=Mjn92fODdaA
Interesting talk. So, let me try and say it back to you. You're suggesting that a GUI in a more FP style would deal with callbacks by separating the action itself from some declarative representation of an action you'd like to have happen. So a button could say "when I get clicked, I'd like to declare that a to-do should be added", but there's no callback function that actually goes and adds a to-do anywhere. Separate from this, you could have functions that represent user interaction. Given a component and any relevant arguments (like mouse position), this function would obtain from the component it's declaration of what to do. And then presumably, somewhere else takes that declaration and maps it to actually doing something? (Not shown in your talk) But the key idea is that you defer that as long as possible so that you're dealing with as much pure function stuff as possible. In the Elm example, the onClick is "declarative" in the sense of just being a message to send, not a function that does stuff. But in Elm, that automatically implies an invocation of the registered update function, while you're suggesting that it could potentially be deferred further. Is that right?
Yes, I think that's a pretty good summary. > But the key idea is that you defer that as long as possible so that you're dealing with as much pure function stuff as possible. The main goal is to try and break User Interfaces down into simpler pieces to make them easier to reuse, test, compose, and reason about. It's also about trying to get to the essence of what user interfaces are actually about. A button 1) has a visual depiction and 2) maps user events like mouse clicks to user intents. That's it. Buttons should not be firing missiles. Another clarification I would add is that this is only about the mental model. There's a bunch of interesting optimizations I haven't tried (because I haven't needed to) that would allow you to analyze a given UI description and spit out an optimized version that speeds things up by directly connecting all the pieces.
If you don't have an atom, you are not updating the values, so there is no change to register a callback for. Without an atom, you're just copying the value, leaving the original as-is.
How so? Say I want to run a reduction across some set of values and notify some interested parties each step of the way. And at the end, I take the result and write it to a database. No atom required, but notification should happen.
I've seen some examples in the past of how you can start with an initial state and reduce through all the states of the application (or at least for a particular set of things). Then, separately, you can walk those transformations and do your side effects. No atoms involved. So I suppose the argument may be that doing this doesn't really require registration of listeners? You get kind of the same by just dispatching the states after the fact via some pool of functions.
You still need a way to register that pool of functions though, and define what they care to listen to. Fwks like reframe (I'm very new to it, so forgive me if I'm missing something here) seem to cover this idea with central registration points of functions for messages. I guess that's basically "listeners", just global rather than per object