Fork me on GitHub
#beginners
<
2021-03-25
>
zackteo06:03:38

On a linux system, where does lein install dependencies to, if i use sudo . Was trying to see if the steps for a tutorial wasn't working because I was not running in sudo. I understand that dependencies are normally installed in /home/.m2

seancorfield06:03:11

$HOME/.m2/repository

seancorfield06:03:26

(same as macOS and effectively the same as Windows)

seancorfield06:03:39

All Clojure dependency tools use the same location.

seancorfield06:03:40

If you use sudo, I would expect it to use root’s ~/.m2 location (but… why on earth would you use sudo with this?)

zackteo07:03:28

I mistakenly believed that I might need sudo permissions for ssh capabilities 😅 Am trying to use jepsen for testing for a distributed systems project

zackteo07:03:44

Realised I don't have a jepsen nodes set up

zackteo07:03:40

I realise is perhaps a bad habit, cause there have been many instances where I spent a lot time figuring out what is wrong with my commands, only to realise all i needed was sudo

motform10:03:34

Does anyone have any recommendations of TCP clients to use with Clojure? I want to programatically communicate with a prepl over the wire. I'm assuming the answer is Aleph, but it feels like there is a lot of buy-in with manifold and byte-streams.

flowthing11:03:58

I wrote this Gist some time ago about communicating with prepl using core.async: https://gist.github.com/eerohele/e06551b115c6a31d1280a115c4c2abb2

flowthing11:03:37

But if you don't already have core.async as a dependency or don't want to add it, you could just use something like java.util.concurrent.LinkedBlockingQueue.

motform10:03:20

Is it possible to use http-kit to do raw tcp communication? I reckoned it was limited to http requests. Networking is not my stronget suite, so forgive me if those terms are interchangable in this context.

Michaël Salihi11:03:39

No you can't. My bad, I read your request too quickly. 🙏

Michaël Salihi11:03:46

If you want to keep it simple as possible, you can use Java interop like that https://github.com/clojure-cookbook/clojure-cookbook/blob/master/05_network-io/5-09_tcp-client.asciidoc, otherwise, I think Aleph is the most likely solution.

💯 1
motform12:03:01

Thanks, I'll check the interop example out!

noisesmith15:03:05

yeah, Socket would be my first go to if all I need is TCP itself

👍 1
Kenneth Gitere10:03:08

Hi Clojurians. I'm not very familiar with libraries in cljs (or Clojure in general) but I noticed that most frontend frameworks are React inspired in some way. Are there any frameworks that work similar to Svelte?

simongray14:03:27

Thomas Heller who makes Shadow-cljs is working on something like that: https://www.reddit.com/r/Clojure/comments/m2bvy1/shadowgrove_playground_sneak_preview/

👍 1
John Preston11:03:39

Hi all, I am trying to set up tracing in Datadog for a Clojure app which is packaged with Capsule, and I need to specify the packages whose methods I want to trace. Can someone please tell me how Clojure namespaces map on to Java packages? e.g. if I have ns's john.core , john.foo.core , ... will these each become their own package at run-time (since I am not using AOT)? Thank you 🙂

Franco Gasperino16:03:39

