Fork me on GitHub

is there a short syntax for selecting namespaced keys of off map? e.g.: {:foo/one 1 :foo/two 2 :three 3} I want to do (select-keys m [:foo/one :foo/two]) but without having to repeat :foo


or even better, select all keys that start with :foo/ without even listing them one by one


@ag Not exactly what you are asking, but in the context of destructuring:

user=> (def m {:foo/one 1 :foo/two 2 :three 3})
user=> (let [{:foo/keys [one two]} m] [one two])
[1 2]


I know you can do that


But, presumably you are looking for a shorter version of

(select-keys m (filter #(= "foo" (namespace %)) (keys m)))


yeah, something like that, but I was hoping there’s some magical trick with #:foo maybe


no magic, just functions 🙂


I hate typing. I dunno how people even deal with semicolons and commas and all that crazy garbage in other languages


Type one namespaced keyword, then copy/paste for the others?


I guess with data-readers you could define #foo[:x :y :z] to become [:x/y :x/z] or whatever

Alex Miller (Clojure team)02:06:32

we've talked about extending the namespaced map literal syntax to vectors #:foo[:x :y :z] but then the question is what about sets #:foo#{:x :y} ? gross.


Hum, not the prettiest for sets, but it's not that bad either.


Especially if you put a space in it #:foo #{:x :y}


deps.edn and private git repositories... any advice? getting: com.jcraft.jsch.agentproxy.AgentProxyException: connector is not available:


Hello, how can I stream System.out.println() to the Clojure REPL? I am using a java class compiled with leiningen, and I want to see its log when calling it in the REPL.


(System/setOut ( ( *out*) true))

(.println System/out "hi")

👍 4

Is everyone using Integrant together with Duct or are you also running it standalone?


I'm using it without

👍 8

both with duct and standalone here

👍 4

If I have clj and cljc file for same namespace, in what order are they compiled? Same for cljc/cljs.

Alex Miller (Clojure team)14:06:25

platform specific is always preferred

Alex Miller (Clojure team)14:06:44

so for clojure usage, I don't think you would get cljc compiled/loaded at all

Alex Miller (Clojure team)14:06:49

cljs is more complicated as prob different stories for macro and non-macro


ah, so it only compiles one

Alex Miller (Clojure team)14:06:31

yeah - they are alternate versions of the same namespace

Alex Miller (Clojure team)14:06:57

in clojure, it will look for a .class first (if newer than clj or cljc), then .clj, then .cljc


thank you for that info


hello guys, I have a reservation system which works with agent, so people can't reserve at the same time. But sometimes it stops working, it gives me no exception, and it doesn't restart. how is this possible?


what evidence do you have that it stops working?

Alex Miller (Clojure team)16:06:21

agents can fail and won't restart


well, on my client-side, when people are reserving the server responds that the agent needs restart, like I wouldn't have setup the error handler.

Alex Miller (Clojure team)16:06:34

there are lots of options for how errors and restarts are handled


but presumably you have a whole stack of code between the client and the agent, how do you know the failure isn't in there somewhere?


so, the error-handler! doesn't handle everything? @alexmiller

Alex Miller (Clojure team)16:06:59

I don't have any of it in my head atm, I just know there's lot of stuff there that I use so infrequently that I have to re-read the source


@hiredman because the error is specific to the agent, and because I log the errors and the restarts, and sometimes restarts doesnt happen, only the error

Alex Miller (Clojure team)16:06:17

and honestly, approx 0% of users use this stuff so it wouldn't surprise me if there were unsurfaced bugs


I thought you said you don't get an error?


what is the error that is specific to the agent?

Alex Miller (Clojure team)16:06:21

how are you configuring the agent wrt error-handler and error-mode?


@hiredman, I log in the database for certain functions. like restarting the agent. And when agent restarts I put the error in my logs. In the case when restarting doesn't happen, my error is logged, but is an empty string


@alexmiller, well it is in my snippet, I set-error-handler! after defining it

Alex Miller (Clojure team)16:06:10

the default error-mode of an agent is :fail, not :continue (unless there's an error handler)

Alex Miller (Clojure team)16:06:22

not sure how that changes if you set the error-handler after the fact


so it sounds like you do get an error


it is hard to say since you deleted the logging bits from your example


I put it back, i didnt want chaos


but it sounds like you are getting an error (the error handler is running) and something is going wrong in your error handler


that's the code without modification

Alex Miller (Clojure team)16:06:03

exceptions thrown in the error handler itself are ignored and lost


yeah, you are running the error handler in a future


so they are racing to handle the error

Alex Miller (Clojure team)16:06:45

you've introduced a race here by restarting in the future - restarts are ignored if the agent is not in a failed state


so the error is already cleared by the time you try to get it with agent-error

Alex Miller (Clojure team)16:06:24

I would have to study all that code more closely to really think about the concurrency aspects of this


so, I take out future and it should be fine?


it may or may not be fine, depending, but it will take care of the empty string thing

Alex Miller (Clojure team)16:06:00

it would take me a lot more time to answer that question, and I don't have it atm


I never did concurrency before, this is my first approach on this topic.


But it will restart then, that's what matters, I guess.

Alex Miller (Clojure team)16:06:45

why not just use error-mode :continue?

Alex Miller (Clojure team)16:06:01

then the agent will automatically restart?


in general (depending on the database) you will be much better off using your database features to keep things consistent in the face of multiple writers

Alex Miller (Clojure team)16:06:35

(set-error-mode! reservation-queue :continue)


presumably at some point you want this running on multiple machines, at which point the serialization you get from agents doesn't exist


@alexmillerdidn't know such thing existed, thank you very much

Alex Miller (Clojure team)16:06:44

if you read the docstring for agent and some of the other functions around it, I think that might help


@hiredman No, this project will stay with 22 shops, so I guess I won't need nothing more sophisticated. But I am trying to learn more about the topic, I also enjoy it more than the frontend. 🙂


@alexmiller Thank you, duly noted. If it weren't for a stackoverflow topic, I wouldn't even used future, so yes, next time I start with the docstring.


Is there a way to have (edn/read-string "{:foo 1}") read 1 as an Integer?


Maybe a custom data reader?

Alex Miller (Clojure team)18:06:46

The string above will not trigger any custom data readers


If I understand correctly, a custom data reader could cause a string like {:foo #my-tag 1 } to read #my-tag 1 as an Integer, but that is a different string.


Yeah but could easily be written as (edn/read-string "{:foo #int 1}")

Alex Miller (Clojure team)18:06:28

Even that would read 1 as a Long first

Alex Miller (Clojure team)18:06:48

And your data reader could convert it to whatever


That's fine. I just want the output to be an int.


Warning: most kinds of Clojure arithmetic done on an Integer will not return an Integer.


That's ok. Our app has config files in EDN. Some of those config maps need to be passed via a Properties map to a Java library. Java libraries typically have methods declared that take an int and not long.


if you use Clojure to call those methods, it usually does the right thing


isn't Properties always string->string?


Hmm, lemme see. I definitely get an exception due to a Long being passed instead of an int.

Alex Miller (Clojure team)18:06:29

Properties extends Hashtable so you can abuse it by using the parent class methods to put other stuff in it


I do this (doto (Properties.) (.putAll kafka-config)) and pass it to a Java method.

Alex Miller (Clojure team)18:06:52

It is one of the worst APIs in Java

🚮 4

right, but it's not going to be via Properties... at least not via standard methods


@kenny all the kafka configs are strings


I know that one specifically


I'm not doubting something wants an int and gets a long, but it's not kafka via properties


I passed {"" 20000} as part of the kafka config and it threw the cannot pass a Long exception. This fixed it {"" (int 20000)}


{"" "20000"} is canonical


int happens to work


Oh cool. I'll do that, much cleaner.


@kenny usually I have a function that turns a clojure hash-map into string/string pairs then puts it into a Properties map


Yeah, should probably add helper function for that, especially now that I know it's a nasty api.


hi, is it possible to require two different versions of a library and use it at the same time?


not in any simple way, no


@noisesmith what would be the trick then?


isolated classloaders iirc


thanks! I will search about it


everything I've tried or heard about it makes it seem frustrating


A classloader hierarchy along the lines of the one OSGi uses, where peer classloaders do not delegate to their parents when looking for a loaded class. Been a long time since I did this, so the details are very fuzzy.


and making it work with Clojure iirc requires a pretty intimate understanding of how clojure extends the runtime classloader - my knowledge of this stuff is not very deep, maybe someone else can offer more detail


I know there was at least one fork of clojure for the express purpose of working with isolated classloaders


That allowed OSGi services to use different versions of classes IIRC


right - the fork I mentioned was for usage with OSGi


because clojure as is wasn't compatible


but mixing that with Clojure? No idea how 🙂


I think it's less about not delegating to parents, and more about creating two (or more) inheritance trees


Delegation might be the wrong word. I remember that it allowed a "child" classloader, instantiated for a service, to access classes "sideways" from other peers, without first looking in the parent. Or something like that 😛


That allowed for an additional security layer, whether a class was exposed outside its service, etc


but this is younger me from ~10 years ago!


oh, that's more than I know about it


It was strange stuff in a way, I ported 2 implementations to a "java on the chip" box my company at the time made.

Alex Miller (Clojure team)21:06:21

you can achieve this isolation in Java by using a post delegation classloader. however, clojure's dynamic classloader explicitly shares a class cache with all other dynamic classloaders


thanks guys, quite interesting, I also heard that it is possible to have clojure repl running along with a pure java application running under Tomcat and invoke commands from the repl, so , in theory we could write java code, compile it and call from clojure repl without restarting the embeded tomcat server, am I correct?

Alex Miller (Clojure team)21:06:11

not exactly - depends what you're doing

Alex Miller (Clojure team)21:06:36

that's not really a clojure question

Alex Miller (Clojure team)21:06:13

depends if you're making new classes (then you need a classloader that knows how to load them) or redefining (there are paths to this in the jvm but it's not trivial to do in general)

Alex Miller (Clojure team)21:06:44

in general, I'd say you should not do any of that. there are probably better ways to accomplish whatever goals you have


thanks Alex!

Alex Miller (Clojure team)21:06:32

like, don't write code, just make new instances using existing classes. and make more flexible frameworks if you need more dynamicity (clojure is great for that via its var system)


Hey guys, there is any Microservices example in Clojure? But I want something full fledged and mostly ready to production. I want to see some real project of a medium size or bigger. Not really interested in small examples, but I guess I won’t find this...


Small projects are fine to understand stuff, but it really doesn’t teach anything about how a ready to production code is working and should be


the idea is, I'm currently working with an old java framework that requires too much time to build, and also, its too coupled so , you never knows how it will behave xD , so I was looking for a solution for faster feedback


I guess that the only option for that is jRebel or hotSwap agent


but anyway, I'm learning clojure now, to leave this crazy java world 😛


@vachichng why not make a small set of stubs that call into clojure from the framemwork, then redefine the clojure stuff as needed while developing?


the stub should only need to change if you have a major architectural design, and the clojure stuff it calls is freely redefinable without a restart


uhmm interesting


I've used this pattern for jsvc for example

👏 4

thanks @noisesmith I will have a look at it!


the code is very small - it just makes a tiny implementation of every method needed, that uses the clojure API to look up a var with a "magic" name and call it


it expects an ns with start, init etc. as vars, then loads the ns and attempts to call them


yeah, its quite intuitive


so my hunch is you can do the same with your old java framework - give it methods (probably easier to just do in java), and just make sure everything those methods do can be freely redefined in a repl


then no more restarting the framework for code changes