#clojure log - Apr 15 2013

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

0:07 thm_prover: anyone here using shen.clj 0.1.6 ?

0:07 I can't even define a function when trying to follow http://www.shenlanguage.org/learn-shen/tutorials/shen_in_15mins.html#shen-in-15mins

0:07 something looks broken

0:11 amalloy: thm_prover: that article looks kinda badly written, and last i heard the effort to implement shen in clojure is far from finished

0:12 thm_prover: amalloy: I have the actual book "The Shen Language"

0:12 examples from chapter 2 there also does not work on shen.clj

0:12 I'm using https://github.com/hraberg/shen.clj

0:12 should I be using somethign else?

0:12 it appears that basica + - * / and or works fine ... but it's define that does not work

0:12 and being able to define functions is sorta important

0:12 it also seems liek a superficial problem, i.e. a namespace clash of some sort

1:15 llll: https://github.com/drcode/webfui

1:15 seems like a serious framework

1:16 Raynes: Had me at wingdings.

1:16 llll: wingdings?

1:25 callen: llll: new to computers huh?

1:26 Raynes: the new hotness is to use unicode instead of wingdings :P

3:19 ucb: does anybody know if nrepl has a who-calls function?

4:21 eriktjacobsen: Anyone around that knows the internals of pmap / futures well enough to debug very odd behavior?

4:22 ucb: eriktjacobsen: I'm not that well versed but I'm happy to lend a hand

