Fork me on GitHub
#clojure
<
2017-01-24
>
bbloom00:01:52

@pelletier the whole point of with-redefs is that it’s not thread-local. all vars would be :dynamic by default if it were fast enough

pelletier00:01:49

gotcha. i reckon the actual way to go is to encapsulate away our side effects and avoid the redefs (or binding) altogether

bbloom00:01:04

sounds like a solid plan 🙂

bostonaholic00:01:55

@pelletier that should always be the goal 😜

seancorfield01:01:49

If there’s anyone here who uses Expectations and isn’t already in the #expectations channel, I just announced there that work on adding “`clojure.test` compatibility” will start this week (with a link to the GitHub issue discussing it). If you are interested in that, please either join #expectations or read / watch the GitHub issue (#82).

bcbradley03:01:42

Is there anything to watch out for when using clojure recur?

bcbradley03:01:18

I can't remember where I read it, or maybe i'm just remembering, but for some reason I recall something about clojure recur not being nestable

bcbradley03:01:51

for instance if i had two async/go-loop, one inside the other, can that actually work?

bcbradley03:01:20

(I know it sounds odd to have something like that, but the question still stands)

bfabry03:01:28

@bcbradley you probably can't have them inside each other in the same lexical scope, as which recur would recur refer to in that scenario?

bcbradley03:01:59

when it says "provides the recur special operator, which does constant-space recursive looping by rebinding and jumping to the nearest enclosing loop or function frame" at https://clojure.org/about/functional_programming is that precise?

bcbradley03:01:09

i mean, is it literally true?

bcbradley03:01:36

if so i guess i don't have a problem

bfabry03:01:41

oh there you go, nearest. so I'm wrong. seems like it works fine

qqq07:01:28

does java have a notion of "with-current-directory" where it (1) goes into the dir (2) execs some stuff, then (3) pops out? or do I have to manage the directory stack myself?

beppu07:01:42

@borkdude I just realized I caught the wrong exception. I created a new problem instead of catching the orignal problem. I will keep looking at xml/parse-str.

qqq07:01:40

@beppu: thanks! In that case, is it possible to say "execute this shell command, with the current directory as" ?

qqq07:01:56

so I'm no longer requiring to change the wrking direcotry of my entire jvm; I just want a particular shell command to be executed with the working directory being something else

qqq07:01:09

what's all I need, three arg exec ftw

beppu07:01:26

@qqq I was playing around in the repl and this worked for me: http://stackoverflow.com/a/38517391/493051

(use '[clojure.java.shell])
(sh "ls")
(binding [*sh-dir* "/usr"] (sh "ls"))

prakhar07:01:28

Hey everyone, I’ve been trying to make a simple game, but stuck at this step. I’m trying to return a new state in the following way, but doing this causes the game to be really slow.

prakhar07:01:10

I thought that the m x n for loop is the problem but the other example, seems to suggest that this isn’t the case. In idea what’s wrong?

cgrand08:01:09

Try wrapping you for in a (into [] …).

prakhar08:01:08

Tried, still the same issue.

cgrand08:01:10

ok so it’s not too many levels of laziness

cgrand08:01:55

when you say it’s slow, one iteration is slow or it slows down as the game progresses?

prakhar08:01:21

@cgrand the slows down the game progress, so the game is like space invaders… as long as there’s one drop traveling the game, its fine.. but when it gets to two drops,, the game almost halts..

sgerguri08:01:39

@prakhar What does your intersect? function look like?

prakhar08:01:27

Oh, its a function that computes whether two circles intersect.

prakhar08:01:13

Even if I remove the :when clause in the for comprehension, the problem persists

cgrand08:01:58

could you trace state (or at least the number of items under keys :flowers and :drops)?

prakhar08:01:26

Sure.. 6 flowers and 2 drops

prakhar08:01:34

6 flowers, and 1 drop seems to work fine

sgerguri08:01:30

Really silly suggestion but can you try 12 flowers and 1 drop?

arttuka08:01:19

if you have multiple drops, the number of flowers multiplies on each iteration

arttuka08:01:58

because you’re doing (for [f flowers, d drops] ,,,)

arttuka08:01:25

if you have 6 flowers and 2 drops at the start, first iteration gives you 12 and 2, then 24 and 2, then 48 and 2

prakhar08:01:25

Tried with 18 flowers 1 drop - works fine

arttuka08:01:38

the number of flowers grows exponentially if you have more than one drop

arttuka08:01:51

because it duplicates each flower for each drop

arttuka08:01:59

when you call that function

prakhar08:01:14

i was trying to do a nested for loop (like you’d do in C)

prakhar08:01:44

basically - test each flower / drop intersection

rauh08:01:34

I'd use a (update state :flower (fn [f] (keep #(... intersect ...) f)))

prakhar08:01:05

what does the keep do?

rauh08:01:31

Throws out any nils

rauh08:01:23

Combine with some in the inner function, that way you stop as soon as it interesct

prakhar08:01:59

wow! this works @arttuka

prakhar09:01:13

can you please explain what was wrong with my previous code?

arttuka09:01:30

does this explain the problem?

(for [f [1 2 3 4 5]
      d [:a :b]]
  f)
=> (1 1 2 2 3 3 4 4 5 5)

prakhar09:01:04

ahh okay.. now i see

prakhar09:01:00

Also, now if i want to keep both the drops and the flowers that dont intersect, is there a better way than calling that for loop twice?

kurt-yagram09:01:15

Here's something weird (well, to me, it's weird)... I have a line: (satisfies? clojure.core.async.impl.protocols/ReadPort ch) in my code that does work when I run my code normally (`boot run`). However, when I do check-sources, throws an error:

