Fork me on GitHub
#clojure
<
2018-01-16
>
rnagpal00:01:55

I am trying to declare multiple gen-class in same name space

rnagpal00:01:55

but I get error that they are not defined

rnagpal00:01:27

but when I declare them as string I get this error Exception in thread "main" java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :gen-class

hiredman01:01:15

the ns macro only allows a single :gen-class

hiredman01:01:00

if you are newish to clojure(which evidence suggests) I would strongly recommend you stay as far away from gen-class in all its guises as possible

seancorfield02:01:35

(and also take advantage of the folks in #beginners who have opted in to help answer new-to-Clojure people's questions @rnagpal!)

nha10:01:58

I have a vector of int/strings and I want to calculate a positive hash of it. Are better options than (Math/abs (hash [ids]))?

nha10:01:39

I wish there was a hash that would be always positive

romni11:01:31

CRC is not really a hash but it can be used as such

romni11:01:35

and it's strictly positive

romni11:01:30

check java.util.zip.CRC32

nha11:01:09

thanks - checking

rauh11:01:50

@nha You can also bit-and with (1 << 31)-1

nha11:01:19

I guess that’s what Math/abs does under the hood isn’t it?

noisesmith18:01:04

just a thought - hash returns an int, if you are OK with a long, you could do a bit-or of the raw bottom 16 bits of the int with long 0 and get a 64 bit number guaranteed positive

noisesmith18:01:02

try #(bit-and (hash %) (dec (bit-shift-left 1 32)))

noisesmith18:01:51

if you prefer, 0xffffffff is the same as (dec (bit-shift-left 1 32))

tjtolton11:01:55

So I'm trying to turn arbitrary data maps into json strings. And that's usually pretty simple, but cheshire/generate-string will sometimes fail when given things like regex patterns. Is there someway to tell cheshire to just get over it and call to string on anything it doesn't recognize?

tjtolton11:01:36

I know there are custom encoders, but is there, like, a "fallback decoder"?

tjtolton11:01:11

where it just does (try ((encoder-lookup thing) thing) (catch Exception e (encode-str thing))

qqq11:01:20

I believe Math/abs also works on floats, and I'm not sure you can take abs of a float by just bit shifting.

tjtolton11:01:04

also does anyone know what the proper classname for functions would be? I want to tell cheshire to use generate-str for functions. but they all seem to be generated classnames, e.g. ring.middleware.multipart_params$wrap_multipart_params$fn__19512

qqq11:01:34

@tjtolton: why not use https://clojure.github.io/clojure/clojure.walk-api.html and pre convert all "should be converted to string" things first ?

tjtolton12:01:56

this is for all log statements. which means 2 things -- a) I don't know what all the things that "should be strings" are in advance, and b) performance matters so I don't want to do case analysis on everything in the tree.

tjtolton12:01:44

or at least that's my thinking right now

qqq12:01:49

Why not dump via EDN, or just call "str" ?

qqq12:01:56

Why does it need to be JSON ?

qqq12:01:26

anything that does clj -> json is going go have to 'walk the tree' anyway, there's no magical "clj -> json" function out there

tjtolton12:01:07

cheshire uses some valuable performance tricks, and I'd certainly prefer not to walk the tree twice?

ido12:01:17

what is the standard way/work-around in clojure to propagate exception via a promise? assuming I do not want to use a sentinel in the returned value nor a future for that?

juhoteperi12:01:28

@tjtolton I don't know how Cheshire and pr-str compare, but Cheshire isn't even that fast. It uses definline (which prevent JVM inlining) and dynamic vars.

juhoteperi12:01:09

@tjtolton Maybe you could try add-encoder Object, and see if that is used if other encoders don't match

tjtolton12:01:23

wow, I did not think of that

tjtolton12:01:09

wonder if it gives precedence to the extensions or the builtins

juhoteperi12:01:42

I think so, it seems to be implemented using protocols (it extends the given class with JSONable protocol)

juhoteperi12:01:58

And for protocols the first implementation is used

qqq12:01:07

floats/doubles can NOT represent all integers, at some point, it starts "skipping values"; so if we have a float/double that we repeatedly call +1 on, does JVM/JS say what happens when we reach a "skip number" ? (does it always increases, always stay the same, or is behaviour undefined)

tjtolton12:01:25

thanks @juhoteperi works like a charm

qqq12:01:57

@rauh: this is interesting, but doesn't answser my question

qqq12:01:09

I'm using it as a "uniqe id generator" by just incrementing it

qqq12:01:22

so if it starts losing precision / skipping, I don't care as longa s it's unique 🙂

rauh12:01:43

Well to answer your question: No nothing happens when do you do double/float math and enter this range

qqq12:01:13

`(= (Math/pow 2.0 54) (+ 1 (Math/pow 2.0 54)))` evals to true -- you're right -- and this does answer my questino; thanks!

qqq12:01:22

what the cljc way to generate incrementing' ids? (I'm not looking for probabilistic uuid, but something that is 'counterish', but perhaps string or vector backed instead of long/float based)

