Fork me on GitHub
#clojure
<
2016-08-18
>
csm00:08:32

(/ 100 0.0) apparently calls clojure.lang.Numbers.divide(JD)D, which has no check for zero https://github.com/clojure/clojure/blob/clojure-1.8.0/src/jvm/clojure/lang/Numbers.java#L3803

gfredericks00:08:01

it sounds like a bug to me

seancorfield01:08:51

I see

boot.user=> (/ 100 0)

java.lang.ArithmeticException: Divide by zero
boot.user=> (/ 100 0.0)
Infinity
boot.user=> (/ 100.0 0)
Infinity
boot.user=> (/ 100.0 0.0)
Infinity
which seems reasonable to me — floating point divide (the last three cases) by zero produces Infinity; integer divide (only the first case) produces an exception.

seancorfield01:08:10

(that’s on Clojure 1.9.0 Alpha 10)

oahner01:08:51

the interesting behavior is what happens if you define (def bla 0.0) and then (/ 100 bla)

oahner01:08:08

one path chooses integer division, the other doesn't

oahner01:08:28

so division by zero behaves differently if the zero is a literal or not

seancorfield01:08:33

Indeed… that is… odd:

boot.user=> (def a 0)
#'boot.user/a
boot.user=> (def b 0.0)
#'boot.user/b
boot.user=> (/ 100 a)

java.lang.ArithmeticException: Divide by zero
boot.user=> (/ 100 b)

java.lang.ArithmeticException: Divide by zero
boot.user=> (/ 100.0 a)
Infinity
boot.user=> (/ 100.0 b)
Infinity

seancorfield01:08:19

I assume the analyzer must be promoting the first argument if it can determine the second one is double not long?

seancorfield01:08:47

boot.user=> (/ 100 ^double b)
Infinity
boot.user=> (/ 100 ^double a)
Infinity

oahner01:08:04

it doesn't seem to matter which argument is a literal

oahner01:08:20

does the same thing if you put 100/100.0 in a variable

oahner01:08:04

something in the analyzer must be able to take a shortcut if it knows ahead of time it'll be doing number division instead of integer division

csm01:08:21

from a class disassembly, if the second arg is a result of get or in a var, it’s just an Object, so it goes to https://github.com/clojure/clojure/blob/clojure-1.8.0/src/jvm/clojure/lang/Numbers.java#L155

csm01:08:07

it’s hard to say that the divide(long,double) variant is wrong per se, but I can see this causing someone confusion, if they say tried to replace a constant with a var

oahner01:08:52

indeed; isn't it possible to change the FPU's behavior around exceptions?

oahner01:08:34

I would have thought the JVM would take care of raising that exception, not clojure

oahner01:08:04

so I grep'd my project for korma.core/exec-raw calls and converted those queries to honeysql syntax; so far it worked with everything

oahner01:08:21

very impressed with it

richiardiandrea01:08:26

A question, is there a way to use a function as generator in test.check?

richiardiandrea01:08:09

something that returns a generator that repeatedly calls the input (no-arg) function

richiardiandrea02:08:09

it is not return because I need it to call my function for fetching the value

oahner02:08:57

hmm, fmap?

richiardiandrea02:08:30

but fmap wants a function and a generator right?

richiardiandrea02:08:12

so I just pass a random generator that I ignore in the function f?

oahner02:08:06

I think that might do the trick

richiardiandrea02:08:20

(tcgen/fmap (fn [_] (eutils/timestamp-now)) tcgen/does not matter)

richiardiandrea02:08:27

ok I am trying, thanks!

oahner02:08:31

your fmap-created generator will still depend on the original generator you're passing in the second argument for it's size tho

oahner02:08:47

so it does matter a bit

richiardiandrea02:08:57

(tcgen/generate (s/gen ::timestamp {::timestamp (tcgen/fmap (fn [_] (eutils/timestamp-now)) tcgen/large-integer)}))

richiardiandrea02:08:10

I might be missing something ^

richiardiandrea02:08:36

it does not seems to work like that

