Fork me on GitHub

That PR does not remove the .test. part so those paths still have strange names for tooling...


Hmm, that wasn't what I was expecting... but, yeah, that's the official forum. OK, posted a new topic about it for tracking purposes.


It seems like you'd need to change the Luminus template as well since that PR isn't quite right.


(I hadn't actually noticed that glitch when I read that section of the book -- I think my mind just auto-translated it to what I expected!)


and makes sense


Alright, I’m sure somebody has written about this before. figwheel-main vs. shadow-cljs “Why use one or the other?” is my question.


Seems like the main benefit to shadow-cljs is easier integration of npm dependencies and having more advanced build stages. Figwheel-main is pretty clean and easy to set up, but that's about it. Seems like shadow is the obvious way to go for everything, but maybe you guys know better.


When I did a little cljs a while back -- hacking on the Chlorine plugin for Atom -- it was a Shadow-cljs project and I was quite impressed by how smooth it was. When I decided to get more serious with cljs recently, and start learning re-frame, I looked at both and decided to use Figwheel because a) I wanted to use CLI/`deps.edn` and b) wanted to avoid npm if I can.


For you, right now, it's really not going to matter: they'll be close to the same for getting started.


Both #figwheel-main and #shadow-cljs have good support channels here.


The support in #shadow-cljs is out-of-this-world awesome.

👍 3

My main reason for using figwheel-main (sorry, could not resist) is that figwheel composes with ClojureScript, and as such is a purely dev concern. I get to compile my prod bundle this way, no figwheel in sight: clojure -M --main cljs.main --compile-opts common.cljs.edn --compile-opts min.cljs.edn --compile-opts prod.edn --compile … simple, clean, stable. Shadow does much more, and I am not convinced I want or need that much more. And with the newish :target :bundle , NPM integration ClojureScript is easy and clean too. And again, not a figwheel concern.


@U04V70XH6 Ok cool, I like how figwheel can be used with just deps.edn. @U9E8C7QRJ I didn't know about any recent npm integration like this. Where can I find more info?


The new-ish integration looks like this: It works well for us.

👍 3
Klavs Klavsen12:02:45

Why can't for ( ) take a list also? it seems to me, it should be able to handle both vectors and lists (and I have a list I'd like to loop over 🙂

Timur Latypoff12:02:42

It can. Would you paste an example that does not work?

Klavs Klavsen12:02:18

The docs just says only vector so I didn't even try 😊


So far as I know, list and vector are both for-able.

Klavs Klavsen12:02:25

Now to look for where to submit PR to improve docs then 🙂

Timur Latypoff12:02:29

@U018FH7446P Ah, it means the syntax of how you write it. You pass it a "vector of binding form pairs": (for [a aaa b bbb] b) [a aaa b bbb] - is a vector of binding form pairs. aaa and bbb themselves can be any sequences, including lists.

Klavs Klavsen13:02:05

I want to call a function that returns a list of maps (shown as ({a: 3} {a: 4}))

Klavs Klavsen13:02:29

and do something on it IF X=Y

Timur Latypoff13:02:48

(doseq [v (my-func) :when (= (:a v) 3)] (println v)) ↑ like this? The my-func returns a list of dictionaries, and we print only those which have :a 3 @U018FH7446P

👍 3
Klavs Klavsen13:02:41

What would be the best way to loop over a list of maps (returned from a function) - and doing something when/if X ?

Klavs Klavsen13:02:23

I thought for could be used.. but it seems to only want to do a let.. and since I NEED to call "remove user" - I would have no need for the let.. which seems a bit wasty/wrong then.

Henri Schmidt13:02:21

What do you mean by "do something"?

Henri Schmidt13:02:40

Do you mean "transform the maps in some way, returning a sequence of transformed maps"

Henri Schmidt13:02:58

Because if so, then I recommend using the map function.


If you want side effects in iteration, you can use doseq, which is similar to for but intended for iterative side effects

🙏 3

Or run!to apply a function over each entry in a collection for side effects.


So doseqis the non-lazy equivalent of for whereas run!is like the non-lazy equivalent of map. Another option is doall but I’d prefer run!

🙏 3

@U018FH7446P there are resource intensive constructs in clojure, let is not one of them. for is a lazy sequence generator (not a loop), and requires a body for generating a new output for each combination of inputs, but it sounds like you aren't trying to produce a new data structure, so don't use for

