Fork me on GitHub
#clojure
<
2019-01-10
>
mhcat00:01:42

that sounds like a rabbithole

fabrao01:01:31

Hello all, I´ve got this from result #object[java.util.Optional 0x5c2aa319 Optional[2019-01-09T23:01-02:00[America/Sao_Paulo]]], what is that?

fabrao01:01:06

is that any way to convert to ZonedDateTime?

noisesmith01:01:25

in general, if you get an object that isn't familiar (especially a java.* object) the javadoc is going to be your best bet

noisesmith01:01:46

you might also want to use one of the methods there to do some default action of it's empty, rather than throwing an exception as get will

fabrao01:01:41

oh, I got it, thanks

fabrao01:01:10

.get did the job

noisesmith01:01:39

some examples of playing with it in a repl:

(ins)user=> (java.util.Optional/of 1)
#object[java.util.Optional 0x319bc845 "Optional[1]"]
(ins)user=> (.get *1)
1
(ins)user=> (java.util.Optional/of nil)
NullPointerException   java.util.Objects.requireNonNull (Objects.java:203)
(ins)user=> (java.util.Optional/ofNullable nil)
#object[java.util.Optional 0xe84a8e1 "Optional.empty"]
(cmd)user=> (.get *1)
NoSuchElementException No value present  java.util.Optional.get (Optional.java:135)

noisesmith01:01:52

using a default value instead of throwing:

cmd)user=> (java.util.Optional/ofNullable nil)
#object[java.util.Optional 0xe84a8e1 "Optional.empty"]
(ins)user=> (.orElse *1 0)
0
(ins)user=> (java.util.Optional/of 1)
#object[java.util.Optional 0x23d1e5d0 "Optional[1]"]
(cmd)user=> (.orElse *1 0)
1

jeroenvandijk13:01:25

I see an exotic regression between clojure 1.8 and newer versions. From 1.9 onwards this is now invalidated by clojure spec