when considering an external map structure, is it best practice to convert all keys to keywords (assuming they're all strings) and internally leverage keywords for access?

noisesmith18:03:00

the external structure is some serialized format - it has not types or implementation yet it's common practice to keywordize keys, but I've seen massive waste of effort in turning some external data into an internal "idiomatic" structure of the same shape, eg. turning "camelCase" into "kebab-case" etc. and implicit keywordizing can lead to the problem of the concretization of the serial format into program data being implicit, and then spread through the program maybe you want keywords maybe you don't, but definitely have an explicit step where the input-stream / string / whatever is turned into usable internal data

noisesmith18:03:13

the bug where keywordizing arbitrary strings would use up the heap is gone, but keywordizing keys when you aren't converting to a specified internal format is still silly

noisesmith18:03:50

I'd rather see (get input-data "someJSONKey") than (:someJSONKey input-data)

Franco Gasperino16:03:06

e.g. keywordize-keys on all external map structures

hiredman17:03:31

I think maybe you can make the argument for keywordizing when the maps have a closed known set of keys, but otherwise it is a waste

Franco Gasperino17:03:50

in this case, i have a known set of keys which i'm treating as a schema. I wish to walk an external structure and assert those keys are present and perform some additional validation on the values associated. The inbound map would likely arrive as string keys. So given your advice, i should treat my schema keys as strings and not keywords.

Franco Gasperino17:03:39

(def internal-schema #{:a :b})
(def external-content {:a 1 :b 2})

(remove #(contains? external-content %) internal-schema)
()

(def external-content {"a" 1 "b" 2})
(remove #(contains? external-content %) internal-schema)
(:b :a)

Franco Gasperino17:03:16

external-data would be sourced from an input stream containing json maps.

DoubleU17:03:10

Hey everyone, I’m trying to figure out a way to enable a css class for xx number of seconds when a user clicks a button, for example, I have this:

[:div {:class "refresh-icon -animate"}]
but i only want to show the -animate class for xx number of seconds when a user clicks some button. In React, I would do something like this:
<div className={`refresh-icon ${showAnimation ? '-animate' : ''}`}>{props.icon}</div>
and then have a method where I would toggle showAnimation true/false can someone lend a hand please? Thanks

dpsutton17:03:27

(cond-> "refresh-icon" show-animation? (str " -animate"))

DoubleU17:03:18

thanks @U11BV7MTK, i’ll if i can make that work

dpsutton17:03:41

at my last job we had a nice utility function for combining class names (u/classes "refresh-icon" {"-animate" show-animation?}) that would take the map of classes and the booleans of whether to add them and combine them. you could implement a function that does this or just use the one-off cond-> style here. The implementation of the utility function would be some kind of accumulation followed by a string/join with a space

DoubleU17:03:51

Oh clever, i think the one off will be fine for now

DoubleU17:03:18

@U11BV7MTK, should my entire line look something like this: [:div {:class (cond-> "refresh-icon" show-animation? (str " -animate"))}

dpsutton17:03:56

your problem is you need to dynamically create a string. the context doesn't seem relevant. that expression should create the string you care about, provided you have a local var called show-animation?. Did it work?

DoubleU17:03:56

actually that doesn’t look right, my compiler is yelling at me, it doesn’t like the show-animation property

DoubleU17:03:12

in my function, I added: (def show-animation false)

dpsutton18:03:19

don't put defs inside of functions. use (let [show-animation? false] your-stuff-here)

DoubleU18:03:53

yeah i read that somewhere and changed it to

(let  [show-animation false])
in my on-click I have:
:on-click (fn [] (show-animation true))
because i want to change it to true when clicked which should show/hide the -animate style here:
[:div {:class (cond-> "tasks--toast-icon" show-animation? (str " -animate"))}

cschep18:03:21

is there a simple way in clojure to say if not nil this else that e.g. (player :fantasy-team) ?? "No Team"

walterl18:03:35

(get player :fantasy-team "No Team")

walterl18:03:29

Or (pun intended)... (or (:fantasy-team player) "No Team")

walterl18:03:53

AFAIK the former is preferred

cschep18:03:57

ohhhh nice

cschep18:03:08

didn’t know maps could have default values but of course

walterl18:03:07

Not maps, but get 🙂

cschep18:03:12

err yeah thanks 🙂

walterl18:03:49

Oh wait... Maps do too!

walterl18:03:15

({:foo "foo"} :missing :default) => :default

delaguardo18:03:55

Keywords too

seancorfield18:03:07

Because they do a get under the covers (essentially).

seancorfield18:03:26

A hash map can be treated as a function that calls get on itself with the provided argument(s). A keyword or symbol can be treated as a function that calls get on its first argument, passing itself as the second argument to get, optionally passing the last argument (default) through.

seancorfield18:03:35

It’s why when folks end up with a symbol (instead of an actual function) and do (f 1) or (f 1 2) they get nil instead of an exception.

seancorfield18:03:27

(having (f) or (f 1 2 3...) would give an arity error)

hiredman18:03:49

something to keep in mind is a map lookup with a default will only return the default if the key does not exist in the map, so if the key is in the map and associated with nil, you will get nil back

cschep18:03:28

all very helpful, thanks everyone!

delaguardo18:03:16

(f 1) will probably give you undeclared var exception. ('f 1) shouldn't

seancorfield18:03:08

@U04V4KLKC f was illustrative of a bound symbol: my comment was about passing in a symbol instead of a function value, into code that tried to call it. Sorry, that wasn’t clear.

seancorfield18:03:56

(that cropped up the other day in relation to someone trying to pass a configurator function into the Jetty adapter via Leiningen project.clj config — because project.clj is data, some.ns/my-cfg is a symbol instead of a function, and the Jetty adapter assumed it was given a function and just “called” the symbol… which “worked” insofar as not throwing an exception but just evaluated to nil because it was basically (f server))

cschep18:03:10

feel clunky to write out a whole if

NoahTheDuke19:03:29

terminal/repl question: For some reason, when I type something into the repl and press "Enter", it deletes the prompt (pushing my input to the left edge of the screen). any ideas why or how to fix this?

andy.fingerhut19:03:22

There was some Q&A on line in the last 4 weeks or so I saw, but not sure where. http://ask.clojure.org maybe?

andy.fingerhut19:03:41

With workaround and to track when rlwrap release fixes it

NoahTheDuke19:03:07

thank you! that's great

hiredman19:03:32

It's an issue with some rlwrap versions

seancorfield19:03:56

@nbtheduke I believe that’s a bug in an older ve… yeah, what @hiredman said.

dpsutton19:03:20

cat ~/.inputrc
$if clojure
    set enable-bracketed-paste off
$endif

seancorfield19:03:21

I’m on an old Mac and have an old rlwrap and it happens to me. I’ve just learned to live with it 🙂

dpsutton19:03:37

forgot where i found this snippet

andy.fingerhut19:03:12

maybe answered in my replies above

dpsutton19:03:46

yes it did thanks! and i was able to remove the workaround after upgrading rlwrap so double thank you

seancorfield19:03:50

Ah, yes! I remember that now. And I think I added that workaround on one of my machines…

dpsutton19:03:12

its quite annoying if you're creating a bug report and the prompt disappears and you have to manually add it back in

NoahTheDuke19:03:25

that snippet fixes it, thank you!

seancorfield19:03:23

I have that .inputrc file on my old Mac but it doesn’t fix it. I guess my rlwrap is too old?

seancorfield19:03:05

(for multi-line pasting — if it’s just a single line, the prompt doesn’t disappear)

DoubleU22:03:24

Hi Everyone, I think I’m pretty close to figuring out this issue, but I’m wondering why my show-animation property isn’t updating to true and I wanted to find out if the steps below look correct. I created a variable in my method (let [show-animation? (r/atom false)]... I have a -animate style that I want to show when show-animation is true

[:div {:class ["refresh-icon"
                       (when @show-animation? "-animate")]}
and I have an on-click method that sets show-animation to true when clicking:
:on-click (fn [] (reset! show-animation? true))} "Show Animation"]...
Nothing is happening when I click the Show Animation button. Is there something obvious that I’m missing here? Edit: might also be worth mentioning when I println show-animation I see #<Atom: true>

hiredman23:03:12

I don't use clojurescript, or do much javascript, but you are almost certainly running afoul of whatever is rending [:div ...] as html not knowing it needs to re-render when the atoms value changes

hiredman23:03:07

I think most js/cljs frameworks need to be told about those kind of dependencies in someway

dpsutton23:03:12

one common bug is to put the let binding of the atom inside the render function, which sets the value of the r/atom to false on each render

dpsutton23:03:38

(defn component [] (let [show? (r/atom false)] [:div {:classname (if show? "show" "hide") :on-click #(swap! show? not)}])) ;; vs (defn component [] (let [show? (r/atom false)] (fn [] [:div {:classname (if show? "show" "hide") :on-click #(swap! show? not)}])))

👆 1
seancorfield01:03:02

(if @show? "show" "hide") right?

dpsutton01:03:00

Ah yeah maybe. The important bit is the returned function and the atom outside of that

1