#clojure logs

2011-08-14

00:11solussdIs there anything like doseq that executes each body in parallel, e.g. a pdoseq ?
00:15drewrsolussd: pmap can have side-effects
00:17solussddrewr- pmap holds onto the head though. I'm not returning anything, I just want to wait until all bodies have executed… guess I have to hold on to something if I want to know. :D
00:18amalloyeach body?
00:20amalloysolussd: you can slap a dorun on front of a pmap if you want
00:21drewror you could wrap each body in a future and let the threadpool throttle it out
00:21drewryou'd get some parallelization there
00:21solussdif I use futures, how can I join? I need to wait until all the futures have executed before I continue
00:22drewrI thought that's what you wanted
00:22drewrbut they won't block anyway
00:22solussd(doseq [item items] (future #(do something item))) would return immediately. I'd like to block until all those futures finish
00:23drewryou could use a latch/await
00:23solussd,(doc latch)
00:23clojurebotExcuse me?
00:23solussd~botsnack
00:23clojurebotThanks, but I prefer chocolate
00:23drewrhttp://download.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html
00:23amalloydrewr: that's so complicated. is there something wrong with pmap/dorun, or pcalls?
00:24drewrno, just giving options
00:24drewrthere's also delays
00:25amalloydelay solves a different problem; how would you use it for this?
00:25solussdguess I might as well use pcalls- a throwaway seq of nil return values i lightweight enough. considering any other scheme would require some other way to monitor the completion of each thread/future
00:26solussd*is
00:28drewramalloy: no, you're right
00:30solussdwonder how much memory a seq of 5 million nils takes up. :D
00:31amalloyabout 64 bytes at any given time :P
00:31solussd?
00:31drewrI didn't know about pcalls
00:32amalloysolussd: it's a lazy sequence that can get garbage-collected whenever
00:32drewrwhy doesn't this work?
00:32drewr,(pcalls (fn [] 1))
00:32clojurebot(1)
00:32drewr?
00:32drewrit gave me an exception locally
00:32amalloyso it's not like having a zillion of them takes up a bunch of memory
00:33solussdso, a map wrapped in a dorun could possibly be being deallocated as it is being churned out?
00:33amalloy64 bytes is a number i made up, but the point is that it doesn't "take up" any memory. it might use some, if nobody else wanted it
00:34solussd,(dorun (pmap #(* 2 %) (range 1000000)))
00:34amalloy&(nth (map inc (range)) 1e7)
00:34clojurebotExecution Timed Out
00:34amalloyaw
00:34lazybot⇒ 10000001
00:35solussdlazybot?
00:35amalloysolussd: pmap is costing you time there
00:35amalloymaking all those threads is way more expensive than multiplying by two
00:35solussdsure- but for what I'm actually doing it is worth it. :D
00:36solussdmore like this: (dorun (pmap #(process-items %) (filter #(not= % p) (keys prefs)))) and 'items' for each key could number in the thousands
00:38amalloysolussd: #(process-items %) is just process-items
00:38amalloyand (filter #(not= % p) x) is (remove #{p} x)
00:38solussdah, right-- I was using pcalls
00:38solussddidn't know that second though, thanks
00:40solussdhm, that made it faster
00:40amalloywhat, my changes? i doubt that
00:41solussdwell, I'm testing on very small numbers of items
00:41solussdmaybe not creating the extra anonymous functions every time?
00:42amalloysolussd: that's a misunderstanding of how closures work. it doesn't have to create any functions at runtime
00:43solussd#(…) doesn't create a function?
00:43amalloysure it does
00:43amalloyat compile time, once
00:43solussdoh geez, right
00:44amalloyif the function is a closure, at runtime it needs a single constructor call to pass in the values it's closing around
00:44amalloybut nothing expensive like compilation
00:44solussdall this clojure stuff makes my day job less fulfilling. :/
01:07jliI don't understand how to dynamically redefine clojure code in a running program
01:08amalloydon't
01:08jliwhy not? it's neat :/
01:08amalloyso is goto
01:08jlibut it's REALLY neat
01:09amalloy*chuckle* WELL then, that's a convincing reason
01:09jliI got it working with Rich's ant simulation, but I can't get it to work with a tiny ring app
01:10jliI'll redefine a part of the app, but it seems to keep calling the same old code
01:11amalloyare you talking about having the program modify itself, or you jump in at the console and type a (def) yourself?
01:11amalloyit's only the former that's a terrible idea
01:12jliI included swank in the app, and I'm connected with slime
01:14amalloyyou probably want to start-jetty with #'myfn, not myfn
01:15jliohhh, hmmm
01:16jliyay, that works
01:20jlithanks amalloy
01:20amalloythe point is that the var is a mutable pointer to a function. when you send jetty "myfn", you deref the pointer and send it the current value. when you pass #'myfn, you give it the pointer
01:20amalloyand, when called as a function, the pointer derefs itself
01:22amalloythe last point is what makes the whole trick work
01:22jliright, awesome
01:22amalloy&(#'inc 1)
01:22lazybot⇒ 2
01:23jliso, why shouldn't I do this now? :)
01:23amalloyfeel free. but what you asked for was vague, and usually people who say that mean something dumber
01:24jliwhat's that?
01:24amalloya program that modifies its code at runtime
01:25amalloythey generally have wild fantasies of magic self-teaching programs based on a misunderstanding of "code is data"
01:25jlicurious
01:26jliI guess you could do that by calling def within functions?
01:26amalloy*nod*
01:27amalloycertainly that sort of thing is possible
01:27amalloythey generally combine it with eval to construct the functions at runtime. i typoed that as ruintime, and that seems appropriate
01:28amalloyANYWAY, short answer: redefining is great when it's something you do manually during development, as you're doing
01:28jliwow, "ruintime" - I'm definitely going to start using that
01:31amalloyruintime: when management takes the gorgeous program you wrote and replaces it with something that breaks all the time?
01:34jliit has lots of applications
01:38amalloybtw i just copyrighted ruintime. for $20 i'll let you say it
01:39jli:(
01:41Hodappgoddammit amalloy
01:44amalloywhat've i done now?
02:17solussdIf I have a map of maps, e.g. {:a {:x 3 :y 4} :b {:z 5}}, and I will be updating the inner maps frequently and adding new maps to the outer map frequently, and I want to use transients… how do I 1. use (contains? outer-map some-key) to check if I need to create a new inner map transient if the key doesn't exist in the outer map; 2. turn the inner transient maps into persistent maps, followed by the outer map (that way I can take advan
02:17solussdof assoc! when reassigning the new persistent inner maps to the outer map keys) ?
02:19solussdof course, I'm doing this all within one function-- the function takes a map of maps and pulls some of the inner map keys out into an outer map and moves some outer map keys into inner makes. It's a map transform of sorts.
02:22amalloysolussd: i don't think you really want to be using contains
02:22solussdwhy's that?
02:23amalloy&(update-in {:x 1} [z] (fnil assoc! (transient {})) :a 10)
02:23lazybotjava.lang.Exception: Unable to resolve symbol: z in this context
02:23amalloy&(update-in {:x 1} [:z] (fnil assoc! (transient {})) :a 10)
02:23lazybot⇒ {:z #<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@1d3981c>, :x 1}
02:24amalloythat's probably not the most efficient way you could do it; probably faster is something like ##(update-in {:x 1} [:z] #(assoc! (or % (transient {})) :a 10))
02:24lazybot⇒ {:z #<TransientArrayMap clojure.lang.PersistentArrayMap$TransientArrayMap@fdb3e8>, :x 1}
02:24solussdneat
02:24solussddidn't know about fnil
02:26amalloythe latter is just a reimplementation of fnil that avoids creating the new transient unless you're going to use it
02:26solussdignoring my implementation for a bit, what I'm trying to accomplish, efficiently, is a transform like this: {:a {:x 3 :y 4} :b {:x 2 :y 8}} -> {:x {:a 3 :b 2} :y {:a 4 :b 8}}
02:27solussdwith many more kvs in the inner and outer maps
02:28solussdand not all outer keyvals will have the same inner map keys
02:28amalloyyou're just writing an index function, then? check out clojure.set; it has a lot of stuff that's at least similar to this
02:42solussdso, if the outer map is a transient as well, how do I iterate over the inner maps and turn them into persistent maps?
02:43solussd(no help from clojure.set afaict)
02:44amalloytransients don't really support sequential access
02:44amalloybecause seqs are immutable views over immutable data; if the underlying data can change, so can that view
02:45solussdwell, my inner maps change the most while building the data structure, so I guess that's good enough.
02:47amalloy&(let [m {:a {:x 3 :y 4} :b {:x 2 :y 8}}] (apply merge-with into (for [[outer inner] m, [k v] inner] {k {outer v}})))
02:47lazybot⇒ {:y {:a 4, :b 8}, :x {:a 3, :b 2}}
02:48amalloynow you can stop worrying about the internals and all the transients :P
02:50solussdwell that sure is elegant
02:54solussdit's so simple, but I don't think I would have thought of, or even looked for merge-with
02:54solussdthanks!
04:00jliwhoo, I just threw a memoize in front of the wikipedia-scraping portion of my little webapp, reloaded live, and it's way faster. go clojure.
04:18amalloyjli: if you use a permanent memoization cache, you'll run out of memory before too long, i imagine
04:24jliamalloy: yeah, that's on the todo
04:24jliare there sweet things in core or contrib for LRU caches and stuff?
04:37amalloyno, but it's a topic that excites people all out of proportion so there are a number of non-core libraries to do it
04:39amalloylike fogus's recent "unk". haven't used it, myself
05:00jliI don't understand how exceptions in clojurescript are supposed to work, and I can't find very helpful docs on it
05:00jliit looks like (try ... (catch x y)) ends up compiling to "<exception> instanceof x"
05:01jliwhat is a valid value for x then?
05:02jlioh, I guess it's an Object.
05:13justinus_M-x clojure-jack-in not working for me after opening emacs in new lein project
05:14justinus_it just says "Starting swank server....."
05:17justinus_I just followed the steps under the Usage section https://github.com/technomancy/swank-clojure
06:24raekjustinus_: try running "lein swank" in a terminal. hopefully this will give you some kind of error message
07:01justinus_"lein swank" works fine...and I am able to "M-x slime-connect"
07:04justinus_is there any advantage of using "jack-in" over "slime-connect"?
09:10pyrrecord fields are immutable, just like map fields, right ? (i.e: no one can modify them from within protocol implementations)
09:11hiredman~ping
09:11clojurebotPONG!
09:12raekpyr: yes, it's the same as with clojure's other data structures. the "modifying" operations have to return a new object instead of changing it in place.
09:22pyrraek: ok cool
09:23pyrchanging some defmultis to defrecord + defprotocol
09:58dabdwhy does (apply str (interpose "," ["ab" "cd"])) outputs "ab,cd" while (apply print-str (interpose "," ["ab" "cd"])) outputs "ab , cd" (extra spaces surrounding the comma)??? Is this some bug in print-str?
10:03upwardindexIs there a clojure introduction article targeted for common lisp programmers?
10:03tufflaxupwardindex there is a video...
10:03upwardindexIs it the 2008 Rich Hickey video?
10:03tufflaxhttp://blip.tv/clojure/clojure-for-lisp-programmers-part-1-1319721
10:03manuel_boston lisp group video
10:03tufflaxthat one
10:03manuel_it's nice
10:04thorwildabd: print-str uses print under the hood
10:04upwardindexHasn't clojure changed substantially since then?
10:04tufflaxnot so much i think upwardindex
10:04upwardindexAh great
10:04thorwil,(print "a" "b")
10:04clojurebota b
10:05tufflaxdabd it's just how print-str works. print functions insert spaces between the arguments
10:05thorwildabd: ^
10:06tufflax,(pr-str "a" "b")
10:06clojurebot"\"a\" \"b\""
10:07dabdbut I don't want the escape characters
10:07tufflaxdabd hehe then don't use the "pr" version. I was just trying
10:08dabdyeah but "str" does not force the evaluation of lazy sequences...
10:08tufflaxif you want to force evaluation use dorun or doall
10:10tufflaxdabd but, str should... what do you mean?
10:10tufflax(should force, how else can it make a string)
10:10dabdtufflax:I am writing an example just a moment please.
10:11tufflaxoh
10:11tufflaxi see what you mean
10:12tufflaxuse doall
10:13dabdtry this example (apply str (interpose "," (c/cartesian-product ["AB" "AC"] ["XX" "YY"])))
10:13dabdc is clojure.contrib.combinatorics
10:13tufflaxhm, that didn't work as i expected...
10:14dabddoall does not work here
10:14tufflaxnoticed..
10:14dabdi guess cartesian-product returns a lazy sequence but doall is not realizing it for some reason....
10:16tufflaxdoall does, but it just doesn't print the way you want it still :p
10:17tufflaxit's still a lazy seq, but it has been realized
10:18dabdI was checking the docs. It produces each head but not the entire seq. How can realize the entire seq?
10:20tufflaxdoall realizes the entire seq, but the thing you get back is still of type lazyseq, so it prints like a lazyseq
10:21dabdI'm looking for a way to get a seq from a lazyseq....
10:22tufflaxyes i know ;)
10:22tufflaxim trying to find a good way
10:25pyrhmm
10:26pyrso (new (Class/forName "something")) doesn't work
10:33raekpyr: new is a special form. it doesn't evaluate its arguments
10:33raekwell, the first one
10:33jeremyheilerpyr: (.newInstance (Class/forName ("java.lang.Object"))
10:33pyryes
10:33pyrI figured as much
10:33jeremyheilersorry, you were trying to create an instance of the Class object, werent you?
10:33pyrbut newinstance doesn't work for records
10:34raekpyr: (FooRecord. a b c)
10:35raekyour problem (whatever it is) might be possible to solve with a macro that expands into a constructor call
10:35raek(but since we don't know what you are trying to do, it's hard to tell)
10:35pyryeah :)
10:35pyrso a bit of context]
10:36pyri have an implementation of storage engine as a record implementing a protocol
10:36pyri want the implementation to be specified in a config file
10:36pyrso what I read is a string
10:37raekin order to construct a record, you must know the number of fields it has
10:37pyrso this isn't possible ?
10:38raekI think some like this would be the simplest solution (def record-constructor-functions {"foo" #(Foo. %), "bar" #(Bar. %)}) (defn construct-record [t x] ((record-contstructor-functions t) x))
10:38pyr'k
10:38tufflaxdabd sorry, I can't find a good solution. (Anyone else?)
10:39raekpyr: if you have different kinds of records with different number of fields, you cannot cal their constructors with the same number of arguments
10:40pyryes, that I get
10:40raekpyr: my suggestion is to create a function for each implementation whose purpose is to create a new instance of the record. these construcrtors would have the same interface.
10:41raekthen you can put those in a map and select the right one with a string
10:42pyrgood enough for now
10:42pyri thought i could do better :)
10:42dabdtufflax:thx. I am puzzled that this is so hard to do!!
10:42raekyou can write a macro or call the constructor with reflection, but then you might get security issues
10:43tufflaxdabd this works? (apply str (interpose "," (map (partial apply str) (c/cartesian-product ["AB" "AC"] ["XX" "YY"]))))
10:43raekpyr: you might be interested in this: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java#L153
10:43raekit allows you to call a constructor with any arity (not just the zero arity one .newInstance exposes)
10:44tufflaxdabd what do you want the end result to look like?
10:44dabdtufflax: that works fine.
10:44dabdanyway I will post the question again later to see if there are other ways... and understand why doall does not work...
10:45dabdthx
10:46pyrraek: ahah!
10:47raekbut if you know the type at compile time, it is unneseccary to use reflection for that
10:47raekdabd: is it a sequence of sequences?
10:48pyrno clearly i won't implement it like that
10:48pyrbut it's cool to find out about these reflection features
10:49raekdabd: also, str is not the right function for turning clojure data structures into strings, use pr-str for that
10:49dabdraek: in the example above the output of cartesian-product is a sequence of strings which technically is a sequence of sequences. But I don't see how that helps
10:49dabdraek:but pr-str shows all the escape characters and I don't want that...
10:49raekdabd: in what way is the sequence not forced?
10:50pyrraek: invokeConstructor does the trick
10:50dabdwith pr-str it is forced but shows all the escape chars
10:50tufflaxdabd why doall doesn't work is this: You have a lazy seq, which prints in "the bad way". It doesn't matter if you do doall on it, it's still a lazy-seq, it's just that after doall it's realized in memory. If you did (iterate inc 1) and used 20 elements, then 20 elements are realized, but it's still a lazy-seq.
10:51raekyes, that's how clojure data structures look in string form. pr-str returns a string which can be read back again
10:51dabdtufflax: I understood that. The problem is how can I access the realized seq
10:51raekstr is for concatenating strings and for turning numbers into strings
10:52pyr(defrecord
10:52pyroops
10:52raekdabd: so you want to turn a sequence of sequences into a pretty string?
10:52raekor concatenate all the elements or somehting?
10:53raekI think your issue is related to formatting rather that laziness
10:53raek*than
10:53dabdraek:yes I want to turn it into a pretty string
10:54raekso what does the resulting data look like? (if you just type it at the repl) and in what format do you wish to have it?
10:55tufflaxraek I think he wants to make a string that looks like it's been printed with print or pr, but does not want the extra spaces.
10:57raekdabd: so you gave the data (("AB" "XX") ("AB" "YY") ("AC" "XX") ("AC" "YY")). what should the string look like?
10:58raek"ABXXABYYACXXACYY"?
10:58dabdraek: that would be fine
10:58raekthat is what you get with pr-str
10:59dabdraek: but I get escape chars
10:59raekthat's because you print it at the repl
10:59raektry (println (pr-str (c/cartesian-product ["AB" "AC"] ["XX" "YY"])))
10:59raekthe backslashes are not part of the string
11:00raekthe repl prints your string as a string literal
11:00dabdraek:thanks
11:01raekdabd: "that would be fine" were you refering to (("AB" "XX")... or ABXX... ?
11:02dabdraek:the latter
11:02raekok, I parsed it as the former... :)
11:03raekthen you need to concatenate all the subsequences and concatenate the strings
11:04tufflaxmy thoughts are not very clear atm but...
11:04tufflax,((juxt (partial apply str) (partial apply print-str)) [(lazy-seq ["a" "b"]) (lazy-seq [1 2])])
11:04clojurebot["clojure.lang.LazySeq@fe2clojure.lang.LazySeq@3e2" "(a b) (1 2)"]
11:04raek(apply str (apply concat (c/cartesian-product ["AB" "AC"] ["XX" "YY"])))
11:04tufflaxwhat if i wanted "(a b)(1 2)" (no space!)
11:05raekno spaces and no quotes?
11:06tufflaxno spaces and no "LazySeq"
11:06raekthen you can't use the clojure printer
11:07raek(def x (c/cartesian-product ["AB" "AC"] ["XX" "YY"]))
11:07raek(apply str (for [subseq x] (str "(" (apply str (interpose " " subseq)) ")")))
11:07tufflaxhm
11:07raek"(AB XX)(AB YY)(AC XX)(AC YY)"
11:08duck1123`This is insane. There has got to be a way to get decent line numbers when exceptions happen in soy templates.
11:09raektufflax: so if you have custom printing rules, you need a custom printing function... :)
11:09tufflaxok :p
11:12tufflaxdabd btw "<dabd> tufflax: I understood that. The problem is how can I access the realized seq" the realized seq is the lazy seq. If you don't want it to be a lazy-seq then (apply list ...) or something.
11:12tufflaxI think that is how it works anyway :p
11:13upwardindexHey I'm watching the 2008 introduction to clojure and I was wondering if TCO made it to the JVM yet?
11:13tufflaxupwardindex no
11:13upwardindextufflax: any ETA?
11:13tufflaxdunno :p
11:14raekI think some made a patch for TCO, but only for self calls, or something
11:15tufflaxupwardindex but you don't need tco that often in clojure. The seq functions and recur takes care of most cases
11:15duck1123`I thought Rich said even if TCO was there, it won't replace recur
11:15upwardindextufflax: ok, good!
11:15dabdtufflax: ok thx
11:16tufflaxtake* :p
11:16upwardindexwell if tco is there recur is irrevelant no?
11:16duck1123`well, recur gives you that assurance that TCO is actually being used
11:16tufflaxyes but recur is nice in other ways, the compiler makes sure its in tail position so u dont make mistakes
11:16duck1123`if you try to recur when you can't, you get an exception
11:17duck1123`and it's very rare that you need to call it directly anyway
11:20tufflaxand recur works for anonymous fns :p
11:20luciantufflax: you can just as easily do (fn bla []...)
11:20tufflaxyes i know
11:20lucianbut yeah, recur is great
11:20tufflaxbut that's one more symbol
11:20tufflax:p
11:21lucianthe only use-case for real TCO i can think of is mutually recursive functions
11:21lucianand that's just way too confusing for me
11:21tufflaxhehe
11:23duck1123`tufflax: you can recur inside a named fn
11:23tufflaxyes of course
11:23lucianduck1123: look up
11:24duck1123`ahh I read the works for as only works for
11:24duck1123`and that confused me
11:24lucianbtw, fn names are only in the fn's scope?
11:24tufflaxyes i think so...
11:25hiredman(fn foo [] ...) foo is the this pointer for the Fn object
11:25lucianhiredman: right, so it doesn't leak in the outside scope. implicit let
11:26danlarkinanonymous function name
11:27tufflaxhiredman does that have any nonobvious consequences?
11:27hiredmannope
11:27tufflaxok :P
11:27duck1123`makes the class names nicer too
12:30lobotomy,(vec {:a 3 :b 2 :c 12})
12:30clojurebot[[:a 3] [:c 12] [:b 2]]
12:30lobotomywhat's a good way to turn [[:a 3] [:c 12] [:b 2]] back into a map?
12:31lobotomyah, apparently into
12:31lobotomy,(into {} [[:a 3] [:c 12] [:b 2]])
12:31clojurebot{:a 3, :c 12, :b 2}
12:31lobotomyyay
12:36no_mindhow do I call the clojure code from other jvm languages ?
12:38duck1123`do you man running clojure fns, or are you looking to make a class in clojure that can be called from java?
12:38duck1123`mean
12:39duck1123`http://stackoverflow.com/questions/2181774/calling-clojure-from-java
12:43no_mindduck1123`: I have a package in clojure and some one wants to extend it using jython. So I need to provide an interface which will allow calling of clojure fns from clojure package.
12:44duck1123`I don't know much about Jython, but you can have clojure produce actual classes and interfaces that jython could then use
12:45duck1123`http://clojure.org/compilation
12:45duck1123`now, that assumes you're able to change this clojure lib
12:45duck1123`and it forces you into AOT compilation
12:47duck1123`that SO pages shows how to simply call clojure from java. I assume you could use Jython's interop to do something similar
12:48no_mindthnxs, I will try
12:48duck1123`If you're planning for interop, better to go the gen-class route
12:48no_mindok
12:51duck1123`http://cemerick.com/2011/07/05/flowchart-for-choosing-the-right-clojure-type-definition-form/
12:52duck1123`that's more for working in clojure, but still a handy chart
12:58paulK_hi there, what's the easiest way to list all files in a directory with clojure?
12:59technomancy(.listFiles (clojure.java.io/file "/tmp"))
12:59technomancyshould work
13:00paulK_thank you technomancy
13:01technomancysure
13:01paulK_works great
13:02technomancyalso .list if you want strings
13:02hiredmanfile-seq
13:02technomancyyeah, also file-seq has the advantage of working from clojurebot
13:03paulK_clojurebot?
13:03clojurebotclojurebot is a cold unfeeling genderless mechanism
13:03pschorf:)
13:04hiredman~botsnack
13:04clojurebotthanks; that was delicious. (nom nom nom)
13:07paulK_ah, sorry my connection went down (and is very flaky ... )
13:21tufflaxpaulK_ http://clojure-log.n01se.net/
13:21tufflaxmight come in handy
13:22paulK_thank you tufflax
14:29tnksI'm new to Clojure, but keeping an eye on it for when Scala/Haskell stops consuming my bandwidth.
14:29tnksbut I'm really intrigued by Clojurescript.
14:29tnksdoes that bring persistent immutable datastructures into the Javascript ecosystem?
14:30fliebeltnks: Yes, but they are not yet as efficient as Clojure's, they are just... immutable.
14:30tnksah. . . I /might/ have /just/ found my answer. . . (not in the alpha, but soon)
14:30tnksfliebel: efficiency asside, are they persistent?
14:30tnks(meaning no exception throwing on attempts to mutate)
14:31tnkshttps://github.com/clojure/clojurescript/wiki/Differences-from-Clojure suggests they aren't yet.
14:31tnks(or not all of them)
14:31tnksmaybe List was easy or something.
14:32fliebelI suppose...
14:34fliebeltnks: It seems hash-map is implemented like array-map for now. https://github.com/clojure/clojurescript/blob/master/src/cljs/cljs/core.cljs#L2035
14:38amalloytnks: "efficiency aside, are they persistent". the definition at your link says they're not all persistent, but only because they're not efficiently persistent
14:38amalloy(which is the only meaningful definition of persistent)
14:50eskatremhello, I have some problem to write a script to get the prime factors of an integer.
14:51eskatremI knew http://pastey.net to paste the code I want to show but it seems to be down. anybody knows a better one?
14:51amalloyhttp://gist.github.com
14:52eskatremthanks amalloy
14:52eskatremI put my code here: https://gist.github.com/1145173 , if someone would be kind and explain me what's wrong with it
14:53amalloythat's a long list of things that are wrong. what language are you coming from?
14:54eskatremhmm
14:54eskatremI use mainly R this days, I learned a bit of C/C++ before
14:54eskatremI was trying to do some problems from Euler project
14:55eskatremto get a hack on clojure
14:55amalloysure, it's a good approach
14:56amalloythe three problems that stand out to me are (1) :while isn't a legal thing to do in a loop; (2) you group expressions like (do expr1 expr2), not ((expr1 expr2)); (3) you shouldn't be def'ing things in a loop, but instead supplying the right arguments to recur
14:56eskatremI feel like an idiot with that piece of code, I dont understand why it doesnt repeat the step "divide by p"
14:57eskatremfor problem (1), I tried many "versions" of a loop, this one happens to be my last failure
14:57amalloy*chuckle*
14:58eskatremBefore I did stuff like (loop [p 2 n a-arg] (while (> n 1) ... ))
14:58amalloythe general structure of a loop is (loop [var-name init-val] (... (if done? (something) (recur new-value-for-var))))
14:59amalloy&(loop [x 1] (do (println "x is" x) (if (even? x) :done (recur (inc x))))) ; for example
14:59lazybot⇒ x is 1 x is 2 :done
14:59eskatremhmm right
15:00eskatremhang on, let me (try to) change my code accordingly
15:00amalloystay far away from (while), which is for side effects, and just (recur) into the loop
15:00eskatremthanks amalloy, come back to you in 5 mins
15:03eskatremsorry, is this gonna be valid inside my loop; (if (= n 1) :done (something else))
15:04Bronsayes
15:04eskatremthank you Bronsa
15:10amalloyeskatrem: i forked and rewrote it at https://gist.github.com/1145191 - don't look unless you want spoilers
15:10eskatremamalloy: I am rewriting my code now. I will try to make it work, and then compare with your version (unless I cant make it work and then come back for more help)
15:14nollidjhello. i've been wondering how in clojure to express custom numeric types; probabilities, for example, which are transparently stored and manipulated in log-space
15:17nollidjthe hitch is that i would like for built-in arithmetic functions to work properly, so i can easily do something like (* (my-numeric-type 0.1) (double 0.5))
15:18nollidjalternately, if i'm doing computation with probabilities that have the potential to grow very small, do i need to worry about converting them to log-space if clojure automagically promotes them to bigdec when precision underflow becomes a problem?
15:20amalloynollidj: just use ratios instead of floats and it's not a problem
15:20amalloy&(reduce / 1 (repeat 100 4))
15:20lazybot⇒ 1/1606938044258990275541962092341162602522202993782792835301376
15:22nollidji'm not sure that works for the scientific computing i'd like to do
15:23amalloyreally? how could that be?
15:23sleepynateheh
15:24sleepynateyea when are floats better than ratios for significant digits? :)
15:25tnksamalloy: ah. . . I see now, I missed the "copy on write" part.
15:25clojurebotamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
15:25nollidjcan i exponentiate ratios?
15:25st3fan&(float (reduce / 1 (repeat 100 4))
15:25lazybot⇒ 0.0 ; Adjusted to (float (reduce / 1 (repeat 100 4)))
15:25clojurebotamespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it
15:26amalloyclojurebot: what the hell, shut up. hiredman, can we muzzle him?
15:26clojurebothiredman <3 XeLaTeX
15:27amalloynollidj: isn't that what i just did? 1 * (1/4)^100
15:27amalloybut if you want a rational power...i can see how that would be a problem
15:28nollidjyeah. sorry, i'm a bit distracted irl
15:29nollidjwhat i mean is something like: keeping things in terms of ratios can do a lot for me, but i'm concerned that at some point i'll have to use a floating-point value of some sort and things will collapse to zero
15:31eskatremamalloy: I couldnt find it by myself, so I peeped at your code. Really awesome
15:33nollidjalso, i am generally wondering about the question of how to extend numeric types in clojure to do something like autodifferentiation
15:35amalloyclojure doesn't really have any nice built-ins for adding new numeric types. you can find a library for it at clojure.contrib.generic-math, or something like that
15:35nollidjok, thanks
15:37eskatremamalloy by curiosity, do you use clojure at your workplace?
15:38amalloysince i started the new job in june, yeah
15:39Chousukenollidj: are you aware of incanter?
15:39Chousukenollidj: it sounds like you might like it
15:39eskatremwow quite recent then
15:39amalloyah, good point
15:42nollidjChousuke: i have heard of it, thanks
15:43nollidjthanks, all.
15:49sritchiehey guys -- when making a leiningen plugin, is there a way to call functions inside of the existing project?
15:50sritchie(:use my.namespace) doesn't seem to be allowed
15:50amalloyeval-in-project, i think? i don't really do that, but i've heard people talking about it
15:50sritchieI wanted to use lein and pallet to scp an uberjar up to a remote machine, then call an ssh command
15:51sritchiethat sounds like a good place to start, though, thanks
16:26eskatremquick question: how do I compute the max of a list of elements? (max 1 2 3) works but not (max (1 2 3))
16:27lobotomy,(apply max [1 2 3])
16:27clojurebot3
16:27Bronsareduce may be slightly faster
16:28eskatremthanks lobo
16:28eskatremhow does reduce work?
16:29Bronsa,(doc reduce)
16:29clojurebot"([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val i...
16:29Bronsainternally max with more than 2 args uses redouce
16:30Bronsaso using reduce isntead of apply you should avoid 2 function calls
16:30Bronsa*instead
16:31Night-hackshi
16:31eskatremthanks Bronsa
16:33Night-hackscode as data participates in clojure, does anyone knows why it's not possible in Java ?
16:43currymjthis is sort of a broad question, but does anyone have advice on how to learn penumbra (the opengl library)? I know nothing of graphics or opengl, should I even be starting with this?
16:44raekNight-hacks: in Clojure you can do (defmacro unless [condition false-exp true-exp] (list 'if condition true-exp false-exp)). how would you do this in Java? :-)
16:45Night-hacksraek: yeah, want to know what makes this limitation to java
16:45raekfor the user to invent a new control flow primitive (like "unless", which works like if but with a inverted condition), you would need a Java source code preprocessor
16:46Night-hackscurrymj: first you should complete your knowledge on OpenGL
16:46currymjso like, learn it in C/C++? or Java or what? I know there are different libraries.
16:47raekNight-hacks: in Lisps, the compiler (or interpreter) can use the functions defined so far in the program to build the code for the following code
16:48Night-hackscurrymj: JOGL is fine
16:48raekcurrymj: the Red Book uses the C API. APIs for other languages are probably translations of this API
16:49raekI expect the Java API(s) to be very similar to the C API
16:50currymjso i should probably work through that, i guess in Java. then i suppose i'll be able to understand how penumbra works underneath all the abstraction. thanks!
16:51Night-hacksraek: but what makes such an ability in Clojure ?
16:51Night-hacksraek: i wonder both are running on JVM
16:52duck1123`it's because of the parser (and the syntax)
16:52raekyes, the JVM can load code at runtime.
16:52duck1123`In clojure, all the code is in the same form as the data
16:52raekbut you generally don't write java code that generates new java code
16:53raekthat would involve either a lot of string manipulation, or parsing and emitting ASTs
16:55raekNight-hacks: maybe it's not really about an ability to do it, but about whether the languages are designed to make these things easy to do
16:56raekruntime generation of code in Clojure is trivial, but is a lot harder in Java (and probably requires additional libraries)
16:56currymjNight-hacks: when you run Clojure code, it converts the source file (with all the nested parens) immediately into nested linked lists. then Clojure executes the nested lists. this means that data manipulation facilities for dealing with nested lists can also be used to write, rewrite, and modify code. that is much easier than having to write and rewrite text, which is how the C preprocessor works, and what you would have to
16:56currymj(this is only a little bit of an oversimplification.)
16:56raekin Clojure you have everything you need for that in the language from the beginning
16:57duck1123`another good example of homoiconicity is XSLT, which is both written and operates on XML
16:57raekNight-hacks: Rich Hickey talks about this stuff at 36:00 in this videohttp://blip.tv/clojure/clojure-for-java-programmers-1-of-2-989128
16:58duck1123`I used to write XSLT templates that produced XSLT. (I feel a bit ashamed of that fact now)
16:58raekAnd he has pretty diagrams too... :-)
16:58raekduck1123`: how meta.. ;-)
16:59Night-hacksso clojure is not just a bytcode compiler, it has something on top of JVM.
17:00raekit has a runtime too. it contains data structures, functions and the concurrency primitives, among other things
17:00raekbut these are ordinary JVM classes
17:00raekafter they have been compiled from java or clojure code
17:01Night-hacksafter compilation
17:01upwardindexWhat is the most common way to host a clojure webapp? GAE?
17:02Night-hacksthanks for helps
17:03raekNight-hacks: one could imagine a homoiconic version of Java. you would write code in a syntax for ArrayList literals. these literals would be read into ArrayList objects, which would then be compiled into JVM bytecode
17:03duck1123`upwardindex: I think it's more common to have your own server and Jetty, but GAE is fairly popular
17:03raekthen macros would be methods that takes some of this data and returns new data, using the Java ArrayList operations
17:04upwardindexduck1123`: Interesting, thanks!
17:04duck1123`upwardindex: If you're just getting started on this, you'll probably want to look to Compojure
17:04Night-hacksyes, i think how this small feature of lisp is beautiful.
17:06upwardindexduck1123`: Yes, but there seems to have been split right? compojure now referes to a group of libraries is that right?
17:07raekupwardindex: http://brehaut.net/blog/2011/ring_introduction <-- this is a really good overview
17:07duck1123`Well, really Ring is the heart of it all, but Compojure will help you get up and running quickly
17:08duck1123`There are a bunch of frameworks that sit on top that privide different ways to build the app
17:08upwardindexraek: this seems to be exactly the article i need :D thanks
17:10upwardindexI gotta say I'm quite impressed with the quantity and quality of documentation related to clojure
17:42tufflaxupwardindex finally, someone who doesn't whine about the docs :p
17:43tufflaxhttp://news.ycombinator.com/item?id=2880935 first comment: "I will say that the online documentation IS atrocious and basically impenetrable" hmm I dunno what he has been reading
17:45duck1123`Wow, that was only a day ago AND he read 2 of the published books?
17:45technomancytufflax: wikibooks probably =)
18:11duck1123Wow, it takes a bit of time for that to show up
18:33sridduck1123 how do you know that he read 2 of the published book within days?
18:43bprIn gloss/lamina is there any way to call (decode frame channel) where channel is a channel containing ByteBuffers, and have it return the decoded value and only consume the number of bytes needed from the channel?
18:44bprI see in gloss.io there's decode-channel-headers, but this wraps the channel with a new channel. I'm going to receive many messages, and I'm afraid of the memory consumption concerns.
18:45bprgloss.io/decode-channel won't work for me because there are multiple message types that could arrive on the channel.
18:55duck1123srid: I don't know how long it took him to read them, I was remarking that comment was posted 2 days ago, not 2 years
20:23jsoft:(
20:23jsoftHate having to translate java (which I barely know) into the clojure equiv
20:24amalloywhy not just use the java you already have?
20:25amalloyclojure and java are buddies
20:26jsoftI dont _have_ any java
20:26amalloyyou're translating something imaginary?
20:26jsoftI am meaning examples on how to do things. Ie, no clojure examples, so I google java examples of a specific thing.
20:36amalloymmm. okay. anything in particular at the moment?
20:36Allaxwhat is wrong in this code?
20:37Allax, (map (partial apply str) (map (fn [s] (sort-by #((zipmap (seq "tzpnfrvmjdsglcbqxkhw") (range)) %) s)) (map seq (string/split "pbxktvfb pqv pxwcnpl pkpqpz pkrb pkgdl " #" "))))
20:37clojurebot#<CompilerException java.lang.RuntimeException: No such namespace: string, compiling:(NO_SOURCE_PATH:0)>
20:40amalloyyou're working too closely with primitives like map instead of factoring out into meaningful, abstract pieces, which makes it too hard for you to debug when something breaks :P
20:41amalloyno opinion about what's actually broken, though
20:43Allaxit was working. I get that code here. I don't know what happend when I saved
20:44Allaxthis code order each letter and each word with my own sequence (instead of abcde, it use tzpnf,,,)
20:51amalloybug reports and requests for help have three components: what you did, what you expected to happen, and what actually happened. can't do much with just the first
20:54buduhi
20:57buduis there someone there?
21:03technomancyeveryone is being very quiet right now: http://thebigcaption.com/post/609996178/everyone-shhh-its-a-sneak-attack-original
21:05Allaxnow where is the error in this code?
21:05Allax, (string/split "q1w2e3r4t5y6u7i8o9p0" #"\d+")
21:05clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox>
21:11duck1123`Allax: I get ["q" "w" "e" "r" "t" "y" "u" "i" "o" "p"] in my repl
21:11duck1123`assuming that string/ is clojure.string/ that is
21:12Allaxprobably you set a namespace, how do it?
21:13Allaxthat message is showed in clojurebot and local compiling
21:13duck1123`(:require [clojure.string :as string]) in the ns clause
21:14duck1123`but I just added clojure. when I pasted it into a clean 1.3 repl
21:14leonid__,(clojure.string/split "q1w2e3r4t5y6u7i8o9p0" #"\d+")
21:14clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox>
21:16duck1123`I wonder what's going on there. Seems bot-specific
21:19Allaxweird, string/split works before
21:20sritchietechnomancy: whoops, sorry
21:20jsoftPhew.
21:20jsoftMan java seems to be verbose.
21:21duck1123`I find that I mentally convert java to clojure when reading java code sometimes
21:22duck1123`Allax: I'd consult a real repl rather that trust what clojurebot says
21:25Allax1:6 user=> (clojure.string/split "q1w2e3r4t5y6u7i8o9p0" #"\d+") java.lang.ClassNotFoundException: clojure.string (repl-1:6)
21:26duck1123`What version of Clojure are you using?
21:28duck1123`clojure.string was added in 1.2
21:29Allaxah
21:30duck1123`and unless you have a really good reason, you should upgrade
21:30amalloygood reasons include: i have no fingers with which to type the upgrade command?
21:31duck1123`that's not even a good enough reason. Voice-to-text man
21:32duck1123`go to at least 1.2 but keep thinking about 1.3
21:32duck1123`the libraries are getting better on compatibility
21:33duck1123`as we speak I'm looking to see which of my patched dependencies I can ditch in favor of the mainline versions
21:35leonid__sudo apt-get upgrade clojure gets me 1.0.0
21:35leonid__what am I doing wrong?
21:36leonid__(linux novice)
21:36duck1123`what are you using for project management
21:36duck1123`you'd be better off with lein, maven, et al. than the one in apt
21:37leonid__hmm okay
21:37duck1123`I'm a big fan of Maven, but arguably lein is much easier
21:37leonid__gotta use lein then
21:37technomancylein is in debian unstable and ubuntu oneric
21:37duck1123`so get the lein script, run "lein new <projectname>"
21:37duck1123`sweet
23:09solussdwhat's a good REST client framework for clojure?
23:13solussdrunning with clj-http, unless someone thinks they should stop me. :D
23:14cheiersolussd: http.agent in contrib
23:16solussdcheier: doesn't seem to support basic auth
23:17duck1123I've been using Aleph's client, but I believe that just uses clj-http under the hood
23:18cheierapache commons httpclient
23:19solussdwhich is what clj-http uses I believe
23:20solussdanother random question- after 'lein deps' is there something I need to do to make what I pulled in accessible in my repl via swank/slime (besides requiring it)?
23:21duck1123nope, just require your ns once you're in
23:22solussdweird. not working.
23:22solussdI don't need to restart swank / reconnect with slime?
23:24leo2007How to get the arg of doc eval'd?
23:25solussddoc is a macro
23:26cheiersolussd: have you tried (in-ns <your ns here>) ?
23:28solussdcheier: I don't understand. :/
23:28cheierswitch to you're ns in the repl
23:29cheier,(doc in-ns)
23:29clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox>
23:30amalloy,1
23:30clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalStateException: replace already refers to: #'clojure.string/replace in namespace: sandbox>
23:30amalloy&(doc in-ns)
23:30lazybot⇒ "([name]); Sets *ns* to the namespace named by the symbol, creating it if needed."
23:32amalloyhiredman: clojurebot seems to be choking on every eval request
23:33solussdcheier: ok, inns allows me to switch to the clj-http.client namespace… wonder why I cannot require it
23:33solussdoh wait, it created it, didn't it
23:34cheierswitch back to you're core ns
23:34cheieryour*
23:36solussdgr. killing restarting 'lein swank' 'fixed' it
23:36solussdmy repl was in 'user
23:36solussdc-c c-k would throw a compilation error -- couldn't find clj-http.client on the classpath
23:50amalloysolussd: you need to restart swank when you have new dependencies
23:51solussd:/ ok.
23:51amalloythe jvm gets sad when you try to change the classpath at runtime
23:51solussdas long as I can blame it on the jam
23:51solussd*jvm (stupid autocorrect)
23:53amalloyhaha i wish i could blame more of my problems on the jam
23:53sarcherhey i'm just checking out clojure and functional programming (coming from java)
23:54sarcherhow do you handle configuration? are configuration parameters just additional function parameters?
23:55amalloy"sorry i'm late, there was so much dang jam"
23:56amalloysarcher: that's one approach. clojure makes it so easy to create and use hashmaps that you can just create one for your options
23:57amalloystore it on disk as a text file for whole-program configuration, pass it to a specific function, whatever
23:57sarcherah cool.
23:57sarcherin java we use spring to configure an object and then just call the methods on it.
23:58sarcherI'm trying to figure out how to make things more scalable.
23:58sarcherif configuration is passed, then we could have multiple servers setup and call our code on either one.
23:58sarcherI know we could do that with java too, but i'm trying to learn the functional way :)