richiardiandrea02:08:49

clojure.test.check.generators.Generator cannot be cast to clojure.lang.IFn

oahner02:08:08

s/gen is from where?

richiardiandrea02:08:16

I am following examples but there must be some trivial mistake

oahner02:08:45

the fmap part looks valid to me

oahner02:08:50

the rest, I can't tell

oahner02:08:24

lemme get a 1.9 project running

richiardiandrea02:08:31

thanks a lot for your pair of eyes anyways 😄

oahner02:08:40

alright, I got the same error

gfredericks02:08:21

@richiardiandrea why do you want to do this?

richiardiandrea02:08:47

@gfredericks: just to have a consistend timestamp with the current time generated

richiardiandrea02:08:15

I am open to other ways of course

gfredericks02:08:20

why are your tests sensitive to the current time?

richiardiandrea02:08:55

good question! they are not

richiardiandrea02:08:13

i just wanted to see if I could do the same thing as in schema

gfredericks02:08:38

what's schema?

richiardiandrea02:08:01

they actually apply a little trick (first time I look at the source)

gfredericks02:08:33

now I'm more confused

gfredericks02:08:06

so in general you don't want to make generators using actually-random functions

gfredericks02:08:22

because then you lose test.check's determinism and its shrinking capabilities

gfredericks02:08:53

if you really really needed the current time in your test, I would say treat that the way you would any IO in tests, and don't make it part of the generator

richiardiandrea02:08:23

yeah it was just out of curiosity...I will revert to good engineering in 10 minutes 😄

gfredericks02:08:40

is there some capability of schema's generators that you're trying to emulate?

richiardiandrea02:08:41

in any case the above does not work

richiardiandrea02:08:07

