Fork me on GitHub
#beginners
<
2021-05-09
>
grazfather13:05:56

Is there an idiom for this sort of thing?

(if expr (cons expr rexprs) '())
Basically I am looping and do a first/rest, but in some cases I want the whole list again, if i just cons the first and rest i can get a list with a list in it if the first was already empty

Alex Miller (Clojure team)14:05:18

You can use fnil to patch the nil case

grazfather16:05:45

but I don’t want cons called at all if expr is nil

grazfather13:05:21

(defn env-new
  ([] (env-new nil))
  ([outer] (env-new outer [] []))
  ([outer binds exprs]
   (let [env (atom {:outer outer :data {}})]
     ;; (mapv #(env-set! %1 %2 env) binds exprs)
     (loop [bind (first binds)
            rbinds (rest binds)
            expr (first exprs)
            rexprs (rest exprs)]
       (when bind
         (if (= bind (symbol "&")) ;; Variadic arg
           (env-set! (first rbinds) (if expr (cons expr rexprs) '()) env)
           (do
             (env-set! bind expr env)
             (recur (first rbinds) (rest rbinds) (first rexprs) (rest rexprs))))))
     env)))
Here’s the whole thing

yuhan13:05:09

do you have the deinition of env-set! and some sample invocation of this function?

yuhan13:05:25

I suspect it could be written in a more idiomatic way without use of atoms

grazfather14:05:51

I need the atom, I am actually writing a lisp in clojure, so what this does is it implements let and other ways to add bindings to the environment. What I am doing here is I am supporting variatic bindings.

yuhan15:05:51

yeah, but it looks like env in this case is local to the function and could be written as a loop binding

grazfather16:05:11

it’s not, we return it

Dave Suico14:05:02

Hi guys, I have 2.7k rows of csv data and I have function for reading and inserting rows into the database. The reading is fast but the jdbc/insert-multi! takes so long. The postgress database is in Ireland and I'm from Philippines, and now my client expects it to be able to insert those rows in less than a minute. Is there a better implementation for this to make the inserts fast?

Noah Bogart14:05:49

Maybe ask in #sql?

❤️ 3
piyer15:05:23

run it in parallel?

mario-star 3
piyer15:05:01

use core.async

jkrasnay16:05:50

Make sure you’re using the right form of insert-multi!. From the http://clojure-doc.org/articles/ecosystem/java_jdbc/home.html : > If you wish to insert multiple rows (in hash map form) at once, you can use insert-multi!; however, insert-multi! will write a separate insertion statement for each row, so it is suggested you use the column-based form of insert-multi! over the row-based form. Passing multiple column values to insert-multi! will generate a single batched insertion statement and yield better performance.

👍 7
GGfpc19:05:05

hello! I'm pretty new to core.async and I'm trying to build the following program. I have a list of tv channels and for each of these channels I will make an HTTP call that will return the programming for that channel. Then I want to make an HTTP call to another endpoint for each of the programs. Right now I'm mapping over all of the channels and making the request with http-kit and in the callback function I push the result to a core.async channel. Then I have a go-loop that listens from the channel and maps the programs in the response into another set of http calls that publish to a second channel in the callback method. Then I have another go-loop that listens from the second channel and compiles the results. The problem I find with this is that it seems like the logic flow is not much different from callbacks inside callbacks, which is something core.async is supposed to avoid. Can you guys give me some insight on what is the proper way to do this?

phronmophobic19:05:04

If you have some code, you can try posting in #code-reviews. From a design perspective, I would recommend working the problem with pencil and paper or on white board using whatever notation, pictures, or diagrams that feel natural. Basically, try to clarify how you think about the problem and then figure out how to best represent how you think about the problem in code.

phronmophobic20:05:36

From your description, each channel requires 2 http calls to gather the required information. I would try combining both steps into one:

(defn get-tv-info [tv-channel]
  (go
     (let [some-info (<! (http-call1 tv-channel))
           more-info (<! (http-call2 tv-channel some-info))
           all-info (merge-info some-info more-info)]
        all-info))
Then you can use pipeline or pipeline-async to retrieve the channel info for each tv channel.

GGfpc20:05:22

Thanks! Your option seems interesting, but it seems like it blocks to wait for some-info and more-info to be finished before merging right?

phronmophobic20:05:26

I don't see how you could merge some-info and more-info without waiting until you have some-info and more-info. right?

phronmophobic20:05:48

And that's per tv-channel, so it wouldn't prevent having multiple tv-channel lookups happening at the same time.

GGfpc20:05:58

Oh I see, I was misreading your code. And in this case would http-call 1 and 2 run in parallel?

phronmophobic20:05:59

not the way it's currently written. I couldn't tell if making the 2nd http call required information from the 1st http call.

phronmophobic20:05:28

It would be an easy change to have them run in parallel if the two http calls are independent

seancorfield20:05:29

It takes a while to get your head around transducers but I find it amazing how much we use them at work these days: they're very powerful and can be much more efficient than combining multiple lazy sequence operations.

👆 3
3