4:23 eriktjacobsen: ok, will try to explain. (actually tbh I can't even track it 100% to threading). I'm reading from a queue using bandalore, and I have a callback function that fetches some data based off the message, and processes those

4:23 ucb: ok

4:24 eriktjacobsen: Now, when I run this callback by hand, a little odd behavior happens, namely the first 2 items in the pmap get run right away, then there is a 10-20 lag in std output , then all the items get processed and work correctly

4:25 However, when I pass the callback through this "deleting-consumer" macro (which I'll post), ONLY the first two items run, and the rest never happen.

4:25 ucb: ok

4:26 eriktjacobsen: (defn deleting-consumer[client f]

4:26 (fn [message](let [ret (f message)]

4:26 (delete client message)

4:26 ret)))

4:26 Now, obviously since my first two items run correctly, I'm inside the callback

4:27 I can't fathom any way for that function "deleting-consumer" to affect execution INSIDE the callback (f)

4:27 ucb: is (delete...) thread safe?

4:27 eriktjacobsen: and yet, based on using it or not, either my first 2 items run, or all 500 of my items run

4:28 tbh, I'm not sure it is a bandalor library app, but since it doesn't get called until f returns, I don't see how it would affect the pmap inside f

4:28 Could you cover how it might do that?

4:29 ucb: oh, no, sorry, I was just wondering

4:29 because if you're pmaping deleting-consumer, then both f and delete should be thread safe

4:29 otherwise bad things will happen^tm

4:29 eriktjacobsen: Yeah, I agree… however this is even for a single message and not wrapping it in a pmap

4:29 ucb: gotcha

4:31 eriktjacobsen: would you mind pasting the code that calls (deleting-consumer...)?

4:31 eriktjacobsen: Sure… This code WORKS 100%

4:31 (map (comp channel/channel-callback :body) (cemerick.bandalore/polling-receive pipeline.queue.core/client (cemerick.bandalore/create-queue pipeline.queue.core/client "eriktest") :max-wait Long/MAX_VALUE :limit 10))

4:31 ucb: eriktjacobsen: you said that manually running the callback f runs fine, but not when running inside deleting-consumer?

4:32 eriktjacobsen: This code breaks 100% of the time (only gets first 2 items inside the callback fetch)

4:32 (map (cemerick.bandalore/deleting-consumer pipeline.queue.core/client (comp channel/channel-callback :body)) (cemerick.bandalore/polling-receive pipeline.queue.core/client (cemerick.bandalore/create-queue pipeline.queue.core/client "eriktest") :max-wait Long/MAX_VALUE :limit 10))

4:32 exactly

4:32 the only difference in the maps is the wrapping of deleting consumer, the (comp callback :body) is identical

4:34 ucb: well, and that you're using the client in both places now

4:35 I'm now wondering more than ever about the thread safety of all this, it could well be (I know nothing about badalore) that you're running your callback on the same message more than once

4:36 eriktjacobsen: well, that usage of client / deleting consumer is provided by the docs of Bandalore

4:36 Even if I was running the callback more than once, how could it short-circuit the execution inside the callback?

4:37 afaik, since it is suggested by the docs, doing a (pmap deleting-consumer polling-receive) is suggested and thread safe

4:37 ucb: what do you mean by shortcircuit?

4:37 eriktjacobsen: What I mean, is that once the callback is running, it should execute over 400 items. There are no points of early entry or exit

4:38 it is executing over 2, and then it just stops

4:40 the callback simply fetches a rest api which yields 400 items, which are pmapped over a database save

4:40 it is basically (pmap db/save (fetch message))

4:40 * ucb nods

4:41 ucb: have you tried a simple count fn with deleting-consumer?

4:41 eriktjacobsen: So whether that is wrapped, determines if the pmap *inside* runs over 2 items, or 400

4:41 ucb: something like inc and @atom or something?

4:41 eriktjacobsen: to see if it is running twice?

4:41 I would be ok if the behavior was simply running twice… it would be inefficient but easy to explain / code around

4:43 ucb: not necessarily, but rather to see whether it's to do with your code or bandalore's

4:43 to be honest with you, your explanation and the code you've shown me calls for a simplification of everything until you find what's breaking

4:43 in the sense that it all seems to make sense and that it should work, and yet it doesn't :)

4:43 eriktjacobsen: heh this is after like 8 hours of simplifying

4:44 ucb: oh dear :)

4:44 eriktjacobsen: and the fact that this is what I'm left with is not where I wanted to be… where a simple wrapping function affects the innards of callback.

4:45 Alright, so you suggest I throw an atom inside deleting consumer?

4:45 ucb: more like having f be something like (fn [_message] (swap! some-global-atom inc))

4:48 eriktjacobsen: it runs the callback once

4:48 atom is incremented exactly once per message

4:48 ucb: hum, eh? the atom has the right number in it?

4:48 oh, right, yeah, so the callback is run exactly once, each time

4:49 sorry, misread that as "callback is run only once"

4:53 eriktjacobsen: If there are any like…. REALLY basic things that I'm missing, I just started with clojure about 2 weeks ago

4:53 ucb: eriktjacobsen: I don't see any obvious issues but I could be well wrong

4:53 eriktjacobsen: it just boggles me that flipping deleting-consumer on and off is what breaks it

4:54 ucb: eriktjacobsen: considering that the inc callback does the right thing, then I'd look at your original callback to see what may be broken

4:54 eriktjacobsen: is it throwing an exception anywhere perhaps?

4:54 eriktjacobsen: I don't believe so, but the inputs to the callback are identical, and the first 2 items run correctly

4:55 is there anything about having the return referenced in a let vs going directly to the output of the highest-map ?

4:57 ucb: what do you mean?

6:06 iwo: hey, can anyone help me with an xml-zipper problem?

6:07 I'm having exactly the same problem described here:

6:07 http://clojure-log.n01se.net/date/2012-09-18.html#04:23c

6:07 this call: (xml-> my-zipper :sometag)

6:07 causes a NullPointerException

6:07 at clojure.zip$branch_QMARK_.invoke(zip.clj:73)

6:10 i'm using clojure.data.zip 0.1.1

6:10 clojure.data.xml 0.0.7

6:13 Apage43: i think data.zip chokes on the data.xml output on account of it being records instead of plain hashes. What happens when you just use clojure.xml/parse ?

6:17 or rather, clojure.zip/xml-zip isn't -quite- compatible with the output of data.xml

6:17 you could probably modify bits, but out of the box, data.zip and data.xml don't play together, at any rate

6:25 babilen: iwo: I use clojure.xml/parse and pl.danliejanus.tagsoup/parse-xml just fine with clojure.zip/xml-zip and clojure.data.zip.xml/xml->

6:26 *danieljanux that is

6:26 danieljanus :-D

6:33 iwo: Apage43: sorry, i realise that i _am_ actually using clojure.xml/parse

6:34 Apage43: ah

6:34 in that case that -is- weird

6:34 iwo: the strange thing is, this works perfectly well locally buy when we deploy it doesn't work

6:34 the only difference: java 1.6 update 31 vs java 1.6 update 24

6:35 Apage43: perhaps something is causing xml/parse to fail. If the XML file has a DTD and it can't fetch it perhaps

6:35 can you successfully parse an xml file in the repl on that configuration?

6:37 iwo: hmmm, not sure what would be the easiest way to create a repl on this server

6:37 the xml has no dtd...

6:38 the thing is, the parsing seems to work well but it's the zipper that has a problem

6:38 clojure.xml/parse completes successfully (is it lazy?)

6:38 oh, i guess it's sax, so it's lazy

8:05 _francis_: (source ns-publics)

9:34 berdario: Hi, I was thinking of writing a test like this

9:35 (is (= [1 whatever 3] [1 (gensym) 3])

9:35 that is, I only care about the first and third element of the vector...

9:36 I could destructure it, but I think it's easier/cleaner if I just supply it a second argument "whatever", that always equals to true...

9:36 I was thinking of using a mock to create "whatever", but apparently it isn't mantained anymore

9:36 what do you suggest?

9:36 ro_st: midje has an anything keyword. checkout what the do?

9:37 berdario: "checkout what the do?" ? btw I'll look into midje, thanks

9:37 ro_st: s/the/they

10:33 ucb: can anybody recommend a library for mock testing?

10:41 cldwalker: ucb: somebody's made clojure.contrib.mock https://github.com/EchoTeam/clj-mock, you could also try https://github.com/amitrathore/conjure

10:41 s/made/ported/

11:07 arrdem: is ^:depricated a thing?

11:08 s/depricated/deprecated/

11:10 technomancy: ucb: just use with-redefs

11:33 clgv: arrdem: it is keyword metadata at least ;)

11:34 arrdem: clgv: heh it is valid metadata we'll see if it does anything tho

11:34 clgv: arrdem: I do not think the compiler handles it by printing warnings or surch

11:35 arrdem: clgv: ok that's what I was afraid of. the dev list only mentions it in the context of javadoc generation.

11:40 aaelony: hey clojure community, I'm trying to use a local jar file for the Vertica database. I have the driver file locally, which I've tried to set up a local maven repo for, but still encountering "SQLException No suitable driver found for jdbc:vertica". My project.clj contains a dependency for [vertica/vertica "4.1.13"], a line for :local-repo "local_maven_repo", and also :repositories {"project" "file:local_maven_repo"}. Any help

11:40 appreciated.

11:49 mefesto: aaelony: i haven't used it but i hear this is the way to go: https://github.com/kumarshantanu/lein-localrepo

11:50 aaelony: also you can install a local jar file using maven directly: http://maven.apache.org/plugins/maven-install-plugin/install-file-mojo.html

11:50 aaelony: mefesto: thanks, I'll give it a try. Much appreciated!!!

11:53 mefesto: aaelony: and for good measure here is leinigen's view on the matter: https://github.com/technomancy/leiningen/wiki/Repeatability

11:54 aaelony: mefesto: yes, I've seen that before, but encountering nonpublic, proprietary jars is a part of life, unfortunately :(

11:55 nDuff: aaelony: Sure, but having your nonpublic, proprietary jars not be in a nonpublic, proprietary repo is a sign of sloppiness.

11:56 aaelony: Repeatable builds are still important for purely in-house artifacts.

11:56 aaelony: nDuff: I agree. I'm just trying to connect to a data warehouse...

12:04 hmmm, no problems with the lein localrepo install command, but still getting the "SQLException No suitable driver found" error message.

12:11 technomancy: aaelony: setting :local-repo and :repositories to the same place doesn't really make sense

12:12 aaelony: technomancy: yeah, I'm in the dark as to what the actual setting needs to be.

12:13 technomancy: :local-repo is if you want to use another directory as the local cache instead of ~/.m2

12:14 aaelony: technomancy: I see. I just pointed the lein localrepo install command to the current location of the jar file

12:15 I had tried this (https://gist.github.com/stuartsierra/3062743) a few week's ago, that is how the file got there

12:16 unfortunately, it hasn't yet resolved the issue though, and doesn't find the jar file at runtime

12:30 arrdem: ,(doc alter-var-root)

12:30 clojurebot: "([v f & args]); Atomically alters the root binding of var v by applying f to its current value plus any args"

12:31 arrdem: ,#'*foo*

12:31 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve var: *foo* in this context, compiling:(NO_SOURCE_PATH:0:0)>

12:33 papachan: ,(doc pprint)

12:33 clojurebot: It's greek to me.

12:33 arrdem: papachan: clojure.core.pprint is the namespace, /pprint is the main function

12:34 papachan: arrdem ok

12:34 arrdem: papachan: clojurebot may or may not have those symbols (:required) so I don't think he can ,(doc) em

12:34 s/symbols/vars

12:34 SegFaultAX: arrdem: The namespace is actually clojure.pprint

12:35 arrdem: -________-

12:35 you'd think I'd remember it for all I use it..

12:35 SegFaultAX: ,(map resolve (apropos "pprint"))

12:35 clojurebot: ()

12:36 SegFaultAX: Doesn't look like the namespace is referred.

12:36 ,(use 'clojure.pprint)

12:36 clojurebot: nil

12:36 juhu_chapa: Hi all! What is clojure's equivalent to java Object.class?

12:36 SegFaultAX: ,(map resolve (apropos "pprint"))

12:36 clojurebot: (#'clojure.pprint/*print-pprint-dispatch* #'clojure.pprint/pprint-indent #'clojure.pprint/pprint #'clojure.pprint/with-pprint-dispatch #'clojure.pprint/pprint-newline ...)

12:36 arrdem: juhu_chapa: &(doc class)

12:36 * arrdem is failing badly today

12:37 juhu_chapa: arrdem: Thank you!

12:37 papachan: cool

12:37 cmajor7: is there a way to parse UNR/URI route by Compojure? e.g. "http://context/aaa:bbb:ccc" to get a "ccc" as param? (Compojure uses [clout] colon internally, hence the question)

12:38 abeaumont: x

12:38 ops, sorry

12:40 SegFaultAX: cmajor7: You can use regex to match any portion of the URI.

12:41 https://github.com/weavejester/compojure/wiki/Routes-In-Detail

12:41 ["/foo/:weird" :id #

12:42 ["/foo/:weird" :id #"\w+(:\w+){2}"]

12:42 Except :id should be :weird.

12:42 * SegFaultAX drinks more coffee.

12:44 Anderkent: So, after the 20th time today I forgot to initialize a set to #{} and then wondered why (conj a-set :item) (contains? a-set :item) was false, did anything happen with the idea of optional typing for clojure?

12:45 arrdem: Anderkent: conj defaults to a sequence and (contains?) explicitly operates only on search structures not seqs

12:46 Anderkent: I know

12:46 * arrdem shrugs

12:47 ucb: technomancy: that's what I'd normally do, yet I need to mock a client inside a let, e.g. (let [c (some.ns/client)] (do-stuff c data))

12:48 Anderkent: arrdem: actually, if it 'explicitly only operated on search structures', I wouldn't have wasted so much time - it throws an exception 'tried to run contains? on ()', I immediately know what's wrong

12:48 but it doesnt do that, it just returns false

12:49 much harder to notice you did {:id-ste #{}} instead of {:id-set #{}} somewhere else ...

12:50 technomancy: ucb: I don't follow

12:51 ucb: technomancy: I can't really use with-redefs if the function I'm testing has the following structure: (defn f [args] (let [c (some.ns/client)] (do-stuff c args)))

12:51 technomancy: or can I?

12:52 technomancy: if there's a reason that won't work, it's not obvious from what you've pasted so far

12:52 Anderkent: (with-redefs [some.ns/client (fn [] my-mock-client)] (f)) should work

12:55 ucb: Anderkent: thanks for the example, for some reason I wasn't extrapolating to redef'ing ns/fn and to just redef'ing local fns

12:55 technomancy: thanks

12:55 Anderkent: thanks!

12:55 technomancy: here's an exclamation mark for you too: !

12:57 SegFaultAX: technomancy: Are you aware of any benchmarks for Jetty on Heroku using ring.jetty.adapter?

12:58 technomancy: SegFaultAX: not aware of any, no

12:59 SegFaultAX: technomancy: Is that the preferred application server on Heroku?

12:59 technomancy: SegFaultAX: yeah, jetty is your best bet

13:00 I/O is pretty variable on EC2 and Heroku by extension

13:00 so you'd have to have a pretty large sample size

13:00 SegFaultAX: Do you support other Java containers? Tomcat, for instance?

13:01 Anderkent: -> / #() interaction is really suboptimal :(

13:01 technomancy: SegFaultAX: of course; anything that runs on Ubuntu and responds to HTTP requests is fair game =)

13:02 I don't think any of the advantages of tomcat would actually apply on Heroku though

13:02 since we do containerization on the process level

13:03 but I've never used Tomcat; so who knows

13:03 SegFaultAX: technomancy: Do you pretty much always stick to Jetty? Even outside of Heroku?

13:04 technomancy: SegFaultAX: you mean me personally? I've only deployed like two web applications in the past 5 years.

13:04 SegFaultAX: Oh, heh. :)

13:05 technomancy: from what I gather, jetty is best unless you need 0) async or 1) integration into an existing Java ops environment

13:05 but I'm not an expert on the subject

13:06 cpoile: technomancy: is there a preferred front-end http server for load balanced, port mapping, serving static resources, etc. on Heroku? (or do you even need one?)

13:07 technomancy: cpoile: load balancing and port mapping are done for you

13:07 jetty is fine for static resources, but you can use a CDN too if jetty doesn't cut it

13:08 nginx might be slightly better, but not enough to justify the extra complexity vs bang-for-buck of a CDN

13:08 Anderkent: cpoile: as a reference, we're running a heroku app with aleph by simply doing java -jar ... So unless you're worried about performance, getting started is pretty easy and you don't need a container.

13:08 cpoile: so, you could have a couple jvms, each running jetty, one mapped to: mydomain.net/app1, the other to mydomain.net/app2?

13:09 technomancy: cpoile: typically you'd use separate subdomains for that

13:10 kanwei: is jetty event-based?

13:10 cpoile: technomancy: but then it would be on the same jetty/jvm? I'm just trying to figure out how to have apps isolated so that one misbehaved app doesn't bring down the other when I have to restart the jetty instance

13:11 technomancy: cpoile: separate subdomains would be separate JVMs

13:12 cpoile: Anderkent: does that mean your app is running on, say, 8080, and everything else is handled for you by Heroku?

13:12 SegFaultAX: Is it viable to host multiple sites on a single Dyno given the memory limitations?

13:12 Anderkent: cpoile: heroku tells you which port to bind via environment

13:12 cpoile: technomancy: ah, okay

13:13 Anderkent: well, I lied a little, I think aleph uses netty or whatever under the hood, so there is a container, but I'm not touching it

13:13 you could of course do the http chitchat manually, if you wish :)

13:13 technomancy: SegFaultAX: impossible to say without details

13:13 muhoo: yes it uses netty whiich uses nio

13:13 technomancy: memory usage varies hugely

13:15 cpoile: technomancy, Anderkent: thanks

13:21 noncom: hi! anyone heard of official clojure -> android port? i remember Rich was saying something, and there was a REPL of clojure-1.4.0 port to android, but nothing since then.. silence.. anyone knows anything?

13:23 arrdem: cemerick: found your old post on binding and lazy seqs, thanks!

13:24 rasmusto: am I weird for trying to use the function "filtercat"?

13:28 bbloom: rasmusto: why would that be weird?

13:28 rasmusto: although i may prefer a `clojure.core/for comprehension with a :when clause

13:29 rasmusto: bbloom: well, filtercat wasn't defined. I guss the for comprehension does the same thing (and is more flexible)

13:29 alexnixon: or just use mapcat and pass a function that returns nil for some elements

13:29 rasmusto: alexnixon: ah, mapcat skips nil ? that's good to know

13:30 alexnixon: ,(concat '(1 2) nil '(4 5))

13:30 clojurebot: (1 2 4 5)

13:30 rasmusto: alexnixon: cool, thanks :)

13:30 Anderkent: well, nil is an empty list, it makes sense for concat '(1 2) '() '(4 5) to give you back '(1 2 4 5) :)

13:38 noncom: (+ 1 2)

13:38 clojurebot: 3

13:38 noncom: (def bot "hi!")

13:38 alexnixon: Anderkent: I don't think it's quite right to call nil an empty list, though they often behave similarly

13:38 arrdem: noncom: clojurebot's sandbox doesn't allow for vardecls

13:38 noncom: (println bot)

13:38 heh

13:38 arrdem: noncom: also you want ,( <expression> ) for clojurebot

13:39 noncom: i think that all that hassle around truths, falses, nils and empty lists is because ppl can't agree on what they mean

13:39 arrdem: yeah, that's exactly what i was testing!

13:42 alandipert: nil isn't a list, but (seq nil) is nil and thus all is right in the world

13:44 kanwei: does anyone have advice for refactoring a "parser" like function that has a lot of "recur"s? https://gist.github.com/kanwei/e2c0415eb118ee79e4f1

13:45 because of immutability I feel like I have to repeat myself a lot

13:45 since i can't progressively "edit" a map

13:45 alandipert: kanwei: you can via reduce (starting w/ empty map)

13:46 kanwei: could be trixty though because of data being variadic, maybe involve a first pass to group ops and their args

13:47 kanwei: alandipert: yeah that's the problem i was having

13:47 Anderkent: well, it seems like every time you're just looking at one line

13:48 a reduce should fit straightforwardingly

13:48 give me 1 s

13:49 kanwei: it's a bit tricky Anderkent

13:49 i'm trying to parse https://gist.github.com/kanwei/eb6b7376498a7ce28035

13:49 the "info" parts can easily be reduced

13:49 but the "play" parts, order matters

13:49 Anderkent: sure

13:50 but you're still looking at a line at a time

13:50 kanwei: i guess i can have an accumulator inside the accumulator map

13:50 for stuff that needs order

13:51 Anderkent: https://www.refheap.com/paste/13646

13:51 that look right?

13:52 then of course if you want to add new opps easily, you could make step-game dispatch to a multimethod based on the op

13:52 thus allowing you to add support for more commands by simply declaring extra methods

13:55 kanwei: wow that's a lot better Anderkent, thanks!!

13:56 lynaghk: cemerick: is there a nice way to just set friend's *identity* so that I don't have to walk through the authentication workflows during, e.g., tests?

13:57 cemerick: lynaghk: binding, with-redefs, etc

13:57 lynaghk: cemerick: okay, yeah, I wasn't sure if that was the proper way to go about it or if you had a helper somewhere

13:57 cemerick: Ideally, you're passing the identity along explicitly ;-)

13:58 arrdem: :-)

13:58 lynaghk: cemerick: yeah dude, it's in the giant config to the fn that returns the ring handler =)

13:58 cemerick: lynaghk: nah, at runtime

13:59 lynaghk: cemerick: not sure I follow, then. I'm just throwing a middleware in that rebinds *friend/identity*

14:02 cemerick: lynaghk: I mean, in your app, you should ideally not refer to *identity* ever. Its value is always in each Ring request. The more you can eliminate use of dynamic bindings like that, the easier things are to test.

14:03 lynaghk: cemerick: I'm only referring to it so I can rebind it. My use case is wanting to return a ring handler where all requests are already "logged in" so that I can use that handler for testing

14:04 cemerick: I can't just remove the friend middleware entirely in those cases, since my routes use friend/authorize

14:05 cemerick: lynaghk: oh, this is full functional testing, i.e. having a dummy client tickle the app through HTTP, etc?

14:06 But, yeah, I painted people into a bit of a corner with friend/authorize

14:06 lynaghk: cemerick: yeah

14:06 cemerick: also doing interactive development where I'm restarting the server often and want to just have "development mode" always start the server as a logged in user

14:07 so I don't have to keep going through the form workflow

14:14 kanwei: is there anything more idiomatic for adding something to a vector inside a map, while returning the updated map?

14:14 (assoc game :plays (conj (:plays game) data))

14:15 arrdem: kanwei: update-in

14:16 ,(update-in {:name "arrdem" :plays ["mwo" "scII" "HoTS"]} [:plays] conj "LoL")

14:16 clojurebot: {:name "arrdem", :plays ["mwo" "scII" "HoTS" "LoL"]}

14:17 kanwei: (update-in game [:plays] conj data)

14:18 hmm cool thanks

14:19 so I can process 15Mb of csv files in less than half a second, not bad :)

14:20 arrdem: :D

14:20 'course you could cut that down to a few tenths if you used lex and yacc... but I can't recommend it

14:24 Luyt_: I once made a very quick CSV parser (in C) it would load in the CSV file into a buffer, make one scan over it, and leave pointers to the fields, and place \0's in the buffer where the fields ended

14:25 so, no copying of string data involbed

14:25 involved*

14:25 jweiss: my code has a ref that is being watched (using add-watch) for changes. One of the fields is a promise. But delivery of the promise does not show up as a change to the ref. So now what? Do I need to remove the promise and implement polling on that place in the ref myself?

14:26 arrdem: Luyt_: oh cute! so you got an array of string pointer linked lists out?

14:27 Luyt_: arrdem: If I remember well, I realloced the string pointer arrays when necessary (doubled the number of entries). There were no linked lists involved, but you could implement it with linked lists.

14:29 also, since I had advance knowledge about the size of the CSV files, I could hint my lib to pre-allocate 'big enough' pointer arrays. The realloc mechanism was only used in unforeseen exceptional situations.

14:47 noncom: so no one knows anything about clojure on android?

14:48 SegFaultAX: noncom: I don't really think it's viable right now.

14:48 n_b: noncom: Checkout out nightweb; IIRC hte author documented his experiences

14:48 SegFaultAX: noncom: Persistent data structures in particular don't jive well with the whole "don't create a shitload of temporary objects" mantra of Android land.

14:49 Luyt_: SegFaultAX: Does Scala suffer from the same?

14:49 noncom: :D

14:49 Raynes: $google lein-droid

14:49 lazybot: [alexander-yakushev/lein-droid · GitHub] https://github.com/alexander-yakushev/lein-droid

14:49 SegFaultAX: Luyt_: Scala has mutable variants for all of its primary data structures.

14:49 Luyt_: And to some extent you could use transient data structures in Clojure to ameliorate the problem.

14:49 Luyt_: But there are other technical limitations at play as well.

14:50 trptcolin: e.g. the `for` macro blows the stack :)

14:50 Luyt_: I understand why clojure developers want to escape the Java staightjacket

14:51 Did I say 'clojure developers'? I meant 'developers who'd like to use clojure'.

14:51 amalloy: jweiss: you can block on the promise separately

14:52 noncom: interestingly enough, the nightweb project.clj depends on [android/clojure "1.5.0"]

14:52 that one is on clojars

14:52 dnolen: SegFaultAX: from what I've heard, the GC issue on Android is less problematic than app startup time - and I know this is something under consideration for future versions of Clojure.

14:52 noncom: so looks like something is going on there

14:52 SegFaultAX: In my opinion the main issue is that using Clojure incurs a significant amount of incidental overhead. Or at least significant WRT devices limited in CPU, memory, and most importantly of all, battery.

14:53 amalloy: assuming that the promise itself isn't changing also, something like (future (notify-delivery @(get @the-ref :the-promise)))

14:55 stuartsierra: jweiss: A watch on a Ref does not get invoked when another mutable thing contained in the Ref changes.

14:56 Watches are only invoked when the state of the Ref itself changes, e.g. with `alter` or `ref-set`.

14:56 jweiss: stuartsierra: yeah i know :)

14:57 SegFaultAX: jweiss: Your original comment indicated that this was surpising behavior to you.

14:57 jweiss: no i am not surprised, i had just accidentally coded it that way without realizing the implication until i saw my program not doing what i expected.

14:58 i use the promise because other part of the code needs to block on that particular piece of data

14:59 so in order to get both the watcher responding to the change AND the blocking behavior, was wondering if i had to implement the polling myself\

14:59 amalloy: jweiss: polling is definitely crazy

14:59 promises exist to block on

14:59 stuartsierra: jweiss: You could do that. Or you could have whatever code which fulfills the promise also modify a Ref that you're watching.

15:00 SegFaultAX: Can promises have watches?

15:00 jweiss: yes

15:00 at least i think so

15:00 SegFaultAX: add-watch only lists agent, atom, var, and ref

15:00 stuartsierra: Clojure's Promises do not support watches.

15:00 jweiss: ah

15:00 well, anyway it wouldn't make sense

15:00 since it only changes once

15:01 noncom: so considering the problems that clojure currently faces on android, what do you think about using clojurescript instead? seems like no problems should be there..

15:01 stuartsierra: Some kind of callback for Promises is under discussion for Clojure 1.6.

15:01 SegFaultAX: jweiss: So?

15:01 jweiss: SegFaultAX: so if you want to watch it just use a future

15:01 SegFaultAX: stuartsierra: Then what's the problem?

15:01 jweiss: ^

15:02 stuartsierra: Sorry, not understanding your question SegFaultAX.

15:02 jweiss: SegFaultAX: i have one ref and a large number of promises

15:02 i wanted to just watch the ref and get ALL the updates.

15:02 cpoile: noncom: search for clojurescript phonegap, I was looking at a github repo doing this just recently

15:02 jweiss: not add watches to hundreds of promises

15:02 stuartsierra: jweiss: I have an experimental library at github.com/stuartsierra/cljque that attempts to provide this capability.

15:03 jweiss: Google Guava also has ListenableFuture.

15:03 amalloy: huh. how are you using hundreds of promises now? the only way i can think of would be to have hundreds of threads listening on them anyway

15:03 jweiss: i guess i will have to separate the data that gets blocked on , and the data that gets watched. using stuartsierra's original suggestion

15:03 SegFaultAX: stuartsierra: Any idea if the callback system in 1.6 is going to be like your cljque work?

15:03 stuartsierra: SegFaultAX: Don't know.

15:03 noncom: cpoile: looks like it's bout 2 yrs old )

15:04 jweiss: amalloy: well, not all of them get listened to immediately

15:05 so in reality only a handful are being watched at any given time

15:05 cpoile: noncom: that's good news, because both of the core libraries (clojurescript and phonegap or whatever it's called now) have advanced a lot since then. :)

15:05 jweiss: this is a test execution harness, so there's promises being watched for each thread of test execution

15:06 so that tests that depend on the watched test can be queued

15:07 stuartsierra: jweiss: If all you need to do is block, you might be able to use a java.util.concurrent.CountDownLatch.

15:07 jweiss: stuartsierra: that doesn't really solve the ref watching problem though, still a mutable object right?

15:08 stuartsierra: yes

15:09 amalloy: jweiss: i wonder if a lamina channel might be a better structure than a promise, if the project is flexible enough to make that change. you can register callbacks on those without tying up any threads

15:10 jweiss: amalloy: i'll take a look, threads are cheap enough, but worth a shot

15:10 amalloy: hundreds of threads aren't cheap :P

15:11 jweiss: amalloy: as i said, it's only a handful of threads at a time

15:11 when a test completes, the promise is delivered. that watch thread exits, a new test starts, and a new watch thread is created

15:11 arrdem: amalloy: the four year old laptop that hosts my blog defies you sir. I think I've dropped about 5k simultaneous futures and not managed to push it over.

15:12 SegFaultAX: Lamina looks pretty cool!

15:12 jweiss: i think on some systems you'll hit the process limit

15:12 but that can be raised with no problem

15:13 SegFaultAX: Just because you can do it doesn't make it cheap.

15:14 jweiss: huh, thanks amalloy lamina seems pretty well suited to what i'm trying to do

15:15 "Lamina also provides mechanisms to instrument code" <- seems especially interesting for a test harness that needs to track execution time, tracing, screenshots etc

15:15 amalloy: sweet, two converts. my side business shilling for ztellman is going well

15:19 SegFaultAX: And here he is. ztellman must have known we were talking about Lamina.

15:19 ztellman: ha, no, should I check the logs?

15:20 jweiss: ztellman: i was trying to fix a problem in my test execution harness, lamina seems like a good solution for not only that but several other things i was trying to do.

15:21 cpoile: question for anyone: what is the current state of clojure web app development? Has much changed since: http://brehaut.net/blog/2011/ring_introduction ? (Pedestal, but is that about it?) As in most/all apps are still using the ring ecosysem? (which is fine, I'm just curious)

15:21 ztellman: jweiss: well, if you have any questions, feel free to email me or the aleph mailing list

15:21 Luyt_: cpoile: I'm also curious how these clojure webapps are deployed. Behind nginx and gunicorn?

15:22 Does ring run compojure apps multithreaded?

15:23 SegFaultAX: Luyt_: Ring doesn't really anything related to running apps.

15:24 cpoile: Luyt_: from what I understand, any deployment scenario that works for a java servlet works for Ring-based apps (Jetty, bigger containers, behind nginx, you name it)

15:27 Luyt_: compojure -- ring -- jetty -- nginx -- internet <--- is that correct>

15:27 ?

15:27 amalloy: Luyt_: ring has adapters to the various java http servers. jetty is the most common adapter to use, and so ring apps are usually run multithreaded

15:28 Luyt_: LIke what gunicorn does for django and flask apps, I guess?

15:29 SegFaultAX: Luyt_: No, gunicorn is an application container. Ring is just provides Clojure adapters for existing Java HTTP servers.

15:29 Luyt_: Ohhhh...

15:30 SegFaultAX: Luyt_: I can't really think of a good Python analog for ring. WSGI is probably the closest thing, but that's still not entirely accurate.

15:30 Luyt_: Suppose I've written a compojure webapp which I want to put in production. How do I do that, given that I want to suffer as little as possible under heavy configuration files?

15:31 SegFaultAX: https://github.com/ring-clojure/ring/wiki/Getting-Started

15:32 Luyt_: You literally just need one call to ring.adapter.jetty/run-jetty with your Compojure handler and a few options.

15:32 Luyt_: (run-jetty ...) will launch a production-ready webserver?

15:33 SegFaultAX: Luyt_: You'll probably need to tune the server based on your needs. For that, you have the :configurator option (just a normal function that receives the server instance) plus some other top level configuration.

15:33 Luyt_: https://github.com/ring-clojure/ring/blob/master/ring-jetty-adapter/src/ring/adapter/jetty.clj#L61

15:34 Luyt_: SegFaultAX: okie, and that'll make a webapp which can be reverse-proxied by something like nginx?

15:34 SegFaultAX: Sure! Just a normal upstream {} with the correct host/port.

15:34 Then you can proxy to it as normal.

15:34 Luyt_: Cool. I knew it wouldn't be too hard ;-)

15:35 Thanks!

15:36 jweiss: anyone seen a weird problem with nrepl.el 0.1.8-preview where it just suddenly pops up a compilation error as you are typing, even though you didn't ask it to compile or evaluate anything?

15:39 seems to be related to having something like (:refer-clojure :exclude (get)) in my ns decl.

15:39 stuartsierra: jweiss: I've seen that with older nrepl releases, but not recently.

15:40 Something to do with autocompletion I think.

15:40 jweiss: yeah, just can't figure out why ac would cause compilation

15:51 solussd: ,(cond-> "thing" string? :string)

15:51 clojurebot: nil

15:52 solussd: cond-> is part of clojure 1.5.1, right?

15:52 getting this: IllegalAccessError cond-> does not exist clojure.core/refer (core.clj:3849)

16:02 gfredericks: is there any way to get nrepl-jack-in to do something with the :repl-options in my project.clj?

16:03 SegFaultAX: solussd: Are you looking for condp?

16:04 BufferUnderpants: Hello

16:04 I have a question on Clojure records

16:04 SegFaultAX: BufferUnderpants: Ahoy

16:04 gfredericks: (defrecord Ahoy [])

16:04 BufferUnderpants: How do you perform apply is-a? against a record type?

16:05 From another namespace, I mean

16:05 gfredericks: records are regular jvm classes

16:05 so you can :import them

16:05 BufferUnderpants: Oh, that's how

16:05 I suspected it, because it worked if I used the fully qualified name

16:05 Thanks

16:05 gfredericks: yeah that's the other approach

16:05 SegFaultAX: BufferUnderpants: But are you sure you even want a record? Is it possible a plain 'ol map will do ya?

16:06 BufferUnderpants: SegFaultAX: I have some functions where I want to dispatch on type, but multimethods seem like they would obfuscate it a bit

16:07 SegFaultAX: some tree-traversal thing

16:08 SegFaultAX: BufferUnderpants: I'm not sure how it would obfuscate it. One nice thing about multimethods is that if someone is using your tree-traversal thingy, they can extend it with their own types trivially.

16:09 bbloom: SegFaultAX: that's also true of protocols

16:09 SegFaultAX: BufferUnderpants: That's also true of protocols!

16:09 :)

16:09 BufferUnderpants: SegFaultAX: hadn't considered that scenario, I was thinking that having the code spread out would be less clear, besides seeming a bit overkill

16:10 Anyway, I settled on records after ending up with a mess after trying with good ol hash maps

16:10 SegFaultAX: Ok

16:19 solussd: SegFaultAX: turns out it was some code I had 'requiring' cond-> from a pre-clojure 1.5 library I had.. it is, in fact, in clojure 1.4

16:19 *1.5

16:23 SegFaultAX: solussd: Looks like they've added a whole set of pointy macros. cond->(>), some->(>), and as->

16:23 solussd: yeah, they're hot

16:24 mthvedt: they should make a macro library to generate pointy macros

16:24 TimMc: "pointy macros", I love it

16:24 ehaliewicz: does anyone know of any good clojure tutorials or books for someone familiar with common lisp?

16:24 SegFaultAX: TimMc: I try.

16:25 ehaliewicz: Joy of Clojure is pretty sweet. And a new version is coming out later this year!

16:25 solussd: the grapist, i love it!

16:25 mthvedt: cond-> already looks a little like a monad

16:25 maybe you can have something that does

16:25 monad in, pointy macro out

16:25 ehaliewicz: SegFaultAX: thanks, i'll take a look at it

16:26 SegFaultAX: ehaliewicz: Also http://www.clojurebook.com/

16:26 ehaliewicz: Although the latter is also good for total beginners.

16:27 mthvedt: or just something like monad-> and monad->>

16:29 SegFaultAX: mthvedt: The former already has a name.

16:29 clojure.ago.monads/with-monad

16:29 algo*

16:31 mthvedt: segfaultax: yes, but with-monad isn't sufficiently pointy.

16:32 ehaliewicz: SegFaultAX: well, i hope it doesn't waste too much time covering the absolute basics, but again, I'll take a look at it. thanks :D

16:41 gfredericks: Do folk still use slingshot?

16:41 SegFaultAX: gfredericks: Only against interns.

16:41 hiredman: yes

16:42 gfredericks: hiredman: I was surprised it doesn't seem very compatible with ex-info

16:42 hiredman: gfredericks: it should actually use ex-info if available

16:43 what do you mean by not very compatible?

16:43 gfredericks: hiredman: I was hoping the built in selectors would work against something thrown with (throw (ex-info {:foo :bar}))

16:44 ah I see

16:44 throw+ uses ExceptionInfo but wraps the object up further

16:44 hiredman: yeah

16:44 which is kind of meh

16:44 gfredericks: I think I just want an ex-info-oriented try+ :/

16:44 feels more idiomatic

16:46 hiredman: talk to scgilardi

16:47 gfredericks: about adding it to slingshot maybe?

16:47 should be doable...throw+ adds metadata so it should be able to distinguish the cases

16:54 solussd: gfredericks: i use slingshot pretty much everywhere

16:55 gfredericks: https://github.com/scgilardi/slingshot/issues/35

17:34 patbrown: Does anyone have any elastic beanstalk experience that can help me figure out how to get a hello world up, I don't think my problem is with lein-beanstalk, but rather setting up the amazon end?

17:37 callen: patbrown: guess you should be in a channel for amazon stuff.

17:38 patbrown: Yeah, I suppose so, I just prefer the weather in here.

17:39 SegFaultAX: patbrown: Have you tried the EBS tutorial?

17:40 patbrown: :SegFaultAX The one I've seen is for eclipse, and I'm an emacs user

17:41 SegFaultAX: patbrown: Huh? What does Eclipse/Emacs have to do with configuring elastic beanstalk?

17:41 patbrown: Exactly, I click on the java tutorial and the instructions are all geared towards the integrated eclipse tool

17:42 There is no clojure tutorial, except I found http://www.ctdean.com/2012/04/10/aws-beanstalk-on-clojure.html but was missing something

17:43 SegFaultAX: patbrown: You said your issue is on the AWS side. Is it just deployment or what?

17:43 patbrown: I'm assuming you already have a war file.

17:44 patbrown: For example: http://docs.aws.amazon.com/elasticbeanstalk/latest/dg/using-features.deployment.newapp.html

17:45 patbrown: I've been attempting to deploy the war via cli, thanks for the link, I'll try to start over with a standalone.

17:46 SegFaultAX: patbrown: FYI anything you can do from a plugin you can do via the CLI tools or API (and probably also the management console for that matter)

17:47 patbrown: The plugins just integrate it into your development process. But once you understand how AWS deployment works you can wrap that up yourself with eg Capistrano or Fabric.

17:48 patbrown: Dumb question, so I am better off ditching lein and using the ruby or python aws cli tool?

17:49 SegFaultAX: patbrown: Depends, is there already a plugin that suits all your needs?

17:51 patbrown: You said you looked at lein-beanstalk already. Does it not do something that you need?

17:51 cljconner: (take 1 (map #(do (print \.) %) (range)))

17:51 why does this print 32 dots?

17:51 patbrown: It does everything I need, except work.

17:52 Which I assume is my fault.

17:52 cljconner: as in the stackoverflwo qn : http://stackoverflow.com/questions/12412038/in-clojure-are-lazy-seqs-always-chunked

17:52 patbrown: I'm just trying to figure out where

17:54 SegFaultAX: patbrown: Can you clarify what you mean by not working? Does it provide an error message?

17:55 patbrown: No, I'm not getting an error, I'm unable to update the 'current version' from the default instance to the war I deploy. I should have started with that

17:57 SegFaultAX: patbrown: Were you able to do a first deploy?

17:59 patbrown: I didn't get an error message, but I also didn't get a new version added to my 'lein beanstalk info' response

18:00 callen: SegFaultAX: it's easy to confuse Elastic Beanstalk and Elastic Block Store if you spell it EBS btw.

18:00 SegFaultAX: callen: I realized that the moment I typed it. :)

18:00 callen: I don't know what the commonly used shorthand is, though. EBST?

18:00 I guess that's not really any better.

18:02 patbrown: What's the output of `lein beanstalk info`?

18:14 ToBeReplaced: how do people do batch getters/setters nowadays?

18:17 Wild_Cat`: ToBeReplaced: I'd say they don't.

18:17 usually, the need for a ton of getters/setters means you're exposing the internal implementation details of your class rather than its behavior.

18:18 ToBeReplaced: the issue is more for constructing new objects from existing java classes... for example a c3po ComboPooledDataSource... where there's about 20 properties you might reasonably want to set

18:21 patbrown: :SegFaultAX Thanks for all your help. Embarrassment ensues. It turns out that I didn't migrate from jetty to tomcat the right way. Change one function and "hello world"

18:22 technomancy: fun fact: did you know that Tomcat was named after the animal on the cover of the O'Reilley book on Tomcat?

18:24 AimHere: You mean they wrote theO'Reilly book before they wrote the language?

18:25 technomancy: not really, but they picked the name because they wanted to have a book with an animal on the cover

18:26 https://en.wikipedia.org/wiki/Apache_Tomcat#History

18:26 patbrown: If I ever write an O'reilley book, the resulting technology would be called Griffin with topless sword wielding three-boobed chick.

18:26 Shout out to Total Recall on the triboob

18:26 AimHere: I always assumed that the guy who wrote 'Falcon' did it purely because he wanted an O'Reilly book

18:26 *named it

18:26 technomancy: unfortunately another project beat them to it re: the tomcat cover, so they had to settle with a snow leopard

18:30 ToBeReplaced: Wild_Cat`: here is what i am using now https://www.refheap.com/paste/13654

18:37 Wild_Cat`: ToBeReplaced: OK, disregard my previous comment, I thought you wanted to batch-*define* getters and setters, not call them

18:38 "this is bad design" doesn't help you at all when the comment refers to code you didn't write and can't modify ;)

18:49 SirLalala: hi guys! I'm playing with the new clojure/java.jdbc. Any hints on how to include a LIMIT BY?

18:49 from the docs I have order-by but no limit-by :(

18:51 ToBeReplaced: the dsl is deliberately minimal and doesn't have LIMIT BY atm... check out honeysql if you want a more sophisticated sl

18:52 hiredman: ugh

18:52 breaking java.jdbc by replacing it with a dsl just makes me mad

18:53 SirLalala: I was actually fine with using the java.jdbc the way it was, it's that everything got deprecated

18:53 hiredman: yeah

18:53 java.jdbc was great

18:54 gfredericks: dynamic var hatin?

18:54 brehaut: wait waht

18:55 all that DSL stuff is *instead* of the old api?

18:55 SirLalala: brehaut: http://clojure.github.io/java.jdbc/#clojure.java.jdbc/with-connection

18:55 It says deprecated

18:56 gfredericks: yeah corefield was talking on the mailing list about removing the old stuff altogether for 1.0

18:56 hiredman: ugh

18:56 brehaut: his SQL DSL better be completely bulletproof :(

18:56 hiredman: time to fork it so it remains not non-sense

18:56 SirLalala: I mean the new stuff is supposed to be easier, but now I have no clue how to add a LIMIT BY

18:57 ToBeReplaced: i think the point is that he did away with all of the dynamic binding stuff and emphasizes you passing around a spec

18:58 amalloy: wait, really? it looks from his clj-dev post that he's only removing the with-* macros, and functions that rely on the dynamic variables therein. he's surely not removing the main features of the library

18:58 hiredman: and he replaced all the useful bits people use with a stupid incomplete dsl

18:58 ToBeReplaced: what useful bits are those?

18:59 hiredman: https://github.com/hiredman/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L982-994 deprecated in 0.30

18:59 0.3.0

19:00 ToBeReplaced: you still have that with "query" i think

19:02 amalloy: yeah, or with https://github.com/hiredman/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L586

19:03 the only feature sean is actually deprecating is the dynamic vars like *db*

19:04 technomancy: getting rid of the with-connection requirement is great

19:04 amalloy: totally

19:04 ToBeReplaced: i want the same thing for carmine ;)

19:07 ehaliewicz: http://pastebin.com/FscjzTgL

19:07 it's a direct translation from common lisp, but it's the first significant bit of clojure i've written

19:09 nDuff: ehaliewicz: In the future, would you mind pasting to somewhere that isn't an eyesore to folks who aren't running adblock/noscripts/...?

19:10 ehaliewicz: ...our local favorite is refheap.com (itself written in Clojure).

19:11 ehaliewicz: hold on

19:13 tieTYT2: i have a screenshot of this at home which would probably be the best way to explain this but, I'm making a simple app with a file chooser and shortcuts to move the selected file into certain folders

19:13 that way I can organize my files without drag and drop

19:13 the shortcuts are configurable (eg: this shortcut moves a file into this folder). To me that seems like mutable state. What's a good way to implement this concept of a configurable folder/shortcut

19:24 ehaliewicz: nDuff: https://www.refheap.com/paste/13657

19:25 never had a problem with pastebin, sorry about that

19:25 Raynes: nDuff is my entire marketing team.

19:26 ehaliewicz: It's fine. It's just that pastebin apparently has tons of ads for people who don't use adblock and what not. It also doesn't have the best Clojure support in the world either.

19:27 ehaliewicz: oh, i haven't run a browser without adblock in years, so i guess i never noticed :D

19:27 tieTYT2: basically I need a variable of a map with shortcuts as keys and a directory as a value. Do I just make the map an atom?

19:27 Raynes: Same here.

19:27 nDuff: tieTYT: Unless you have a specific reason to use a different primitive, an atom is a good default.

19:28 Raynes: ehaliewicz: Are you after code review?

19:28 tieTYT2: can I use a ^dynamic for this?

19:28 nm, I don't think I could

19:29 ehaliewicz: Raynes: not really, I was just posting it for the hell of it. I'm sure there are issues with the code from a clojure perspective though

19:29 Raynes: Well, congrats on your first Clojure code.

19:29 tieTYT2: nDuff: I don't plan to have any concurrency in my app. An atom is still a good default?

19:29 Raynes: :)

19:29 ehaliewicz: even ignoring the whole parsing a string-based dsl rather than sexp

19:29 thanks

19:30 Raynes: ehaliewicz: The first thing that stands out is holyshitsomanymacrosomgomgomg. But you did say this was a translation from Common Lisp.

19:31 Another thing worth mentioning is that you should avoid using 'use' without the `:only` bit. Or, if using 1.4.0+, don't use use at all. (require '[clojure.string :refer [split-lines split trim]])

19:31 nDuff: tieTYT: If this is a transient, local value, there might be a more appropriate way to deal with it, depending on the details (accumulating values in a reducer, or loop/recur, or what-have-you). If it's something you're putting directly in a var and changing over time, an atom remains a good default choice.

19:32 Raynes: If you need to use a bunch of stuff from clojure.java.io and don't want to :refer it all, you can do (require '[clojure.java.io :as io]) and then refer to things like (io/reader foo)

