clojure

New to Clojure? Try the #beginners channel. Official docs: https://clojure.org/ Searchable message archives: https://clojurians-log.clojureverse.org/
zendevil 2021-02-10T12:02:23.428700Z

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

Dominic Pearson 2021-02-10T13:44:20.429200Z

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?

Dominic Pearson 2021-02-10T13:46:45.429500Z

https://stripe.com/docs/api/customers

Dominic Pearson 2021-02-10T14:02:31.430700Z

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)

Yehonathan Sharvit 2021-02-10T15:26:16.433100Z

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.

dpsutton 2021-02-10T15:28:41.434Z

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

dpsutton 2021-02-10T15:30:21.434400Z

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

alexmiller 2021-02-10T15:55:10.436Z

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

p-himik 2021-02-10T16:00:20.436500Z

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

alexmiller 2021-02-10T16:07:54.436900Z

fixed

Yehonathan Sharvit 2021-02-10T16:20:41.437100Z

@dpsutton what is this Numbers.num?

dpsutton 2021-02-10T16:23:18.437300Z

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

dpsutton 2021-02-10T16:23:29.437500Z

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

dpsutton 2021-02-10T16:24:05.437700Z

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

Yehonathan Sharvit 2021-02-10T16:27:24.437900Z

Voted like a responsible Clojure citizen

Yehonathan Sharvit 2021-02-10T16:38:49.438100Z

Why boxing is required here?

alexmiller 2021-02-10T16:40:50.438300Z

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

dpsutton 2021-02-10T16:45:59.438600Z

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

borkdude 2021-02-10T16:47:04.439900Z

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?

dpsutton 2021-02-10T16:50:06.440400Z

i see it in the changelog but basically nowhere else.

dpsutton 2021-02-10T16:50:33.441Z

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

borkdude 2021-02-10T16:51:21.441500Z

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

dpsutton 2021-02-10T16:52:51.442500Z

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

borkdude 2021-02-10T16:53:23.443100Z

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

dpsutton 2021-02-10T16:53:30.443300Z

"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

🙏 1
borkdude 2021-02-10T17:15:16.443800Z

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 ;).

pavlosmelissinos 2021-02-10T17:43:21.443900Z

@alexmiller 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 🙂

alexmiller 2021-02-10T17:48:09.444100Z

it is the only form of authentication

👍 1
alexmiller 2021-02-10T17:49:11.444400Z

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

👌 1
roklenarcic 2021-02-10T17:52:02.446700Z

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

roklenarcic 2021-02-11T12:16:07.477400Z

added this bit to the cljdocs examples

dpsutton 2021-02-10T17:57:56.447200Z

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

roklenarcic 2021-02-10T17:58:50.447400Z

seems to imply reify call creates two objects?

roklenarcic 2021-02-10T17:59:42.447600Z

yes further testing proves that’s the case:

roklenarcic 2021-02-10T17:59:50.447800Z

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

dpsutton 2021-02-10T18:09:07.448100Z

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

2021-02-10T18:20:13.450500Z

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."

alexmiller 2021-02-10T18:21:49.451Z

I've written a couple longer form things that might help: https://insideclojure.org/2015/01/02/sequences/ https://insideclojure.org/2016/03/16/collections/

2021-02-10T18:22:15.451800Z

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

alexmiller 2021-02-10T18:23:47.453Z

from a Java class pov, sequences ARE collections

alexmiller 2021-02-10T18:25:05.454400Z

ISeq extends IPersistentCollection

alexmiller 2021-02-10T18:25:49.455400Z

coll? returns true for seqs, etc

2021-02-10T18:26:03.455800Z

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.

2021-02-10T18:28:09.457100Z

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

alexmiller 2021-02-10T18:28:23.457400Z

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

2021-02-10T18:29:26.458200Z

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.

alexmiller 2021-02-10T18:31:11.458700Z

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

2021-02-10T18:53:43.458900Z

this is an artifact of compilation

2021-02-10T18:57:00.459100Z

no its not

2021-02-10T18:57:54.459300Z

or at least that is not a good description

2021-02-10T18:58:44.459500Z

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

2021-02-10T18:59:13.459700Z

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

borkdude 2021-02-10T19:34:15.461200Z

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?

dpsutton 2021-02-10T19:35:03.461500Z

where's that example from?

dpsutton 2021-02-10T19:35:20.461800Z

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

Yehonathan Sharvit 2021-02-10T19:35:33.461900Z

Thank you for your help!

borkdude 2021-02-10T19:35:50.462200Z

this example is from the tests

borkdude 2021-02-10T19:41:31.462700Z

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

dpsutton 2021-02-10T20:55:37.463400Z

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

dpsutton 2021-02-10T20:55:44.463600Z

and i don't like it ha

zimablue 2021-02-10T21:07:01.464Z

is the word "class" a keyword in clojure?

zimablue 2021-02-10T21:07:12.464300Z

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

p-himik 2021-02-10T21:09:12.464400Z

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

dpsutton 2021-02-10T21:09:37.464600Z

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

dpsutton 2021-02-10T21:10:09.464800Z

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

p-himik 2021-02-10T21:10:40.465Z

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

dpsutton 2021-02-10T21:11:15.465200Z

yeah i know. was showing how i knew 🙂

zimablue 2021-02-10T21:11:25.465400Z

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

dpsutton 2021-02-10T21:11:31.465600Z

not stupid at all

borkdude 2021-02-10T21:11:40.465800Z

anyway, the full syntax should now be supported on master

zimablue 2021-02-10T21:11:42.466Z

but repl-able, thanks a lot for your help

dpsutton 2021-02-10T21:11:44.466200Z

can you describe the weird behavior you are seeing?

dpsutton 2021-02-10T21:12:06.466400Z

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-himik 2021-02-10T21:12:22.466600Z

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

zimablue 2021-02-10T21:14:31.466800Z

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

zimablue 2021-02-10T21:15:10.467100Z

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

zimablue 2021-02-10T21:15:40.467300Z

I believe they call this yak shaving

p-himik 2021-02-10T21:20:01.467600Z

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

zimablue 2021-02-10T21:21:57.467800Z

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

dpsutton 2021-02-10T21:22:28.468Z

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