$ boot check-sources
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: clojure.tools.analyzer.utils, being replaced by: #'clojure.tools.analyzer.utils/boolean?
WARNING: boolean? already refers to: #'clojure.core/boolean? in namespace: clojure.tools.analyzer, being replaced by: #'clojure.tools.analyzer.utils/boolean?
             clojure.lang.ExceptionInfo: java.lang.ClassNotFoundException: clojure.core.async.impl.protocols, compiling:(...)
    data: {:file "/tmp/boot.user5239864754805408740.clj", :line 63}
clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: clojure.core.async.impl.protocols, compiling:(...)
       java.lang.ClassNotFoundException: clojure.core.async.impl.protocols
                                              ...                      
                             clojure.core/load/fn        core.clj: 5893
                   clojure.core/load/invokeStatic        core.clj: 5892
                                clojure.core/load        core.clj: 5876
                                              ...                      
               clojure.core/load-one/invokeStatic        core.clj: 5697
                            clojure.core/load-one        core.clj: 5692
                         clojure.core/load-lib/fn        core.clj: 5737
               clojure.core/load-lib/invokeStatic        core.clj: 5736
                            clojure.core/load-lib        core.clj: 5717
                                              ...                      
                  clojure.core/apply/invokeStatic        core.clj:  648
              clojure.core/load-libs/invokeStatic        core.clj: 5774
                           clojure.core/load-libs        core.clj: 5758
                                              ...                      
                  clojure.core/apply/invokeStatic        core.clj:  648
                clojure.core/require/invokeStatic        core.clj: 5796
                             clojure.core/require        core.clj: 5796
                                              ...                      
  yagni.namespace/prepare-namespaces/invokeStatic   namespace.clj:   14
               yagni.namespace/prepare-namespaces   namespace.clj:    7
yagni.core/construct-reference-graph/invokeStatic        core.clj:   32
             yagni.core/construct-reference-graph        core.clj:   26
                                              ...                      
                     pod$eval1107$fn__1108.invoke  NO_SOURCE_FILE      
                        pod$eval1107.invokeStatic  NO_SOURCE_FILE      
                              pod$eval1107.invoke  NO_SOURCE_FILE      
                                              ...                      
                   clojure.core/eval/invokeStatic        core.clj: 3105
                                clojure.core/eval        core.clj: 3101
                                boot.pod/eval-in*         pod.clj:  437
                                              ...                      
                                boot.pod/eval-in*         pod.clj:  440
        tolitius.checker.yagni/check/invokeStatic       yagni.clj:   36
                     tolitius.checker.yagni/check       yagni.clj:   33
             tolitius.boot-check/eval257/fn/fn/fn  boot_check.clj:   44
                              boot.core/run-tasks        core.clj:  938
                                boot.core/boot/fn        core.clj:  948
              clojure.core/binding-conveyor-fn/fn        core.clj: 2019
