Fork me on GitHub
#beginners
<
2017-08-03
>
sundarj00:08:21

now i think about it, core is a silly name

sundarj00:08:26

think i'll start going with either main or orchestration

mobileink00:08:23

there's also martha and bigly

mobileink00:08:15

gloria is good

sundarj00:08:28

(ns app.mastermind) is tempting

mobileink00:08:59

hah! mini-me?

sundarj00:08:15

app.fuhrer

sundarj00:08:45

or app.stepmother

sundarj00:08:00

not sure which is more terrifying

mobileink00:08:04

don't wana get political, but the name of a certain POTUS comes to mind. might work. or not.

sundarj00:08:22

(ns app.impotus)

sundarj00:08:54

then if the fbi comes a-knockin you can just pass it off as a typo

mobileink00:08:45

blame the editor. "my .emacs was confused"

mobileink00:08:09

(time to migrate to #off-topic methinks šŸ˜‰ )

sundarj00:08:46

we toed the line there

urbanslug07:08:54

Anyone know how I can simplify this any further? Feels wonky

(when format
     (when data-id (str "/" data-id))
     (str "." format))

zilti08:08:08

Well, right now you're throwing away the value of (when data-id (str "/" data-id))

urbanslug08:08:45

Only when data-id is falsey

zilti08:08:52

No, also when it is true. When format is falsey, you get nil, else you get (str "." format)

zilti08:08:44

when always returns the result of the last expression it has

urbanslug08:08:06

yes but only when format is truthy. There are cases when format is truthy and data-id is falsey

urbanslug08:08:18

I didnā€™t know that one

zilti08:08:57

I guess you want to put it together into one string then?

urbanslug08:08:50

(when format
   (str (when data-id (str "/" data-id))
   (str "." format)))

urbanslug08:08:58

Feels stupid

urbanslug08:08:24

(when format (str (when data-id (str "/" data-id)) "." format))

urbanslug08:08:47

Itā€™s making a url

zilti08:08:53

you'd have to do ` (when format (str (if data-id (str "/" data-id) "") "." format))

urbanslug08:08:08

no need for the if ā€œā€ because the nil when passed to string will return the same thing

urbanslug08:08:42

Thanks for the ā€œ`when` always returns the result of the last expression it hasā€

urbanslug08:08:48

Seems so obvious when read

zilti08:08:18

yw šŸ™‚

foamdino11:08:17

does anyone have experience of using the nebula.clojure gradle plugin to build a clojure project?

gdeer8120:08:05

beginner performance question: I want to lazily process a collection of numbers but my code needs the sum of all the numbers so it can do its job so unless there is some clever math trick that I haven't thought of it looks like I have to populate the entire collection

noisesmith20:08:37

feed a reduce with a lazy-seq

noisesmith20:08:48

you donā€™t need to realize more than one of the inputs at a time

noisesmith20:08:12

(reduce + 0 (map some-processing-fn input))

noisesmith20:08:48

see also transduce if you need to make it perform slightly better

noisesmith20:08:20

(transduce (map some-processing-fn) + 0 input) - almost the same, less wasteful internals

noisesmith20:08:38

(but here the difference is very minor)

gdeer8121:08:47

sorry, every time I tried to write this gist someone would come up and interrupt me with work. This gist might illustrate what I'm trying to do a little bit better https://gist.github.com/gdeer81/0a3254afa21c853c87a0635e09063504

noisesmith21:08:32

canā€™t you add an extra data slot in your accumulator and do the sum in the reduce?

noisesmith21:08:48

that avoids needing to hold onto the head of coll, which is a problem

noisesmith21:08:29

so instead of your acc being [] it would be {:coll-sum 0 :result []} and you update both on each iteration

noisesmith21:08:17

oh wait do you need to know that sum before any item is processed?

noisesmith21:08:31

yeah, thatā€™s trickier

noisesmith21:08:59

but is coll always just the numbers? if so just use range and call it each place you need it

noisesmith21:08:12

instead of holding onto it in one place

noisesmith21:08:10

the numbers are cheap enough to just generate them twice using range - the extra work to put them into a collection you reuse (which range wonā€™t do inside reduce btw) is more expensive than getting the numbers is

noisesmith21:08:37

(which is why to use range instead of iterate)

gdeer8121:08:52

so in the for loop just call range?

noisesmith21:08:01

right, call range in both places

noisesmith21:08:07

never bind the numbers

noisesmith21:08:24

perhaps make a thunk like #(range 1 (inc n)) and call it in each place you currently use coll

noisesmith21:08:45

that way you arenā€™t holding onto head, which is the problem with huge n here

noisesmith21:08:31

also, for certain values of ā€œhugeā€ you might need +' and *' to replace + and *

gdeer8121:08:54

so I've done all that and I've even added some type hints and it's only shaved about 400 milliseconds off the processing time

noisesmith21:08:47

+' and *' slow down the math - they would be for correctness on numbers too big for a Long

gdeer8121:08:49

I feel like I'm missing something important about the problem that is the key to not having to code it like this

noisesmith21:08:27

well, thereā€™s always not trying to do number crunching in fp, some people swear by that one

noisesmith21:08:19

but in all seriousness I bet thereā€™s some more simple stuff we can do - try checking for warn-on-boxed for example http://insideclojure.org/2014/12/15/warn-on-boxed/

noisesmith21:08:02

but beyond a certain point it does get easier to do your number crunching in java and use interop compared to the tricks needed to get clojure to behave

seancorfield22:08:53

@gdeer81 The sum of a series of numbers from 1-n is half of n squared minus n or (/ (* n (dec n)) 2)

gdeer8122:08:14

@seancorfield I knew there was a magic formula I was missing, thank you šŸ¼

seancorfield22:08:32

Glad my BSc in Math from '83 is useful for something šŸ™‚

seancorfield22:08:44

What sort of timings are you getting for what sort of numbers?

sundarj22:08:11

@seancorfield @gdeer81 i believe you're misremembering the formula:

boot.user=> (reduce + (range 1 101))
5050
boot.user=> (/ (* 100 (dec 100)) 2)
4950
boot.user=> (* (inc 100) (/ 100 2))
5050

sundarj22:08:46

ah,

boot.user=> (/ (* 100 (inc 100)) 2)
5050
is correct

seancorfield23:08:01

Ah, I'd already incremented n to produce the range that @gdeer81 needed

seancorfield23:08:45

I refactored after that so I have (/ (* n (inc n)) 2) now so we agree šŸ™‚

sundarj23:08:04

fair enough! šŸ˜€

noisesmith23:08:38

@seancorfield I wonder if it would speed things up at all to turn that into into / filter

noisesmith23:08:50

since itā€™s effectively that

noisesmith23:08:33

also, if it remains a reduce, it should speed up a little if you hold onto the second arg to the fn and reuse it instead of creating another vector

noisesmith23:08:59

but the into/filter transducer would probably be more straightforward anyway

noisesmith23:08:21

(into [] (filter (fn [[^long num1 ^long num2]] (= (- coll-sum num1 num2) (* num1 num2)))) (for ...))

seancorfield23:08:39

Duh, don't need the reduce at all -- could use :when in the for...

seancorfield23:08:00

That's 650ms for 3003

noisesmith23:08:05

wait what about the incsā€¦

noisesmith23:08:36

I think they should be taken out of the vector now

seancorfield23:08:33

Doesn't make much difference to the timing at that point

seancorfield23:08:08

And if you take out the doall then it's lazy as well which might be useful. I just did that for timing.

seancorfield23:08:30

(I ran it with :warn-on-boxed to be sure there was no boxing -- there wasn't)

noisesmith23:08:36

itā€™s amazing how many warnings spill out just removing the ^long annotation on line 1

seancorfield23:08:23

Ah, I should have (set! *unchecked-math* :warn-on-boxed) above the function! I use it so rarely I forget how...

seancorfield23:08:52

That's better... down to 283ms for 3003!

seancorfield23:08:19

Updated the snippet...

seancorfield23:08:17

So I think that's down from 4 seconds for the original I saw to sub-300ms?

seancorfield23:08:09

I think @gdeer81 has gone home for the evening...

seancorfield23:08:24

@noisesmith Can you speed that up further?

noisesmith23:08:27

heh, itā€™s all good, the process is informative for us all anyway

noisesmith23:08:48

my first few tries are not improving it

noisesmith23:08:20

haha, binding inc n to a new symbol and reusing it instead of incrementing inline slows the code down - just a bit, but less than the std-deviation as calculated by criterium

gdeer8123:08:28

Yes I am still in transit