Fork me on GitHub
#clojure
<
2021-12-28
>
Fudge07:12:13

How to iterate through nested mapped data stored in a file using clojure?

bg07:12:17

Could you please share an example of the data structure? Clojure core functions are enough to perform any kind of data processing. Usually you’d read the file, convert it into a Clojure data structure and use the core fns for processing. If it’s a nested map, take a look at functions like select-keys, reduce-kv, get-in, etc.

👍 1
bg07:12:21

If it’s a very large file then of course it gets more complicated, but the core ideas still remain (mostly) the same.

pavlosmelissinos08:12:06

#beginners is a better channel for this question @U02RRUT1ALQ And we need an example: 1. what does the file look like and 2. what result do you expect

pavlosmelissinos08:12:06

Furthermore, like @U0505RKEL said, your question includes a couple or problems: 1. Read a file 2. Convert it to a clojure data structure 3. Transform the data structure to get the result you want Try to find out which part of the process you're struggling with and come up with a more specific question.

Dynom13:12:35

Hopefully someone can explain this to me. I have a case which tries to match on a specific map, ala:

(case result
   {:version supported-version} (prn "success"))
This will not work. The supported-version statement has been defined earlier, but it seems like it will not be compiled into the clause. Because, when I replace supported-version with the string which has been assigned to it, then does work.

Ben Sless13:12:41

Case statements are symbolically compiled. It doesn't interpolate the defined symbol

Dynom13:12:17

Does this mean that the clojure compiler will not make simple def statements compile-time constants? I would assume that for the case statement, it would resolve it at compile time.

phill00:12:26

As a rule of thumb, use cond, not case. In Clojure, case's dispatch keys are literals, which leads to duplication (as we can't use constants). In ClojureScript, case opportunistically uses constants if they have been defined, which leads to surprises when a case changes behavior when constants' definitions are added and removed. Considering the brittle idiosyncrasy of Clojurescript's case, the fact that case isn't portable from clj to cljs, and the ideal that just about any Clojure code ought to be repurposeable in ClojureScript, you might as well avoid case entirely. Use cond.

cap10morgan14:12:45

How do you use the Java method reference operator (`::`) in Clojure interop?

p-himik14:12:58

You don't, you just write a lambda.

cap10morgan14:12:36

fair enough 🙂

emccue14:12:46

There is no equivalent. You need to reify the interface you are targetting explicitly.

(reify Function
  (apply [_ x]
    (Code ... x)))

Alex Miller (Clojure team)15:12:30

Or use the method handle api (which is way more cumbersome, but dynamc)

emccue16:12:15

has anyone really done that yet / are there examples out there?

ghadi17:12:48

The MethodHandle api isn't sufficient, still need to take the MH and adapt it into the correct interface

ghadi17:12:08

When you do Class::staticMethod or Object::instanceMethod, java tears off a MethodHandle then adapts it into the target interface

match3717:12:29

Seems use.clj is loaded when running a clojure test. any way to avoid that?

dorab18:12:38

Just make sure that the user.clj is not in your CLASSPATH when running tests. Perhaps via appropriate aliases.

match3701:12:06

Somehow it got invoked when I ran clojure test from intellij. Probably the cursive plugin invoked it. Thanks!

djeis18:12:08

So, I'm trying to write an extension for https://guacamole.apache.org/ in clojure and I've run into a rather annoying roadblock: Guacamole loads each extension using a dedicated classloader (which prefers the extension's resources over its own) but it doesn't set the thread context. The upshot is, Clojure's runtime classes load but when it tries to load clojure core etc. that fails. I can vaguely imagine a couple of ways I could solve this, all requiring I write the entrypoint of my extension as a java shim. However, I've no idea what the right approach would be, if there even is one. Does anyone have suggestions?

djeis18:12:41

As a basic idea, I could capture the context classloader in the constructor of my entrypoint class, set it to the entrypoint's classloader, call out to clojure's load routines myself, and then reset the context back again? I worry about code trying to load lazily or such though...

djeis18:12:21

:thinking_face: or maybe it'd be sufficient to set *use-context-classloader* to nil somehow, also in that constructor...

djeis18:12:53

No, I suspect that's been stubbed out in the runtime...

hiredman19:12:23

A Java shim sounds like a good idea

hiredman19:12:43

A long time ago, for some vaguely similarly issue with writing Jenkins plugins in clojure I wrote this code https://github.com/hiredman/jenkins-clojure-injector/blob/master/src/leiningen/jpi.clj which avoids writing java by instead using clojure's vendored copy of the asm library to generate bytecode

hiredman19:12:04

But that kind of thing is usually viewed as horrendous

djeis19:12:02

Oh wow, I hadn't even considered that...

djeis19:12:00

I... think I follow what you're doing there, but I don't think I could bring myself to attempt adapting that to be honest 😅

djeis19:12:22

Saving, setting, and resetting the context classloader worked for you though?

hiredman19:12:27

I assume it did, it has been a long time, I vaguely recall playing with https://github.com/hiredman/jenkins-nrepl, so it must have worked