This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-07-01
Channels
- # admin-announcements (1)
- # beginners (16)
- # boot (22)
- # cider (96)
- # clojure (146)
- # clojure-dev (5)
- # clojure-germany (7)
- # clojure-greece (3)
- # clojure-italy (5)
- # clojure-japan (76)
- # clojure-russia (6)
- # clojure-seattle (1)
- # clojure-sg (1)
- # clojure-uk (19)
- # clojure-ukraine (1)
- # clojurescript (114)
- # code-reviews (11)
- # datomic (42)
- # editors (4)
- # euroclojure (3)
- # jobs (18)
- # ldnclj (59)
- # off-topic (1)
- # om (17)
- # reagent (5)
- # yada (43)
@alexmiller: Thanks for the reference. My confusion is to see when transducer would be useful. I managed to find some explanation on HN: https://news.ycombinator.com/item?id=9806755
that was me :)
@alexmiller: Thanks again
For us a transducer was a great fit for an operation that had a complex way of removing internal duplicates from a sequence and ended with a customized sort operation — that we also needed to combine with pagination of the result.
the "collapsing" transducer could use a volatile internally for tracking duplicates, and it could easily be composed with the pagination logic (`drop` and take
)
It was much nicer than the accumulating reduce operation it replaced.
Now if only java.jdbc result sets were reducible, it could be even faster
I joke because there’s a JIRA ticket open for exactly that.
@seancorfield: wow definitely the stuff I'm drooling over
currently to imitate the "collapsing" transducer functionality I have been writing some loop recur stuff, which does not seem as elegant
Yeah, the big simplification and speed up for us with this case was that we could have a volatile inside the transducer and just vswap!
values into it as we processed the data. Each step is clearly separated out. And it’s composable.
We were like "so much win!"
692645c73c86d12c93a97c858dc6e8b0f4280a0b looks like Rich did have a "real" commit on 1.7
@seancorfield: do you have the URL/keyword for the java.jdbc JIRA ticket?
thanks!
@seancorfield: I noticed that we can pass some function to the result set, :row-fn and :result-set-fn. Will this ticket affect that?
arrdem: what does that mean?
@alexmiller someone on the mailing list observed that you didn't list rich in your contributors credits and I was mildly amused to find him when I read the log.
well, he did all of the symbol and keyword re-work, all of the initial transducers work, and the printing changes, so plenty involved :)
Rich has never been included on the list of patch contributors in previous release emails either afaik
@goodwind89: I don't know yet what form the reducible version will look like but it will maintain backward compatibility. At least for a few versions :)
Hi, what are people using to access H2 text columns? When using korma one gets back a java Reader object, which has to be parsed while the db is still in transaction, being a bit cumbersome. Is there an "easier" way, maybe using a different library or plain sql?
Well I just updated Grimoire with 1.7 docs... but they don't show up due to a version sorting issue. Neat. http://conj.io/store/v1/org.clojure/clojure
@xhh: yeah that's hand coded somewhere since I don't want to show all the snapshots and minor versions
I’m new to Clojure and I want to modify some libraries I’m using. Is this the correct procedure: cloning them from github, running lein install and then just using it normally in my project. Or should I do something different?
@pupeno: depends on whether you want to share the changes with others. But that method should suffice for development
Although be sure to bump the version to make sure you know which one you're using
@danielcompton: yes, my plan is to send a pull request. What’s the procedure to go back to the mainstream version after that? Am I relaying on remembering to change version numbers?
If you're just going to do a PR then you can let the library author update the versions
But if you're waiting for changes you can do a non canonical fork to clojars
@danielcompton: that’s not what I meant, I mean in my local system, how do I get rid of all my custom libraries and go back to the main ones?
Go to ~/.m2/repositories and delete your ones. Maven will download anything it needs so you can delete it all
In Ruby project, using Gemfile, I can point to a path, so I know I’m using the library from that path and when I’m doing developing that library I go back to pointing to a version which is the released library. I’m looking for a way to do that.
Got it.
If that was me I'd change the groupid on the project before lein installing
So you can have a clear separation between the two
How do you do that? change the groupid? should it be in project.clj?
What's the function that given a sequence gives you another empty sequence of the same type?
@pupeno: yep in the project.clj it's groupid/name
ragge: thanks.
Why does (flatten 1) return ‘() instead of ‘(1) or raising an error?
the implementation is very simple
[x] (filter (complement sequential?) (rest (tree-seq sequential? seq x))))
it's because it uses tree-seq which will make leaves into sequences, and then filter only on the actual sequences
I guess it's not very useful to do (flatten 1) but () I think it's correct, since there is nothing nested, so nothing to flatten
I agree with pupeno that it's surprising
If you remove rest from the implementation, it returns ‘(1) instead of ‘().
So it’s not due to the simplicity of the implementation as an even simpler version would do the other functionality.
If I was implementing it, I’d make (flatten non-seq) return ‘(non-seq), non-seq or throw an error. Silently returning ‘() seems like something that might masquerade a bug.
But maybe I’m missing something.
I think (1) would be wrong, 1 is not a sequence so it has nothing to flatten
assuming that flatten always returns a flattened list then () was the right answer for me
but I didn't write that
yeath, flatten shouldn't turn a non-seq into a seq
but a pre-condition that x is seqable seems sensible
At the very least, the docstring should include that the result is undefined for nonseqable arguments
Anyone using timbre to log within wildfly/immutant? I experience that output from timbre
is wrapped in another log format resulting in two timestamps etc.
after bumping clojure version from 1.6.0 to 1.7.0 in one of my projects I'm getting a following error when trying to launch repl session: Caused by: clojure.lang.ArityException: Wrong number of args (2) passed to: StringReader, compiling:(abnf.clj:186:28)
- anybody experienced this?
What’s the equivalent of (require ‘(foo.bar)) when declaring a namespace (that is, no alias).
@pupeno: I think you mean (require 'foo.bar)
I meant (:require foo.bar)… it wasn’t working because of a typo somewhere else.
out of pure curiosity, does anyone know the reasoning behind why (comp …)
works in reverse order with transducers relative to normal functions?
@jballanc: it only seems that way, if you understand how they work it becomes clearer it’s not really “backwards” but a result of how the transducer stack is built.
@dnolen: sure, under the covers I understand the mechanics, but it’s going to be difficult for beginners I should think...
right, but how do you explain that the result of (sequence (comp (map #(+ 2 %)) (map #(* 3 %))) [1 2 3])
not match (map (comp #(+ 2 %) #(* 3 %)) [1 2 3])
(sequence (comp (map #(+ 2 %)) (map #(* 3 %))) [1 2 3])
is more like (->> [1 2 3] (map #(+ 2 %)) (map #(* 3 %)))
😕
@jballanc: like I said those two examples do not seem related to me. you’re not composing multiple map
s.
@jballanc: pick a less trivial example mix map
and filter
and take
and it really falls apart
@dnolen: oh, sure…perhaps it’s my bias having worked with comp
. I usually rewrite the forms in my head applying r-to-l
so the temptation is to mentally convert (sequence (comp (map #(+ 2 %)) (map #(* 3 %))) [1 2 3])
=> (map #(+ 2 %) (map #(* 3 %) [1 2 3]))
(sequence (comp (filter even?) (map inc)) [1 2 3])
using r-to-l application for comp
looks like it should be (filter even? (map inc [1 2 3]))
but it’s actually more like (map inc (filter even? [1 2 3]))
what I wrote above is the sensible thing, doesn’t look different from your later thing now does it?
oh, I agree that comp
’s ordering with transducers “makes more sense” on its own…my problem is that it’s subtly different than what you might expect working with comp
on its own
for one thing, normally ((comp f g) x)
is equivalent to (g (f x))
, but that doesn’t work with transducers since changing the arity changes the behavior
i.e. you can’t turn (comp (map inc) (filter even?))
into #(filter even? (map inc %))
because now map
and filter
are no longer transducers
gah…mildly confusing, but it does work if you consider that transducers are nothing without sequence
or eduction
i.e. (sequence (comp (map inc) (filter even?)) [1 2 3])
is actually equivalent to (sequence (filter even?) (sequence (map inc) [1 2 3]))
Anybody upgraded to cider-0.9.1? I did and nothing works. No REPL, no eval, various interesting error messages.
jrychter: did you also update the corresponding nrepl middleware?
then I don't know
I'm now looking through the cider changelogs, because I didn't expect major breaking changes moving from 0.8.2 to 0.9.1.
@jrychter: there is a cider room as well
@jballanc: I always find it easiest to look at the definition of a transducer. For instance: map: https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L2596
the comp
still does call the right transducer first, but 'calling' here means really "instatiating" the transducer with a reducing function
Thus the left (first argument of comp) really gets the right (sec. argument) instantiated transducer as the rf
(reducing function)
then when a step is performed each transducer does it's own work first (look at the code of map
) and then calls the reducing function (`rf`)
So comp still does the same thing. It just happens so that the return value of the ((comp xf1 xf2) ...) is the function (transducer) of xf1
which then calls xf2
nope, I think you're right on it
Welcome @stuarthalloway !
thanks
@annapawlicka: The config component is's a bit of a cute trick, but I think it has some merits. For example, it's obvious from looking at the system declaration what components actually use it. I think you could consider it to be stateful, too -- after all, it has to be loaded from somewhere before any of the dependent components and it should be done only once. I guess it's a matter of taste whether to do that in an extra step before starting the system or whether to make it part of the system itself. Anyway, thanks for taking a look, let me know if I can clarify anything else
I totally create a config component
this allows changing config cleanly (as part of a restart)
otherwise changing config would be more tedious
Yep, that's another nice side-effect (haha)
Is *assert*
ever set to false under any normal clojure runtime operation (e.g. running from uberjar, REPL, e.t.c.), or do I need to explicitly set it myself?