Fork me on GitHub
#beginners
<
2019-11-07
>
Marcio Arakaki00:11:07

hi, could you help me please ? I'm a trying to code function that read multiple lines of input (at once) but function only reads the first one

seancorfield01:11:53

@marcio.akk Share your code and we'll try to help.

seancorfield01:11:23

(if it's a lot of code, you can put it in a gist on github and just share the link here)

seancorfield01:11:58

Small code snippets shared here can be surround with triple backticks for formatting

like this

Marcio Arakaki01:11:49

What I'm trying to accomplish: paste a bunch of lines (json) and function reads it. I tried this code, but I seems that it keeps waiting for user input indefinitely

seancorfield01:11:58

(! 806)-> clj
Clojure 1.10.1
(defn read-json
     []
     (println (line-seq (java.io.BufferedReader. *in*))))
#'user/read-json
user=> (read-json)
Hello <-- pressed RETURN here
World <-- pressed RETURN and then control-d here
(Hello World)
nil
user=> 

seancorfield01:11:19

Did you press control-d to signal end of file?

Marcio Arakaki01:11:15

control-d writes ^D in the console

seancorfield01:11:16

Oh, are you on Windows?

seancorfield01:11:32

Then it would need to be control-z instead of control-d I think.

seancorfield01:11:12

PS C:\Users\sean> clj
Clojure 1.10.1
user=> (defn read-json
     []
     (println (line-seq (java.io.BufferedReader. *in*))))
#'user/read-json
user=> (read-json)
Hello <-- pressed RETURN here
World <-- pressed RETURN here
^Z <-- pressed control-z and then RETURN here
( Hello World)
nil
user=>

😅 4
👍 4
sb08:11:25

I use pedestal/ mount. When I modified the Clojure part, then everything works just I need to push CTRL+F5 on browser. Now I solved with a watcher script which do that automatically. Is that possible to do more Clojure native way? Browser (one active tab) refresh?

hawari10:11:26

Hi guys, I was wondering how do you guys usually keep your database connection in Clojure? During my search I stumbled upon this great question: https://stackoverflow.com/questions/39579023/clojure-best-approach-for-singleton-like-data-connection But it doesn’t address my concern about flexibility of the connection created. I wanted the connection to be global in order to be accessed from anywhere so I was thinking def or defonce should do it. But I also want to be able to pass values for creating the connection, I don’t want to rely heavily on configuration reading tools like environ etc to determine my connection configuration. This way I heavily depends on env, which is provided by environ

(def conn-options {:jdbc-url (env :database-url)})

(defonce conn (delay (make-datasource conn-options)))
Ideally I want something like
(defn create-connection [& params] (make-datasource params))
But by using it will result in connection being created every time the function is invoked. That’s why I was looking for something like a Singleton. I realize maybe better approach is possible in Clojure, but being a beginner, this is the only way I can think about.

dharrigan10:11:03

I have a simple example of using next jdbc with integrant here: . All db calls are handled within one namespace (db.clj)

dharrigan10:11:30

Adapt as you see fit, i.e., swap out integrant with another solution if suits you better 🙂

hawari10:11:12

Thanks! It’s exactly what I was looking for

dharrigan10:11:43

You're welcome.

hawari10:11:54

I also observed that many people use tools like integrant, mount, component, etc. Why is that?

dharrigan10:11:59

It's just a simple way of doing IoC in Clojure, where you can inject functions with side-effects into another namespace during "system" initialisation. i.e., setup a jetty webserver and hand that off to other namespaces as required.

dharrigan10:11:31

A way of describing your "system" through data

dharrigan10:11:04

which also permits stopping/starting/restarting your "system" within your REPL during development

dharrigan10:11:57

it's just a tool - you don't need integrant et al, if you don't need it.

hawari10:11:33

I still don’t quite grasp how it works and in what situation would I want to use that

dharrigan10:11:08

Don't worry about it for now then. Scratch that itch when you need it - but no need in overly complicating your learning experience with something that you don't need atm.

hawari10:11:11

But maybe that’s the problem, if I don’t have the trouble, I shouldn’t use the tool at all

dharrigan10:11:48

There isn't anything special in my simple example that needs integrant

hawari10:11:58

> Don’t worry about it for now then. Scratch that itch when you need it Well noted, thanks again friend for your kind help

dharrigan10:11:15

I guess what I was trying to say, is simply keep your database connection in one namespace.

hawari10:11:35

That as well, oh by the way, are you on ClojureVerse as well @U11EL3P9U?

hawari10:11:16

I’ve made a duplicate question there in order to receive more inputs, also to keep me from having to search the question again in the future

hawari10:11:40

If you don’t mind, would you post your answer to the post as well?

hawari11:11:08

Thank you @U11EL3P9U, you’ve been a very big help!

dharrigan11:11:52

You're welcome. Bear in mind, that's just one way - i.e., my way 🙂 You may discover a better way, or others may suggest other ways too 🙂

hawari11:11:17

That’s what I’m hoping for. I’ve gotta say, it’s kinda hard looking for beginner problem discussion on Clojure. Whereas in other language you’d find it on top 5-6 results in your search engine.

dharrigan11:11:56

Oh people here on Slack are 99.9999% friendly, so I hope you'll discover answers to any other issues you may encounter 🙂

hawari11:11:32

Yeah, but searching a problem on Slack isn’t as straightforward as it is on Google, haha

hawari11:11:38

I’ve been on this forum actually, more than a year ago when I started to learn Clojure, but after not getting enough traction in my workplace I didn’t pursue it any longer.

dharrigan11:11:22

welcome back!

hawari11:11:34

Now, I’m going to give Clojure another chance, who knows, maybe after a year I’ve matured enough and Clojure might seems more familiar this time.

hawari11:11:13

I gotta say, I was a total noob back then when I was starting Clojure, everything seems like some sorts of incantation, lol

dharrigan13:11:13

btw, I've just pushed up a new repo

dharrigan13:11:06

which uses the new JUXT Clip library rather than integrant. I've actually moved my stuff over to Clip as it's less intrusive/demanding than Integrant.

dharrigan13:11:11

super simples

dharrigan13:11:36

You may want to consider that library if you're investigating IoC stuff.

hawari14:11:38

Thanks for letting me know, I’ll definitely check it out

ldolberg13:11:14

A beginner question, I'm using cljs for first time. I used in the past clj-http

ldolberg13:11:42

in cljs, cljs-http return a chanel when doing an http get

ldolberg13:11:44

so I would like to have the body of the response in a sequence (is a json)

ldolberg13:11:17

(into [] (map :body) (client/get "http://myapi")) returns a channel

ldolberg13:11:30

I'm so confused

ldolberg13:11:38

Is that right?

Jan K13:11:20

That doesn't look right. You need to consume the response in a core.async go block. There's an example on https://github.com/r0man/cljs-http

ldolberg13:11:28

I ll been followin the example, how could I get a sequence out of that go block

Jan K13:11:28

You're making only one request. What kind of sequence do you want?

ldolberg14:11:14

I would like to have the response of the http get in a sequence, or in an object, the http response is json.

ldolberg14:11:42

does it makes sense?

Jan K14:11:41

You might have to deserialize the json from a string, I'm not sure if cljs-http does it automatically.

(go (let [response (<! (http/get ""))]
        (do-something-with-your-response response)))

ldolberg15:11:50

What is that go block returing?

ldolberg15:11:10

(sequence (take 1) (client/get "http://example.com" {:channel (cljs.core.async/chan 1 (map :body))}))

ldolberg15:11:21

This does not seems correct, I dont understand why

ldolberg15:11:13

(go (let [response (<! (http/get "https://api.github.com/users"))] (:body response)))

ldolberg15:11:55

return this #object[cljs.core.async.impl.channels.ManyToManyChannel]

ldolberg15:11:58

what is that?

Jan K16:11:33

That is a core.async channel which you shouldn't worry about. You should use the response within the go block.

ldolberg13:11:44

Im making one request and thats it

ldolberg13:11:12

I tired this but still return a chanel

Oz15:11:33

Hi clojurians 😎 I have 2 Java files I want to use in my clojure project, The directory structure is:

myproject/src/java/somelib/Class.java
                          ./somelib/OtherClass.java
I ran lein jar and lein install and it created a jar and a pom file that refers it. I also added :java-source-paths ["src/java" "test/java"] To my project.clj file But how do I use it from clojure? Like, how to add a dependency and imports Thanks!

jumar15:11:09

You just use import or a fully qualified name. Did you check https://clojure.org/reference/java_interop ?

Oz16:11:13

Thank you! The solution was indeed (import Class) and (import someLib.OtherClass) wasn't sure why i thought it doesn't work Maybe I needed to also run lein install in the subfolder? anyways it worked afterwards.

ScArcher16:11:12

I'm trying to work through some socket examples in the Java Tutorials with Clojure - https://docs.oracle.com/javase/tutorial/networking/sockets/readingWriting.html Is there anything similar to the Java Trails, but with clojure examples that anyone is aware of? My first step is just to get something to work, but then I'd like to understand the "Clojure" way of organizing the code to push the side effects to the edges of the system.

ScArcher16:11:17

@U3L6TFEJF I really just want to have a way to read a string off the socket's InputStream and pass that to a handler, the hander would return a string that gets written back to the socket's OutputStream. I'm not going to try to implement anything complex.

schmee16:11:28

makes sense. I’m not aware of anything trail-like for this particular thing unfortunately

ScArcher17:11:06

I guess if I get it working, I can start something on github and get some folks to review it 🙂

schmee17:11:18

that probably the best way :thumbsup:

schmee16:11:02

@scott.archer anything involving Java Sockets in Clojure is going to result in some gnarly interop. The Socket APIs are some of the oldest in Java and they are written in a very imperative style, so pushing side-effects to the edges with Sockets is going to be hard work.

bartuka22:11:01

hi what is a good pattern to test asyncronous code? For example, I have a setup & teardown setup using midje that create/delete a datomic database for each bundle of facts. However, I am now testing this portion of async code that instantly returns and midje promptly deletes the databse. I would need a way to know when the async processes finished in order to call the delete-database function. Is there a good pattern to treat it?

bartuka22:11:51

I thought about sending a data through the chan to inform that it was the last one and save this into a table. In the test portion I would be "looking at" the table for the arrival of this information. Does not feel right for me, but I am inexperienced with the async world

hiredman22:11:07

the easiest way to interface core.async code with non-core.async code is using the double bang operations, <!!, >!!, alt!!

hiredman22:11:26

it is, in extremely general sense, a good idea for any bit of async code to provide some way to "wait" for it to finish. this is useful for backpressure, for clean shutdowns, and for tests

hiredman22:11:59

the most trivial example is something like (async/go ...) which returns a channel that closes when the block exits

hiredman22:11:43

so as long as you provide something like that, in your tests you can use <!! to order things around async operations

bartuka22:11:25

@hiredman it makes total sense.. this is exactly the pattern I have... a go-block processing stuff in a buffered channel

bartuka23:11:59

let me ask you, if I call this async function as a provider for a REST API call, I don't desire to make the client to wait for my response. however, I don't know if this could be problematic as many clients start to consume my service.. something like too many threads opened for example. Do you see problems around it?

hiredman23:11:30

you won't get too many threads, but you will get an accumulation of go blocks to run in the core.async threadpool, which can cause you to run out of memory given enough of them (it would likely have to be a ton)

bartuka23:11:56

I was curious about the backpressure bit of this situation because each call to the API would span a new channel, right? And each channel would manage its own 'queue'

hiredman23:11:05

the channels don't matter

hiredman23:11:36

the way to do backpressure is determine some limit on the number of concurrent operations you want to allow, and return an error to clients when that limit is hit, maybe returning a 503 for http

nmkip23:11:48

Hi, I don't understand why I can do (Integer/parseInt "5")and (map #(Integer/parseInt %) ["5"]) but I can't do (map Integer/parseInt ["5"])

bfabry23:11:58

because (Integer/parseInt X) is java interop. Integer/parseInt is not a clojure function

ghadi23:11:12

Java static methods cannot automatically be turned into Clojure functions

nmkip23:11:25

Thanks 😄

💯 4
ghadi23:11:02

#(Integer/parseInt %) <-- a Clojure function that calls the static method inside