#clojure log - May 06 2015

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:06 ScottishPig: Hey, guys. I'm the noobiest noob anywhere. I'm trying to use (re-find ...) with a (let...)ed String as the regex. I can't get past the syntax here. Obviously (re-find revar "blahdeblah") doesn't work. Neither does #revar or anything else.

0:07 justin_smith: ,(re-pattern ".*")

0:07 clojurebot: #".*"

0:07 * ScottishPig facepalms

0:07 justin_smith: ScottishPig: http://conj.io

0:07 ScottishPig: Thanks.

0:07 justin_smith: it has most of the interesting stuff built into clojure.jar, all on one page

0:08 ScottishPig: Sweet. Thanks!

0:18 sobel: is there a popular library for making event reactors, maybe somewhat like the 'twisted' library in python

0:24 bbloom_: sobel: core.async

0:24 sobel: huge piles of articles, videos, etc about it

0:25 see also golang & the various stuff pike et al have written about it

0:25 brehaut: bbloom_: depends if 'somewhat like twisted' means 'callback soup'

0:25 in which case not so much

0:27 sobel: so there's not a category-winner

0:27 i can search just fine, was hoping for an opinion

0:27 brehaut: sobel: core.async. i was makign a shitty joke

0:27 ed-g: sobel: Twisted is about event loop integration, is that right?

0:28 sobel: ed-g: i guess that's accurate

0:28 mischov: sobel: You might get a better answer if you ask in terms of what you're trying to do, not how you'd do it in python. :D

0:28 justin_smith: it's about tying callbacks to event sources I thought

0:28 bbloom_: it's just more human CPS compiler bullshit

0:29 sobel: i want to integrate events from disparate sources. i only meant twisted as a vague reference to the type of system.

0:29 justin_smith: oh, then definitely core.async

0:29 mischov: yup

0:29 sobel: it's easy enough to DIY with core.async so i'll probably just do that

0:29 justin_smith: though ztellman's manifold, and prismatic/plumbing are worth a quick look too while you are at it

0:29 mischov: Could peek at Manifold, too, but core.async is the cannon answer

0:30 Canon*

0:30 justin_smith: sobel: depending on what kind of network stuff you are talking about, sente connects websockets to core.async

0:30 in a way that is nice to work with in my experience

0:34 sobel: also, there was a book that came out recently "clojure reactive programming" about compositional event streams, and I like it so far

1:30 brainproxy: yourkit is telling me that for one of my hot loops, RT.first and RT.next are dominating the w.r.t. "own time"

1:30 dominating the cpu

1:32 now, if I can't know ahead of time exactly what kind of sequential? things are going to be looped over, is there anything I can try to cut down on the first/next time?

2:51 puredanger: brainproxy: in 1.7, you might consider using a reducible/iterable source instead of a sequence - that's generally more efficient with less allocation.

2:54 brainproxy: puredanger: good point; I may be able to provide an optimal path for some inputs, but I guess I'm stuck if inputs can be any kind of sequential coll?

2:54 i mean stuck with a path for some inputs which is always going to be limited by overhead of first/next

2:55 puredanger: reduce will take a reducible path if it can and a seq path if it can't

2:56 or things built on reduce like into

2:56 brainproxy: well in this case I actually need to (loop ...)

2:57 I'm doing a "forward composition" thing/experiment with transducers

2:57 i.e. I'm handling the continuation passing rather than relying on comp

5:33 kaiyin: https://gist.github.com/kindlychung/c874be3b9554df988ced what does ~@ mean here?

5:35 wasamasa: it unsplices

5:36 TEttinger: ,`(str ~@["alpha" "beta"])

5:36 clojurebot: (clojure.core/str "alpha" "beta")

5:36 wasamasa: aka removing one level of parentheses

5:36 TEttinger: it only works in a syntax quote though

5:36 (I think)

5:42 kaiyin: but ~@ks is enclosed in [], what's point in removing if you add them back anyways?

5:43 the point.

5:46 chipf0rk: because you're also unquoting them with this

5:46 http://stackoverflow.com/questions/20260516/how-to-explain-the-env-example-in-book-clojure-programming

5:47 if you didn't unquote them, the entire macro would not do what it's supposed to

5:47 ~@ is called 'unquote-splice', it unquotes AND spreads the unquoted list out

5:47 clojurebot: Ik begrijp

5:59 kaiyin: chipf0rk: why not use ~ks instead?

5:59 ,(let [x 2 y 3 z [x y]] `(1 ~z))

5:59 clojurebot: (1 [2 3])

6:00 chipf0rk: try it :) it will expand to a list, the list will be executed and you'll get an error about not being able to invoke a number

6:00 hence you spread it into a vector so you can use a literal

6:01 debugging this macro is easier if you define it as taking the env map as an argument

6:01 kaiyin: chipf0rk: ah, i see.

6:06 chipf0rk: you mean something like this? (defmacro spy-env [] (let [km &env] `(prn ~km)))

6:06 this does not work.

6:06 isaac_rks: how do I get unbanned from a channel

6:06 bcn-flor: Could anyone help me with clojure.tools.analyzer ? Specifically, I'd like to analyze a form without evaluating the symbols inside it, I just need the AST if that makes any sense :)

6:06 wasamasa: isaac_rks: sure it's not a matter of getting a nickserv account?

6:06 isaac_rks: yes

6:06 :(

6:06 wasamasa: isaac_rks: if not, speak to the channel operators in a /query

6:07 isaac_rks: thx

6:07 wasamasa: ideally another one than the person who banned you

6:07 Bronsa: bcn-flor: hi, not sure I understand what you mean

6:07 wasamasa: isaac_rks: why are you asking this here though

6:07 isaac_rks: this is a topic for #freenode

6:07 isaac_rks: thanks wasamasa

6:07 ok

6:07 im a noob at irc

6:08 its some web 1.0 shit :/

6:10 wasamasa: ...

6:12 isaac_rks: :

6:12 :^)

6:18 chipf0rk: kaiyin: no, this: (defmacro spy-env [env]

6:18 (let [ks (keys env)]

6:18 `(prn (zipmap '~ks [~@ks]))))

6:18 the same macro, but instead of getting (keys &env), you pass env as an argument and use it: (spy-env {x 1 y 2})

6:19 oops, you have to quote the map '{x 1 y 2}

9:24 tdammers: quick question here; I'm trying to store things with newlines in them in an h2 database through yesql and jdbc, but something somewhere seems to be stripping the newlines out

9:24 is this a known issue anywhere? am I doing anything wrong? common mistake?

9:26 clojer: Can anyone help me getting Figwheel working in vim?

9:27 When I edit a core.cljs file the browser doesn't update

9:27 justin_smith: clojer: the vim part should not matter at all

9:28 clojer: justin_smith: I have a connection, just no updates.

9:29 justin_smith: I get the Clojure logo in the browser when I update the source file but nothing updates.

9:29 oddcully: clojer: have you tried with some basic setup like lein new figwheel myapp?

9:29 clojer: oddcully: Yes, that's what I'm using.

9:30 oddcully: clojer: what are you changing? do changes to the css show up?

9:30 clojer: is your change there, after a ctrl-f5 browser reload?

9:30 clojer: oddcully: Just changing the "Hello world" text

9:31 oddcully: Yes, there after F5

9:31 chipf0rk: you're using the default template that uses Om, right?

9:32 change `defonce` to `def` if that's the case

9:32 clojer: chipf0rk: No, it uses Reagent.

9:32 chipf0rk: oh yeah it does that by default... judging from the source, it's the same line:

9:32 (defonce app-state (atom {:text "Hello world!"}))

9:33 needs to be def instead

9:33 and then one last reload ;)

9:34 clojer: chipf0rk: BRILLIANT!! I owe you a drink.

9:34 oddcully: (inc chipf0rk)

9:34 lazybot: ⇒ 1

9:34 chipf0rk: np :)

9:34 oddcully: clojer: but remember: this is now fine for get going. the defonce makes sence for a larger scale soon

9:35 clojer: now your state gets overthrown each time figwheel reloads

9:35 chipf0rk: the file includes a line on this: ;; define your app data so that it doesn't get over-written on reload

9:35 I think it should be more explicit on the usage of `defonce` here. might do a tiny PR as this has confused me before

9:36 clojer: oddcully: So change back to defonce before deployment?

9:36 chipf0rk: nope, change it back during development :) when your app gets to a larger scale

9:36 because you don't want to lose all your accumulated state on every code change when that happens

9:36 clojer: chipf0rk: So Figwheel's no good for large apps?

9:37 oddcully: clojer: defonce does not overwrite an existing def. such you can keep and accumulate your state in your browser session

9:38 that was the reason, why your change was not visisble

9:38 chipf0rk: guess I'm putting this the wrong way. this actually improves developing large apps. usually you change your state with swap! and the likes

9:38 oddcully: it was def(ined) once

9:38 chipf0rk: not in the definition

9:39 the definition is there for initial state in the end; now imagine having clicked through your complex app to a certain state and then wanting to change the structure of your initial state

9:39 if you use def and add just one entry to your state map, you save, the def gets evaluated, and your whole state you had in the browser gets thrown out the window. that's why you use defonce

9:40 hope I'm making sense here...

9:40 clojer: chipf0rk: I kinda get what you're saying but does that mean Figwheel isn't appropriate for large apps?

9:41 chipf0rk: no, I'm not sure how my explanation would imply that :)

9:41 can you elaborate?

9:41 clojer: chipf0rk: Well FW seems to need def instead of defonce, at least with Reagent

9:41 oddcully: it makes it in appropriate for your toy example ;)

