Fork me on GitHub
#clojure
<
2020-11-02
>
fullNameHere02:11:57

Hey guys, I got two questions first would be, what would be a better way of writing this?? (into {} (map (fn [x] (hash-map x (hash-map "booked?" (random-boolean) "nameOfEvent" "nothingBookedYet"))) (get-next-4-weeks-dates))) it would get assigned to a def and returns something like {2020-11-07 {nameOfEvent nothingBookedYet, booked? true} 2020-12-07 {nameOfEvent nothingBookedYet, booked? false} ... } (get-next-4-weeks-dates) returns vector of dates as strings ex ["2020-11-01" ...] second, is how could I filter all trues so that it returns all trues with date aswell 11/01/20 {nameOfEvent nothingBookedYet booked? true}

phronmophobic03:11:03

maybe something like:

(defn get-next-4-weeks-dates []
  ["2020-11-01" "2020-11-07"  "2020-11-14" "2020-11-21" ])

(def date->event
  (into {}
        (map (fn [dt]
               {dt {"booked?" (rand-nth [true false])
                   "nameOfEvent" "nothingBookedYet"}}))
        (get-next-4-weeks-dates)))

(def booked-events
  (filter (fn [[dt {:strs [booked?]}]]
            booked?)
          date->event))

fullNameHere03:11:38

Thank you, ill give that a shot

didibus05:11:20

You can use reduce instead:

(reduce
  (fn[acc e]
    (assoc acc e
               {:booked? (random-boolean)
                :name-of-event :nothing-booked-yet}))
    {}
  (get-next-4-weeks-dates))

didibus05:11:53

Or just using map literals instead of hash-map already reads a lot better:

(->> (get-next-4-weeks-dates)
     (map
       (fn[x]
         {x {:booked? true
             :name-of-event :nothing-booked-yet}}))
     (into {}))

fullNameHere07:11:37

I havent uaed a macro before, ill check it out.

dominicm12:11:11

I'd reach for zipmap:

(zipmap (get-next...) (repeatedly (fn [] {:booked ...})))
(On mobile, so abbreviated)

fullNameHere16:11:45

Ill try zipmap aswell, thank you

didibus22:11:31

Macro? Oh you mean ->>?

didibus22:11:09

With the reduce way, you can even just skip doing the assoc when random-boolean isn't true, so it can filter and create the map on one go.

fullNameHere23:11:41

Is ->> not a macro? Eventually a user will select a date and flip booked to opposite boolean. I appreciate the different approach though.

didibus03:11:44

It is, but, you've definitly been using macros without realizing, things like if, or, and, defn and more are all macros as well

didibus03:11:17

You might just not have been defining your own macros yet

fullNameHere15:11:12

I just haven't really looked into it. Last time I did the syntax and how it worked looked advanced so I backed off.

didibus17:11:44

Ya fair enough, it is a little more advanced, I remember I took a bit of time before learning to use it as well when I started

👍 3
valerauko09:11:52

Could someone please point me to where Clojure's memory model is implemented? The part where differences are branched off

andy.fingerhut13:11:17

Do you mean where path copying is implemented for collections that you are updating, so that they return a new collection instead of modifying the one they are given?

andy.fingerhut13:11:34

If you mean something else, it is not clear from your question

alexmiller14:11:04

Clojure's memory model is Java's memory model since it runs on the jvm

valerauko14:11:44

I mean the path copying as you say

alexmiller14:11:46

based on Bagwell's HAMT http://infoscience.epfl.ch/record/64398/files/idealhashtrees.pdf (with some mods for performance)

valerauko05:11:45

> Any errors are my own i love this comment

suren10:11:27

I am trying to deploy a package in clojars . I am getting following error

java.lang.IllegalArgumentException: Must provide valid :files to deploy-artifacts
Can anyone help me with this?

dharrigan10:11:57

@suren try asking in the #clojars channel. Someone may be able to help there. 🙂

mafcocinco15:11:12

Is there currently a “best” Clojure SFTP client library? “Best” is kind of squishy but something that is relatively well maintained and provides good examples. I was thinking https://github.com/clj-commons/clj-ssh but its tests are currently failing and it is somewhat lacking in examples (was looking specifically for a put example from an in-memory file).

manutter5115:11:19

We’re suddenly having production issues with org.httpkit.client throwing java.lang.IllegalStateException: Client/Server mode has not yet been set whenever we try to connect to one of our other servers over https. The only thing that’s changed since last Friday when everything was fine is that Daylight Savings Time ended over the weekend. Java version is 1.8 (and not Java 11, which seems to have had a lot of issues with this). It’s a long shot, but has anyone else ever seen a problem like this?

