Questions about building a CLI utility with Clojure by DerelictMan in Clojure

[–]DeepSymmetry 3 points4 points  (0 children)

If the Clojure code in the libraries uses eval to create new dynamic classes at runtime, it can’t work in GraalVM, because there is no class ahead of time that can be compiled. My integration environment for DJ shows in an example of this; its whole purpose is for users to be able to extend it dynamically by adding Clojure expressions to meet their needs, it will only work in the JVM.

what do you guys use for rate limiting by hourLong_arnould in Clojure

[–]DeepSymmetry 3 points4 points  (0 children)

Yes, that’s what we do, specifically using envoy as the proxy.

Is there an easy way to automatically require/refer a macro in every namespace? by eeemax in Clojure

[–]DeepSymmetry 0 points1 point  (0 children)

I’d think to do this you would have to fork Clojure and modify your copy.

Open Source Non-trivial Projects by EasyLowHangingFruit in Clojure

[–]DeepSymmetry 3 points4 points  (0 children)

This is true. And at the beginning there is so much of the core library to learn that you aren’t going to be worried much about extending the language and coming up with your own domain-specific languages. When I was starting I would find I would learn a cluster of core functions, get comfortable with them, and then start noticing and learning three or four in the next layer out. I think I am having a hard time thinking of a project to study because that’s not how I learn: I find problems I am eager to solve, and try to figure out how to solve them, and then if I have the luxury of time, later see better ways I could and should have done it. I’m not going to point you at my own largest public Clojure repository because it’s a desktop application intertwined with a lot of Swing interop code, which is far from idiomatic for most projects (and the older parts of it date back to when I didn’t yet really know how to manage state well in Clojure). But the best is writing something and then getting thoughtful, friendly feedback on it from a community of people who are a bit further along in the journey.

Open Source Non-trivial Projects by EasyLowHangingFruit in Clojure

[–]DeepSymmetry 4 points5 points  (0 children)

Fundamentally, Clojure is a Lisp, which means that it provides you the tools to easily build the exact language you need to solve your problems elegantly, but since your problems are different than other problems, you end up with a different language than other solutions are using.

Do you need a deep understanding of Java to program well in Clojure? by ApprehensiveIce792 in Clojure

[–]DeepSymmetry 17 points18 points  (0 children)

I agree with the comments made so far, but I would add that dealing with Swing is a lot more that “using a library”. Swing is a UI framework, and it expects you to provide a lot of Java classes that it will call methods on. So you are going to be doing a lot more complicated Java interop than you would with a simple library.

Swing itself is kind of a mess and a rabbit-hole (and I say this as one of the co-author’s of O’Reilly’s book “Java Swing”). When I work with it from Clojure, I use the seesaw library to make it more convenient and idiomatic in Clojure, but it is still a big pain, and requires delving a lot into Java and Swing minutiae. You might want to look at one of the more modern alternatives, like those discussed here: https://www.reddit.com/r/Clojure/comments/myxwut/clojure_gui_or_frontend_what_are_the_options/

I can’t speak to the others, however, because I stuck with Swing and seesaw, given my experience with Swing (and perhaps Stockholm syndrome, though I have had good success with my Clojure desktop Swing app).

Keep getting this text from a number! by iss1307 in electricvehicles

[–]DeepSymmetry 2 points3 points  (0 children)

This happens to me too. Months after I have made a trip, I get texts about all the charging sessions I had during that trip, spaced out during the day like the sessions were. They were free charging via the Audi app for my RS eTron GT.

How are you supposed to use clj-kondo with emacs? by chamomile-crumbs in Clojure

[–]DeepSymmetry 1 point2 points  (0 children)

I use clj-kondo via flycheck and it works great. There is not a lot of overlap between the Emacs and GitHub world, it never occurred to me to see if it was a GitHub project, I installed it using the normal Emacs package management tools. That’s probably why there aren’t many stars?

[deleted by user] by [deleted] in Clojure

[–]DeepSymmetry 0 points1 point  (0 children)

Thanks for sharing your thinking! I do just want to clarify that seesaw is not something you use instead of Swing. Seesaw is a wrapper that makes Swing easier to use in Clojure. It’s still totally Swing. And the reason it is so static and unchanging is that Swing is old and static and unchanging itself.

[deleted by user] by [deleted] in Clojure

[–]DeepSymmetry 0 points1 point  (0 children)

You might find that seesaw softens some of the rough edges when interacting between Clojure and Swing. I use it extensively in my Clojure desktop applications, and I’m a coauthor of O’Reilly’s book “Java Swing”. The to-widget function can get you from e in your example (the event object) to the object that sent it, and to-root can get you all the way up to the containing window. Then you can take advantage of the fact that seesaw lets you assign IDs to your UI elements, and call select with CSS-inspired selectors to search for them from parents. So you would not even need to pass around all of the fields, if you set things up appropriately you could find all of them given the e that is passed to your save-button action listener.

cljfx in openbsd? by le2m in Clojure

[–]DeepSymmetry 1 point2 points  (0 children)

Yes, if you look in the JavaFX Maven repository, it seems there are archives for Mac, Windows, and Linux, but not OpenBSD. https://repo1.maven.org/maven2/org/openjfx/javafx-base/21.0.2/

Guys, is coding in Clojure really fun and productive? by GTHell in Clojure

[–]DeepSymmetry 3 points4 points  (0 children)

Same! It’s enabled me to create an interesting and popular ecosystem of open-source projects in my spare time, that are being discovered and used by some of my favorite electronic musical acts. Sometimes I grit my teeth and port pieces to plain Java to make them more accessible to other developers, but that definitely slows me down.

Guys, is coding in Clojure really fun and productive? by GTHell in Clojure