19:32 tieTYT2: nDuff: what does transient mean in your context?

19:32 ehaliewicz: Raynes: the first two macros are actually pretty unecessary

19:32 tieTYT2: i think my variable is going to be a map. I'll assoc and dissoc it a lot

19:33 ehaliewicz: i didn't even write them really, i was just comparing the performance with my cl implementation and looking into type hints and stuff

19:33 Bronsa: ehaliewicz: also you probably want to use `into` instead of `reduce conj`

19:34 amalloy: or just vec instead of the whole thing

19:34 Bronsa: or even better, just `vec` instead of `into []` or `reduce conj []`

19:34 yeah

20:11 TimMc: &(let [v [1 2 3]] (identical? v (vec v)))

20:11 lazybot: ⇒ false

20:11 patbrown: Are there any instances where (type n) returns float?

20:11 TimMc: &(type (float 5))

20:11 lazybot: ⇒ java.lang.Float

20:12 TimMc: &(class (float 5))

20:12 lazybot: ⇒ java.lang.Float

20:13 patbrown: So, only if (type n) acts directly on a newly created float?

20:13 metellus: ,(type 5.0f)

20:13 clojurebot: #<NumberFormatException java.lang.NumberFormatException: Invalid number: 5.0f>

20:14 patbrown: Cool, thanks, that covers my use cases.

