Fork me on GitHub
#clojure
<
2021-02-10
>
zendevil.eth12:02:23

I’m getting an inexplicable error in the clojurewerkz/elephant library and would appreciate help

dsp13:02:20

Looking at the library code,

(defn ^IPersistentMap create
  [^IPersistentMap m]
  (cnv/customer->map (Customer/create m)))
This is calling com.stripe.model.Customer, passing in the map. The codepath seems unrelated to the clj library. Have you tried inspecting the map and checking it is correct, and comparing it to the Stripe docs?

dsp14:02:31

Also the stacktrace seems to indicate the erroris when doing subscription creation. Can you give more context for: vendo.routes.home$create_subscription.invokeStatic(home.clj:62)

zendevil.eth04:02:40

This is the create-subscription function:

(defn create-subscription [req]
  (prn "request is " (:params req))
  (prn "payment method is " (:payment-method-id (:params req)))
  (let [customer (cust/create {"email" (:email (:params req))
                               "payment_method" (:payment-method-id (:params req))
                               })
        subscription (esub/create customer {"items"
                                            [{"price" (:price-id (:params req))}]
                                            "expand" ["latest_invoice.payment_intent"]})]
    (prn "subscription is " subscription)
    )
  (req-res/response "response"))

zendevil.eth04:02:47

and the error is in the cust/create

zendevil.eth04:02:38

in the docs under create a customer, there’s a payment_method parameter @UJA1Z6ZJ7

zendevil.eth04:02:22

which is what I have as well

Yehonathan Sharvit15:02:16

What’s the most efficient way to convert a string to a number without specifying the type of the number (Long, BigInt). I was thinking of clojure.edn/read-string but it will successfully reads strings that are not numbers. Also, I am not sure that it’s the most efficient option.

dpsutton15:02:41

you could look at how the reader does it. from memory a bit ago, it constructs a bigint from it and then if its sufficiently small turns that into a long

dpsutton15:02:21

BigInteger bn = new BigInteger(n, radix);
...
return bn.bitLength() < 64 ?
     Numbers.num(bn.longValue())
                         : BigInt.fromBigInteger(bn);

Yehonathan Sharvit16:02:41

@dpsutton what is this Numbers.num?

dpsutton16:02:18

static public Number num(Object x){
	return (Number) x;
}

static public Number num(float x){
	return Float.valueOf(x);
}

static public Number num(double x){
	return Double.valueOf(x);
}
from /clojure/src/jvm/clojure/lang/Numbers.java

dpsutton16:02:29

in this case as a long its not doing any work i think

dpsutton16:02:05

static public Number num(long x){
	return Long.valueOf(x);
}
is what its doing in this case. its boxing it i think?

Yehonathan Sharvit16:02:49

Why boxing is required here?

dpsutton16:02:59

this is reader code and the reader doesn't return primitives is my guess. but i'm very handwavy on boxing vs primitive. my work in Clojure normally doesn't depend on this stuff so i'm just surface level on that stuff

Yehonathan Sharvit19:02:33

Thank you for your help!

Alex Miller (Clojure team)15:02:10

I would actually like to have a core function for this and may even have created a CLJ ticket for it already

p-himik16:02:20

Seems like Jira exporter does some things wrong so that the resulting http://ask.clojure.org post looks off: - Some code is enclosed in <code>, as it should be; but some is just wrapped in {{...}} and is left as a regular text - Somehow parse-* has become *} with a bunch of spaces

Yehonathan Sharvit16:02:24

Voted like a responsible Clojure citizen

Alex Miller (Clojure team)16:02:50

thx, this really does help raise visibility - we are looking at votes for prioritization

pavlosmelissinos17:02:21

@U064X3EF3 Is github login the only form of authentication or am I missing something? I'd prefer to register separately but it's fine if not possible 🙂

Alex Miller (Clojure team)17:02:09

it is the only form of authentication

👍 3
Alex Miller (Clojure team)17:02:11

the github auth does not grant access to anything except public info

👌 3
borkdude16:02:04