It's not onlywith check/with-yagni but also on running check/with-kibit

kurt-yagram09:01:18

check/with-eastwood gives something similar:

Got exception with extra ex-data:
    msg='No such namespace: clojure.core.async.impl.protocols'
    (keys dat)=(:ns :form :file :end-column :column :line :end-line)
    (:form dat)=
^{:line 33} clojure.core.async.impl.protocols/ReadPort

ExceptionInfo No such namespace: clojure.core.async.impl.protocols
	clojure.core/ex-info (core.clj:4617)
	clojure.core/ex-info (core.clj:4617)
   ...
check/with-bikeshed seems to have problems finding datomic, I do get a bunch of: Unable to parse ...: java.io.FileNotFoundException: Could not locate datomic/api__init.class or datomic/api.clj on classpath., compiling:(...:1:1)

kurt-yagram09:01:31

so well, why is boot-check not finding some files/namespaces? (which seems to be the problem)

cgrand10:01:07

@kurt-yagram Try adding a :require [clojure.core.async.impl.protocols] to the ns form

cgrand10:01:32

it should help checkers figuring out this dep

kurt-yagram10:01:23

seems to work... funny. Thanks

kurt-yagram10:01:19

memoizing only after x times... here's the use case: there is a call that takes some time. However, after a number of calls, it stabilizes, meaning: the first few calls, the result changes, but after that, it's always the same. I only found out now 🙂. So, since it's a pretty heavy call, I memoized it:

(mem/lru fn
             (cache/ttl-cache-factory {} :ttl ttl)
             :lru/threshold max-in-cache)))
However, it would be better only to memoize it after x calls with the same arguments... any ideas of how to implement this?

kurt-yagram10:01:48

- or even better: changing ttl of an entry based on the number of times it's called.

cgrand10:01:08

Hmmm. What’s your function doing?

kurt-yagram10:01:12

it basically fetches data from external resources: I push data to an external resources, and from that moment, I can fetch a 'result' from it. The first few calls, the 'result' may still be changing, after about 3-5 calls, the 'result' is stable (enough for memoization)

Pablo Fernandez11:01:41

I need to have an variable in a profile and not I others so, I set it in profiles in project.clj but when I read it with environ it casts the boolean to string. What's the correct way of handling booleans?

igrishaev11:01:56

does anyone know how to dispatch any possible value in multimethods? I mean:

(defmethod foo [:some-val _ _])...
(defmethod foo [:some-val :bar _])...
(defmethod foo [:some-val :bar :baz])...

igrishaev11:01:18

the syntax with _ does not work

igrishaev11:01:19

talking more precisely, I have map with :name and :version fields. At first, I'd like to dispatch by the name, but in addition to be able to dispatch by version

pesterhazy11:01:39

that's not how it works

kurt-yagram11:01:39

you probably want to take a look at core.match

igrishaev11:01:45

if some specific version will break the rules

pesterhazy11:01:54

you need to specify an exact value to dispatch on in defmethod

kurt-yagram11:01:12

you seem to be looking at the wrong solution to your problem

igrishaev11:01:39

I know it uses hierarchies and isa?, I've read the code

kurt-yagram11:01:04

you can use hierarchies, right 🙂

pesterhazy11:01:37

I don't think I've seen hierarchies used in the wild

igrishaev11:01:02

How can I make _ to be the ancestor for "42.0.2"?

pesterhazy11:01:04

my advice is to start simple when you're writing your first multimethod 🙂

kurt-yagram11:01:21

(derive ::_ ::42.0.2) or something like that? Never use it...

igrishaev11:01:37

I wish good old scheme generics with predicates were here...

(defmulti (eq "some-name") (any?))....
(defmulti (eq "some-name") (eq? "42.0.3"))....

bronsa11:01:08

@igrishaev multimethod dispatch is not pattern matching

bronsa11:01:15

if you want pattern matching take a look at core.match

igrishaev11:01:56

@rauh that does not answer the question. @bronsa yes, that might work: pass a quoted pattern and then match it in dispatch

mpenet12:01:14

not the right tool for the job tho

lhmariano13:01:08

Hello! Good morning! I have a question. What is the best library of migrations in clojure?

mavbozo13:01:24

DB migration?

