Fork me on GitHub
#beginners
<
2019-12-09
>
Jared Schreiber02:12:39

im a clojure noob and im having a bit of a problem,

Jared Schreiber02:12:16

i wrote an app and it runs using lein run but when i try to compile it using lein uberjar it takes forever and ever and hangs basically

dpsutton02:12:18

i don't know if this is your root problem but using (load "utils") in your core namespace and extending your core namespace with in-ns 'supremereality.core is strange

alexmiller02:12:19

it's unusual, but that's how clojure.core is defined too (and core is AOT compiled)

alexmiller02:12:55

that shouldn't by itself be an issue

dpsutton02:12:35

maybe threadlocks? are you sure you don't have circular dependencies?

dpsutton02:12:11

sorry. threadlock is meaningless. i meant i think you've got a deadlock due to io on files

Jared Schreiber02:12:44

I'm not sure what that means, how would I resolve this

alexmiller02:12:51

compilation is single threaded. I don't understand how deadlock is possible.

alexmiller02:12:26

one thing to try would be to get a thread dump via jstack on the pid to see where it's stuck

dpsutton02:12:48

i'm going on this

"main" #1 prio=5 os_prio=0 cpu=2304.61ms elapsed=85.45s tid=0x00007f6420014800 nid=0x68f2 in Object.wait()  [0x00007f6427986000]
   java.lang.Thread.State: WAITING (on object monitor)
	at java.lang.Object.wait([email protected]/Native Method)
	- waiting on <0x000000071a679550> (a java.lang.Thread)
	at java.lang.Thread.join([email protected]/Thread.java:1305)
	- waiting to re-lock in wait() <0x000000071a679550> (a java.lang.Thread)
	at java.lang.Thread.join([email protected]/Thread.java:1379)
	at .Pipe.join(Pipe.java:120)
	at leiningen.core.eval$sh.invokeStatic(eval.clj:191)
	at leiningen.core.eval$sh.doInvoke(eval.clj:173)
	at clojure.lang.RestFn.applyTo(RestFn.java:137)
	at clojure.core$apply.invokeStatic(core.clj:665)
	at clojure.core$apply.invoke(core.clj:660)
	at leiningen.core.eval$fn__6360.invokeStatic(eval.clj:263)

alexmiller02:12:57

I don't think that's relevant

alexmiller02:12:22

leiningen launches two vms - I think that's just the first one waiting for the second one

alexmiller02:12:26

you can use jstack (or kill -3) on the other lein vm (`jps` can tell you pids for java processes)

dpsutton02:12:58

i think i see your issue. in your main file you have the form

