This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-10-04
Channels
- # babashka (17)
- # beginners (82)
- # calva (42)
- # clj-commons (9)
- # cljdoc (2)
- # cljsrn (3)
- # clojure (142)
- # clojure-europe (12)
- # clojure-nl (1)
- # clojure-sg (1)
- # clojure-uk (14)
- # clojurescript (22)
- # community-development (3)
- # cryogen (12)
- # cursive (15)
- # data-science (13)
- # datomic (11)
- # deps-new (8)
- # emacs (3)
- # fulcro (31)
- # gratitude (7)
- # holy-lambda (8)
- # honeysql (6)
- # introduce-yourself (1)
- # jackdaw (11)
- # jobs-discuss (7)
- # kaocha (1)
- # malli (8)
- # other-languages (9)
- # pathom (14)
- # pedestal (1)
- # polylith (3)
- # portal (12)
- # re-frame (3)
- # react (3)
- # reagent (4)
- # releases (3)
- # reveal (7)
- # ring (11)
- # shadow-cljs (17)
- # specter (3)
- # sql (1)
- # timbre (2)
- # tools-deps (122)
- # xtdb (18)
I'm trying to get this example working in Clojure https://developers.line.biz/en/reference/messaging-api/#send-push-message
final LineMessagingClient client = LineMessagingClient
.builder("<channel access token>")
.build();
but I can't seem to get the above working. my first instinct was
(def client (-> (LineMessagingClient.)
(.builder channel-access-token)
.build))
but seems like there is no constructor https://javadoc.io/doc/com.linecorp.bot/line-bot-api-client/latest/com/linecorp/bot/client/LineMessagingClient.html
Should I be using something like proxy
etc. (Also I feel that Spring Boot examples tend to make Java interop less direct)builder
looks like a static method, so perhaps (LineMessagingClient/builder "<channel access token>")
Thanks @lennart.buit you were right! 😄
I was looking into mount
example mentioned here https://github.com/tolitius/mount/blob/master/dev/clj/app/example.clj#L17 , we are not passing any argument to (mount/start)
how all state will be initialised here ?
Does start
just takes number of states present in namespace? according to https://github.com/tolitius/mount#recompiling-namespaces-with-running-states
How can I make (.plus (Instant/now) EXPIRY_DAYS ChronoUnit/DAYS)
human readable?
😄I mean when printing out
(prn (.plus (Instant/now) EXPIRY_DAYS ChronoUnit/DAYS))
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/format/DateTimeFormatter.html contains some predefined formatters which might help you
NOt sure if it's what you're looking for, but I strongly recommend https://github.com/dm3/clojure.java-time, which is super easy to use, comes with formatters, easy to use functions and much more. I love it.
Your code would be re-written as:
(plus (instant) (days EXPIRY_DAYS))
And if you want to format it :
(-> (instant)
(plus (days EXPIRY_DAYS))
(format))
I did something pretty hacky a while ago to make Date. more readable:
(defn v-time [timestamp]
(let [dos (java.util.Date. timestamp)]
(str (subs dos 0 10) " " (subs dos 24 48) " " (subs dos 10 20))))
You pass in unix time and you get something "human readable" out
I wrote a library with quite some namespaces; what is the most idiomatic way to offer a (ns mylib.porcelain)
that simply re-exports most of the relevant functions and macros? I looked at intern
, which doesn’t seem to work for macros, and I looked at simply re-`def`/`defmacro`-ing everything.
There are tools for this, but personally, I’d say write your ‘api’ in an .api
or .core
namespace in plain old Clojure.
Re-exporting comes with lots of tool caveats (for one, Cursive doesn’t understand re-exported vars).
The no-magic, no surprises approach sounds appealing indeed, thanks!
obvious code is best code 🙂
> I looked at simply re-`def`/`defmacro`-ing everything I agree, this is fine. It's your API, it's better to devote some of your time to it and be explicit about how you expect the users to use your library. I'd suggest that you also consider defn instead of def. def might seem like less effort because you don't have to type as much but with defn you can have different docstrings for the users vs for contributors and maybe even (slightly) different signatures, which can be useful.
both def
and defn
will ignore the original doc string, and require adding a new one
Right, didn't realize that def
can also have a docstring, thanks. That makes sense actually.
and with either def or defn you can copy the metadata of the original as part of the declaration
or maybe it's simpler with intern
actually
(cmd)noisesmith.gui=> (intern *ns* (with-meta 'my-conj (meta #'conj)) conj)
#'noisesmith.gui/my-conj
(cmd)noisesmith.gui=> (doc my-conj)
-------------------------
noisesmith.gui/my-conj
([coll x] [coll x & xs])
conj[oin]. Returns a new collection with the xs
'added'. (conj nil item) returns (item). The 'addition' may
happen at different 'places' depending on the concrete type.
nil
Hello all, How do I access
public class GoogleAuthorizationCodeFlow { ....
public static class Builder extends AuthorizationCodeFlow.Builder
{
public Builder(HttpTransport transport, JsonFactory jsonFactory, GoogleClientSecrets clientSecrets, Collection<String> scopes)
{ ....
? (GoogleAuthorizationCodeFlow$Builder/Builder. HTTP_TRANSPORT JSON_FACTORY (generate-secrets) SCOPES)
?why casting to other class it show source class?
(:import [com.google.api.client.json JsonFactory]
[com.google.api.client.json.gson GsonFactory])
(def JSON_FACTORY (cast com.google.api.client.json.JsonFactory (GsonFactory/getDefaultInstance)))
(type JSON_FACTORY) -> com.google.api.client.json.gson.GsonFactory
why?Probably because it is a subclass of ...gson.GsonFactory https://clojuredocs.org/clojure.core/cast#example-542692cdc026201cdc326ccd
(defn type
"Returns the :type metadata of x, or its Class if none"
{:added "1.0"
:static true}
[x]
(or (get (meta x) :type) (class x)))
(defn class
"Returns the Class of x"
{:added "1.0"
:static true}
^Class [^Object x] (if (nil? x) x (. x (getClass))))
JsonFactory JSON_FACTORY = (JsonFactory) GsonFactory.getDefaultInstance();
System.out.println(JSON_FACTORY.getClass());
No matching method Builder. found taking 4 args for class com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow$Builder
@U0YJJPFRA does the ctor have a varargs parameter?
you are calling a method named Builder on the class com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow$Builder and passing it 4 arguments
you want something like (com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow$Builder. 1 2 3 4)
not whatever you are doing
Hey guys/gals. I ran into this discussion https://stackoverflow.com/questions/7491360/how-do-you-return-from-a-function-early-in-clojure#:~:text=There%20isn't%20a%20return,something%2C%20in%20these%20cases%20nil%20. and the accepted answer says if your algorithm needs a return statement, it's a major code smell.
I thought I needed a return statement for what I’m trying to do, and was wondering if someone could point me to a better way of writing this:
I’m looping through a vector using doseq
to save files from an http request, but if one of those looped objects is themselves a vector and not a map, I wanted to ‘return’ or ‘throw’ a bad-request. But do-seq
returns nil so my (if (vector? file) (bad-request "Not a map")
doesn’t actually return and make it to the http-response.
Any suggestions?
(defn handle-file-upload [params]
(if (vector? (params :file))
(doseq [file (params :file)]
(if (vector? file)
"Cannot parse request body. Found a vector within the file vector. Expected maps.\n"
(copy-file-local file))
)
(if (map? (params :file))
(copy-file-local (params :file))
"Expected file request to be a map.\n"))
)
(defn upload-route []
(wrap-multipart-params
(POST "/upload" {params :params}
(let [res (handle-file-upload params)]
(if (nil? res) (response "File uploaded\n")
(bad-request res)))
)))
(if (vector? (params :file))
(loop [[file & rest] (params :file)]
(if (vector? file)
"Cannot parse request body. Found a vector within the file vector. Expected maps.\n"
(do
(copy-file-local file)
(recur rest)))
...)
(reduce
(fn [_ file]
(if (vector? file)
(reduced "Cannot parse request body. Found a vector within the file vector. Expected maps.\n")
(copy-file-local file)))
(params :file))
my code there might be a bit wrong - i think you need to check if file is nil which happens at the end w/ the loop - but i think it still shows you some ways to do what you want
Yes it does, I just read through loop
and reduced
in the docs, just what I was looking for thank you.
A little surprised there isn’t a foreach
macro, I guess that’s pretty much just a loop
?
Hello Friends! I just made my first API with compojure-api and it is very very cool. Just wanted to thank everyone for the support. The Clojurians community is amazing and I always get a lot of cool tips here.
Of course it's super silly and stupid, but I can change an atom from the outside world.
(ns econ.core
(:require [compojure.api.sweet :refer :all]
[ring.util.http-response :refer :all]
[schema.core :as s]))
(s/defschema Transaction {:amount s/Num
:account s/Str
:type (s/enum :outbound :inbound)})
(def transactions (atom []))
(defn add-transaction [transaction]
(swap! transactions conj transaction))
(def app
(api
:swagger
{:ui "/"
:spec "/swagger.json"
:data {:info {:title "Econ API"
:description "Econ API Documentation"}
:tags [{:name "api" :description "Econ API documentation."}]}}
(context "/api" []
:tags ["api"])
(GET "/transactions" []
:return [Transaction]
:summary "Returns all transactions"
(ok @transactions))
(POST "/transactions" []
:return Transaction
:body [transaction Transaction]
:summary "Echoes a transaction"
(do
(add-transaction transaction)
(ok transaction)))))
Hello guys, i struggle finding a way to filter the first vector, with the pred: • name_A = name_B, but age_A not= age_B
(let [list-A [{:name "unique_A_name" :age "99"} {:name "joyce" :age "25"} {:name "connor" :age "32"} {:name "brad" :age "21"}]
list-B [{:name "joyce" :age "77"} {:name "connor" :age "60"} {:name "brad" :age "21"}]]
<filter?! function here>)
the expected result is a list of items that have same :name but different :age ({:name "joyce" :age "25"} {:name "connor" :age "32"})
Thank you in advance!Struggling to find a way to filter the items suggests that you might want to structure your data differently, if it's in your control.
Do you explicitly want the returned list be a filtered version of list-B
(ie. in the same order)?
One approach would be to (group-by :name list-A)
and then check elements of list-B
against that.
(let [list-A [{:name "unique_A_name" :age "99"} {:name "joyce" :age "25"} {:name "connor" :age "32"} {:name "brad" :age "21"}]
list-B [{:name "joyce" :age "77"} {:name "connor" :age "60"} {:name "brad" :age "21"}]]
(filter (fn [person]
(some #(and (not= (:age %) (:age person))
(= (:name %) (:name person))) list-B))
list-A))
and yes my instinct is also what @UCYS6T599 said, the datastructure feels wrong. It sounds like you want to deal with relations here (sets of maps) and maybe some of the clojure.set operations, depending on the context surrounding that code.
take a peek here if you didn’t have already, might be useful: https://clojuredocs.org/clojure.set
This is a nice tutorial on creating lookup maps which are generally very useful in my day to day job; https://www.youtube.com/watch?v=n0BTsKVs1Lw
(into {} (map (juxt :name identity) list-b))
might be how I'd start if I was solving the above problem
sorry I couldn’t figure out a better data structure. but I edited my above suggestions to be a bit more efficient. It works but I think there must be something more elegant and efficient.
I second finding a representation of your data more amenable to the kinds of queries you'd like to do. If that's not an option, you can get quite expressive using clojure.set
. The following
(set/difference (set/join list-A list-B {:name :name})
(set/join list-A list-B {:name :name :age :age}))
returns a set of the values in list-A
you want to keep. You can convert this into a vector, or, to preserve order, use this set as a predicate with filter
.thank you all for your time and effort,
(let [list-A [{:name "unique_A_name" :age "99"} {:name "joyce" :age "25"} {:name "connor" :age "32"} {:name "brad" :age "21"}]
list-B [{:name "joyce" :age "77"} {:name "connor" :age "60"} {:name "brad" :age "21"}]]
(filter (fn [person]
(some #(and (not= (:age %) (:age person))
(= (:name %) (:name person))) list-B))
list-A))
@U01EFUL1A8M’s solution works for mei will try the other solutions also and read the links provided. Thanks
As long as all names are unique,@U01EFUL1A8M's solution will work perfectly. My solution is actually not correct, due to how set/join
can pick a key's value from either list.
If a name can appear more than once in list-B
, you need to deal with that somehow. I don't know if that's a possible scenario for your code.
(let [n (group-by :name list-B)
na (group-by (juxt :name :age) list-B)]
(filter (fn [person]
(and (get n (:name person))
(nil? (get na (juxt :name :age person)))))
list-A))