Fork me on GitHub
#clojure
<
2020-01-21
>
macrobartfast04:01:04

I'm having a funny situation where the jetty server in a default pedestal app is not reachable over the local network on an osx machine with the firewall opened up for that... all other servers such as the node type servers (http-server) work fine... thoughts?

seancorfield05:01:07

@macrobartfast check whether it's binding to 0.0.0.0 or 127.0.0.1

seancorfield05:01:37

The defaults will differ across the variant server types I suspect.

macrobartfast05:01:52

ok... I'll take a look.

macrobartfast05:01:38

I had grepped unsuccessfully for a reference to either but I'll look more carefully.

hiredman06:01:49

Some bsd jvm builds (from which the osx openjdk builds were originally derived) would preferentially bind to ipv6 addresses

hiredman06:01:08

But that is an old thing that may not happen any more

zignd10:01:18

Why is it recommended in The Clojure Style Guide (https://guide.clojure.style/) to prefer swap! over reset! ? I was checking the implementation of both functions in the Clojure source code and I thought they looked very similar

delaguardo11:01:10

swap! and reset! are mutations per ce. So you probably want to show in your source code what kind of mutations you want to apply. Also most of code base are not static thing and during refactoring you might catch some problems because you silently dropping everything from the atom

zignd11:01:45

Oh I see, that about dropping silently is a good point! It's actually just a coding challenge, in this case I believe it might be necessary to go with swap! , but I will certainly consider to use it in other projects to prevent losing data. Thanks for this insight @U04V4KLKC!

kelveden11:01:31

For me, both are fine depending on the context. I prefer swap! over reset! by default but only if semantically it makes more sense - i.e. there's no point in trying to force what you're doing into a swap! at the expense making less expressive code.

👍 4
zignd11:01:54

I felt that when I tried to force myself to replace it with swap! and came to mind that maybe it wasn't worth because the data structure stored in the atom wasn't complex, but I wasn't sure, maybe due to my lack of experience, and the style guide did not provide arguments on that recommendation :thinking_face: Thanks @UJF10JP8A

👍 4
jaihindhreddy11:01:32

I dunno if the recommendation is about style really. A (swap! a (constantly x)) can always be replaced by a (reset! a x) without any problems. On the other hand, let's say you have an atom that you want to use as a counter. You can't replace a (swap! a inc) with a (reset! a (inc @a)) because your count will be less than correct with the second code sometimes.

borkdude11:01:53

I believe the section about swap! in the style guide is missing the point and fails to explain why you should use swap! over reset! (cc @U051BLM8F)

👍 4
borkdude11:01:34

reset! is totally fine if you just want to ... eh .. (re)set a single value that doesn't depend on the previous value

12
caio13:01:19

> Rich Hickey designed Clojure to specifically address the problems that develop from shared access to mutable state. In fact, Clojure embodies a very clear conception of state that makes it inherently safer for concurrency than most popular programming languages

caio13:01:48

If you use reset! For updating it you just negate the usefulness of an atom and are using it just as a regular variable like other languages, which is not its purpose

ghadi14:01:03

seems like a weird thing for a style guide to have an opinion about

4
Aaron Cummings14:01:20

I like that the style guide goes beyond guidance on naming and indentation, going on to recommend better practices. This style guide was probably the single most useful document when I was learning Clojure.

Matti Uusitalo15:01:18

I think you're supposed to avoid pulling values from an atom, calculating new ones and then reset! As that will be more risky than using swap!

ghadi15:01:40

"Avoid using reference types unless you really need them"

🎯 12
💯 4
didibus18:01:06

I think it means in cases where you read the value of an atom, and then want to update it, you should prefer swap! over reset!

didibus18:01:28

That's because only swap! will be thread safe

didibus18:01:41

So @U6PCW7E9F, the way you describe your use, it does sound like you're trying to update from a read. You probably want to use swap! then, unless you don't have to be thread safe

zignd18:01:08

I thought both swap! and reset! were thread safe, the code implementation is almost the same for both. I thought that because of the things I had read about as well :thinking_face:

caio01:01:35

both are atomic, but swap! applies f atomically, while (reset! (f @a)) doesn't (stuff can happen between reading and then updating and resetting the atom)

caio01:01:57

try this snippet for instance:

(defn inc-val [v]
  (Thread/sleep 1000)
  (inc v))

(let [a (atom 1)]
  (.start (Thread. (fn [] (println "With reset:" (reset! a (inc-val @a))))))
  (Thread/sleep 400)
  (swap! a inc))

(let [a (atom 1)]
  (.start (Thread. (fn [] (println "With swap:" (swap! a inc-val)))))
  (Thread/sleep 400)
  (swap! a inc))

💯 4
🎯 4
deas12:01:39

Seeing Could not transfer metadata foo:bar/maven-metadata.xml from/to releases (): Read timed out pretty often. Any suggestion what might be wrong and how to get around?

deas13:01:28

Appears I want -Dmaven.wagon.rto=... - sorry for the noise.

ghadi13:01:23

@deas is that with lein or what?

deas14:01:56

Yes. Solved it.

p-himik16:01:45

Does compile check any timestamps or anything else to determine that the result is already up to date to avoid unneded compilation?

ghadi16:01:15

specifically on the namespace__init.class vs the namespace.class

ghadi16:01:32

It's in load, not compile though

p-himik16:01:57

Thanks! Thought so. An interesting issue because of that. I start using a library v1, I compile its sources, all is good. Turns out, before I compiled it, v2 was released. Eventually, I upgrade to v2 not even thinking about the compilation step since it's done automatically. Since v2 timestamps are before I ran my compilation, the classes are never recompiled. v2 is on the classpath, but in fact v1 is uses.

p-himik16:01:51

I guess the lesson here is that I really shouldn't compile thirdparty libraries.

vemv18:01:28

By any chance does macOS like to randomly hide Java from the Dock? It hinders Swing usability (normally I set -Dapple.awt.UIElement=true so it's hidden upfront. Not this time) ...I would say that for a few hours this worked correctly, then java was removed from the Dock just like that

vemv18:01:08

I'm sure (via ps aux) that -Dapple.awt.UIElement=true is unset

hiredman18:01:56

Have you initialized a swing component?

hiredman18:01:38

Awt I guess

vemv18:01:49

yes e.g. https://hypirion.github.io/clj-xchart/examples was working for me this morning, now it doesn't even after restarting jvm

hiredman18:01:10

Are you using the same jvm?

hiredman18:01:23

Sounds like you might have switched to a headless build

vemv18:01:48

nope, I changed nothing

hiredman18:01:13

What do you mean by it doesn't work?

hiredman18:01:50

The library doesn't work at all (how does it fail)? Or using the library you don't get a dock icon?

vemv18:01:22

* the resulting JFrame isn't visible * no java element shows up in the Dock * (doto ... (.setSize 800 600) (.pack) (.setVisible true) (.toFront) (.show)) doesn't improve anything

vemv18:01:38

the lib worked this morning, 100% sure I didn't change the code or my jvm setup. macOS just decided to stop displaying a Dock icon which makes it hard ever see the JFrame

vemv18:01:47

Worked around by invoking macOS Mission control which makes more windows reachable

jjttjj20:01:42

Let's say you have several components in a project which use sente. What are the factors you consider when determining if the sente object should be totally private/internal to the component, or passed to the component as a dependency, or allowing the user to choose between these two?

noisesmith20:01:45

@jjttjj as far as I'm concerned one of the main benefits of using a component library is explicitly defining an interface of a module of your program, I'd start by thinking about what makes sense in a flow diagram for the component to consume from another component, and provide to other components, and refine that flow so that it makes it easier to understand your application design

👍 4
noisesmith20:01:52

another consideration is when testing that module / the modules that consume it, what would you want to parameterize in order to make the tests as functional and data-oriented as possible

noisesmith20:01:33

the thing that still trips me up in my projects is config - I definitely want to have parameterized config during testing, but in a system diagram config ends up being an input to everything which seems like a problem

noisesmith20:01:49

maybe I'm missing something obvious there

jjttjj20:01:57

Have you played with Integrant at all? I have just a little bit but it seems like it attempts to help this issue

lukasz20:01:09

It helps to separate configuration of your comments (usually static) and runtime configuration

lukasz20:01:27

still passing a config map around, but much smaller in scope

noisesmith20:01:31

@jjttjj yes I use integrant with my current app, and my approach is to explicitly consume a sub-key of config in each component rather than the whole map (but this is a convention and not enforced by integrant)

noisesmith20:01:13

of course nothing prevents calling def or alter-var-root inside a component init then using the config as a var