🙏 3

Is clojure.spec used much in real projects? (It looks very attractive to me as an outsider, and I'm thinking of making a demo to my company to entice them to try a clojure project). I wouldn't want to promote an approach that may not be "the way" things are done these days.


it's used, but not by everyone. IMHO the common mistakes are to treat it as if it were your type system or a coercion system. it's best at being a fail fast layer between parts of a system - like a fuse that goes off if the wrong shape of data passes through.


Malli is quite good also. Personnaly what I started with spec has been into malli. Easier to read and share, compose store ... apiified. Search schema malli spec to have comparaison articles.

👍 3

@U9RGZJC4C We use Spec very heavily at World Singles Networks -- and have done so since it first appeared in a Clojure 1.9 prerelease build (which feels like "years" ago now). I wrote up the various ways we use it:


With the caveat that there is a Spec 2.0 in development which will be quite different in some areas, Spec has proved to be very stable, solid, and useful for us, both in dev/test and in production.


I’m working on a involving graph theory. I’m trying to create an algorithm that can create groups using some given data. It’s a little complicated to explain but I’ll do my best once I start this thread.


So my dataset has each individual, represented by an alias (the animal names). Each individual responded how many groups they want to be in, and whether they want to be in a group with that individual. I figured a weighted graph would be my best bet.


I’m wondering how I can get a better visual…


As in, if you have 100 individuals, do each of those 100 respond with 99 yes/no "I individual X want to be in a group with individual Y", for all 100x99 (X,Y) pairs?


i.e. is part of the input data you are starting with effectively this NxN table of true/false values? and you must honor those true/false values when creating groups? Or is it more numeric 0 to 10 scale of 10=definitely OK, 0=never, and 5=lukewarm about being in same group with the other individual, and you are trying to create groups not with hard yes/no constraints, but trying to minimize the number of pairs that hate each other in the same group?


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


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!


I’m not sure how I would implement a force directed graph using ubergraph.


If you are interested in using neato, or one of the other GraphViz programs, then the problem becomes how to write the appropriate file that neato can read, and produce the graph you want. That process is probably best begun by hand-creating a small input file with 3 or 4 nodes and a few edges and running neato on it until it doesn't give syntax errors and produces a graph like you want. Then from that knowledge of what the file should look like, write a function that traverses all nodes and edges of an ubergraph data structure, printing out the correct syntax for each one to an output file.


or fdp or sfdp, if those produce output more like you want. Not sure if they do, but if they do, then very likely the code for printing the input file they need is probably simpler than writing code to create a force directed graph yourself.


I think a directed graph would be enough for what I understand the problem to be -- and you could have Yes edges and Maybe edges and No edges colored differently.


I would love to have the edges be different line thickness, with the value corresponding to this function.


Now my output looks like this


Is there a way to do clustering? I was looking at K-means clustering and other clustering algorithms but I don't know how to create a cluster graph from edges and distances.


If you make up a spring force input file that Might give best possible output, e.g. nodes 1 through 4 are all Yes pairwise with each other, and nodes 5 thru 7 are all pairwise yes with each other, but any of first 4 nodes are no with the last 3, you could see whether neat or other Graphviz programs can “separate” those groups for you visually. If they cannot do it for a simple input like that, it might not be a useful approach.


In general, if the inputs aren’t so clearly divisible into groups, then the output node placement is going to be less clearcut than the straightforward inputs


Ok, so I’m thinking of taking a different approach. Instead of trying to use graph theory and springs, I was thinking of doing a brute force approach. Assign higher scores to greater compatibility, (ex. yes-yes would be higher than yes-maybe, yes-no, maybe-no, etc.) then try each combination of group configuration until they converge. I’m not sure how I would approach this at all.

Kelsey Sorrels18:02:54

> how to create a cluster graph from edges and distances Certainly not a silver bullet, but multi-dimensional scaling can transform pair-wise distances into points in a cartesian space which are then appropriate for clustering.


Ok, so I’m thinking of taking a different approach. Instead of trying to use graph theory and springs, I was thinking of doing a brute force approach. Assign higher scores to greater compatibility, (ex. yes-yes would be higher than yes-maybe, yes-no, maybe-no, etc.) then try each combination of group configuration until they converge. I’m not sure how I would approach this at all.