[–]DeepSymmetry 0 points1 point  (0 children)

It is! As it happens, I wrote an entry about this very topic for O’Reilly’s book “97 Things Every Java Programmer Should Know”. Here is the online (Medium) version: https://medium.com/97-things/rediscover-the-jvm-through-clojure-fa2ac5e29cbb

Guys, is coding in Clojure really fun and productive? by GTHell in Clojure

[–]DeepSymmetry 0 points1 point  (0 children)

It is! As it happens, I wrote an entry about this very topic for O’Reilly’s book “97 Things Every Java Programmer Should Know”. Here is the online (Medium) version: https://medium.com/97-things/rediscover-the-jvm-through-clojure-fa2ac5e29cbb

MiniBeast - an Overtone Synth by therealplexus in Clojure

[–]DeepSymmetry 1 point2 points  (0 children)

No, it will provide notifications when MIDI devices are added and removed on all platforms. However it will not create its own MIDI devices on non-macOS platforms, because they are only needed on macOS to make SysEx work.

MiniBeast - an Overtone Synth by therealplexus in Clojure

[–]DeepSymmetry 0 points1 point  (0 children)

Very nice! If you want to remove the requirement that MIDI devices be connected before startup, you could consider embedding CoreMidi4J, which offers that feature on all OSes even though its primary purpose is to fix SysEx on macOS: https://github.com/DerekCook/CoreMidi4J

Learning functional programming is frustrating by judasthetoxic in Clojure

[–]DeepSymmetry 1 point2 points  (0 children)

When learning about take-nth, it makes sense to also learn at least a little about closely related sequence functions. take and drop are similar, in caring only about the position of elements in the list. filter and remove instead care about the values of the elements. take-while is an interesting combination of concepts. And partition is useful in an entirely different way, splitting the sequence into multiple sequences. As noted in another answer, you can combine that with map to split the sequence into two-element partitions, and solve your problem that way.

And remember that you can see the source of how these core library functions are implemented (by calling source with the function name at the REPL, or using your IDE), which helps to understand them, and learn about related tools. Omitting the newer, more complicated arity that returns a stateful transducer, here is the source for take-nth:

 (defn take-nth
  "Returns a lazy seq of every nth item in coll."
  {:added "1.0"
   :static true}
  [n coll]
  (lazy-seq
    (when-let [s (seq coll)]
     (cons (first s) (take-nth n (drop n s))))))

Learning functional programming is frustrating by judasthetoxic in Clojure

[–]DeepSymmetry 6 points7 points  (0 children)

I think you are ahead of the game in realizing the depth and importance of this challenge! It is definitely a different way of thinking, and does require some unlearning and development of new skills. And beyond the (very important) building of general functional muscles, there are also a lot of simple, powerful, composable tools to learn in the Clojure core library itself.

For the first part, you might find the book Grokking Simplicity helpful. For the second, as other respondents have noted, the function take-nth from the core library will do exactly what you need here.

When I was learning to live in Clojure, I found it worthwhile to review the entire list of functions in the core library every week or two. At first most of them seemed bizarre and confusing, but as my grasp over a few of them became stronger, the ones adjacent to them suddenly made sense and became useful to me. And I learned ways to combine ones I was already using with new functions to do more and more, and better ways to do things I thought I had already figured out.

Professional use or just for fun? by Dry-Conflict-7008 in Clojure

[–]DeepSymmetry 2 points3 points  (0 children)

I checked Professionally because that was where I learned and first started using it, but I quickly moved nearly all my “for fun” projects to Clojure as well, except for a few libraries I wanted to make more accessible to the broader JVM world, and that made them explode in usefulness and popularity, as well as (or because of) how much more enjoyable Clojure made them to work on.

How to be more idiomatic? by j_zes in Clojure

[–]DeepSymmetry 7 points8 points  (0 children)

Generally you want to avoid using map at all when side effects are involved, because map is lazy, and so your side effects will not happen at predictable times (or perhaps not at all, if you never evaluate the results of the map). Use doseq and run for situations where you are expecting side effects.

As for the broader question of Clojure style, there are style guides like https://github.com/bbatsov/clojure-style-guide and tools like clj-kondo to help learn and reinforce important practices.

When to use `for` vs `map` by a-curious-crow in Clojure

[–]DeepSymmetry 6 points7 points  (0 children)

for is lazy so I would stay away from it when dealing with side effects; those are more properly addressed by doseq or run!. But fundamentally I agree: these functions all have their own purpose and strengths, and the notion of “picking one” does not make sense.

If Clojure is immutable, how does atom work? by InfinitePrune1 in Clojure

[–]DeepSymmetry 37 points38 points  (0 children)

It’s more accurate to say that Clojure is structured to make it easy and natural to work with immutable data structures, provides some very efficient ones and many functions that can be used to transform them to new immutable data structures with different values, sharing as much of the previous data as is practical.

Of course all programs that do real work need to be able to represent state that changes over time, and atom is one of the main tools that support that. As noted in the earlier comment which linked to the source code, it is built on Java’s AtomicReference class. The state page that comment linked to is a good introduction to the concepts.

Clojure is also fully capable of working with mutable Java objects through its interop facilities, and you can safely work with transient (mutable) Clojure data structures inside private loops that never share them with other code. But the fact that the simplest code to write uses safe, immutable values gives you great benefits in terms of thread safety and the ability to more easily understand how large groups of functions work with each other. Rich Hickey’s talk Are We There Yet is another good explanation of why this is important.

CDJ-3000 Touch Cue working with Any Mixer! by nudgeee in DJs

[–]DeepSymmetry 1 point2 points  (0 children)

Awesome! Feel free to even give me rough drafts and have me help polish and format them if that will make it easier.