#clojure log - Dec 16 2014

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

0:00 andyf: What expressions are the \2 and \3 supposed to refer to there?

0:06 Seems like a reasonable definition would be that it could match the string "xx", where (y) matches nothing, and so does \3, but the Java regex implementation doesn't see it that way.

0:09 gfredericks: yeah that's a good summary of my thoughts

0:09 rritoch: gfredericks: There is no third term so what is the point of \3?

0:09 gfredericks: rritoch: there is

0:10 I wonder how easy it is to statically determine whether a regex has such impossibilities

0:10 andyf: \3 should refer to expression starting with 3rd (

0:10 rritoch: ,(clojure.string/replace "xxx" #"((x)|(y))" "$3")

0:10 clojurebot: ""

0:10 rritoch: ,(clojure.string/replace "xxx" #"((x)|(y))" "$2")

0:10 clojurebot: "xxx"

0:13 rritoch: gfredericks: I obviously need to dig more into the docs but $3 is returning that which isn't matched ##(clojure.string/replace "dxxxe" #"((x)|(y))" "$3")

0:13 lazybot: ⇒ "de"

0:14 gfredericks: ,(clojure.string/replace "yyy" #"((x)|(y))" "$3")

0:14 clojurebot: "yyy"

0:15 gfredericks: I don't understand that "de" part

0:15 TEttinger: it's replacing it with an empty string

0:15 gfredericks: oh right

0:15 TEttinger: ##(clojure.string/replace "" #"(.)" "$9")

0:15 lazybot: ⇒ ""

0:16 TEttinger: ##(clojure.string/replace "a" #"(.)" "$9")

0:16 lazybot: java.lang.IndexOutOfBoundsException: No group 9

0:16 TEttinger: oh!

0:16 interesting

0:17 oh ok

0:17 so it never matched y, so group 3, (y), was empty

0:18 ##(clojure.string/replace "a" #"((h)|(i)|(j))" "$4")

0:18 lazybot: ⇒ "a"

0:18 TEttinger: ##(clojure.string/replace "a" #"((a)|(h)|(i)|(j))" "$4")

0:18 lazybot: ⇒ ""

0:18 TEttinger: ##(clojure.string/replace "a" #"((a)|(h)|(i)|(j))" "$2")

0:18 lazybot: ⇒ "a"

0:19 TEttinger: so you can't use $n to get an n that is higher than the number of groups in the regex.

0:19 but if those groups were empty, the $n for that group will be ""

0:20 ##(clojure.string/replace "dxxxe" #"((x)|(y))" "$1")

0:20 lazybot: ⇒ "dxxxe"

0:25 rritoch: TEttinger: Ok, I see, my problem was that I was only working with the x values of the problem. ##(list (re-matches #"((x)|(y))\3" "xx") (re-matches #"((x)|(y))\3" "yy"))

0:25 lazybot: ⇒ (nil ["yy" "y" nil "y"])

0:26 rritoch: gfredericks: I believe you are right, the regex you provided is unmatchable because either \2 or \3 will have a value, but not both. Or so it seems.

0:42 Does clojure have anything similar to LPC reg_assoc? http://discworld.atuin.net/lpc/playing/documentation.c?path=/driver/efuns/strings/reg_assoc ?

0:48 justin_smith: something like this? ##(let [[a b c] (re-seq #".a." "happy and sad")] [c b a])

0:48 lazybot: ⇒ ["sad" " an" "hap"]

0:48 justin_smith: no, that's not the same at all

0:50 rritoch: justin_smith: Yeah, this is for natural language processing, you pass it an array of patterns which are each attempted, and when a match is found it returns the token associated with that expression.

0:54 justin_smith: I coded it once in pike https://github.com/rritoch/PikeVM/blob/master/root/boot/system-1.1/simul_efuns.pike#L648-L719 but right now I can't recall how the no-match moves forward

0:55 justin_smith: ,(condp re-find "hello" #"good" :exit #"sup" :stay #"hel" :greet)

0:55 clojurebot: :greet

0:55 justin_smith: still not it

1:11 rritoch: justin_smith: Well, either way I need to add this to my todo list, but I am not looking forward to it, but being able to tokenize a string with regular expressions is occasionally useful.

1:11 justin_smith: why not a proper parser?

1:13 rritoch: justin_smith: Parsers in java tend to be a bit slow, even if you use a stringbuilder. Regular expressions are implemented in native code in many languages so it is usually faster. I am not sure if java uses a binary library to backup regular expressions though.

1:40 Html-01: someone is here ? ì

1:41 justin_smith: yeah, there area a few of us here

1:41 Html-01: someone here is a unity 3d programmer ?

2:04 rritoch: Does anyone know how to monitor for creation of a certain DOM node when using PhantomJS? Specifically I want to pause until a certain condition is met, such as document.getElementById returns non-null.

2:28 BorisKourt: I can't figure out how to turn something like: {:z [[:z 262.0] [:z 262.0] [:z 262.0]] :x [[:x 262.0] [:x 262.0] [:x 262.0]] : y [[:y 262.0] [:y 262.0] [:y 262.0]]}

2:28 into just this: {:z [262.0 262.0 262.0] :x [262.0 262.0 262.0] :y [262.0 262.0 262.0]} can anyone help?

2:28 preserving order in the vectors

2:28 SagiCZ1: BorisKourt: you can call set on each of the key

2:28 ,(set [262.0 262.0 262.0])

2:28 clojurebot: #{262.0}

2:29 SagiCZ1: or distinct

2:29 ,(distinct [262.0 262.0 262.0])

2:29 clojurebot: (262.0)

2:29 SagiCZ1: wait, nevermind

2:29 BorisKourt: [[k a] [k b] [k c]] into [a b c]

2:30 Empperi: ,(into {} (for [[k v] {:z [[:z 262.0] [:z 263.0]]}] [k (map second v)])

2:30 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

2:30 Empperi: ,(into {} (for [[k v] {:z [[:z 262.0] [:z 263.0]]}] [k (map second v)]))

2:30 clojurebot: {:z (262.0 263.0)}

2:30 andyf: BorisKourt: Maybe you want to call #(map second %) on each value in the map?

2:30 BorisKourt: Ill try Empperi's solution one moment

2:38 Empperi works perfectly thank you

2:38 Empperi: np

2:55 otti: has someone a clue how i can close database connections when using korma that is based on jdbc?

3:02 nXqd: hi guys, what is this kind of variable, does it have any special meaning or just naming convention : options#

3:02 (let [options# (dissoc ~options :xml?)]

3:07 luxbock: nXqd: it's syntax sugar for `gensym`

3:07 nXqd: it's used to create unique local variable names inside macros

3:08 nXqd: luxbock: thanks ! it is, I just forgot what I read yesterday ...

3:16 rhg135: Is gensym unique per VM invocation?

3:21 andyf: rhg135: yes

3:22 rhg135: Good, andyf , i considered UUID

3:22 rritoch: rhg135: It is not guaranteed. I tested this myself by launching (gensym "x") as the first repl command, and repeating, I received the same value. So it is not guaranteed unique

3:23 rhg135: D:

3:23 andyf: Wait, when you say "per VM invocation" I thought you meant "within a single JVM running a single instance of Clojure". Within that, it is unique. Across different JVM invocations, the names can be the same.

3:23 rhg135: ,(repeatedly 3 gensym)

3:23 clojurebot: (G__27 G__28 G__29)

3:24 andyf: gensym source: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L558

3:24 rritoch: rhg135: You can use UUID to get guaranteed unique gensyms though

3:24 opqdonut: andyf: I think it's more like "per clojure classloader" or something like that, if you unload all the clojure stuff from your jvm, you'll probably get the same values again

3:24 rritoch: ,(gensym (.toString (java.util.UUID/randomUUID)))

3:24 clojurebot: 176704f8-55bc-476c-9b62-0b0c30c0a2de54

3:25 rhg135: im using it to label strings i get over irc

3:25 im not to worried

3:26 If i get non uniques chances are im OOM anyway

3:27 TEttinger: rhg135, add the timestamp then

3:29 rhg135: TEttinger: it's completely possible for two people to say something

3:29 TEttinger: at the same millisecond?

3:29 with the same username?

3:29 rhg135: I could lean on the fact lazybot runs sequentially

3:30 TEttinger: heh

3:30 rhg135: But it smells ugly

3:30 andyf: If you are willing to look up new messages time stamps in the collection of previous messages, you can append a unique counter value per second or millisecond to the messages that occur at the same time.

3:31 rritoch: TEttinger: On IRC it is because of network latency, if both messages arrive on the same packet, and your code is extremly fast (such as using multiple threads).

3:31 TEttinger: For a single threaded app, it would probably be impossible.

3:34 rhg135: Im indexing by network channel and gensym I think I'm just being paranoid about collisions

3:35 rritoch: rhg135: A single person isn't going to be able to send two messages at the same millisecond, not even a bot. If you don't like UUID's for some reason, you could use something more exotic, like a SHA256 hash of the catenated string of username, IP, and timestamp (ms).

3:36 rhg135: There are no known collissions of SHA256 yet.

3:36 rhg135: rritoch: you beat me in paranoia lol

3:37 TEttinger: or inc a ref

3:38 rhg135: Isn't this basically a gensym, assuming I run one JVM which I hope so?

3:39 To the counter not hashing

3:40 TEttinger: yeah, except it isn't clear how well many many gensyms work without collision

3:42 rhg135: ,(reduce = true (repeatedly 100000 gensym))

3:42 clojurebot: false

3:42 rhg135: Oops

3:43 rritoch: Has anyone here used clj-webdriver? I thought I found a solution to my problem by using wait-until, but it's implementation doesn't seem to work as I keep getting "No implementation of method: :wait-until of protocol" errors.

3:49 rhg135: Gensym seems unique

4:07 TEttinger: ,(distinct (repeatedly 100000 gensym))

4:07 clojurebot: (G__27 G__28 G__29 G__30 G__31 ...)

4:07 TEttinger: ,(distinct? (repeatedly 100000 gensym))

4:07 clojurebot: true

4:07 TEttinger: there we go

4:08 yogsototh: ikitommi_: thanks I just saw your message.

4:18 rhg135: TEttinger: thx

4:28 amalloy: TEttinger: ITYM (apply distinct? ...)

4:28 ,(distinct? (repeat 100 10))

4:28 clojurebot: true

4:29 TEttinger: ,(apply distinct? (repeat 100 10))

4:29 clojurebot: false

4:29 TEttinger: ,(apply distinct? (repeatedly 100000 gensym))

4:29 clojurebot: true

4:32 rhg135: Why is Symbol an IObj and keyword not?

4:33 andyf: I guess if you are going to stress gensym, realize that it can only return 2^32 unique gensym's, since it is based on the AtomicInteger class.

4:35 nXqd: can we disable a test in clojure by adding _ prefix ?

4:35 skip*

4:36 luxbock: nXqd: you can ignore any expression by prepending it with #_

4:36 nXqd: luxbock: thanks :)

4:37 luxbock: I'd like to get a sanity check for something that I'm working on

4:37 I have a C library that I call via Clojure's JNA that crunches some data for me, and this data can take up to 50gb of memory to hold

4:38 and I'd like to save this data on disk, and then serve it via a ring based Clojure web app

4:39 the data is basically just a collection of double-arrays

4:40 so I think for saving disk space I should keep it in the native data format, and I'm thinking about using ztellman's Gloss for this

4:42 I've also thought that maybe I should use Gzip to minimize it further, and to transport it to the client for the webapp

4:42 does this all seem sensible?

4:43 zarkone: hello all. I want to learn apache storm and try to implement my first example. In examples data in spout is always local.. Is there simple example with outer source, e.g. from websoket stream

4:54 rritoch: Is there any way to automatically ungreedy a regular expression? I tried using flag 512 from PCRE but java doesn't honor that flag for ungreedy.

4:54 I just need to mimic the ungreedy flag of PCRE.

4:55 BorisKourt: Is there a library or set of examples that deal with analysis of numeric collections? Having a hard time describing what I need. Some sort of super rudimentary wave analysis, grab highest peaks, average amplitude, sustain, and other 'wave shape' facts? This is not related to sound.

4:56 vijaykiran: BorisKourt: doesn't Incanter have something like that ?

4:56 dysfun: incanter has loads of stuff like that

4:57 BorisKourt: It likely would, I am hesitant though as my sets of data are miniscule and this is not meant for any visual output whatsoever. Ill take a look for sure if there is no smaller alternative.

5:01 Looks like its innards do have just what I want. Thanks. Now to get it into the project :)

5:03 rritoch: Will this mimic perl's /U (ungreedy) properly? (defn ungreedy [re] (re-pattern (clojure.string/replace (.toString re) #"(\*)([^?])" "$1?$2")))

5:05 andyf: rritoch: It does not cover * at the end of regex, nor handle the difference in their meaning when they are inside of [], and it doesn't include +

5:06 probably a few other things that I'm not thinking of, but not sure

5:06 rritoch: andyf: Ok, as for the * at the end of the regex, isn't that ungreedy?

5:07 andyf: I'll have to check but I'd think "/.*/U" would still match the entire string

5:08 andyf: parsing regex's to modify them is not something I'd do lightly, if I wanted it to be correct in all cases.

5:11 amalloy: andyf: it woulsn't be quite so bad if rritoch were actually parsing them. but just wanton string replacement is going to be a disaster. there are a *lot* of cases this ungreedy function misses that you didn't think of

5:13 eg, #"\Qabcd*\E"

5:13 or #"abc\*def"

5:13 and it doesn't un-greedify the + repetition operator, or the {N,M} operator

5:15 andyf: amalloy quantifies my unnamed fears. Thanks amalloy :)

5:15 amalloy: clojurebot: amalloy |is| your unnamed fears made real

5:15 clojurebot: 'Sea, mhuise.

5:16 birdspider: hello, how would I access a inner enum value ? (https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/Pixmap.java Pixmap's Format/RGBA8888 for instance)

5:19 rhg135: I love having a good gc

5:20 Pixmap$Format/xxx

5:29 andyf: rritoch: I'd suggest if you truly need PCRE capabilities, you use actual PCRE library. Going to the trouble of building it and calling it via JNI or similar mechanisms might be more pain than it is worth.

5:30 Google searches for existing PCRE library implementations in Java are not promising.

5:32 rritoch: andyf: Thanks, for now I'm just trying to see if I can just solve the currently mentioned issues.

6:48 hellofunk: is this most elegant way to assoc the same value into all the maps that are values of a sorted map? https://www.refheap.com/94984

6:49 basically taking the map apart and then putting it back together.

6:49 i suppose an alternative would be to reduce over the map but wouldn't be more elegant

6:50 triss: is there a form of let where all functions used take the same first argument?

6:50 so I say:

6:50 (let [a (func ctx)

6:51 b (func-two ctx)

6:51 martinklepsch: is there a reason = works for one argument as well?

6:51 triss: c (func-three ctx)] blah blah)

6:51 but i don't want to type ctx all the time

6:51 jack_rabbit: triss, not that I know of... You could easily macro it if you do it often.

6:52 hellofunk: tris you could (defn f [func] (partial func ctx)) then do (let [a (f func..) b (f func-two)

6:52 triss ^

6:53 or you could put the defn f as the first let form

6:54 triss: cheers guys. I'll have a play.

6:54 hellofunk: i can't tell if you are defining fns or calling them but you get hte idea

6:55 triss: calling them...

6:55 hellofunk: triss: (defn f [x & a] (apply x 2 a))

6:55 then if you do (f inc) or (f + 5 6) whatever, the arg 2 is added to every call

6:56 triss: cheers. hellofunk that's splendid.

6:56 hellofunk: jack_rabbit: definitely don't need or want a macro for this. it's basic FP at work

6:58 triss: well it's not saving that much typing as it is.... a macro would result in cleaner code.

6:58 hellofunk: triss: no, first rule of macros, never use a macro if a good higher order function will do the trick instead

6:59 there is no reason for a macro here.

6:59 triss: I'm writing a little DSL for doing web audio stuff.

6:59 hellofunk: DSL's typically use macros, but the problem you've presented is not good macro material

7:00 triss: ok man. I can see why they'd be avoided. I'll bare that in mind and try and get things done functionaly.

7:01 luxbock: hellofunk: I would use reduce-kv, but I don't think it makes a big difference

7:01 hellofunk: whenever you are trying to consolidate functions, as you are, or consolidate args to functions, etc, then this is normal stuff for FP without macros

7:01 jack_rabbit: hellofunk, if he wants to write just [a (func) b (func-two)] I don't see a way around it.

7:02 hellofunk: jack_rabbit: he wants to pass other args but keep one arg the same for the functions

7:03 unless i misunderstood his question

7:03 jack_rabbit: I still don't see the problem with a macro, if that's what he wants to do. It's only worthwhile if he's doing it lots of places (probably not), but if he wants to do this, setting up the environment without a macro would be more code than just inserting the first parameter where it goes manually.

7:04 hellofunk, no, I reread it. I think you're right.

7:05 hellofunk: whether you are "setting up more code" by not using a macro, or setting up more code by writing the macro, either way it's all code. and in this case the important uses for macros isn't apparent here. he is not delaying evaluation of arguments, for example.

7:07 jack_rabbit: My only argument is that if this is worth doing, it's worth putting in a macro, so he doesn't need to "set up the code" everywhere. If it's not worth doing that, it's just easier and more readable to put the argument where it goes in each function call.

7:08 hellofunk: building the HOF only needs to be done once, just as writing a macro would probably be done once, so it's not causing lots of code to get written everywhere

7:09 jack_rabbit: Well, it would need to be done once for each let, no?

7:10 hellofunk: jack_rabbit: then it wouldn't go in a let, it would be its own separate function

7:10 jack_rabbit: That's fine. You'd still need something like [a (f func) b (f func-two)] which is not quite the requirement

7:10 clgv: if really need, a macro combining `let` and the `doto` like fill-in would be the way to go

7:12 jack_rabbit: unless I'm mistaken. [a (f func) b (f func-two)] doesn't seem any better than [a (func ctx) b (func-two ctx)]

7:20 clgv: jack_rabbit: that simple pattern word be solvable via `juxt`

7:20 triss: (let [[a b] ((juxt func func-two) ctx)] ...)

7:24 jack_rabbit: clgv, thanks! I was unaware of that.

7:25 clgv, although, I don't see that he could add other parameters to those functions.

7:25 triss: ah very nice. thanks clgv

7:25 hellofunk: jack_rabbit: the point is that with func and func-two, you are now having to define each of those, which isn't making anything easier

7:26 triss: func & func-two are already defined in a library

7:27 jack_rabbit: hellofunk, sorry, I miss your meaning.

7:30 At the very least, something *like* juxt could be written as a function that would satisfy triss's requirements. Not exactly to how he specified them, but close enough probably. Better than a macro.

7:31 clgv: jack_rabbit: yeah, well for the most flexible scenario you'd need a macro

7:31 jack_rabbit: clgv, right.

7:31 clgv: jack_rabbit: although the difference to an higher order function can be made pretty small

7:32 jack_rabbit: right again

7:33 clgv: (defn invoke-with-ctx [ctx & fns] (reduce #(conj %1 (%2 ctx)) [] fns)) called via (invoke-with-ctx ctx #(some-fn % arg2 arg3) #(other-fn % arg4))

7:35 jack_rabbit: Not quite so elegant.

7:36 clgv: jack_rabbit: yeah, but probably the closest you can get with a higher order function

7:37 jack_rabbit: hmm... what about something that would result in a call like (invoke-with-ctx ctx [some-fn arg2] [other-fn arg2 arg3])

7:37 That shouldn't be too hard.

7:37 clgv: jack_rabbit: easy to do, but not much better

7:37 jack_rabbit: Looks a little better *maybe*

7:38 clgv: you have replaced the lambdas by implicit specification...

7:40 jack_rabbit: It only looks better. Is it inferior in some way?

7:41 (apply (first fn-seq) cxt (rest fn-seq))

7:42 ctx even

7:43 clgv: I don't think it is. More code in the implementiation but not problematic

7:44 jack_rabbit: Right. I just like the look of [some-fn arg2] better than #(some-fn % arg2)

7:56 triss: I'm feeling like a proper noob today. super slow.

7:56 so if i want to adda new namespace to a project I just create a folder....

7:56 clgv: triss: source file and potentially a folder

7:56 triss: stick my my-ns/core.cljs my-ns/thing.cljs

7:57 clgv: triss: namespace my.lib.core needs to be in my/lib/core.clj

7:57 triss: and then I can require it another namespace via (:require [my-ns :as my-ns])

7:58 clgv: no. you need to require the full namespace

7:58 triss: oh yeah so (:require [my-ns.core :as my-ns])

7:58 ?

7:58 clgv: namespace "my.lib.core" needs to be in "my/lib/core.clj" and is required via (:require [my.lib.core :as mlc])

7:59 triss: god dman I don't understand why it;s not being seen

8:00 I get the error message:

8:01 WARNING: Required namespace not provided for hm.core

8:01 but hm.core lives under my source folder in hm/core.cljs

8:01 clojurescript btw

8:03 clgv: triss: you got an "(ns hm.core ...)" expression in that file?

8:04 triss: yup.

8:04 i just restarted the repl....

8:05 now the cljs compiler has stopped warning me but in the browser I'm told hm.core can't be found:

8:06 Uncaught Error: Undefined nameToPath for hm.corebase.js

8:06 erm ignore the base.js on the end of that

8:07 I'm using figwheel... could that make things more complex?

8:09 clgv: triss: the provided information is not enough to be able to help you further. try to minimize the project setup until it stops failing, then you usually find the problem.

8:09 triss: cheers man will do

8:11 dnolen_: triss: there's also a #clojurescript specific channel you might want to join.

8:11 triss: oh... hadn't spotted that. thanks dnolen.

8:27 michaelr525: hey

8:52 thatguy: anyone have a favorite validation library for web forms? building my first and the options are almost overwheliming

9:14 SagiCZ1: thatguy: i have no experience in this matter, but what seems so complex about it?

9:25 thatguy: probably nothing, just seeing what people have had success with

9:27 zot: random idiom: i have a variable that gets updated in a loop. go figure. in any case, is there a naming convention for these sorts of things, similar to A and A' (A-prime)?

9:32 clgv: zot: not that I know. if you don't need the old value you should bind it to the name of the loop argument to avoid errors

9:33 *you should bind the new value to the name of the loop argument

9:33 zot: generally i do, but sometimes it's useful to have both; foo-cur and foo-next work, but i thought there might be sth already "normal"

9:35 clgv: zot: not really since it is application specific anyway. in a time series calculation "v_n+1 (f v_n)" might be a documenting name

9:38 zot: I have used both "prime" and "subscript-like indices"

10:01 craigglennie: I’m trying to write a toy web-scraper for threadless.com. The site has multiple pages of links to t-shirts. I would like a function that produces a list of all the links, moving to the next page as needed. In Python I could use a generator that took the starting URL, extracted product links to a list, yielded them one-by-one, and repeated this for the next page once the list of product links was empty. If there was no next page the generator would

10:01 exit. How would I go about something like this in clojure? I’ve looked at lazy-seq but I’m not sure that it’s the right answer

10:02 I also thought about using a list comprehension, but it doesn’t seem quite right, either

10:02 SagiCZ1: you could use lazy-seq

10:02 teslanick: You could use core.async to do something like a producer-consumer.

10:04 hellofunk: thatguy are you talking about browser-side web form validation?

10:04 craigglennie: teslanick: That sounds like what I’d want - would that also allow for the consumers to work in parallel?

10:10 teslanick: craigglennie: Yes. One go-block would consume the pages and put to a channel. Another (pool?) of go-blocks would consume the channel and generate a list of links.

10:12 ebaxt: Is there a simple way to access the constructor function (map->Name) of a record given only an instance of the record?

10:16 justin_smith: triss: quick correction - my-ns.core needs to go in src/my_ns/core.clj - note the underscore

10:19 craigglennie: teslanick: Thanks, I’ll take a look at core.async - I had wanted to parallelize this anyway

10:21 EvanR: join #haskell

10:22 s/^/\//

10:23 justin_smith: ebaxt: it is possible, since the class of the record and the namespace it is in will match up, but there is no simple method

10:24 ebaxt: but if you have the thing already you can use (into (empty this-record) {:some "input"})

10:24 which does what map->Name does anyway

10:25 ebaxt: justin_smith: thx, guess I will have to call qualified_record_name/name or empty the map like you say

10:25 justin_smith: well that's not "emptying the map"

10:25 it just makes an empty record, of the same type as the input

10:25 records are immutable

10:26 pjstadig: i don't think empty works on records

10:26 ebaxt: justin_smith: ah, didn't see the into. Nice, thanks a lot!

10:26 justin_smith: pjstadig: actually, you are right, my bad

10:26 ebaxt: never mind, i expected empty to work on records, but it does not

10:26 pjstadig: it would be nice if it did :)

10:27 dissoc'ing any of the basis keys in a record cause it to "degrade" to a plain hashmap

10:27 justin_smith: ,(defrecord MyRec [a b])

10:27 clojurebot: sandbox.MyRec

10:27 justin_smith: ,(def r (MyRec. 0 1))

10:27 clojurebot: #'sandbox/r

10:27 justin_smith: ,(into r {:a 42})

10:27 clojurebot: #sandbox.MyRec{:a 42, :b 1}

10:28 justin_smith: so that works, but will leave the old values for anything you did not specify

10:28 EvanR: whats the difference between defrecords and maps, practically

10:29 justin_smith: you can implement protocols on records

10:29 pjstadig: EvanR: some performance differences when you access the basis fields, and you can extend protocols to them

10:29 EvanR: i implemented protocols on the map though

10:29 pjstadig: they are also a distinct type

10:29 justin_smith: EvanR: but what if you wanted to implement the protocol differently on a different map

10:30 records are distinct classes, so they can be extended seperately

10:30 EvanR: ok

10:30 each record schema has to be a dedicated type/class ?

10:30 ebaxt: ,(sandbox.MyRec/create {:foo "bar})

10:30 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

10:31 justin_smith: EvanR: defrecord creates a class

10:31 pjstadig: ,(sandbox.MyRec/create {:foo "bar"})

10:31 clojurebot: #sandbox.MyRec{:a nil, :b nil, :foo "bar"}

10:31 ebaxt: ,(sandbox.MyRec/create {:foo "bar"})

10:31 clojurebot: #sandbox.MyRec{:a nil, :b nil, :foo "bar"}

10:31 EvanR: like, it registers a new class name? or its anonymous

10:31 justin_smith: EvanR: there is no such thing as an anonymous class

10:31 pjstadig: ,(class MyRec)

10:31 clojurebot: java.lang.Class

10:31 clgv: EvanR: usually you should use a map. if a map is not sufficient anymore you can switch to a record.

10:31 EvanR: there isnt?

10:31 pjstadig: er

10:31 ,(class r)

10:31 clojurebot: sandbox.MyRec

10:32 justin_smith: EvanR: nope, the closest you get is gibberish auto-generated names

10:32 ,(class (fn [x] x))

10:32 EvanR: ok that explains that

10:32 clojurebot: sandbox$eval232$fn__233

10:32 justin_smith: names like the ones you get for fn

10:37 arkh: I was wondering if someone could explain defmulti to me. I have a map like the following: {:something/new {:id 1 :userid 100}} and like to run maps like that through a multimethod. I'm trying to do variadic argument deconstruction but I'm not getting something right

10:37 (defmulti foo (fn [[k v & xs]] k))

10:38 justin_smith: that is not variadic

10:38 that is destructuring a single arg

10:38 arkh: (defmulti foo :something/new [[k v & xs]] (:id v))

10:38 I'd like to do variadic destructuring on that single arg

10:38 andyf: arkh: Will all of your maps have a single key/value pair? If not, the particular key/value pair chosen will vary from map to map.

10:39 justin_smith: arkh: you don't need to do the & xs part at all for destructuring to work

10:39 arkh: all the maps will have a single key value pair

10:39 ok

10:39 justin_smith: ,((fn [[a b c]] c) (range)) ; arkh

10:39 clojurebot: 2

10:39 justin_smith: where (range) of course produces an "infinite" series of numbers

10:40 arkh: I'm trying to understand that magic right now ... ; )

10:40 justin_smith: it's not magic, destructuring does not specify the length - it only specifies which parts you have names for

10:40 it's not pattern matching

10:41 arkh: right - my brain just had to catch up. I think I get it now

10:41 justin_smith: also, maps through list destructuring is a bit odd, because maps are not ordered

10:42 arkh: true, but I thought it would be ok if my maps are only a single key/value pair

10:42 justin_smith: nope, nth not supported, it will fail

10:42 arkh: that's what the repl was saying too

10:42 fair enough

10:42 justin_smith: ,((fn [[a b]] b) {:a 0 :b 1})

10:42 clojurebot: #<UnsupportedOperationException java.lang.UnsupportedOperationException: nth not supported on this type: PersistentArrayMap>

10:42 justin_smith: ,((fn [[a b]] b) (seq {:a 0 :b 1}))

10:42 clojurebot: [:a 0]

10:43 justin_smith: so you could add seq to your defmulti definition

10:43 arkh: sure!

10:43 justin_smith: or just not try to destructure maps with list destructuring

10:44 arkh: thank you

10:45 justin_smith: haha, you could define a defmulti for your dispatch function for your defmulti

10:45 yo dawg, I heard you like multimethods...

10:45 arkh: no need(!)

10:45 #xzibit #yolo

10:49 craigglennie: Another question… In my toy web-scraper I am going to be extracting data from multiple sites, each with their own layouts. I’d like a common public interface to each scraper; in OO I would have an actual interface, or an abstract base class. In Clojure I could put each scraper in it’s own namespace, and just make sure each one implements the appropriate functions, but it seems like multi-methods or protocols might also be appropriate. Any

10:49 advice?

10:49 clojurebot: the tao of warfare is deception

10:50 justin_smith: craigglennie: if performance is not the main concern, multimethods are more flexible, and easier for interactive usage (you can actually redefine them and may not break things)

10:51 and a protocol is literally an interface plus some niceties - it literally compiles down to a java interface in the bytecode

10:52 craigglennie: justin_smith: Performance is not a concern (I’m still just trying to learn Clojure) so multimethods might be good.

10:52 Interactive usage would probably be nice, too

10:52 justin_smith: craigglennie: another option is to write a higher order function, and pass in the function that fulfills some task it needs

10:53 that would be the old-school-lisp (pre-clos) option

10:54 arkh: a warning on interactive usage of defmulti - it can't be redefined at the repl apparently

10:54 justin_smith: arkh: it can, you just need to undef it first

10:55 ,(defmulti foo :x)

10:55 clojurebot: #'sandbox/foo

10:55 justin_smith: ,(defmulti foo :y)

10:55 clojurebot: nil

10:55 justin_smith: ,(ns-unmap *ns* 'foo)

10:55 clojurebot: nil

10:55 justin_smith: ,(defmulti foo :y)

10:55 clojurebot: #'sandbox/foo

10:55 arkh: nice

10:56 justin_smith: clojure.tools.namespace has some utilities for this kind of redefinition stuff

11:03 puredanger: you can also (remove-all-methods foo)

11:03 justin_smith: oh, I was not aware that existed, cool

11:04 (inc puredanger)

11:04 lazybot: ⇒ 25

11:08 andyf: Clojure cheatsheet has what I think are all multimethod-related functions/macros grouped together in a Multimethod section, including remove-all-methods: http://jafingerhut.github.io Most other related functions/macros are grouped near each other, too.

11:10 ppppaul: does read-string work with cljs?

11:13 chouser: ppppaul: yes, but consider cognitect/transit, depending on use case.

11:26 arkh: even if there's clojure on both sides of the communication is cognitect/transit still recommended from a e.g. compression standpoint?

11:28 tomjack: too bad #(partition-by f %) can't be like #(eduction (partition-by f) %)

11:28 stuartsierra: arkh: Transit will usually be faster than EDN.

11:28 puredanger: arkh: if all-Clojure, then Fressian will be faster than Transit or EDN (also does caching)

11:28 stuartsierra: arkh: Because Transit can take advantage of platform-native JSON libraries.

11:29 Hi puredanger!

11:29 puredanger: HI

11:30 stuartsierra: ppppaul: read-string is in its own namespace in cljs, I think it's called cljs.reader

11:30 chouser: but fressian isn't a real option in ClojureScript yet

11:31 arkh: my use case is clojurescript on one side and clojure on the other - thanks!

11:32 puredanger: in that case, I'd use Transit

11:32 chouser: ditto

11:39 annapawlicka: mpenet: hi Max, how do I do “UPDATE users SET top_places[2] = 'riddermark' WHERE user_id = 'frodo’;” using hayt?

11:44 verma: ,(def options ["hello" "world"])

11:44 clojurebot: #'sandbox/options

11:45 verma: ,(for [o options] {:text o :selected false})

11:45 clojurebot: ({:text "hello", :selected false} {:text "world", :selected false})

11:45 verma: dafuq

11:45 when I am doing it here in cljs, its giving me an emtpy {} in that list

11:45 checking again

11:46 ppppaul: transit is an optimization... i'll use it in the future.

11:47 ticking: everytime I use fold I get bitten by argument counts changing on mapentry, please somebody tell me that this is done with a sane reason

11:49 puredanger: ticking: don't understand what you mean

11:49 triss: so is there anything in the library that's equivalent to (comp doall repeat)

11:49 ticking: reduce and reducers/reduce have different semantics

11:49 triss: ?

11:49 stuartsierra: triss: dotimes

11:49 puredanger: ticking: you mean around maps in particular ?

11:50 ticking: puredanger: to be more precise, reduce and clojure.reducers/reduce behave differently on maps, reduce will require you a function like (fn [acc [k v]] while reducers/reduce will require (fn [acc k v]

11:50 triss: so dotimes returns the list of things it acts on?

11:51 ticking: puredanger: yeah

11:51 stuartsierra: triss: No, it's just for side effects.

11:51 ticking: triss: no

11:52 triss: most functions in clojure that do things just for side effects make this explicit by returning nil, e.g. dorun println dotimes

11:53 triss: ah ok....

11:54 so its seems doall is the only one that returns...

11:54 ticking: all yes

11:54 puredanger: ticking: yeah, it was done for efficiency I believe

11:54 triss: i suppose mapv sort of fits in there

11:54 ticking: puredanger: I think in the code there is an explicit check for this case which would seem slower to me

11:55 puredanger: I believe it has to do with parallel folding over maps but I haven't looked at in depth

11:55 stuartsierra: triss: In general, the "do" is a hint that these functions are reserved for side effects. It frequently doesn't work out well to combine the lazy-sequence functions with side effects.

11:55 ticking: puredanger: https://github.com/clojure/clojure/blob/f3259f4f34a68eae7db7efc0be9d19fa5dafbd3c/src/clj/clojure/core/reducers.clj#L77

11:55 tomjack: ticking: I guess (r/map identity) is a "just reduce please" shim

11:56 ticking: tomjack: yeah but urgh

11:56 tomjack: (which makes some parts of me unhappy, since (r/map identity) should be identity!)

11:56 ticking: tomjack: that this "fixes" it shows how broken the current behaviour is

11:56 tomjack: yeah exactly :D

11:57 ppppaul: i'm using datascript and it comes with some readers in a file. how do i get my cljs read to use those? (right now i'm doing a (swap!...) in my application code

11:58 dnolen_: Bronsa: ping

11:58 puredanger: ticking: the clojure map impls can .kvreduce themselves and avoid creating every intermediate entry object

11:58 ticking: only to then tear it apart again into k and v

11:59 tomjack: but we have reduce-kv already

11:59 puredanger: the reducer impl is trying to have the best of both reduce and reduce-kv automatically

11:59 ticking: tomjack: reducers/reduce uses reduce-kv internally

12:00 puredanger: there is a ticket to consider this aspect again for transducers in 1.7

12:00 sorry in 1.8

12:00 ticking: puredanger: really transducers do this to?

12:00 tomjack: I guess the auto-kv behavior is specialized for stuff like conj?

12:01 puredanger: tomjack: not sure what you're thinking of

12:01 tomjack: can't be just "I don't have to type -kv when I know I'm reducing a map", I presume

12:02 puredanger: I think there would be more double work than just that inside reducers

12:02 tomjack: so it only makes sense if the binary op is also at least ternary, like (conj coll k v)

12:02 stuartsierra: ,(conj {} :key 3)

12:02 clojurebot: #<IllegalArgumentException java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword>

12:03 dysfun: is anyone using core.async with aleph? or is there something aleph-like people are using with it?

12:03 tomjack: ,(conj [] :key 3)

12:03 clojurebot: [:key 3]

12:03 stuartsierra: ,(conj {} [:key 3])

12:03 clojurebot: {:key 3}

12:03 ticking: wow

12:04 stuartsierra: conj is variadic, but key/value pairs must be passed as a vector.

12:04 ticking: and this is done by transducers as well?

12:04 puredanger: no, not right now

12:04 there's a ticket to consider this again

12:05 ticking: puredanger: do you have a link for the ticket? can't seem to find it :/

12:05 puredanger: CLJ-1552

12:05 ticking: puredanger: thanks :D

12:05 puredanger: http://dev.clojure.org/jira/browse/CLJ-1552

12:05 stuartsierra: puredanger is the kinder, gentler interface to JIRA

12:05 ticking: lol

12:06 tomjack: stuartsierra: if you knew you were reducing a map, you could just call reduce-kv. so I'm trying to think of cases where the reducing fn works for either reduce or reduce-kv

12:06 puredanger: I just loaded it all into my brain and can regurgitate it at will

12:06 dysfun: there used to be a workable emacs library for doing jira things

12:06 that was vastly preferable to the web interface

12:06 stuartsierra: tomjack: I think that would be pretty rare.

12:06 puredanger: I have a Clojure library that can access it

12:06 that I wrote to scrape jira

12:06 dysfun: now we just need someone to finish DEUCE and we can use that, heh

12:07 ticking: puredanger: I'm begging you please don't do this :D, it is so horribly confusing and breaks abstraction in so many ways, (reduce ... foo should equal (reduce ... (map identity foo

12:07 puredanger: I'm about 90% of the way towards an automated program that can scrape it and replicate it (with history) in Datomic :)

12:07 tomjack: if it's rare, why https://github.com/clojure/clojure/blob/f3259f4f34a68eae7db7efc0be9d19fa5dafbd3c/src/clj/clojure/core/reducers.clj#L77 ?

12:07 dysfun: puredanger: great, now you have to write datomic bindings in elisp. that's gonna be *fun*

12:08 puredanger: dysfun: well I don't need that :)

12:09 ticking: I'm mostly in agreement

12:09 kenrestivo: dysfun: aleph has its own async-like thing called manifold (in case nobody answered already)

12:09 puredanger: in a side bar, I've built a new direct iterator for maps (CLJ-1499) and also built a variant of it that would provide a new direct iterator for only-keys and only-values (which avoids this same intermediate entry cost). it was surprisingly (to me) not much faster

12:09 dysfun: i'm tickled by the idea of just treating it as a database though

12:10 kenrestivo: yeah, i was just reading through it. i understand there's interop with core.async

12:10 ticking: puredanger: interesting, JIT being fancy?

12:10 puredanger: ticking: the cost of allocating and throwing away small Java objects is really really low these days

12:10 dysfun: i've got a brand new app and i've been looking for a reason to play with core.async, so it seems like a fun project

12:11 ticking: puredanger: long live the generational gc and david ungar :D

12:11 puredanger: heh. I've tried to get him to speak at Strange Loop a couple times, just hasn't worked out

12:12 ticking: puredanger: too bad :D, I'd love to hear some more stuff from him, self is so awesome

12:13 puredanger: he seemed interest, maybe in the future. just bad timing in the past.

12:14 ticking: anyhow, what I got from the key/val iterator experiment was that we're not getting *that* much benefit from reduce-kv over reduce

12:14 once you're leveraging transducers/reducers

12:15 ticking: puredanger: good to hear, every time an implicit reduce-kv is used god kills a kitten ;)

12:15 puredanger: and maybe the complexity of reduce-kv is not worth it. unrolled small collections will also possibly make this faster

12:16 ticking: puredanger: yeah, can't wait for the small fixed arity vectors

12:28 hellofunk: is this most elegant way to assoc the same value into all the maps that are values of a sorted map? https://www.refheap.com/94984

12:30 joegallo: you might (empty sorted-map-in) rather than invoking (sorted-map) directly.

12:30 but besides that it seems like perfectly fine code

12:31 you also could have used a reduce rather than an into/for, but that's a matter of taste, imho

12:31 i prefer the into/for route, but that's just me

12:31 clgv: which is the default library to implement a service via ring + compojure consuming and producing JSON?

12:32 weavejes_: clgv: There's ring-json

12:33 clgv: weavejester: I just found that, but it's use case is serializing return values only. what is the usual setup to get the json data from the request?

12:33 weavejester: clgv: It does both

12:34 clgv: ah thank you. quick reading was too quick ;)

12:35 dnolen_: puredanger: is CLJ-1499 ready to go? http://dev.clojure.org/jira/browse/CLJS-836

12:36 m1dnight_: Can I use an atom to wait() and notifyAll()?

12:37 Or should I create a seperate object for that?

12:41 EvanR: when i do future-cancel, and then the corresponding java Future.cancel "cancels a task if possible", what exactly does this mean?

12:41 what if my "task" is blocking waiting for something

12:41 does it really cancel?

12:43 justin_smith: EvanR: well, .cancel is a method on java.util.concurrent.Future http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)

12:43 it returns a boolean that tells you whether it was actually cancellable

12:45 EvanR: so future is the recommended way to spawn a thread to do something, possibly forever?

12:45 llasram: EvanR: And the actually mechanics of the interruption will generally defer to http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt()

12:45 EvanR: llasram: thanks for that, i was really wondering

12:45 justin_smith: EvanR: it's one way to do it, and it tends to work pretty nicely

12:46 (inc llasram)

12:46 thanks for the extra info

12:46 lazybot: ⇒ 43

12:46 EvanR: on one hand you see people saying threads cant be killed/cancels/interrupted, and then theres this interaction with Future

12:46 justin_smith: EvanR: not that they *can't* be

12:46 just that there is no foolproof way to do it

12:46 llasram: Exactly. It's just ultimate cooperative

12:47 ultimately

12:47 EvanR: and then theres this Thread.interrupt which suggests that it works if its sleeping or "doing IO"

12:47 and not if its busy looping

12:47 llasram: Exactly -- that's the "cooperative" part

12:48 justin_smith: EvanR: if you have a loop in your future, check (.isInterrupted (Thread/currentThread)) before recurring

12:48 EvanR: good to know

12:48 justin_smith: a future-cancel will set the interrupted flag

12:48 then you are cooperating :)

12:48 EvanR: im planning to be blocking-dequeuing

12:48 then looping

12:49 so hopefully i dont need to check the flag explicitly

12:57 justin_smith: EvanR: I'd say a check on that flag can't hurt and could possible help "If none of the previous conditions hold then this thread's interrupt status will be set." - better safe than sorry

12:58 EvanR: yes

12:58 justin_smith: it's effectively a race condition, if you catch the thread while it isn't blocking, the interrupt is a no-op (other than setting that flag)

12:59 EvanR: hold on... what would cause a no-op?

12:59 justin_smith: the thread isn't blocking, so none of the listed exceptions are triggered

12:59 EvanR: what exceptions

13:00 justin_smith: the ones listed before "If none of the previous conditions hold then this thread's interrupt status will be set." in the docs llasram linked to

13:01 EvanR: urg

13:01 justin_smith: which makes it clear that you should check that status, to be safe ##(.isInterrupted (Thread/currentThread))

13:01 lazybot: ⇒ false

13:02 justin_smith: you can wrap it in a function (defn alive? [] (not (.isInterrupted (Thread/currentThread))))

13:02 EvanR: so if it happens to not be blocking on the queue, the flag will get set and obviously nothing like ClosedByInterruptedException will be thrown, and then later it will attempt to dequeue, and the flag being set doesnt make a damn of a difference?

13:02 it will just continue?

13:02 justin_smith: as llasram meantioned, at the root, it is cooperative, you need to check that flag to cooperate

13:02 EvanR: exactly

13:03 EvanR: got it

13:04 and also i need a loop recur, not normal recursion for a thread like this to work?

13:04 or is there something like "loop forever"

13:06 justin_smith: using the function I defined above (while (alive?) ...)

13:26 danneu: building an oauth api at the moment. can anyone recommend a site with a pleasant oauth api experience that i can swaggerjack some ideas from? so far i'm aping twitter and github

13:28 took a gander at oauthbible.com and was paralyzed with indecision

13:28 ajmccluskey: danneu: Stack Overflow works well from memory

13:28 danneu: ajmccluskey: thanks

13:29 linkedin ranks up there among the worst oauth apis i've used, though

13:35 TimMc: danneu: What made it bad?

13:37 ajmccluskey: Is there a library function to check "cyclic equality"? e.g. (ce? [1 2 3] [2 3 1]) => true

13:38 justin_smith: I assume this is more strict than (= (set a) (set b))

13:39 ajmccluskey: justin_smith: yeah - I'm looking at a path through a graph where I can start from any node in the path - so order matters, but not starting point

13:39 justin_smith: I checked clojure.math.combinatorics, it was my first guess, but seems to have nothing like that

13:40 ajmccluskey: I'm thinking I can roll my own easily enough with a rotate fn, iterate, and some

13:40 justin_smith: I bet a combination of cycle and take would be useful

13:41 ,(take 4 (drop 2) (range 4))

13:41 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/take>

13:41 justin_smith: err

13:41 ,(take 4 (drop 2 (range 4)))

13:41 clojurebot: (2 3)

13:41 justin_smith: ,(take 4 (drop 2 (cycle (range 4))))

13:41 clojurebot: (2 3 0 1)

13:42 ajmccluskey: justin_smith: thanks, something like this should make for a neater rotate function

13:43 EvanR: calculate the cyclic equivalence class representative and compare those

13:43 triss: ok so I've got a load of static data in: resources/public/my_files

13:44 how do I add a route to compojure that serves these up?

13:44 justin_smith: EvanR: that is awesome, TIL

13:44 (inc EvanR)

13:44 lazybot: ⇒ 7

13:44 EvanR: wuh

13:45 justin_smith: ?

13:45 * EvanR looks up TIL in aol travel guide

13:45 justin_smith: today I learned

13:45 EvanR: i didnt even think my idea was that great

13:45 justin_smith: heh, no, it's the right answer here

13:49 ajmccluskey: EvanR: I don't know enough maths to understand what you mean :(

13:50 TimMc: EvanR: You mean rotate to lowest-ID element or something?

13:51 so [9 7 23 4 10] would be become [4 10 9 7 23]

13:52 EvanR: good idea ;)

13:52 * ajmccluskey reads https://en.wikipedia.org/wiki/Equivalence_class

13:54 justin_smith: ajmccluskey: the idea is to define a rotation that would be guaranteed to give you the same result for any rotation of the same items (eg. TimMc's suggestion of rotating so the lowest item is always first before comparing)

13:55 ajmccluskey: justim_smith: gotcha

13:55 TimMc: There's probably some higher-performing approach where you take the first element of the first path, find a match in the second path, then walk both and compare.

13:55 ajmccluskey: TimMc: EvanR: thanks

13:55 TimMc: Do you know for sure that your paths are simple cycles?

13:55 or whatever the term would be

13:56 ajmccluskey: TimMc: I thought of that, but my paths may traverse the same node multiple times

13:56 TimMc: In that case finding the class representative could be tricky.

13:56 EvanR: sounds like a more sophisticated notion of equivalence

13:57 TimMc: Pathological cases could look like ##(take 20 (interleave (repeat 0) (range)))

13:58 lazybot: ⇒ (0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9)

13:58 TimMc: err, close enough

13:58 ajmccluskey: basically, yes

13:59 TimMc: The slow and simple approach it is!

14:00 ajmccluskey: right now I was just looking at doing this for a unit test, so the easiest approach is to manually verify that my returned path is equivalent to the expected output in the sense I'm thinking and then reorder the expected output

14:00 TimMc: This is probably a *great* opportunity to use test.check, by the way.

14:01 ajmccluskey: TimMc: good point. I'm verifying an eulerian path, so I guess I could verify that the path is valid and contains each edge only once.

14:05 ebaxt: ,(defrecord Foo [a])

14:05 clojurebot: sandbox.Foo

14:05 ebaxt: ,(eval (list (symbol (str (-> (Foo. "a") class .getName) "/create")) {:a "a"}))

14:05 clojurebot: #sandbox.Foo{:a "a"}

14:05 ebaxt: I can't figure out how to do the above without eval, any suggestions?

14:07 gfredericks: ebaxt: what's the input? an instance of Foo?

14:08 ebaxt: it's not clear what the crucial part of this is that you're trying to replicate

14:09 ebaxt: gfredericks: I'm trying to call the constructor function of a record using only an instance of that record

14:09 gfredericks: ebaxt: I assume assoc wouldn't work for your use case?

14:11 ebaxt: gfredericks: So basically I want to call (map->Foo {:a "a") , only I must figure out which record by the instance passed to me

14:15 gfredericks: I don't think there's any clean way to do this, but maybe cleaner than what you have

14:15 ebaxt: gfredericks: I have a couple of workarounds.But I'm trying to understand why the above works but not (. (resolve (symbol (-> (Foo. "a") class .getName))) create {:a "a"})

14:15 gfredericks: ,(Foo. 2)

14:15 clojurebot: #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: Foo, compiling:(NO_SOURCE_PATH:0:0)>

14:16 justin_smith: . is a reader macro, you cannot synthesize args to it

14:16 you need eval for that

14:16 TimMc: ajmccluskey: I was thinking more that test.check might help you generate some really good pathological test cases. :-)

14:16 Bronsa: ebaxt: you have to use reflection

14:16 mgaare_: ebaxt: you could create a Constructible protocol and implement it on the records you want, if you know them ahead of time

14:17 ebaxt: mgaare_: Yeah, that's the workaround I'm going with

14:17 mgaare: (probably with a different name, one that's spelled correctly at least)

14:17 Bronsa: ebaxt: core.incubator has a new-by-name function you can use

14:18 ajmccluskey: TimMc: my code got me past the question in my course, so I'm almost scared to go there right now. Got a deadline :p. Definitely want to throw test.check at it when I get time.

14:18 puredanger: dnolen_: re CLJ-1499, it's ready to be screened (hey, you could help with that wink wink)

14:19 dnolen_: puredanger: heh ok

14:19 ebaxt: Bronsa: thanks, that worked

14:19 puredanger: dnolen_: I'm still mentally wondering whether I should push forward with the additional stuff I have on it for key- and val-only iterators

14:20 ebaxt: justin_smith: thanks btw, that explains it

14:20 Bronsa: puredanger: btw re: 979 I tried loading aleph/lamina/core.typed with the new patch and didn't see any slowdown in compilation times. If anything I actually saw a minor performance improvement but that was probably a random fluctiation

14:21 puredanger: Bronsa: I'm not really expecting any slowdown, but it's a question that needs to have an answer

14:21 dnolen_: puredanger: probably not a bad idea? keys / vals is quite common. CLJS used to not have keys / vals specific iterators, adding them lot match Clojure made a huge difference.

14:21 s/lot/to

14:22 puredanger: dnolen_: I added a new interface to obtain those specific iterators, then made use of them in CLJ-1602. surprisingly little improvement.

14:22 over the improvements already in 1602 that is

14:22 maybe a 5% additional benefit

14:23 dnolen_: puredanger: you benching against zipmap usage or something like that?

14:23 puredanger: there's a test in 1602

14:23 there are so many outstanding patches with perf improvements in different areas right now, it's hard to keep them all straight :)

14:24 reduce over maps, keys, vals, range, repeat, cycle, iterate, vec, etc!

14:26 dnolen_: the additional iterators required the creation of a new interface (I called it MapIterable) to provide them. I wasn't sure if I was pushing it too far for a 5% benefit.

14:27 dnolen_: puredanger: right 5% seems kind small

14:28 puredanger: it's basically just saving the cost of creating and throwing away the entry objects, but object allocation is really fast these days

14:29 maybe I'll make a separate ticket for it so it can be evaluated separately

14:34 EvanR: justin_smith: what about easily getting exceptions from the future thread

14:35 noonian: Evan I believe if you deref a future that threw exceptions it will throw it on the thread you deref the future from so you could try/catch your deref

14:35 EvanR*

14:35 EvanR: right...

14:36 though my main thread is busy, it cant wait forever on a particular future

14:36 and yet another thread for this purpose seems to have the same issues

14:39 noonian: if you want to know about exceptions on your main thread but dont want to block maybe core async is appropriate? could have a channel and deref your future in another thread (of just try/catch in your future thread) and put on the channel if you get an exception

14:40 EvanR: i dont even want to know about it in the main thread

14:40 i just want the error print out somewhere

14:40 i guess i have to catch all exceptions in the future

14:40 noonian: can't you just wrap your call inside future in a try/catch block then?

14:44 znn: what is the difference between a channel and a message bus?

14:45 or is a channel another term for a bus and vice versa?

14:45 noonian: in this context a channel is specific to core.async, its like a queue with "blocking" put/read semantics by default

14:47 zanes: Aw man. I guess instaparse can’t parse indentation?

14:48 gfredericks: zanes: I think I remember coming to that conclusion at some point

14:48 zanes: gfredericks: Sad panda.

14:48 gfredericks: is generating keywords w/ test.check a guaranteed memory leak?

14:48 reiddraper: probably

14:49 gfredericks: I can't remember if they get GC'd somehow

14:49 amalloy: EvanR: you can put a try/catch in your future that prints the exception somewhere useful, or even write a macro/function that does that. or you can set the defaultuncaughtexceptionhandler for your whole program, which controls what happens when an exception makes it out of a thread's run() method

14:50 gfredericks: pretty sure they do get GCd

14:50 stuartsierra: Keywords are interned as WeakReferences.

14:50 amalloy: as long as you don't hang onto them, anyway

14:51 noonian: zanes: this stackoverflow talks about trying to parse indentation ala python in instaparse: http://stackoverflow.com/questions/16779676/can-i-parse-an-indentation-based-language-using-instaparse-or-any-other-clojure

14:51 zanes: noonian: Yeah, thanks. I saw that one.

14:52 Serializing it and running it through instaparse a second time feels gross.

14:52 gfredericks: stuartsierra: amalloy: yeah that was my hunch

14:52 noonian: agreed

14:52 amalloy: gfredericks: if you're interested, the relevant code is in Keyword.intern and Util.clearCache

14:52 gfredericks: has anybody written a JSONish generator for test.check yet?

14:53 amalloy: gfredericks: how would that be different from (fmap json/generate-string ...)?

14:53 gfredericks: I remember bbloom complaining about parsing json with keywords...I assume that's just because calling .intern at runtime is slow, not because of memory concerns

14:53 stuartsierra: It's not clear to me if Keyword automatically removes references to interned keywords that are never used.

14:53 bbloom: gfredericks: ignoring perf, i'm complaining semantically

14:53 puredanger: stuartsierra: yes

14:54 that is, yes they should get removed

14:54 amalloy: stuartsierra: never used? they're used once, of course, when they get interned. but after that if nobody has any references to them, they get cleaned up

14:54 Bronsa: stuartsierra: yeah, see Util.clearCache

14:54 bbloom: the day you decide you want a map with URLs as keys is the day you say "fuck. i wish i didn't keywordize everything"

14:54 gfredericks: amalloy: it wouldn't be necessarily generating the strings, just a restricted set of scalars & collections -- e.g., only vectors (no lists/sets), no characters, only keyword keys (or strings if bbloom is looking)

14:54 I think I might have just started three parallel conversations

14:54 amalloy: i always weigh in with bbloom on this one

14:54 puredanger: bbloom: given the evil things URLs do with the network, I don't think I'd use java.net.URL as a key in a map

14:54 amalloy: gfredericks: it's a test of character. you've just started a fourth i think

14:54 TimMc: Ooh, this is my favorite complaint too!

14:55 bbloom: puredanger: no, i meant string encodings of URLs

14:55 stuartsierra: An interesting idea: "soft intern" — create a new keyword, but only intern it if it's already interned.

14:55 amalloy: anyone who can keep up is clearly of high moral fibre

14:55 puredanger: bbloom: withdrawn :)

14:55 bbloom: puredanger: ie anything other than a valid keyword as a property which is valid json

14:55 amalloy: stuartsierra: why would that be useful? it's not different from the regular intern except that it allocates a map entry briefly, right?

14:55 bbloom: hell, even just id numbers :5 vs "5", neither of which are 5, which is invalid json

14:56 gfredericks: k I'm prollably gonna put a json-data generator in test.chuck

14:56 stuartsierra: amalloy: It's a vague thought: If I'm creating keywords from JSON, or an HTTP request, or something, I don't want interned keywords for things which weren't already keywords in my code.

14:57 dgleeson: hello all, does anyone know if there is a way to get at the file attributes of a file in clojure? I can see how to read and write, but what if I want to know the permissions or ownership?

14:57 stuartsierra: But I guess I wouldn't want them to be keywords at all.

14:57 puredanger: gfredericks: regarding your comment N messages ago, in 1.7 keywords and symbol no longer string intern

14:57 amalloy: stuartsierra: right, exactly: you don't want keywords

14:57 if you *did* get keywords which weren't interned, you would be inviting disaster

14:57 stuartsierra: yeah, right

14:57 of course

14:57 gfredericks: puredanger: oh I remember seeing something about that; curious what the advantage is there

14:57 puredanger: intern is slow :)

14:58 gfredericks: puredanger: does that mean keyword comparisons might require string comparisons?

14:58 puredanger: keywords are still cached

14:58 dgleeson: oh, doh, I suppose I could just use the java interopt to get that

14:58 gfredericks: okay that's the detail I was missing

14:58 amalloy: gfredericks: for your json generating thing, you can just do some slight tweaks to gen/any, right?

14:58 stuartsierra: dgleeson: Yes, you will have to use Java interop.

14:58 puredanger: gfredericks: the cache code was tweaked slightly too to make it faster

14:58 gfredericks: puredanger: so before it was effectively "interning" in two steps?

14:59 amalloy: totes

14:59 amalloy: also maybe use my double generator

14:59 puredanger: gfredericks: yes, it's all tricky

15:02 gfredericks: ~it is all tricky

15:02 clojurebot: Alles klar

15:04 gfredericks: I just sampled an old json generator I wrote and got: {:--:Rb!?8:tTJi-:iB5:8*?*m false, :JJ:8:3:T (), :d+eI:L:!KXg false}

15:04 curious if that's even readable

15:04 ,{:--:Rb!?8:tTJi-:iB5:8*?*m false, :JJ:8:3:T (), :d+eI:L:!KXg false}

15:04 clojurebot: {:--:Rb!?8:tTJi-:iB5:8*?*m false, :JJ:8:3:T (), :d+eI:L:!KXg false}

15:08 TimMc: gfredericks: Make sure to throw some \u2028 and \u2029 in there for good measure.

15:10 gfredericks: TimMc: in the oven: https://github.com/gfredericks/test.chuck/tree/regexes-2#string-from-regex

15:11 TimMc: oooo

15:13 amalloy: gfredericks: i don't want test.chuck to subsume my library, but are you aware of https://github.com/amalloy/thrift-gen ?

15:14 TimMc: gfredericks: Please tell me you have a macro that turns that BNF into clojure code. :-)

15:14 gfredericks: TimMc: what? you mean instaparse?

15:15 amalloy: nope

15:15 TimMc: Does instaparse do that?

15:15 gfredericks: TimMc: well it turns the BNF into a parser...

15:16 amalloy: what BNF are we even talking about?

15:17 gfredericks: I hope this one, otherwise I'm even further confused: https://github.com/gfredericks/test.chuck/blob/regexes-2/resources/com/gfredericks/test/chuck/regex.bnf

15:18 amalloy: man, who looks in resources/ anyway?

15:18 uptown: i have a different generation question. i seem to spend a lot of time wrapping fns for use by controllers of some sort. 'component' for instance. has anyone tried to generate those wrappers? maybe scanning code based on metadata tags or similar?

15:32 TimMc: I think that's called spring.

15:33 and it is the source of all evil

15:36 clrnd: hey is there something like Akka for Clojure?

15:36 xemdetia: speaking of sources of evil, does anyone know of a quick and dirty LDAP server for integration testing?

15:36 uptown: i was hoping for a clever metamacro

15:36 but i see what you mean

15:40 amalloy: i think sdegutis has something vaguely like the evil uptown is thinking of, but i don't recall the details

15:42 gfredericks: ~metamacros are functions for writing macros for writing macros for writing functions for deleting your code

15:42 clojurebot: Cool story bro.

15:42 gfredericks: ~metamacros |are| functions for writing macros for writing macros for writing functions for deleting your code

15:42 clojurebot: You don't have to tell me twice.

15:49 turbofail: clrnd: there's some libraries that do bindings for akka - https://github.com/setrar/akka-clojure

15:50 might be a little bit dead though

15:51 clrnd: turbofail, I see, was hoping for something actually clojurist

15:52 turbofail: message-passing isn't really the clojure way™

15:53 stuartsierra: message-passing — with queues — is totally the Clojure way!

15:53 core.async + your messaging bus of choice is really all you need.

15:54 dnolen_: reiddraper: ping

15:54 turbofail: i guess i meant more "erlang-style message passing"

15:54 reiddraper: dnolen_: pong

15:55 dnolen_: reiddraper: I have a some real interest to just port test.check a la core.async now (rather than wait for feature expressions), I've already started, probably won't take me long to wrap it up

15:55 reiddraper: would you take a patch?

15:55 clrnd: well that's not really fault tolerant

15:56 see akka implements actor system architectures for error tolerance

15:57 reiddraper: dnolen_: yes, however, gfredericks, aphyr and i have been doing some work that may be interesting/tough to do in js. There's a branch now that uses a new RNG, and adds parallel tests, using executors, etc.

15:58 just anticipating some interesting merge conflicts

15:58 gfredericks: oh I'm sure JS comes with a few block ciphers

15:58 dnolen_: reiddraper: that's I meant about core.async style - there's separate directory for all the cljs stuff, no code sharing

15:58 reiddraper: yeah, maybe it won't be too bad then

15:58 gfredericks: well actually: http://docs.closure-library.googlecode.com/git/class_goog_crypt_Aes.html

15:59 dnolen_: reiddraper: it means copy and pasting to but honestly I don't think it's a big deal esp. when the Clojure side may be evolving faster

15:59 reiddraper: ends up being nice, was true for core.async

16:00 reiddraper: dnolen_: here's what the diff looks like at the moment: https://github.com/aphyr/test.check/compare/clojure:master...feature/parallel-testing

16:00 dnolen_: yeah, I think that would be great. Will we be able to run the cljs tests from the command-line?

16:01 dnolen_: reiddraper: yep that's the idea

16:01 reiddraper: excellent

16:01 dnolen_: reiddraper: cljs.test is basically good to go in ClojureScript master

16:01 reiddraper: gfredericks: any objections?

16:01 dnolen_: reiddraper: so I'm making sure all the clojure.test integration stuff just works similarly w/ cljs.test

16:02 gfredericks: reiddraper: nope

16:03 dnolen_: what system deps do you need to run the tests? same as cljs proper?

16:03 l1x: hi guys, i was wondering what am i doing wrong here https://gist.github.com/l1x/3e991063483f1204536f

16:03 it seems i cant catch that exception

16:04 amalloy: ~map

16:04 clojurebot: map is *LAZY*

16:04 amalloy: ~botsnack

16:05 clojurebot: thanks; that was delicious. (nom nom nom)

16:05 turbofail: crypto in javascript?

16:05 amalloy: l1x: that one's for you. map is lazy. it immediately returns a lazy seq, and your try/catch completes successfully. then, the repl tries to print your map, and gets an exception while realizing the seq

16:05 gfredericks: turbofail: the new test.check RNG uses a block cipher

16:05 l1x: amalloy: ahh this is what i missed

16:05 thanks!

16:05 gfredericks: I'd like to figure out something simpler but that would require learning how to test the quality of a RNG

16:06 amalloy: l1x: this would be more apparent if you tried printing the stacktrace, by the way

16:06 dnolen_: gfredericks: cljsbuilds w/ :notify-command, probably simplest for everyone if we just run the tests against Node.js

16:06 amalloy: the summary message that gets printed by the repl is often not terribly useful

16:06 turbofail: gfredericks: ah, so not actual crypto-crypto

16:06 EvanR: theres dieharder for testing rngs

16:06 amalloy: but if you look at the trace, and see it's inside of printing instead of inside something else...

16:06 gfredericks: turbofail: no, not crypto-crypto-crypto

16:07 reiddraper: turbofail: actual crypto, but not for the purposes of crypto

16:07 turbofail: heh

16:07 seon: hello

16:07 no one from Lyon

16:07 reiddraper: turbofail: http://publications.lib.chalmers.se/records/fulltext/183348/local_183348.pdf

16:09 l1x: amalloy: so is there any way to catch an exception like this?

16:10 turbofail: doall

16:10 around the map

16:11 l1x: turbofail: thanks!!

16:13 EvanR: ~filter

16:13 clojurebot: filter doesn't stop

16:14 joobus: is aleph considered stable for production work? The bottom of the github page says "Aleph is meant to be a sandbox for exploring how Clojure can be used effectively in this context.".

16:17 ben8: hi. quick question about compojure. I'm missing a run-jetty function?

16:18 joobus: ben8: I'm guessing you are reading some example with a run-jetty function?

16:18 ben8: ring can be used with multiple servers. run-jetty runs the jetty server, and there is some include that you'll need to use it.

16:18 ben8: I've read several of various age I guess

16:19 ah right, it's a ring function. compojure has an app function

16:20 Petruchio: I'm having trouble getting started with Leiningen. Per the instructions, I downloaded lein (to Ubuntu), ran it, and I just get the main help menu.

16:20 joobus: Petruchio: go to a scratch directory and do 'lein new app whateveritscalled'

16:21 Petruchio: it should make a new lein folder/app with all the relevant parts if lein installed correctly

16:22 Petruchio: Ah! I didn't get it... apparently it's already installed correctly, since that worked. Thanks.

16:29 EvanR: ,(= false nil)

16:29 clojurebot: false

16:29 EvanR: just checking

16:29 gfredericks: ,(#'= false nil)

16:29 clojurebot: false

16:29 gfredericks: oh right

16:30 Bronsa: gfredericks: did you brainfart for a second and think = was a macro or what?

16:31 gfredericks: Bronsa: yeah I confused inlining with macrotude

16:32 I misremembered the nature of the classic wat

16:32 Bronsa: ,(#'or true true)

16:32 clojurebot: nil

16:32 gfredericks: oh also there's that other one

16:32 ,('= false nil)

16:32 clojurebot: nil

16:32 gfredericks: still a falsy answer, but now quite the same ;-)

16:32 Bronsa: ,('= true true) is more effective

16:32 clojurebot: true

16:32 gfredericks: not*

16:33 Bronsa: :< no wait.

16:33 ,('= false true) there

16:33 clojurebot: true

16:33 stuartsierra: ugh

16:33 Never do that again.

16:34 gfredericks: ,(:= false true)

16:34 clojurebot: true

16:34 gfredericks: it's great that = := '= and #' are all callable

16:35 #'= I mean

16:35 ,#{= := '= #'=}

16:35 clojurebot: #{= #'clojure.core/= #<core$_EQ_ clojure.core$_EQ_@88f71a> :=}

16:36 nullptr: ,((juxt = := '= #'=) 1 2)

16:36 clojurebot: [false 2 2 false]

16:37 * nullptr attempts to erase this trivial knowledge from his brain, fails

16:37 gfredericks: ,(let [eqs [= := '= #'=]] ((fn [[f & args]] (apply f args)) (shuffle eqs)))

16:37 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol>

16:37 gfredericks: ,(let [eqs [= := '= #'=]] ((fn [[f & args]] (apply f args)) (shuffle eqs)))

16:37 clojurebot: false

16:38 gfredericks: I guess that could be written a little clearer

16:38 ,(let [eqs [= := '= #'=], [f & args] (shuffle eqs)] (apply f args))

16:38 clojurebot: #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: Symbol>

16:45 l1x: joobus: i tried the netty version but it was yielding to less performance as stock compojure with jetty

16:45 ztellman: joobus: yes, it's used extensively in production, that sentence hasn't changed in three years

16:46 joobus: ztellman: thanks.

16:46 l1x: haha, i did not realize the author is here! :)

16:46 ztellman: did you measure the performance of aleph?

16:46 joobus: ztellman: I'm guessing you favor event-based architecture for web servers?

16:46 ztellman: l1x: https://github.com/ptaoussanis/clojure-web-server-benchmarks/

16:47 joobus: I favor having the ability to do async and streaming request/responses

16:47 but the synchronous ring model is good enough for most cases

16:48 joobus: ztellman: yeah, i'm at the point of picking one or the other for a project right now, and at this point it is a toss-up, but I don't want to limit myself down the line. Currently, I use python's twisted framework for most of my web stuff, so I am familiar with the event-based model right now.

16:49 ztellman: joobus: the concurrency model for Aleph is pretty similar to Twisted's

16:49 joobus: i know, i've been reading your/the docs :)

16:50 ztellman: well, happy to answer any questions

16:51 l1x: ztellman: thanks

16:52 joobus: i don't have any brainbusters for you today. I did just notice that benchmarks graph has looked different every time I've looked at it.

16:52 EvanR: always run it until it breaks a speed record

16:52 then publish i

16:52 ztellman: no, we did extensive testing across all of them, with feedback from all the authors

16:53 mostly it's just that people are actively working on improving performance

16:53 l1x: ztellman: are you familiar with this project? https://github.com/basho/basho_bench

16:53 ztellman: a lot of the approaches used by one server tend to get borrowed, too

16:53 l1x: prefer latency + throughput together on a chart when talking about performance

16:53 ztellman: l1x: latency is in the raw data

16:53 l1x: cool

16:53 thanks

17:00 Jaood: ztellman: was the reason of the improvement in performance of Aleph from May to Nov? or is it that just performs much better with big hardware?

17:01 ztellman: jaood: May was 0.3.x, November is 0.4.x

17:01 basically a ground-up rewrite

17:01 a lot of the improvement is from using the latest Netty

17:03 mgaare: I've been working on updating a little TCP server app that was originally on aleph 0.3 to the stack around aleph 0.4. Liking it so far

17:06 l1x: ztellman: nice!

17:06 mgaare: ztellman: it might be nice to have a link to the aleph google group somewhere in the readme, since there's a lot of useful stuff on the group that helps fill in the gaps until the documentation catches up

17:06 l1x: i am rerunning my benchmarks just noticed the new version

17:06 Jaood: ztellman: cool, thx

17:07 ztellman: l1x: here's latency metrics from an earlier run of the benchmark https://github.com/ptaoussanis/clojure-web-server-benchmarks/blob/5fd6ec249851dd9ab08e32f590929a9a2f3cced8/results/20141025-20-40.png

17:07 it was too tedious to do it for every run

17:08 l1x: ztellman: thanks, this is exactly why i settled on basho_bench

17:08 it just 2 commands and you are done

17:09 ztellman: l1x: might be worth investigating for this, or we just write a little turd script that turns the benchmark output into a csv

17:19 l1x: ztellman: cool

17:19 ztellman: where did the wrap-ring-handler function go from aleph?

17:19 ztellman: l1x: it's gone, aleph handlers = ring handlers

17:19 except that aleph handlers can returned a deferred response

17:20 l1x: nice one!

17:20 noonian: long time passing

17:21 l1x: ztellman: WARNING: get already refers to: #'clojure.core/get in namespace: hystrix-event-stream-clj.core, being replaced by: #'aleph.http/get

17:21 Jaood: ztellman: does Aleph implements ring-core or it implements some ring netty adapter?

17:22 ztellman: Jaood: it follows the ring spec for requests and responses

17:23 I'm not sure if the lein plugins for Ring would work with it, last I checked they assumed servlets but that may have changed

17:27 nicferrier: can anybody think of a good way to handle async http requests with go blocks?

17:27 amalloy: l1x: that's a warning to remind you to stop using :use

17:27 ztellman: nicferrier: aleph can do that

17:27 amalloy: (or :refer :all)

17:27 ztellman: nicferrier: you just coerce the channel returned by a go block to a Manifold deferred

17:27 nicferrier: ztellman: looking, thx.

17:28 puredanger: …. said the technologically advanced alien

17:28 seriously, that was like the nerdiest thing I heard all day ztellman

17:28 ztellman: puredanger: I try

17:28 l1x: amalloy: you are right, i have stopped using it, but this time i got the code from my co-worker and guess what :)

17:28 thanks for pointing out though

17:28 amalloy: l1x: put the fear of god into your co-worker

17:29 l1x: :D

17:29 ztellman: i see lots of 500 errors in the logs are you interested what is happening or you are aware of these ?

17:30 ztellman: l1x: this is in the webserver-benchmark?

17:30 l1x: yes

17:30 well it seems the new code is a little bit unhappy with hystrix

17:30 ztellman: l1x: I'm not aware of any issues, happy to look at any stack traces

17:31 l1x: this is weird

17:31 the performace is up ~20%

17:31 ztellman: why is hystrix being used in the benchmarks, exactly?

17:32 l1x: http://s4.postimg.org/arrpn2x4s/summary.jpg

17:32 out stack works with hystrix

17:33 ztellman: oh, this isn't the standard benchmark, it's your service, gotcha

17:33 l1x: yes, sorry, i misunderstood your question earlier

17:33 i wanted to compare our stack + aleph 0.3 vs. our stack + aleph 0.4

17:33 ztellman: I see

17:34 l1x: yeah it looks pretty sweet

17:34 ztellman: yeah, should be an across-the-board improvement

17:34 but at that throughput maybe not too drastic

17:34 l1x: ok, i am going to figure out why hystrix is unhappy

17:34 this is on my 13" mbp

17:34 do you have any performance recommendation how to start up the service?

17:35 :max-threads 200 :min-threads 20 or something like that

17:35 ztellman: oh

17:35 the defaults should be okay

17:35 you can specify the executor

17:35 check out aleph.flow

17:35 l1x: cool thanks!

17:42 arohner: l1x: FYI, the words "async", "performance" and "hystrix" are unlikely to go together well, depending on your load

17:43 (assuming you're using the default hystrix thread pool)

17:44 m1dnight_: is there a function that allows me to modify the statements in tail position of a form?

17:44 im wanting to replace either all recurs (which are in tail position by definition) or otherwise the other expressions in tail position

17:45 l1x: arohner: i see, do you have any more details? we are in the initial phase of this project

17:45 so if you have more context please share it

17:45 arohner: m1dnight_: you could use a (complex, hard to write) macro to do that, but first I'd ask why

17:45 ztellman: m1dnight_: https://github.com/ztellman/vertigo/blob/master/src/vertigo/core.clj#L409-L441

17:45 arohner: l1x: hystrix runs each command in a separate thread, so then if the command times out, it just terminates the thread

17:45 m1dnight_: because i'm writing an actor library for my thesis and I have to have hooks when a receive block (which is my macro) finished

17:46 arohner: l1x: that works fine, but lots of threads = lots of context switching, which is a problem if you want "real" performance

17:47 l1x: if you care more about reliability, that's great. I'm just pointing it out because you were mentioning benchmarks

17:47 l1x: hmm i see what you mean

17:49 TimMc: arohner: Have you played around with their newer support for rx?

17:49 arohner: TimMc: no

17:49 TimMc: Previously there was no way for an Observable-emitting Hystrix command to register failure (leading to a circuit breaker trip) but I hear they've addressed that now.

17:50 l1x: arohner: what is the alternative way of handling a request lets say skip hystrix, just use a go block or something

17:50 is there a good pattern to lets say talk to a DB with a timeout and retry?

17:50 arohner: TimMc: I don't know enough about how Rx works. What is the recovery situation like? they still terminate your thread?

17:52 l1x: probably, but that depends on your DB drivers

17:52 l1x: if you need serious performance, the best way is to process all the async requests in the same thread, using NIO select

17:53 but that code is tricky to write, so I wouldn't recommend it unless you know you need it

17:57 l1x: hmm alright, i am going to investigate this more, thanks for the info

18:06 wildnux: hi, if i have a seq of objects (say eg, File objects i got using file-seq ), how do i turn the list into a map of name attribute of object and the object itself?

18:07 i tried (map #(assoc m (.getName %) %) s)

18:07 but it created many maps

18:08 justin_smith: what is m ?

18:08 amalloy: wildnux: you are looking for reduce

18:08 Bahman: wildnux: fold the list.

18:08 justin_smith: yeah, actually that does sound like a reduce

18:08 wildnux: justin_smith: the map is called inside let binding, m is empty map

18:10 basically i was doing something like this: (let [s (filteredseqoffilesindir d) m {}] (map #(assoc m (.getName %) %) s))

18:11 justin_smith: ,(reduce #(assoc % %2 (name %2)) {} [:a :b :c :d]) ; something like this

18:11 clojurebot: {:d "d", :c "c", :b "b", :a "a"}

18:11 justin_smith: but with (.getName %2) %2 instead

18:11 wildnux: justin_smith: cool, let me try

18:12 TimMc: arohner: Recovery situation?

18:12 justin_smith: wildnux or (group-by #(.getName %) files) - especially good if more than one file may have the same base name

18:12 wildnux: justin_smith: i tried replacing map with reduce but did not work.. probably i needed to pass empty map as well for it to fold the list

18:12 justin_smith: and it takes an extra arg, the accumulator

18:12 amalloy: it is a common beginner error to try and modify an immutable object in a for loop or a map or something

18:12 arohner: TimMc: in your Rx + hystrix situation. 'normal' hystrix terminates the thread. I was asking how Rx Hystrix recovers there

18:13 amalloy: remember that in clojure, objects never change. if m starts as {}, it will be {} forever. the way to do this sort of "incremental build-up" of an object is with a recursive function, or with reduce, which is the same thing under the hood

18:14 TimMc: arohner: Hmm, not sure. I didn't dig that much into hystrix in the first place after finding out it didn't work well with rx (at the time.)

18:15 wildnux: justin_smith: actually i am calling function on that file object so probably group-by does not work

18:15 justin_smith: why would calling a function on the file make the group-by not work?

18:15 wildnux: calling function on that object as the value of the map

18:16 justin_smith: oh, I see

18:16 wildnux: what i am trying is get list of classes from all of jar files in a directory

18:17 justin_smith: ahh, so the key is .getName and the val is some function call

18:17 wildnux: so, i have file-seq on that directory, filter jar files, create JarFile out of them and get enumeration of the contents, then again filter based on .class

18:17 and now, i have list of classes for a single jar, i want to write a function which can give me map of jarfile name (absolute path) and the classes in them

18:17 :)

18:19 justin_smith: yes

18:19 justin_smith: ,(into {} (map (juxt keyword #(str % (.toUpperCase %))) ["a" "b" "c"]))

18:19 clojurebot: {:a "aA", :b "bB", :c "cC"}

18:19 justin_smith: juxt / map / into will do that trick

18:20 actually, for is often more readable for that (but it would do the same thing)

18:20 wildnux: justin_smith: cool, let me try juxt as well

18:20 for some reason, i have not been able to get my head around using for for looping and collecting value easily :(

18:21 justin_smith: for is not a loop

18:21 it's a list comprehension

18:22 wildnux: justin_smith: what is the best way to accumulate values using for?

18:22 dbasch: justin_smith: feature request: parse chat lines that have “for” and “loop” in them, and make the bot reply

18:22 justin_smith: ,(into {} (for [c ["a" "b" "c"]] [(keyword c) (str c (.toUpperCase c))]))

18:22 clojurebot: {:a "aA", :b "bB", :c "cC"}

18:22 justin_smith: dbasch: that is a good one

18:22 though it could be annoying if you do it wrong

18:23 amalloy: ~for

18:23 clojurebot: for is not a loop

18:23 * amalloy closes issue

18:23 dbasch: feature request: make amalloy a bot

18:24 EvanR: ~though

18:24 clojurebot: Cool story bro.

18:24 wildnux: dang!

18:24 amalloy: dbasch: i did that a while ago. amalloybot was a rousing success

18:24 hyPiRion: ~amalloy

18:24 clojurebot: amalloy is the spotlight illuminating my dumb mistakes

18:24 TimMc: ~amalloybot

18:24 clojurebot: Cool story bro.

18:25 amalloy: apparently this was on march 10th: http://logs.lazybot.org/irc.freenode.net/%23clojure/2014-03-10.txt

18:26 justin_smith: lol, I remember it like it was yesterday

18:29 m1dnight_: Is there a particular reason that macroexpand does not do a "deep" expand?

18:29 it's simply solved by (postwalk macroexpand <form>) though, but i'm not sure

18:30 ztellman: midnight_ macroexpand is for the top-level form, by definition

18:30 amalloy: m1dnight_: because it's not the compiler, and trying to be the compiler is hard

18:30 ztellman: m1dnight_ and don't use postwalk with macroexpand, that will cause issues

18:30 https://github.com/ztellman/riddley

18:30 amalloy: postwalk macroexpand, for example, is one of those things that works great for simple cases but breaks if you try to rely on it

18:32 ztellman: how does that compare to the stuff in tools.macro?

18:32 m1dnight_: hrm, any hints, then?

18:32 I can't imagine a case where it could break too, though

18:32 ztellman: amalloy: last I checked, tools.macro didn't do inline function transformation, and didn't differentiate between expressions and non-expression forms

18:33 amalloy: m1dnight_: easy. (quote (let 1))

18:33 ztellman: m1dnight_ did you see this wen I posted it earlier? https://github.com/ztellman/vertigo/blob/master/src/vertigo/core.clj#L409-L441

18:33 m1dnight_: ztellman: Yes, that's what Im using

18:33 ztellman: I see

18:33 m1dnight_: but i'm thinking that it requires an exanded form, no?

18:33 ztellman: so yeah, use riddley.walk/macroexpand-all

18:33 and apply that

18:33 that's what the code surrounding the quoted region does

18:33 amalloy: that's a perfectly fine expression, which produces the list (let 1). but if you postwalk macroexpand, it will break because it doesn't understand quoting

18:34 m1dnight_: oh, I did not notice the macroexpand-all

18:34 :) sorry

18:34 ztellman: no worries

18:35 amalloy: ztellman: expressions and non-expression forms? i think i understand the difference between those two things but not what tools.macro does wrong with them

18:35 ztellman: amalloy: oh, I just meant that tools.macro didn't give you a way to walk expressions and transform them

18:36 w.r.t. macorexpansion I think the issue is only inline functions

18:36 amalloy: inline functions?

18:36 oh

18:36 inlined functions :P

18:36 ztellman: :inline functions

18:36 not handling that will break pervasive transforms pretty badly, sometimes

18:36 amalloy: yeah, fair enough, that seems like it could matter

18:37 actually i just remembered another issue with tools.macro that is pretty interesting. i wonder if riddley handles it right

18:37 ztellman: file an issue if not

18:38 amalloy: oh, and tools.macro passes in a nil &env, too

18:38 again, last time I checked

18:39 amalloy: ztellman: yeah, pretty sure it does

18:39 ztellman: riddley doesn't have macrolet, does it?

18:39 ztellman: amalloy: it trivailly could

18:40 trivially*

18:40 amalloy: macrolet is like the only thing in tools.macro i use

18:40 ztellman: I just haven't needed it

18:40 amalloy: ztellman: (macrolet [(m [x] `(case ~x ~@(mapcat (partial repeat 2) (range 10))))] (m 9)) is a way to reproduce the problem in tools.macro

18:40 it doesn't break for numbers smaller than 10 and 9, which is the fun part

18:41 Bronsa: amalloy: ouch. sorted map -> hash map

18:41 amalloy: Bronsa: yep

18:41 Bronsa: amalloy: I don't think that's tools.macro's fault

18:41 amalloy: Bronsa: yeah it is

18:41 Bronsa: uh ok.

18:41 amalloy: tools.macro implements something like postwalk, and does it via like (cond (map? x) (into {} (map ... x)))

18:42 Bronsa: ah, gotcha

18:42 ,(defmacro x [] (sorted-map 1 1))

18:42 clojurebot: #'sandbox/x

18:42 Bronsa: ,(class (x))

18:42 clojurebot: clojure.lang.PersistentArrayMap

18:42 Bronsa: i thought it was a case of that ^

18:42 amalloy: i don't think so

18:43 because the sorted map emitted by the macroexpansion of case is consumed by case* at macro time, not emitted to be eval'd

18:43 Bronsa: yeah, makes sense

18:45 ztellman: amalloy: I do handle that case correctly

18:45 I ended up getting bit by it in automat

18:45 amalloy: ztellman: anyway, feature request: add macrolet, c'mon how can you be a macro library without macrolet

18:46 ztellman: amalloy: https://github.com/ztellman/riddley/blob/master/src/riddley/walk.clj#L161

18:46 yeah, ok

18:50 amalloy: ztellman: is a special-cased handler for case really the right way to do this? what if someone else writes a macro like case that needs to emit a sorted map for consumption by something else?

18:50 ztellman: amalloy: this is the underlying case* map

18:51 if they want to handle sorted-map specially, they can define a special handler for whatever their scope is

18:52 since we don't know what the comparator is, that's the only way we can do it

18:52 amalloy: i see, you first go through their predicate/handler function

18:53 ztellman: amalloy: right, and if the predicate fires, I don't descend any further

18:53 you can have scoped transforms

18:54 chouser: What if I want to write some transit data, but for any object that doesn't have a write handler, I'd like to just write out a special symbol, like 'unwritable. That should be possible, right?

18:55 amalloy: ztellman: what about https://github.com/ztellman/riddley/blob/master/src/riddley/walk.clj#L242-L243 ? it won't trigger this case/case* issue because you handle that separately. but if i want to transform some of my code, and it's inside of a map that's sorted and needs to stay sorted, i don't want to have to handle that myself

18:56 ztellman: amalloy: you can halt the walk when you find a sorted map

18:56 unless (empty sorted-map) retains the comparator?

18:56 in which case I should change that

18:56 Bronsa: ztellman: it does

18:56 ztellman: oh!

18:57 ok, new release forthcoming soon

18:57 amalloy: lovely

18:58 ztellman: you can enjoy the shiny new features in 1.4 by using mapv here, too: https://github.com/ztellman/riddley/blob/master/src/riddley/walk.clj#L237

18:58 ztellman: amalloy: eh, I'll use (into (empty x) ...) just to make sure I retain whatever weirdo vector type it is, too

19:01 amalloy: ,(var inc dec)

19:01 clojurebot: #'clojure.core/inc

19:01 amalloy: very funny, clojure

19:04 ztellman: why is walkable? defined the way it is? is it intended to roughly correspond to "forms which could possibly be macro invocations" or what? it seems weird to say "sequential but not a vector or a map entry"

19:04 ie, it looks kinda like a weird way to write the function seq?

19:04 ztellman: amalloy: I'm pretty sure walkable? means expression-ish

19:05 yeah, it's only used by walk-exprs

19:05 poor name

19:06 amalloy: i don't get expression-ish at all. vectors are expression-ish, in that they are actual expressions

19:08 if you just used seq? instead of defining walkable? i think you'd be fine; all the uses of walkable? that exist seem to be using it to check for a special form

19:08 ztellman: amalloy: it's been a while since I looked at this code, I recall some reason seq? wasn't good enough

19:08 just not what it was

19:08 and I may have been wrong

19:10 amalloy: i worry because Sequential is an open interface, of course, so someone can write a sequential thing which is neither a vector nor a seq, so that you'll think it's walkable but the compiler wouldn't actually treat it as a macro invocation

19:10 ztellman: fair point

19:26 crispin: hi there crew!

19:26 I cant get *command-line-args* to work

19:26 I want to get the name of the executable, argv[0] in other languages

19:26 if I (defn -main [& args]

19:27 args is everything but the first argument

19:27 if I use *command-line-args*, the same thing with lein run, and nil with a binary

19:27 how do you get the name of the executable

19:28 Im using "lein bin" to make a standalone executable

19:29 https://github.com/Raynes/lein-bin

19:30 $ lein run arg1 arg2

19:30 Program: arg1

19:31 $ target/binary arg1 arg2

19:31 Program: nil

19:34 http://rosettacode.org/wiki/Program_name#Clojure

19:35 ^ this doesnt work

19:35 justin_smith: crispin: with a *nix type system, you should find it via (System/getenv "_")

19:35 ,(System/getenv "_")

19:35 clojurebot: #<AccessControlException java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv._)>

19:35 crispin: yeah its unix... let me try

19:37 $ lein run arg1 arg2

19:37 Program: /usr/bin/java

19:37 $ target/binary arg1 arg2

19:37 Program: nil

19:37 works with leiningen. Doesn't work with standalone

19:38 but good idea to use java interop

19:38 justin_smith: OK. Try printing the output of (System/getenv) from the standalone, there may be some env key

19:38 if it's anywhere at all that is

19:40 crispin: justin_smith: nope

19:40 has SHELL, and PWD

19:40 but no executable name

19:40 sheeeeet :P Am I gonna have to look up the PID in /proc?

19:40 blech

19:41 justin_smith: that's weird, because I know for a fact that the shell puts that info into env for the java process

19:41 so I don't know why java is hiding it from you...

19:41 crispin: it could be a side effect of lein bin

19:41 now the header of the self executable is...

19:41 :;exec java -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -client -Droll.version=0.1.0-SNAPSHOT -jar $0 "$@"

19:41 @echo off

19:41 java -XX:+TieredCompilation -XX:TieredStopAtLevel=1 -client -Droll.version=0.1.0-SNAPSHOT -jar %1 "%~f0" %*

19:41 goto :eof

19:42 but I dont see how thats removing the /usr/bin/java

19:44 I think it must be an issue with lein-bin

19:45 will open an issue on the project and see what comes out of it

19:47 justin_smith: if nothing else, you should be able to modify that header to pass in the executable name

19:51 crispin: submitted ticket: https://github.com/Raynes/lein-bin/issues/19

19:51 yes, thanks for your help justin_smith

19:52 justin_smith: cool info of the day "You can get anyone's SSH pubkey from GitHub via https://github.com/USERNAME.keys . Handy for giving people access to servers."

19:53 dbasch: (inc justin_smith) great to know

19:54 (inc _)

19:54 lazybot: ⇒ 1

19:54 dbasch: (inc justin_smith)

19:54 lazybot: ⇒ 160

20:29 crack_user: hey guys

20:30 some one have a good article about clojure immutability internals?

20:31 justin_smith: hyPiRion has a good series of blog posts on persistentvector

20:31 TimMc: ++ to that, good series

20:31 justin_smith: http://hypirion.com/musings/understanding-persistent-vector-pt-1

20:32 (inc hyPiRion)

20:32 lazybot: ⇒ 57

20:33 TimMc: (inc hyPiRion)

20:33 lazybot: ⇒ 58

20:36 triss: so just to double check in clojure the theory for the most part is to keep all the do and doseq etc in the applicaion level of code?

20:38 you would try not to hide these in he api and make sure its happens from a single place?

20:38 or am I not getting FP?

20:40 ztellman: triss: it depends if the library needs to do side effects

20:40 if they're interacting with Java libraries, they often do

20:40 triss: ah ok... coz thats exactly what i've been doing

20:40 just had a little panic there...

20:41 so this "virtual dom" idea... is that becoming really common in libs too?

20:42 but mapped across different objects?

20:42 the code I'm writing is fast becoming a library

20:43 and I can't really work if there any best practices you could folllow for wrappng oo code

20:44 ^wrapping oo java/js code in clojure style clothing

20:50 NoCreativity: Hello people

20:51 Im trying to use clojure.java.jdbc and reuse a transaction, but something is going wrong and my transaction loses connection with database before I can insert all data. Does anybody has any tips ?

20:51 gratimax: can you confirm that you are actually connected to the database for some period of time

20:52 justin_smith: NoCreativity: also, that symptom can be caused by trying to use a lazy operation like map or for inside a db operation

20:52 NoCreativity: gratimax: yes! I have an answer from it with the generated primary key

20:52 justin_smith: where by the time the laziness is forced, you are no longer in the transaction context

20:52 NoCreativity: justin_smith: Aw jeez

20:52 justin_smith: so be sure you aren't doing anything lazy in the db

20:53 NoCreativity: justin_smith: Im trying to use for

20:53 justin_smith: OK, wrap it in a doall

20:53 or use doseq instead of for

20:53 laziness and resource lifetimes don't play nicely together

20:53 gratimax: well you got to it before I did :P

20:53 NoCreativity: Thx a lot, guys!

20:53 I will try here

20:57 crack_user: can I convert clojure symbol to string?

20:57 justin_smith: ,(name 'sym)

20:57 clojurebot: "sym"

20:57 gfredericks: ,(name 'com.gfredericks.forks.org.clojure.test.check.generators.properties/cats)

20:57 clojurebot: "cats"

20:59 crack_user: the ' does the symbol not evaluate?

20:59 justin_smith: ,''cats

20:59 clojurebot: (quote cats)

20:59 justin_smith: it's a read syntax for quote

20:59 which gives you a symbol, instead of resolving it

21:00 ,'''cats

21:00 clojurebot: (quote (quote cats))

21:00 justin_smith: s/symbol/value

21:01 crack_user: it makes sense

21:07 gfredericks: ,(cycle '(boots cats))

21:07 clojurebot: (boots cats boots cats boots ...)

21:10 gfredericks: help I'm about to write a custom data structure

21:14 amalloy: gfredericks: put down the keyboard and back away slowly

21:15 NoCreativity: Im so stupid

21:15 :(

21:15 (sql/db-set-rollback-only! t-con)

21:16 It would never commit my stuff

21:17 Well... btw... I think I need more 4clojure training and reading... :( Again, thank you guys! It made my night. =] Now I'm happy again.

21:18 gfredericks: maybe I'll just start with a sorted set

21:19 justin_smith: NoCreativity: actually, since none of 4clojure deals with side effects, the gotchas of lazy-seqs are not really covered I don't think

21:19 NoCreativity: justin_smith: hmmm... Okay. This made me feel better! =D

21:20 justin_smith: Well... I think these relational databases are going to help me somehow on learning datastructure functions to build data the way I want.

21:20 I hope Im right. ^ ^

21:38 TimMc: gfredericks: Stop it you're making me want to pick up Overtone again!

21:39 boots and cats and boots and cats and boots and boots and boots and cats

21:39 gfredericks: TimMc: huh? like to play boots and cats?

21:39 TimMc: generative music in general

21:40 gfredericks: ,(repeatedly #(rand-nth '(boots boots cats)))

21:40 clojurebot: (cats boots boots cats boots ...)

21:42 TimMc: That generates long stretches of the same word.

21:43 ,(sort-by key (frequencies (map count (partition-by identity (repeatedly 100 #(rand-nth '(boots boots cats)))))))

21:43 clojurebot: ([1 18] [2 9] [3 4] [4 4] [5 1] ...)

21:44 TimMc: True randomness is less satisfying.

21:46 justin_smith: TimMc: yeah, algorithmic composition code is often full of stuff like (repeat (+ x (rand-int y)) z)

21:46 though Xenakis was fond of requiring that events in his compositions fit a poisson distribution

21:47 he was an outlier though

21:47 (he also made the first GUI for making music with)

21:49 gfredericks: okay I have no idea how sorted-set-by works

21:50 ,(def self (sorted-set-by #(> %1 %2)))

21:50 godd2: gfredericks you mean what it does or how it does what it does?

21:50 clojurebot: #'sandbox/self

21:50 gfredericks: ,(conj self 5 1 4 2 3)

21:50 amalloy: gfredericks: it takes a comparator, not a predicate

21:50 clojurebot: #{5 4 3 2 1}

21:50 amalloy: right?

21:50 gfredericks: ,(def self (sorted-set-by #(compare %1 %2)))

21:50 clojurebot: #'sandbox/self

21:50 gfredericks: ,(conj self 5 1 4 2 3)

21:50 clojurebot: #{1 2 3 4 5}

21:50 gfredericks: ,(def self (sorted-set-by #(compare %2 %1)))

21:50 clojurebot: #'sandbox/self

21:50 gfredericks: ,(conj self 5 1 4 2 3)

21:50 clojurebot: #{5 4 3 2 1}

21:50 gfredericks: I don't get this behavior at my repl

21:51 oh I bet it's that damn puget

21:51 amalloy: gfredericks: your pretty-printer is evil

21:51 * gfredericks runs around screaming wildly

21:51 amalloy: what is the draw of puget? so far all i've heard about it is weird bugs

21:52 justin_smith: PRETTY COLORS

21:52 gfredericks: compared to no pretty printer or to some other one I don't know about?

21:52 amalloy: compared to no pretty printer

21:52 gfredericks: you must never deal with data

21:53 amalloy: i manually pprint the things i want pretty

21:53 it's not onerous

21:54 gfredericks: we each have our own stockholm syndrome

21:54 amalloy: i suppose so. but everyone else's is dumb

21:55 justin_smith: ~everyone else |is| dumb

21:55 clojurebot: 'Sea, mhuise.

21:55 gfredericks: so if I want to handle generic unicode "characters" I'm gonna use length-1-or-2 Strings is that accurate? or maybe int I guess?

21:56 justin_smith: gfredericks: the jvm native representation is 32 bit, right?

21:57 so, thanks to sign issues, I would think you would need a long

21:57 TimMc: gfredericks: Is this a regex generator thing?

21:57 gfredericks: TimMc: generator *from* a regex

21:58 justin_smith: oh snapchat maybe so; I'll just stick with strings

22:02 TimMc: "oh snapchat"

22:03 gfredericks: that's what the kids say these days right?

22:04 TimMc: I think so

22:14 andyf: gfredericks: Max code point fits in 20 or 21 bits so int is enough

22:14 gfredericks: andyf: why would justin_smith lie to me?

22:15 andyf: Yeah, still working out some kinks in his OS

22:17 There was a proposal for Unicode lib sent to clojure-Dev in early Oct 2014 . Not sure if it would have anything of use for you

22:18 justin_smith: andyf: wait, I thought it was a 32 bit representation?

22:18 gfredericks: oh the connection between code points and surrogats is nontrivial isn't it

22:18 sourroguhts

22:18 sourguts

22:18 soregum

22:19 andyf: Depends on what you call trivial :-). Just a bit of shifting and anding/prong

22:19 *ORing

22:19 justin_smith: "Characters whose code points are greater than U+FFFF are called supplementary characters. The Java platform uses the UTF-16 representation in char arrays and in the String and StringBuffer classes. In this representation, supplementary characters are represented as a pair of char values, the first from the high-surrogates range, (\uD800-\uDBFF), the second from the low-surrogates range (\uDC00-\uDFFF)."

22:19 http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html

22:20 so it uses UTF-16, but some characters require 2 Chars

22:20 andyf: Wikipedia pages are decent for Unicode info, too

22:21 gfredericks: justin_smith: right but the code point representation is still small

22:21 looks like max is ##16r10FFFF

22:21 andyf: Check out Wikipedia for code point

22:21 gfredericks: ,16r10FFFF

22:21 clojurebot: 1114111

22:22 gfredericks: ~1114111 is totes intsable

22:22 clojurebot: Ok.

22:22 justin_smith: Unicode comprises 1,114,112 code points in the range 0hex to 10FFFFhex

22:22 yeah

22:22 gfredericks: half of which are snowmen characters

22:22 justin_smith: ,Integer/MAX_VALUE

22:22 clojurebot: 2147483647

22:24 andyf: Yeah, we're good until meeting the pangalactic empire, but then different tech will be available

22:24 TEttinger: andyf, if star wars has taught me anything it's that they'll speak either english or huttese.

22:25 or unpronounceable rawrs

22:25 justin_smith: with occasional reverse-polish grammar

22:25 andyf: There is a how to speak wookie book with push buttons to make sounds. Hilarious

22:28 Amazon reviews for it are even entertaining

22:28 TimMc: There are entertaining Amazon reviews for toilet paper, to be fair.

22:28 and gallon jugs of milk

22:29 gfredericks: I'm intrigued that the max unicode char is a palindrome in decimal.

22:29 s/char/code point/

22:29 gfredericks: TimMc: numbers! how do they work!

22:30 TimMc: ,[16r10FF 16r10FFF 16r10FFFF 16r10FFFFF]

22:30 clojurebot: [4351 69631 1114111 17825791]

22:30 rritoch: justin_smith: I completed the reg_assoc function and the re-ungreedy, though I did end up needing to use a parser, I couldn't find a regex that would do the job. https://github.com/rritoch/andylisp/blob/master/src/clj/andylisp/regex.clj

22:32 gfredericks: TimMc: did you know that numbers that look like 100010001000100010001 are never prime?

22:33 no wait

22:33 that's probably false

22:33 andyf: The matches a short regex primes conjecture?

22:34 gfredericks: ,(apply str (repeat (rand-int 10) (rand-int 19389243)))

22:34 clojurebot: ""

22:34 gfredericks: ,(apply str (repeat (rand-int 10) (rand-int 19389243)))

22:34 clojurebot: "90907769090776909077690907769090776909077690907769090776"

22:34 gfredericks: ^ that sort of number

22:34 is never prime

22:35 okay this numeric approach makes it a lot simpler

22:37 andyf: I don't have the heart to tell you that there are undefined holes in the range of code points, and those change from one JDK to the next as more are defined.

22:37 But I don't think that should need to affect your random gen fn

22:41 gfredericks: test.check will tell me if anything weird happens

22:43 andyf: I choose to interpret that as: nothing weird happened before test.check was created

22:50 TimMc: gfredericks: If there's anything I've learned from the tiny bit of number theory I've been exposed to, it's that you can't make provable statements about prime numbers. :-P

22:50 except that there are lots f them

22:50 justin_smith: "60 is not prime"

22:51 TimMc: there's an xkcd for this

22:51 rritoch: TimMc: Prime numbers are evil, as are the supposed "rules" about them, most of the rules you'll run into are simply invalid, like the ln(x) approaching Pi(x) as you near infinity.

22:51 TimMc: http://xkcd.com/1310/ "Goldbach Conjectures"

22:52 rritoch: And yet they're the atoms of the number world.

22:52 rritoch: TimMc: If I recall correctly, the zeta function is the only thing in prime number theory that has provided significant results.

22:53 TimMc: The zeta function has led to significant advances in the field of fragmentary ceramics.

22:54 rritoch: TimMc: I spent a few weeks trying to crack the Pi function. I had this idea that maybe I could find a power that would match the Pi function. I found that no matter what I chose it would curl away from the real value, so I made an adjustment that would curl to ln(x) at some number in the distant future of the pattern. It probably would have worked if the rule about ln(x) was true

22:54 TimMc: Since the ln(x) rule isn't true, it failed miserably

22:55 TimMc: "psychoceramics", that's the phrase

22:56 gfredericks: "The limit of the quotient of the two functions pi(x) and x/ln(x) as x approaches infinity is 1

22:56 "

22:56 rritoch: gfredericks: Yes, that statement is false

22:57 gfredericks: x/ln(x) eventually crosses over pi(x)

22:57 TimMc: Where?

22:58 Reminds me of being given the https://en.wikipedia.org/wiki/P%C3%B3lya_conjecture as an extra credit assignment (but not by name)

22:58 rritoch: TimMc: I really don't know. I don't have enough computing resources to prove it, but that was the explaination I received from experts in number theory as to why curling to it didn't work.

22:59 gfredericks: finite behavior doesn't prove anything about assymptotic behavior

22:59 rritoch: TimMc: Either way, if you solve Pi(x) you solve the P(x) function, and to me Pi(x) seems easier to solve, but it's still not solved.

22:59 gfredericks: what's P(x)?

22:59 rritoch: gfredericks: The nth prime

22:59 gfredericks: ah right

23:01 rritoch: TimMc: Anyhow, my point is, take much of what you learn in number theory with a grain of salt, they are just theories, and many of them have recently been disproven, but the information hasn't fully disseminated.

23:01 TimMc: hmm

23:01 gfredericks: o_O

23:02 rritoch: TimMc: In my case, I wasted a few weeks trying to solve a nearly unsolvable problem using inaccurate information. It wasn't until I consulted the experts that I found my error.

23:03 TimMc: They suggested I look into the zeta function, but my frustration was at the level that I really had to drop that project.

23:03 Fare: hi. Is there an easy way to build a map that mirrors the deconstructor {:keys [a b c d]} ?

23:03 of course, I could write a defmacro to do the same...

23:03 gfredericks: Fare: some util libs have a macro for it

23:03 Fare: ok

23:03 TimMc: Fare: Yeah, flatland/useful has something for that, right?

23:04 https://github.com/flatland/useful/blob/develop/src/flatland/useful/map.clj#L9

23:04 keyed

23:12 rritoch: TimMc: If your interested, this is the "project" https://www.physicsforums.com/threads/epic-fail-trying-to-solve-p-x.614121/

23:18 TimMc: The real problem with my attempt is there is no solution to the cosine integral, so I hit a dead-end.

23:19 gfredericks: rritoch: is that reply there what you mean about the earlier statement of the prime number theorem being wrong?

23:20 rritoch: gfredericks: Yes.

23:21 gfredericks: it doesn't seem like a contradiction to me

23:21 crossing over doesn't mean not approaching

23:23 rritoch: gfredericks: According to the response it doesn't approach Pi(x), it wraps around it, similar to the behavior of my function for low values of Pi(x). What I needed for my function is a case where the limit of the function approaches Pi(x) as x approaches infinity.

23:24 gfredericks: rritoch: well the limit of the quotients approaching 1 doesn't mean that they actually approach each other, and the crossing over doesn't contradict either of those

23:24 rritoch: gfredericks: It wasn't a complete loss though because if the cosine integral is solved, the accuracy of my formula could be further improved.

23:26 gfredericks: I don't know where you learned math but x/x = 1

23:26 tuft_: core.match goes really nicely with instaparse

23:26 rritoch: gfredericks: I can't think of any other case where that's true

23:26 amalloy: rritoch: for most x, anyway

23:27 gfredericks: rritoch: e.g., x/(x+1) approaches 1 but x does not approach x+1

23:28 so pi(x)/(x/ln(x)) approaches one but x/ln(x) does not approach pi(x)

23:30 rritoch: gfredericks: I accounted for this "issue" by curling to x/ln(x) at something like x^10, so if the prime number theory held the deviation would have been less than .01

23:31 gfredericks: Either way, the number was very large so it could have been floating point errors that caused some of my problems.

23:31 * gfredericks never minds

23:34 rritoch: gfredericks: Since clojure promotes to Big types I'm somewhat curios how reducing the floating point errors would improve the results for large primes, but I've already invested enough time in that project. I'm just waiting for someone to solve the cosine integral.

23:47 gfredericks: help I'm using a sorted-set with a partial ordering

23:48 andyf: sounds like an invitation to disaster.

23:48 help you create a total order instead, or some other way?

23:49 gfredericks: I was hoping somebody would tell me to back slowly away from the keyboadr

23:49 keyboard

23:50 andyf: I'm trying to store unions ranges of numbers (characters) efficiently

23:50 andyf: I?d recommend sending the RSVP with the answer ?no? back to disaster.

23:50 hiredman: sure, you could use a total order, but wouldn't you rather experience the rush of living like there is no tomorrow?

23:51 gfredericks: andyf: so if I do it right there shouldn't ever be two incomparable elements in a set together

23:52 andyf: elements of the set are contiguous ranges like [10,15], or elements of the set are sets of contiguous ranges?

23:52 gfredericks: the former

23:52 rritoch: gfredericks: Sets have a map impl, it "should" be possible to create a map with the behaviors you want, and then use that as the impl for the set. I dug into the source code of sets because I was looking into how to establish equality criteria in sets.

23:53 andyf: What operations do you want to do on such sets efficiently?

23:54 gfredericks: union, difference, count, nth

23:54 and right not I'd settle for "eh sorta efficiently"

23:54 in the sense of ignoring the worst-case assymptotics

23:54 s/not/now/

23:55 andyf: Maybe just implement union and difference so that the contiguous ranges are always non-overlapping?

23:55 gfredericks: right that's what I'm doing

23:55 andyf: So the elements can always be compared by the beginnings of their ranges, or the ends, and you have a total order?

23:56 gfredericks: yeah within the set it's a total order

23:56 just not over the whole space of possible elements

23:57 andyf: you want to compare two sets-of-contiguous-ranges and put them as elements into a sorted set?

23:58 gfredericks: I'm only using sorted sets for this

23:58 specifically (sorted-set-by (fn [[x1 x2] [x3 x4]] (if (< x2 x3) -1 (if (< x4 x1) 1 0))))

23:58 so I don't know what you mean by "put into"

23:59 andyf: if the contiguous ranges are always kept non-overlapping, then I don't see the problem yet.

23:59 e.g. if you implement union so that #{[1 5] [8 10]} with #{[4 9]} so that the result is #{[1 10]}

Logging service provided by n01se.net