9:41 clojer: .. but defonce is needed to protect cumulative state, no?

9:42 sritchie: clojer: you need defonce if you have some other way of updating the state

9:42 clojer: otherwise figwheel will reset you every single time

9:42 oddcully: defonce has nothing to do with reagent, rum, or om

9:42 sritchie: oddcully: sure; it has to do with figwheel reloading code

9:42 clojer: sritchie: Yes, so it sounds like the 2 use cases are at odds, no?

9:42 oddcully: it has to do with you running basically a living/breathing application in your browser

9:43 sritchie: clojer: only for this particular tutorial where you’re changing your initial state in the file

9:43 oddcully: sritchie: that is what i am saying

9:43 sritchie: oddcully: sorry, wasn’t trying to contradict

9:44 I had my own issues with figwheel last week, though, with reader conditionals

9:44 figwheel was trying to load clojure-only functions

9:44 chipf0rk: oddcully: I now think i's inappropriate for the toy example too... Will open a PR on the template repo when I've figured out a concise way to explain this

9:45 sritchie: clojer: you can get around it by adding a bare “(reset! app-state {:text “Hello, world!”})” in the file

9:45 and changing that instead

9:45 oddcully: chipf0rk: i could argue, that the section about this topic on the GH page explains this quite well

9:46 chipf0rk: https://github.com/bhauman/lein-figwheel#writing-reloadable-code

9:46 or better clojer: https://github.com/bhauman/lein-figwheel#writing-reloadable-code

9:47 clojer: oddcully: Thanks. That explains everything. Will study it.

9:48 chipf0rk: even better, then you'd just need a link across the repo in the main source file :)

9:49 I mean @oddcully

9:52 tdammers: hah, found it

9:52 newlines got stripped when converting from Clob to string

9:52 serves me right for copy-pasting code from teh intarwebz without checking

9:53 particularly, this bit: https://en.wikibooks.org/wiki/Clojure_Programming/Examples/JDBC_Examples#SELECT

9:54 the (apply str (line-seq rdr)) part effectively removes newlines

10:23 justin_smith: seems like it would be easier to just slurp it

10:40 sritchie: my solution for X only was to wrap the body in #?@ so one implementation gets an empty defn

10:43 timvisher: i have `(let [...] (try ... (catch ...)))`. is there anyway for paredit to wrap the let around the `...` inside the try?

10:43 i thought for a second that i had finally found a use for paredit convolute sexp but alas, it was a foolish thought

10:43 although it almost gets me there :)

10:45 actually! wow. i think i finally found it! the only problem was that i then had to barf the catch form afterwards

10:45 omg! :)

10:46 achievment unlocked

10:46 chipf0rk: try putting the cursor before the inner ...

10:46 justin_smith: timvisher: congrats

10:46 chipf0rk: (try | ...)

10:46 timvisher: this feels even better than when i found a use for juxt in prod :)

10:46 justin_smith: haha

10:47 * timvisher bows low to the thunderous applause

10:48 chipf0rk: barfing catch works too I guess :D nice one!

10:49 timvisher: chipf0rk: maybe i'm on an older version of paredit. point where you indicate still doesn't prevent me from having to barf the catch

10:51 chipf0rk: oops, you're right. only makes a difference for where the ... after try will go.

11:00 timvisher: chipf0rk: good to know. :)

11:01 yeah i can't imagine how it could possible know about the special catch form at the end of the try.

11:35 kaiyin: could anyone help with this? http://stackoverflow.com/questions/30081343/why-doesnt-type-hinting-improve-performance-in-this-function

11:37 xemdetia: kaiyin, .substring causes a new string to be created.

11:38 justin_smith: the second function doesn't have any information that the first doesn't have - unless the clojure compiler is really that dumb that it doesn't know (or a b) will be T if a and b are both T

11:42 dnolen: justin_smith: the compiler really does very little type inference, even so kaiyin that's not a meaningful benchmark. the overhead of seqs will dominate. Even if you removed that you would probably end up with a meaningless benchmark on the JVM.

11:46 kaiyin: dnolen: ok, the task is probably too trivial.

11:50 xemdetia: kaiyin, I don't think it is even that it is trivial it's just that calling many substrings is a lousy case even in plain java. http://www.javaadvent.com/2012/12/changes-to-stringsubstring-in-java-7.html

11:55 pyr: hi clojure!

11:56 I have an idiom I use in several projects with core.async and was wondering if there was a corresponding transducer idiom I was maybe missing

11:56 I quite often do: (core.async/reduce state-update-fn some-state input-channel)

11:57 which doesn't translate 1-1 to transducers, even though it would make my tests easier (as I would be able to mimick channels with standard collections)

11:59 do you end up just doing (transduce state-update-fn identity some-state input) ?

12:09 {blake}: ,(println println)

12:09 clojurebot: #object[clojure.core$println 0xb0e7468 clojure.core$println@b0e7468]\n

12:12 {blake}: &(println println)

12:12 lazybot: ⇒ #<core$println clojure.core$println@2bdac138> nil

12:15 {blake}: The second part of this appears to be namespace$function@address. What's the first part? I mean, I guess it's not-fully-qualified-namespace$function, but I don't get why we see it.

12:15 puredanger: in the #object form you see: class-name identity-hash to-string

12:16 lazybot is showing you the older form which was just the toString of a function in the format "class-name@identity-hash"

12:17 actually it's #<class-name to-string> where to-string is "class-name@identity-hash"

12:17 {blake}: puredanger: OK, I figured it was something like that. So there could be a different namespace, like "myns.core" that had a "println", and it would also show up as #<core$println...>?

12:18 puredanger: Oh, that makes more sense than "address". =P

12:18 puredanger: well as I said, that's the <= 1.6 form so now you'll never see that form

12:19 {blake}: "now" being 1.7+?

12:19 puredanger: but now you'd see #object[myns.core$println 0xdeadbeef myns.core$println@deadbeef]

12:19 yes

12:19 {blake}: puredanger: Oh, okay, cool. I like that better.

12:19 (inc puredanger)

12:19 lazybot: ⇒ 48

12:20 puredanger: there is a ticket for printing something more useful for the tostring of a function (the last component of that) too

12:20 http://dev.clojure.org/jira/browse/CLJ-1278

12:21 {blake}: Kewl.

12:21 Yeah, that would be a good thing.

12:23 kaiyin: vnoremap < <gv vnoremap > >gv

