#clojure logs

2013-12-18

01:07{[^-^]}is there any point in learning ruby if you know clojure
01:07{[^-^]}I think ruby has the advantage of availability of entry level jobs and scripting
01:08noidi_ruby works much better than clojure as a shell-script replacement
01:10Raynes{[^-^]}: There is never not a reason to learn x.
01:10Raynes:p
01:10RaynesLearn ALL the things.
01:10LajjlaWorship only one Shadow though.
01:10LajjlaOnly His Shadow.\
01:10{[^-^]}Raynes: I don't understand why you said that
01:10RaynesPrecisely.
01:10noidi_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
01:10LajjlaWorshiping any other shadow than His would be blasphemy.
01:10{[^-^]}It's like someone asking 'Why?' and the other person saying 'Why not?'
01:10Raynes{[^-^]}: I'm trying to tell you that yes, it's a good idea to learn other languages.
01:11RaynesRuby is a good one in particular if you like coding for a living.
01:11{[^-^]}I already hava java, C++, and haskell under my belt
01:11RaynesI've so far never done Clojure work that didn't have some rails somewhere. :p
01:11{[^-^]}really?
01:11andyfLearning ALL the things is a bit impractical, though, without a drastically increased learning capacity, longer life span, or both.
01:12akurilinDoes 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.
01:13{[^-^]}sounds like scala
01:13akurilinMakes you appreciate Clojure's consistency.
01:13{[^-^]}Raynes: I'm a language slut
01:13RaynesMe too :3
01:13{[^-^]}I don't know when to stop learning new languages
01:15seangroveakurilin: What parts of js seem to want to follow the immutable paradigm?
01:17Raynesakurilin: I haven't found the part of js that wants to follow the immutable paradigm.
01:17amalloyi was going to say "well you can't mutate numbers", but of course you can by fiddling with Number.prototype
01:17nopromptundefined
01:20seangroveamalloy: *but* you have to surround the numbers with (), because syntactically you can't extend numbers
01:20seangrove(5).times(function(index) {...});
01:20seangroveBeautiful...
01:20noprompti'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.
01:21nopromptsometimes you can say exactly what you want. sometimes you can't.
01:22nopromptfor instance, javascript is a good language for telling jokes.
01:22eggnogginRaynes: js, like java, needs to be taught to be immutable :)
01:23noprompteggnoggin: no. programmers just need to avoid writing it directly.
01:23eggnogginnoprompt: like java?
01:23noprompteggnoggin: or whatever.
01:23seangrovenoprompt: Either nonsense, or understated truism.
01:24nopromptseangrove: i'm just being honest.
01:26nopromptbut i'll probably pick up another one this year.
01:26eggnoggintry rust
01:26nopromptand it probably won't be haskell.
01:26nopromptor rust.
01:26nopromptsorry.
01:27seangrovenoprompt: I don't doubt it, I just doubt the ultimate veracity
01:27eggnogginwhat you should do is learn the language least like the languages you already know
01:27eggnogginmaybe idris or prolog or who knows
01:27nopromptseangrove: don't doubt what?
01:27Raynesnoprompt: I've been doing Go.
01:27TEttingernoprompt, J?
01:27noprompteggnoggin, Raynes learning towards factor or prolog
01:27nopromptsomething esoteric.
01:28RaynesFactor is definitely that.
01:28TEttingerI've heard good things about factor
01:28RaynesIt's also a great language.
01:28nopromptTEttinger: it maximizes the fun.
01:28eggnoggininstead of learning prolog you should read the reasoned schemer and play with core.logic :)
01:29noprompteggnoggin: i should. but i won't.
01:29eggnogginor, as well as
01:29nopromptlol
01:29eggnogginno reason for it to be instead
01:29noprompteggnoggin: actually, i'm just giving you a hard time. i'll probably look at those too.
01:30nopromptmy goal this year is to do a bunch of weird stuff with text. none of it immediately useful for serious work.
01:30TEttingernoprompt, like procedural poetry or something?
01:31nopromptTEttinger: i want to turn works of literature in to intelligent madlibs.
01:31alandipertRaynes: how do you feel about go?
01:32nopromptTEttinger: but generating poetry sounds fun too.
01:32TEttingernoprompt, heh. I know the guy who made http://www.happyponyland.net/lyrics.php , which is entertaining
01:32Raynesalandipert: 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.
01:32eggnogginRaynes: have you looked at rust?
01:32eggnogginnice type system :)
01:32nopromptalandipert: i thought i knew bash. you made me realize i don't. <3 thank you. :)
01:32Rayneseggnoggin: Aye, I like it better.
01:33Rayneseggnoggin: But the Go thing was specifically because I might be using it for a job at some point.
01:33alandipertnoprompt: i'm flattered but i forgot it all last week i think
01:33eggnogginwhere I work using go would be off the wall, rust is just as off the wall to that crowd :p
01:34eggnogginthe footprint of langs like rust and go (and for that matter c et al) is so nice compared to jars and the jvm
01:34nopromptalandipert: you are to modest, sir.
01:34alandipertRaynes: re: go/clj/conch have you considered modeling programs as channels?
01:34nopromptit's inspiring.
01:35Raynesalandipert: You should talk to amalloy.
01:35Raynes;)
01:35alandipertRaynes: oh he computes on this?
01:35amalloywhat
01:35Raynesamalloy: Modeling programs as channels.
01:35alandipertamalloy: re: shelling out and getting back a channel
01:36nopromptthat sounds like a good idea.
01:36alandipertit works out well for unix, anyway
01:36RaynesOh, well that's specifics.
01:36amalloyseems reasonable enough; does java actually expose the machinery to listen to a subprocess in an async way though?
01:36RaynesYou said a whole bunch of things.
01:36Raynes:p
01:37RaynesConch could possibly make use of channels.
01:37alandipertamalloy: not that i know of, but i think this could be emulated by backing with/managing fifos
01:37RaynesI should look into it.
01:38Raynesalandipert: Conch is backed by a queue already for <insert long painful story here>
01:39amalloyalandipert: 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
01:41nopromptalandipert: is there something other than unix? :P
01:41alandipertamalloy: 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*
01:44alandipertamalloy: 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
01:45TEttingergherkin?
01:45TEttingerlike the cucumber?
01:45alandipertTEttinger: https://github.com/alandipert/gherkin
01:46TEttingerneat alandipert!
01:47alandipertTEttinger: thx!
01:47nopromptTEttinger: it's "amazeballs" as one might describe.
01:47nopromptproper abuse.
01:47TEttingertotes mcgotes.
01:50akurilinseangrove, Raynes : sorry, switched away for a sec. Take a string.replace()
01:50akurilinit's not in-place mutation.
01:51akurilinAnything string-related at least appears to be immutable in JS.
01:53eggnogginakurilin: are you using _ ?
01:54akurilinyeah
01:54akurilin_ is annoying too.
01:54seangroveakurilin: Heh, string were where I went immediately as well. But I still think it's a pretty low bar, heh
01:54akurilinFor example, _.extend(a,b) mutates a in addition to returning the result.
01:54akurilinBit me in the ass today, I was clueless about what was happening.
01:55eggnogginya, kind of the semantics of extend tho
01:55eggnogginwhat I do is _.extend({}, a, b);
01:55akurilinWell, my point of reference is Clojure's merge
01:55eggnogginunfortunately that does a shallow copy as well and winds up giving you shared refs
01:55eggnoggin:3
01:55akurilinI use lodash, it has deep copy.
01:57pinkiesOutQuestion: 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:
01:57eggnogginya js is not a fantastic lang, ref types are a bitch
01:57pinkiesOut(with-open [rdr ((fn [line] (filter #(not (.startsWith % "%")) line))
01:57pinkiesOut (line-seq (clojure.java.io/reader "test.txt")))]
01:57pinkiesOut (doall (map #(println %) rdr)))
01:58pinkiesOutNew 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
01:59eggnogginwith-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
02:00eggnogginoh wait parens derp
02:01pinkiesOutthe doall print statement does in fact print the filtered file, but returns:
02:01pinkiesOutIllegalArgumentException No matching field found: close for class clojure.lang.LazySeq clojure.lang.Reflector.getInstanceField (Reflector.java:271)
02:01eggnogginya
02:01eggnogginLazySeq doesn't implement close, things like java.io.File does
02:01andyfpinkiesOut: with-open always calls a Java method .close on the thing after the [
02:02andyfpinkiesOut: Typically that thing will be the return value of (io/reader), not a sequence.
02:03eggnogginso do the filtering and casting to line-seq inside the body of the with-open
02:03andyfConsider starting with the line (with-open [rdr (io/reader "test.txt")] and then put the rest of the functionality in the body
02:07pinkiesOutandyf: 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)
02:07pinkiesOutIf that makes sense...
02:09alandipertpinkiesOut: so un-edit-able-function is expecting a java.io.Reader?
02:09pinkiesOutalandipert: that's correct
02:09TEttingercan't you re-coerce it to reader?
02:09andyfpinkiesOut: So use the first line I suggested above, and then as part of the body, call (un-edit-able function rdr)
02:11andyfpinkiesOut: 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.
02:12pinkiesOutTEttinger: re-coercing was my first instinct, but I'm new to clojure and clueless on how to do so
02:12TEttingerI'm exploring the options in a repl now
02:12pinkiesOutandyf: I'm trying some of your ideas now...
02:13andyfpinkiesOut: 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 "%"?
02:13pinkiesOutandyf: that's correct
02:16andyfOK, 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.
02:16andyfSomething like (StringReader. (apply str (expression that returns a sequence of strings)))
02:17alandipertone could reify a java.io.Reader backed by the seq
02:17andyfIf 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.
02:19andyfbut if you know it will be small enough that isn't a problem, that is fairly straightforward.
02:19TEttingeroh god this is awful
02:19TEttingerbut
02:19TEttinger(with-open [rdr (clojure.java.io/reader "LICENSE")] (clojure.java.io/reader (.getBytes (apply str (filter #(.startsWith % " ") (line-seq rdr))))))
02:19TEttingerthat filters out all the lines starting with non-space chars and creates a reader from it
02:20pinkiesOutThe input file will be arbitrarily large, so I can't rely on it being small unfortunately
02:20TEttingerlike terabytes or what?
02:21TEttingerI bet there's some java class for this
02:22andyfTEttinger: The .getBytes is unnecessary in there, I think.
02:22pinkiesOutUnlikely that large, but the file will be data for processing in incanter so the sky is the limit
02:22pinkiesOutin theory
02:22TEttingerandyf, reader will coerce strings to filenames or URIs
02:22andyfpinkiesOut: Sounds like alandipert's answer would be necessary, then.
02:22RaynesThe sky is a long way for a harddrive to go.
02:25TEttingerI think part of the issue is that it needs to be in memory at some point to modify the file, right?
02:25TEttingeror rather modify the memory's copy of the file?
02:26pinkiesOutYes, that seems to be the case
02:26andyfJava has a pair of classes PipedWriter and PipedReader that might be useful.
02:27pinkiesOutI 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
02:27andyfYou write some code that reads and filters lines from your file, writing them to a PipedWriter.
02:27andyfCreate a PipedReader from that PipedWriter, and that is what you feed as input to the function that needs a Reader.
02:28TEttingerhttp://docs.oracle.com/javase/6/docs/api/java/io/PipedReader.html I have no idea what this does...
02:28pinkiesOutandyf: this sounds very promising...
02:28andyfHow many times do you need to repeat this?
02:28pinkiesOutOnce
02:28RaynesTEttinger: Create a PipedReader from that PipedWriter, and that is what you feed as input to the function that needs a Reader.
02:28Raynes- andyf
02:28andyfAnd you have the file on disk now that needs to have comments stripped out?
02:28RaynesDecember, 2013
02:28TEttingeryeah, sorry I meant from the javadocs
02:29Raynes:p
02:29TEttingerthey are pretty vague on that page, seriously
02:29pinkiesOutandyf: 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
02:30andyfWhat do you mean in an automated setting? I thought you said you needed to do it once?
02:31pinkiesOutI misunderstood you--- the filtering happens once only in my script. But the script will be applied to many files down the road
02:32andyfIf 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.
02:32andyfand by slightly, I mean noticeably easier :-)
02:33andyfbut if it can really be terabytes, you might not want to do that.
02:34pinkiesOutPrecisely the problem. It seems like a pretty useful feature to be able to lazily read a file, skipping lines that match a pattern.
02:34andyfI 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.
02:35andyfpinkiesOut: or in general read one file, writing out an arbitrarily transformed one, but not to disk, but to the equivalent of a Unix pipe
02:36pinkiesOutandyf: yes, well put
02:36andyfThat is what the PipedWriter should give you
02:37andyflet me hack a couple mins on this.
02:37pinkiesOutI 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
02:39pinkiesOutYou're welcome (and encouraged) to hack away :)
02:39andyfI might not get what you want, but there is some chance it might work
02:41pinkiesOutNewbie question: would this require loading a new dependency, or are PipedReader/Writer available for calling from java as is from clojure?
02:41Raynesandyf: You have to do it on a whiteboard.
02:41andyfShould be part of standard JDK library as is
02:42RaynesLike in an interview.
02:42andyf:-)
02:42andyfYou hiring?
02:44pinkiesOutTEttinger: your solution and effort didn't go unnoticed-- thanks for tinkering :)
02:44TEttingerhaha thanks
02:44TEttingerand thanks andyf for doing the work!
02:44pinkiesOutyes indeed!
02:45andyfThank me if it works :)
02:45Raynesandyf: Hah, I wish.
02:47seriously_randomWhat's the difference between these two uses of 'rest': http://pastebin.com/9F3JeJAZ
02:48Raynesseriously_random: (rest '([:a 3] [:b 2]))
02:48RaynesYou're trying to call a vector as a function.
02:48RaynesWhich works, but you have to give it a number and it looks up by index.
02:51Raynes&([1 2] 0)
02:51lazybot⇒ 1
03:07andyfNo fabulous success yet. Only head-scratching experiment so far.
03:10pinkiesOutthanks for trying-- don't feel obligated to try any more. At least I have a direction in which to look
03:22clgvpinkiesOut: possibly one of the clojure books gets you a headstart on clojure ;)
03:23seriously_randomhow to "extract" 3 out of (3)? http://pastebin.com/64UY4N4R
03:23pinkiesOutclgv: Two in the mail already :)
03:25clgvpinkiesOut: meanwhile http://clojure-doc.org/articles/content.html might help you out on the basics ;)
03:25clgvseriously_random: ##(first '(3))
03:25lazybot⇒ 3
03:27clgvseriously_random: what exactly are you trying to do? seems overly complicated atm
03:29seriously_randomclgv, repeat :a in [:a 3] 3 times
03:29TEttingermaking [:a :a :a 3] ?
03:30clgvseriously_random: so a map of keywords and repetition counts is the input and what is the output? a concatenation of the repeats?
03:30seriously_randomTEttinger, (:a :a :a)
03:31TEttinger,(let [inp [:a 3]] (repeat (second inp) (first inp)))
03:31clojurebot(:a :a :a)
03:31clgvseriously_random: ##(let [m {:a 3 :b 2}] (for [[k n] m, _ (range n)] k))
03:31lazybot⇒ (:a :a :a :b :b)
03:32TEttingerclgv, I have no idea what's going on in that for
03:32seriously_randomsorry, I want to do it my way. How do I get 3 out of (rest (first short)) ;=> (3)
03:34TEttingerok, rest returns a seq, I think if you know (first short) always returns a pair, you can use second
03:34TEttingerwhich it should, if you're getting it from a map
03:34seriously_randomyou can't get stuff out of persistent lists in clojure?
03:35TEttingersure
03:35TEttingerwhy couldn't you?
03:35seriously_randomhow?
03:35clojurebotwith style and grace
03:35TEttingeryou would use nth, first, second...
03:35TEttingernth is the general case
03:36TEttinger,(nth '(1 2 3) 0)
03:36clojurebot1
03:36glosoliAnyone using rainbow_parentheses.vim with Clojure here experienced problems when auto loading it has no effects, neither does manual activation ?
03:37TEttingerbut my point I think, seriously_random, is that you don't need to construct a list and then immediately de-construct it, do you?
03:37TEttinger(also it's a seq, not a list, but they print the same, which is confusing)
03:38seriously_randomTEttinger, PersistentVector$ChunkedSeq is a sequence? Vector is [], list is ()?
03:38TEttingerthat's what rest returns, apparently
03:39TEttinger,(class (rest [1 2 3]))
03:39clojurebotclojure.lang.PersistentVector$ChunkedSeq
03:39clgvseriously_random: either use `nth` or destructuring or `first`, `second`
03:39TEttingerrest does not return individual elements, and repeat expects a single number for the number of times to repeat
03:43TEttinger(inc clgv)
03:43lazybot⇒ 10
03:44clgv:D
03:45clgvseriously_random: also ##(let [m {:a 3 :b 2}] (for [[k n] m] (repeat n k)))
03:45lazybot⇒ ((:a :a :a) (:b :b))
03:47clgvstacking lots of first/second/rest/nth usually makes your code hard to understand
03:51TEttinger,(doc ffirst)
03:51clojurebot"([x]); Same as (first (first x))"
03:51TEttingerdon't use too much of that either though
03:53daGrevisWhere are the frameworks?
03:54daGrevis(from https://news.ycombinator.com/item?id=6925775 )
04:19clgvdaGrevis: 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...
04:29seriously_randomto get "((1 2) (3 4))" you could write "(cons '(1 2) (cons '(3 4) '()))", is there a shorter way?
04:31TEttinger,(list '(1 2) '(3 4))
04:31clojurebot((1 2) (3 4))
04:31TEttingerseriously_random: ^
04:31clgv,'((1 2) (3 4))
04:31clojurebot((1 2) (3 4))
04:32TEttingerwell that too
04:32clgveven shorter since you usually want vectors instead of lists for sequential constants: ##[[1 2] [3 4]]
04:33clgv,[[1 2] [3 4]]
04:33clojurebot[[1 2] [3 4]]
04:35andyfI failed the interview question, but I think I have a decent answer, anyway.
04:36clgvseriously_random: imho if you are not constructing lazy sequences you seldom use `cons` in Clojure
04:36clgvandyf: what was the question?
04:36TEttingerI can't say I recall ever using cons in clojure
04:36andyfpinkiesOut: ping
04:37clgvTEttinger: me too, only in conjunction with lazy-seq :=
04:37clgv;)
04:37andyfA 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.
04:38andyfalandipert (I think) suggested making a proxy Reader that implemented the read calls using a string sequence as a source of characters.
04:38andyfI finally got it working.
04:38TEttingerNICE!
04:38TEttingerthat took some effort!
04:39TEttinger(inc andyf)
04:39andyfIt is not the prettiest thing to read, but using it is pretty easy.
04:39clgvandyf: but mostly useful for interop right?
04:40TEttingerit was a very specific use case I think
04:40TEttingeroh, that's why inc doesn't work
04:41TEttingerRaynes, are you the guy running lazybot?
04:41clgvhe is^^
04:42clgvthe bot went to sleep again ;)
04:42andyfThe 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.
04:42TEttingerI don't know if it's been fixed in master, but on a different server my lazybot fork will not reconnect after netsplits
04:43andyfBasically 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.
04:44TEttingerI hope pinkiesOut sees it, that sounds great
04:45andyfIt's the kind of thing I could imagine using some time myself.
04:45andyfI guess it is time to create a teeny Github project. Not sure where else to put it.
04:46TEttingergist?
04:46clojurebothttp://gist.github.com/
04:46TEttingerthank you clojurebot
04:50clgvandyf: as TEttinger says, if it is too small for a library just make a named gist on github
04:52andyfMakes sense. Cleaning it up now.
05:00andyfI 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
05:02TEttingerI'll (inc andyf) until the cows come home
05:03clgvandyf: better give it a clj ending for syntax highlighting ;)
05:04andyfCan I rename it, or just create another one with the same contents?
05:05andyfRenamed.
05:05clgvoh 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
05:08noneshello
05:09nonesis there ways to use Seesaw library with third party components?
05:09andyfIs it a bot feature to save a message for the next time someone connects to the channel?
05:09andyfIf so, I guess I can't use that now.
05:11andyfnones: 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
05:12TEttingernones, yes. which components do you mean? I've used it with insubstantial
05:12clgvnones: you can extend seesaws mechanism to new components - but you have to dig into it to do that
05:12clgvnones: though it is not too complicated, I implemented some of seesaws features for jfreechart
05:15nones<TEttinger>, for example , RSyntaxTextArea : https://gist.github.com/alhimik45/8020047
05:15TEttingernice
05:16TEttingerI'm getting sleepy, don't take my advice
05:18clgvnones: there is support for rsyntaxtextarea in seesaw
05:20clgvnones: https://github.com/daveray/seesaw/blob/89b25f992a80624c4c59ac56efd796588a019982/src/seesaw/rsyntax.clj
05:20amalloyandyf: lazybot supplies $mail <username> <message> for saving messages
05:20amalloynext time recipient is seen, lazybot sends him a private message with instructions on how to read saved mail
05:21nonesclgv: thanks, I'll try it, but why there no this information in docs?
05:23clgvnones: seesaw's documentation is too sparse for my taste as well
05:23andyf$mail pinkiesOut See this code here, especially examples of use at the bottom: https://gist.github.com/jafingerhut/8019871
05:24clgvnones: 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
05:24andyfclgv: Dave Ray would likely be open to help there, if you are interested.
05:25clgvandyf: I am sure. but that's unlikely in the next 6 months due to my time constraints... :(
05:34dabdIs clojuratica abandonware or still works with the latest clojure versions?
05:36carklast update 4 years ago ... you might have to try it
05:36carkprobably won't work with latest tho
05:37dabdThey mention it in the Clojure Data Analysis Cookbook which is very recent
06:16clgvdabd: 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
06:31ArjunaxHi, 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")}
06:33ArjunaxI want it with one when
06:34Arjunaxbut when i go (when cond :foo2 "bar2") it obviously doesn't work
06:40clgv,(let [m {:foo1 "bar1"}, cond (= 1 1)] (cond-> m cond (assoc :foo2 "bar2")))
06:40clojurebot{:foo2 "bar2", :foo1 "bar1"}
06:40clgvArjunax: ^^
06:40clgv,(let [m {:foo1 "bar1"}, cond (= 1 2)] (cond-> m cond (assoc :foo2 "bar2")))
06:40clojurebot{:foo1 "bar1"}
06:41Arjunaxok, thanks
06:55clgvis definterface supposed to not convert clojure naming for methods to feasible java names?
06:55clgv"modify!" ends up as "modify!" literally instead of "modify_BANG_"
07:00jeis <!! missing from cljs core.async?
07:01carkje: yes, there are no threads in js
07:02carkyou still have <!
07:05jecark: I know - I'll just need to find another way around the problem, thanks :)
07:05cark=)
08:02gabe_hollombeHey 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
08:02gabe_hollombeanyone have a minute for some guidance here?
08:08seriously_randomtrying to write a recursive function, running into indexoutofboundsexception. Don't understand why: http://pastebin.com/FCFyNw8e
08:08CookedGryphongabe, you're mixing up your quoted and unquoted stuff
08:08gabe_hollombeCookedGryphon: I totally believe it. Can you help me grok it with a pointer?
08:08CookedGryphonso waht do you want to write? (doto + 1 2 3)?
08:09CookedGryphondoit*
08:09gabe_hollombe(doit (+ 1 2 3))
08:10CookedGryphonokay, so the trivial version of this macro is actually (defmacro doit [exp] exp)
08:10CookedGryphonwhich if you macroexpand it will write out the code (+ 1 2 3)
08:10gabe_hollombeyes
08:11gabe_hollombeI'm with you so far
08:11CookedGryphonand the functional version of this would be (defn doit [exp] (apply (first exp) (rest exp)))
08:11gabe_hollombeyep
08:12CookedGryphonbut 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:
08:13CookedGryphon(defmacro doit [exp] (let [f (first exp) args (rest exp)] (list 'apply f args))
08:14CookedGryphonwait, that's not quite right
08:15CookedGryphonbecause the code it outputs (macroexpand '(doit (+ 1 2 3))) => (apply + (1 2 3)) which isn't valid clojure, because 1 isn't a function
08:15CookedGryphonso you'll need to either quote that or make it a vector
08:15gabe_hollomberight... which is more idiomatic?
08:16CookedGryphon(defmacro doit [exp] (let [f (first exp) args (rest exp)] (list 'apply f (list quote args))
08:16CookedGryphon(defmacro doit [exp] (let [f (first exp) args (rest exp)] (list 'apply f (list 'quote args))
08:16CookedGryphonthe quote one is better for learning, which is the point of this
08:17gabe_hollombeok. just reviewing this final example
08:18gabe_hollombeit starts with list, because we want our macro's output to be a list
08:18CookedGryphonyep
08:18gabe_hollombethen we have to quote apply or else it will actually try to apply right there in the macro code generation
08:18gabe_hollombe(instead of putting apply in the output)
08:18CookedGryphonexactly
08:18gabe_hollombef comes straight from the binding as-is
08:19gabe_hollombethen we need to make a list for the application of f
08:19gabe_hollombeand we're quoting the quote function there for the same reason as apply
08:19gabe_hollombei get it
08:19CookedGryphonthe second list is actually for the quote function
08:19CookedGryphonbut yeah
08:20CookedGryphonand 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
08:21CookedGryphonbut for completeness, teh backtick version would be something like (defmacro doit [f & args] `(apply ~f (quote ~args)))
08:21gabe_hollombeyeah. I agree. and thank you
08:21CookedGryphonbut for completeness, teh backtick version would be something like (defmacro doit [[f & args]] `(apply ~f (quote ~args))) sorry
08:42jballancHmmm...so the "uberjar" profile in lein gets automatically included during an uberjar compilation...but what about "dev"?
08:42jballancrunning "lein ring uberjar", it sure seems like my "dev" profile is being included
08:53seriously_randomreverse of nthrest?
09:06ngwhi *
09:06edwHey.
09:06ngwI'm having troubles using the create function in the REPL
09:06ngwhttps://gist.github.com/ngw/f8ef003532c8d712dd9b
09:07ngwI think I should require it directly without defining a ns, right?
09:07ngwuser=> (:require [theshire.models.element :as model])
09:07ngwCompilerException java.lang.ClassNotFoundException: theshire.models.element, compiling:(/private/var/folders/r_/8jpc8nbx6x1g6gq3r1djmr900000gp/T/form-init3432138121469073363.clj:1:1)
09:07ngwwhat am I doing wrong?
09:10Morgawris 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?
09:10Morgawrbecause doing (:a (:b (:c my-map))) feels tedious
09:10MorgawrI guess I could do (reduce [:a :b :c] my-map) ?
09:11vijaykiranMorgawr: get-in ?
09:11octagonhttp://clojuredocs.org/clojure_core/1.2.0/clojure.core/get-in
09:12Morgawrneat! thanks
09:12Morgawrexactly what I needed
09:26maravillasngw: try (require '[theshire.models.element :as model])
09:27maravillasthe form you pasted is part of the ns macro
09:27pandeiroanybody 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?
09:28ngwmaravillas: Exception lib names inside prefix lists must not contain periods clojure.core/load-lib (core.clj:5359)
09:30maravillasthe ns form in your pasted file is wrong, too :)
09:30maravillasshould be (:use [ring.util...
09:30maravillasthe opposite problem
09:41arkhcompojure 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
09:46daGreviswhat's wrong with this? (= '(:a :b :c :d :e) (conj '(:a :b :c :d) :e))
09:46Bronsa,(conj '(:a) :b)
09:46clojurebot(:b :a)
09:47Bronsaconj on a list adds the item to the front
09:47daGrevisBronsa, what's the difference from cons then?
09:48hyPiRionthat conj is polymorphic, whereas cons is not
09:48arkhdaGrevis: http://stackoverflow.com/questions/3008411/clojure-seq-cons-vs-list-conj
09:48gabe_hollombedaGrevis: operates differently depending on the type, I believe
09:48Bronsaconj is a polymorphic construct that works on colls, (conj coll el) will attach the el in the most convenient position for the coll
09:49gabe_hollombepooh, right. sorry what Bronsa said
09:49cark,(conj {:a 1} [:b 2])
09:49clojurebot{:b 2, :a 1}
09:49carkworks on sequable i'd say
09:51CookedGryphonCan anyone give me some pointers on handling exceptions in core.async code
09:52CookedGryphonI'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
09:52daGrevisdid lisp had exceptions?
09:52daGrevislisp as cl or scheme.
09:52CookedGryphonbut I also don't want to have to add the boilerplate (try .. (catch ...)) inside every go block
09:53carkcl has conditions and restarts that's like exceptions 2.0
09:53carkfor scheme, exceptions are more problematic due to continuations (afaik)
09:55daGreviscark, ty
09:56clgvCookedGryphon: then write a "safe-go" macro that automatically adds try-catch to notify you of exceptions
09:57CookedGryphonyeah, i guess so, but then I'd need a safe-go-loop
09:58CookedGryphonand yeah... I was sort of hoping there was something built in
09:58clgvCookedGryphon: humm then just a safe-sync macro ^^
09:59clgvCookedGryphon: you can easily add try-catch to `go` and `go-loop` via clojure.tools.macro/macrolet
10:00CookedGryphonclgv: that might not be such a bad idea actually, just add it in for debugging
10:04fredyrdaGrevis: scheme have exceptions as well
10:05clgvCookedGryphon: yeah, won't hurt I guess...
10:07CookedGryphonclgv: oh, and I only need to do go, because go-loop expands to go... right?
10:07CookedGryphonor will it already have expanded by that point...
10:07CookedGryphonconfused
10:07CookedGryphon:P
10:08clgvI am not sure whether macrolet does expand the code. I doubt that it.
10:09clgvbut you can use the same implementation for both macro symbols
10:20CookedGryphonclgv: any idea what it means when it says can't macrolet qualified symbol go?
10:21CookedGryphonis it just saying I can't redefine a macro that's already been defined?
10:28clgvCookedGryphon: please post a gist where the error occurs
10:29CookedGryphonclgv: I think I've got it
10:29CookedGryphonI should have been using a symbol-macrolet
10:31clgvCookedGryphon: does symbol-macrolet also work with custom expansions? not just replacing different symbols?
10:32CookedGryphonYeah, that didn't work either
10:32CookedGryphonI'm not sure I get these macrolets
10:35CookedGryphonI think I'll just make my own versions
10:36clgvthere is no stable version of core.async yet?
10:37tbaldridgeclgv: define stable?
10:38clgvtbaldridge: stable, as in the maintainers are confident enough to remove the "alpha"
10:38stuartsierraStable as in 'Can you keep a horse in it?' :P
10:38clgv:D
10:39stuartsierraI wouldn't keep a horse in core.async right now. Maybe a pony. Or a goat.
10:39tbaldridgewell we haven't changed the public API in months (like six months)
10:39clgvtbaldridge: but got used to the "alpha" ? ;)
10:40tbaldridgeAlthough you'd probably want to talk to Bodil when it comes to ponies and Clojure.
10:40stuartsierraTrue, I should defer to the expert on ponies.
10:40andyf_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:41tbaldridgeclgv: 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:41clgvandyf_: I know. It is a good thing those are removed now. didnt you trigger that?
10:41tbaldridgeclgv: if it works for you use it. As always, we try to keep public API changes to a minimum.
10:41andyf_clgv: No, that was all Alex Miller, bless his heart
10:41clgvoh sorry.
10:41stuartsierraAll version numbers are lies. On rare occasions they are useful.
10:41clgvtbaldridge: but then why do you keep an alpha in it anyway?
10:42tbaldridgeclgv: 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:43stuartsierraI should write an IRC bot that links to my blog rants automatically.
10:43tbaldridgeBlizzard's "Beta" games are about the same as version 1.6 from other companies.
10:43clgvstuartsierra: which one this time?
10:44stuartsierrahttp://stuartsierra.com/2013/01/28/brief-rant-about-versioning
10:44andyf_You guys are giving anecdotal evidence that version numbers *are* meaningful, just that their meaning depends upon the source.
10:45stuartsierrabah, I don't want to talk about this. Going to go find some work to do.
10:45tbaldridgeandyf_: agreed.
10:46tbaldridgeSo my view is "rich's alpha is most people's 1.0". But perhaps that is just me.
10:47tbaldridgeAnd yeah, read stuart's rant. That's pretty much my views on it as well.
10:47technomancy"Don't bother doing this thing, because other people do it badly and it's hard"
10:47technomancymkay
10:48smilerNever do hard stuff.
10:48smilerIt's hard.
10:49tbaldridgetechnomancy: 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:50tbaldridgeupgrading any library should require full testing anyways, so what does it matter what version numbers are?
10:51clgvtbaldridge: 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:51tbaldridgerefheap please?
10:52clgvtbaldridge: non.existet yet. it was just the idea to give him information when something is thrown in his go blocks
10:52CookedGryphonthe basic problem is that I have a lot of little go blocks working in concert
10:52clgvtbaldridge: originally he was looking for something builtin in core.async
10:52CookedGryphonand it obfuscates my logic to surround each one of them in error handling boilerplate
10:52tbaldridgeyeah, 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:53tbaldridgeI'd just use defmacro though, not sure why you'd need macrolet.
10:53CookedGryphonthat's what I've gone with
10:53CookedGryphonit wouldn't be so annoying if I was working on the jvm
10:53tbaldridgethis is cljs?
10:53CookedGryphonbut on android uncaught exceptions in threads kill the whole app
10:53clgvtbaldridge: yeah writing a macro with defmacro - macrolet was a suggestion to easily replace `go` and `go-loop` bodies
10:54tbaldridgeyeah, 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:54clgvtbaldridge: usage as (report-errors code, several function using multiple go blocks) ;)
10:56CookedGryphonIt would be nice if there was an approved way to catch errors with a slightly wider net
10:56CookedGryphonmakes interactive development harder as it stands
10:56tbaldridgein CLJS there's the JS console. Errors pop up there don't they?
10:57CookedGryphonyeah, and on the jvm they dump to stderr
10:57CookedGryphonbut 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:58tbaldridgeah.
10:59CookedGryphonit 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:59CookedGryphonthen i can wrap that with a log rather than letting the exception bubble up
11:01tbaldridgeCookedGryphon: 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:02tbaldridgeif you git checkout core.async and look in the impl.dispatch namespace the code is in there.
11:03CookedGryphontbaldridge: great, thanks!
11:03tbaldridgeBut 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:03tbaldridgeBut I see value in turning that into some sort of dynamic var that you can bind to any fn you want.
11:16edoloughlinIs is possible to know in a finally clause if an exception was caught?
11:16joegallowhy do you think you want that?
11:16joegallothat is, what's the actual problem you're trying to solve?
11:17`cbpyou know if an exception was caught inside the catch
11:17edoloughlinI'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:18edoloughlin...I'm logging the same variables each time
11:21edoloughlinIn 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:11goracihi 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:16goracianyone alive here )?
12:18jhnHi, 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:18clgvgoraci: 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:19clgvgoraci: you'd need to switch to desk.models.user to use the "config" alias
12:19goraciclgv: how ?
12:20clgvgoraci: in pure "lein repl" use "(in-ns 'desk.models.user)"
12:20goraciclvg: so use and then in-ns ?
12:20clgvgoraci: but if you want to remain in 'user then you could also (require '[config :as config])
12:21goraciclgv: kind weird thing
12:21clgvgoraci: not really, once you understood namespaces
12:21goraciclgv: well namespaces should be simple )
12:21clgvgoraci: grab a book or clojure-doc.org toe read up on namespaces
12:21clgvgoraci: they are
12:22goraciclgv: cause it's first place user try something
12:22technomancyjhn: clojure.contrib.* namespaces are deprecated
12:22goraciclvg: not really if i use (in-ns ..) only then it will not load even clojure.core
12:22clgvgoraci: you just have wrong assumptions about them (may be from different languages). just read up how namespaces work ;)
12:23clgvgoraci: no idea what your last message ment
12:23goraciclvg: i see how they work ) in that example
12:24goraciclvg: i mean just (in-ns..) loads nothing
12:24goraciclvg: just namespace switch
12:25clgvgoraci: yes thats true. I assumed the exectuion of your use form already loaded the config namespace
12:25clgvgoraci: gotta go...
12:30jhntechnomancy: 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:33emaphisjhn: this might help: http://dev.clojure.org/display/community/Where+Did+Clojure.Contrib+Go
12:33jhnemaphis: that's what I just linked...
12:34emaphis oh sorry, :-)
12:35emaphisjhn: well, it was last updated Dec 11th
12:36hiredmanjhn: 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:36jhnso what I'm trying to use—clojure.contrib.server-soket—has no migration deatils
12:37jhnhiredman: does that mean... it's simply not available anymore?
12:38hiredmancorrect
12:38hiredmantechnomancy has some kind of version of it somewhere though
12:38jhnhiredman: ah. I guess that explains a lot. thanks.
12:38jhnI'll look into it.
12:38technomancythere is an unofficial fork, yeah. need to put it in your project.clj
12:39hiredmanjhn: but you also need to add external dependencies to your project.clj
12:40hiredmanthe contrib stuff old or new doesn't come with clojure, so you have to tell leinigen to include it if you want it
12:40jhnI'm guessing you're referring this one: https://github.com/technomancy/server-socket
12:41hiredmanhttps://clojars.org/server-socket
12:42jhnhiredman: Thanks!
12:49mvidis there a more appropriate channel for liberator questions?
13:10jjl`_is there a clojure equivalent of let*? (macro that nests lets so that bindings can see all previous bindings in the statement) ?
13:10Bronsajjl`_: clojure's let already does that
13:10jjl`_oh. that's rather handy
13:10Bronsa,(let [a 1 b a] b)
13:10clojurebot1
13:11jjl`_:)
13:11jjl`_one thing i've found since i picked up clojure is that i keep discovering things that make me smile
13:12pmonksI keep discovering how dumb I am. #fwiw
13:13pmonksI guess COBOL didn't really set me up to learn Clojure. :-(
13:13jjl`_on the other hand, i should imagine clojure is infinitely more pleasurable to program
13:13pmonks+INF !
13:14emaphisCOBOL to Clojure is quite a jump. :-)
13:14hyPiRionI feel COBOL to anything is quite a jump these days :p
13:15jjl`_i saw that someone added object orientation to COBOL, but the syntax was absolutely hilariously verbose
13:15pmonksThough COBOL has its charms - I do love a good PIC S999 COMP-4.
13:15emaphisyeah, COBOL is pretty unique.
13:16jjl`_http://supportline.microfocus.com/Documentation/books/VisualCOBOL/Intro_to_OO_Programming_for_COBOL_Developers.pdf
13:17pmonksIt ain't COBOL if it doesn't run on System/Z...
13:17jjl`_but you can buy a plugin for visual studio!
13:18emaphislet's add functional programming to COBOL.
13:18pmonksIt also ain't COBOL if "Visual" != CICS.
13:18ystael_emaphis: what's the recursion operator called? FIXED POINT OF ?
13:19S11001001ystael: LEAST FIXED POINT OF
13:19pmonksI reckon the "COBOL way" might involve writing functions in COBOL (as programs), then "orchestrate" them using JCL.
13:19pmonksmmm……..JCL………<drool>
13:20hcumberdaleHi :)
13:20jjl`_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:20ystaelpmonks: because JCL is just like mapreduce right?
13:20pmonksummm…..
13:20hcumberdaleIs there a way to get the cnt of the current iteration in a reducer function?
13:21emaphisThere is a way to write recursive procedure in COBOL but darned if I remember how.
13:22jjl`_hcumberdale: if you mean with (reduce ..), you have an accumulator
13:22jjl`_hcumberdale: but maybe if you're looking at doing more complex things, you want to unroll it
13:23hcumberdalejjl`_: 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:23hcumberdalebut i've conj lists, no index or sth.
13:24hcumberdaleagents, atom and so on doesn't work
13:24hcumberdaleduring @ they lead to crazy values
13:25noncomwhat is the predicate to know if a value can be dereferenced with (deref) ?
13:25hcumberdaleImagine chunks of sets, I want to know what has been processed so far :) like assigning a counter to my println
13:25hcumberdalenoncom: number
13:26noncomhcumberdale: what do you mean?
13:26hcumberdalesorry, ignore my last message
13:26jjl`_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:26TimMcWhat is the desired effect?
13:27noncomi 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:27hcumberdaleTimMc: I've chunks of sets and I'm printing out what has been changed from set to set
13:28hcumberdaleThat chunks are '( { k v } { k v } ... )
13:29hcumberdaleWith the keys & intersection I can already print changes from set to set
13:30hcumberdaleBut also want to print the index of the set I'm currently processing
13:30turbofailnoncom: dunno about anything that comes standard, but you can use (instance? clojure.lang.IDeref ref)
13:31noncomturbofail: right
13:31jjl`_hcumberdale: sounds like you want to store it in the accumulator
13:31hcumberdaleahh that's the way how to deal with it in such a case..!?
13:32jjl`_it's *a* way to deal with it. whether it's the best one, i can't answer
13:33jjl`_e.g. (fn [[index acc]] ...)
13:34jjl`_i don't know what the performance impact of destructuring bind here is likely to be
13:34justin_smith,(reduce (fn [[i acc] el] [(inc i) (conj acc el)]) [0 []] (range 10))
13:34clojurebot[10 [0 1 2 3 4 ...]]
13:35justin_smiththat is the idiomatic way to do it
13:36justin_smithI guess you could use List or Record instead of a vector if you wanted to tweak performance?
13:37justin_smithbut the overhead of a two element vector should be very low
13:38jjl`_premature optimisation and all that
13:39justin_smiththe destructuring bind is not going to be significantly more expensive than indexing the vector directly, if that was the concern
13:40jjl`_i didn't expect it would be, but i've little experience in profiling clojure
13:41justin_smithjjl`_: criterium is a good way to do microbenchmarks (comparing two function implementations for example)
13:41justin_smithhttps://github.com/hugoduncan/criterium
13:41justin_smithI have it in my dev profile so I can always access it in a repl
13:41jjl`_microbenchmarks aren't a terribly reliable thing where the jvm is concerned
13:42justin_smiththe point of criterium is it runs repeatedly to warm up the jit
13:42jjl`_(but on that, timbre seems to provide a very usable implementation of the bare minimum)
13:42justin_smithI mean microbenchmark in terms of looking at a small task
13:42justin_smithand it gives a statistical overview of the range of timings
13:42mabeshas anyone used a migration library in clojure (for SQL DBs) that they have liked?
13:43mabesI have found a few but I'm looking for experience reports...
13:43technomancyclojurebot: clojars migrations?
13:43clojurebotExcuse me?
13:43technomancydang it I feel like I've taught him this like three times
13:43jjl`_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:44technomancymabes: skip the libs, do something like this: https://github.com/ato/clojars-web/blob/master/src/clojars/db/migrate.clj
13:44justin_smithjjl`_: check out criterium, I think the way it does things should address your concerns
13:44jjl`_mabes: fwiw, i gave up trying to do it in clojure and use sqitch (which is really quite nice)
13:44jjl`_justin_smith: i'll take a look. thanks.
14:14HoloIRCUser1
14:15hcumberdaledoes Korma support db2
14:15hcumberdaleanyone every tried?
14:15hcumberdale every = ever
14:17jjttjjI know this isn't #datomic, but since no one's answering there I figured I'd try here:
14:18jjttjjIf 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:24hiredmanjjttjj: that is two things, a chore which is sort of a class of actions, and instances of that class
14:25hiredmanjjttjj: I dunno what #datomic would say, but I think a good place to start would be chore entities and chore performance entities
14:33jjttjjOk cool
14:38jjl`_what's the idiomatic way of partial'ing a function where you want to provide an argument that isn't the first?
14:40seangrovejjl`_: Anonymous functions
14:40jjl`_i expected that would be the answer :(
14:40jjttjj,(map #(conj {:a 1} %) [[:b 2] [:c 3]])
14:40clojurebot({:b 2, :a 1} {:c 3, :a 1})
14:40AimHereif it's the last function, you might tweak something with ->>
14:40AimHereBut that's probably not overly idiomatic
14:41seangroveThere's another helper library somewhere that kind of beefs up partial, but I don't recall its name
14:41jjl`_in this case it's a two arg func. i was wondering if there's an analog to haskell's flip
14:41jjl`_not that i couldn't write one in a couple of lines
14:41technomancyrpartial would be really nice
14:41technomancyevery so often I wish I had it
14:41justin_smithI think flatland/useful has flip
14:42jjl`_(which would be) (defn flip [f] (fn [a b] (f b a)))
14:42seangrovejjl`_: Sometimes as-> is appropriate as well, but probably not in the case you're using a partial
14:43jjl`_in this case i've just written it explicitly, but flip made for some quite elegant code in haskell
14:43seangrovetechnomancy: Yeup.
14:45justin_smithjjl`_: more generally (fn [f & args] (apply f (reverse args)))
14:46pyrtsaI think the general case would be just (fn [a b & more] (apply f b a more)).
14:46justin_smitherr I mean (fn [f] (fn [& args] (apply f (reverse args))))
14:46pyrtsaDoh, add f of course.
14:46jjl`_API design: it's hard :)
14:46pyrtsaCorrect. :)
14:47justin_smithpyrtsa: that is useful if you only want to flip the first two, rather than flip all
14:48pyrtsaOkay, I see your point. Flipping them all makes sense for something like (comp f g h).
14:48pyrtsa..maybe. :)
14:48jjl`_matter of taste perhaps
14:49pyrtsaI 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:50jjl`_flip-2, flip-all
14:50pyrtsaHaskell conveniently avoids that yak shaving by not introducing variadic functions. :)
14:50jjl`_and yet we're programming clojure. obviously it was a good choice.
14:51augustlanyone 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:51pyrtsaFWIW, 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:51pyrtsajjl`_: Yes. :)
14:52jjl`_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:53augustljjl`_: I'm using datomic, so I wan to put the ID of the item to be indexed and the daotmic T there
14:53augustlso I would like the old one to be removed :)
14:53augustlbut interesting point..
14:53jjl`_i'll be interested in the solution you come up with to solve that issue :)
14:54augustljjl`_: very interesting point actually ;)
14:56jjl`_resource management: also hard :)
14:58jjl`_(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:58bhenrythe 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:58bhenryis that an issue that is known?
14:59Apage43also: what do you do if the job is *currently executing*?
15:00jjl`_CompilerException java.lang.RuntimeException: Unable to resolve symbol: defn in this context, compiling:(quarter/core.clj:5:1) <-- ehehehe
15:09augustljjl`_: 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:09augustldidn't think this through ;)
15:24`cbpwhat the, why does emacs have "add to itunes as spoken track" on the mode menus
15:24`cbpemacs pls
15:25bitemyapp`cbp: lolwut
15:26jjl`_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:26TEttinger,(doc clojure.core//)
15:26clojurebot"([x] [x y] [x y & more]); If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators."
15:26jjl`_oh. fair enough
15:27TEttinger,(doc /)
15:27clojurebot"([x] [x y] [x y & more]); If no denominators are supplied, returns 1/numerator, else returns numerator divided by all of the denominators."
15:27TEttingersurprised that one works
15:27seangrove`cbp: Don't have it here.
15:28`cbpbitemyapp: the mode menus above the minibuffer have an option at the end that says "add to itunes as a spoken track"
15:28seangrove,clojure.core//
15:28`cbpIt opens itunes then gives an error :P
15:28clojurebot#<core$_SLASH_ clojure.core$_SLASH_@776482>
15:28jjl`_TEttinger: hrm, but i can't seem to do that if i (:require [clojure.core :as cc]) and then try cc//
15:28seangroveI believe it's special-cased though
15:29`cbpit is special cased
15:29`cbpI don't think you can do that
15:29`cbpmaybe its the aftermath of the homebrew invasion
15:30seangroveWow, I must have a much lower priority than TEttinger
15:30TEttingereh?
15:30`cbpyou have negative karma
15:33bitemyapp$karma seangrove
15:33`cbpclojure.core// and / are treated specially by the parser, amalloy taught me that
15:33TEttingerlazybot still has not returned, odd. hail, Raynes, destroyer of netsplits!
15:33seangrove,(inc 1)
15:33clojurebot2
15:34seangroveHrm, I wonder if that's it. Bummer.
15:35TEttingerseangrove, I see clojurebot replying to you in under a second from here
15:35TEttingerhooray!
15:36`cbpyou summoned it!
15:36TEttingerwhat is this power?!?!?
15:36seangroveOr maybe clojurebot just waits until TEttinger says something to return a value :)
15:37TEttingerwhat freenode server are you on?
15:38seangroveRelativistic effects, obviously.
15:38seangroveOne of us is traveling much closer to the speed of light
15:39TEttingerdo you have ctcp responses disabled, seangrove? "/ctcp seangrove time" isn't returning anything
15:39seangrovesendak
15:39gfredericks,'#'#'#'foo
15:40clojurebot(var (var (var foo)))
15:41gfredericks,'#'[(a b c)]
15:41clojurebot(var [(a b c)])
15:42seangroveTEttinger: Not sure, just using the default erc config, as far as I know. Not the end of the world in any case :)
15:42TEttingerit took over 2 minutes to get here...
15:42TEttingerit did get there though
15:43TEttingerI think our servers must have some issue between the two, and yours to clojurebot, but not mine to clojurebot?
15:43TEttingerthe magic of IRC
15:44pcnThe magic of distributed systems
16:00kilernI 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:00kilernIn 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:04edw,(+ 1 1)
16:04clojurebot2
16:05edw,(+ *1 1)
16:05clojurebot#<ClassCastException java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to java.lang.Number>
16:18logic_progin 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:26modulushi 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:26modulusany ideas how to fix this?
16:30modulusSpeicifically I get:
16:30modulusMessage: 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:34hyPiRionmodulus: http://seancorfield.github.io/clj-time/doc/clj-time.coerce.html <- See from and to sql.timestamps
16:34TimMcTEttinger: 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:37modulushyPiRion - thanks
16:39akonnyhow do you automatically assign new entity-id in datomic?
16:40modulushyPiRion - any clue why this works without coercion on sqlite3?
16:45BobSchackakonny you send over temp id's which are then converted to entity id's
16:47logic_progdumbass 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:47akonnyWell I keep getting this: IllegalArgumentExceptionInfo :db.error/datoms-conflict Two datoms in the same transaction conflict:
16:47hyPiRionmodulus: 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:48akonnywill it help to give the entities different id's?
16:50brehautlogic_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&amp;redirectslug=Web%2FGuide%2FDOM%2FUsing_full_screen_mode#Getting_out_of_full_screen_mode
16:50logic_progbrehaut: awesome, thanks for helpful response! (I was fearing "go to #javascript") :-)
16:51brehautlogic_prog: it was my polite way of saying always check MDN first ;)
16:51logic_proglol
16:51BobSchackakonny how are you getting the id's for you entities?
16:51brehautlogic_prog: seriously though, MDN is an excellent resource. they often have shims for various APIs and good compatibility tables too
16:52logic_progbrehaut: 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:52akonnyBob
16:52akonnyit works now.
16:53brehautlogic_prog: w3school is a last resort for me. its information tends to be a combination of antiquated, incomplete or wrong
16:53modulushmm 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:53akonnyI'm just confused: what does :e and :a mean?
16:54gfredericksmodulus: ideally this should be possible
16:55modulusI'm hoping so, but no idea how to go about it.
16:55gfredericksI think I might have patched korma to allow for custom serialization
16:55S11001001modulus: jdbc has a thing that lets you write those contramaps, no idea if korma exposes that
16:55gfredericksS11001001: last I checked korma doesn't even use java.jdbc in that respect
16:55gfredericksit generates its own sql
16:56BobSchackakonny where are you seeing :e or :a (also #datomic would be a better place for answers)
16:56gfredericksI guess it does the ? parameterization
16:56modulusi still find it pretty puzzling that the sqlite3 driver supports this
16:56gfrederickshttps://github.com/korma/Korma/blob/master/src/korma/sql/engine.clj#L139
16:57akonnythank you
16:57gfredericksmodulus: there's an ISQLValue protocol in java.jdbc
16:58gfredericksif 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:58gfredericks(which it could easily not)
16:59gfrederickshttps://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc.clj#L272
17:00modulushmm thanks
17:01jowagHi, why there are two fns for item removal (disj and dissoc), and not just one fn working with both maps and sets?
17:05modulusso what am i supposed to extend, date-time with the ISQLValue protocol?
17:05gfredericksjowag: are there situations where you want to write code that doesn't care whether it is dealing with a map or a set?
17:05gfredericksmodulus: yeah
17:05modulusI'm quite new so haven't used protocols much.
17:06gfredericksmodulus: right below the defprotocol statement it extends to object and nil, so you could mirror that
17:07brehautdisj is the inverse of conj, dissoc is the inverse of assoc.
17:07technomancybrehaut: conj can do assoc though
17:07brehautjowag: associative structures tend to also be conjable, but not all conjable structures are associative
17:07technomancyand the inverse of conj is rest
17:07technomancyor... pop
17:08hyPiRionthe inverse of conj doesn't exist
17:08brehauttechnomancy: is it? what if you conj onto an ordered collection
17:08technomancy"it depends"
17:08jowaggfrederics: not really, I was just going through the core API and this caught my eye, 'cause they do the very similar thing.
17:09brehautordered? i think i mean sorted
17:09brehautso im definately wrong, but i just dont know exactly how ;)
17:10modulusright, i'm trying to find out what jdbc is used by my korma release
17:10S11001001technomancy: I don't think anything will work as its inverse; there isn't enough information
17:10hyPiRionbrehaut: 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:10hyPiRionThe inverse of conj is (run
17:10gfredericksjowag: the whole point of it is a giant nerd trap for technomancy/brehaut/hyPiRion/S11001001
17:11jowagthere is not inverse of conj, you cannot e.g. disj a vector
17:11bitemyapphas anybody here poked around with clojure-py?
17:11technomancygfredericks: pwn'd
17:13hyPiRionThe closest is maybe, (run* [q] (== (conjo q elt) coll))
17:13hyPiRionif conjo existed
17:13bitemyapptim__: would it be sensible to try to repurpose clojure-py's reader as a parser for edn data?
17:14tbaldridgebitemyapp: perhaps, does this not work? https://pypi.python.org/pypi/edn_format
17:14modulusmaybe stupid question but where does lein puts deps or how can i see the version of a given dep?
17:14bitemyapptbaldridge: lol no, all the edn parsers (I've seriously tried all of them) in Python are broken and terrible.
17:14bitemyapptbaldridge: we've been patching and working on edn_format at work, but it's pretty bad.
17:14bitemyappa map inside of a set breaks. a string with an escaped quote breaks. everything breaks.
17:15bitemyappI'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:15gfredericksmodulus: try `lein deps :tree`; placement is in ~/.m2 but that's global
17:15bitemyapptbaldridge: this is making it very hard to use Datomic with a Python client.
17:15tbaldridgeYou 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:15brehautbitemyapp: does it handle lists as keys of maps?
17:16bitemyapptbaldridge: I don't really want to get rid of the hashable data types
17:16bitemyapptbaldridge: what's this first/next stuff, what type does the reader expect?
17:17bitemyappbrehaut: you're more likely to get me to test something by sending the literal.
17:18brehaut{[1 2] 3}
17:19tbaldridgebitemyapp: I'd just use clojure.lang.lispreader.readString
17:19bitemyappthank you.
17:19brehautif it uses python lists for vectors and or lists and dicts for maps that is unlikely to work
17:21bitemyappbrehaut: that's why I've been implementing immutable colls
17:21tbaldridgebitemyapp: someone should just write something like this for Python https://github.com/relevance/edn-ruby/tree/master
17:21bitemyappbrehaut: it seems like clojure-py is the better solution.
17:21tbaldridgenotice the use of generative testing
17:22bitemyapphum, my test string that breaks things breaks clojure-py's reader too
17:22bitemyappsad-face :(
17:22bitemyapptbaldridge: yeah this is clearly a good place to use generative testing.
17:22tbaldridgethe ruby parser uses a parser generator + generative testing to make the computer do much of the heavy lifting
17:22bitemyapptbaldridge: 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:23tbaldridgeyeah, I can see that.
17:23bitemyapp"""{: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:23bitemyapptbaldridge: ^^ that string breaks clojure-py, edn_format, edn, pyclj, etc.
17:24bitemyapp*** ReaderException: Invalid number: 5-1-13 at line 1
17:27modulushmm no joy, korma uses a 0.2 version of the jdbc adaptor
17:29moduluswell, i'll try to sort this one out tomorrow i think. thaks hyPiRion, S11001001 and gfredericks
18:13mikerodwhen 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:13mikerodSince every form seems to get its own DynamicClassLoader
18:14mikerodI 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:15nDuffmikerod: unless my memory badly fails me, it's not creating a new DynamicClassLoader when you define a new type within an existing namespace.
18:16nDuff...so, my memory was indeed failing me.
18:16mikerodnDuff: 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:16mikerodI have printing the ClassLoader parent chains
18:16mikerodthey do not intersect
18:17mikerodexcept at the App ClassLoader
18:17mikerodand the Thread/currentThread getContextClassLoader has its own stack of DynamicClassLoaders with no intersection of these defrecord generated classes.
18:17mikerod*besides at the App ClassLoader*
18:18mikerodat this point, I think it must just be magic that does it :)
18:23coventryWhat's the right way to compare #inst's? This is super confusing: https://www.refheap.com/22025
18:24justin_smithcoventry: they are java.util.Date instances, so maybe compare their getTime
18:24justin_smith,(= (.getTime #inst "2013-09-12T23:35:17.000000000-00:00") (.getTime #inst "2013-09-12T23:35:17.000000000-00:00") )
18:24clojurebot#<SecurityException java.lang.SecurityException: denied>
18:24justin_smithwell that returns true
18:25justin_smithand .getTime is a lossless translation to / from Date
18:25hyPiRionwell
18:25hyPiRionsame applies for #inst-read values
18:25hyPiRion,(= #inst "2013-09-12T23:35:17.000000000-00:00" #inst "2013-09-12T23:35:17.000000000-00:00")
18:25clojurebot#<SecurityException java.lang.SecurityException: denied>
18:26justin_smithbut not neccessarily for dates coming from elsewhere
18:26justin_smiththough they could still print as an #inst
18:26justin_smithbut .getTime will be =
18:26justin_smithbetween them
18:26hiredmanmikerod: classloaders form a hierarchy of parent and child classloaders, and the dynamic classloaders form a chain of parent/child classloaders
18:26coventryjustin_smith: Thanks, that comparison works.
18:28justin_smithcoventry: np
18:28mikerodhiredman: the DynamicClassLoader seems to be fairly minimal, so I'm surprised how I can't see how this works
18:29nDuff...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:29hiredmanmikerod: because the classloader delegation is baked in, so it just inherits that behaviour from urlclassloader
18:30mikeroddefineClass 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:30mikerodhmmm
18:31hiredmanthe big change dynamic classloader makes is to change the order of where classes are looked for
18:31mikerodin your own cache => then your parent
18:31mikerodis there more to it?
18:31hiredmanright
18:32hiredmanmost classloaders do the reverse, parent first and if that fails then the child will look for the class
18:32mikerodyes, that was my understanding of the standard flow
18:32mikerodI've read a lot of articles on "how class loaders" work and all that fun
18:33mikerodit just seems to me taht a parent DynamicClassLoader is able to find a class that it's *child* made
18:33mikerodunless 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:33hiredmanwhy do you think that?
18:33mikerodIf I do `(defrecord MyType [])`
18:34mikerod(def m (->MyType))
18:34mikerod(.getClassLoader (class m))
18:34mikerodit seems that a new class loader was created
18:35mikerodfor that class, but the context classloader of the Thread does not have that new class in its ancestors
18:35jaccarmacHello!
18:35jaccarmacFirst time here. On Emacs. Quick Q: Is Cider any good?
18:35hiredmanmikerod: the context classloader doesn't play in to it
18:35mikerodUnless 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:35nDuffjaccarmac: Quick answer: Yes.
18:35mikerodcider == (former) nrepl.el right?
18:35nDuff*nod*.
18:35jaccarmacnDuff: Thanks. I like it so far. Seems a lot like SLIME, which is fantastic.
18:36jaccarmacmikerod: Yes.
18:36hiredmanmikerod: the compiler evals a form it starts off by creating a new classloader with the previous classloader as its parent
18:36bitemyapptbaldridge: the situation with parsing edn data is bad enough that we're considering a convention for expressing edn data in JSON.
18:36mikerodjaccarmac: then I'd say yes too
18:37mikerodhiredman: that makes a lot of sense, I just have never seen how this is done
18:37hiredmanthe current loader is kept in clojure.lang.Compiler/LOADER which is a var
18:37mikerodI guess that's what I'm missing
18:38mikerodI was seeing this RT#baseLoader()
18:38mikerodif the LOADER.isBound() it is used
18:38mikerodthe context classloader is the fallback
18:38hiredmanclojure 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:39mikerodI 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:40hiredmanthis only if you are evaling forms one by one at the repl
18:40mikerodSo if you do a (DynamicClassLoader.) from the system classloader, it will use the Compiler.class class loader as the parent
18:41mikerodif you have some non-system classloader set as the context classloader of the current thread, it'll use that
18:41hiredmanthat question doesn't make sense
18:41hiredman"from the system classloader"
18:41mikerodClassLoader.getSystemClassLoader()
18:42hiredmanmikerod: the context classloader is only used if you have *use-context* classloader as true, which it is not by default
18:42mikerodI'm referring to the constructor logic @ ClassLoader.getSystemClassLoader()
18:42mikerodsorry, @ https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/DynamicClassLoader.java#L35
18:43mikerodI think I have something broken with dynamically loaded classes. I suspect it where I am calling this no arg DynamicClassLoader from.
18:43hiredmansure
18:43hiredmanI don't think the clojure runtime ever calls that arity
18:43hiredmanwhy are you constructing dynamicclassloaders?
18:45mikerodComplicated, 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:46dotemacsstruggling 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:46hiredmanmikerod: sounds terrible
18:46mikerodIt 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:46mikerodhiredman: yes, indeed. I'm trying to come up with a better approach. :)
18:47hiredmanmikerod: aot compile everything, that drools can just look it all up via the system classloader
18:47mikerodthat is one possible idea I had for this
18:47mikeroddefinitely sounds safest
18:48hiredmandotemacs: methods on objects are not functions
18:48hiredmandotemacs: resolve takes a symbol and looks up the var with that symbol name, methods don't live in vars
18:48hiredmanthey are not values you can apply like that
18:48dotemacsso how can I apply it ?
18:49mikerodhiredman: thanks for the feedback, it has certainly been helpful
18:49hiredmanin your example `(.getTitle ...)
18:50hiredman,(macroexpand '(.foo bar))
18:50clojurebot(. bar foo)
18:50hiredman,(macroexpand '(.foo bar 1 2 3 4))
18:50clojurebot(. bar foo 1 2 ...)
18:50dotemacshiredman: thats fine, but what I really wish to figure out is get a string, convert it to a method and call it
18:50justin_smith.getTitle is not a symbol
18:50dotemacsah, ok
18:50hiredmandotemacs: you'll need to read the docs on the jaba reflection api
18:51dotemacshiredman: cool, thanks
18:51technomancytee hee
18:51justin_smith"bring me the object heirarchy and the class loader"
18:51turbofailyour jedi reflection tricks will not work on me!
18:53technomancyI 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:53technomancy=D
18:53scottjstaggered keyboards ftw
18:54justin_smithbefore I used a split keyboard I was in the habit of typing b with my right index finger
18:54justin_smiththat led to so many typos when I upgraded to split
18:54technomancyI suspect this is due more to the matrix alignment than the split, but maybe that's just me
18:54Profpatsch Urgh. How do I do a vector of a vector?
18:55Profpatsch10000x10000
18:55ProfpatschI thought about (repeat 10000 (repeat 10000 (rand-int 100)))
18:55justin_smiththat is sequences but not vectors
18:55scottjtechnomancy: I just noticed that Swiftkey, the most popular alternative android keyboard (I think), uses a half staggered and half matrix layout
18:56ProfpatschBut that gives me the same int for every item.
18:56justin_smith,(repeatedly #(rand-int 100))
18:56seangrovetechnomancy: New keyboard?
18:56clojurebot(12 51 46 77 32 ...)
18:56technomancyscottj: software keyboarlds are a disgrace to the entire industry
18:56scottjseangrove: ergodox
18:56scottjseangrove: but his dad and son put it together for him
18:56technomancyseangrove: https://secure.flickr.com/photos/technomancy/11437911574/
18:57technomancyheh
18:57technomancyscottj: just the caps on the left half =)
18:57Profpatschjustin_smith: Is (rand-int) a side-effect?
18:57ProfpatschOh, wow, of course it is.
18:57justin_smithrepeat only evaluates the arg once
18:58seangroveProfpatsch: With great foresight and care
18:58justin_smithrepeatedly evaluates it each time
18:58ProfpatschSo ,,(repeatedly (fn [] repeatedly #(rand-int 100)) should work.
18:59justin_smiththat looks about right
18:59justin_smithwell maybe give number args to the repeatedly calls :)
18:59justin_smithunless you want nested infinite laziness
19:00justin_smith,(repeatedly 3 #(rand-int 100))
19:00clojurebot(59 76 91)
19:01ProfpatschWhoo.
19:01seangrovetechnomancy: You've got a bit of collection of keyboards at this point, right?
19:02technomancyseangrove: I suppose. this is actually my first mechanical one though
19:03scottjtechnomancy: are you planning to pantsify them?
19:03technomancyscottj: it's too much hassle when I need to leave my desk for nature's call, etc
19:03scottjthem=the ergodox
19:04technomancyalso I need to be able to use them at coffee shops etc
19:04scottjtechnomancy: having made my own pair, I totally understand :)
19:04technomancythinking of building a mount for them that can sit underneath the surface of the desk at a serious tenting angle
19:04technomancyoh yeah? nice
19:04technomancyscottj: pics?
19:05technomancyis that for the freestyle too?
19:05scottjtechnomancy: nope, long time ago, returned them after a short time. really needed to be wireless
19:06technomancyhuh. wires weren't a problem for me.
19:06scottjtechnomancy: I used a hanging from a belt apparatus
19:06technomancyoh, didn't you have trouble with stability?
19:07scottjyeah
19:07technomancyI found having them even just not completely tight on my thighs would cause them to wander too much for touch-typing
19:33ProfpatschOkay, 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:35ProfpatschIs it because reduce can’t use lazy sequences? But that would be dumb.
19:36ProfpatschI create a lazy 2d-array of n random numbers square in `benchmark` and then call the function f with it and time that.
19:37ProfpatschWhich in this case is a simple function that finds the maximum in the 2d-array and returns it.
19:37hiredmanProfpatsch: you should use criterium for benchmarking, and you are missing some parens
19:38hiredmanhttps://github.com/hugoduncan/criterium
19:38ProfpatschNah, 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:39ProfpatschAnd because I need to learn Clojure. Which apparently I’m way too dumb to use. >.>
19:40ProfpatschWhat’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:40AimHere(fn [] repeatedly n #(rand-int 100))) is probably your mistake
19:40AimHereI reckon you want a left parens before 'repeatedly'
19:41ProfpatschOh gosh, you’re right.
19:41ProfpatschWhy doesn’t the thing blow up in my face then?
19:41technomancyit's totally valid to treat a function as a value that isn't called
19:42AimHereWell v is still a well-formed sequence isn't it, just a sequence of gibberish
19:42technomancya linter would catch it though
19:42AimHereIt's the kind of error that those static typing dweebs would smugly sneer at
19:44ProfpatschBut why do I get an ISeq Exception? Why can it somehow pass repeatedly, which is a function symbol?
19:45ProfpatschOr can it pass *because* repeatedly is a defined symbol?
19:45AimHereIsn't it getting 'repeatedly' and then trying to treat that as a seq
19:45hiredmanProfpatsch: because somewhere you are trying to treat the result of that function as a seq, but it is returning a function
19:45hiredman,(seq +)
19:45clojurebot#<ExceptionInfo clojure.lang.ExceptionInfo: Don't know how to create ISeq from: clojure.core$_PLUS_ {:instance #<core$_PLUS_ clojure.core$_PLUS_@147fda0>}>
19:45hiredmanneat, exceptioninfo, that's new
19:46ProfpatschOooh, and because it is a lambda it doesn’t have a name.
19:46ProfpatschSo it *would* show the name of the function if it had one?
19:46Profpatsch(+ "test" 4)
19:46Profpatsch.(+ "test" 4)
19:46Profpatsch,(+ "test" 4)
19:46clojurebot#<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number>
19:46ProfpatschGosh, sorry for spamming.
19:48ProfpatschAnd, sudden realization: It isn’t showing glibberish, but the exact function. Just separated by `$` because that’s the JVM-internal representation.
19:49ProfpatschIn 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:50ProfpatschI should try to understand error messages better. But that’s what I promise myself every time …
19:58technomancywell... assuming clojure error messages are not gibberish is actually not such a great strategy
20:03ProfpatschYes, they are. Wouldn’t it be easy to parse these to something useful on first glance?
20:04ProfpatschI mean there seems to be a logic behind them and some information.
20:04ProfpatschThese are still the raw JVM error messages, right?
20:05technomancyusability is not generally considered a priority by the core developers
20:27dotemacsIs using memfn, the way I use it here OK: https://www.refheap.com/22029 ?
20:39allenj12hey 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:39allenj12more specifically in the functions args
20:40justin_smiththe same syntax as in a let block
20:40bitemyapparrdem: found daylight servers
20:40justin_smith,((fn [[a b c]] (+ a b)) [2 3 4])
20:40clojurebot5
20:43allenj12hmm but for defn i cant due say (defn [[alpha beta gamma] input])
20:43allenj12do*
20:45allenj12o wow wait im silly i see it now
20:45allenj12thanks!
21:20dsrxwait, there are exercises in the joy of clojure?
23:06{[^-^]}how do I use maven dependencies in leiningen
23:09xeqi{[^-^]}: [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:54TEttinger{[^-^]}, uh... you may encounter performance stuff from java defaulting to unboxed data and clojure defaulting to boxed (except in arrays)
23:54TEttingerI need to fix my game that indirectly uses OpenGL, because performance is bad on my game logic stuff
23:55TEttingerbut 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)