#clojure log - Dec 18 2013

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

1:07 {[^-^]}: is there any point in learning ruby if you know clojure

1:07 I think ruby has the advantage of availability of entry level jobs and scripting

1:08 noidi_: ruby works much better than clojure as a shell-script replacement

1:10 Raynes: {[^-^]}: There is never not a reason to learn x.

1:10 :p

1:10 Learn ALL the things.

1:10 Lajjla: Worship only one Shadow though.

1:10 Only His Shadow.\

1:10 {[^-^]}: Raynes: I don't understand why you said that

1:10 Raynes: Precisely.

1:10 noidi_: those sorts of scripts are always small and very imperative, so clojure's features for managing complexity don't bring much to the table, and the startup time is way too long

1:10 Lajjla: Worshiping any other shadow than His would be blasphemy.

1:10 {[^-^]}: It's like someone asking 'Why?' and the other person saying 'Why not?'

1:10 Raynes: {[^-^]}: I'm trying to tell you that yes, it's a good idea to learn other languages.

1:11 Ruby is a good one in particular if you like coding for a living.

1:11 {[^-^]}: I already hava java, C++, and haskell under my belt

1:11 Raynes: I've so far never done Clojure work that didn't have some rails somewhere. :p

1:11 {[^-^]}: really?

1:11 andyf: Learning ALL the things is a bit impractical, though, without a drastically increased learning capacity, longer life span, or both.

1:12 akurilin: Does anybody ever get really confused by other languages that can't seem to decide whether they want to follow the mutable or immutable paradigm? Looking specifically at JS here.

1:13 {[^-^]}: sounds like scala

1:13 akurilin: Makes you appreciate Clojure's consistency.

1:13 {[^-^]}: Raynes: I'm a language slut

1:13 Raynes: Me too :3

1:13 {[^-^]}: I don't know when to stop learning new languages

1:15 seangrove: akurilin: What parts of js seem to want to follow the immutable paradigm?

1:17 Raynes: akurilin: I haven't found the part of js that wants to follow the immutable paradigm.

1:17 amalloy: i was going to say "well you can't mutate numbers", but of course you can by fiddling with Number.prototype

1:17 noprompt: undefined

1:20 seangrove: amalloy: *but* you have to surround the numbers with (), because syntactically you can't extend numbers

1:20 (5).times(function(index) {...});

1:20 Beautiful...

1:20 noprompt: i've picked up half a dozen languages in the 4 short years i've programmed; just half a dozen ways to say the same thing in a different way.

1:21 sometimes you can say exactly what you want. sometimes you can't.

1:22 for instance, javascript is a good language for telling jokes.

1:22 eggnoggin: Raynes: js, like java, needs to be taught to be immutable :)

1:23 noprompt: eggnoggin: no. programmers just need to avoid writing it directly.

1:23 eggnoggin: noprompt: like java?

1:23 noprompt: eggnoggin: or whatever.

1:23 seangrove: noprompt: Either nonsense, or understated truism.

1:24 noprompt: seangrove: i'm just being honest.

1:26 but i'll probably pick up another one this year.

1:26 eggnoggin: try rust

1:26 noprompt: and it probably won't be haskell.

1:26 or rust.

1:26 sorry.

1:27 seangrove: noprompt: I don't doubt it, I just doubt the ultimate veracity

1:27 eggnoggin: what you should do is learn the language least like the languages you already know

1:27 maybe idris or prolog or who knows

1:27 noprompt: seangrove: don't doubt what?

1:27 Raynes: noprompt: I've been doing Go.

1:27 TEttinger: noprompt, J?

1:27 noprompt: eggnoggin, Raynes learning towards factor or prolog

1:27 something esoteric.

1:28 Raynes: Factor is definitely that.

1:28 TEttinger: I've heard good things about factor

1:28 Raynes: It's also a great language.

1:28 noprompt: TEttinger: it maximizes the fun.

1:28 eggnoggin: instead of learning prolog you should read the reasoned schemer and play with core.logic :)

1:29 noprompt: eggnoggin: i should. but i won't.

1:29 eggnoggin: or, as well as

1:29 noprompt: lol

1:29 eggnoggin: no reason for it to be instead

1:29 noprompt: eggnoggin: actually, i'm just giving you a hard time. i'll probably look at those too.

1:30 my goal this year is to do a bunch of weird stuff with text. none of it immediately useful for serious work.

1:30 TEttinger: noprompt, like procedural poetry or something?

1:31 noprompt: TEttinger: i want to turn works of literature in to intelligent madlibs.

1:31 alandipert: Raynes: how do you feel about go?

1:32 noprompt: TEttinger: but generating poetry sounds fun too.

1:32 TEttinger: noprompt, heh. I know the guy who made http://www.happyponyland.net/lyrics.php , which is entertaining

1:32 Raynes: alandipert: Its type system makes me sad as an occasional Haskell programmer, but in general it isn't the worst thing ever. I enjoyed writing things in it. Will do it again for sure.

1:32 eggnoggin: Raynes: have you looked at rust?

1:32 nice type system :)

1:32 noprompt: alandipert: i thought i knew bash. you made me realize i don't. <3 thank you. :)

1:32 Raynes: eggnoggin: Aye, I like it better.

1:33 eggnoggin: But the Go thing was specifically because I might be using it for a job at some point.

1:33 alandipert: noprompt: i'm flattered but i forgot it all last week i think

1:33 eggnoggin: where I work using go would be off the wall, rust is just as off the wall to that crowd :p

1:34 the footprint of langs like rust and go (and for that matter c et al) is so nice compared to jars and the jvm

1:34 noprompt: alandipert: you are to modest, sir.

1:34 alandipert: Raynes: re: go/clj/conch have you considered modeling programs as channels?

1:34 noprompt: it's inspiring.

1:35 Raynes: alandipert: You should talk to amalloy.

1:35 ;)

1:35 alandipert: Raynes: oh he computes on this?

1:35 amalloy: what

1:35 Raynes: amalloy: Modeling programs as channels.

1:35 alandipert: amalloy: re: shelling out and getting back a channel

1:36 noprompt: that sounds like a good idea.

1:36 alandipert: it works out well for unix, anyway

1:36 Raynes: Oh, well that's specifics.

1:36 amalloy: seems reasonable enough; does java actually expose the machinery to listen to a subprocess in an async way though?

1:36 Raynes: You said a whole bunch of things.

1:36 :p

1:37 Conch could possibly make use of channels.

1:37 alandipert: amalloy: not that i know of, but i think this could be emulated by backing with/managing fifos

1:37 Raynes: I should look into it.

1:38 alandipert: Conch is backed by a queue already for <insert long painful story here>

1:39 amalloy: alandipert: you're thinking of creating fifos for subprocess stdin/stdout, and then selecting on filechannels of those fifos? seems like it ought to work, although of course it's not very portable if you make the fifos in an os-dependent manner

1:41 noprompt: alandipert: is there something other than unix? :P

1:41 alandipert: amalloy: right - i imagine the shell-out primitive returns a process parked on a system-managed fifo, and some plumbing for put/take from/to *in* and *out*

1:44 amalloy: i went down this path researching interop for gherkin (gonna do it there w/ bash 4 "coproc"), sadly have no clojure to show. but i've sold myself on the concept, and modulo jvm suck it maybe could work

1:45 TEttinger: gherkin?

1:45 like the cucumber?

1:45 alandipert: TEttinger: https://github.com/alandipert/gherkin

1:46 TEttinger: neat alandipert!

1:47 alandipert: TEttinger: thx!

1:47 noprompt: TEttinger: it's "amazeballs" as one might describe.

1:47 proper abuse.

1:47 TEttinger: totes mcgotes.

1:50 akurilin: seangrove, Raynes : sorry, switched away for a sec. Take a string.replace()

1:50 it's not in-place mutation.

1:51 Anything string-related at least appears to be immutable in JS.

1:53 eggnoggin: akurilin: are you using _ ?

1:54 akurilin: yeah

1:54 _ is annoying too.

1:54 seangrove: akurilin: Heh, string were where I went immediately as well. But I still think it's a pretty low bar, heh

1:54 akurilin: For example, _.extend(a,b) mutates a in addition to returning the result.

1:54 Bit me in the ass today, I was clueless about what was happening.

1:55 eggnoggin: ya, kind of the semantics of extend tho

1:55 what I do is _.extend({}, a, b);

1:55 akurilin: Well, my point of reference is Clojure's merge

1:55 eggnoggin: unfortunately that does a shallow copy as well and winds up giving you shared refs

1:55 :3

1:55 akurilin: I use lodash, it has deep copy.

1:57 pinkiesOut: Question: I have a file test.txt that I'd like to open with io/reader, filter out lines starting with "%", and stick the results into something called "rdr". I'd like "rdr" to be the same kind of lazy sequence as returned by clojure.java.io/reader (minus the filtered lines of course). What I have appears to filter the lines out, but after printing the result it throws an error:

1:57 eggnoggin: ya js is not a fantastic lang, ref types are a bitch