12:23 ,(let [^String y "abc"] (meta y))

12:23 clojurebot: nil

12:23 kaiyin: isn't type info supposed to be stored in meta?

12:23 why isn't it working here?

12:24 sdegutis: Pop quiz: you have a sequence of either true or false values. What's the most breathtaking way to get a percent of how many are true?

12:25 {blake}: sdegutis: Outsource it to a sweatshop of southeast asian children?

12:25 sdegutis: So, (your-function [true true true false]) should result in 0.75

12:25 {blake}: that's not a valid Clojure function

12:25 puredanger: sdegutis: frequencies + something with juxt ?

12:25 {blake}: sdegutis: Well, first solve AI...

12:26 sdegutis: puredanger: that's almost the solution I have, but I'm betting there's way more impressive

12:26 {blake}: *lights up the amalloy_ signal*

12:26 sdegutis: {blake}: I solved that already, put it into a toaster's firmware

12:27 {blake}: sdegutis: That's what I did. Damn thing became passive-aggressive and started burning the edges.

12:27 sdegutis: :)

12:27 puredanger: you need to tap into POPCNT to be really impressive

12:27 sdegutis: Someone sure is in a good mood today.

12:28 {blake}: Heh. I'd do something pedestrian like frequency/count.

12:28 sdegutis: There's got to be something way more functional.

12:29 puredanger: check out Integer.bitCount() to tap into hardware level bit counting :)

12:29 PersistentHashMap uses this trick btw :)

12:29 sdegutis: What if I give you a vector and a function that returns true on some items and false on others?

12:29 {blake}: I do love me some bitcounting.

12:31 puredanger: kaiyin: your best bet for this kind of question is Bronsa :)

12:31 {blake}: Woudldn't actually matter, would it? Lazy sequence vs. function?

12:32 kaiyin: puredanger: thanks. it seems he offline at the moment?

12:32 is

12:32 puredanger: kaiyin: I believe in that position the compiler is using it as :tag meta on the y symbol in the let but the symbol inside the let is a different symbol

12:34 Bronsa: kaiyin: I'm not, what's the question again? :)

12:34 puredanger: iow, I don't think you can recover that in the way you expect there, but you could apply meta to the value bound to y (assuming it was something that took meta) and recover it. not sure what your actual goal is.

12:34 Bronsa: (let [^String y "abc"] (meta y))

12:35 Bronsa: only the compiler can access that metadata

12:36 kaiyin: ok, thanks.

12:36 Bronsa: kaiyin: you need to understand the difference between compile-time metadata and run-time metadata

12:36 kaiyin: puredanger: I don't have a specfic goal here other than the gratification of my curiosity. :-)

12:37 Bronsa: kaiyin: I guess the confusion arises from the fact that e.g. (meta ^:foo [1 2]) returns {:foo 1}

12:37 expez: Can you create default methods with definterface?

12:37 Bronsa: kaiyin: the thing is, collections are compiled in such a way that their compile-time metadata is available at runtime while everything else doesn't

12:40 kaiyin: Bronsa: you mean their metadata are removed after compilation?

12:41 Bronsa: kaiyin: not really, think about the different stages of evaluation -- the {:tag String} metadata is attached to the y symbol, which is consumed by the compiler

12:42 mpenet: pyr: depends, but if you always will reduce over the values just pass an "xform" arg to the chan

12:42 kaiyin: and then?

12:42 Bronsa: kaiyin: the clojure compiler special cases only constant collection values to preserve their compile-time/read-time metadata at runtime

12:43 kaiyin: ok

12:43 Bronsa: `y` is just a symbol mapping to a local, the read-time metadata is used by the compiler and doesn't exist at runtime

12:43 mpenet: pyr: I do something similar in qbits.jet.http/client to fold (or not) chunked responses depending on the options passed

12:49 kaiyin: ,(meta ^:foo [1 2])

12:49 clojurebot: {:foo true}

12:51 kaiyin: Bronsa: what does this even mean? No one attached any metadata to [1 2], and then {:foo true} just comes out of nowhere...

12:52 Bronsa: kaiyin: as i said, collection values are the only thing that preserves read/compile-time metadata at runtime

12:54 kaiyin: Bronsa: but what is there to preserve?

12:54 {blake}: Speaking of elegant ways to do things: Move a decimal point two places to the left in a string. I've got "(/ (read-string (clojure.string/replace val #"[%,]" "")) 100)".

12:54 kaiyin: ,(meta ^:foofoobarbar [1 2])

12:54 clojurebot: {:foofoobarbar true}

12:56 kaiyin: ok, i finally got it.

13:04 mpenet: ,(import (java.text NumberFormat) (java.util Locale))

13:04 clojurebot: java.util.Locale

13:05 mpenet: ,(/ (-> (NumberFormat/getInstance Locale/FRANCE) (.parse "1221,3")) 100)

13:05 clojurebot: 12.213

13:05 mpenet: {blake}: it's not shorter but a bit less hairy

13:06 ah but wait, it's not really the same, you just ignore the "," position. Anyway, you get the idea

13:07 Long/parseLong would be better than the read-string in your example then

13:08 {blake}: mpenet: Yeah, I see the problem with read-string. I need a double, tho'.

13:09 mpenet: Double/parseDouble then

13:09 Jefffrey: Hello

13:09 {blake}: mpenet: Right. That's where I ended up.

13:09 (inc mpenet)

13:09 lazybot: ⇒ 7

13:10 Jefffrey: Say I have a function x in some "module" sample.module. I can refer to it via `sample.module/x`, but is there a way to rename that whole `sample.module` to something else, say `a`, so that I can call `a/x`?