martinklepsch13:01:43

If I want to pr-str an arbitrary nested data structure containing lazy seqs, what’s the best way to do this?

qqq13:01:18

you want the lazy-seqs to be made concrete, and not show up as @Clojure$List... ?

martinklepsch13:01:38

basically I want this to work without changing map to mapv, and by using some function that ensures all (potentially nested) data is fully realized before being printed

(->> (range 30)
     (map #(do (println %) %))
     (pr-str))

qqq13:01:34

sounds like you just want to walk the structure and make everything strict

lmergen13:01:42

@martinklepsch i think laziness is a property of the collection type (sequence vs vector)

lmergen13:01:55

what you're asking for is a mechanism that basically sits between two sequences

lmergen13:01:02

and realizes all of the first

lmergen13:01:15

and then feeds the output sequence

martinklepsch13:01:35

@qqq yeah walking is the option that also came to mind but I don’t know, this seems harder than it should be. 🙂

flowthing13:01:27

I guess there's really no function in Clojure core that does (awesome-fn :id [{:id 1 :last-name "Doe" :first-name "John"} {:id 2 :last-name "Doe" :first-name "Jane"}]) => {1 {:id 1, :last-name "Doe", :first-name "John"}, 2 {:id 2, :last-name "Doe", :first-name "Jane"}}? I know about set/index and group-by, but I'd like the val to be a single value instead of a sequence of values.

flowthing13:01:07

Not that there's any problem in implementing it yourself — just wondering…

rauh13:01:34

(into {} (map (juxt :id identity)) ...) should work

flowthing13:01:56

That's pretty compact — thanks!

dpsutton13:01:45

that will clobber duplicate id keys. if you have the possibility of multiple id keys you can just use `group-by :id ...~

flowthing13:01:17

Yes, I know, but in my case the key is unique.

dpsutton13:01:41

i figured. just making sure

tomaas13:01:53

hi, is there a way to compile a single source file to a .class file and run it just like it were compiled with java java file.class (and not java -cp target/classes:clojure-1.8.0.jar file.core) ?

manutter5114:01:49

You can make an executable jar file.

tomaas14:01:29

i know, but there is a tool that just accepts plain .class files, that's why I started wondering

pfeodrippe14:01:49

Hi, guys, how could I write a Java 8 lambda function like in

stream.filter((key, value) -> value > 0);
with Clojure? Should I reify something or the Clojure 1.9.0 function implementation just works?

manutter5114:01:24

Ah, well clojure does compile down to .class files, but it's like one .class for every function, not sure how useful that would be in this case.

vemv14:01:06

Wondering if transducers can make the typical ->> transformations more efficient, without drastically reshaping them / making me think i.e., given code in the shape (->> [1 2 3] (map inc) (map str)), is there always a transducer equivalent that will avoid intermediate collections? that transducer equivalent being machine-writable, e.g. I can just have an emacs keybinding

Alex Miller (Clojure team)14:01:30

and they are not the same - there are cases (like mapcat) where you could stumble into drastically different behavior

martinklepsch14:01:50

So seems that the easiest way to make sure all nested seqs are realized is (clojure.walk/prewalk identity some-data)

vemv14:01:33

thanks Alex!

fantomofdoom16:01:26

Some one use Quasar\Pulsar in clojure or it outdate?

josh_tackett16:01:38

What's the best way to create a worker threadpool?

hiredman17:01:16

java.util.concurrent.Executors/newFixedThreadPool

boogie66617:01:34

Hello, does anybody know any lib that does nearest neighbor?

grzm17:01:12

I'm trying to create a portable version of ns-interns: the Clojure version takes a namespace, and the ClojureScript version takes a quoted symbol. My thought is to create something like

(defn ns-interns* [ns-sym]
  (ns-interns #?(:clj (find-ns ns-sym)
                 :cljs ns-sym)))
And called like (ns-interns* 'com.example.ns). The Clojure version works fine. I can't figure out how to quote the value of ns-sym (which is a symbol) for the ClojureScript version.

grzm17:01:45

(quote ns-sym) of course returns 'ns-sym, rather than 'com.example.ns. I'm open to changing the argument type of ns-interns*.

noisesmith18:01:00

@grzm clojure ns-interns accepts a symbol

penguin.tracking=> (ns-interns 'user)
{clojuredocs #'user/clojuredocs, help #'user/help, le #'user/le, find-name #'user/find-name, non-macros #'user/non-macros, lf #'user/lf, src-dir #'user/src-dir, with-use #'user/with-use, user.proxy$java.lang.Object$SignalHandler$d8c00ec7 #'user/user.proxy$java.lang.Object$SignalHandler$d8c00ec7, l #'user/l, all-debugged #'user/all-debugged, cdoc #'user/cdoc, exercise-coverage #'user/exercise-coverage, ll #'user/ll, set-debug #'user/set-debug, unset-debug #'user/unset-debug, apropos-better #'user/apropos-better}

noisesmith18:01:07

@grzm if what you have is a symbol, you don’t need to quote it, quoting is an operation in the reader, to ensure you get the form itself (in this case a symbol) instead of the evaluated result of the form (which would be something in scope with that binding, or an error)

noisesmith18:01:19

if what you have is a symbol, you’re done, no special operation required at that point

hiredman18:01:20

ns-interns in clojurescript is likely a macro

hiredman18:01:43

clojurescript doesn't have a reified namespace system at runtime

hiredman18:01:00

so you are not going to be able to invoke ns-interns on a symbol not known until runtime (a symbol passed in as a function argument)

grzm19:01:44

@noisesmith thanks. That saves me the find-ns call.

itaied19:01:17

For those who use spec, do you test the specs? Both the maps and the predicates?

seancorfield19:01:05

@itaied What do you mean by "test the specs"?

seancorfield19:01:46

I usually try to have specs that I can s/exercise which means they need to generate -- which isn't always possible (or sometimes is just a lot of work). Depending on exactly what I'm writing a spec for, I'll sometimes run a few sample s/conform calls via the REPL. But in some ways, the specs are the tests -- so it's sort of like asking "how do you test your tests?"...

itaied19:01:01

Some things that come to my mind are "is the email regex works correctly?" "Does the ::name in the user map is required?" etc... And yes it does actually sound like testing your tests, I just feel like writing just the specs leave me vulnerable for mistakes that may happen in future changes

seancorfield19:01:29

That's true of any system you use to specify the expected behavior of your code tho'... unit tests, specs...

seancorfield19:01:08

Even if you used formal methods to specify your system, you still have the question "What if I made a mistake in my formal definition?"

seancorfield19:01:35

I don't see how writing specs makes you any more vulnerable than writing unit tests...?

noisesmith19:01:22

I think an important part of any verification system you use is integrating information from runtime regressions - so if there’s a bug in production that slipped past a test (or caused by a test being misguided), the resolution should include verifying the system now handles that case correctly

noisesmith19:01:06

your system is turing complete, it’s about making it as useful as possible, because there will always be some case that sneaks through

itaied20:01:54

@seancorfield So do you test your predicates or use generative testing? I can't really find a way to test the specs in any other way other than unit tests... As for functions that uses the specs I understand generative testing, it's just the docs doesn't mention verifying the specs themselves

noisesmith21:01:57

my M.O. is to find an example of data the spec should reject, and write an example based test that verifies the test rejects that input

noisesmith21:01:13

(in a unit test, that is)

noisesmith21:01:39

(I’m using prismatic/schema at the moment and not spec, but that’s how I’d do it)

seancorfield21:01:29

@itaied I work with a live REPL all the time, so I'm constantly evaluating code as I write it. I tend to use (comment ...) forms containing scratch expressions I write along the way to verify behavior of actual production or test code, and leave them in the code if they provide a useful crumb trail of how I arrived at my final solution.

seancorfield21:01:36

So as I develop a spec, I tend to be evaluating forms using that spec as a "live" sanity check: maybe a s/conform call, maybe a s/exercise call, maybe just some notes in code form.

seancorfield21:01:10

That work in the live REPL is not "unit testing" but code that I've evaluated might become unit tests at some point (or might become production code). It's a flow, a process. There's no real distinction into "phases" which is what your question seems to imply.

kenrestivo22:01:34

i opened this ticket in october, apparently it was a stumper. anyone else tried to get cloverage to cope with dynamic vars and reader literals? https://github.com/cloverage/cloverage/issues/197

kenrestivo22:01:12

TL;DR: this causes cloverage to die: (clojure.edn/read-string {:readers data-readers})

kenrestivo22:01:20

i feel like i might be doing something obviously wrong here tho

hiredman22:01:41

there is nothing in that stacktrace that would indicate the code in the ticket

hiredman22:01:28

my guess is cloverage is intercepting code reading (so it can instrument code), and is calling tools.reader without passing in *data-readers*

hiredman22:01:19

clojure.tools.reader has its own *data-readers* var too

kenrestivo22:01:13

makes sense. any ideas how ot hack around it?

kenrestivo22:01:09

i'm guessing either nobody uses cloverage, or nobody uses datomic, or nobody uses cloverage and datomic together