Fork me on GitHub
#beginners
<
2018-10-28
>
alex00:10:48

@jesse.wertheim aha! that makes sense. thanks!

Michael Fiano01:10:32

Hello. I have this snippet:

(let [blocks (repeatedly #(parse-block file))]
  (->> blocks
       (take-while (complement :header/last?))
       vec))
That repeatedly calls a function which returns a map and produces a vector of maps until some key in the returned map is logical true. My question is what would be an idiomatic way to extend this, such that the resulting vector also includes the last item - the one where the key's value was true, but no more after that?

Michael Fiano02:10:37

Thanks, although I was looking for a way to do it with Clojure 1.9.0

mfikes03:10:02

Yeah, you could copy the fn from the patch and use it

(defn take-until [pred coll]
  (lazy-seq
    (when-let [s (seq coll)]
      (if (pred (first s))
        (cons (first s) nil)
        (cons (first s) 
          (take-until pred 
            (rest s)))))))

jaawerth04:10:36

@mfiano since it's eager you could also just do (reduce #(if (:name %2) (reduced (conj %1 %2)) (conj %1 %2)) [] blocks)

jaawerth05:10:55

I like the take-until idea better but I would probably use the full definition so you can do (into [] (take-until :name) blocks) instead of making a lazy-sec to turn into a vec

kingjuliyen09:10:33

what are some good source code for beginners of clojure to read and understand clojure programming idioms?

borkdude15:10:41

@kingjuliyen often those of weavejester are mentioned

borkdude15:10:21

You can also go through solutions of Advent of Code by bhauman or mfikes

kingjuliyen16:10:58

Thanks borkdude

Michael Fiano17:10:22

What is a nice way to filter a vector of maps, such that a specific key of each map can only one of a predefined set of values, removing the maps that have different values?

mfikes17:10:53

@mfiano

cljs.user=> (filter
       #_=>  (comp #{:allowed-1 :allowed-2} :my-key)
       #_=>  [{:a 1}
       #_=>   {:my-key :allowed-1 :other-key 2}
       #_=>   {:my-key :not-allowed :other-key 3}])
({:my-key :allowed-1, :other-key 2})

mfikes17:10:06

There is also a filterv that has interesting behavior and perf for this case.

Michael Fiano17:10:34

@mfikes Thank you. That is very nice

mfikes17:10:55

Just be careful if the set of values allowed includes nil or false, in which case the above wouldn't be sufficient.

Michael Fiano17:10:50

Nope, always keywords. I see how that wouldn't work though. Thanks for the tips!

kaffein19:10:57

Hi people, I am playing around with the ‘apply’ function but there is a behaviour I do not quite understand. In the following snippet, why is the last format specifier %s truncating the word ?

lilactown20:10:37

@kaffein it’s because apply expects a sequence as the last argument

👍 4
lilactown20:10:24

typically you would use it like this: (apply + [1 2 3]) which outputs 6

noisesmith20:10:01

all the args before the last can be provided normally though

noisesmith20:10:29

user=> (apply format "dear %s, thanks a lot for sending me the %s" "Tom" "Gift" [])
"dear Tom, thanks a lot for sending me the Gift"

👍 4
noisesmith20:10:55

there's not much reason to use apply in a situation like that

noisesmith20:10:49

but this does come up:

user=> ,(apply + 1 [2 3])
6

lilactown20:10:14

the reason it got weird in your example is it turns out strings are also sequences 😉 so in your example it passes in each character, G in to format like:

(format "dear %s, thanks a lot for sending me the %s" "Tom" "G" "i" "f" "t")

kaffein20:10:36

thanks for the explanation guys!!! I should have #rtfm-ed 🙂

zlrth21:10:13

idle question: could try be implemented as a macro?

zlrth21:10:45

it's a special form, defined (i think) here: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L2163 i like reading clojure's source, but i i can't read java very well

hiredman21:10:11

a macro has to expand to something, and there is nothing else it could expand in to

zlrth21:10:51

thanks--could you explain a little bit more? or point me to a link : )

hiredman21:10:21

a link to what?

hiredman21:10:00

there is no other form in clojure that handles exceptions, so if you removed try and tried to write a macro that does what try does, there is nothing for it to expand to

zlrth21:10:01

things clojure's macros can't do (for example)

hiredman21:10:24

a macro is a transformation over sytnax

hiredman21:10:08

so a try macro would have to take a form like (try ... (catch ...) (finally ...)) and transform it in to some other sytnax

hiredman21:10:16

and there is none

hiredman21:10:35

like when is a macro, it transforms (when X Y) in to (if X Y) (technically a little more complicated because when introduces a do, but whatever)

zlrth21:10:29

ok thanks. as regards handling exceptions as the JVM throws them--agreed. can a clojure macro try to eval an expression, and if that expression bubbles up an error value of some sort, short-circuit the evaluation of that expression, and eval a (also a macro) catch expression?

noisesmith21:10:01

a macro can contain a try/catch

zlrth21:10:56

yeah! that's part of why i'm posting here. i was looking at try-let and try+, and saw that they're wrappers around try

noisesmith21:10:19

that's different, that's generating a try/catch as the result of the macro

noisesmith21:10:29

macros take a source form and return a replacement source form

zlrth21:10:36

oh interesting. so a-macro-containing-a-try-catch is a compile-time try catch?

hiredman21:10:45

macros are just functions that take syntax and return syntax, so anything you can do in any other clojure function you can do in a macro