Fork me on GitHub
#beginners
<
2018-09-17
>
Conor08:09:07

If any of you happen to be in Manchester, UK, we're running a beginner Clojure workshop this evening (with free pizza/booze): https://www.eventbrite.com/e/lambdalounge-clojure-workshop-tickets-49803651061

Lutz09:09:21

How do I extract the day of an instant?

schmee09:09:27

an instant doesn’t have a day, you need to convert it to a LocalDateTime or ZonedDateTime in the appropriate zone and then get the day from that

mfikes11:09:32

Also, an instant could really be any value that satisfies inst?, so one approach would be to inst-ms and then use some means to convert that value to a day.

schmee13:09:31

why delete the original message though?

mfikes15:09:22

Because it was only an inst, ephemeral

Lutz06:09:15

Sorry, that was a mistake

joaohgomes11:09:49

People learn from mistakes. There is nothing in it to be ashamed of. 😀

g14:09:36

hey folks, trying to get started with some java interop

g14:09:09

i keep running into a ‘no matching constructor found’ issue when trying to instantiate a new object. as far as i can tell i’ve imported the core library correctly

g14:09:19

any ideas?

mbjarland14:09:46

assume I have a seq (list of vector) of strings, what would be a concise way of creating an english language list string of them, e.g. elem1, elem2, and elem3? I know cl-format can do this but lets for the sake of argument assume I want to accomplish this without cl-format. I.e. the goal is to have commas in between except for the last one which should have either , and or just and

deliciousowl15:09:11

(defn english-list [coll]
  (let [j clojure.string/join]
    (j [(j ", " (drop-last coll)) ", and " (last coll)])))

mfikes15:09:31

nice!

🙂 4
dpsutton15:09:56

@gtzogana java allows overloading on type. for instance if new Foo(3) and new Foo("baz") are both constructors, if you try (Foo. 3) it might throw an error saying there is no Foo (Object) method. Can you read the error message for which constructor it is trying to find? Possibly a typehint might work. (Foo. ^long 3)

g15:09:31

unfortunately all i get is CompilerException java.lang.IllegalArgumentException: No matching ctor found.. not particularly illuminating for me

mfikes15:09:43

@mbjarland That's a nice problem. This can do it, but it produces an odd result if the sequence is of length 2

(defn english-list [coll]
  (-> coll
    reverse
    (interleave (cons ", and " (repeat ", ")))
    reverse
    rest
    clojure.string/join))

mbjarland15:09:41

@mfikes :thinking_face: thanks, I’ll mull that over for a bit. I was going with interpose and then replacing the last comma with an and…but I don’t like how it looks

mfikes15:09:54

Yeah, something based on interpose would be nice

justinlee15:09:14

for bonus points, add an option whether or not to include the oxford comma :))

mbjarland15:09:43

@mfikes the “replacing the last comma with an and” turned ugly (or rather I could not cook up anything pretty), you have to handle special cases like the list only containing one item etc

deliciousowl15:09:55

(defn english-list [coll oxford] (if (= (count coll) 1) (apply str coll) (let [j clojure.string/join] (j [(j ", " (drop-last coll)) (when oxford ",") " and " (last coll)]))))

4
8
deliciousowl15:09:32

ill be waiting for those bonus points

Imad15:09:34

(defn english-list [data] (str (str/join "," (butlast data)) " and " (last data)))

mbjarland15:09:46

