@andy.fingerhut the source code looks https://gitlab.com/wildwestrom/group-creator/-/blob/master/src/wildwestrom/grouper.clj like yes/maybe/no/me
So is "no" a hard constraint that the two indviduals cannot be put into the same group, or that it is a worse solution, by some measurement of worse? And what does 'me' mean?
In terms of getting some kind of useful visualization for a large number of individuals, there are inputs for which it will probably always look messy. There are graph drawing algorithms that take weights on the edges, and try to make nodes connected by edges with large weights close together (at least 'more often') and nodes connected by edges with small weights farther apart, but there is no way on a 2-dimensional flat surface to place nodes so that the distance between them is equal to the weight of the edge between them, for arbitrary input edge weights.
i would think "me" means self... the edge that points back to the node (?) and "no" probably means avoid 100%
yeah distance probably doesn't matter... a solid line and dashed line could represent Yes vs Maybe
hash tag ideas
Possibly relevant Wikipedia article https://en.wikipedia.org/wiki/Force-directed_graph_drawing
The "See also" section of that article mentions that the Graphviz library has some code that can do some variant of this. I haven't used that part of Graphviz before.
I've almost always used the dot
command when using Graphviz, but looks like neato
, fdp
, and sfdp
might be useful to experiment with here.
Cool! I look forward to seeing if that solves OP's problem.
Iβll get back to this tomorrow, but thank you for all the responses!
Hi, How to get the key of Enum instead of the value when converting Java object to Clojure map using bean or javadata/from-javaοΌ
I don't think I understand your question. If I call bean
on a Java object, it returns a value that acts like a Clojure map, and its keys are all keywords, e.g.:
user=> (def m1 (bean (atom 5)))
#'user/m1
user=> m1
{:class clojure.lang.Atom, :validator nil, :watches {}}
user=> (keys m1)
(:class :validator :watches)
user=> (map class (keys m1))
(clojure.lang.Keyword clojure.lang.Keyword clojure.lang.Keyword)
All of the keys are Clojure keywords. You want a map where the keys are some other non-keyword values?
Sorry, I don't describe it clearly. The problem is I have an Enum in Java like this:
public enum Test {
A("a", ""),
B("b", "")
}
So, I want to get the key of Enum when converting Java objects to Clojure maps. Now is get the name of Enum.Can you give an example of something you have tried in a REPL with such an enum, showing the return value that you get (but wish it were different), and what return value you wish to get? I still do not understand what you are after.
public class Test {
private QueryTypeEnum type;
public enum QueryTypeEnum {
A("a", ""),
B("b", "");
private String key;
private String desc;
}
}
(bean test instance) or (from-java test instance)
My except map is like this: {":type" "a"}, But it will take the name of Enum, so the result will be like this: {":type" "A"}.
Now, I found a way to solve it. IΒ rewrite defmethod from-java [Enum]Β inside the java.data like this:
(defmethod j/from-java Enum [enum] (.getKey enum))
Team , I have a vector like below
[A1 B1 C1
A2 B2 C2
A3 B3 C3]
I wanted to split and put it like
[[A1 B1 C1 ][A2 B2 C2 ][A3 B3 C3]]
so that I can iterate over 3 elements each and pass as argument
how can I achieve in clojure
@popeyepwr perhaps https://clojuredocs.org/clojure.core/partition?
(mapv vec (partition 3 [:A1 :B1 :C1 :A2 :B2 :C2 :A3 :B3 :C3]))
PS I'm not very experienced in clj either so take it with a grain of salt π
@rextruong what if input is like this
["A1 B1 C1"
"A2 B2 C2"
"A3 B3 C3"]
output should be
[["A1" "B1" "C1" ]["A2" "B2" "C2" ]["A3" "B3" "C3"]]
@popeyepwr (map #(clojure.string/split % #" ") input)
will be close to what you want...
user=> (def input ["A1 B1 C1"
"A2 B2 C2"
"A3 B3 C3"])
#'user/input
user=> (map #(clojure.string/split % #" ") input)
(["A1" "B1" "C1"] ["A2" "B2" "C2"] ["A3" "B3" "C3"])
user=>
mapv
if you really want a vector back instead of a (lazy) sequence.
Ah sorry I thought they are all separate strings.
Do you want to turn a vector of strings into a vector of vectors of strings?
(mapv vector ["A1 B1 C1" "A2 B2 C2" "A3 B3 C3"]) ; [["A1 B1 C1"] ["A2 B2 C2"] ["A3 B3 C3"]]
or am I misunderstanding something π
your solution yields a vector who's elements are single item vectors. ["A1 B1 C1"]
. The desired shape is a vector of 3 item vectors [["A1" "B1" C1"] ...]
ah!
yeah it's hard to see on the slack client
Not seeing quotes, probably the biggest time sink in my life π
i had to do a bit of a double take myself
Interesting how the brain works, I looked at the question from one hour ago and then I did not even see the quotes in the revised question
ahhh... i forgot that clojure.string/split functions! gonna take note again.
I assume that if I create a channel with a distinct
transducer, eg
(async/chan 10 (distinct))
that this will not be thread safe, i.e. it is not safe for multiple threads to read/write from the channel?or even just the distinct transducer without the channel
if I wanted a thread safe distinctβ¦what would you choose? locking
?
It is safe
It is a bad idea because distinct will hold a copy of every message that passes through the channel in a set
@hiredman thank you. This is a short lived tree traversal, multi threaded yes, but accumulation is not an issue. Hmmβ¦I read about the volatile
used in distinct
and came out thinking it would not be safe. Care to elaborate a bit?
The main thing is every channel has a lock inside it, and when you add or remove things from the channel (which is when the transducer operates) you hold the lock
ok got it, so distinct by itself outside a channel is not thread safe, but used as a transducer for a channel we get safety
The usage of volatile inside a lot of the mutable transducers is there to make them safe for use with core.async
The volatile makes sure mutations propagate between threads, the channel lock says one thread at a time
makes sense. Thanks again!
Damn, I realized I didn't know how to pass a java property using -J
(Clojure CLI). I tried many ways of prefixing it without any luck, an example in the reference guide would be welcome
-J-Xmx512m
A property would -J-Dfoo=bar
All right, it was about the order of args... -J
must figure before -M
. Kinda makes sense but my coffee wasn't strong enough this morning...
Hi, I using Java class to representing Clojure dataset like this:
{
"query": {
"source-table": 2,
"aggregation": [
[
"distinct",
[
"field-id",
5
]
],
[
"sum",
[
"field-id",
8
]
]
}
}
Now, I have classes here:
public class QueryReq {
private Query query;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Query {
private String sourceTable;
private List<Aggregation> aggregation;
}
@Data
public class Aggregation {
private AggregationEnum aggregation;
private AggregationColumn aggregationColumn;
@Data
public class AggregationColumn {
private KeywordEnum column;
private Integer id;
}
}
So, my question is how to convert AggregationColumn which nested in the Aggregation to Clojure vector? Is here have some convenient ways to do converting datastructure between Java and Clojure?I'm having some trouble with a reflection warning. I have a library, with a defrecord
in it that extends a defprotocol
. E.g.. (defrecord SomeThing [name type] myProtocol ...)
.
This protocol has a release-props
method. When I make a call to this method, like so:
(.release-props my-thing)
I'm getting a reflection warning call to method release_props can't be resolved (target class is unknown)
. I'm trying to resolve it like (.release-props ^mylib/SomeThing my-thing)
, but that's not working. I get Unable to resolve classname.
What am I doing wrong?Maybe I'm missing something on the library side? I admit to having no clue about what (:gen-class)
does...
even a fully qualified name like ^my.lib.SomeThing
doesn't work. I still get a ClassNotFoundException
.
I guess the most basic question is: how do I refer to a record in a library? I just get No such var
Java method names canβt have a - in them
Doh! Showing my Java ignorance again.
So the . call with the - doesnβt seem right
Anyone know that does java-data/from-java can work with the Java Inner class?
It works, though. Just gets a reflection warning.
Yeah, it might be getting munged
Ah, right. I'll give these methods more JavaLikeNames, then. Thank you!
The names are fine now
Itβs just that calling via java interop requires java naming
Excuse the extreme ignorance, but is there another way to call a protocol method here?
If you have a protocol, why are you not invoking the protocol method?
(release-prop my-thing)
Because this is the very first time I have used protocols and thought that was how they work.
Ok, theyβre just like regular functions when you invoke them
And protocol functions exist in the namespace where theyβre declared so you require/refer them just like any other function
Bingo, that did it. Thank you!
Hi everybody! From this map:
(def homes [{:name "Home 1",
:wifi "y",
:shower "y",
:laundry "y",
:metro "n",
:balcony "y",
:fireplace "n",
:pool "y"},
{:name "Home 2",
:wifi "n",
:shower "y",
:laundry "y",
:metro "n",
:balcony "n",
:fireplace "n",
:pool "n"}
{:name "Home 3",
:wifi "y",
:shower "y",
:laundry "y",
:metro "n",
:balcony "y",
:fireplace "y",
:pool "n"}
{:name "Home 4",
:wifi "y",
:shower "y",
:laundry "n",
:metro "n",
:balcony "n",
:fireplace "n",
:pool "n"}]);
I want to only keep/filter houses meeting the following needs (def needs [:wifi :shower :laundry])
Is my solution a decent one? (filter #(every? #{"y"} (vals (select-keys % needs))) homes)
Did you have suggestions?
(filter #(every? #{"y"} (vals (select-keys % needs))) homes)
({:name "Home 1",
:wifi "y",
:shower "y",
:laundry "y",
:metro "n",
:balcony "y",
:fireplace "n",
:pool "y"}
{:name "Home 3",
:wifi "y",
:shower "y",
:laundry "y",
:metro "n",
:balcony "y",
:fireplace "y",
:pool "n"})
is there any possibility to do java interop from source files instead of compiling first? Or is there a way to use deps to build local java libs first before starting the repl?
no to the first question. the latter is possible but probably depends on lots of things
i might consider modeling like this:
(def homes' [{:name "Home 1",
:amenities #{:wifi :shower :laundry :pool}},
{:name "Home 2",
:amenities #{:shower :laundry}}
{:name "Home 3",
:amenities #{:wifi :shower :laundry :balcony :fireplace}}
{:name "Home 4",
:amenities #{:wifi :shower}}])
(def needs' #{:wifi :shower :laundry})
then to filter:
(filter
(fn [home] (clojure.set/subset? needs' (:amenities home) ))
homes')
;; => ({:name "Home 1", :amenities #{:pool :shower :laundry :wifi}}
;; {:name "Home 3", :amenities #{:shower :laundry :balcony :wifi :fireplace}})
Thx for your suggestion. Concerning the modeling, let's assume that it can be changed because it comes from a converted JSON.
I have not tried it before, but do not know of any reason why it shouldn't work, either. Inner classes named from Clojure have names like OuterClass$InnerClass -- did you try naming the inner class that way?
If so, what did you try, and what unexpected result did you get?
I think your solution is good, although you could simplify it by changing (vals (select-keys % needs))
to (map % needs)
.
Hey, Iβm coming from Haskell and excited about clojure! Iβm working through 4clojure and some basic problems right now just getting the hang of it. Are there any recommended intro projects out there? Would like to dig into something but Iβm not sure whatβs reasonable in this language.
While I can solve easy 4clojure puzzles, I am curious about the best learning strategy when stuck. Obviously I can use a search engine for some public gist where other users would share their solution and revert engineer it, but is there a more obvious path to learn ?
Team I am getting
Caused by: java.lang.Exception: Cyclic load dependency:
i understand that using namespace one in another
is there anyway to avoid it? I wanted to use one of the function from another namespaces, which already I imported the file in another
Perfect @regen! I suspected that there was a way to simplify. Thank you, that was exactly the advice sought. π
Maps as functions ... it's really powerful!
@popeyepwr Imho, this is usually a sign that you need a namespace restructuring. In other words, think again whether you really need a relationship like ns a -> ns b -> ns c -> ns a
(read ->
as requires
).
Usually the part of a
that requires b
is higher level than the part that c
is using.
So, assuming that all of the affected namespaces are under your control, it might make sense, depending on the case, to either:
β’ further break them down (to split the higher from the lower level stuff of a
) or
β’ merge the interconnected parts into a single namespace
extract out the shared code into a new namespace
There's also a technique by which stuff is moved at runtime ((resolve 'my.nsp/f) arg1 arg2)
generally not good practice.
Of interest, there is also Timothy Baldridge's answer here (use interfaces and implementations): https://groups.google.com/g/clojure/c/-PvQvVmmLQg
Yes, and it doesn't just stop at maps [=
Yes, sets as function too π
Java classes pretty much all have custom APIs defined by their methods, so I cannot imagine any general technique to convert between Java object values and Clojure values. If you use Java classes that implement interfaces like List, Map, and Set, Clojure collections implement those interfaces, so at least in some cases no conversion is necesary -- they already satisfy those interfaces.
are there any reference apps or starter kits that include this workflow for reference?
are these local java libs things that are yours or external libs? the latter is nearly always built and published to a maven repo somewhere and you should just include the lib that way.
are you looking at java-only or java/clojure mix?
so, my use-case is running the terraform CDK (`cdktf`). It ships with a java flavor (but also typescript, python, and dotnet-core as well), and when you add provider dependencies (ie: docker
), you run cdktf get
and it pulls down some typescript and generates java source to be consumed by your project. For a java project, it then is accessible by the code you've written yourself, but for clojure -- it's not yet compiled. Usually cdktf get
code is not checked into the repo, it goes in a .gen
directory.
but my use-case is to only write clojure with java interop
if you don't need to recompile very often, I was able to use this one liner to compile java files:
find javasrc -name '*.java' -print0 | xargs -0 javac -d classes -cp `clj -Spath
`
make sure the directory classes
exists and add it to the paths in your deps.edn
which should have a key like:
:paths ["src" "resources" "classes"]
I'm trying to do a reduction (or something else.... catamorphic? lots into 1) but I'm having trouble figuring out exactly how to shape it. The first def is an example from the docs of a library I'm trying out, and the second is the way that my data is shaped.
(def g1 (-> (dep/graph)
(dep/depend :b :a) ; "B depends on A"
(dep/depend :c :b) ; "C depends on B"
(dep/depend :c :a) ; "C depends on A"
(dep/depend :d :c))) ; "D depends on C"
(def my-data {:a #{:b :c}
:b #{:d :c}
:d #{}})
The end goal is a dependency graph of all that data
There's a sort of double higher order fn going on: for every key, I want to put all its dependents into this growing dependency graph
maybe I should be using a loop-recur form
You have basically two options 1. Reduce over the map, reducing over each map entry 2. Transform your map into a more linear structure, then reduce over that
i'm getting thrown by f should be a function of 2 arguments
in reduce's docs. This is a 3 argument function. At first I thought, use partial, but the first argument of dep/depend is that graph that's accumulating
see https://gist.github.com/hiredman/7d17d8d2b58c41ce95bf2db305b0f427
it is two arguements
the graph and a map entry (which is a pair)
oh ho
the above is an example of choice 2
so the linearized version of what i started with would be something more like
[{:depends :a, :depends-on :b}
{:depends :a, :depends-on :c}
{:depends :b, :depends-on :d}
{:depends :b, :depends-on :c}
{:depends :d}]
?sure
or even just a bunch of pairs like [:a :b], the relationship implied by the context
when "linearizing"(normalizing? it is connected in some way to normalizing data for a rdms) your structure like that you have two choices in how to do it, via seqs or via transducers
using a for like in my example produces a lazy seq, lazy seqs are sort of a habitual thing to grab for, but transducers are often faster, use less memory, and behave nicer when mixed with io/side effects
when i finally run this function, i anticipate running it approximately once. so i'll skip the transduction
so where you have that empty map in your db def, i would have (dep/graph), which is the empty val for my case
cool, it was not hard to linearize this, and that does make it easier to think about
(defn linearize [[component references ]]
(for [ref references]
[component ref]))
(def normalized (mapcat linearize adjacency-list))
(def dependency-graph
(reduce (fn [g entry] (dep/depend g (first entry) (second entry))) (dep/graph) normalized))
Piece of π° , thanks hm!Team I have below var
(def var [{:a "a1":b "b1" :c "c1"}
{:a "a2" :b "b2" :c "c2"}])
want to collect the values like below
[[a1 b1 c1] [a2 b2 c2]]
OH! That's interesting
cannot use vals
wanted to fetch according to keys
I tried something like
(mapv #(get var %) [:a :b :c])
but did not help
thing is
:a :b :c
will not be in order in each map
var is 1. a really bad name to use because it conflicts with the var special form 2. a vector of maps
so need to pull it from each map,
so for example (get [{:a 1}] :a)
is not going to return anything useful
which is what your map is doing
mapv
(def var {:a "a1":b "b1" :c "c1"})
=> #'user/var
(mapv #(get var %) [:a :b :c])
=> ["a1" "b1" "c1"]
hi, I'm struggling with hyphens in clojure.java.jdbc. I'm using SQLITE and have a column user_id
. I'm doing a simple insert like this:
(jdbc/insert! db :user {:user-id 555} {:identifiers #(.replace % \- \_)})
Getting the error: SQL error or missing database (near "-": syntax error)
tried using that :identifiers key to fix the hyphens but it seems too have no effect
if vector as multiple map values thn it shouls extract
nope
get looks some thing up by a key in the immediate thing you give it, it will not reach down through other collections to look for something with a key
:identifiers
deals with names coming back from SQL to Clojure; :entities
is what you want for names going from Clojure to SQL.
thanks sean wow really nice to get a reply from the author so fast!
would love to use next.jdbc but due to circumstances out of my control I need to target JDK7
I try to keep an eye out for SQL-related Qs here in #beginners -- posting in #sql is certain to get my attention more quickly tho'... π
π
that worked thanks
So the issue is that for each of the keys [:a :b :c]
you need to call (get)
on each of your maps. so its a nested iteration
you need to do it the inner fn that youre passing to mapv for each of your keys
see if using https://clojuredocs.org/clojure.core/for in the mapping function helps?
@hiredman I wrote this
(map (fn [x] (mapv #(get x %) [:a :b :c])) var)
Looks nice, you might want to use mapcat, and again, don't use the name "var" it conflicts with the var special form, and will act really odd in some situations
yeah sure, i have something else in my code
Hello, am currently trying to prototype a simple clojure backend with Ring. Am using https://github.com/lispcast/listronica/tree/1.17 as a template. Are there any resources I might want to look at?
How do I best create an API to transmit edn from a clojurescript webapp to ring backend? Can I just put edn in the :body
of a route? That gives me some errors. Do I wrap it in a string like "{:test [\"test\"]}"
I'm reading Web development with Clojure (3rd ed.) and I noticed that the book starts off with what I would consider traditional web development, then introduces AJAX with ClojureScript, before adding reagent and eventually re-frame. I love the book, but this seems like a lot of additional complexity to me, and I'm wondering if I need that additional complexity. I want to make simple and fast websites with text fields for inputting some data, and some buttons and checkboxes for filtering said data. If I need fancy animations I can use CSS. I don't think I need reactivity, but maybe I would be missing something else? Is the workflow of using reagent (with reframe?) somehow more productive than just writing Clojure on the server and producing HTML? Asked in another way, what are some good use cases for ClojureScript with reagent?
"Modern" web apps these days are SPAs (single page applications) that communicate with a REST-like backend -- and that's what the book is aiming at. It's why I don't recommend that book -- or the Luminus template -- for people who are brand new to Clojure: it's just too many moving parts. Take a look at the Practicalli stuff for web development and start simple with just Ring and a few small, simple libraries. Then as you understand that process, you can add complexity as you need it.
https://practicalli.github.io/blog/posts/clojure-web-server-cli-tools-deps-edn/ (at https://practicalli.github.io/ -- lots of great beginners content there).
I will take a look, @seancorfield. Thanks for the suggestion! I think my question could be asked as "How do you decide if an SPA is the right fit?", if anyone has input on that instead π
I think you've answered your own question there @endrejoh -- if you want to make simple/fast websites with forms for capturing data and storing it somewhere, then SSR (server-side rendered) HTML is going to be just fine and Ring + Compojure + maybe Selmer + next.jdbc
is about all you'll need (assuming a database for storage). Take a look at https://github.com/seancorfield/usermanager-example (or the Reitit-based variant linked in the README).
Thank you so much, @seancorfield!
I have a function that takes 3 arguments. How do I call it if I have arguments packed in a list?
(apply my-fn args)