(sched/interspaced 900000 #(reset-floodlist) my-pool) ;;time in ms, 900000 = every 15 mins - resets flood list
which is being evaluated at compile time

dpsutton02:12:07

if i comment that out i can get a jar

ScArcher04:12:48

If I have a vector and I want to break it up into chunks like. [1 2 3 5 6 7 8 9 0] and I want to turn that into [[1 2] [3 4] [5 6] [7 8] [9 0]] what would I need to do?

ScArcher04:12:17

I'm having a hard time understanding when to use map, when to use reduce and when I need to use something else 🙂

seancorfield05:12:21

FWIW, you can write map in terms of reduce (although it then becomes eager instead of lazy) so reduce is the more primitive, more fundamental concept.

seancorfield05:12:33

mapv really. (mapv f l) == (reduce (fn [s x] (conj s (f x))) [] l) -- not sure if that helps?

ScArcher04:12:26

Or maybe it's how to put them together.

dpsutton04:12:14

Check out partition

dpsutton04:12:29

And partition-all is often what you actually want. Read the docs of both and be aware of the differences

👍 2
Jeevaraj MV04:12:05

(partition 2 vector )

Jeevaraj MV04:12:38

Vector will be ur assigned vector

Jeevaraj MV04:12:14

“2” will be arguments

Jared Schreiber05:12:14

hey im back, sorry for the delay

Jared Schreiber05:12:42

thanks for the advice, do you see any way to keep that line and still get a jar?

Jared Schreiber05:12:31

the reason i say that is, I have an atom that keeps track of POST requests and every time someone posts it ASSOC's their IP address : timestamp into the map

seancorfield05:12:38

@jaredkschreiber All top-level forms are evaluated when the namespace is loaded -- which is done when a JAR is made. You'd need to turn it into function that you explicitly call when your application starts up.

Jared Schreiber05:12:57

this is used to track if they post more than every 20 seconds (to prevent spam)

Jared Schreiber05:12:14

thanks.. so, ill put it in main then

seancorfield05:12:26

Yup, that would work.

seancorfield05:12:08

In general, you don't want anything as a top-level form that isn't a defn or a very simple def that defines a "constant".

ScArcher05:12:20

I have another beginner question, if I want to take a vector of vectors [[1 2] [1 2] [3 4]] and turn them into [[1 1 3] [2 2 4]] is there something that makes that simple?

ScArcher05:12:38

basically build vectors out of the first element in each, then second element in each.

seancorfield05:12:55

@scott.archer Are you after the general case of pivoting an N x M "matrix"? Or just a specific subset of that?

ScArcher05:12:33

Yes, my vectors are the same size, but it's not 2x3

seancorfield05:12:52

I think (apply mapv vector matrix) is what you want...?

seancorfield05:12:37

user=> (def matrix [[1 2] [1 2] [3 4]])
#'user/matrix
user=> (apply mapv vector matrix)
[[1 1 3] [2 2 4]]
user=> (apply mapv vector *1)
[[1 2] [1 2] [3 4]]
user=> 

ScArcher05:12:18

That's exactly what I want, but why does that work?

ScArcher05:12:32

you apply mapv to what?

ScArcher05:12:41

the function vector and our matrix?

seancorfield05:12:56

map/`mapv` can operate on multiple collections -- and apply their function argument across all successive elements of each collection

seancorfield05:12:29

(mapv vector [1 2] [1 2] [3 4]) => [[1 1 3] [2 2 4]]

seancorfield05:12:51

apply just unrolls the collection into separate arguments.

seancorfield05:12:21

(apply mapv vector [[1 2] [1 2] [3 4]]) => (mapv vector [1 2] [1 2] [3 4])

seancorfield05:12:44

So you get (vector 1 1 3) then (vector 2 2 4) in the result.

ScArcher05:12:20

I think I understand, but this is my struggle with learning Clojure.

seancorfield05:12:02

This sort of stuff can be pretty mind-blowing until you internalize some of the fundamental abstractions... and that often only comes with practice, practice, practice...

ScArcher05:12:17

I'm learning a language and a new way of solving problems. 🙂 Do you just need to stick with it long enough to get over the hump?

seancorfield05:12:44

Yup. Just keep plugging away. The light bulb comes on very brightly one day 🙂

ScArcher05:12:25

Thanks again! I'm working through Advent of Code in Clojure. I've written some pretty horrendous Clojure, but some of it I think turned out well!

seancorfield05:12:40

Remind me, what's your programming background?

ScArcher05:12:43

It's funny because I know what I want to do, but I just struggle to know how to do it with the language. I'm a old Java developer that's written some Ruby (Jruby) and some C#. In management at my company. I'm sold on functional programming and determined to learn it, though learning things is harder now than it was 20 years ago 🙂

seancorfield05:12:33

Ah, so you have a lot of "bad habits" to unlearn from years of OOP then... That can make FP tough to internalize, but stick with it!

seancorfield05:12:14

My professional arc was assembler, COBOL, C, C++ ('92), Java ('97), Groovy, Scala, Clojure -- but I was helped by doing Lisp/ML/etc back in university in the early 80's 🙂

ScArcher05:12:17

Yes, I already see the benefits of FP. I manage a team of C++ devs and a team of C# devs. We're about to start a new project and I'd love to consider some functional languages. I feel like I need to know it to recommend it though.

ScArcher05:12:04

I took a class on Lisp in college and hated it until it clicked. But I forgot most of it after that class as I didn't pick it up again until recently.

ScArcher05:12:05

I started with Java 1.2 writing servlets hosted on JServ. I stopped doing any real development around the time spring-mvc came on the scene.

seancorfield05:12:53

Back when Java was still a "small" language 🙂 I started with 1.1 and I sort of left after 1.5 came out... it had grown so huge by then 😞

ScArcher05:12:34

Yep, I understood generics pretty well, but didn't really jump onto the Java 8 bandwagon. I did most of my work in Java 1.5 / 1.6.

ScArcher05:12:03

I watched Rich's rant on the Servlet Spec. I LOVE the way clojure handles http.

seancorfield05:12:25

As a C++ shop, have you looked at Rust? That would probably be my go-to if I was still "close to the metal" or looking at embedded stuff (I did a bunch of telecoms with C++ in the mid-90's).

ScArcher05:12:11

At this stage the "corporate" language of choice looks like .net. We have some good C++ developers. There's some interest in Rust, but it would probably depend on what we were writing.

seancorfield05:12:27

OK, so F# is a possibility? That's a nice language.

ScArcher05:12:32

We have clients and web components. A bit of everything really.

ScArcher05:12:05

F# would be an easier sell, though I think everything will be on the table for this new project.

ScArcher05:12:32

I'd love to at least do some prototyping in Clojure.

1
seancorfield05:12:31

I try to learn a new language every year or two. F# was several years ago... I did a workshop at a conference and hung out with a bunch of F# folks for a while... seems to have an awesome community.

seancorfield05:12:00

Rust was another one of those "new languages" to learn. Very interesting and, again, a really nice community.

seancorfield05:12:17

Go, on the other hand, was a massive disappointment on pretty much every front 😐

ScArcher05:12:57

I've heard that from several people. One person on my team has been doing go on the side for some open source projects. They enjoyed it for a while, but I think the end result was "meh"

Cameron05:12:18

I was really surprised with Rust in how many parts of it felt like Haskell (and if anything, just dressed up in a more familiar form), with an example being algebraic data types dressed up as Enums, or traits which,if I remember, were typeclasses or close to them. I had already heard it pulled inspiration from Haskell, but I was still surprised somehow

seancorfield05:12:44

Rust is beautifully designed. I was very impressed with it. I have had kind of a love/hate relationship with Haskell ever since it appeared (nearly 30 years ago now -- OMG!).

seancorfield05:12:21

I think if I was working on the JVM and couldn't use Clojure, I'd go with Kotlin. I think that's well-designed and very pleasant to use.

seancorfield05:12:03

(I'm very opinionated about languages since my background is actually language design and compilers etc 🙂 )

seancorfield05:12:25

I think it's awesome that we have so many to choose from!

Cameron06:12:35

Aha its funny because its usually me having this conversation, and it goes in an awfully similar direction where I mention Kotlin and end with "if you're wondering why I care about so many languages, its because one of my main interests is language design and compilers" (flat out almost verbatim), I feel like I'm suddenly on the other side of the table

Cameron06:12:44

although funnily enough, while now I love Clojure specifically from that angle

Cameron06:12:53

I got into it because of my interest in the paradigms

Cameron06:12:10

didn't even know of its merits there, just thought of it as a functional language, and a newer lisp

seancorfield06:12:40

Rich is a thoughtful, careful language designer too 🙂

Cameron06:12:49

There is a lot of design merit to Clojure that is easy to overlook as well, because many of those merits come not from individual features, but from the harmony between others, or the well placed pruning of features

Cameron06:12:02

Strangely enough, I've seen Common Lispers seem to detest Clojure more than anyone, when I would have thought them to be our loving siblings (then again, many siblings fight explosively). When I try to read their points, though, I can't be sure but it almost seems like likewise they themselves have not come to intuit these hidden benefits, but worse I feel like they may just be looking at Clojure from a Common Lisp lens, since they already know it so well (such that its image overshadows Clojure), where Clojure will always do Common Lisp things worse than Common Lisp because, despite all of its similarity, its strategy is actually very different (with of course exceptions; Clojure's error messages being an example of Clojure for now being flat out weaker somewhere, and I assume Common Lisp's condition and restarts are a case of Common Lisp being flat out stronger, unless there is some trade off of that system I'm unaware of -- its not something I've personally analyzed). I don't want to assume their point of view -- its easy to do that and then have an easy strawman to take down (sort of like what I spoke of with FP yesterday ahahah), but sometimes I get this impression . There is just as much benefit in what is removed from Clojure as there is from what's added; as an artist, Rich makes great use of negative space

seancorfield06:12:16

I think a lot of Common Lisp folks have developed a bit of a complex because CL has been around for so long, it's got an ANSI standard, and yet it really hasn't gotten much mainstream traction -- and along comes Clojure, the upstart Lisp, on the JVM (and CLR and JS) and it gets all the love.

seancorfield06:12:30

Clojure has exceptions because all three of its host platforms have exceptions. Adding a condition system with restarts would be great, but it wouldn't work well with exceptions. CL doesn't have to play nice with anything else -- it can be its own island -- so it can be much more dogmatic about language/library features (but that's also a weakness because it can't interop easily with all these other languages -- like Clojure can).

ScArcher06:12:57

(defn do-stuff []
  (let [input (seq-number (slurp "/home/archer/code/advent-of-code-2019/8/sarcher/input.txt"))
        layer-size (* 25 6)
        image (vec (build-image input layer-size))
        zero-counts (doall (map #(count-occurences 0 %) image))
        layer-index (first (index-of (apply min zero-counts) zero-counts))]
    (apply str (map flatten-pixel (flatten-image image)))
    ))
I find myself doing this a lot. I'm assuming it's an anti-pattern or something in Clojure. Is this typical, or is there a way to avoid some of this? Specifically all the function calls in let blocks

ScArcher06:12:46

Is it better to push those types of calls into separate functions to simplify and make it easier to understand?

andy.fingerhut06:12:51

I think it is a pattern, personally.

ScArcher06:12:07

So not inherently bad.

andy.fingerhut06:12:25

If you find yourself using a particular combination of function calls repeatedly, and have a good name for it, then good to create a function for that.

andy.fingerhut06:12:21

If you had 50 lines like that, then probably a good idea to see if there is a good logical split into multiple functions.

ScArcher06:12:14

I've kept it to just a few typically, but I feel like it can make it hard to understand what a function is doing. You have to parse through all the functions that build the let block.

ScArcher06:12:57

Thanks for the feedback though! It's nice to know it's not bad.

andy.fingerhut06:12:59

Clojure code can be much more terse than some other programming languages, and so take longer to understand a single line than a single line of code in another language. That is a good thing when writing it, but can be a source of (at least initial) frustration when reading it. Not that it is difficult to read, but there is usually more packed into a smaller space.

seancorfield06:12:53

I would probably update build-image to return a vector (so you don't need to call vec on it), and use mapv instead of (doall (map ,,,))

seancorfield06:12:14

That code doesn't seem to use layer-index -- I assume there's more stuff you omitted? (and if you don't need layer-index, you don't need zero-counts either)

Jared Schreiber07:12:17

well friends, it's up! i deployed my demo app thanks to the help here:

Ike Mawira09:12:47

Hi, not sure, is this intended? Like i have to click on a picture to see it. And when i click another picture, the first picture i had clicked on becomes hidden again. Under the content warning area in memes.

Cameron07:12:54

oh an imageboard

Cameron07:12:58

this is something I can get behind

Cameron07:12:16

I unfortunately browsed 4chan and hispachan a bit back in the day

Jared Schreiber07:12:47

yes, but this one is slightly different

Jared Schreiber07:12:06

on traditional forums (ex: phpbb) and imageboards, its sorted by most recent reply

Jared Schreiber07:12:20

i.e. a reply bumps a thread up tothe top of the catalog

Jared Schreiber07:12:43

however this is sorted by average post "quality score" i call it weight in the code

Jared Schreiber07:12:35

so a posts weight is the average word length squared, multiplied by amount of words in that post

Jared Schreiber07:12:50

so effortposts bump more than responding 'lol' or something

Jared Schreiber07:12:25

also its an average rather than a sum, so if the thread gets derailed with '**posting' (im sure you know the term)

Jared Schreiber07:12:30

it sinks it to the bottom

Jared Schreiber07:12:51

I'm pretty excited, gonna make a blog post explaining all this later

Cameron07:12:53

I'm still messing around with possibly topic descriptions here ahaha as right now I have two similarly redundant topics of "All topics about the language" and "Topics relating to technology" (perhaps in those cases it would be better to just repeat the board name)

Cameron08:12:02

as it was, I pulled 'topics relating to technology' from somewhere at the top of /g/

Cameron08:12:38

somehow that slightly reminds me of a time where I was thinking about playing around with certain forum mechanics (in my case though it was some really far fetched stuff, basically having a karma system with different personality traits like 'intelligent' 'moral' 'machiavellian' 'fun' (well, I don't think they were quite like that) and you would have like this avatar that would grow into different kinds of monsters depending on your combination of karma (so you might try to make posts that people would rate as dark or machiavellian or whatever I wrote it as to grow your monster in a 'dark' direction), and I think I decided you'd be able to battle them ... really out there stuff, have no idea what would have come of that

Cameron08:12:21

yea I've been on a lot of these sorts of forums for about 15 years now ahahah so I too like to see something like this!

Jared Schreiber08:12:29

The reason I used the post length mechanic is because bumping based on latest reply encourages quick responses, this encourages effortposting. Also i didn't want to use upvotes like on reddit as it encourages groupthink, so i had to come up with a somewhat objective metric of whats going to be seen at the top

Cameron08:12:17

as it was, it feels like slack and discord sort of took something like IRC and reintroduced it in modern clothing to big success, and I would wonder about the potential for imageboards as well

Jared Schreiber08:12:29

slack/discord = modern IRC, reddit = modern phpbb forum, etc. to an extent

nmkip13:12:06

is there a clojurians discord?

Ike Mawira12:12:46

I need help to understand why my dependency resolution fails on a fresh new lein project. The added dependencies are

[org.clojure/clojure "1.10.0"]
               [datomic-free "0.8.3331"]
               [expectations "2.1.10"]

Ike Mawira12:12:11

The error i get is

Error synchronising pet-owners:0.1.0-SNAPSHOT: The following artifacts could not be resolved: aws-java-sdk:aws-java-sdk:jar:1.3.0, bsh:bsh:jar:2.1b5, commons-compiler:commons-compiler:jar:2.6.1, commons-compiler-jdk:commons-compiler-jdk:jar:2.6.1, data.json:data.json:jar:0.1.2, guava:guava:jar:r09, h2:h2:jar:1.3.165, hornetq-core:hornetq-core:jar:2.2.2.Final, httpclient:httpclient:jar:4.2-alpha1, httpcore:httpcore:jar:4.2-alpha2, infinispan-client-hotrod:infinispan-client-hotrod:jar:5.1.2.FINAL, infinispan-core:infinispan-core:jar:5.1.2.FINAL, jackson-core-asl:jackson-core-asl:jar:1.8.0, java-xmlbuilder:java-xmlbuilder:jar:0.4, java.classpath:java.classpath:jar:0.1.1, jboss-logging:jboss-logging:jar:3.1.0.CR2, jboss-marshalling:jboss-marshalling:jar:river-1.3.6.GA, jboss-transaction:jboss-transaction:jar:api_1.1_spec-1.0.0.Final, jcl-over-slf4j:jcl-over-slf4j:jar:1.6.4.jar, jets3t:jets3t:jar:0.8.1, jetty:jetty:jar:6.1.25, jetty-util:jetty-util:jar:6.1.25, jgroups:jgroups:jar:3.0.6.Final, jline-win:jline-win:jar:1.0, jul-to-slf4j:jul-to-slf4j:jar:1.6.4.ja, log4j-over-slf4j:log4j-over-slf4j:jar:1.6.4, logback-classic:logback-classic:jar:1.0.1, logback-core:logback-core:jar:1.0.1, lucene-core:lucene-core:jar:3.3.0, netty:netty:jar:3.2.4.Final, ring-core:ring-core:jar:1.0.1, ring-jetty-adapter:ring-jetty-adapter:jar:1.0.1, ring-servlet:ring-servlet:jar:1.0.1, servlet-api:servlet-api:jar:2.5, slf4j-api:slf4j-api:jar:1.6.4, spymemcached:spymemcached:jar:2.8.1, stax2-api:stax2-api:jar:3.1.1, test.generative:test.generative:jar:0.1.4, tomcat-jdbc:tomcat-jdbc:jar:7.0.27, tomcat-juli:tomcat-juli:jar:7.0.27, tools.namespace:tools.namespace:jar:0.1.1, woodstox-core-asl:woodstox-core-asl:jar:4.1.1: Could not find artifact aws-java-sdk:aws-java-sdk:jar:1.3.0 in central ()

Ike Mawira13:12:51

Ah, seems like the issue is i used the wrong datomic on clojars.