20:15 TimMc: patbrown: I may have misunderstood you.

20:15 Do you mean float or Float?

20:16 amalloy: patbrown: no, it never will return lower-case float

20:17 it will return Float if anyone passes it a Float object

20:18 patbrown: I meant Float

20:19 I'm trying to ensure that in my dsl, if I type check for double, that I'll be cool… I believe I will

20:35 TimMc: patbrown: No, there are plenty of ways.

20:35 &(let [x (float 6)] (type x))

20:35 lazybot: ⇒ java.lang.Float

20:36 TimMc: $findarg map % [(float 6.0) 6.0] [true false]

20:37 lazybot: []

20:46 patbrown: Interesting, I ended up converting everything to a string and then running (read-string n) on them. I have no idea what this does for performance, but I haven't been able to break my code.

20:47 :TimMc btw, it's a convenience library on top of cl-format if that fuels better insight into what I'm doing

20:55 amalloy: patbrown: fwiw, calling read-string on arbitrary user-created strings introduces serious security problems

20:55 &(doc float?)

20:55 lazybot: ⇒ "([n]); Returns true if n is a floating point number"

20:55 amalloy: &(map float? [1.0 (float 1.0) (double 1.0)])

20:55 lazybot: ⇒ (true true true)

21:01 patbrown: :amalloy I'm confused, why something will return as a float with (float? 1.0) and (= (type 1.0) java.lang.Float) returns false

