Fork me on GitHub
#clojure
<
2018-08-29
>
aarkerio00:08:03

what the "#" means?

noisesmith00:08:26

generally, # introduces reader macros, #{} is a data literal for a set

aarkerio00:08:13

great, thanks a lot noisesmith

alexmiller02:08:26

Different angle on the same thing

john03:08:23

I was just noticing that in Clojure, when you reverse a vector before looping over it, it goes a little faster. πŸ™‚

john03:08:38

So does that mean that things like map might go faster on vectors if they always reversed them first, then looped on them from the tail backward, to get the original mapping order?

john03:08:57

Or does the speed increase only work the first time it's reversed?

john04:08:54

Or no, that's not a vector πŸ˜„

john04:08:53

Still, that's strange the reversals would cause speed ups

seancorfield05:08:42

@john range produces something very specific (not a vector, as you observed).

seancorfield05:08:45

I'd also say you're not getting accurate timings doing one-offs with time. Take a look at criterium for running benchmarks more reliably.

andy.fingerhut05:08:46

If you replace (range 10000) with (vec (range 10000)) to get an actual Clojure vector, it is significantly faster than either of the first two expressions you gave, according to a Criterium run, i.e. 200 to 300x faster.

andy.fingerhut05:08:36

Also, if you use Criterium and Leiningen, the default Leiningen REPL starts a JVM with command line options intended to speed startup time, at the likely expense of long-term optimizations that a JVM JIT can do for you.

aisamu16:08:24

Thanks for sharing that!

andy.fingerhut05:08:36

See the project.clj of this project for an example of how to make Leiningen not do that: https://github.com/jafingerhut/funjible-test-project/blob/master/project.clj#L15-L19

andy.fingerhut05:08:44

I agree the difference in access time between (range 10000) and (reverse (range 10000)) is a little weird, but maybe not a performance bug. (range 10000) I believe tries to save memory by calculating the entry values on demand.

henrik13:08:48

Yeah, range is lazy, so it makes more sense to use when you want to realize values one by one, on demand. Perhaps because you expect to only use a subset of them, or because it’s awkward to fit it all in memory at once.

urbanslug14:08:51

How do people get it on there?

urbanslug14:08:52

For say a docker container

urbanslug14:08:07

Hey, when I look at this https://pkgs.alpinelinux.org/packages it seems clojure isn't in the alpine repos

urbanslug14:08:25

How do people get it on there for a docker container

urbanslug14:08:29

clojure:alpine?

john14:08:33

is java on alpine?

john14:08:51

@andy.fingerhut @seancorfield @henrik yeah, I might crack open the ol' criterium and get a more solid picture of that reverse behavior

john14:08:24

@urbanslug I think some other common docker OS targets have clojure in their repos. It'd be awesome to have an alpine package though.

urbanslug14:08:57

I found clojure:alpine

urbanslug14:08:04

but I wanted more control

urbanslug14:08:07

this will do for now

john14:08:08

But, worst case, you could install java on there and then install clojure on top as part of a startup script... Ah

urbanslug14:08:34

you mean compile and install clojure on it?

urbanslug14:08:43

because it's not in the alpine repos

john14:08:56

naw bring the clojure jar into the docker as an external dep

john14:08:41

You could probably just rejigger the clojure install scripts from one of the other distros for alpine

urbanslug14:08:34

I was hoping to just apk add clojure > naw bring the clojure jar into the docker as an external dep

john14:08:36

But they also say you can just 'submit an issue' here https://bugs.alpinelinux.org/projects/alpine/issues and request it as a 'feature' and they may build it for you.

urbanslug14:08:50

hmmm but I'd have to maintain it. Ok I'll look into that. > Looks like this is one way to accomplish that: https://wiki.alpinelinux.org/wiki/Creating_an_Alpine_package

john14:08:53

If you manage to get clojure into the Alpine repos, that'd be awesome!

urbanslug15:08:58

hmm seems even clojure:alpine doesn't have clojure

pauld15:08:07

In case this helps, I had been testing my clojure app using gitlab-ci.

pauld15:08:20

Here is the begging of my yaml file:

urbanslug15:08:48

hmmm lein comes with clojure?

urbanslug15:08:00

I'm going a different path which seems to work

ghadi15:08:09

want to redirect this stream to #docker ?

urbanslug15:08:31

I didn't know it existed

pauld15:08:15

lein deps puts clojure in the java classpath using maven

urbanslug16:08:32

hey @john you could use clojure:tools-deps-alpine as a base image

noisesmith16:08:03

I found it very useful to make a custom docker image, otherwise you always redownload your deps on startup

delaguardo16:08:52

Or you can mount your local .m2 with the container. docker run -v $HOME/.m2:/root/.m2 clojure:tools-deps ...

noisesmith16:08:45

that doesn't work optimally with my company's specific marathon based infrastructure where nodes get recycled, but yeah, that can help too

urbanslug16:08:01

I noticed this and I'm thinking of caching ~/.m2 > I found it very useful to make a custom docker image, otherwise you always redownload your deps on startup

urbanslug16:08:26

What about CI? > Or you can mount your local .m2 with the container. docker run -v $HOME/.m2:/root/.m2 clojure:tools-deps ...

delaguardo17:08:25

Depends on your service. In circleci it is about adding save_cache directive with a key prefixed with check sum of deps.edn

kaosko23:08:55

I'm using chime-at, which periodically calls an fn. it doesn't accept a collection of fns. how would I be able to alternate between two different fn calls?

hiredman23:08:52

(defn alt [f1 f2]
  (let [a (atom false)]
    (fn []
      (if (swap! a not)
        (f1)
        (f2)))))

hiredman23:08:06

true might be a better initial value for atom

kaosko23:08:29

sure, but I feel like I shouldn't need to use an atom, but just couldn't figure out a way to create an infinite seq of fns that gets executed one by one

hiredman23:08:57

cycle and interleave

hiredman23:08:11

or repeat and interleave

hiredman23:08:27

but you need mutable state

hiredman23:08:37

because you want a function to do something different each time you call it

kaosko23:08:22

ok yeah kinda wanted a confirmation for that. thanks @hiredman