the link I sent, g-by allowed me to do (def url-gen (sgen/g-by #(str image-url "/test-" (rand-int 1000))))

richiardiandrea02:08:26

so passing a function there with no args, no other input

richiardiandrea02:08:14

I copied the code of function, it does not seem to work anymore...but it's not a big deal

gfredericks02:08:02

(gen/->Generator (fn [_ _] (clojure.test.check.rose-tree/pure __get-a-value-somehow__))) #donttrythisathome

gfredericks02:08:14

#strictlyforYOLOpurposesonly

oahner02:08:53

s/gen doesn't take a map of generators, it takes a map of functions that returns a generator

richiardiandrea02:08:12

oooooooooooooooooooh facepalm

oahner02:08:02

anytime ^^

richiardiandrea02:08:02

I think I need to call it a day

richiardiandrea02:08:13

after this one 😄

oahner02:08:35

don't worry, I read the function's docstring twice and still had dig deeper to find the issue, lol

richiardiandrea02:08:57

I read it too a couple of times...now everything works as expected

gfredericks02:08:01

I suppose fmaping with an impure function is a much easier way to do that isn't it

richiardiandrea02:08:38

yes @gfredericks is now: {::timestamp #(tcgen/fmap (fn [_] (eutils/timestamp-now)) tcgen/large-integer)}

gja02:08:39

@bg: you awake?

csm04:08:52

wrt the (/ 100 0.0) thing from earlier, there is already a (old) bug on that: http://dev.clojure.org/jira/browse/CLJ-1142

seancorfield04:08:16

Thanks @csm -- good to know there's an existing JIRA issue.

seancorfield04:08:53

As you said in your comment, it does seem to be a bit of an edge case in practical terms, even tho' it's definitely weird.

dpsutton04:08:29

i'm looking in the clojure.zipper code. Zippers store lots of information in meta. Is this a common paradigm? Seems unique to me at first glance

seancorfield04:08:20

I wouldn't say unique but I think it's uncommon...

freakynit06:08:31

I'm new to clojure. Was reading through clojure.spec to write specs for existing clojure codebase. Any guidelines on organizing the specs?

eggsyntax12:08:04

@freakynit: in terms of putting specs with the code they spec vs in separate files?

freakynit13:08:11

Yes, what would be more appropriate, with code, or separate file for specs?

Alex Miller (Clojure team)13:08:54

I think both can be appropriate. For clojure.core we’re putting them in clojure.core.specs. Sean put them in a separate namespace in java.jdbc to make them optional so as to support backwards compatibility to older versions of Clojure.

Alex Miller (Clojure team)13:08:03

I also think putting them with the code is fine in other cases.

Alex Miller (Clojure team)13:08:41

“domain” type data specs are probably a good fit for a separate file whereas function specs might be better with the code in some cases

Alex Miller (Clojure team)13:08:29

some care does need to be taken in terms of dependency cycles if you have specs built on predicates etc

jstokes13:08:20

thanks for the JIRA link @csm!

roberto19:08:23

that seems to be broken

roberto19:08:32

it depends on an old version of schema

roberto19:08:39

that doesn’t work anymore

pesterhazy19:08:12

a prismatic schema is just a data structure

pesterhazy19:08:22

what do you want to do with it?

roberto19:08:33

print out readable errors

roberto19:08:44

i imagine there are some libraries out there that do this

roberto19:08:18

for example: (chk {:foo 42,:bar "bar”}) => {:foo “42 is not a string”}

roberto19:08:05

the issue with integrity is that it depends on a very old version of schema

pesterhazy19:08:09

hm yeah that'd be nice

roberto19:08:21

and it won’t build with newer versions (1.0.0 and newer)

timgilbert20:08:03

FWIW, it looks as though the author has begun work on upgrading schema and has a branch in progress: https://github.com/cddr/integrity/issues/16#issuecomment-218929014

roberto20:08:06

yeah, I saw that

arohner20:08:58

Is there a way to pass a class as a variable in a java static field invoke? i.e. (def c Integer) (.-MIN_VALUE c)?

arohner20:08:17

to answer my question, yes, using the reflection API

timgilbert21:08:04

Say, is there a Clojure version of java.util.LinkedHashSet, eg a set that retains insertion ordering?

timgilbert21:08:46

(I suppose I can just use a vector or something easily enough, I'm just curious)

timgilbert21:08:54

Ah, found https://github.com/amalloy/ordered which has an implementation

kaosko21:08:47

hey all, is there really no function that "forces" a value to a certain range? i.e. something like (to-range 2 5 6) => 5

lfn322:08:50

@timgilbert: If your keys in a set contain some sort of timing information you can use that in sorted-set-by

credulous22:08:56

Hey gang… newb with lots of reading done, completed 4clojure, but no actual projects. I have an experiment I want to run and I’d like to use clojure but I don’t know if it’s suitable. Is it appropriate to ask for advice on that?

credulous22:08:44

I want to fool around with neural nets for sentiment analysis - the plan is to record a bunch of tweets from the streaming twitter api, tagging tweets based on hashtag. I’ll have 10 or 15 happy hashtags (#blessed, #thrilled, etc) and some negative ones (#angry, #frustrated, etc) and tag the tweet accordingly.

credulous22:08:50

Then use that data to train a neural net.

credulous22:08:48

I could write the code to collect the data from Twitter in about an hour in go, javascript, or python. It will probably take me 2 days in Clojure. 🙂

credulous22:08:38

It’s worth it to me, if Clojure is an appropriate tool for this kind of experiment. But if it’s the wrong tool for the job, I should wait for another opportunity. Opinions on that? Clojure for reading streaming data from Twitter?

arrdem22:08:45

There exist a couple libraries which wrap the Twitter streaming APIs, but they weren't amazing when last I looked at them and they certainly predate core.async or most of the "modern" clojure streaming tooling.

quoll22:08:25

@kaosko: you could use (defn to-range [bottom top v] (min top (max bottom v))) but I like something that returns a function: (defn to-range-fn [bottom top] (comp (partial min top) (partial max bottom))) (def range-2-5 (to-range-fn 2 5)) (range-2-5 6) => 5

kaosko23:08:21

thanks @quoll. that's what I have but I just wanted to check.. so many times I write a utility function only to find out later that one existed already in the core