21:02 Raynes: &(type 1.0)

21:02 lazybot: ⇒ java.lang.Double

21:02 amalloy: because float? is abstractly checking "is this floating-point", whereas j.l.Float is checking for a particular concrete type of float

21:03 just like ##(vector? (first {1 2})) is true, but ##(class (first {1 2})) isn't clojure.lang.PersistentVector

21:04 lazybot: (vector? (first {1 2})) ⇒ true

21:04 (class (first {1 2})) ⇒ clojure.lang.MapEntry

21:05 patbrown: So, if I am doing my type inspection comparing to the concrete java.lang types, how would I encounter a float?

21:08 :amalloy further, I think I've heard the security issue mentioned before, it's mitigated by using read-string from clojure/tools.reader ?

21:09 amalloy: i can't imagine a good reason to compare to concrete java.lang types

21:10 and, as i said before, you will encounter a float whenever someone passes you a float

21:13 patbrown: Hmmmm, can't imagine a good reason… What should I be doing differently?

21:13 I've got this sinking feeling I've been doing it wrong for a long time now

22:42 tyler_: any whiteheadians in here? question: can two actual occasions happen in the same instant in time, or can there only be one actual occasion per instant in time?

22:49 muhoo: tyler_: sounds like a question for heisenberg, not whitehead