I guess if you don’t want to use join you could replace the innermost j with interpose and the outer one with (apply str?

mbjarland15:09:32

@imad would that not need to be (apply str...? I’m probably missing the point

deliciousowl15:09:47

(apply str instead of the first j works yeah

mfikes15:09:48

Maybe something based on assoc? Partial soln:

(defn english-list [coll]
  (let [v (vec (interpose ", " coll))]
    (assoc v (- (count v) 2) ", and")))

mbjarland15:09:09

@coinedtalk would that not fail for one item lists?

mbjarland15:09:40

same for @mfikes above I think assoc outside of vec

john15:09:42

I revoke my bonus point

mbjarland15:09:51

well I guess I didn’t explicitly state that so incomplete problem description, but yes, it should also work for one item lists

john15:09:51

Bonus point challenge reversed. The play is good.

mbjarland15:09:01

@mfikes that’s pretty much what I was going with and then I ended up with (if handling for the one item case

mbjarland15:09:24

was hoping for some brilliant stroke of genius piece of code without special cases

mfikes15:09:40

If you go with assoc you can also work the transducer variant of interpose in the mix and probably end up with a wicked fast solution for vector inputs.

mbjarland16:09:41

like I said above, this is possible with cl-format:

(clojure.pprint/cl-format nil "~{~a~#[~;, and ~:;, ~]~}" ["alice" "why" "is"])
=> "alice, why, and is"
but I was hoping there was a non-cl-format way

mbjarland16:09:46

in fact it seems that for this to work properly for 2 element lists you need to go neanderthal with the cl-format format string:

(clojure.pprint/cl-format 
 nil 
 "~{~#[~;~a~;~a and ~a~:;~@{~a~#[~;, and ~:;, ~]~}~]~}" 
 ["alice" "why"])
=> "alice and why"

mfikes16:09:02

That's cool. Many ClojureScript devs will avoid clojure.pprint owing to its effect on code size. But, cl-format is curiously strong, leading to nice compact solutions.

mbjarland16:09:55

I would agree to compact…not sure about nice : )

mbjarland16:09:31

we are essentially asking the reader to learn a whole new language, the cl-format “format string language”

mbjarland16:09:52

which is, it could be argued, not the most readable

mfikes16:09:46

Right, write only 🙂

mbjarland16:09:29

cl-format seems to have some serious pedigree, from what I can glean the code has more or less been around and transplanted into the following languages / envrionments: BOS -> multics -> lisp machine lisp -> common lisp -> clojure

mbjarland16:09:00

so some time in the 70s would be a guess

schmee16:09:17

whoa, that cl-format snippet above is a new level of write only 😄

mbjarland16:09:24

for an explanation search for the format string at: http://www.gigamonkeys.com/book/a-few-format-recipes.html

mbjarland16:09:03

but yes, even with the explanation this is still write only

mbjarland16:09:03

indeed, ergo the wish for something a little less obfuscated : )

mbjarland16:09:40

well since we are gorging on write-only code, the following does word wrap using cl-format:

(defn wrap-line [size text]
  (clojure.pprint/cl-format nil (str "~{~<~%~1," size ":;~A~> ~}") (clojure.string/split text #" ")))

deliciousowl16:09:52

(defn english-list [args]
  (let [pa (fn ([] args)
              ([word & rests] [word ", " (last rests)]))]
   (clojure.string/join "" 
     (flatten 
      (take (dec (* (count args) 2))
        [(reduce pa (butlast args)) ", and " (last args)])))))
look at this monstrosity

4
mbjarland17:09:48

an attempt:

(defn english-list [args]
  (condp = (count args)
    0 ""
    1 (first args)
    2 (str (first args) " and " (last args))
    (let [xs (interpose ", " args)]
      (apply str (flatten [(butlast xs) "and " (last xs)])))))

deliciousowl17:09:18

I wanted to make one using map and cycle

noisesmith17:09:05

why not (concat (butlast xs) [" and " (last xs)]) - flatten actually works here but has so many gotchas

noisesmith17:09:58

like performing very slowly, and turning general code into special case code that breaks with collection inputs

deliciousowl17:09:21

And it might split up a string into chars

noisesmith17:09:30

(of course you only get strings here, so the collection input case which is the real gotcha, doesn't apply)

noisesmith17:09:38

flatten does ignore strings

mbjarland17:09:45

@noisesmith duly noted, result:

(defn english-list [args]
  (condp = (count args)
    0 ""
    1 (first args)
    2 (str (first args) " and " (last args))
    (let [xs (interpose ", " args)]
      (apply str (concat (butlast xs) ["and " (last xs)])))))
(english-list ["alice" "bob" "mary"])
=> "alice, bob, and mary"

👍 4
mbjarland17:09:46

hrm…quite verbose that, could be you can do this with a reduce and some state

noisesmith17:09:27

reduce would be weird, as it can't peek forward

noisesmith17:09:06

(so you end up making a cache of values to simulate a forward peek, and a loop would be simpler than that)

dangercoder18:09:28

Has anyone gotten Ring Session to work with luminous? I've only seen examples where they use flash sessions.

mfikes19:09:06

@mbjarland It is now just a short step from your last version to a transducer / vector based version that runs twice as as fast in ClojureScript and thrice in Clojure

(defn english-list [args]
  (case (count args)
    0 ""
    1 (first args)
    2 (str (first args) " and " (last args))
    (let [xs (into [] (interpose ", ") args)]
      (clojure.string/join (into (pop xs) ["and " (peek xs)])))))

mfikes19:09:44

- case does a constant-time dispatch - (interpose ", ") is a transducer and if args is a vector, then things can be directly reduced via into (no intermediate sequence) - pop and peek are faster - I think clojure.string/join is faster under ClojureScript

mfikes19:09:09

No need to do this sort of stuff, but if you're interested in it...

Caio Guedes19:09:51

Guys, do you have some article or kind of exercices about core.async? I’m in trouble with that, I couldn’t understand it yet (I came from a world without threads)

hiredman19:09:52

java concurrency in practice is pretty good

mfikes19:09:39

Nobody has written a book on core.async right?

mfikes19:09:16

Maybe Alex's book has a chapter in it. Can't recall.

Caio Guedes19:09:09

Oh, I’ll look it

mfikes19:09:30

Yeah, there's about 5 pages dedicated to core.async in Clojure Applied

👍 4
jaawerth19:09:29

looks like Brave has a chapter on it https://www.braveclojure.com/core-async/

👍 8
borkdude20:09:29

@caio.cesar.g.souza there are a couple of videos here on core.async: https://cognitect.com/videos.html

❤️ 4
Caio Guedes11:09:45

Oh my god! Thanks so much!

Yehonathan Sharvit21:09:58

I just published a short beginner-friendly blog post that introduces the Clojure CLI tool: http://blog.klipse.tech/clojure/2018/09/16/hello-clojure.html

👍 8
john01:09:05

Great intro!

Yehonathan Sharvit04:09:46

Thanks @UAX2MK4PP Were you already familiar with the CLI tools?