I am implementing linting for the core.match macro. I'm running through its unit tests to see what clj-kondo can't yet understand. Now I've arrived at the :when syntax:

(match [y]
             [([_ (a :when even?) _ _] :seq)] :a0
             [([_ (b :when [odd? div3?]) _ _] :seq)] :a1
             :else [])
but I can't find docs on this, neither in the Basic usage nor in the Advanced usage wiki page. Is this undocumented behavior?

dpsutton16:02:06

i see it in the changelog but basically nowhere else.

dpsutton16:02:33

but that multimethod allows for dynamic additions. I've got one like

(defmethod match/emit-pattern-for-syntax [:isa? :default]
  [[_ parent]] {::match/tag ::isa? :parent parent})
so there's no way to encompass all statically i think

borkdude16:02:21

oh so :when is defined using a multimethod and is something custom?

dpsutton16:02:51

its custom but defined in the source just like :seq :or :guard :<< etc. it uses a mechanism that is exposed for others to add syntax to match

borkdude16:02:23

I just added support for :<<. I'll take a look

dpsutton16:02:30

"Handles patterns wrapped in the special list syntax. Dispatches
  on the first or second keyword in the list. For example, the pattern
  `(:or 1 ...) is dispatches as :or, and `(1 :as a)` is dispatched by :as."
docstring for emit-pattern-for-syntax

🙏 3
borkdude17:02:16

Haha, the advanced usage docs: > You should read Understanding the algorithm before reading the rest of this section. And then there is hardly any rest of this section ;).

roklenarcic17:02:02

hey people… I’ve been experimenting with finalize on reified objects and I’ve noticed that finalize method is called twice for each object, which seems odd, since Java is supposed to call each finalize once.

(defn test1 []
  (reify Object
    (finalize [this]
      (println "collected"))))
and this produces:
(do (test1) (System/gc))
collected
collected
=> nil
Seems odd

dpsutton17:02:56

user=>
(defn test1 []
  (reify Object
    (finalize [this]
      (println "collected" this))))
#'user/test1
user=> (do (test1) (System/gc))
nil
collected user=> #object[user$test1$reify__179 0x5802c0da user$test1$reify__179@5802c0da]
collected #object[user$test1$reify__179 0x202cf2e7 user$test1$reify__179@202cf2e7]
logging this shows there are different things involved

roklenarcic17:02:50

seems to imply reify call creates two objects?

roklenarcic17:02:42

yes further testing proves that’s the case:

roklenarcic17:02:50

(let [t (test1)] (System/gc) t)
collected

dpsutton18:02:07

i browsed the code a little bit. I see that Object is cons onto the interfaces without checking if its already there. i wonder if its duplicating this stuff accidentally. Note this is cursory glance and I could easily be wrong

hiredman18:02:43

this is an artifact of compilation

hiredman18:02:54

or at least that is not a good description

hiredman18:02:44

I am pretty sure the two instances are a result of the code the compiler emits to add any metadata attached to the reify form to the instance

hiredman18:02:13

and reify supports metadata as a value, so adding metadata returns a new instance

roklenarcic12:02:07

added this bit to the cljdocs examples

andy.fingerhut18:02:13

I kinda feel like I only half understand the finer distinctions here, but in Clojure, is it correct to say that sequences are not collections? You can create sequences from collections. You can create collections from sequences. But sequences themselves are not collections? As far as official docs go, this page seems to imply that sequences are separate things from collections: https://clojure.org/reference/sequences e.g. these sentences on that page imply they are separate kinds of things: "Many of the functions in the seq library take one or more collections, call https://clojure.github.io/clojure/clojure.core-api.html#clojure.core/seq on them, and then operate on the resulting seq. In other words, many of these functions take collections but operate on their seqs."

andy.fingerhut18:02:15

Thanks for the links. If anyone has written more deeply on this topic, I figured it would be you 🙂

Alex Miller (Clojure team)18:02:47

from a Java class pov, sequences ARE collections

Alex Miller (Clojure team)18:02:05

ISeq extends IPersistentCollection

Alex Miller (Clojure team)18:02:49

coll? returns true for seqs, etc

andy.fingerhut18:02:03

My question arises from wondering what an "authoritative" answer would be for explaining to someone why peek throws an exception for at least some kinds of sequence inputs. peek mentions a few collection types like vectors, lists, and queues explicitly, but then also says what it does for "collections" in general. If sequences are collections, then in some minds it might raise the question of whether sequences are collections, or not.

andy.fingerhut18:02:09

That might be just one of those corners of implementation or docs that is kinda near the hairy edge of these questions.

Alex Miller (Clojure team)18:02:23

as usual, I think you should read absence of information as significance of undefined behavior

andy.fingerhut18:02:26

Ah, so perhaps the word "collection" in peek's doc string should be interpreted as "one of the aforementioned kinds of collection early in the doc string", not "any arbitrary kind of Clojure collection". That would make sense.

Alex Miller (Clojure team)18:02:11

peek / pop really only make sense as a concrete sequential data structure operation, not as seq ops

borkdude19:02:15

In order to write linting for :when in core.match, I'm trying to understand it. @dpsutton already pointed me to the docs of the defmulti. it dispatches on the first or second keyword in the pattern. But I'm also seeing expressions like:

(match [y]
    [([_ _ :when even? _ _] :seq)] :a0
    [([_ _ :when [odd? div3?] _ _] :seq)] :a1
    :else [])
How do these get handled? The keyword :when occurs in seemingly random place in the pattern?

dpsutton19:02:03

where's that example from?

dpsutton19:02:20

its possible that that is matching on the literal :when?

borkdude19:02:50

this example is from the tests

borkdude19:02:31

it seems it supports a "flattened syntax"? hmm, this complicates things

dpsutton20:02:37

i've seen the group by stuff but never understood what it does

dpsutton20:02:44

and i don't like it ha

borkdude21:02:40

anyway, the full syntax should now be supported on master

zimablue21:02:01

is the word "class" a keyword in clojure?

zimablue21:02:12

having some inherent meaning when used as first element of a form?

p-himik21:02:12

It's not a keyword, it's a regular function in clojure.core.

dpsutton21:02:37

(map (juxt identity special-symbol?) '[if class deftype let* fn])

dpsutton21:02:09

(let [class inc] (class 3)) yields 4 for me

p-himik21:02:40

Because it's a regular function. :)

user=> (source class)
(defn class
  "Returns the Class of x"
  {:added "1.0"
   :static true}
  ^Class [^Object x] (if (nil? x) x (. x (getClass))))
nil

dpsutton21:02:15

yeah i know. was showing how i knew 🙂

zimablue21:02:25

thank you, sorry for the stupid question, I am not a regular clojure user, was trying to understand some clojurescript, should have got a repl going

dpsutton21:02:31

not stupid at all

zimablue21:02:42

but repl-able, thanks a lot for your help

dpsutton21:02:44

can you describe the weird behavior you are seeing?

dpsutton21:02:06

oh i never mean "you can answer this question yourself so don't ask it". i always mean great question and here's an authoritative answer

p-himik21:02:22

Indeed not stupid. But in case you have a lot of entry-level questions, you'll find #beginners to be a great place.

zimablue21:02:31

it's understandable now I know it's a clojure core function, someone in this library: https://github.com/groundedSAGE/konserve has some cljc files whic haven't been used under cljs for a long time so don't compile, because they include that function without a guard for :clj

zimablue21:02:10

I was slightly ambitiously trying to get them to compile/run under node in order to get a version of datahike working under node for a project I'm mostly working in typescript but want a node logic db as backend

zimablue21:02:40

I believe they call this yak shaving

p-himik21:02:01

Yeah, class is not defined in CLJS at all - because the platform has no proper classes, I guess.

zimablue21:02:57

one could imagine there being some special magic for cljc files under a cljs/clj compiler which detects the more obvious compatibility errors, but then I imagine they're obvious for more experienced devs

dpsutton21:02:28

there's not a ton of magic to the cljc stuff.