Fork me on GitHub
#clojure
<
2019-02-04
>
Christian Johansen10:02:27

how can I find the approximate size (bytes of memory) of a piece of Clojure data?

Christian Johansen10:02:01

alternately, what is the approx size of maps and keywords?

Christian Johansen10:02:01

awesome, more than I could have hoped for 🙂

souenzzo13:02:43

There is some "core utils" with a index-by function, that do (index-by :id [{:id 1}]) => {1 {:id 1}}?? It's almost like group-by, but do not conj on value.

borkdude13:02:24

yes, there is, but often people write it themselves, using (into {} (map (juxt f identity) coll))

lisphug 2
borkdude13:02:01

This PR for medley has been open for a while. I like the name index-by better. Propose it 😉 https://github.com/weavejester/medley/pull/28

❤️ 1
rutledgepaulv13:02:07

https://github.com/vodori/missing (a lib I maintain) has index-by and indexcat-by and groupcat-by :P

bronsa13:02:54

@souenzzo not exactly but clojure.set/index

bronsa13:02:02

user=> (set/index [{:id 1} {:id 2} {:id 1 :x 2}] [:id])
{{:id 1} #{{:id 1, :x 2} {:id 1}}, {:id 2} #{{:id 2}}}

Arthur15:02:39

Hello guys!! Do we have a channel for Lacinia? I have found one, but it is archived..

lispyclouds15:02:40

#graphql should be the one i think

Arthur15:02:00

Thank you!!

Ben Hammond15:02:22

I am using clojure.edn/read to read an .edn file which contains #object[ tags like #object[java.io.File 0x6ae4aa5 "hello-world.pdf"] Ideally I would like to interpret these as a record, something like (->EdnObject clazzname identityHashCode string-description) at the moment I get an error

java.lang.RuntimeException: No reader function for tag object
Is the preexisting reader function that I can reuse to do this? Do I have to write my own?

Ben Hammond16:02:31

I was hoping to wire in the binding using

(binding [clojure.core/*data-readers* (assoc clojure.core/*data-readers*
                                        'object #'dev/my-special-edn-binding)]
does that only work for namespaced tags?

Ben Hammond16:02:28

oh I see I can just pass in :readers in the options to clojure.edn/read thus

(clojure.edn/read {:eof eof-sentinel :readers {'object #'dev/my-special-edn-binding}} r)

Ben Hammond16:02:47

thank vlaad; that good to know

😊 1
dtsiedel19:02:58

Why is spec imported as spec.alpha? Does this notation imply that the interface is liable to change?

noisesmith19:02:49

it has alpha in the name because it is alpha, yes

dtsiedel19:02:28

It just seems odd to explicitly notate it, since AFAIK breaking changes have happened in Clojure core even when not notated alpha

alexmiller19:02:38

trying to do better :)

seancorfield19:02:50

(:require [clojure.spec.alpha :as s]) means that when it comes out of alpha you can just update that to (:require [clojure.spec :as s]) and (hopefully) not having to change your code 🙂

alexmiller19:02:51

spec 2 dev is under way and will likely include some breaking changes

seancorfield19:02:58

Except for those breaking changes 🙂

alexmiller19:02:05

although we are trying to minimize those

seancorfield19:02:32

We're very heavy users of spec and I have almost everything running at work on spec2 -- and the code changes weren't too extensive. I'm still working with Alex on a couple of issues tho'... 🙂

alexmiller19:02:59

more changes to come, although I expect a lot will be additive

dtsiedel19:02:36

Sounds good - really I was just curious about the choice of notation, I'm not concerned too about having to make small changes to keep using spec 🙂

seancorfield19:02:32

There was a good thread about the alpha naming here https://clojureverse.org/t/are-clojure-core-alpha-namespaces-chosen-to-avoid-upgrade-conflicts/3722/5 -- relating to Rich's talk about semantic versioning and accretive design...

dtsiedel20:02:31

Thanks for the link @seancorfield

seancorfield20:02:33

Strong adoption of Clojure 1.10 in the State of the (Clojure) Union survey results! Already 54% on 1.10. That's awesome. And only 3% on 1.7 or earlier. Great news for library developers.

Christian Johansen20:02:29

that's the result of caring about backwards compatibility 👌

Christian Johansen20:02:41

stable software ❤️

alexmiller20:02:47

I was actually disappointed it was so low :)

deep-symmetry00:02:09

I am eager to move to it, but am being held back by CIDER not coping with the change in error format. Normally I adopt much faster. 😄

deep-symmetry05:02:13

Oops, it looks like they fixed that issue and I somehow missed it. I thought I was tracking the issue on GitHub. It’s been a busy few months! I am trying again to move to 1.10.

Christian Johansen20:02:03

agreed, should've been higher

Christian Johansen20:02:24

but I'm more surprised at 3% on 1.7 or earlier

alexmiller20:02:45

in line with prior surveys - generally most people are on the last 2-3 releases

dpsutton20:02:46

conversely, people who updated were much more likely to participate in the survey 🙂

alexmiller20:02:06

always hard to predict the selection bias for respondents

dpsutton20:02:24

agreed. really looking forward to the results. i like hearing from fellow clojure users

Christian Johansen20:02:54

I'll throw in another data point: thanks a lot for the tireless great work you and your team put in @alexmiller!

👍 1
dpsutton20:02:24

agreed. immutable datastructures, a repl, and an alex. all features i value in Clojure

alexmiller20:02:49

tell your friends :)

Christian Johansen20:02:54

I do that too 🙂

johanatan20:02:19

is this a pattern that people use?

#(do [:a :vector :or :other :literal])
or do most people opt for specific constructor functions (or into etc) ?

johanatan20:02:50

i tend to go with do because it's only two characters

borkdude20:02:48

I tend to go with (fn [] [:a :vector]) or (constantly [:whatever])

💯 2
johanatan20:02:24

the question pertains specifically to lambdas

johanatan20:02:33

i.e., assume you are using a lambda then ...

johanatan20:02:10

there are reasons why i don't always use a lambda but if a lambda is available to me, then I do opt for it first.

borkdude20:02:38

with lambda you mean a function literal?

alexmiller20:02:46

#(vector :a :vector)

alexmiller20:02:58

^^ if you want a vector constructor, use the vector constructor

johanatan20:02:31

any reason for this preference? performance or aesthetic?

alexmiller20:02:58

I think it is clearest way to say what you are doing here. you are invoking a function to make a vector from some elements

alexmiller20:02:28

whereas #(do […]) is fewer characters but much weirder imo

johanatan20:02:01

lol, yea, i tend to prefer fewer characters unless it's really confusing

johanatan20:02:16

another argument for do is that it is possible to return any literal that way, not just the ones which happen to have a nice constructor (like say vector or hash-map).

alexmiller21:02:43

don’t all of the literals have a constructor though?

johanatan19:02:13

Perhaps. Set, vector, list & hash-map do.

alexmiller19:02:33

sorted-set, sorted-map, queue

alexmiller19:02:49

ok, queue doesn’t :)

johanatan20:02:08

@borkdude no, i mean the #( ... ) shorthand syntax for a function literal

lilactown20:02:19

just FYI, things that start with # are referred to as "literals"

johanatan20:02:54

fyi... {:a :b} is a literal. [:a :b] is also a literal.

johanatan20:02:18

as are: 9, :a, "blah" etc etc

borkdude20:02:27

@U0E98NQG2 #(…) is a function literal

lilactown20:02:02

OK, sorry; I'm just basing this off of the Clojure docs: https://clojure.org/guides/higher_order_functions#_function_literals

johanatan20:02:28

what would you call (fn [] ...) then?

johanatan20:02:34

just "anonymous function" ?

johanatan20:02:46

[although technically it can be named too :)]

johanatan20:02:56

(fn the-name [] ...)

lilactown20:02:05

yeah. or a "form" maybe?

borkdude20:02:12

function value?

borkdude20:02:31

just function maybe. don’t know

borkdude20:02:03

the function’s name is only known to itself, so it’s still anonymous to the outside

johanatan19:02:30

Yes, that’s right. It allows self-reference. That’s about it.

borkdude20:02:50

bikeshedding if you ask me

johanatan20:02:10

@borkdude yea, probably. was just staring at some code and wondered what other people thought.

eraserhd20:02:24

I am seeing the weirdest thing: (symbol x) returning nil, when we are passing it a valid string without a slash, and both type and class report java.lang.String.

eraserhd20:02:43

I don't see how this can happen, though. Has anyone seen this?

hiredman21:02:19

not possible, so it is something else

eraserhd21:02:42

I agree that it is not possible, however, I am repeatedly demonstrating it.

hiredman21:02:25

are you literally doing (doto (symbol x) (-> class prn)) ?

eraserhd21:02:54

I'm going to see how far I can whittle down the example, but this is the current state: https://gist.github.com/eraserhd/f4f8f52fb43a2e4a5b6fc740a1101c02

hiredman21:02:42

you are shadowing clojure.core/symbol with the argument name

👍 2
eraserhd21:02:08

It's OK everyone. Compiler's not broken

donyorm21:02:25

So I'm trying to generate longs with clojure.spec.gen.alpha/large-generator. This works fine when using generate, but with clojure.spec.gen.alpha/sample it generates extremely low values (+-60 from 0). I need it to generate pretty much the full range of longs. Any idea why it has this behavior?

Lennart Buit21:02:50

it generates larger integers with a larger sample size

Lennart Buit21:02:26

What I think it is trying to do is try the “edge” cases first, so zero, minus one, plus one, etc. Before actually switching to completely random longs

donyorm21:02:13

Hmm, seems your right. The numbers get more random as I get more. Anyway I can force it to be random from the beginning?

Lennart Buit21:02:48

I am not sure, you can always define your own generator tho

donyorm21:02:12

Alright, thanks!

Lennart Buit21:02:48

May I ask, why don’t you just increase the sample size?

Lennart Buit21:02:00

Is there really no value in testing small values for you

donyorm21:02:18

Yeah, I'm testing dates. So one low value is fine (Jan 1, 1970), but then I want to start seeing other values. Having to scroll past the first 10 values in the web app is just wasting space, but it may be the easiest solution. Or I guess I could drop the first 10 or so values

Lennart Buit21:02:11

Well - from a formal background - I understand why gen is doing this, bugs usually occur on boundaries. So testing for 0, -1, 1 etc. is usually more valuable than testing complete random values. Further reading: boundary analysis

donyorm21:02:32

Cool. Thanks for the input. I appreciate the help

alexmiller22:02:32

that’s not actually why - gen is designed to “grow” more “complex” values as it generates more samples, then has support for “shrinking” a complex test case into a simpler one

alexmiller22:02:47

you can use large-integer* to generate longs with uniform distribution (note: spec’s int-in uses this so that’s another path)

alexmiller23:02:54

well, actually those might grow too

alexmiller23:02:38

my memory was faulty

Lennart Buit01:02:19

Hah, interesting!

Lennart Buit01:02:23

I stand corrected ^^