Fork me on GitHub
#beginners
<
2017-12-21
>
hawari04:12:23

Hi, when compiling a ring project into a jar, is there a difference that I should know between using lein ring uberjar and lein uberjar?

hawari04:12:26

I've always blindly using lein ring uberjar as the tutorial suggested, and I notice when I run the jar produced by lein uberjar it starts a repl session instead of running a web server like lein ring uberjar does.

hawari04:12:21

I'm curious on how it became so.

noisesmith18:12:35

with lein uberjar you must configure the main ns to be launched when the jar is run

noisesmith18:12:47

if that config is missing, you get clojure.main as a default, clojure.main is a repl

noisesmith18:12:33

you can still run an app with that jar java -cp my-uber.jar clojure.main -m my.ns will launch my.ns/-main

noisesmith18:12:55

but you can also config leinengen so that ns of your choosing runs when someone runs the jar

hawari03:12:20

That's a very concise explanation @noisesmith, thank you

shidima07:12:04

I have an Atom with a list like so

'((1 2)(2 3)(3 4))
And I need to append an item to the front and drop the last one of. Can I do that in one swap! ?

genmeblog08:12:21

yes, just write function which does it and pass this function to swap!

shidima08:12:22

Yes, duh. why didnt I think of that 🙂

genmeblog08:12:23

if you are looking for queue, there is such data structure in clojure

shidima09:12:21

Im working on a snake clone in clojure

shidima09:12:24

No sure if a queue would apply there

shidima12:12:03

If I want to keep to the functional pardigem as much as possible, i should not let my functions operate on the global state?

jedahan16:12:38

is there documentation on when/why (gimme-a-fn (fn [x] (some-thing x))) works where (gimme-a-fn #(some-thing %)) doesn't?

seancorfield16:12:08

@slack1478 Can you give a bit more context of where the #( .. ) form doesn't work?

seancorfield16:12:58

All three of (gimme-a-fn (fn [x] (some-thing x))), (gimme-a-fn #(some-thing %)), and (gimme-a-fn some-thing) should be identical in behavior...

jedahan16:12:54

`(->> my-weird-java-object (map (fn [o] [(keyword (.getKey o)) (.getVal o)]))`

seancorfield16:12:01

Ah, because the function is creating a vector literal.

seancorfield16:12:46

#([(keyword (.getKey %)) (.getVal %)]) would try to "call" the vector since it's in the first position.

jedahan16:12:16

could i quote it out

seancorfield16:12:25

You could use #(vector (keyword (.getKey %)) (.getVal %))

seancorfield16:12:50

(and, no, you can't quote it -- you want the contents to be evaluated)

jedahan16:12:38

i like vector word better, its easier to read for me

jedahan16:12:56

ahh interesting, vector and vec are different as well

seancorfield16:12:03

(vector a b c) vs (vec coll)

New To Clojure17:12:09

Why changing global variable using just def is discouraged and using atom is considered better than that?

manutter5118:12:36

I’d say thread-safety mostly. But conceptually, def is for defining immutable values. There’s ways around that, but if you use them you’re kind of fighting against the language.

New To Clojure18:12:19

But the same applies to single-threaded programs. People just go and use atom or volatile.

New To Clojure18:12:47

It seems like an language convention indeed.

manutter5118:12:03

Yeah, "convention" sounds like a good way to put it. I'd even call it a best practice, in the sense of "you're better off using an atom you don't need than needing one you don't use."

noisesmith18:12:26

@ghsgd2 volatiles are never a good choice to replace a var

noisesmith18:12:41

they are unsafe to use from more than one thread, they are only good for local bindings

ghadi18:12:33

What @noisesmith said. Consider them effectively private API for the purposes of this room

seancorfield20:12:28

@ghsgd2 Also, a Var (from a def) is a very particular thing with its own special behaviors, different from an atom:

boot.user=> (def a 42)
#'boot.user/a
boot.user=> a
42
boot.user=> #'a
#'boot.user/a
boot.user=> (type #'a)
clojure.lang.Var
boot.user=> (ancestors *1)
#{clojure.lang.IFn java.lang.Runnable java.io.Serializable clojure.lang.IDeref clojure.lang.IRef clojure.lang.AReference java.util.concurrent.Callable clojure.lang.Settable clojure.lang.ARef java.lang.Object clojure.lang.IMeta clojure.lang.IReference}
boot.user=> (def b (atom 42))
#'boot.user/b
boot.user=> (type b)
clojure.lang.Atom
boot.user=> (ancestors *1)
#{clojure.lang.IDeref clojure.lang.IRef clojure.lang.AReference clojure.lang.IAtom2 clojure.lang.IAtom clojure.lang.ARef java.lang.Object clojure.lang.IMeta clojure.lang.IReference}

seancorfield20:12:14

In particular, if you def something else to a, it gets a's value at that point whereas if you def something else to b, you'll get the indirection:

boot.user=> (def c a)
#'boot.user/c
boot.user=> (def a 13)
#'boot.user/a
boot.user=> c
42
boot.user=> (def d b)
#'boot.user/d
boot.user=> (reset! b 13)
13
boot.user=> d
#object[clojure.lang.Atom 0x46bd848a {:status :ready, :val 13}]
boot.user=> @d
13
boot.user=> 

New To Clojure20:12:10

Thank you, @seancorfield! Indirection stuff is interesting.

emillime22:12:48

Hi, I want to play around and build an mobile app/game with clojurescript. The most popular way seems to be with re-natal. Do you know of any good tutorials or similar? I've been using clojure(script) for about two months now and I really like it. Want to do everything with it now! But I'm new to react and everything, so not sure where to start. Which one of on.next/reagent/rum is easiest to start with? I'm leaning towards reagent, but rum looks cool too. I want it to be as simple as possible. Thanks in advance!