manutter5113:01:03

@lhmariano It depends what you want in a migrations library, but I’ve been pretty happy with migratus so far — part of the luminus web app stuff but could be used alone.

mavbozo13:01:21

i've use joplin for mysql and i have no complain so far

theblackbox13:01:33

anyone using Franzy? I'm confused by the example scripts - they use 0.0.2-SNAPSHOT which I don't have access to (I'm assuming this is to do with the :repositories config that I haven't replicated? - they also use a couple methods (e.g. subscribe-to-partitions) I don't appear to have access to and I'm not sure how to provide it or if this is related to the first issue and I'm wasting my time with this.

ben.mumford14:01:46

i'm quite new to clojure. is anyone able to provide a succinct description of a transducer? are they analogous to anything in java?

pesterhazy14:01:14

if you're new to clojure, you may not need transducers. They're kind of an advanced feature

pesterhazy14:01:56

not very helpful I know 🙂 I can't explain transducers well so I'll leave that to others, but I do know that I don't typically need them in my day to day work

robert-stuttaford14:01:43

think of the middleware pattern from web applications, but applied to collection transformations. transducers compose a sequence of transformations into a single function, that can then be used with many categories of collections - lazy seqs, sets, streams, channels

robert-stuttaford14:01:53

because it makes a function, it means you can make the transducer once, and reuse it with multiple collections or collection categories

ben.mumford14:01:52

so... a tranducer is like something i could supply to a threading macro and then pass a collection to?

ben.mumford14:01:52

(-> my-collection (filter #(> % 2)) (even?) ...)

ben.mumford14:01:08

(filter #(> % 2)) is a tranducer?

ben.mumford14:01:46

@pesterhazy yeah i guess they're advanced, haven't needed them so far. kept seeing them in the docs (returns a transducer) and was curious 🙂

robert-stuttaford14:01:13

threaded (->> (range 10) (map inc) (filter even?)) eager transduced (into [] (comp (map inc) (filter even?)) (range 10)) lazy transduced (sequence (comp (map inc) (filter even?)) (range 10))

robert-stuttaford14:01:06

the call to comp can be lifted to a def and reused: (def xform (comp (map inc) (filter even?))) eager transduced (into [] xform (range 10)) lazy transduced (sequence xform (range 10))

robert-stuttaford14:01:02

@ben.mumford (filter #(> % 2)) is a transducer, but not when it’s inside a threading macro call. filter with one arg - a function - is a transducer that can be applied to a collection later. a threading macro would inject a second arg, causing the filter op to happen immediately

robert-stuttaford14:01:52

the threaded example above, with the threading removed, is (filter even? (map inc (range 10)))

ben.mumford14:01:53

is it similar to a partial function then?

robert-stuttaford14:01:10

to echo what @pesterhazy said, though, you can totally never use these and get along just fine. but if you learn them and use them, your code will run faster 🙂

ben.mumford14:01:19

(you must be tearing your hair out! sorry for being dumbass!)

robert-stuttaford14:01:04

yes, similar-ish. in the sense in that you’re capturing some stuff to be applied later

robert-stuttaford14:01:16

not tearing my hair out 🙂 i love teaching

bronsa14:01:19

it's not just a curried function tho

bronsa14:01:43

you'll get nonsensical results if you try to use a transducer as if it was a curried version of that function

ben.mumford14:01:49

could you elaborate please?

ben.mumford14:01:54

how is it different?

arnaud_bos14:01:15

@ben.mumford if you're more familiar with JavaScript, there's this post I've read some times ago that is a good starting point. It links to a longer Clojure based post on tranducers.

ben.mumford14:01:17

google says transducers don't create the intermediate collections

robert-stuttaford14:01:01

@ben.mumford i highly recommend watching Rich’s talks on this stuff

robert-stuttaford14:01:16

let it soak in a bit 🙂

ben.mumford14:01:39

this is a most useful resource!

lhmariano15:01:00

Thank you for your help with migrations!

nooga16:01:31

pixie has transducers at the bottom, which is quite awesome

bcbradley16:01:54

does reduce-kv work on priority-map?

joshjones17:01:28

@ben.mumford http://elbenshira.com/blog/understanding-transducers/ this page does a good job at deriving transducers, would recommend

prakhar18:01:33

Ended up clicking around on that website and ended up at http://elbenshira.com/blog/the-end-of-dynamic-languages/. Not a good idea 😛

arnaud_bos18:01:45

> - This could be the end of Dynamic Languages. > - But I just got Dynamic Languages! > - And now, you must save it! Dynamic Languages Panda 2

tbaldridge18:01:11

Yeah, there's plenty of people on the other side of that argument, lol

tbaldridge18:01:36

Never forget, the network is untyped, the moment you talk to something over a wire all your static typing is gone.

tbaldridge18:01:55

They can disagree all they want, I can always send garbage down a TCP socket

joshjones18:01:06

that’s not “the wire” @qqq

joshjones18:01:09

in fact, it’s not even close to the wire … a few layers to go down for that

tbaldridge18:01:53

@prakhar @arnaud_bos I guess I need to link this again....what it would take to get me to "want" a type system again: https://gist.github.com/halgari/f431b2d1094e4ec1e933969969489854

tbaldridge18:01:06

Hint, it's basically spec + typed clojure

arnaud_bos18:01:45

Yeah, was about to mention spec too

arnaud_bos18:01:57

Cool thing is that you can get it if you want to

qqq18:01:10

@tbaldridge: how much does someone have to pay cognitect for cognitect to build that?

prakhar18:01:25

thanks for the link @tbaldridge. Not to get a discussion started on this, but as mentioned in that article, how do you generally deal with the uncertainty? the kind that the author has mentioned

oli18:01:26

the rabbit hole can get pretty deep https://github.com/hraberg/shen.clj

tbaldridge18:01:01

@prakhar spec helps a lot, but I'd say what also helps a lot is keeping the data model simple. A map with 100 keys and values is going to be a mess no matter what you try. But naming conventions, namespaced keywords, etc. All help with that.

borkdude18:01:01

How does one say in Schema: it can be anything, but it should be valid edn?

tbaldridge18:01:52

@prakhar also, keeping structures as flat as possible is good, I'd rather 20 keys in 1 map then a tree of 10 maps with two keys in each.

borkdude18:01:36

yes, namespaced keywords > nesting

wei18:01:32

speaking of namespaced maps, has anyone run into this error where newlines in namespaced maps break the repl reader? it’s happening for me in leiningen repl and clojure-inf https://github.com/clojure-emacs/inf-clojure/issues/39

tbaldridge18:01:18

Yeah, I'm pretty sure that's a bug in some of the nrepl code.

prakhar18:01:27

thanks for the tips, @tbaldridge!

tbaldridge18:01:19

@wei I'm going to try that at a bare CLJ repl without lein

tbaldridge18:01:21

@wei, yep, not a problem in Clojure, must be something wrong with lein or some other tool

wei18:01:30

@tbaldridge ok good to know, thanks for testing that out

bfabry20:01:13

anyone got any tooling for cursive intellij or otherwise that would help pick up typos in keywords?

bfabry20:01:54

interesting. maybe I should look at eastwood again, it's been a few years

bfabry20:01:16

oh, often produces a large number of warnings that are not errors. oh well

Al Baker20:01:47

bfabry: it's pretty easy to try out, I have used it on projects.

Al Baker20:01:24

I didn't find it too noisy, basically in line with other source code quality analysis tools

bfabry20:01:02

yeah I've tried it before, basically the problem was it always had quite a lot of false positives, which at that point means it doesn't get used. it does seem to have gotten a lot better though

cfleming21:01:03

@bfabry I’ve been planning to implement that inspection basically as described in the Eastwood docs. There’s not much more you can do unfortunately, except spec of course.

bfabry21:01:56

yeah the keyword typos thing sounds reasonable, it'd be good to be able to run it without mixing with reflection warnings though, and I'll have to figure out what I can change to make things like this not show up

src/link_dataflow/classic/tickets.clj:1:1: keyword-typos: Possible keyword typo: :brands instead of :brand ?
src/link_dataflow/classic/tickets.clj:1:1: keyword-typos: Possible keyword typo: :submitter-id instead of :submitter_id ?

bfabry21:01:12

probably spec will help there as those keys will get different namespaces and be repeated at least in their spec somewhere down the line

bfabry21:01:20

(the reflection thing was our bad)

tdavis22:01:36

trying to serve a generated PNG via ring... ring is failing to coerce body of OutputStream, BufferedWriter, and byte[]. what do you guys use?

geoffs22:01:52

@tdavis I think you maybe want a ByteArrayInputStream wrapped around your byte[]

tdavis22:01:52

yup, that did it. thanks @jr

tdavis22:01:33

yeah, i imagine that would work too.

tdavis22:01:22

@geoffs worked a lot better, in fact, since slurp tries to decode it 😉

mobileink22:01:41

is it better to ask questions here or on the mailing list?

Alex Miller (Clojure team)22:01:12

it’s better to just ask than ask to ask ;)

Alex Miller (Clojure team)22:01:03

the mailing list has the benefit of reaching more people, but asynchronously, and with a slightly more reliable archive

Alex Miller (Clojure team)22:01:12

this has the benefit of immediacy

mobileink23:01:08

thanks alex. more specifically: noob stuff. i'm running into the usual resistance at work - a python guy actually complained about all those parens yesterday. mailing list is better for that sort of thing? i.e. how to not strangle people, easevthem in, etc. the slack channel seems more suited for, well, sth other than that. maybe a newbie channel would be useful?

7h3kk1d23:01:11

Sometimes it’s hard depending on the type of coworkers you have.

mobileink23:01:15

luv the clojure community btw

7h3kk1d23:01:55

If any of your coworkers have a history of scheme/commonlisp or other less OO languages winning them over might be advantageous.

mobileink23:01:10

unfotunately that is not the case. the programmers seem interested - clojure is at least a little bit sexy. the python guy is a data scientist. nice guy, but maybe not a language geek.

7h3kk1d23:01:55

Do you need the data science guy to be on board? Or is it possibly something were you can split concerns and use python for that part

esanmiguelc23:01:46

@mobileink how are you approaching the problem? typically huge rewrites / risky projects are met with more resistance (with good reason) than smaller less risky projects

bfabry23:01:52

in my experience you're never going to convince the data science guys to like clojure. python is much more than the language to them, it's an entire giant toolchain that all their skills are built around. I would not start there

mobileink23:01:13

@7h3kk1d don't need him to go clojure, just need him not to badmouth it to others.

mobileink23:01:49

@esanmiguelc small, very small. iot stuff, with some backend server stuff. bot crazy enuff to suggest a wholesale switch to clj. 😉

7h3kk1d23:01:20

Hmm.. I would try to shift the conversation in a way that makes it seem that he doesn’t see the advantageous. Like functional programming is more modular and lends itself to be refactored much easier than imperative code. It might not be things that matter to him but it’s important from the development side.

7h3kk1d23:01:27

As well as testability, performance, etc.

bfabry23:01:44

that's an unfortunate people problem. you're probably best off ignoring it and not responding. I dunno that people who go around bad mouthing things are ever that influential

esanmiguelc23:01:51

@mobileink how many languages do you have to support currently?

mobileink23:01:22

@bfabry: completely agree. need to better articulate the clojure v. datascience space, for our situation.

mobileink23:01:31

@bfabry not even sure. unique situation. i know we do a bunch of java stuff, data scientists do lots of python. some javascript - one of our guys has glommed onto red-node which also worries me. ;)

mobileink23:01:24

anybody in chicago offer clojure intro training?

7h3kk1d23:01:48

idk, but the people at the meetup are helpful

mobileink23:01:08

i knew that! 😉

mobileink23:01:34

never been, i guess its about time, thx.

7h3kk1d23:01:12

It might seem condescending but it’s a good article.

sophiago23:01:55

is there something like nthnext that works on transients?

seancorfield23:01:46

@mobileink "maybe a newbie channel would be useful?” — you mean like #beginners ?

mobileink23:01:50

i'm leaning toward "boss, let's sponsor some lunches/happy hours for geekiness, and we'll plant some clj evangelists" v. "boss, make them do clj!"

mobileink23:01:27

@seancorfield ha! missed that, thanks!

seancorfield23:01:28

Very helpful crowd hangs out in #beginners — along with lots of brand-new-to-Clojure folks 🙂

mobileink23:01:53

great! just got folks into slack a few weeks ago and they've really taken to it this is a Very Good Thing!

mobileink23:01:49

now i just have to figure out how to get them past fear of posting.