13:11 {blake}: Jefffrey: (require '[sample.module :as a])

13:11 Jefffrey: {blake}: Doesn't that also import `x` in the current namespace?

13:11 {blake}: Jefffrey: You mean so that you could just say "x"? No.

13:12 Jefffrey: That would be (require '[sample.module :refer :all])

13:12 Jefffrey: Alright, and why is there a ' in front of that vector?

13:12 {blake}: Jefffrey: That's for doing it in the REPL.

13:13 In your code, you'd have your namespac:

13:13 (ns my.stuff

13:13 (:require [sample.module :as a])

13:13 No ' required. (The ' keeps the reader from immediately evaluating.)

13:16 Jefffrey: In other words, in the REPL, if you say (require [sample.module :as a]) without the ', the reader will look for a symbol called "sample.module" which you do not have.

13:16 With the quote, you just pass the whole vector to "require", which knows you're referring to a namespace.

13:16 Jefffrey: I thought that behaviour was reserved for lists.

13:17 brainproxy: puredanger: figured out I can do a nice optimization if the caller hints (w/ metadata) that a sequential thing being passed as an argument is known to be finite; w/ that info, I can greatly reduce the number of first/next calls

13:18 {blake}: Jefffrey: Lists without the ' get interpreted as function calls, yes.

13:19 brainproxy: {blake}: except for ()

13:19 I used to write '() as shorthand, then realized the ' isn't necessary in that case

13:19 {blake}: brainproxy: Good point.

13:20 Jefffrey: But everything read by the reader has to be something, right? It's either a literal value or a symbol.

13:20 So, you can't say: {arbitrary stuff} in a map, either.

13:20 ,{arbitrary stuff}

13:20 clojurebot: #error{:cause "Unable to resolve symbol: arbitrary in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: arbitrary in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6543]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: arbitrary in this contex...

13:20 {blake}: Because ther eader doesn't know what "arbitrary" is.

13:21 Jefffrey: Right

13:21 But now this code: http://pastebin.com/wHSM5e5F, gives me "Parameter declaration let should be a vector" on the record definition.

13:22 brainproxy: Jefffrey: in the HtDP/2e book, which uses a Racket dialetc, there's an explanation for how to think about the ' and ` operators

13:22 http://www.ccs.neu.edu/home/matthias/HtDP2e/i2-3.html

13:22 the same concepts apply to Clojure

13:22 Jefffrey: Thanks

13:23 brainproxy: the difference being that clojure uses ~ instead of , (comma)

13:27 {blake}: I don't see how that can be. defrecord shouldn't be affected by anything you have.

13:37 pyr: mpenet: i'm not sure i get what you mean

13:40 mpenet: c.c.async/chan can take a transducer (xform argument), which could do the reduction you describe. But this is only useful if you can afford to set this when you create the chan.

13:41 pyr: mpenet: ah ok, I wasn't aware of this

13:41 mpenet: sounds perfect

13:42 mpenet: pyr: https://github.com/mpenet/jet/blob/master/src/clj/qbits/jet/client/http.clj#L66-L74

13:42 it's an example of this

13:43 it's still a chan, but N inputs, 1 output produced by the transucer

13:43 transducer*

14:56 patchwork: Currently using clojure.java.jdbc/execute!, when I supply args of type Long they are getting converted to strings inside the sql statement? ["insert ... ? ?" a-long b-long] --> "insert ... 'a-long' 'b-long'"

14:56 Anyone know how to control the type of the interpolation?

15:02 hiredman: what makes you think you are passing it longs?

15:06 I ask because the simplest explanation for your input being treated like strings, is that they are in fact strings, so have you ruled that out?

15:13 amalloy: {blake}: eh?

15:15 daviid: hello. if someone writes the following in java: "public class Particles4_ implements PlugInFilter {...}", in a jar file that i symlinked to "mc.jar", so my repl is launched like this: "java -cp clojure.jar:ij-core.jar:mc.jar:cljs clojure.main", how do i know what to import so i can use it? asking because i tried this (import '(ij.plugin.filter PlugInFilter)) but get an error: (IJ/run imp "Particle4 " "white label show=Particles

15:15 minimum=120 maximum=9999999 display redirect=None") \n Unrecognized command: "Particle4 "

15:16 hiredman: that looks very IJ (that is some image library or something?) specific

15:16 daviid: hiredman: yes, it is

15:17 {blake}: amalloy: sdegutis was looking for a "breathtaking" way took calculate the percentage of trues, given a sequence of true/false.

15:17 hiredman: but as a guess, maybe "Particle4 " needs to match the name of the class?

15:17 daviid: hiredman: the class is defined in the java file as this:

15:18 public class Particles4_ implements PlugInFilter

15:18 hiredman: java also needs to be compiled to class file, you can't just load the source (maybe you have compiled it)

15:18 oddcully: Particles4_ vs Particles4 ?

15:18 hiredman: daviid: yeah, that class has an underscore in the name

15:18 {blake}: amalloy: We only had pedestrian solutions involving frequencies.

15:18 gfredericks: ,(let [{t true f false} (frequencies (repeatedly 1000 #(rand-nth [true false])))] (/ t (+ t f)))

15:18 daviid: hiredman: i did not compile

15:18 clojurebot: 51/100

15:18 hiredman: well, there you go

15:19 amalloy: yeah, frequencies is the way to do it

15:19 daviid: Unrecognized command: "Particle4_"

15:19 amalloy: what gfredericks did is pretty good imo. if you wanted something less legible but more breathtaking, you could try to go point-free

15:20 oddcully: daviid: package?

15:21 {blake}: I like the destructuring, gfredericks.

15:21 amalloy: What's point-free?

15:21 amalloy: ,(apply / ((juxt first (partial apply +)) (map (frequencies (repeatedly 1000 #(rand-nth [true false]))) [true false])))

15:21 clojurebot: 64/125

15:22 amalloy: {blake}: a programming style in which you avoid naming locals or function arguments, instead composing higher-order functions

15:22 dnolen: thanks to Jonathan Boston & Shaun Lebron ClojureScript now has a full port of clojure.pprint - https://github.com/clojure/clojurescript/commit/d0dedcb155d2c742e11d50ec79c54e5c8c4b8e73

15:22 monster commit, like 4000 line patch

15:22 seriously awesome

15:23 {blake}: amalloy: Oh, I did not know that had a name.

15:24 gfredericks: amalloy: #(rand-nth [true false]) => (partial rand-nth [true false])

15:24 amalloy: gfredericks: yeah but both are point-free so who cares

15:24 daviid: oddcully: sorry don't understand. the thing is through the fiji interface, putting this exact plugin .jar file so fiji sees it, without compiling anything, fiji loads the jar and things are usable. then i ask fiji to write the java code that mimic the user actions, it writes exactly this: (IJ/run imp "Particle4 " "white label show=Particles minimum=120 maximum=9999999 display redirect=None")

15:25 gfredericks: amalloy: having one function with zero points is a little less point-free than having no functions

15:25 it's like an infintesimal point

15:25 kaiyin: what's wrong with this? (defmacro mmm [& body] ~body)

15:25 amalloy: gfredericks: is it? point-free malarkey comes from haskell, where there's no such thing as a function with no arguments

15:25 TimMc: {blake}: Also sometimes called point-less programming. :-)

15:26 kaiyin: or, ,(defmacro mmm [& body] ~@body)

15:26 TimMc: s/programming/stlye/

15:26 gfredericks: amalloy: well then we have the freedom to extend the concept to clojure as we wish and mine is obviously better than yours

15:27 TimMc: amalloy: *Obviously* gfredericks' solution is better because it involves more fns not in head position.

15:28 daviid: here is the java code that's in the jar that i'm trying to use from clojure: http://paste.lisp.org/+364S

15:28 amalloy: TimMc: i have a fix for that: (do get inc dec + * #(rand-nth [true false]))

15:29 gfredericks: ~amalloy |wins| goodest fumctional programmer on a technicality

15:29 clojurebot: A nod, you know, is as good as a wink to a blind horse.

15:30 amalloy: gfredericks: now i'll forever be known as fumctional. my secret shame

15:30 daviid: i don't know java, which is why i'm asking these stupid quizz

15:30 gfredericks: ~fumctional programming is the shady underbelly of FP

15:30 clojurebot: 'Sea, mhuise.

15:31 oddcully: daviid: i wondered, if you Particle4_ class is in a package. according to the code it ain't

15:32 s/you/&r/

15:32 daviid: i don't understand sorry, it's in a jar file

15:32 oddcully: daviid: never mind, my way-to-short-question was answered by your code

15:35 daviid: i thought, as for other jars, that adding it to my java path would let me use it from clojure, the problem is, not knowing java, i'm not sure that Particles4_ lands in PlugInFilter, also why fiji does not write the _ ...

15:36 maybe i should '(import Particle4_) ?

15:36 oddcully: daviid: in your example there you wrote "Particle4 " (space at the end). mind to try without it

15:36 just guessing...

15:37 daviid: oddcully: did that already, the problem is clojure does not see that class/function ...

15:37 oddcully: if you pass it as a string, i'd expect IJ/run to pick it up via java means

15:38 daviid: well it does not but i don't know why

15:38 (IJ/run imp "Particle4 " "white label show=Particles minimum=120 maximum=9999999 display redirect=None")

15:38 Unrecognized command: "Particle4 "

15:38 so i guess it is a load/import problem?

15:39 brainproxy: is there a (potentially clunky one-off way) to put metadata on a fuction (not its var) that includes a varargs arity and yet avoid the RestFn invocation penalty of AFunction?

15:41 arohner: brainproxy: how would that work?

15:41 brainproxy: also, metadata doesn't affect how fns behave

15:41 brainproxy: arohner: yes it does

15:41 look at clojure.lang.AFunction

15:43 arohner: brainproxy: ah, I was thinking of .AFn

15:44 brainproxy: I wasn't sure if maybe it's possible to cook up something with gen-class that wouldn't be convenient in general but would allow a function to have attached metadata and yet not always dispatch with RestF

15:44 *RestFn

15:44 arohner: why are you hitting this? Are you adding lots of metadata at runtime?

15:45 brainproxy: in any case, a workaround is to make the metadata available through invoking the varargs arity with a namespaced keyword

15:45 since that arity isn't hit often, it's okay

15:45 perf wise i mean

15:45 yes, I'm doing some fun things with runtime metadata on funcs

15:47 daviid: am i right to say that this public class Particles4_ implements PlugInFilter will add the function "Particles4 " to the PlugInFilter namespace, which itself is defined by imagej and is imported by the java user code as import ij.plugin.filter.PlugInFilter;

15:48 amalloy: brainproxy: i mean if you want to you can (let [f (...), m {:fake true}] (reify IFn (invoke [this x] (f x)), IMeta (meta [this] m))

15:49 and you probably have to implement applyTo

15:49 daviid: any tutorial on how to load a java code and call it from clojure ?

15:49 amalloy: it's more work, but it's not like the implementation of with-meta for functions is complicated

15:50 brainproxy: amalloy: but invoke can't support a [this x & xs] arity, right?

15:50 oddcully: daviid: this code makes Particles4_ implement a interface from IJ. the IJ/run then takes a command as that param. what there happens is implementation of this library

15:50 amalloy: of course not. but you wouldn't want it to, because you know the function's arity

15:50 oddcully: daviid: all the guesswork done here revolved around the fact, that there was a class name involved. but the API docs suggest, that some "command" is passed there

15:51 amalloy: oh, i think i misread

15:51 brainproxy: amalloy: no, in this case I need the func to support several arities, including a varargs arity

15:51 oddcully: daviid: its hard to tell, what would make this work, without knowning the IJ lib

15:51 amalloy: brainproxy: i'm not sure what overhead you think you'd be getting around, by doing this

15:51 the only way to avoid going through restfn is basically to reimplement restfn yourself

15:52 hiredman: (or why you are using metadata at all)

15:52 amalloy: if you want a function that supports varargs

15:52 brainproxy: amalloy: that in the [this] [this x y] [this x y & zs] I don't want dispatch to involve RestFN

15:52 sorry, not the &zs case

15:52 i meant: [this] [this x] [this x y]

15:53 daviid: oddcully: can i list what's in IJ from clojure ?

15:53 brainproxy: okay, missed your comment re: reimpl'ing restfn

15:53 amalloy: brainproxy: okay, so, here is the thing. you are returning a wrapper around some function, right, which you are using to hold the metadata

15:53 and you want that wrapper to be exactly as general as restfn is

15:54 so you really can't do any better performance-wise than the existing implementation of with-meta, which uses restfn

15:54 but of course as hiredman says, putting metadata on functions is tricky business that often ends in tears

15:55 hiredman: people tend to you use "metadata" to glom on extra data to thinks that really could just be data, e.g. {:extra-data data :thing thing}, and metadata on functions has some gross issues (with-meta implies value identity, but functions have reference identity, so the whole thing is full of hazzards)

15:55 brainproxy: amalloy: i'm in deep, and it's working out fine, but I'll admit it's a bit unusual

15:56 I just have a function that gets called *a lot* and I don't want the RestFn penalty

15:56 hence, my workaround; but I would be happy with a clunky one-off impl for that function

15:57 as you say, it probably means doing some custom classes

15:57 amalloy: brainproxy: i don't think you're getting what i'm saying. i'm saying, all you can do is reimplement restfn, and if you do you won't be getting around the restfn penalty

15:58 brainproxy: so there's no way to have a custom wrapper dispatch w/o using RestFn on the arities that aren't vararg?

16:00 patchwork: hiredman: Yes, I have verified they are longs

16:03 hiredman: how?

16:03 clojurebot: with style and grace

16:03 hiredman: ~botsnack

16:03 clojurebot: Thanks! Can I have chocolate next time

16:03 patchwork: (class a-long) --> java.lang.Long

16:04 hiredman: and you are checking that right before you hand off to clojure.java.jdbc?

16:05 patchwork: hiredman: Yes, they are verified longs right before they are passed to clojure.java.jdbc/execute!

16:06 hiredman: what jdbc driver are you using? if I recall by default clojure.java.jdbc uses the .setObject method, which is up to the driver to interpret

16:06 kaiyin: could anyone help me figure out what went wrong with this macro? https://gist.github.com/kindlychung/c226d6e7680a31614d38

16:06 patchwork: [postgresql/postgresql "8.4-702.jdbc4"]

16:07 hiredman: do you have any dependencies that might be doing some antisocial like globally changing how clojure.java.jdbc sets parameters?

16:07 something

16:08 patchwork: hiredman: How could the way clojure.java.jdbc handles parameters be globally changed?

16:08 I can look around for that...

16:09 hiredman: patchwork: there are protocols you can extend

16:10 dogonthehorizon: Hey folks, I have a bit of a puzzler: https://gist.github.com/dogonthehorizon/ba7feb3c08202f61b004 I'm attempting to compare reducers v tesser performance when operating on a sqlite result set of ~1mil rows. On a cold run tesser outperforms reducers by a good 3seconds, but on each successive run the reducers routine gets faster until it consistently outperforms tesser by about 2 seconds. Can anyone help me

16:10 understand the performance difference over time?

16:10 hiredman: you could start with an empty project, confirm that the parameters are correct, then either add deps to the empty project until they go bad, or remove deps from your real project until it goes good

16:12 gfredericks: project bisect

16:12 justin_smith: project netsplit?

16:14 brainproxy: hiredman: execellent point re: value/identiy, but in my use case the fact that vary/with-meta changes the identity works for me

16:14 gfredericks: with-meta always changes the identity, it just sometimes doesn't change the value

16:14 hiredman: dogonthehorizon: that is sort of the definition of how a jit works

16:15 chouser: It looks like js-delete doesn't work with advance compilation. Is this a known issue?

16:16 hiredman: dogonthehorizon: I think you have a lot going on here, sqlite, some sql dsl, etc, I would load the data in to memory and try each there

16:16 dogonthehorizon: hiredman: does that mean that tesser does not take advantage of the JIT as well as core.reducers? Otherwise I'm afraid I don't follow why reducers get faster to a much larger degree than tesser :/

16:16 brainproxy: gfredericks: good point; in my use case it's more that the value changes which makes possible what I'm doing

16:16 justin_smith: dogonthehorizon: some things can be JIT'd better than others. Not all code is equally analyzable / optimizable

16:17 hiredman: dogonthehorizon: I am not sure how that sql dsl is operating, but my understanding is the sqlite driver doesn't allow for any concurrency (although that may just be for writes) so if the results returned by that sql dsl are lazy in some way, and tesser is reading them in many threads that is going to effect things

16:18 dogonthehorizon: tesser likely has a larger overhead to its folds to support doing them concurrently

16:19 overhead not just in terms of cycles, but of code that exists that has to be inlined (which can blow the inlining budget) or conditionals or whatever

16:20 and, depending on what the sql dsl is returning, calling fold there for the reduces example my just be doing a single threaded reduce

16:20 just too many variables

16:20 dogonthehorizon: Hmm, that makes some intuitive sense. I'm using sqlkorma for the selects and its unclear from the docs whether the resultset is lazy or not. Based on my reading tesser forgoes fork/join pools (like reducers) in favor of managing threads itself.

16:22 Good food for thought though, thanks for pointing me in the right direction folks :)

16:34 kaiyin: could anyone help with this? http://stackoverflow.com/questions/30086634/clojure-lang-arrayseq-cannot-be-cast-to-clojure-lang-ifn-error-in-macro/30086887#30086887

16:39 brainproxy: ,(let [r (range)] (first r) (realized? r))

16:39 clojurebot: #error{:cause "clojure.lang.Iterate cannot be cast to clojure.lang.IPending", :via [{:type java.lang.ClassCastException, :message "clojure.lang.Iterate cannot be cast to clojure.lang.IPending", :at [clojure.core$realized_QMARK_ invoke "core.clj" 7224]}], :trace [[clojure.core$realized_QMARK_ invoke "core.clj" 7224] [sandbox$eval25 invoke "NO_SOURCE_FILE" 0] [clojure.lang.Compiler eval "Compiler.ja...

16:39 brainproxy: ^ that same expression works in 1.6

16:39 clojure i mean

16:40 gfredericks: kaiyin: you want (cond2 ~(next (next body)))

16:40 brainproxy: ,(let [r (map inc [1 2 3])] (first r) (realized? r))

16:40 clojurebot: true

16:40 gfredericks: kaiyin: your line had two problems; the loud one was that you were calling (body)

16:41 puredanger: brainproxy: we are aware of this change and don't care

16:41 kaiyin: gfredericks: yeah, that one was fixed.

16:41 brainproxy: puredanger: no problem, was just curious if it's the expected behavior

16:43 kaiyin: gfredericks: ah, i see, i think it's (cond2 ~@(next (next body))) that i need.

16:43 gfredericks: kaiyin: ah right

16:47 seancorfield: Can CIDER (in Emacs) connect to a bare nREPL server (that does not use the CIDER middleware)?

16:48 Frozenlock: seancorfield: yes

16:48 But you'll have limited functionality.

16:53 seancorfield: Frozenlock: that's fine... I just want a basic connection... now the more interesting question: can CIDER connect to remote bare nREPL server without attempting to use SSH and tunneling etc?

16:53 clojurebot: Pardon?

16:54 seancorfield: So far cider (0.8.1 in Emacs Live) has defeated any and all attempts of mine to persuade it to connect to remote server on a given port...

16:55 I found an issue (now closed) that seems related where the presence of a server in .ssh/known_hosts seemed to cause SSH behavior but that doesn't apply in my case and I still can't get it to simply use an IP and port for a basic connection

16:57 Frozenlock: Can't help really help you there; I always use ssh port forwarding when connecting to a remote repl.

16:58 Wait, that's what you are doing, right?

16:58 turbofail: i feel like the nrepl server probably only allows connections from the local machine, so you have to SSH tunnel

16:59 by default, anyway. because there's no security to speak of otherwise

16:59 amalloy: brainproxy: they're changing a number of lazy-seq producers in 1.7, to instead produce reducible things or transducer sources or whatever it is these days

16:59 Frozenlock: turbofail: I regularly connect to repl on other machines from my lan, so I doubt it's the default.

17:00 puredanger: amalloy: seqs with fast reduce paths

17:00 turbofail: Frozenlock: really? hm. that's probably not a good thing

17:00 puredanger: amalloy: although you should really not think of them as "lazy-seq" producers, they just happened to produce seqable things that were lazy seqs in the past

17:01 amalloy: puredanger: i think it would be nice if realized? returned true for things that aren't realizable, instead of throwing an exception, so that you at least get reasonable behavior out of it

17:01 and iterate is documented to return a lazy seq

17:01 so it's a bit harsh to tell people they shouldn't think of it as a lazy-seq producer

17:02 seancorfield: Frozenlock: with nrepl.el you could just connect directly to a remote repl without ssh

17:02 puredanger: amalloy: hmm, maybe fair in that case

17:02 it does still produce a lazy seq, just not a LazySeq :)

17:03 seancorfield: turbofail: no, the nrepl server happily accepts lein repl :connect ip:port from another machine without ssh involved

17:03 amalloy: puredanger: 1.7 is introducing a bunch of backwards-incompatible changes, which is fine, but it feels to me like the attitude of "we're only changing the behavior of things you shouldn't have depended on" is a bit tough to swallow

17:04 because it's not like many things in clojure really have a contract, other than "what they happen to do in this version"

17:04 puredanger: it's not introducing a "bunch" of backwards-incompatible changes

17:04 we've gone to great lengths to remain compatible imo

17:05 and I'm now thinking maybe we should implement IPending on those new types...

17:06 amalloy: puredanger: it's true, you're not really introducing a bunch of those changes. there's one big change, which ripples into a lot of smaller behavior changes that aren't expected

17:06 MietroP: /msg NickServ VERIFY REGISTER MietroP mmwczdwqjjza

17:06 oddcully: BUSTED

17:06 puredanger: amalloy: with great benefits. language evolution is hard.

17:06 amalloy: puredanger: sure. like i said, i think breaking changes are fine, and to be expected

17:07 brainproxy: puredanger: probably does warrant a mention in changes.md since there is an example dating back to v1.3 in that same document which calls realized? on a (range)

17:07 amalloy: what's frustrating is that i hear "this is breaking stuff that you shouldn't have done anyway"

17:08 puredanger: breaking changes are not fine and not expected

17:09 there are a few we're aware of and decided to live with

17:09 brainproxy: I'm excited though for broad support to make transducers fast

17:09 I decided to dive into them last month, and it struck me how important a pattern they are

17:10 puredanger: amalloy: because Clojure is "delicately specified", we are naturally always walking a fine line

17:11 Bronsa: while on the subject, at the risk of sounding like a broken record I still think making iterate a generator when used in a reduce context is neither intuitive nor a performance win

17:11 timvisher: anyone know how to create a trigger in mysqlf from a ragtime migration?

17:12 puredanger: thinking back to when we talked about IPending, things like iterate, cycle, and (infinite) repeat are never realized because they're infinite, so it was unlikely anyone was calling realized? on them to do something useful

17:12 but certainly for finite repeat, that might be useful, or in contexts where you don't know what you have it might be

17:13 brainproxy: it would be cool if it were possible to ask a lazy thing if it knows whether it is *fully* realized

17:13 TimMc: MietroP: ruh roh

17:14 MietroP: ?

17:14 turbofail: nice password

17:14 MietroP: hahahaa

17:14 ok

17:14 trying to get used to the irc

17:15 amalloy: puredanger: that's not true at all: iterate, cycle, and infinite repeat returned true for realized? all the time

17:15 (by which i mean, often, not always)

17:15 puredanger: yeah, you're right

17:15 amalloy: it returns true if the seq is realized up to the current element, not all the way to the end

17:15 puredanger: like I said, I think it's probably worth going back to this before we release

17:17 http://dev.clojure.org/jira/browse/CLJ-1726

17:18 amalloy: puredanger: i think it would help a lot, at least for realized?, if (realized? 5) returned true: "5 isn't a lazy thing I understand, so I guess it must be realized." in previous versions, that would have made realized? work smoothly for seqs from iterate, since its first element is non-lazy

17:18 (where of course i mean anything not IPending, not just 5 specifically)

17:19 puredanger: worth considering

17:22 TimMc: "Delicately specified" is one way of putting it, yes. :-)

17:22 seancorfield: Frozenlock: and the answer is that the bug is fixed in cider 0.8.2 but emacs live uses 0.8.1 and the update-live-packs script is currently broken /cc turbofail

17:24 puredanger: amalloy: I just looked at crossclj and github and I think there are very few uses for realized? with lazy seqs, although I do see a few. most are for other delayed computations.

17:25 kaiyin: how can i disable code snippets in cursive?

17:26 cfleming: kaiyin: Tools->Editor->Live Templates, uncheck "Clojure"

17:27 kaiyin: cfleming: cool!

17:28 cfleming: kaiyin: Sorry, that should be Settings->Editor->Live Templates

17:28 kaiyin: yeah, i reckoned so. :)

17:30 amalloy: puredanger: yes, most of the time when people use realized? on a lazy seq they are actually doing something pretty fragile and/or wrong

17:30 but, eg, i know lighttable uses (used?) it to decide when to truncate a lazy seq in its instarepl

17:30 puredanger: which is to not to say that we should break it for the few people that are using it :)

17:30 cfleming: puredanger amalloy: I use realized? on lazy seqs and would be sad if that went away

17:30 puredanger: it's not going away

17:31 cfleming: puredanger: Then I'm not sad

17:31 puredanger: was just getting out my caulking gun

17:31 seancorfield: Frozenlock: update... I figured out that in order to run update-live-packs, I first need to git submodule init / git submodule update!

17:32 * seancorfield searches World Singles code base for realized? and is relieved to see we don't use it :)

17:32 TimMc: Same here.

17:33 We use it on one promise.

17:33 cfleming: puredanger:

17:33 Oops

17:34 puredanger: TimMc: we were specifically talking about its use with lazy seqs

17:34 cfleming: puredanger: For context, I use that in the debugger, so I can show the realised elements of a seq without actually provoking any further realisation

17:36 puredanger: Actually, looking at the code I lie - I check whether a seq implements IPending, and if so call isRealized on it.

17:36 puredanger: is that likely to be fragile with all these new reducible things?

17:36 puredanger: there's a wee regression there, but we'll fix

17:38 amalloy: cfleming: out of curiosity, do you correctly handle seqs that are only part-lazy? like (list* -2 -1 (range))?

17:39 cfleming: amalloy: yeah. This is a renderer for anything implementing ISeq - I walk it calling next() and at each step test for IPending and call isRealized if it implements

17:39 amalloy: lovely

17:39 puredanger: and what if it doesn't?

17:40 cfleming: puredanger: Then I call first() and use the value

17:41 I do this in two contexts - showing the values in the debugger, when I iterate the seq as described and render the values, and when just counting the number of realised elements - in that case I don't call first(), I just iterate

17:41 I just use the IPending/isRealized check to stop iteration

17:42 puredanger: so the regression here is on returns of ~range, repeat, cycle, and iterate which now don't return IPending seqs

17:43 cfleming: puredanger: Ok, they'll blow the stack in the Cursive debugger, then

17:44 (which should be handled elegantly, but isn't ideal)

17:44 amalloy: cfleming: wait, really? you mean that a single long non-lazy seq currently blows the debugger stack?

17:45 cfleming: amalloy: No, but instead of seeing your values rendered in the debugger you'll see a StackOverflowException

17:45 amalloy: i.e. it'll be caught, handled and rendered nicely, but you won't see what you want to see

17:45 daviid: i'm trying to get some help from imagejdev but no answer, i guess no one uses clojure there ..., let me ask here again, here is a better description maybe: http://paste.lisp.org/+364S/1

17:45 amalloy: cfleming: that seems super weird. can't you do it iteratively instead of recursively?

17:46 cfleming: amalloy: I'm an idiot. I do do it iteratively. So you'll see the moral equivalent of an endless spinning wheel.

17:47 amalloy: interesting

17:47 cfleming: amalloy: But you still won't see what you'd really like to see, which is the thus-far-realised elements of your seq

17:47 puredanger: how often is that none of them?

17:47 dpark: I am curious whether anyone is using om in production. I recently switched from backend to frontend, worked through the om tutorials, developed an application that works great in a dev environment, but when using advanced optimization, om seems to break. This is easily reproduced directly from the tutorial, see https://gist.github.com/daviddpark/97a4e878c83c95f1074f Any ideas?

17:47 amalloy: cfleming: suggested feature: do something like eclipse's java debugger does for arrays. which is to display the first 10 elements, and a [more] button or something like that

17:48 cfleming: puredanger: A lot of the time

17:48 puredanger: dpark: you might want to ask in #clojurescript but yes, many people use Om in production

17:48 dpark: puredanger: Thanks! Sorry, wrong window!

17:49 puredanger: cfleming: cool, just wasn't sure. I guess if you've already used it in prior code above the point where you stop you would see that

17:49 cfleming: amalloy: So if you're talking about paginating long results, IntelliJ automatically does that. I haven't added another [more] button to explicitly realise elements from the seq, though.

17:49 puredanger: Sure, I think in 99% of the cases your seq is either 0% or 100% realised.

17:50 puredanger: if only there was a way to eagerly apply composable transformations to a collection

17:50 TimMc: puredanger: I know, just confirming we don't use it that way.

17:50 amalloy: cfleming: i meant for realize seqs. you said you currently loop over all realized elements, even if that's a lot. i was suggesting you stop after 10 items or whatever, even if #11 is realized, and wait for the user to tell you to keep going

17:55 brainproxy: puredanger: what do you mean?

17:56 puredanger: I was just making a joke about transducers and avoiding laziness when you want to :)

17:57 brainproxy: ah i see, yeah, I was thinking "hey, that's what I *thought* transducers did...", didn't realize you were joking :)

17:58 puredanger: too sly I guess

17:58 the new LongRange actually has multiple ways it can be walked and "realization" has different senses for them

17:58 amalloy: puredanger: it was just sly enough that i was thinking of writing "wait, is this a sarcastic plug for transducers?"

17:58 but then i realized, yes, it is

17:58 puredanger: (no pun intended)

17:59 cfleming: amalloy: Yeah, I'll add something like that sooner or later. The pagination is actually achieved by reusing the IntelliJ array renderer, which it uses for for all collections under the hood (i.e. renders them into an array then shows that). I'd have to write a new renderer to chunk it as you describe.

17:59 puredanger: you can walk a LongRange as a seq with first/next and then it's always realized (the value for first() is always computed)

17:59 if you walk it as a chunked seq though, it may not yet have forced the chunk (although the first() is still available)

17:59 brainproxy: when I started looking at transducers, one of questions I had was whether it would be possible for members of the composition (which in turn may be the result of composition) to refer to one another

18:00 puredanger: (none of that is particularly important, just interesting to muse about)

18:00 brainproxy: so you get recursion; and/or to have lazy composition stacks that basically act as an interpreted program

18:01 puredanger: well each intermediate "step" will complete before a new value is produced. that seems bad in tandem with unbounded recursion.

18:01 kaiyin: could anyone have a look at this? http://stackoverflow.com/questions/30088399/imposing-restrictions-on-function-args-in-clojure

18:02 puredanger: breaking the first rule, have you considered a macro? :)

18:02 brainproxy: puredanger: it does require one to have a mechanism so say "go to the end", in addition to plain return or returning @reduced

18:03 but it's actually feasible; I went from having an impl of the idea that was 2 orders of mag. slower than normal comp to one that's only 3x - 5x slower

18:03 still working out some of the details, but it plays nicely with normal comp

18:04 i.e. you can build stacks that have "normally composed" parts and other parts which use this other kind of comp that allows for recursion/interpretation

18:05 puredanger: kaiyin: any time you find yourself writing the same thing over and over again you should try to pull it out into a function

18:05 which you did

18:05 if you still find yourself doing that, then it's worth considering whether a macro might help

18:05 amalloy: i dunno, puredanger, i don't think a macro is the "first" answer here for kaiyin. the answer is to make qc take extra arguments for whatever customizations you want, so you can write (qc coll 2) to check that args is 2 or whatever. or (qc {:count 2} coll) is probably better

18:05 later you can wrap calls to qc in a macro if there's some reason to, but so far i don't really see one

18:05 puredanger: yep

18:05 amalloy: because what is the macro really going to do? it's going to do exactly what qc does, as a function

18:10 brainproxy: qc could be a function factory, could it not? so you pass in * / + etc. and you get back the equiv of f1,f2,f3

18:10 kaiyin: amalloy: I really miss a type system here, so that when you are applying a function to a certain instance, you know for sure certain criteria are satisfied.

18:14 daviid: how can i list the content of a jar fro clojure?

18:14 puredanger: daviid: command line or programmatically?

18:14 jar tf foo.jar

18:14 works on the command line

18:15 oddcully: unzip -l foo.jar does too

18:15 brainproxy: kaiyin: i may misunderstand what you were asking, but does this help? https://gist.github.com/michaelsbradleyjr/6f7dc255b6b9cef60384

18:17 TimMc: Hey, do any of y'all deploy stuff to Maven Central using Leiningen?

18:17 kaiyin: brainproxy: yeah, i guess that's a nicer way to put it than i did. thanks!

18:17 brainproxy: kaiyin: also, you could pass in predicate function/s in addition to op, paired with exception messages

18:17 TimMc: Someone at Sonatype asked if I wanted to contribute to documentation on how to do so, and I'm wondering if there's anyone I can get to review or help write it (once I get around to it.)

18:18 amalloy: daviid: also if you're using emacs, you can just open the jar file, and it auto-expands the contents to treat it as if it were a directory

18:19 oddcully: same for vim

18:19 kaiyin: brainproxy: cool.

18:25 TimMc: Fun fact: You can edit the jar of a running clojure process and use require :reload to make the changes take effect.

18:25 daviid: lost my connection again, i'm back

18:25 TimMc: So make sure to put emacs on your production servers. ;-)

18:26 brainproxy: kaiyin: this code isn't tested, but something like https://gist.github.com/michaelsbradleyjr/7a7bc10d0e28ff39759d

18:29 kaiyin: brainproxy: why do you need a doall here?

18:30 brainproxy: to force realization of the lazy seq returned by map

18:30 actually, there's probably a better abstraction than doall map

18:30 lemme see...

18:33 amalloy: brainproxy: you want doseq

18:34 brainproxy: was just cooking up a rev w/ doseq :)

18:34 amalloy: also, as currently written it's indented wrong: (apply ...) should be further right. and you don't want (apply op coll), just (op coll)

18:35 brainproxy: indeeed

18:37 no, you do want apply

18:37 kaiyin: here's the doseq version https://gist.github.com/michaelsbradleyjr/c700e265a64c2f2feb91

18:39 amalloy: oh, i see. i thought op was the checker, but i see it's the actually-do-work function

18:39 brainproxy: right

18:41 kaiyin: if guarding function calls is what you're actually interested in, i.e. in addition to how to leverage HOFs, maybe look into clojure's core.contracts facility

18:41 also, there's :pre and :post for functions

18:42 see also core.typed and perhaps prismatic's schema

18:42 kaiyin: is there a log of this channel somewhere? my pc went asleep a few minutes ago, and i might missed something.

18:42 have missed.

18:43 brainproxy: kaiyin: see http://logs.lazybot.org/irc.freenode.net/%23clojure

18:45 kaiyin: wonderful. :-)

18:52 TimMc: ~logs

18:52 clojurebot: logs is http://clojure-log.n01se.net/

18:52 TimMc: ^ there too

18:52 amalloy: ~lazy-logs

18:52 clojurebot: lazy-logs is http://logs.lazybot.org/

18:53 amalloy: i know it was already linked, just pointing out that there's a factoid for it

18:55 TimMc: good to know

19:00 daviid: what information can I ask, from clojure repl, upon a jar content?

19:00 amalloy: roughly none

19:01 daviid: because i don't know how to debug my problem

19:01 java -cp clojure.jar:ij-core.jar:mc.jar:cljs clojure.main

19:01 list the content of mc.jar please ...

19:01 what functions are defined...

19:01 amalloy: don't do that from inside the repl, as people mentioned

19:01 do it from your shell, or your editor

19:02 TimMc: It's *possible* to do it from the REPL, but I don't think anyone has made a library to make it pleasant or easy.

19:03 daviid: i need to do it from the repl

19:03 TimMc: Interesting claim, tell me more. :-)

19:04 daviid: more is how can i debug this :) http://paste.lisp.org/+364S/1

19:10 anyone knows if Albert Cardona appears here from time to time ? he wrote http://imagej.net/Clojure_Scripting

19:17 TimMc: daviid: Remind me why you're not using leiningen?

19:19 daviid: i use emacs

19:20 i'm trying to understand why the jar works perfectly fine from fiji [which just ffer an gui over inagej] and i can't use it from clojure

19:23 TimMc: Well... it's not emacs vs. leiningen. Those are two tools that many, many people in the Clojure community use together. One is an editor (among other things!) and the other is a build tool.

19:24 I hate to say it, but you're going to have a hard time getting help if you don't have a pretty good reason not to use an actual build tool -- people are going to get hung up on that (for good reason.)

19:26 bcm: or boot? :)

19:27 daviid: TimMc: i don't understand, I don't build anything, I'm trying to use a jar from another user, exactly the same way i'm using ij-core.jar, clojure.jar ...

19:28 I don't see how leningen would help me with that respect

19:30 amalloy: leiningen makes it a lot easier to depend on other jars, by downloading them and managing your classpath automatically

19:31 i don't think whatever you're currently running into is related to your choice to not use leiningen, but it will be harder for anyone else to reproduce without a leiningen project

19:31 the main problem is your insistence on doing everything from a clojure repl, when several people have told you that is the wrong way to do it and it's really hard

19:41 kaiyin: amalloy: what if the jar file is not hosted on maven or clojars? e.g. http://www.siegmann.nl/epublib

19:41 amalloy: kaiyin: first, you get a mob together with pitchforks and torches

19:41 but then you shrug your shoulders, and install it locally under a groupid of your own

19:42 or publish it to clojars, again under a groupid of your own

19:42 so that you can carry on using leiningen like a civilized person, and get all your other dependencies

19:43 kaiyin: nice.

19:44 amalloy: how exactly do you install it locally?

19:45 amalloy: kaiyin: as i recall, if you depend on a jar that doesn't exist yet, lein prints instructions for how to install a jar with that groupid/artifactid

19:46 kaiyin: amalloy: ok, that's cool.

19:46 amalloy: hm, no it doesn't

19:47 but http://www.elangocheran.com/blog/2013/03/installing-jar-files-locally-for-leiningen-2/ has the instructions that i think used to be printed

19:49 daviid: i think that fiji does some hidden stuff to pretend that the filsystem is as the jar has been defined, maybe

19:50 anyway, thanks all, bbl have to run

20:13 timvisher: has anyone created database triggers from clojure?

20:20 erikcw: If I have a vector of core async chans, how can I map over the that vector to take an element from each chan? I’ve tried cljs.core.async/map but that just seems to return a single item. What am I missing?

20:21 justin_smith: erikcw: (map #(<! %) chan-vec)

20:22 no need for a special core.async version of map when you are mapping over a vector

20:22 turbofail: will that work with goroutines?

20:22 i feel like it wouldn't

20:23 justin_smith: ahh...

20:23 (map #(go (<! %)) chan-vec) maybe? I forget about that goroutine issue sometimes

20:23 erikcw: justin_smith: I get an error saying “Uncaught Error: <! used not in (go ...) block” when I try that

20:23 justin_smith: riht

20:23 *right

20:24 you would have to manually insert a go in there, or find some other solution

20:24 brainproxy: you'll still end up w/ a vector of channels

20:24 justin_smith: yeah, haha

20:24 right

20:24 brainproxy: i've been thinking about the same thing

20:24 but haven't spent any time on a "solution" yet

20:25 turbofail: the basic problem is that goroutines only capture a local continuation

20:25 brainproxy: maybe a variant of transduce

20:26 it would return a channel itself

20:26 erikcw: Tricky getting the values out!

20:26 brainproxy: and for each channel in the collection it would park before performing the xform and handing off to say ocnj

20:26 *conj

20:28 (<! (a/transduce xform conj [...chans...]))

20:29 there is a reduce function in the the core.async ns; maybe it would be sufficient to impl a/transduce with a call to that rather than regular reduce

20:29 not sure

20:29 justin_smith: would a merge of the channels suffice, or does it strictly need to take only one thing from each?

20:30 erikcw: justin_smith: there is only 1 thing in each

20:30 justin_smith: do they need to come in order?

20:30 erikcw: nopes

20:31 justin_smith: if no, merge will suffice I think?

20:31 erikcw: ok, I’ll give that a try

20:31 thanks guys!

20:31 justin_smith: https://clojure.github.io/core.async/#clojure.core.async/merge

20:32 turbofail: there's always the callback API and manual CPS transformation to fall back on

20:39 brainproxy: justin_smith: the issue I see with merge is that it doesn't use the :priority option for alts!

20:39 so the results could be in any order, right?

20:39 as opposed to the order of the channels in the vector

20:40 justin_smith: right, I alreayd asked erikcw if that would be OK

20:40 *already

20:40 brainproxy: ah, missed that

20:57 justin_smith, erikcw: https://gist.github.com/michaelsbradleyjr/ca75a0d38e6e84cdabb4

21:02 actually, nvm; I think alts! completes at most one of the chan ops

21:06 creese: When I have a macro that uses a third-party lib, I need to list that lib as a dependency. Why is that?

21:18 Bronsa: creese: it's a compile-time dependency and you're compiling just-in-time

Logging service provided by n01se.net