Fork me on GitHub
#beginners
<
2021-02-03
>
suren05:02:46

How do we interop following Java Class in Clojure?

GoogleIdTokenVerifier verifier =
    new GoogleIdTokenVerifier.Builder(new NetHttpTransport(), new JacksonFactory());
I tried following which does not work.
(. GoogleIdTokenVerifier/Builder (NetHttpTransport.) (JacksonFactory.))
From the source code here https://github.com/googleapis/google-api-java-client/blob/master/google-api-client/src/main/java/com/google/api/client/googleapis/auth/oauth2/GoogleIdTokenVerifier.java I can see Builder is a class in that file. It looks like Builder is in the namespace GoogleIdTokenVerifier .

sova-soars-the-sora05:02:24

What's your import line like ?

sova-soars-the-sora05:02:24

maybe this will help https://livebook.manning.com/book/clojure-in-action-second-edition/chapter-5/73 maybe 20% down the page... hopefully someone more experienced with interop can chime in ^.^

dpsutton05:02:30

https://clojure.org/reference/java_interop#_class_access you can see how to access nested classes here. I would try (GoogleIdTokenVerifier$Builder. (NetHttpTransport.) (JacksonFactory.))

dpsutton05:02:40

updated after reading it incorrectly

suren05:02:49

@U3ES97LAC The import statements are given below

(:import com.google.api.client.http.javanet.NetHttpTransport
           com.google.api.client.json.jackson2.JacksonFactory
           com.google.api.client.googleapis.auth.oauth2.GoogleIdTokenVerifier))

suren05:02:25

@U11BV7MTK I have tried it before but unfortunately does not work It throws following error

Caused by: java.lang.IllegalArgumentException: Unable to resolve classname: GoogleIdTokenVerifier$Builder

seancorfield05:02:10

You need to import GoogleIdTokenVerifier$Builder

seancorfield05:02:16

or use it fully-qualified

suren05:02:44

Thank you guys a lot.

seancorfield05:02:11

Nested classes in Java aren't really "nested", they're more like "siblings".

suren05:02:23

Hmm got it.

suren06:02:55

I did came across the gist. But I reckon its better to use the SDKs instead of apis.

sova-soars-the-sora05:02:35

Hmm I think you are very close...

afry14:02:24

Hello again fellow beginners! Yesterday I started my journey into learning Clojure Spec, which is a really interesting tool for making assertions about data. I don't know so much about it yet, but I've gotten my feet wet with it. In my livestream today we're going to be continuing with the "name validator" coding challenge from Eric Normand's newsletter, which seems like a great use case for Spec and a good way to learn it: https://purelyfunctional.tv/issues/purelyfunctional-tv-newsletter-412-module-depth-is-bogus/ If you'd like to watch some guy with about four weeks of Clojure under his belt bungle his way through and learn a few things along the way, feel free to join! Coding challenge should start around 9:40-ish AM EST: https://www.twitch.tv/a_fry_

Christian16:02:54

Maybe this is a stupid question, but I was wondering how much of the syntax in Clojure is set in stone.

(defn testfunc1 [a b] (+ a b))
(defn testfunc2 (vec a b) (+ a b))
The second one does not work, I thought the [a b] is just another way to say (vec ab). Is this because def is a special form?

dpsutton16:02:10

defn is a macro and expects certain literal syntax

dpsutton16:02:06

its looking for a vector which is how arguments are supplied. macros takes forms and return forms. so there's a difference between the literal [a b] and a form that will evaluate to the same form (vec a b)

andy.fingerhut16:02:09

You can write a macro that would contain an expression like (vec a b) that takes some expression as input, and constructs and returns an expression that looks like your first expression, but it would operate upon the symbols and other syntactic elements of the input expression given to the macro, not the "run-time" values of a and b.

aratare16:02:18

Hi there. I have a bit of a question regarding how to do things the "Clojure" way. So let's say I have a Java class Foo with a bunch of methods that return void like setBar or calculateBaz. Is there a way where I can do something like this:

(-> newFoo
      .setBar
      .setBar
      .calculateBaz)
and return newFoo by the end?

dpsutton16:02:31

doto is your friend here

andy.fingerhut16:02:57

I thought doto would only be your friend if you have methods that return the object they mutate?

andy.fingerhut16:02:46

Oh, never mind me. Forgetting things.

aratare16:02:47

From the clojuredoc

;; Note that even though println returns nil, doto still returns the HashMap object
(doto (java.util.HashMap.)
      (.put "a" 1)
      (.put "b" 2)
      (println))

šŸ‘ 4
dpsutton16:02:54

doto doesn't thread the object i don't believe

aratare16:02:56

So yeah it is my new friend

aratare16:02:07

Thanks a lot šŸ™‚

aratare16:02:15

Also to add another question on top of that, I've seen a utility library floating around somewhere which allows me to -> but with certain position within each form. Can anyone remember what it is?

dpsutton17:02:53

there's a library that provides lots of arrow or threading functions. you might be able to use as->. Or I find it often better to figure out why the "position" changes and build forms that acknowledge that. a let binding or perhaps (->> (-> x foo bar) ...) can solve the "mismatch" problem many times

noisesmith17:02:20

as a correction, -> needs to be on the outside, all the other arrows work inside it by design

dpsutton17:02:07

that's valid there. its threading that single form through the thread last versions. You are talking about a different kinda pattern

noisesmith17:02:31

ahh - I see what you are doing OK

noisesmith17:02:06

that said, (-> x foo bar (->> ...)) does the same thing, and is more flexible

noisesmith17:02:16

I'd call it the "canonical" version

dpsutton17:02:41

fair. when the thread last form does the majority of the work or is longer i prefer my version as its a bit more clear to me

dpsutton17:02:20

it makes it feel more contained. but its just pure personal preference

aratare17:02:09

Exactly what I need. Thanks again šŸ™

grazfather17:02:20

DAE use babashka? I know borkdude is in here. Iā€™m looking for some reason to use clojure more (get more practice day to day doing real things) and I am pretty good at python/bash one liners, so this might be it

borkdude17:02:37

@grazfather There's also a #babashka channel with 400+ people

grazfather17:02:46

Yep, I just joined šŸ™‚

grazfather17:02:53

after I wrote that I figured Iā€™d check šŸ˜›

Pravin22:02:02

Hi, iam trying to find date difference in days, currently using [java-time :as jt] namespace. I have something which yields me difference between two dates in months. (.toTotalMonths(jt/period ?start-date ?end-date)) I want to extend this further and see what is the difference in days between these two dates. Is there any toDays method which will yield difference in days ?

Stuart23:02:23

(ns 
  (:import (java.time LocalDate)
           (java.time.temporal ChronoUnit)))

(let [d1 (LocalDate/parse "2016-04-02")
      d2 (LocalDate/parse "2016-05-25")]
  (-> (ChronoUnit/DAYS) (.between d1 d2)))
=> 53
I think this works to get total number of days. Or with ..
(let [d1 (LocalDate/parse "2016-04-02")
      d2 (LocalDate/parse "2016-05-25")]
  (.. ChronoUnit/DAYS (between d1 d2)))
=> 53

šŸ‘ 3
Pravin15:02:02

this worked, thank you !!!

borkdude23:02:05

You'll probably have to fix the ns form

Stuart23:02:28

Yeah, I just wanted to show where ChronoUnit was coming from

šŸ‘ 3
seancorfield23:02:10

(a lot of times it's not worth using a wrapper for Java Time stuff, although clojure.java-time does make some type conversions easier)