(let [f (fn [] "hi")]
  (eval `(defn foo [] (~f))))
In older versions this was possible

jeroenvandijk13:01:08

Is this a bug or a feature? 🙂

bronsa13:01:45

the problem has got nothing to do with the fn

bronsa13:01:55

your foo is namespace qualified

bronsa13:01:00

should be (defn ~'foo

bronsa13:01:19

and the fact that it's rejected by spec now is indeed a feature

jeroenvandijk13:01:00

Thanks, sorry for the noise

eboersma16:01:19

Is there a channel on the slack for telling people that hey, I just published a library on Clojars in case anyone is looking for something similar?

taylor16:01:22

#announcements

👍 5
borkdude16:01:18

is there a way to fully qualify symbols in a data structure that’s not a literal? e.g.:

(qualify (clojure.edn/read-string  "{str #{:clj :cljs}}" ))

bronsa16:01:54

what is the result you want out of that?

borkdude16:01:05

{clojure.core/str ....}

bronsa16:01:16

you can use clojure.tools.reader/syntax-quote

bronsa16:01:04

although you probably want the function equivalent

ghadi16:01:04

explicate is a great word @alexmiller

5
bronsa16:01:04

that won't respect quoting

bronsa16:01:13

but if you don't care it's fine

bronsa16:01:25

if you're using edn you probably don't anyway

borkdude16:01:32

yeah, I’m reading from EDN

borkdude16:01:50

full example for those interested:

(defn- explicate-1 [a-ns form]
  (walk/postwalk
   #(cond
      (keyword? %) %
      (symbol? %) (or (->> % (ns-resolve a-ns) symbol) %)
      :else %)
   form))

(comment
  (explicate-1 'clojure.core (clojure.edn/read-string "{str #{:clj :cljs}}"))
  ;; => #:clojure.core{str #{:clj :cljs}}
  )

paulspencerwilliams19:01:41

Hey all, can anyone suggest how I can twist clj-http's arm into sending such as request

curl -i -XPOST -H "Content-Type:application/octet-stream" -H "Authorization: Bearer blah" --data-binary "@/Users/me/Downloads/an-image.png" 
I've tried
{:body         (IOUtils/toByteArray (io/input-stream "Users/me/Downloads/an-image.png")
but get a 404 from the server

hiredman19:01:33

and what was the rest of your clj-http call?

noisesmith19:01:46

are you sure you're hitting the right endpoint with the right http method?

noisesmith19:01:16

also I'd be surprised if clj-http couldn't just use an input-stream directly

hiredman19:01:25

404 seems unlikely to be the result of the body content

paulspencerwilliams19:01:41

Yeah, I believe so, I've tried the same ensuring same url with IntelliJ's http client without specifying the actual binary data, and again receive a 404, so I believe that's the servers behaviour.

paulspencerwilliams19:01:53

Full request coming after I've stripped secrets 😉

noisesmith19:01:20

are you sure you're doing a POST?

paulspencerwilliams19:01:46

(->> (client/post
       (str
         ""
         (System/getenv "CONTENTFUL_SPACE_ID")
         "/uploads")
       {:body         (IOUtils/toByteArray (io/input-stream "/Users/will/Downloads/BP TUM Pictures PNG/TUM1 001K.png"))
        :headers      {"Authorization"             (str "Bearer " (System/getenv "CONTENTFUL_MANAGEMENT_KEY"))}
        :content-type "application/octet-stream"}))

paulspencerwilliams19:01:55

Yeah, definitely a post.

wilkerlucio19:01:30

@paulspencerwilliams did you tried using the input-stream directly? (remove the IOUtils/toByteArray)

isak19:01:31

@paulspencerwilliams you might need a .trim on the thing you get from getenv, i've had that problem before

paulspencerwilliams19:01:37

(->> (client/post
       (str
         ""
         (System/getenv "CONTENTFUL_SPACE_ID")
         "/uploads")
       {:body         (io/input-stream "/Users/will/Downloads/BPTUMPicturesPNG/TUM1001K.png")
        :headers      {"Authorization"             (str "Bearer " (System/getenv "CONTENTFUL_MANAGEMENT_KEY"))}
        :content-type "application/octet-stream"}))

paulspencerwilliams19:01:05

Input-stream seems okay

(io/input-stream "/Users/will/Downloads/BPTUMPicturesPNG/TUM1001K.png")
=> #object[java.io.BufferedInputStream 0x36e4cf6f "java.io.BufferedInputStream@36e4cf6f"]

noisesmith19:01:35

what about directly using the string instead of creating it using getenv (for now) - or at least verifying that CONTENTFUL_SPACE_ID is space-id

paulspencerwilliams19:01:27

Um... removing the --data-binary param from curl command returns 400, not 404, so it definitely seems to be something wrong with my clojure code, and not server weird 404s when no file is uploaded :thinking_face:

john19:01:34

spaces is not in the url, while it is in the curl command?

noisesmith19:01:00

yeah -that would likely explain it

noisesmith19:01:29

unless CONTENTFUL_SPACE_ID was spaces/space-id of course

noisesmith19:01:56

this is why people hate strings

paulspencerwilliams19:01:27

Haha, yeah! that will be it! Thank you rubber ducks!

paulspencerwilliams19:01:25

It's funny when you're learning new tech, libraries, etc, how you assume failures are down to your lack of knowledge about that thing, rather than the basics!

noisesmith19:01:46

there's a clj-http-fake lib, that is useful for separating this kind of issue from server misbehavior https://github.com/myfreeweb/clj-http-fake

paulspencerwilliams19:01:05

Oh, and thanks for suggesting removing commons; it's great to remove dependencies!

john19:01:06

It never stops happening 😉

john19:01:20

(for me, at least)

paulspencerwilliams19:01:39

It certainly hasn't for me either, in my 20 years commercial programming!

adamfrey19:01:47

how does macroexpansion interact with laziness? For instance do I need a doall around the for here?

(defmacro defstyle
  [style-id & styles]
  `(defstyle* ~style-id
     ~@(for [style styles]
         (walk/postwalk (fn [node]
                          (if (map? node)
                            (prefix node)
                            node))
style))))

noisesmith19:01:00

the compiler is eager, so you shouldn't need doall

adamfrey19:01:13

great, thanks!

noisesmith19:01:26

this all depends on what defstyle* does of course - some forms aren't eager of consuming their arguments...

noisesmith19:01:06

but the absence or presence of doall wouldn't change this

dottedmag19:01:11

Has anyone tried to write Kafka Streams code in Clojure? I have googled a few libraries, but haven't found any reports of what works and what does not in reality.

jaide20:01:59

Dunno if this helps but this one was posted to the Clojure reddit a few weeks ago: https://www.reddit.com/r/Clojure/comments/aa12wz/ziggurat_a_stream_processing_framework_to_build/

dottedmag20:01:41

Thanks, I'll have a look.

noisesmith20:01:21

my company open sourced our kafka-streams library recently, https://github.com/FundingCircle/jackdaw

👍 5
borkdude20:01:36

interesting. I subconsciously used this as a feature in a test for months now…

user=> (str/includes? {:a 1} "1")
true

taylor20:01:23

hmm yeah it toStrings the input (.contains (.toString s) substr)

taylor20:01:50

looks like several of the clojure.string predicates do the same

ghadi20:01:28

it’s because they assume the interface CharSequence as an input, not Object AFIAK

👍 5
borkdude20:01:46

yeah, it worked accidentally. I changed the code now 😉

Alex Miller (Clojure team)21:01:16

if only that worked in real life

Alex Miller (Clojure team)21:01:28

“I put a chainsaw in my toaster and it accidentally came out as toast”

😂 5
lvh21:01:09

Instaparse question: I have an existing yacc/lex grammar; I assume the yacc one is the least strenuous to port over (there's no embedded code besides yyerror), I'd like to use this with instaparse which takes EBNFs -- any chance someone has done something like that and has a converter laying around? I feel like as soon as I'm writign a file called yacc.cfg and lex.y I have taken a wrong turn

lvh21:01:57

https://github.com/jrester/EBNF.cr claims to do this but doesn't work.

lvh21:01:28

(the endgame here is being able to parse C headerifles and automagically generating the right Clojure bindings)

hiredman22:01:08

you might try using, uh, I forget, that tool that generates jni bindings, and then relective over the java to generate the clojure

hiredman22:01:25

is that tool really just javah?

hiredman22:01:48

(it is not)

hiredman22:01:43

swig is what I am thinking of

dpsutton22:01:28

I just checked (doc eduction) and (source eduction) and their doc strings differ. I didn't think this was possible?

dpsutton22:01:39

Well the arg lists i suppose is different to be more precise

hiredman22:01:50

for example, whatever tooling you use might override doc

hiredman22:01:36

which arglists?

dpsutton22:01:50

{:arglists '([xform* coll])
   :added "1.7"}
  [& xforms]

hiredman22:01:01

and what does doc say?

dpsutton22:01:04

user> (doc eduction)
-------------------------
clojure.core/eduction
([xform* coll])

hiredman22:01:09

that matches

dpsutton22:01:28

the arg list in the source is

[& xforms]
  (Eduction. (apply comp (butlast xforms)) (last xforms)))

hiredman22:01:43

the definition includes custom metadata that overrides the arglist form

Alex Miller (Clojure team)22:01:45

the arglists meta overrides

hiredman22:01:09

:arglists '([xform* coll])

dpsutton22:01:15

ok. threw me for a loop when i went to check the source.

Alex Miller (Clojure team)22:01:24

the override is trying to convey something impossible to say in the actual arg list

Alex Miller (Clojure team)22:01:31

which is a leading vararg

dpsutton22:01:16

i see. thank you

seancorfield22:01:39

(side note: :arglists can confuse tooling that tries to use that information to check source code -- such as Eastwood -- since the :argslists metadata doesn't have to represent a valid actual call)

noprompt22:01:58

@seancorfield it can also help it. 🙂

(defmulti ^{:arglists '([a-map])} do-thing :key)

seancorfield22:01:13

Eastwood can't check defmulti calls without a hint? I didn't know that.

noprompt22:01:49

defmulti can’t attach :arglists meta to the var because there’s no general way to derive it from the dispatch-fn.

kenny22:01:21

Will calling count on a vector of lazy seqs realize the lazy seqs?

kenny22:01:48

Thought so. This result was confusing:

(let [xs [(iterate (fn [x]
                     (inc x)) 0)
          (iterate (fn [x]
                     (inc x)) 0)]]
  (map realized? xs))
=> (true true)
Guessing realized? must be talking about something else here?

noisesmith22:01:58

yeah - I wouldn't trust realized? for lazy inputs - it's reliable for delay or promise objects

5
noisesmith23:01:02

@U083D6HK9 - I had to play with this more - it seems like it kind of works but not for the head of the collection(?)

(cmd)user=> (def l (iterate println nil))
#'user/l
(cmd)user=> (realized? l)
true
(cmd)user=> (realized? (rest l))
false
(ins)user=> (realized? (nthrest l 2))
nil
false
(cmd)user=> (realized? (rest l))
true

noisesmith23:01:49

that nil after calling nthrest shows one element being realized

kenny23:01:51

Perhaps because the first element is passed explicitly to iterate?

noisesmith23:01:22

oh! I'll try another thing to test that

noisesmith23:01:29

yeah - you figured it out

(ins)user=> (def l (repeatedly #(println :realized)))
#'user/l
(ins)user=> (realized? l)
false
(cmd)user=> (realized? (rest l))
:realized
false
(cmd)user=> (realized? (rest l))
false
(cmd)user=> (realized? (nthrest l 2))
:realized
false
(cmd)user=> (realized? (rest l))
true

10
mfikes02:01:47

Yeah, the first value in a lazy sequence generated by iterate has been “produced”, and thus the sequence vacuously satisfies realized?

noisesmith22:01:50

I tested by adding println inside those function bodies - not even the first element is being produced