Fork me on GitHub
#clojure
<
2019-06-26
>
pinkfrog06:06:01

why to build tools exist, boot and lein?

pinkfrog06:06:10

this is weird for the eco.

andy.fingerhut06:06:57

Leiningen was created first, and served the purposes of many many developers. Some developers decided they wanted something significantly different. I haven't used boot myself, but my impression is that the build "scripts" you create with it are just Clojure code, leveraging useful libraries provided by boot. Many developers decided they liked that style of tool better, and used it instead of Leiningen.

andy.fingerhut06:06:26

The development of boot did not cause everyone to switch to it from Leiningen, and some fraction of people use neither Leiningen nor boot.

magthe07:06:00

I, on the other hand, think it's rather impressive that there are only 2 😁

😁 4
mpenet07:06:33

there are more 🙂

borkdude07:06:10

some fraction of people use leiningen, boot and clj 🙂

andy.fingerhut07:06:56

The "What tools do you use" question on the 2019 State of Clojure survey shows what the responders use: https://www.surveymonkey.com/results/SM-S9JVNXNQV/ (Question 17)

akond10:06:46

(xml/parse-str "<book><!-- i can see you--></book>") produces #xml/element{:tag :book} but i want to keep the comment. what should i do?

Alex Miller (Clojure team)11:06:33

You can tell it which infoset types to keep while parsing. There’s a default set, but you can override it.

akond11:06:22

@alexmiller you are super helpful, thank you very much

stathissideris15:06:50

I’m trying to call this (GLFW/glfwCreateWindow (int 300) (int 300) title nil nil) but I get a reflection warning call to static method glfwCreateWindow on org.lwjgl.glfw.GLFW can't be resolved (argument types: int, int, java.lang.CharSequence, unknown, unknown)

stathissideris15:06:07

the last 2 arguments really have to be nil

ghadi15:06:09

what is the signature(s) of that method @stathissideris? (include all if there are different types for the same arity)

stathissideris15:06:28

public static long glfwCreateWindow​(int width,
                                    int height,
                                    java.nio.ByteBuffer title,
                                    long monitor,
                                    long share)

public static long glfwCreateWindow​(int width,
                                    int height,
                                    java.lang.CharSequence title,
                                    long monitor,
                                    long share)

ghadi15:06:27

so you can't pass a nil into a long arg -- the Java wouldn't compile

ghadi15:06:48

send in 0, 0

ghadi15:06:59

which is the default value for a long

stathissideris15:06:53

ooooooh I just realized that the java example I’m translating uses NULL instead of null, probably a static member of some class. Thanks, let me investigate

ghadi16:06:25

maybe it's the constant 0

stathissideris16:06:48

it seems to be that 🙂

PaulGureghian17:06:30

is Clojure pre-installed on MAC OS ?

Alex Miller (Clojure team)17:06:47

but if you have brew, it's just a "brew install clojure" away

PaulGureghian17:06:14

Yup. That's my plan

Dave Goodchild17:06:55

They took away telnet they wouldn’t want something as awesome as Clojure in there it might give people ideas

PaulGureghian17:06:45

I am just getting into Clojure, setting up my dev env ...

dog18:06:32

i just started with clojure too, found this to be really helpful https://www.braveclojure.com/clojure-for-the-brave-and-true/

PaulGureghian18:06:37

Dog, how do you feel today. I know it's been a bad day

dog18:06:14

sorry i dont believe i know you, anything that made your day bad?

dog18:06:40

oh okay 🙂

PaulGureghian18:06:58

Guess you didn't hear the news

dog18:06:13

did we declare war against iran or something

dog18:06:15

whats the bad news

dog18:06:29

i looked up google news, nothing extremely bad, just the regular varity of depressing lol

markx18:06:45

Is there a good tutorial or article or whatever about functional patterns of interop with java?

dog18:06:49

i guess the heavily depends on what you want to do in java

noisesmith18:06:32

I can think of a few from StuartSierra that apply don't wrap side effects in laziness https://stuartsierra.com/2015/08/25/clojure-donts-lazy-effects and the one about "it isn't mutation if the consequences don't escape scope"

noisesmith18:06:43

maybe that was someone else's

noisesmith18:06:49

@markx my tl;dr version is don't build "pure" facades over impure things unless the scope of the thing ends with the return of your function

noisesmith18:06:25