22:50 tyler_: yeah because whitehead never talked about time o actual occasions

22:50 or*

22:55 muhoo: Raynes: huh, a paste with a "burn after reading" setting http://0bin.net/

22:55 Raynes: muhoo: Hah, nice. I could implement that easily.

22:56 I certainly don't nor do I intend to encrypt pastes.

22:56 muhoo: cool, i could think of a few people who'd make use of it.

22:57 yeah, it didn't seem to fit too well with the refheap model of things, but just FYI.

22:57 Raynes: Burn after reading would be great, just the encryption stuff I wouldn't want to do.

23:36 desertmonad: Hi all. Is there a way to escape a semicolon in a double quoted string? I get "unsupported escape character in the repl when I try "\;"

23:40 Raynes: desertmonad: Why do you need to escape a semicolon?

23:42 mthvedt: raynes: he's playing nethack. escaping semicolons is very difficult

23:42 desertmonad: I'm trying out Engleberg's instaparse (https://github.com/Engelberg/instaparse). The BNF I'm trying it out with has a semicolon as a keyword.

23:42 Raynes: Well, you're officially my new favorite person, mthvedt

23:42 mthvedt: i am honored

23:43 Raynes: desertmonad: Well, you're trying to escape it in Clojure, not the language that needs it to be escaped. Try \\; perhaps?

23:44 desertmonad: Yeah, I'm not really clear on what I am trying to do, tbh. Instaparse can interpret ; as it's own keyword as an optional line ending of a rule. So my first inclination was to escape it, but then ran into clojury troubles.

23:45 I suppose I need to discuss this with Engleberg at this point

23:45 mthvedt: desertmonad: you also might be able to use instaparse's combinators… but if the language can't escape it, consider opening a github issue or emailing him

23:46 alternately, you can use my favorite parser, https://github.com/mthvedt/clearley :)

23:46 desertmonad: I'll have a look :)

23:47 That looks pretty nice, mthvedt. Instaparse was interesting because it interpreted strings of BNF, so I could copy and paste from a spec.

23:47 I don't think it was going to actually save me time in the end though

Logging service provided by n01se.net