1:57 pinkiesOut: (with-open [rdr ((fn [line] (filter #(not (.startsWith % "%")) line))

1:57 (line-seq (clojure.java.io/reader "test.txt")))]

1:57 (doall (map #(println %) rdr)))

1:58 New to clojure and pulling my hair out trying to accomplish what is probably a simple task. If anyone can shed light on this I'd be ever thankful

1:59 eggnoggin: with-open is going to call .close() on your rdr after the inner expression finishes, your reader is returning a lazy sequence (from filter), that doesn't implement .close

2:00 oh wait parens derp

2:01 pinkiesOut: the doall print statement does in fact print the filtered file, but returns:

2:01 IllegalArgumentException No matching field found: close for class clojure.lang.LazySeq clojure.lang.Reflector.getInstanceField (Reflector.java:271)

2:01 eggnoggin: ya

2:01 LazySeq doesn't implement close, things like java.io.File does

2:01 andyf: pinkiesOut: with-open always calls a Java method .close on the thing after the [

2:02 pinkiesOut: Typically that thing will be the return value of (io/reader), not a sequence.

2:03 eggnoggin: so do the filtering and casting to line-seq inside the body of the with-open

2:03 andyf: Consider starting with the line (with-open [rdr (io/reader "test.txt")] and then put the rest of the functionality in the body

2:07 pinkiesOut: andyf: this would be a great solution, however I have a function (that I can't edit) that expects as input the result of (io/reader "test.txt"): (un-edit-able-function (io/reader "test.txt")). This is why I'd like to be able to filter that file, and have the result of the filtering be an equivalent return value to simply calling (io/reader)

2:07 If that makes sense...

2:09 alandipert: pinkiesOut: so un-edit-able-function is expecting a java.io.Reader?

2:09 pinkiesOut: alandipert: that's correct

2:09 TEttinger: can't you re-coerce it to reader?

2:09 andyf: pinkiesOut: So use the first line I suggested above, and then as part of the body, call (un-edit-able function rdr)

2:11 pinkiesOut: I can understand wanting to call your function with the argument rdr, but if that function returns a Clojure sequence of things (e.g. strings), then there is no reason I can think of to have that function call in the [] after with-open.

2:12 pinkiesOut: TEttinger: re-coercing was my first instinct, but I'm new to clojure and clueless on how to do so

2:12 TEttinger: I'm exploring the options in a repl now

2:12 pinkiesOut: andyf: I'm trying some of your ideas now...

2:13 andyf: pinkiesOut: Or maybe I am missing your point. You want to create an argument to your function that is the contents of file "test.txt", except without the lines that begin with "%"?

2:13 pinkiesOut: andyf: that's correct

2:16 andyf: OK, now I am lost for an answer. Does anyone know a way to take a sequence of strings, and from them create a Java Reader that when read returns the concatenation of those strings? Actually, I guess I do know a way, but I think it requires concatenating all the strings together into one long string in memory.

2:16 Something like (StringReader. (apply str (expression that returns a sequence of strings)))

2:17 alandipert: one could reify a java.io.Reader backed by the seq

2:17 andyf: If the file is bigger than you want to hold in memory at one time, the (apply str ...) part will blow out your process's memory.

2:19 but if you know it will be small enough that isn't a problem, that is fairly straightforward.

2:19 TEttinger: oh god this is awful

2:19 but

2:19 (with-open [rdr (clojure.java.io/reader "LICENSE")] (clojure.java.io/reader (.getBytes (apply str (filter #(.startsWith % " ") (line-seq rdr))))))

2:19 that filters out all the lines starting with non-space chars and creates a reader from it

2:20 pinkiesOut: The input file will be arbitrarily large, so I can't rely on it being small unfortunately

2:20 TEttinger: like terabytes or what?

2:21 I bet there's some java class for this

2:22 andyf: TEttinger: The .getBytes is unnecessary in there, I think.

2:22 pinkiesOut: Unlikely that large, but the file will be data for processing in incanter so the sky is the limit

2:22 in theory

2:22 TEttinger: andyf, reader will coerce strings to filenames or URIs

2:22 andyf: pinkiesOut: Sounds like alandipert's answer would be necessary, then.

2:22 Raynes: The sky is a long way for a harddrive to go.

2:25 TEttinger: I think part of the issue is that it needs to be in memory at some point to modify the file, right?

2:25 or rather modify the memory's copy of the file?

2:26 pinkiesOut: Yes, that seems to be the case

2:26 andyf: Java has a pair of classes PipedWriter and PipedReader that might be useful.

2:27 pinkiesOut: I thought I had a simple feature to add to incanter to make my life easier... using emacs to strip commented lines is looking more and more enticing

2:27 andyf: You write some code that reads and filters lines from your file, writing them to a PipedWriter.

2:27 Create a PipedReader from that PipedWriter, and that is what you feed as input to the function that needs a Reader.

2:28 TEttinger: http://docs.oracle.com/javase/6/docs/api/java/io/PipedReader.html I have no idea what this does...

2:28 pinkiesOut: andyf: this sounds very promising...

2:28 andyf: How many times do you need to repeat this?

2:28 pinkiesOut: Once

2:28 Raynes: TEttinger: Create a PipedReader from that PipedWriter, and that is what you feed as input to the function that needs a Reader.

2:28 - andyf

2:28 andyf: And you have the file on disk now that needs to have comments stripped out?

2:28 Raynes: December, 2013

2:28 TEttinger: yeah, sorry I meant from the javadocs

2:29 Raynes: :p

2:29 TEttinger: they are pretty vague on that page, seriously

2:29 pinkiesOut: andyf: yeah, I have the file and can easily strip the comments out. But in an automated setting, I'd prefer not to have to do this manually

2:30 andyf: What do you mean in an automated setting? I thought you said you needed to do it once?

2:31 pinkiesOut: I misunderstood you--- the filtering happens once only in my script. But the script will be applied to many files down the road

2:32 andyf: If you are willing to spend the compute cycles reading the file, filtering, and writing another file back to disk or wherever, then sending that file to your unchangeable function, that is slightly easier code to write.

2:32 and by slightly, I mean noticeably easier :-)

2:33 but if it can really be terabytes, you might not want to do that.

2:34 pinkiesOut: Precisely the problem. It seems like a pretty useful feature to be able to lazily read a file, skipping lines that match a pattern.

2:34 andyf: I haven't personally used the PipedWriter/Reader thing before, but it wouldn't take long to hack up some code to test if it works as advertised.

2:35 pinkiesOut: or in general read one file, writing out an arbitrarily transformed one, but not to disk, but to the equivalent of a Unix pipe

2:36 pinkiesOut: andyf: yes, well put

2:36 andyf: That is what the PipedWriter should give you

2:37 let me hack a couple mins on this.

2:37 pinkiesOut: I have the docs up, but I know nothing of Java and little of clojure. I'll test things out later, but I couldn't produce anything quickly for our immediate gratification

2:39 You're welcome (and encouraged) to hack away :)

2:39 andyf: I might not get what you want, but there is some chance it might work

2:41 pinkiesOut: Newbie question: would this require loading a new dependency, or are PipedReader/Writer available for calling from java as is from clojure?

2:41 Raynes: andyf: You have to do it on a whiteboard.

2:41 andyf: Should be part of standard JDK library as is

2:42 Raynes: Like in an interview.

2:42 andyf: :-)

2:42 You hiring?

2:44 pinkiesOut: TEttinger: your solution and effort didn't go unnoticed-- thanks for tinkering :)

2:44 TEttinger: haha thanks

2:44 and thanks andyf for doing the work!

2:44 pinkiesOut: yes indeed!

2:45 andyf: Thank me if it works :)

2:45 Raynes: andyf: Hah, I wish.

2:47 seriously_random: What's the difference between these two uses of 'rest': http://pastebin.com/9F3JeJAZ

2:48 Raynes: seriously_random: (rest '([:a 3] [:b 2]))

2:48 You're trying to call a vector as a function.

2:48 Which works, but you have to give it a number and it looks up by index.

2:51 &([1 2] 0)

2:51 lazybot: ⇒ 1

3:07 andyf: No fabulous success yet. Only head-scratching experiment so far.

3:10 pinkiesOut: thanks for trying-- don't feel obligated to try any more. At least I have a direction in which to look

3:22 clgv: pinkiesOut: possibly one of the clojure books gets you a headstart on clojure ;)

3:23 seriously_random: how to "extract" 3 out of (3)? http://pastebin.com/64UY4N4R

3:23 pinkiesOut: clgv: Two in the mail already :)

3:25 clgv: pinkiesOut: meanwhile http://clojure-doc.org/articles/content.html might help you out on the basics ;)

3:25 seriously_random: ##(first '(3))

3:25 lazybot: ⇒ 3

3:27 clgv: seriously_random: what exactly are you trying to do? seems overly complicated atm

3:29 seriously_random: clgv, repeat :a in [:a 3] 3 times

3:29 TEttinger: making [:a :a :a 3] ?

3:30 clgv: seriously_random: so a map of keywords and repetition counts is the input and what is the output? a concatenation of the repeats?

3:30 seriously_random: TEttinger, (:a :a :a)

3:31 TEttinger: ,(let [inp [:a 3]] (repeat (second inp) (first inp)))

3:31 clojurebot: (:a :a :a)

3:31 clgv: seriously_random: ##(let [m {:a 3 :b 2}] (for [[k n] m, _ (range n)] k))

3:31 lazybot: ⇒ (:a :a :a :b :b)

3:32 TEttinger: clgv, I have no idea what's going on in that for

3:32 seriously_random: sorry, I want to do it my way. How do I get 3 out of (rest (first short)) ;=> (3)

3:34 TEttinger: ok, rest returns a seq, I think if you know (first short) always returns a pair, you can use second

3:34 which it should, if you're getting it from a map

3:34 seriously_random: you can't get stuff out of persistent lists in clojure?

3:35 TEttinger: sure

3:35 why couldn't you?

3:35 seriously_random: how?

3:35 clojurebot: with style and grace

3:35 TEttinger: you would use nth, first, second...

3:35 nth is the general case

3:36 ,(nth '(1 2 3) 0)

3:36 clojurebot: 1

3:36 glosoli: Anyone using rainbow_parentheses.vim with Clojure here experienced problems when auto loading it has no effects, neither does manual activation ?

3:37 TEttinger: but my point I think, seriously_random, is that you don't need to construct a list and then immediately de-construct it, do you?

3:37 (also it's a seq, not a list, but they print the same, which is confusing)

3:38 seriously_random: TEttinger, PersistentVector$ChunkedSeq is a sequence? Vector is [], list is ()?

3:38 TEttinger: that's what rest returns, apparently

3:39 ,(class (rest [1 2 3]))

3:39 clojurebot: clojure.lang.PersistentVector$ChunkedSeq

3:39 clgv: seriously_random: either use `nth` or destructuring or `first`, `second`

3:39 TEttinger: rest does not return individual elements, and repeat expects a single number for the number of times to repeat

3:43 (inc clgv)

3:43 lazybot: ⇒ 10

3:44 clgv: :D

3:45 seriously_random: also ##(let [m {:a 3 :b 2}] (for [[k n] m] (repeat n k)))

3:45 lazybot: ⇒ ((:a :a :a) (:b :b))

3:47 clgv: stacking lots of first/second/rest/nth usually makes your code hard to understand

3:51 TEttinger: ,(doc ffirst)

3:51 clojurebot: "([x]); Same as (first (first x))"

3:51 TEttinger: don't use too much of that either though

3:53 daGrevis: Where are the frameworks?

3:54 (from https://news.ycombinator.com/item?id=6925775 )

4:19 clgv: daGrevis: yeah frameworks are only useful if they implement a decent amount of functionality for you and you only fill in the missing/special bits. one example where I think they are useful is algorithm engineering where you have a "meta algorithm" for the metaheuristic under research. then this "meta algorithm" could be called framework...

4:29 seriously_random: to get "((1 2) (3 4))" you could write "(cons '(1 2) (cons '(3 4) '()))", is there a shorter way?

4:31 TEttinger: ,(list '(1 2) '(3 4))

4:31 clojurebot: ((1 2) (3 4))

4:31 TEttinger: seriously_random: ^

4:31 clgv: ,'((1 2) (3 4))

4:31 clojurebot: ((1 2) (3 4))

4:32 TEttinger: well that too

4:32 clgv: even shorter since you usually want vectors instead of lists for sequential constants: ##[[1 2] [3 4]]

4:33 ,[[1 2] [3 4]]

4:33 clojurebot: [[1 2] [3 4]]

4:35 andyf: I failed the interview question, but I think I have a decent answer, anyway.

4:36 clgv: seriously_random: imho if you are not constructing lazy sequences you seldom use `cons` in Clojure

4:36 andyf: what was the question?

4:36 TEttinger: I can't say I recall ever using cons in clojure

4:36 andyf: pinkiesOut: ping

4:37 clgv: TEttinger: me too, only in conjunction with lazy-seq :=

4:37 ;)

4:37 andyf: A while back someone was asking how to read from a file, filter the lines via some arbitrary Clojure fn, and then return a Java Reader that was the result of those fn calls.

4:38 alandipert (I think) suggested making a proxy Reader that implemented the read calls using a string sequence as a source of characters.

4:38 I finally got it working.

4:38 TEttinger: NICE!

4:38 that took some effort!

4:39 (inc andyf)

4:39 andyf: It is not the prettiest thing to read, but using it is pretty easy.

4:39 clgv: andyf: but mostly useful for interop right?

4:40 TEttinger: it was a very specific use case I think

4:40 oh, that's why inc doesn't work

4:41 Raynes, are you the guy running lazybot?

4:41 clgv: he is^^

4:42 the bot went to sleep again ;)

4:42 andyf: The problem as stated was: there is some function he could not change that required a Java Reader as an argument. He has some huge file on disk somewhere, but wanted to strip out comments using a Clojure function to decide what lines were comments (generalization: transform each line to some other string), and call that function with a Reader that returns the modified version of the file, without creating the intermediate file.

4:42 TEttinger: I don't know if it's been fixed in master, but on a different server my lazybot fork will not reconnect after netsplits

4:43 andyf: Basically what I've got is a function that takes a Reader and a Clojure function, and returns a Reader that when read gives the contents of the modified file. The Clojure function is sort of behaving like a process in a Unix pipe.

4:44 TEttinger: I hope pinkiesOut sees it, that sounds great

4:45 andyf: It's the kind of thing I could imagine using some time myself.

4:45 I guess it is time to create a teeny Github project. Not sure where else to put it.

4:46 TEttinger: gist?

4:46 clojurebot: http://gist.github.com/

4:46 TEttinger: thank you clojurebot

4:50 clgv: andyf: as TEttinger says, if it is too small for a library just make a named gist on github

4:52 andyf: Makes sense. Cleaning it up now.

5:00 I haven't made a gist before, so not sure if I've got the right link: https://gist.github.com/jafingerhut/8019871#file-gistfile1-txt

5:02 TEttinger: I'll (inc andyf) until the cows come home

5:03 clgv: andyf: better give it a clj ending for syntax highlighting ;)

5:04 andyf: Can I rename it, or just create another one with the same contents?

5:05 Renamed.

5:05 clgv: oh it's been a while since my last gist. I think I just told it that the content is Clojure. just reviewed my gists which dont have any endings

5:08 nones: hello

5:09 is there ways to use Seesaw library with third party components?

5:09 andyf: Is it a bot feature to save a message for the next time someone connects to the channel?

5:09 If so, I guess I can't use that now.

5:11 nones: I do not know, but there is a Seesaw Google group that would be a perfect place for such a question if no one here knows the answer. https://groups.google.com/forum/#!forum/seesaw-clj

5:12 TEttinger: nones, yes. which components do you mean? I've used it with insubstantial

5:12 clgv: nones: you can extend seesaws mechanism to new components - but you have to dig into it to do that

5:12 nones: though it is not too complicated, I implemented some of seesaws features for jfreechart

5:15 nones: <TEttinger>, for example , RSyntaxTextArea : https://gist.github.com/alhimik45/8020047

5:15 TEttinger: nice

5:16 I'm getting sleepy, don't take my advice

5:18 clgv: nones: there is support for rsyntaxtextarea in seesaw

5:20 nones: https://github.com/daveray/seesaw/blob/89b25f992a80624c4c59ac56efd796588a019982/src/seesaw/rsyntax.clj

5:20 amalloy: andyf: lazybot supplies $mail <username> <message> for saving messages

5:20 next time recipient is seen, lazybot sends him a private message with instructions on how to read saved mail

5:21 nones: clgv: thanks, I'll try it, but why there no this information in docs?

5:23 clgv: nones: seesaw's documentation is too sparse for my taste as well

5:23 andyf: $mail pinkiesOut See this code here, especially examples of use at the bottom: https://gist.github.com/jafingerhut/8019871

5:24 clgv: nones: for example some documentation on the "architecture" for developers would be awesome. so it's trial and error on the REPL and reading source on github if you extend seesaw to a new component for the first time

5:24 andyf: clgv: Dave Ray would likely be open to help there, if you are interested.

5:25 clgv: andyf: I am sure. but that's unlikely in the next 6 months due to my time constraints... :(

5:34 dabd: Is clojuratica abandonware or still works with the latest clojure versions?

5:36 cark: last update 4 years ago ... you might have to try it

5:36 probably won't work with latest tho

5:37 dabd: They mention it in the Clojure Data Analysis Cookbook which is very recent

6:16 clgv: dabd: well if it is a generic connector, it might still be usable but probably frustrating if you need to hack on it yourself without the needed knowledge of the mathematica bridge

6:31 Arjunax: Hi, is there a more beautiful way, to archive {:foo1 "bar1" :foo2 "bar2"} when cond=true than this?:{:foo1 "bar1" (when cond :foo2) (when cond "bar2")}

6:33 I want it with one when

6:34 but when i go (when cond :foo2 "bar2") it obviously doesn't work

6:40 clgv: ,(let [m {:foo1 "bar1"}, cond (= 1 1)] (cond-> m cond (assoc :foo2 "bar2")))

6:40 clojurebot: {:foo2 "bar2", :foo1 "bar1"}

6:40 clgv: Arjunax: ^^

6:40 ,(let [m {:foo1 "bar1"}, cond (= 1 2)] (cond-> m cond (assoc :foo2 "bar2")))

6:40 clojurebot: {:foo1 "bar1"}

6:41 Arjunax: ok, thanks

6:55 clgv: is definterface supposed to not convert clojure naming for methods to feasible java names?

6:55 "modify!" ends up as "modify!" literally instead of "modify_BANG_"

7:00 je: is <!! missing from cljs core.async?

7:01 cark: je: yes, there are no threads in js

7:02 you still have <!

7:05 je: cark: I know - I'll just need to find another way around the problem, thanks :)

7:05 cark: =)

8:02 gabe_hollombe: Hey folks. I'm super new, just learning about macros. As an exercise, I'm trying to write a macro that will take an expression, split up into the first and the rest, and then apply the rest to the first. See paste here https://www.refheap.com/22017 My problem is, I don't understand why what I've written doesn't work

8:02 anyone have a minute for some guidance here?

8:08 seriously_random: trying to write a recursive function, running into indexoutofboundsexception. Don't understand why: http://pastebin.com/FCFyNw8e

8:08 CookedGryphon: gabe, you're mixing up your quoted and unquoted stuff

8:08 gabe_hollombe: CookedGryphon: I totally believe it. Can you help me grok it with a pointer?

8:08 CookedGryphon: so waht do you want to write? (doto + 1 2 3)?

8:09 doit*

8:09 gabe_hollombe: (doit (+ 1 2 3))

8:10 CookedGryphon: okay, so the trivial version of this macro is actually (defmacro doit [exp] exp)

8:10 which if you macroexpand it will write out the code (+ 1 2 3)

8:10 gabe_hollombe: yes

8:11 I'm with you so far

8:11 CookedGryphon: and the functional version of this would be (defn doit [exp] (apply (first exp) (rest exp)))

8:11 gabe_hollombe: yep

8:12 CookedGryphon: but if you want to split up the code in the macro, i find the backtick operator confuses things, you are doing a data structure manipulation, so work out what the data structure you want is:

8:13 (defmacro doit [exp] (let [f (first exp) args (rest exp)] (list 'apply f args))

8:14 wait, that's not quite right

8:15 because the code it outputs (macroexpand '(doit (+ 1 2 3))) => (apply + (1 2 3)) which isn't valid clojure, because 1 isn't a function

8:15 so you'll need to either quote that or make it a vector

8:15 gabe_hollombe: right... which is more idiomatic?

8:16 CookedGryphon: (defmacro doit [exp] (let [f (first exp) args (rest exp)] (list 'apply f (list quote args))

8:16 (defmacro doit [exp] (let [f (first exp) args (rest exp)] (list 'apply f (list 'quote args))

8:16 the quote one is better for learning, which is the point of this

8:17 gabe_hollombe: ok. just reviewing this final example

8:18 it starts with list, because we want our macro's output to be a list

8:18 CookedGryphon: yep

8:18 gabe_hollombe: then we have to quote apply or else it will actually try to apply right there in the macro code generation

8:18 (instead of putting apply in the output)

8:18 CookedGryphon: exactly

8:18 gabe_hollombe: f comes straight from the binding as-is

8:19 then we need to make a list for the application of f

8:19 and we're quoting the quote function there for the same reason as apply

8:19 i get it

8:19 CookedGryphon: the second list is actually for the quote function

8:19 but yeah

8:20 and yeah, I would recommend playing about with macros in this form before going to the backtick shortcut, it's simpler and gives a better understanding of what's going on underneath

8:21 but for completeness, teh backtick version would be something like (defmacro doit [f & args] `(apply ~f (quote ~args)))

8:21 gabe_hollombe: yeah. I agree. and thank you

8:21 CookedGryphon: but for completeness, teh backtick version would be something like (defmacro doit [[f & args]] `(apply ~f (quote ~args))) sorry

8:42 jballanc: Hmmm...so the "uberjar" profile in lein gets automatically included during an uberjar compilation...but what about "dev"?

8:42 running "lein ring uberjar", it sure seems like my "dev" profile is being included

8:53 seriously_random: reverse of nthrest?

9:06 ngw: hi *

9:06 edw: Hey.

9:06 ngw: I'm having troubles using the create function in the REPL

9:06 https://gist.github.com/ngw/f8ef003532c8d712dd9b

9:07 I think I should require it directly without defining a ns, right?

9:07 user=> (:require [theshire.models.element :as model])

9:07 CompilerException java.lang.ClassNotFoundException: theshire.models.element, compiling:(/private/var/folders/r_/8jpc8nbx6x1g6gq3r1djmr900000gp/T/form-init3432138121469073363.clj:1:1)

9:07 what am I doing wrong?

9:10 Morgawr: is there a more graceful way of extracting a sequence of keywords from a map? I know it's possible to use assoc-in to walk a sequence [:a :b :c] and modify a map, is there something similar just to access the value?

9:10 because doing (:a (:b (:c my-map))) feels tedious

9:10 I guess I could do (reduce [:a :b :c] my-map) ?

9:11 vijaykiran: Morgawr: get-in ?

9:11 octagon: http://clojuredocs.org/clojure_core/1.2.0/clojure.core/get-in

9:12 Morgawr: neat! thanks

9:12 exactly what I needed

9:26 maravillas: ngw: try (require '[theshire.models.element :as model])

9:27 the form you pasted is part of the ns macro

9:27 pandeiro: anybody using archlinux know how to make keychain/gpg-agent work so i don't need to type my passphrase every time i access a private jar repo?

9:28 ngw: maravillas: Exception lib names inside prefix lists must not contain periods clojure.core/load-lib (core.clj:5359)

9:30 maravillas: the ns form in your pasted file is wrong, too :)

9:30 should be (:use [ring.util...

9:30 the opposite problem

9:41 arkh: compojure question: if defroutes specifies a response function with no args, how can the definition of that function be arity 1 (the request) and still work? https://github.com/http-kit/chat-websocket/blob/master/src/main.clj

9:46 daGrevis: what's wrong with this? (= '(:a :b :c :d :e) (conj '(:a :b :c :d) :e))

9:46 Bronsa: ,(conj '(:a) :b)

9:46 clojurebot: (:b :a)

9:47 Bronsa: conj on a list adds the item to the front

9:47 daGrevis: Bronsa, what's the difference from cons then?

9:48 hyPiRion: that conj is polymorphic, whereas cons is not

9:48 arkh: daGrevis: http://stackoverflow.com/questions/3008411/clojure-seq-cons-vs-list-conj

9:48 gabe_hollombe: daGrevis: operates differently depending on the type, I believe

9:48 Bronsa: conj is a polymorphic construct that works on colls, (conj coll el) will attach the el in the most convenient position for the coll

9:49 gabe_hollombe: pooh, right. sorry what Bronsa said

9:49 cark: ,(conj {:a 1} [:b 2])

9:49 clojurebot: {:b 2, :a 1}

9:49 cark: works on sequable i'd say

9:51 CookedGryphon: Can anyone give me some pointers on handling exceptions in core.async code

9:52 I'm not *expecting* errors as such, but I'm working interactively and make mistakes, and don't want to have to re-launch my app every time I make a typo

9:52 daGrevis: did lisp had exceptions?

9:52 lisp as cl or scheme.

9:52 CookedGryphon: but I also don't want to have to add the boilerplate (try .. (catch ...)) inside every go block

9:53 cark: cl has conditions and restarts that's like exceptions 2.0

9:53 for scheme, exceptions are more problematic due to continuations (afaik)

9:55 daGrevis: cark, ty

9:56 clgv: CookedGryphon: then write a "safe-go" macro that automatically adds try-catch to notify you of exceptions

9:57 CookedGryphon: yeah, i guess so, but then I'd need a safe-go-loop

9:58 and yeah... I was sort of hoping there was something built in

9:58 clgv: CookedGryphon: humm then just a safe-sync macro ^^

9:59 CookedGryphon: you can easily add try-catch to `go` and `go-loop` via clojure.tools.macro/macrolet

10:00 CookedGryphon: clgv: that might not be such a bad idea actually, just add it in for debugging

10:04 fredyr: daGrevis: scheme have exceptions as well

10:05 clgv: CookedGryphon: yeah, won't hurt I guess...

10:07 CookedGryphon: clgv: oh, and I only need to do go, because go-loop expands to go... right?

10:07 or will it already have expanded by that point...

10:07 confused

10:07 :P

10:08 clgv: I am not sure whether macrolet does expand the code. I doubt that it.

10:09 but you can use the same implementation for both macro symbols

10:20 CookedGryphon: clgv: any idea what it means when it says can't macrolet qualified symbol go?

10:21 is it just saying I can't redefine a macro that's already been defined?

10:28 clgv: CookedGryphon: please post a gist where the error occurs

10:29 CookedGryphon: clgv: I think I've got it

10:29 I should have been using a symbol-macrolet

10:31 clgv: CookedGryphon: does symbol-macrolet also work with custom expansions? not just replacing different symbols?

10:32 CookedGryphon: Yeah, that didn't work either

10:32 I'm not sure I get these macrolets

10:35 I think I'll just make my own versions

10:36 clgv: there is no stable version of core.async yet?

10:37 tbaldridge: clgv: define stable?

10:38 clgv: tbaldridge: stable, as in the maintainers are confident enough to remove the "alpha"

10:38 stuartsierra: Stable as in 'Can you keep a horse in it?' :P

10:38 clgv: :D

10:39 stuartsierra: I wouldn't keep a horse in core.async right now. Maybe a pony. Or a goat.

10:39 tbaldridge: well we haven't changed the public API in months (like six months)

10:39 clgv: tbaldridge: but got used to the "alpha" ? ;)

10:40 tbaldridge: Although you'd probably want to talk to Bodil when it comes to ponies and Clojure.

10:40 stuartsierra: True, I should defer to the expert on ponies.

10:40 andyf_: clgv: There are features that have been marked alpha in Clojure since 1.2 or 1.3 that are only having their alpha designation removed in 1.6

10:41 tbaldridge: clgv: I see it this way. If I wrote a library and released it as version 5 what would that tell you? What would keep me from rewriting the public API from scratch in v 6?

10:41 clgv: andyf_: I know. It is a good thing those are removed now. didnt you trigger that?

10:41 tbaldridge: clgv: if it works for you use it. As always, we try to keep public API changes to a minimum.

10:41 andyf_: clgv: No, that was all Alex Miller, bless his heart

10:41 clgv: oh sorry.

10:41 stuartsierra: All version numbers are lies. On rare occasions they are useful.

10:41 clgv: tbaldridge: but then why do you keep an alpha in it anyway?

10:42 tbaldridge: clgv: I haven't a clue. I do naming completely different in my personal projects. Versions are utterly meaningless no matter what the software you're using is. Google's Beta is completely different from other companies.

10:43 stuartsierra: I should write an IRC bot that links to my blog rants automatically.

10:43 tbaldridge: Blizzard's "Beta" games are about the same as version 1.6 from other companies.

10:43 clgv: stuartsierra: which one this time?

10:44 stuartsierra: http://stuartsierra.com/2013/01/28/brief-rant-about-versioning

10:44 andyf_: You guys are giving anecdotal evidence that version numbers *are* meaningful, just that their meaning depends upon the source.

10:45 stuartsierra: bah, I don't want to talk about this. Going to go find some work to do.

10:45 tbaldridge: andyf_: agreed.

10:46 So my view is "rich's alpha is most people's 1.0". But perhaps that is just me.

10:47 And yeah, read stuart's rant. That's pretty much my views on it as well.

10:47 technomancy: "Don't bother doing this thing, because other people do it badly and it's hard"

10:47 mkay

10:48 smiler: Never do hard stuff.

10:48 It's hard.

10:49 tbaldridge: technomancy: no, I just tell people "upgrading may break things. Do your research before upgrading" what's bad about that? I think people are just lazy (including myself) and want to be able to go from v 1.01 to v 1.02 without thinking about what they are doing.

10:50 upgrading any library should require full testing anyways, so what does it matter what version numbers are?

10:51 clgv: tbaldridge: maybe you can help CookedGryphon - wrapping try-catch blocks (for exception notification) around the body of `go` and `go-loop` occurences within a given scope via a macro using `macrolet` - reasonable idea for development or not?

10:51 tbaldridge: refheap please?

10:52 clgv: tbaldridge: non.existet yet. it was just the idea to give him information when something is thrown in his go blocks

10:52 CookedGryphon: the basic problem is that I have a lot of little go blocks working in concert

10:52 clgv: tbaldridge: originally he was looking for something builtin in core.async

10:52 CookedGryphon: and it obfuscates my logic to surround each one of them in error handling boilerplate

10:52 tbaldridge: yeah, putting a try/catch in a go is often a good idea. I normally just println the exception. But there's nothing wrong with wrapping all this up with a macro

10:53 I'd just use defmacro though, not sure why you'd need macrolet.

10:53 CookedGryphon: that's what I've gone with

10:53 it wouldn't be so annoying if I was working on the jvm

10:53 tbaldridge: this is cljs?

10:53 CookedGryphon: but on android uncaught exceptions in threads kill the whole app

10:53 clgv: tbaldridge: yeah writing a macro with defmacro - macrolet was a suggestion to easily replace `go` and `go-loop` bodies

10:54 tbaldridge: yeah, that sounds like too much black magic. I normally just start my CLJS code with [clojure.core.async.macros :refer [go]]. Doing it that way should be easy to pull in go from a custom ns.

10:54 clgv: tbaldridge: usage as (report-errors code, several function using multiple go blocks) ;)

10:56 CookedGryphon: It would be nice if there was an approved way to catch errors with a slightly wider net

10:56 makes interactive development harder as it stands

10:56 tbaldridge: in CLJS there's the JS console. Errors pop up there don't they?

10:57 CookedGryphon: yeah, and on the jvm they dump to stderr

10:57 but on android they cause an AndroidRuntime exception which kills the entire app and you have to restart it, which takes a while, and then if you've been working in the repl, all your changes are lost

10:58 tbaldridge: ah.

10:59 CookedGryphon: it would be sufficient if I could get at the uncaughtexceptionhandler for the async dispatch thread pool or whatever it uses to do the work

10:59 then i can wrap that with a log rather than letting the exception bubble up

11:01 tbaldridge: CookedGryphon: yeah for that, I'd recommend patching core.async. I'm in the process of figuring out what to do in the case where exceptions bubble all the way up.

11:02 if you git checkout core.async and look in the impl.dispatch namespace the code is in there.

11:03 CookedGryphon: tbaldridge: great, thanks!

11:03 tbaldridge: But yeah, the general idea we've had is that if you want any error handling you should create a go-try macro (or something like that) and handle errors the way you see fit.

11:03 But I see value in turning that into some sort of dynamic var that you can bind to any fn you want.

11:16 edoloughlin: Is is possible to know in a finally clause if an exception was caught?

11:16 joegallo: why do you think you want that?

11:16 that is, what's the actual problem you're trying to solve?

11:17 `cbp: you know if an exception was caught inside the catch

11:17 edoloughlin: I'm looking at some old code that uses slingshot and I want a quick way of adding some log output without putting it in each catch clause

11:18 ...I'm logging the same variables each time

11:21 In general, if anyone has a good way of handling logging without making functional code look ugly, I'd love to know. I've tried writing macros to help but haven't succeeded in coming up with anything that doesn't look as ugly as just putting (doto (something) (log stuff)) everywhere

12:11 goraci: hi why (use 'desk.models.user) will not eval (ns ....) form ? for example i (:require [config :as config]) in ns - with use i don't have access to config, why ?

12:16 anyone alive here )?

12:18 jhn: Hi, I get classpath errors when requiring clojure.contrib.server-socket. The project was generated with 'lein new app NAME'. Here's the gist: https://gist.github.com/jhn/a49ed88154c104130824

12:18 clgv: goraci: because in the REPL you are in a different namespace named "user" that does not have the require statement you specified in the other namespace

12:19 goraci: you'd need to switch to desk.models.user to use the "config" alias

12:19 goraci: clgv: how ?

12:20 clgv: goraci: in pure "lein repl" use "(in-ns 'desk.models.user)"

12:20 goraci: clvg: so use and then in-ns ?

12:20 clgv: goraci: but if you want to remain in 'user then you could also (require '[config :as config])

12:21 goraci: clgv: kind weird thing

12:21 clgv: goraci: not really, once you understood namespaces

12:21 goraci: clgv: well namespaces should be simple )

12:21 clgv: goraci: grab a book or clojure-doc.org toe read up on namespaces

12:21 goraci: they are

12:22 goraci: clgv: cause it's first place user try something

12:22 technomancy: jhn: clojure.contrib.* namespaces are deprecated

12:22 goraci: clvg: not really if i use (in-ns ..) only then it will not load even clojure.core

12:22 clgv: goraci: you just have wrong assumptions about them (may be from different languages). just read up how namespaces work ;)

12:23 goraci: no idea what your last message ment

12:23 goraci: clvg: i see how they work ) in that example

12:24 clvg: i mean just (in-ns..) loads nothing

12:24 clvg: just namespace switch

12:25 clgv: goraci: yes thats true. I assumed the exectuion of your use form already loaded the config namespace

12:25 goraci: gotta go...

12:30 jhn: technomancy: this http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go is outdated then, I suppose? where can I find more info on this?

12:33 emaphis: jhn: this might help: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go

12:33 jhn: emaphis: that's what I just linked...

12:34 emaphis: oh sorry, :-)

12:35 jhn: well, it was last updated Dec 11th

12:36 hiredman: jhn: the library you are trying to use is shown there to not have a replacement, and you don't have any additional libraries in your project.clj anyway

12:36 jhn: so what I'm trying to use—clojure.contrib.server-soket—has no migration deatils

12:37 hiredman: does that mean... it's simply not available anymore?

12:38 hiredman: correct

12:38 technomancy has some kind of version of it somewhere though

12:38 jhn: hiredman: ah. I guess that explains a lot. thanks.

12:38 I'll look into it.

12:38 technomancy: there is an unofficial fork, yeah. need to put it in your project.clj

12:39 hiredman: jhn: but you also need to add external dependencies to your project.clj

12:40 the contrib stuff old or new doesn't come with clojure, so you have to tell leinigen to include it if you want it

12:40 jhn: I'm guessing you're referring this one: https://github.com/technomancy/server-socket

12:41 hiredman: https://clojars.org/server-socket

12:42 jhn: hiredman: Thanks!

12:49 mvid: is there a more appropriate channel for liberator questions?

13:10 jjl`_: is there a clojure equivalent of let*? (macro that nests lets so that bindings can see all previous bindings in the statement) ?

13:10 Bronsa: jjl`_: clojure's let already does that

13:10 jjl`_: oh. that's rather handy

13:10 Bronsa: ,(let [a 1 b a] b)

13:10 clojurebot: 1

13:11 jjl`_: :)

13:11 one thing i've found since i picked up clojure is that i keep discovering things that make me smile

13:12 pmonks: I keep discovering how dumb I am. #fwiw

13:13 I guess COBOL didn't really set me up to learn Clojure. :-(

13:13 jjl`_: on the other hand, i should imagine clojure is infinitely more pleasurable to program

13:13 pmonks: +INF !

13:14 emaphis: COBOL to Clojure is quite a jump. :-)

13:14 hyPiRion: I feel COBOL to anything is quite a jump these days :p

13:15 jjl`_: i saw that someone added object orientation to COBOL, but the syntax was absolutely hilariously verbose

13:15 pmonks: Though COBOL has its charms - I do love a good PIC S999 COMP-4.

13:15 emaphis: yeah, COBOL is pretty unique.

13:16 jjl`_: http://supportline.microfocus.com/Documentation/books/VisualCOBOL/Intro_to_OO_Programming_for_COBOL_Developers.pdf

13:17 pmonks: It ain't COBOL if it doesn't run on System/Z...

13:17 jjl`_: but you can buy a plugin for visual studio!

13:18 emaphis: let's add functional programming to COBOL.

13:18 pmonks: It also ain't COBOL if "Visual" != CICS.

13:18 * pmonks should probably state for the public record that his actual commercial COBOL experience was < 6 months.

13:18 ystael_: emaphis: what's the recursion operator called? FIXED POINT OF ?

13:19 S11001001: ystael: LEAST FIXED POINT OF

13:19 pmonks: I reckon the "COBOL way" might involve writing functions in COBOL (as programs), then "orchestrate" them using JCL.

13:19 mmm……..JCL………<drool>

13:20 hcumberdale: Hi :)

13:20 jjl`_: i amused myself by adding this fake COBOL to one of my talks recently as a comparison to other languages http://pastebin.com/DF4tDefq

13:20 ystael: pmonks: because JCL is just like mapreduce right?

13:20 pmonks: ummm…..

13:20 hcumberdale: Is there a way to get the cnt of the current iteration in a reducer function?

13:21 emaphis: There is a way to write recursive procedure in COBOL but darned if I remember how.

13:22 jjl`_: hcumberdale: if you mean with (reduce ..), you have an accumulator

13:22 hcumberdale: but maybe if you're looking at doing more complex things, you want to unroll it

13:23 hcumberdale: jjl`_: just conj' ning list and checking what has been collected so far and if it is in the next set containded as a subset

13:23 but i've conj lists, no index or sth.

13:24 agents, atom and so on doesn't work

13:24 during @ they lead to crazy values

13:25 noncom: what is the predicate to know if a value can be dereferenced with (deref) ?

13:25 hcumberdale: Imagine chunks of sets, I want to know what has been processed so far :) like assigning a counter to my println

13:25 noncom: number

13:26 noncom: hcumberdale: what do you mean?

13:26 hcumberdale: sorry, ignore my last message

13:26 jjl`_: hcumberdale: i'd have to see code to help at this point i'm afraid. but the two things that spring to mind are using a more structured accumulator and using destructuring bind, or unrolling it

13:26 TimMc: What is the desired effect?

13:27 noncom: i just need to know, can i pool kvs from a map directly or it is stored in an atom or ref and needs be derefed

13:27 hcumberdale: TimMc: I've chunks of sets and I'm printing out what has been changed from set to set

13:28 That chunks are '( { k v } { k v } ... )

13:29 With the keys & intersection I can already print changes from set to set

13:30 But also want to print the index of the set I'm currently processing

13:30 turbofail: noncom: dunno about anything that comes standard, but you can use (instance? clojure.lang.IDeref ref)

13:31 noncom: turbofail: right

13:31 jjl`_: hcumberdale: sounds like you want to store it in the accumulator

13:31 hcumberdale: ahh that's the way how to deal with it in such a case..!?

13:32 jjl`_: it's *a* way to deal with it. whether it's the best one, i can't answer

13:33 e.g. (fn [[index acc]] ...)

13:34 i don't know what the performance impact of destructuring bind here is likely to be

13:34 justin_smith: ,(reduce (fn [[i acc] el] [(inc i) (conj acc el)]) [0 []] (range 10))

13:34 clojurebot: [10 [0 1 2 3 4 ...]]

13:35 justin_smith: that is the idiomatic way to do it

13:36 I guess you could use List or Record instead of a vector if you wanted to tweak performance?

13:37 but the overhead of a two element vector should be very low

13:38 jjl`_: premature optimisation and all that

13:39 justin_smith: the destructuring bind is not going to be significantly more expensive than indexing the vector directly, if that was the concern

13:40 jjl`_: i didn't expect it would be, but i've little experience in profiling clojure

13:41 justin_smith: jjl`_: criterium is a good way to do microbenchmarks (comparing two function implementations for example)

13:41 https://github.com/hugoduncan/criterium

13:41 I have it in my dev profile so I can always access it in a repl

13:41 jjl`_: microbenchmarks aren't a terribly reliable thing where the jvm is concerned

13:42 justin_smith: the point of criterium is it runs repeatedly to warm up the jit

13:42 jjl`_: (but on that, timbre seems to provide a very usable implementation of the bare minimum)

13:42 justin_smith: I mean microbenchmark in terms of looking at a small task

13:42 and it gives a statistical overview of the range of timings

13:42 mabes: has anyone used a migration library in clojure (for SQL DBs) that they have liked?

13:43 I have found a few but I'm looking for experience reports...

13:43 technomancy: clojurebot: clojars migrations?

13:43 clojurebot: Excuse me?

13:43 technomancy: dang it I feel like I've taught him this like three times

13:43 jjl`_: i think jmh is the currently fashionable thing in the java world. they seem to have covered off quite a few of the concerns about jvm microbenchmarking

13:44 technomancy: mabes: skip the libs, do something like this: https://github.com/ato/clojars-web/blob/master/src/clojars/db/migrate.clj

13:44 justin_smith: jjl`_: check out criterium, I think the way it does things should address your concerns

13:44 jjl`_: mabes: fwiw, i gave up trying to do it in clojure and use sqitch (which is really quite nice)

13:44 justin_smith: i'll take a look. thanks.

14:14 HoloIRCUser1:

14:15 hcumberdale: does Korma support db2

14:15 anyone every tried?

14:15 every = ever

14:17 jjttjj: I know this isn't #datomic, but since no one's answering there I figured I'd try here:

14:18 If I have a user entity and a chores entitiy in datomic, and I want to be able to indicate that a user can do the same chore repeatedly over time, is it standard to just give the User an attribute "chore-completed" with a cardinality of many, and then use time queries to figure out who did what, when? (sorry if my termonology is a little off, really new at datomic)

14:24 hiredman: jjttjj: that is two things, a chore which is sort of a class of actions, and instances of that class

14:25 jjttjj: I dunno what #datomic would say, but I think a good place to start would be chore entities and chore performance entities

14:33 jjttjj: Ok cool

14:38 jjl`_: what's the idiomatic way of partial'ing a function where you want to provide an argument that isn't the first?

14:40 seangrove: jjl`_: Anonymous functions

14:40 jjl`_: i expected that would be the answer :(

14:40 jjttjj: ,(map #(conj {:a 1} %) [[:b 2] [:c 3]])

14:40 clojurebot: ({:b 2, :a 1} {:c 3, :a 1})

14:40 AimHere: if it's the last function, you might tweak something with ->>

14:40 But that's probably not overly idiomatic

14:41 seangrove: There's another helper library somewhere that kind of beefs up partial, but I don't recall its name

14:41 jjl`_: in this case it's a two arg func. i was wondering if there's an analog to haskell's flip

14:41 not that i couldn't write one in a couple of lines

14:41 technomancy: rpartial would be really nice

14:41 every so often I wish I had it

14:41 justin_smith: I think flatland/useful has flip

14:42 jjl`_: (which would be) (defn flip [f] (fn [a b] (f b a)))

14:42 seangrove: jjl`_: Sometimes as-> is appropriate as well, but probably not in the case you're using a partial

14:43 jjl`_: in this case i've just written it explicitly, but flip made for some quite elegant code in haskell

14:43 seangrove: technomancy: Yeup.

14:45 justin_smith: jjl`_: more generally (fn [f & args] (apply f (reverse args)))

14:46 pyrtsa: I think the general case would be just (fn [a b & more] (apply f b a more)).

14:46 justin_smith: err I mean (fn [f] (fn [& args] (apply f (reverse args))))

14:46 pyrtsa: Doh, add f of course.

14:46 jjl`_: API design: it's hard :)

14:46 pyrtsa: Correct. :)

14:47 justin_smith: pyrtsa: that is useful if you only want to flip the first two, rather than flip all

14:48 pyrtsa: Okay, I see your point. Flipping them all makes sense for something like (comp f g h).

14:48 ..maybe. :)

14:48 jjl`_: matter of taste perhaps

14:49 pyrtsa: I think it boils down to whatever is the most common use case. And because it's not obvious what it is, it's probably better to leave flip undefined. :)

14:50 jjl`_: flip-2, flip-all

14:50 pyrtsa: Haskell conveniently avoids that yak shaving by not introducing variadic functions. :)

14:50 jjl`_: and yet we're programming clojure. obviously it was a good choice.

14:51 augustl: anyone know about embeddable services that I can use for local task execution? My use case is to ensure that stuff from a database is indexed. An embedded activemq would do the trick, except that there's no way to say "if there's already a job on the queue for item 123, discard that job"

14:51 pyrtsa: FWIW, my typical use case for flip is something like (flip get), where I'm always interested in flipping the order of the index and the container, not the default value.

14:51 jjl`_: Yes. :)

14:52 jjl`_: augustl: i suspect you actually want "if there's a job on the queue for job n, don't add it" (otherwise it might get starved and never indexed)

14:53 augustl: jjl`_: I'm using datomic, so I wan to put the ID of the item to be indexed and the daotmic T there

14:53 so I would like the old one to be removed :)

14:53 but interesting point..

14:53 jjl`_: i'll be interested in the solution you come up with to solve that issue :)

14:54 augustl: jjl`_: very interesting point actually ;)

14:56 jjl`_: resource management: also hard :)

14:58 (the immediate solution that springs to mind is to rewrite the existing job with the new data, but dependent on the mechanism you use, that might not be possible)

14:58 bhenry: the only difference we can see between these is the clojurescript version change (the one that took out format from clojure.core) https://gist.github.com/bhenry/3856e1889084a52a8db2

14:58 is that an issue that is known?

14:59 Apage43: also: what do you do if the job is *currently executing*?

15:00 jjl`_: CompilerException java.lang.RuntimeException: Unable to resolve symbol: defn in this context, compiling:(quarter/core.clj:5:1) <-- ehehehe

15:09 augustl: jjl`_: another problem is that I actually do want the job execution to be synchronous. I.e. I don't want my http request to return until the thing is indexed

15:09 didn't think this through ;)

15:24 `cbp: what the, why does emacs have "add to itunes as spoken track" on the mode menus

15:24 emacs pls

15:25 bitemyapp: `cbp: lolwut

15:26 jjl`_: given that '/' has special meaning for separating namespaces, if i wanted to refer to it in a fully-qualified manner, how can i do that?

15:26 TEttinger: ,(doc clojure.core//)

15:26 clojurebot: "([x] [x y] [x y & more]); If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators."

15:26 jjl`_: oh. fair enough

15:27 TEttinger: ,(doc /)

15:27 clojurebot: "([x] [x y] [x y & more]); If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators."

15:27 TEttinger: surprised that one works

15:27 seangrove: `cbp: Don't have it here.

15:28 `cbp: bitemyapp: the mode menus above the minibuffer have an option at the end that says "add to itunes as a spoken track"

15:28 seangrove: ,clojure.core//

15:28 `cbp: It opens itunes then gives an error :P

15:28 clojurebot: #<core$_SLASH_ clojure.core$_SLASH_@776482>

15:28 jjl`_: TEttinger: hrm, but i can't seem to do that if i (:require [clojure.core :as cc]) and then try cc//

15:28 seangrove: I believe it's special-cased though

15:29 `cbp: it is special cased

15:29 I don't think you can do that

15:29 maybe its the aftermath of the homebrew invasion

15:30 seangrove: Wow, I must have a much lower priority than TEttinger

15:30 TEttinger: eh?

15:30 `cbp: you have negative karma

15:33 bitemyapp: $karma seangrove

15:33 `cbp: clojure.core// and / are treated specially by the parser, amalloy taught me that

15:33 TEttinger: lazybot still has not returned, odd. hail, Raynes, destroyer of netsplits!

15:33 seangrove: ,(inc 1)

15:33 clojurebot: 2

15:34 seangrove: Hrm, I wonder if that's it. Bummer.

15:34 * seangrove times it

15:35 TEttinger: seangrove, I see clojurebot replying to you in under a second from here

15:35 hooray!

15:36 `cbp: you summoned it!

15:36 TEttinger: what is this power?!?!?

15:36 seangrove: Or maybe clojurebot just waits until TEttinger says something to return a value :)

15:37 TEttinger: what freenode server are you on?

15:38 seangrove: Relativistic effects, obviously.

15:38 One of us is traveling much closer to the speed of light

15:39 TEttinger: do you have ctcp responses disabled, seangrove? "/ctcp seangrove time" isn't returning anything

15:39 seangrove: sendak

15:39 gfredericks: ,'#'#'#'foo

15:40 clojurebot: (var (var (var foo)))

15:41 gfredericks: ,'#'[(a b c)]

15:41 clojurebot: (var [(a b c)])

15:42 seangrove: TEttinger: Not sure, just using the default erc config, as far as I know. Not the end of the world in any case :)

15:42 TEttinger: it took over 2 minutes to get here...

15:42 it did get there though

15:43 I think our servers must have some issue between the two, and yours to clojurebot, but not mine to clojurebot?

15:43 the magic of IRC

15:44 pcn: The magic of distributed systems

16:00 kilern: I have a defrecord and a bunch of operations that mangle it. Given a record instance, I want to "bake in" some once-computed stuff to customize the operations.

16:00 In java/python, I'd stick the precomputed stuff on the object and have the methods use it. What's the clojure way? Just use java classes functionally? memoization? metadata?

16:04 edw: ,(+ 1 1)

16:04 clojurebot: 2

16:05 edw: ,(+ *1 1)

16:05 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.lang.Number>

16:18 logic_prog: in gui design, shoudl content be of fixed size, and windows forced to be scrolling, or should content be variable size and auto adjust to window size?

16:26 modulus: hi there, when using clj-time and korma, with sqlite date-time objects are inserted with no problem into the db, but with postgresql it fails

16:26 any ideas how to fix this?

16:30 Speicifically I get:

16:30 Message: Can't infer the SQL type to use for an instance of org.joda.time.DateTime. Use setObject() with an explicit Types value to specify the type to use.

16:34 hyPiRion: modulus: http://seancorfield.github.io/clj-time/doc/clj-time.coerce.html <- See from and to sql.timestamps

16:34 TimMc: TEttinger: IRC servers use a spanning tree. Presumably the server your client is connected to is on the path between seangrove's and clojurebot's.

16:37 modulus: hyPiRion - thanks

16:39 akonny: how do you automatically assign new entity-id in datomic?

16:40 modulus: hyPiRion - any clue why this works without coercion on sqlite3?

16:45 BobSchack: akonny you send over temp id's which are then converted to entity id's

16:47 logic_prog: dumbass question: is there a javascript function for "exit full screne" ? I have written a main.cljs file where Ctrl-0 causes the app to go full screen, but now I weant to exit full screen, and apparently all stackoverflow questions are about "how do get full screen" and not "hwo to exit full screen"

16:47 akonny: Well I keep getting this: IllegalArgumentExceptionInfo :db.error/datoms-conflict Two datoms in the same transaction conflict:

16:47 hyPiRion: modulus: I guess because the SQLite dependency can actually infer that you're using jodatime, but it's not something the main Java packages can officially do, I guess?

16:48 akonny: will it help to give the entities different id's?

16:50 brehaut: logic_prog: mozilla developer network is always a great place to look for web API things https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode?redirectlocale=en-US&redirectslug=Web%2FGuide%2FDOM%2FUsing_full_screen_mode#Getting_out_of_full_screen_mode

16:50 logic_prog: brehaut: awesome, thanks for helpful response! (I was fearing "go to #javascript") :-)

16:51 brehaut: logic_prog: it was my polite way of saying always check MDN first ;)

16:51 logic_prog: lol

16:51 BobSchack: akonny how are you getting the id's for you entities?

16:51 brehaut: logic_prog: seriously though, MDN is an excellent resource. they often have shims for various APIs and good compatibility tables too

16:52 logic_prog: brehaut: I will remember to keep MDN in mind. I've found stacklerflow + w3schol to be horrible in recent days for svg/css/javascript issues

16:52 akonny: Bob

16:52 it works now.

16:53 brehaut: logic_prog: w3school is a last resort for me. its information tends to be a combination of antiquated, incomplete or wrong

16:53 modulus: hmm hyPiRion - i see. so is there no way to automate this inference somehow, otehrwise using to-sql-date on every instance where a date-time object must be sent to the db gets pretty tedious

16:53 akonny: I'm just confused: what does :e and :a mean?

16:54 gfredericks: modulus: ideally this should be possible

16:55 modulus: I'm hoping so, but no idea how to go about it.

16:55 gfredericks: I think I might have patched korma to allow for custom serialization

16:55 S11001001: modulus: jdbc has a thing that lets you write those contramaps, no idea if korma exposes that

16:55 gfredericks: S11001001: last I checked korma doesn't even use java.jdbc in that respect

16:55 it generates its own sql

16:56 BobSchack: akonny where are you seeing :e or :a (also #datomic would be a better place for answers)

16:56 gfredericks: I guess it does the ? parameterization

16:56 modulus: i still find it pretty puzzling that the sqlite3 driver supports this

16:56 gfredericks: https://github.com/korma/Korma/blob/master/src/korma/sql/engine.clj#L139

16:57 akonny: thank you

16:57 gfredericks: modulus: there's an ISQLValue protocol in java.jdbc

16:58 if you extend that to joda objects it _might_ work, depending on whether your java.jdbc is recent enough and korma actually does go through that codepath

16:58 (which it could easily not)

16:59 https://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L272

17:00 modulus: hmm thanks

17:01 jowag: Hi, why there are two fns for item removal (disj and dissoc), and not just one fn working with both maps and sets?

17:05 modulus: so what am i supposed to extend, date-time with the ISQLValue protocol?

17:05 gfredericks: jowag: are there situations where you want to write code that doesn't care whether it is dealing with a map or a set?

17:05 modulus: yeah

17:05 modulus: I'm quite new so haven't used protocols much.

17:06 gfredericks: modulus: right below the defprotocol statement it extends to object and nil, so you could mirror that

17:07 brehaut: disj is the inverse of conj, dissoc is the inverse of assoc.

17:07 technomancy: brehaut: conj can do assoc though

17:07 brehaut: jowag: associative structures tend to also be conjable, but not all conjable structures are associative

17:07 technomancy: and the inverse of conj is rest

17:07 or... pop

17:08 hyPiRion: the inverse of conj doesn't exist

17:08 brehaut: technomancy: is it? what if you conj onto an ordered collection

17:08 technomancy: "it depends"

17:08 jowag: gfrederics: not really, I was just going through the core API and this caught my eye, 'cause they do the very similar thing.

17:09 brehaut: ordered? i think i mean sorted

17:09 so im definately wrong, but i just dont know exactly how ;)

17:10 modulus: right, i'm trying to find out what jdbc is used by my korma release

17:10 S11001001: technomancy: I don't think anything will work as its inverse; there isn't enough information

17:10 hyPiRion: brehaut: It doesn't even have to be sorted. Both default sets and maps are unsorted, and pop/rest doesn't give you any inverse

17:10 The inverse of conj is (run

17:10 gfredericks: jowag: the whole point of it is a giant nerd trap for technomancy/brehaut/hyPiRion/S11001001

17:11 jowag: there is not inverse of conj, you cannot e.g. disj a vector

17:11 bitemyapp: has anybody here poked around with clojure-py?

17:11 technomancy: gfredericks: pwn'd

17:13 hyPiRion: The closest is maybe, (run* [q] (== (conjo q elt) coll))

17:13 if conjo existed

17:13 bitemyapp: tim__: would it be sensible to try to repurpose clojure-py's reader as a parser for edn data?

17:14 tbaldridge: bitemyapp: perhaps, does this not work? https://pypi.python.org/pypi/edn_format

17:14 modulus: maybe stupid question but where does lein puts deps or how can i see the version of a given dep?

17:14 bitemyapp: tbaldridge: lol no, all the edn parsers (I've seriously tried all of them) in Python are broken and terrible.

17:14 tbaldridge: we've been patching and working on edn_format at work, but it's pretty bad.

17:14 a map inside of a set breaks. a string with an escaped quote breaks. everything breaks.

17:15 I've started faking an immutable collections namespace so that the coll types are hashable and I'm trying to fix edn_format but this is driving me fucking insane.

17:15 gfredericks: modulus: try `lein deps :tree`; placement is in ~/.m2 but that's global

17:15 bitemyapp: tbaldridge: this is making it very hard to use Datomic with a Python client.

17:15 tbaldridge: You can try copying the reader from clojure-py and just ripping out all the persistent data structure stuff. Last I checked the clojure-py reader can read core.clj

17:15 brehaut: bitemyapp: does it handle lists as keys of maps?

17:16 bitemyapp: tbaldridge: I don't really want to get rid of the hashable data types

17:16 tbaldridge: what's this first/next stuff, what type does the reader expect?

17:17 brehaut: you're more likely to get me to test something by sending the literal.

17:18 brehaut: {[1 2] 3}

17:19 tbaldridge: bitemyapp: I'd just use clojure.lang.lispreader.readString

17:19 bitemyapp: thank you.

17:19 brehaut: if it uses python lists for vectors and or lists and dicts for maps that is unlikely to work

17:21 bitemyapp: brehaut: that's why I've been implementing immutable colls

17:21 tbaldridge: bitemyapp: someone should just write something like this for Python https://github.com/relevance/edn-ruby/tree/master

17:21 bitemyapp: brehaut: it seems like clojure-py is the better solution.

17:21 tbaldridge: notice the use of generative testing

17:22 bitemyapp: hum, my test string that breaks things breaks clojure-py's reader too

17:22 sad-face :(

17:22 tbaldridge: yeah this is clearly a good place to use generative testing.

17:22 tbaldridge: the ruby parser uses a parser generator + generative testing to make the computer do much of the heavy lifting

17:22 bitemyapp: tbaldridge: part of the problem is that the mutable (ie, most of them) collections in Python aren't hashable which makes some data that Datomic sends back unrepresentable.

17:23 tbaldridge: yeah, I can see that.

17:23 bitemyapp: """{:result ([17592186227381 "WF1085" "PCR Library Plate Generation" "PCR ReBatch- rady\"s rebatch"] [17592186054111 "WF1000" "do-not-use" "Test WORKFLOW"] [17592186640113 "WF1314" "Normalization Through Pooled Sequencing Library Generation || BANGLES || Agilent Version" "clin- CLIA 5-1-13"]), :count 424}"""

17:23 tbaldridge: ^^ that string breaks clojure-py, edn_format, edn, pyclj, etc.

17:24 *** ReaderException: Invalid number: 5-1-13 at line 1

17:27 modulus: hmm no joy, korma uses a 0.2 version of the jdbc adaptor

17:29 well, i'll try to sort this one out tomorrow i think. thaks hyPiRion, S11001001 and gfredericks

18:13 mikerod: when in the REPL; if you do a `(defrecord MyType [])`, my understand is that a new DynamicClassLoader is created that defines the new class MyType. Since this is a new child classloader, how does the next REPL statement know about this class definition?

18:13 Since every form seems to get its own DynamicClassLoader

18:14 I do not see how they can be aware of the classes within successive form evals. I have been looking at the DynamicClassLoader impl and I'm stumped.

18:15 nDuff: mikerod: unless my memory badly fails me, it's not creating a new DynamicClassLoader when you define a new type within an existing namespace.

18:16 ...so, my memory was indeed failing me.

18:16 mikerod: nDuff: every time I eval (defrecord MyType []) and say do a (def mt1 (->MyType)); and then I do the defrecord again and do (def m2 (->MyType)); I see that (= (class m2) (class m1)) => false

18:16 I have printing the ClassLoader parent chains

18:16 they do not intersect

18:17 except at the App ClassLoader

18:17 and the Thread/currentThread getContextClassLoader has its own stack of DynamicClassLoaders with no intersection of these defrecord generated classes.

18:17 * nDuff shrugs. Been about a year since he actually built anything useful around Clojure's classloader infrastructure, and e's obviously forgotten too much to be useful.

18:17 mikerod: *besides at the App ClassLoader*

18:18 at this point, I think it must just be magic that does it :)

18:23 coventry: What's the right way to compare #inst's? This is super confusing: https://www.refheap.com/22025

18:24 justin_smith: coventry: they are java.util.Date instances, so maybe compare their getTime

18:24 ,(= (.getTime #inst "2013-09-12T23:35:17.000000000-00:00") (.getTime #inst "2013-09-12T23:35:17.000000000-00:00") )

18:24 clojurebot: #<SecurityException java.lang.SecurityException: denied>

18:24 justin_smith: well that returns true

18:25 and .getTime is a lossless translation to / from Date

18:25 hyPiRion: well

18:25 same applies for #inst-read values

18:25 ,(= #inst "2013-09-12T23:35:17.000000000-00:00" #inst "2013-09-12T23:35:17.000000000-00:00")

18:25 clojurebot: #<SecurityException java.lang.SecurityException: denied>

18:26 justin_smith: but not neccessarily for dates coming from elsewhere

18:26 though they could still print as an #inst

18:26 but .getTime will be =

18:26 between them

18:26 hiredman: mikerod: classloaders form a hierarchy of parent and child classloaders, and the dynamic classloaders form a chain of parent/child classloaders

18:26 coventry: justin_smith: Thanks, that comparison works.

18:28 justin_smith: coventry: np

18:28 mikerod: hiredman: the DynamicClassLoader seems to be fairly minimal, so I'm surprised how I can't see how this works

18:29 nDuff: ...btw, any of y'all hiring in Chicago? I'm looking at making a trip to look at real estate in near future, and wouldn't mind chatting w/ some folks while in the neighborhood.

18:29 hiredman: mikerod: because the classloader delegation is baked in, so it just inherits that behaviour from urlclassloader

18:30 mikerod: defineClass seems to possibly clean up the cache of soft refs, then define the class, then cache it. I don't even see who is doing the resolveClass for these new classes. When findClass is called, I see the cache is searched and if that fails, it delegates to the parent

18:30 hmmm

18:31 hiredman: the big change dynamic classloader makes is to change the order of where classes are looked for

18:31 mikerod: in your own cache => then your parent

18:31 is there more to it?

18:31 hiredman: right

18:32 most classloaders do the reverse, parent first and if that fails then the child will look for the class

18:32 mikerod: yes, that was my understanding of the standard flow

18:32 I've read a lot of articles on "how class loaders" work and all that fun

18:33 it just seems to me taht a parent DynamicClassLoader is able to find a class that it's *child* made

18:33 unless the child is making it and somehow passing that up to the parent to use; these observations are also coming mostly from the REPL

18:33 hiredman: why do you think that?

18:33 mikerod: If I do `(defrecord MyType [])`

18:34 (def m (->MyType))

18:34 (.getClassLoader (class m))

18:34 it seems that a new class loader was created

18:35 for that class, but the context classloader of the Thread does not have that new class in its ancestors

18:35 jaccarmac: Hello!

18:35 First time here. On Emacs. Quick Q: Is Cider any good?

18:35 hiredman: mikerod: the context classloader doesn't play in to it

18:35 mikerod: Unless the REPL is using the classloader of the previous form eval'ed as it's current classloader and I just don't see how it does that

18:35 nDuff: jaccarmac: Quick answer: Yes.

18:35 mikerod: cider == (former) nrepl.el right?

18:35 nDuff: *nod*.

18:35 jaccarmac: nDuff: Thanks. I like it so far. Seems a lot like SLIME, which is fantastic.

18:36 mikerod: Yes.

18:36 hiredman: mikerod: the compiler evals a form it starts off by creating a new classloader with the previous classloader as its parent

18:36 bitemyapp: tbaldridge: the situation with parsing edn data is bad enough that we're considering a convention for expressing edn data in JSON.

18:36 mikerod: jaccarmac: then I'd say yes too

18:37 hiredman: that makes a lot of sense, I just have never seen how this is done

18:37 hiredman: the current loader is kept in clojure.lang.Compiler/LOADER which is a var

18:37 mikerod: I guess that's what I'm missing

18:38 I was seeing this RT#baseLoader()

18:38 if the LOADER.isBound() it is used

18:38 the context classloader is the fallback

18:38 hiredman: clojure doesn't touch the context classloader unless you ask it to use the context classloader unless you ask it to use the context classloader instead of the classloader that loaded Compiler.class which is used for the initial parent of the chain of dynamicclassloaders

18:39 mikerod: I guess I didn't put it together that the LOADER is bound always and to the previous eval-ed form's classloader that was created

18:40 hiredman: this only if you are evaling forms one by one at the repl

18:40 mikerod: So if you do a (DynamicClassLoader.) from the system classloader, it will use the Compiler.class class loader as the parent

18:41 if you have some non-system classloader set as the context classloader of the current thread, it'll use that

18:41 hiredman: that question doesn't make sense

18:41 "from the system classloader"

18:41 mikerod: ClassLoader.getSystemClassLoader()

18:42 hiredman: mikerod: the context classloader is only used if you have *use-context* classloader as true, which it is not by default

18:42 mikerod: I'm referring to the constructor logic @ ClassLoader.getSystemClassLoader()

18:42 sorry, @ https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/DynamicClassLoader.java#L35

18:43 I think I have something broken with dynamically loaded classes. I suspect it where I am calling this no arg DynamicClassLoader from.

18:43 hiredman: sure

18:43 I don't think the clojure runtime ever calls that arity

18:43 why are you constructing dynamicclassloaders?

18:45 mikerod: Complicated, but I guess short story is I'm working with a (Java) 3rd party lib, Drools. Using AOT compilation, I have code passing a (DynamicClassLoader.) to Drools so that it has a way to find dynamically loaded classes. I have some dynamically generated Clojure classes being loaded from a different jar at runtime.

18:46 dotemacs: struggling with this macro where I'm trying to use ((resolve (symbol ".someFun)) instance), any hints as to why it might be failing, and the first two passing: https://www.refheap.com/22029

18:46 hiredman: mikerod: sounds terrible

18:46 mikerod: It looks like the DynamicClassLoader I'm giving to Drools, doesn't have a connection to the class loaders created later to make these new classes

18:46 hiredman: yes, indeed. I'm trying to come up with a better approach. :)

18:47 hiredman: mikerod: aot compile everything, that drools can just look it all up via the system classloader

18:47 mikerod: that is one possible idea I had for this

18:47 definitely sounds safest

18:48 hiredman: dotemacs: methods on objects are not functions

18:48 dotemacs: resolve takes a symbol and looks up the var with that symbol name, methods don't live in vars

18:48 they are not values you can apply like that

18:48 dotemacs: so how can I apply it ?

18:49 mikerod: hiredman: thanks for the feedback, it has certainly been helpful

18:49 hiredman: in your example `(.getTitle ...)

18:50 ,(macroexpand '(.foo bar))

18:50 clojurebot: (. bar foo)

18:50 hiredman: ,(macroexpand '(.foo bar 1 2 3 4))

18:50 clojurebot: (. bar foo 1 2 ...)

18:50 dotemacs: hiredman: thats fine, but what I really wish to figure out is get a string, convert it to a method and call it

18:50 justin_smith: .getTitle is not a symbol

18:50 dotemacs: ah, ok

18:50 hiredman: dotemacs: you'll need to read the docs on the jaba reflection api

18:51 dotemacs: hiredman: cool, thanks

18:51 technomancy: tee hee

18:51 justin_smith: "bring me the object heirarchy and the class loader"

18:51 turbofail: your jedi reflection tricks will not work on me!

18:53 technomancy: I shouldn't laugh because I know exactly why hiredman typo'd and am making a ton of typos for the same reason, but I couldn't resist

18:53 =D

18:53 scottj: staggered keyboards ftw

18:54 justin_smith: before I used a split keyboard I was in the habit of typing b with my right index finger

18:54 that led to so many typos when I upgraded to split

18:54 technomancy: I suspect this is due more to the matrix alignment than the split, but maybe that's just me

18:54 Profpatsch: Urgh. How do I do a vector of a vector?

18:55 10000x10000

18:55 I thought about (repeat 10000 (repeat 10000 (rand-int 100)))

18:55 justin_smith: that is sequences but not vectors

18:55 scottj: technomancy: I just noticed that Swiftkey, the most popular alternative android keyboard (I think), uses a half staggered and half matrix layout

18:56 Profpatsch: But that gives me the same int for every item.

18:56 justin_smith: ,(repeatedly #(rand-int 100))

18:56 seangrove: technomancy: New keyboard?

18:56 clojurebot: (12 51 46 77 32 ...)

18:56 technomancy: scottj: software keyboarlds are a disgrace to the entire industry

18:56 scottj: seangrove: ergodox

18:56 seangrove: but his dad and son put it together for him

18:56 technomancy: seangrove: https://secure.flickr.com/photos/technomancy/11437911574/

18:57 heh

18:57 scottj: just the caps on the left half =)

18:57 Profpatsch: justin_smith: Is (rand-int) a side-effect?

18:57 Oh, wow, of course it is.

18:57 justin_smith: repeat only evaluates the arg once

18:58 seangrove: Profpatsch: With great foresight and care

18:58 justin_smith: repeatedly evaluates it each time

18:58 Profpatsch: So ,,(repeatedly (fn [] repeatedly #(rand-int 100)) should work.

18:59 justin_smith: that looks about right

18:59 well maybe give number args to the repeatedly calls :)

18:59 unless you want nested infinite laziness

19:00 ,(repeatedly 3 #(rand-int 100))

19:00 clojurebot: (59 76 91)

19:01 Profpatsch: Whoo.

19:01 seangrove: technomancy: You've got a bit of collection of keyboards at this point, right?

19:02 technomancy: seangrove: I suppose. this is actually my first mechanical one though

19:03 scottj: technomancy: are you planning to pantsify them?

19:03 technomancy: scottj: it's too much hassle when I need to leave my desk for nature's call, etc

19:03 scottj: them=the ergodox

19:04 technomancy: also I need to be able to use them at coffee shops etc

19:04 scottj: technomancy: having made my own pair, I totally understand :)

19:04 technomancy: thinking of building a mount for them that can sit underneath the surface of the desk at a serious tenting angle

19:04 oh yeah? nice

19:04 scottj: pics?

19:05 is that for the freestyle too?

19:05 scottj: technomancy: nope, long time ago, returned them after a short time. really needed to be wireless

19:06 technomancy: huh. wires weren't a problem for me.

19:06 scottj: technomancy: I used a hanging from a belt apparatus

19:06 technomancy: oh, didn't you have trouble with stability?

19:07 scottj: yeah

19:07 technomancy: I found having them even just not completely tight on my thighs would cause them to wander too much for touch-typing

19:33 Profpatsch: Okay, I’m lost: https://bigmac.caelum.uberspace.de/paste/benchmark-iseq.html I have no idea why I get this error and the stacktrace doesn’t help at all (line number or real function name would be nice)

19:35 Is it because reduce can’t use lazy sequences? But that would be dumb.

19:36 I create a lazy 2d-array of n random numbers square in `benchmark` and then call the function f with it and time that.

19:37 Which in this case is a simple function that finds the maximum in the 2d-array and returns it.

19:37 hiredman: Profpatsch: you should use criterium for benchmarking, and you are missing some parens

19:38 https://github.com/hugoduncan/criterium

19:38 Profpatsch: Nah, it’s just for funsies, reimplementing the functions from that article: http://rfrn.org/~shu/2013/03/20/two-reasons-functional-style-is-slow-in-spidermonkey.html

19:39 And because I need to learn Clojure. Which apparently I’m way too dumb to use. >.>

19:40 What’s giving me the error in above? I know that for-loop does what it should, `(for-loop [[3 5] [10 6]])` returns 10.

19:40 AimHere: (fn [] repeatedly n #(rand-int 100))) is probably your mistake

19:40 I reckon you want a left parens before 'repeatedly'

19:41 Profpatsch: Oh gosh, you’re right.

19:41 Why doesn’t the thing blow up in my face then?

19:41 technomancy: it's totally valid to treat a function as a value that isn't called

19:42 AimHere: Well v is still a well-formed sequence isn't it, just a sequence of gibberish

19:42 technomancy: a linter would catch it though

19:42 AimHere: It's the kind of error that those static typing dweebs would smugly sneer at

19:44 Profpatsch: But why do I get an ISeq Exception? Why can it somehow pass repeatedly, which is a function symbol?

19:45 Or can it pass *because* repeatedly is a defined symbol?

19:45 AimHere: Isn't it getting 'repeatedly' and then trying to treat that as a seq

19:45 hiredman: Profpatsch: because somewhere you are trying to treat the result of that function as a seq, but it is returning a function

19:45 ,(seq +)

19:45 clojurebot: #<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: clojure.core$_PLUS_ {:instance #<core$_PLUS_ clojure.core$_PLUS_@147fda0>}>

19:45 hiredman: neat, exceptioninfo, that's new

19:46 Profpatsch: Oooh, and because it is a lambda it doesn’t have a name.

19:46 So it *would* show the name of the function if it had one?

19:46 (+ "test" 4)

19:46 .(+ "test" 4)

19:46 ,(+ "test" 4)

19:46 clojurebot: #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>

19:46 Profpatsch: Gosh, sorry for spamming.

19:48 And, sudden realization: It isn’t showing glibberish, but the exact function. Just separated by `$` because that’s the JVM-internal representation.

19:49 In my case mason_clj.engine$benchmark$fn__10093$fn__10094 because it’s in the namespace mason_clj.engine, inside the function benchmark, inside one lambda and another.

19:50 I should try to understand error messages better. But that’s what I promise myself every time …

19:58 technomancy: well... assuming clojure error messages are not gibberish is actually not such a great strategy

20:03 Profpatsch: Yes, they are. Wouldn’t it be easy to parse these to something useful on first glance?

20:04 I mean there seems to be a logic behind them and some information.

20:04 These are still the raw JVM error messages, right?

20:05 technomancy: usability is not generally considered a priority by the core developers

20:27 dotemacs: Is using memfn, the way I use it here OK: https://www.refheap.com/22029 ?

20:39 allenj12: hey i just read the joy of clojure and now going back and doing the exercises. having a function that takes a vector say [1 2 3] how can i destruct the arguments to a is 1 b is 2 etc without using a let block

20:39 more specifically in the functions args

20:40 justin_smith: the same syntax as in a let block

20:40 bitemyapp: arrdem: found daylight servers

20:40 justin_smith: ,((fn [[a b c]] (+ a b)) [2 3 4])

20:40 clojurebot: 5

20:43 allenj12: hmm but for defn i cant due say (defn [[alpha beta gamma] input])

20:43 do*

20:45 o wow wait im silly i see it now

20:45 thanks!

21:20 dsrx: wait, there are exercises in the joy of clojure?

23:06 {[^-^]}: how do I use maven dependencies in leiningen

23:09 xeqi: {[^-^]}: [group-id/artifact-id "version"] in :dependencies [...]

23:10 {[^-^]}: thanks

23:30 do you guys think that there is a performance difference in the graphical rendering between clojure and java using opengl?

23:31 I think with the new opengl api's anyway, most of that computation is done on the gpu

23:54 TEttinger: {[^-^]}, uh... you may encounter performance stuff from java defaulting to unboxed data and clojure defaulting to boxed (except in arrays)

23:54 I need to fix my game that indirectly uses OpenGL, because performance is bad on my game logic stuff

23:55 but I do think that more intensive uses of graphics stuff from clojure could be slower than if it were done in java (clojure really does prefer not mutating things)

Logging service provided by n01se.net