but there are plenty of things in java (that one would use via interop) that are immutable / functional

markx18:06:25

Thanks I’ll read it later. My problem is that I found everything I want to do requires some java interop, which is very sad. (I wish Clojure didn’t encourage java interop) Recently I’ve been using Jline and I can’t find a comfortable pattern to integrate it to my clojure code. I basically create an object from the class and store it into an atom, and then all functions refer to that atom. I feel if I have to do it this way why don’t I just write java.

noisesmith18:06:05

why an atom?

noisesmith18:06:19

if you mutate the object, the atom isn't safe

markx18:06:02

what else then? A var?

noisesmith18:06:10

swap! etc. guarantee to retry on conflict, you can't retry operations on a stateful mutable thing

noisesmith18:06:33

you could use an agent (operations are guaranteed not to overlap, no retries)

markx18:06:49

well I don’t use swap! to call methods of that object. I just use atom to keep a reference.

noisesmith18:06:50

you could only use the object in one thread, and not create a global handle to it

markx18:06:14

What if, say I have a tcp connection, and I need to write to it in different threads?

noisesmith18:06:20

then you need some sort of locking scheme to prevent interleaved partial writes

noisesmith18:06:48

or make a worker thread with the sole job of writing, and a queue that pulls requests from other threads

noisesmith18:06:13

it's still not safe to simply put the connection in a global without other infrastructure

noisesmith18:06:21

stateful objects shouldn't be global, and if they are global, they need some other infrastructure in order to be used correctly

markx17:06:54

Ah I see your point. Thanks!

noisesmith17:06:08

and I was overgeneralizing - there's such thing as thread safe mutable objects - it's just not the norm (and you usually need to fill in some details about what to do in conflicts in surrounding code, or understand the possibility of deadlocks...)

noisesmith18:06:44

anyway, atoms are meant for safely updating contents that are immutable, so are a mismatch for holding a mutable object

noisesmith18:06:19

(not using swap! or swap-vals! or compare-and-set is a sign an atom is the wrong container to me)

noisesmith18:06:33

libraries like stuartsierra/component, and integrant, etc. are designed for managing stateful objects (doing initialization as you spin up your system, and shutting them down cleanly when done, handing references to the parts of the system that need to use them without relying on globals)

noisesmith18:06:27

@markx "Functional programming with immutable values is wonderful, but sooner or later every program has to deal with mutable, stateful, imperative tasks." https://www.youtube.com/watch?v=13cmHf_kt-Q

markx18:06:14

What if, say I have a tcp connection, and I need to write to it in different threads?

andy.fingerhut21:06:11

@mikerod Regarding one of your comments about the cljol library I mentioned in the announcements channel recently, there is certainly more that could be done with it to programmatically analyze a collection of Java objects, and in fact the JOL library itself already contains some code to print summary statistics of a collection of objects in a few different ways. The graph drawing parts of cljol are nice for small to medium sized things, but quickly become too much for a person to make use of.

👍 4
mikerod21:06:59

@andy.fingerhut yeah, it makes sense. It looks like something interesting to look at though. I could see it being valuable to be able to navigate over these things

mikerod21:06:45

The graphing part is cool indeed. Of course, that could get huge obviously.

andy.fingerhut21:06:56

Definitely. I have already written some code that does sanity checks on the Java object graphs obtained using the JOL library. For example, if a GC occurs in the middle of walking a structure, the addresses of objects can change, and memory addresses is the way that JOL remembers which object is which while doing the walks, so in those cases you can end up with much less useful results.

andy.fingerhut06:06:03

I do not know yet. Thanks for pointing it out. I may be able to answer that question later, but at first look, the graphs that clj-memory-meter are ASCII art only, but it definitely seems better at giving total stats for a single object or all objects reachable from there within a REPL.

👍 4
andy.fingerhut21:06:21

As it is now, the code looks for such inconsistencies, and if it finds one, runs (System/gc) and tries walking the structure again, up to 4 times.

andy.fingerhut21:06:01

The Clojure data structures created as an intermediate step would be straightforward to do other kinds of analysis on, other than drawing graphs.

mikerod21:06:15

Nice. Makes sense.

dbernal23:06:59

has anyone been having issues with the https://repo1.maven.org/maven2/org/clojure maven repository? Or perhaps anyone that uses Travis having any issues running lein deps?