mafcocinco15:11:34

Thanks! The documentation implies that it is FTP only. Does it work with SFTP connection?

borkdude15:11:53

yes, it does

mafcocinco15:11:09

awesome, thanks!

borkdude15:11:11

I even made a little PR related to that, to that lib

dpsutton16:11:23

take-while as a transducer "takes while" the input satisfies some predicate. easy enough to write but is there a transducer that "takes while" the accumulated value satisfies some predicate?

dpsutton16:11:21

(defn foo [rf finish?]
  (fn
    ([] (rf))
    ([result] (rf result))
    ([result input] (let [result' (rf result input)]
                      (if (finish? result')
                        (reduced result')
                        result')))))

dpsutton16:11:16

built-in or possibly in cgrande's lib?

hiredman19:11:08

it isn't really safe for transducers to make assumptions about result

dpsutton19:11:32

do you know of a concrete example that can help clarify for me?

phronmophobic19:11:52

@dpsutton, why not just use the built in take-while ?

(defn take-while
  "Returns a lazy sequence of successive items from coll while
  (pred item) returns logical true. pred must be free of side-effects.
  Returns a transducer when no collection is provided."
  {:added "1.0"
   :static true}
  ([pred]
     (fn [rf]
       (fn
         ([] (rf))
         ([result] (rf result))
         ([result input]
            (if (pred input)
              (rf result input)
              (reduced result))))))
  ([pred coll]
   (lazy-seq
    (when-let [s (seq coll)]
      (when (pred (first s))
        (cons (first s) (take-while pred (rest s))))))))

Jan K19:11:03

I agree with hiredman, this is something out of scope for an individual transducer (imagine if it's attached to a channel, what's the accumulator value?). But I guess you could use clojure.core/reductions and wrap the reducing function manually with some transducers if needed, and then take-while the resulting sequence.

hiredman19:11:08

transduce calls (f) before applying the xform to f, so you cannot assume result is the value returned by your step fn's init arity

dpsutton19:11:58

@smith.adriane because no inputs are bad. its when i've taken "enough" inputs that i can stop

dpsutton19:11:10

something like (reduce (reduce-until + #(> % 100)) (range 300))

phronmophobic19:11:53

the accumulator could be anything. it seems like you may want to write your own transducible process if you want to make assumptions about the accumulator value

dpsutton19:11:39

i don't follow. using a reducing function assumes i know something about the accumulator shape.

dpsutton19:11:19

(fn [acc input] ...) if acc is completely opaque then i could never reduce anything

phronmophobic19:11:13

the transducer (map f) can work when the accumulator is a core/async channel, a clojure sequence, a socket connection, standard out, outputstream, and many other accumulator types. not sure how your take-while would work with all those examples

hiredman19:11:04

(defn part [n]
  (fn [retf]
    (fn
      ([] {:value (retf)
           :part []})
      ([{:keys [value part]}]
       (if (seq part)
         (retf (retf value part))
         (retf value)))
      ([{:keys [value part]} item]
       (let [new-part (conj part item)]
         (if (= (count new-part) n)
           {:value (retf value new-part) :part []}
           {:value value :part new-part}))))))
#'user/part
user=>
user=> (let [f ((part 2) conj)] (f (reduce f (f) (range 10))))
[[0 1] [2 3] [4 5] [6 7] [8 9]]
user=> (transduce (part 2) conj (range 10))
([8 9] [6 7] [4 5] [2 3] (1 0))
user=> (into [] (part 2) (range 10))
Execution error (NullPointerException) at user/part$fn$fn (REPL:13).
Cannot invoke "clojure.lang.ITransientCollection.conj(Object)" because "coll" is null
user=>

hiredman19:11:53

part there is a kind of naive purely functional transducer that wraps the input result to keep a buffer, and unwraps it at the end

hiredman19:11:04

and if you sort of manually do the things when you use it with reduce, it works, but in a "real" usage with a function that takes a transducer it doesn't

hiredman19:11:31

it almost sort of works in that example with transduce, but will completely fall apart with different types and reducing functions

hiredman20:11:59

result is opaque, the only operation you can safely do on it is call rf

dpsutton20:11:09

thanks everyone

hiredman20:11:39

if you need to keep a count then you need to keep it in an atom closed over by your reducing function, similar to how the stateful transducers work