#clojure logs

2010-12-28

00:00amalloy&(apply concat ((juxt take (comp rest drop)) 2 [1 2 3 4]))
00:00sexpbot⟹ (1 2 4)
00:01Gigarobylook a bit complicated just to remove a element
00:01Gigarobylol
00:01amalloyGigaroby: or you could do it more explicitly, like ##(let [x [1 2 3 4]] (concat (take 2 x) (drop 3 x)))
00:01sexpbot⟹ (1 2 4)
00:01Gigarobygot it
00:01LeonidasI have a list of regexp that I want to chain on a string (using re-sub), what can I use? -> and reduce don't work for me in this case...
00:01Gigarobythanks
00:02Leonidas(re-sub second "" (re-sub first "" input-string)) etc.
00:02amalloyhippiehunter: -> is a form-restructuring macro like doto. for example: ##(-> {:a {:b 2}} :a :b)
00:02sexpbot⟹ 2
00:03hippiehunterdoes it have a non symbol name?
00:03amalloy,(macroexpand '(-> {:a {:b 2}} :a :b))
00:03clojurebot(:b (clojure.core/-> {:a {:b 2}} :a))
00:03hippiehunter-> doesnt google well
00:03amalloyhippiehunter: i don't think so. maybe one in common lisp? i'll find you the clojure ref
00:03Leonidashippiehunter: "theaded first", there is a nice intorduction in full disclojure.
00:03Leonidas"thread first" I mean, sorry.
00:04amalloyhttp://blog.fogus.me/2009/09/04/understanding-the-clojure-macro/
00:04hippiehunterperfect, thank you
00:05amalloyLeonidas: why doesn't reduce work? (reduce (fn [s [match replace]] (re-sub match replace s)) input-string [[first ""] [second ""]])
00:07Leonidasamalloy: the reduce docs says that when coll contains only one element it will return coll without applying f to it
00:08amalloyLeonidas: unless you supply it with an initial value, which i do with input-string
00:08amalloy&(reduce + 1 [4])
00:08sexpbot⟹ 5
00:09Leonidasah
00:09amalloythe docs do say that, but they're rather poorly written in that regard
00:11amalloyyou're meant to read it as "(If val is not supplied...If coll has only 1 item)...If val is supplied..."
00:13Leonidasamalloy: you're right, it works just fine, I added it in my code and it passes the tests :)
00:14rata_Gigaroby: you could use split-at also... (let [[a b] (split-at 2 [1 2 3 4])] (concat a (rest b)))
00:14Leonidasthanks!
00:15amalloyLeonidas: great! hippiehunter, is -> starting to make sense?
00:15Gigarobyrata_, thanks, I alredy used the other one is shorter
00:15Gigarobyrata_, (fn [idx lst] (concat (take idx lst) (drop (inc idx) lst)))
00:16rata_good
00:16Gigarobyrata_, is just strange that someonle else didn't alredy implement it
00:16Gigarobyrata_, I tought was common enaugh
00:17amalloyGigaroby: it's pretty rare that you need to do it, with clojure's functional/lazy idioms. what do you need it for, out of curiosity?
00:17Gigarobyamalloy, well is a bit of a long explanation
00:17Gigarobyamalloy, I have a list
00:18rata_Gigaroby: I haven't need it... as amalloy said is not common at all
00:18Gigarobyamalloy, containing a variable number of maps such as {:board [ ... ] :current 0}
00:19Gigarobyamalloy, I have to extract a value from one of those boards and see if there is a board with the same number in the same position
00:19Gigarobyamalloy, therefore I need to delete the board itself to check the others
00:20amalloyGigaroby: but you don't need to delete it by index. you could, eg, (remove #{the-map-to-remove} all-the-maps)
00:20Gigarobyamalloy, ah
00:20Gigarobyamalloy, didn't think about it lol
00:21Gigarobyamalloy, waith tho because 2 of them may contain the same board and number
00:23amalloyyou might have two exactly-identical maps, and you want to remove only one of them?
00:24Gigarobyamalloy, well in worse case I can have all the maps identical
00:24Gigarobyamalloy, probably they will not point to the same reference but they will be the same at =
00:26amalloyGigaroby: removing by index is probably not *that* sinful then, i guess, though you could do without it if you wanted to
00:27tomojhow many boards?
00:27Gigarobytomoj, variable number
00:27Gigarobytomoj, suppose not over 20
00:27tomojok
00:27Gigarobytomoj, and not less then 5 or 6
00:28tomojI was thinking that'd be slow, but with those numbers it won't matter I bet
00:28Gigarobytomoj, no the bottle neck is not there for sure
00:28amalloytomoj: remove/filter won't be any faster, will they?
00:28rata_Gigaroby: what happens when there's a board with the same number in the same position?
00:29Gigarobyall right I'll explain the whole problem than
00:29GigarobyI'm trying to do a strange kind of 8 queens problem
00:30Gigarobyby taking 8 single problems and trying to make them fit one in the other
00:30tomojamalloy: what would be faster would be not keeping this in a list, I think..
00:30amalloytomoj: for sure
00:30Gigarobyall the fuss is about checking that a queen on a single board will not collide with one in another board
00:31Gigarobyso nothing happend when 2 maps are equals simply the check returns false
00:32rata_Gigaroby: the question is, what do you do when a queen collide with one in another board? do you delete one of those boards?
00:33Gigarobyrata_, no simply the check returns false
00:33rata_ok
00:33Gigarobyrata_, I delete one board into the check
00:33Gigarobyrata_, to make sure that some will not take the board itself as argument
00:35Gigarobyrata_, I'll show you the source as short as I finish that function
00:35rata_ok
00:42Gigarobyrata_, you were right I thought about it and I did a mess for nothing
00:43Gigarobywas just a matter of check if the count was greater then 1
00:43rata_=)
00:43Gigarobyrata_, afk for couple of hours or so
00:43rata_glad I've been helpful
00:45hippiehunteramalloy: yes that made -> much more clear
01:08amalloyhippiehunter: it occurs to me, you could make this "prettier" with (defmacro set-member! [inst field val] `(set! (. ~inst ~field) ~val)))
01:25rata_why, if (map reverse lst) returns (([1 2] [3 4])), when I do (into {} (map reverse lst)) it returns {1 2, 3 4} instead of {[1 2] [3 4]}?
01:25rata_but when I do (into {} (map (comp vec reverse) lst) it works
01:59amalloy&(into {} [[1 2]])
01:59sexpbot⟹ {1 2}
02:00amalloy&(into {} ['(1 2)])
02:00sexpbotjava.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Map$Entry
02:00amalloyrata_: vectors can be coerced into map entries, but lazyseqs can't
02:01rata_oh ok... didn't know that
02:01rata_thanks =)
02:01rata_strange anyway
02:01amalloy&(supers (class (first {:a 1})))
02:01sexpbot⟹ #{clojure.lang.Sequential clojure.lang.IPersistentCollection clojure.lang.APersistentVector clojure.lang.ILookup java.lang.Object clojure.lang.IFn java.lang.Runnable java.io.Serializable clojure.lang.AMapEntry java.util.List java.lang.Iterable clojure.lang.IPersisten... http://gist.github.com/756986
02:01amalloy&(class (first {:a 1}))
02:01sexpbot⟹ clojure.lang.MapEntry
02:15rata_good night
02:18joshua__I just realized something really cool.
02:19joshua__It felt natural for me for the first time to choose Clojure instead of Python for my last little script.
02:19joshua__yeay
02:37amalloyinspired by hippiehunter's recent question: is there some way to combine the -> family of macros to get a macro M, such that (M a (b c d e...)) yields (b c a d e...); that is, splices into the third position instead of second or last? i realize this is not useful, nor difficult to do by a plain defmacro, but it seems to me there must be some way to do it with ->
02:43notsonerdysunnycan members of a record be type hinted? will this enhance performance or improve storage efficiency?
02:55amalloynotsonerdysunny: if it's possible (i'm not sure), it won't improve storage efficiency, and won't enhance performance any more than you could by type-hinting the members when you access them
02:58amalloynotsonerdysunny: (doc defrecord) says the fields can have type hints
03:00zvrbahmm. i was intrigued that clojuer's vector implementation has log_32(n) access time
03:00zvrbahow are they implemented?
03:00zvrbaamalloy: i settled down with emacs+slime :-)
03:00zvrbagetting leiningen to work under windows wasn't too painful either
03:00amalloy$google higher order blog implement ipersistentvector
03:00sexpbotFirst out of 11 results is: Ruminations of a Programmer: Random thoughts on Clojure Protocols
03:00sexpbothttp://debasishg.blogspot.com/2010/08/random-thoughts-on-clojure-protocols.html
03:01amalloybah
03:01zvrbahttp://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/
03:01zvrbathis one? :)
03:01amalloythat's the one!
03:01zvrbainterestingly, that WAS the first result in my google search
03:03amalloyzvrba: google corrected you to persistentvector; sexpbot's using the api, which doesn't do that
03:05amalloyzvrba: clojure's persistent data structures are amazing things, and i'm glad i don't have to deal with them. but if you're interested in working on an effort to implement another useful persistent data structure, check out https://github.com/Chouser/finger-tree/commits/master
03:08zvrbauh, no. :)
03:09notsonerdysunnythanks amalloy
03:10zvrbaamalloy: anyway, starting to read on finger trees now
03:10zvrbai got a bit intrigued :-)
03:10notsonerdysunnyamalloy: you don't think it would improve storage efficiency.. ?
03:10notsonerdysunnydouble would require more storage than a int ..right ..
03:11zvrbaamalloy: but why did he choose int? using long would make access time log_64(n) ?
03:11amalloynotsonerdysunny: an Object reference takes up exactly as much space as a LinkedList reference
03:12amalloynotsonerdysunny: you might save a little space if you wanted to store primitives, but you'll suffer performance penalties for the boxing and unboxing
03:13amalloyzvrba: it's a trade-off. with a larger branching factor, there's less room for pointer-sharing between "related" vectors
03:13zvrbauh, that finger_tree.clj is way above my clojure-fu atm. :-)
03:13amalloyzvrba: yeah, mine too. chouser is something else
03:14notsonerdysunnyamalloy: I am storing primitives only
03:14notsonerdysunnythey are all doubles.
03:14amalloynotsonerdysunny: so...why not just use (make-array Double/TYPE 10)?
03:15notsonerdysunnyyea true but .. I like being able to access with the automatic getters ..
03:15notsonerdysunnyfor example I could have (defrecord point [x y]) and I can access it via (:x somepoint)
03:16amalloynotsonerdysunny: so type-hint your defrecord, then. you'll save four bytes for each double, i guess
03:26notsonerdysunnyamalloy: is there some way to say that this will contain an array of 3-doubles? i.e. type hint that it will contain an array of 3 doubles..
03:28amalloynotsonerdysunny: afaict protocols only allow type-hinting of primitives, and double[] is an Object
03:29amalloynotsonerdysunny: er, records, not protocls
03:29amalloyif you wanted to type-hint a double[] outside of a record, the tag would be ^"[D"
03:29notsonerdysunnyactually I was able to type hint it with another record type...
03:30notsonerdysunnyamalloy: where do you get these type-hint strings.. do you have a reference?
03:30amalloy&(class (make-array Double/Type 0))
03:30sexpbotjava.lang.Exception: Unable to find static field: Type in class java.lang.Double
03:30amalloy&(class (make-array Double/TYPE 0))
03:30sexpbot⟹ [D
03:31amalloynotsonerdysunny: ^"Foo" hints "the java class Foo", and the class string for double[] is [D
03:31amalloynotsonerdysunny: but all this is madness. you don't gain anything unless you're type-hinting primitives directly; if you hint it as some other defrecord, it just stores it as an Object anyway, because the references are the same size
03:33amalloysame goes for arrays of primitives
03:33notsonerdysunnyoh .. ic
03:35amalloynotsonerdysunny: https://gist.github.com/757058
03:38notsonerdysunnyamalloy ah ic .. thanks for the gist .. I need sitback and see how I have to do what I am doing.. :)
03:39notsonerdysunnyI guess the type-hinting with other records/classes will also be taken into account in the future releases of clojure ...
03:42amalloynotsonerdysunny: maybe. it's probably a good feature, but i suspect the core team has a lot of higher-priority stuff to do, and there may be reasons not obvious to either of us that it's a bad feature anyway
03:48notsonerdysunnyI defined a an array of some-user-defined record .. and tried to assign a different record .. so it is trying to check if the type of array and that of assigned objects match .. ? can I disable this.. ? just out of curiosity
03:48notsonerdysunny*forgot to say that the repl didn't allow this .. *
03:50amalloynotsonerdysunny: yes; no. java's type system is strict
03:54_atonotsonerdysunny: specify the type as "Object" when you create the array and you can put anything in it. Like: (into-array Object [1 2 3 4])
03:54notsonerdysunny_ato .. Yeah I tried that .. thanks
03:57notsonerdysunnysuppose I have an array of size 10x10 .. is it faster to zero out all the elements of the array or just create another array?
03:59amalloynotsonerdysunny: try it and see
04:05notsonerdysunnyamalloy: using the aset macros from http://clj-me.cgrand.net/2009/10/15/multidim-arrays/ both are about the same speed ..
04:05notsonerdysunnyI guess it is just easier to create a new array then ...
04:08notsonerdysunnya naive implementation would be about a 20 times slower when I reset all the values to zero ..
05:48ngwis there something similar to http://www.liquidmarkup.org/ for clojure ?
05:49ngwwhat I need is a simple lib to use a DSL (something simple, basic looping and mostly functions that return strings, very limited) inside HTML templates
05:50ngwconsidering how good clojure is at building DSLs ...
05:50lenwngw : like velocity ?
05:53ngwactually liquid is much more limited, and that is very good :p
05:53ngwvelocity seems more similar to erb/PHP
05:55ngwfleet is the best I found until now
08:42RaynesI'm happy that that little outburst happened early on a Tuesday morning.
08:44Raynescemerick: Nobody has ever used the banstick here. Unfortunately, not nearly enough people have a banstick.
08:45cemerickRaynes: I think it's been used once, a long time ago.
08:45cemericklate 2008, maybe?
08:45RaynesBefore my time.
08:45cemerickBut yes, I agree. There should be an op in here at all times IMO.
08:45RaynesWait until Clojure is *really* popular.
08:46RaynesThere will be no choice in the matter.
08:46ejacksonsigh, indeed.
08:46RaynesToo bad chouser isn't omnipresent.
08:46ejacksonso I learnt this am that the java client for Redis is called jedis.
08:46ejacksonI didn't notice the pun until I googled it
08:47RaynesI wouldn't have noticed the pun.
08:47ejacksonalso before you time ? :P
08:47RaynesI think I pronounce Redis incorrectly.
08:47RaynesNo, I get 'jedi', but I don't enunciate the 'i' in Redis.
08:48RaynesIt wouldn't have popped out at me.
08:48ejacksonit didn't me either
08:50ejacksonit stresses me out how easy these new dbs are
08:50ejacksonto get clojure working with jedis was < 5 mins of work
08:50ejacksonsomething terrible must be hiding under the rug here
09:08LauJensencemerick: Hows responsible for moderating #clojure?
09:09cemerickLauJensen: only Rich and chouser have op IIRC
09:09LauJensenk
09:13bendlasCan somebody tell me what's up with that snippet: http://pastebin.com/AgNVKFhW
09:14bendlasand what happens when you do (= (Vec2. 5 6) (Vec2. 5 6))
09:59bendlasWhy is instance? _broken_ in deftype method bodies?
10:13bendlasPlease guys, take a look at http://pastebin.com/cTdUCKfp
10:19cemerickbendlas: it's a known issue, related to a stub class being generated prior to the "real" deftype class being generated (the former being required for hinting).
10:19cemerickbendlas: I don't see an issue for it in jira yet; feel free to submit one with your testcase.
10:20bendlasok, thanks
10:21bendlasisn't issue tracking done at assembla?
10:21cemerickbendlas: no: http://www.assembla.com/wiki/show/clojure
10:24bendlasoh, it's fixed in current 1.3 snapshot
10:37drewolsonanyone have experience with aleph? on large requests the body is a channel and i'm having trouble turning this channel into a string.
11:02Appl6Hello, I'm just getting started with Clojure. I'd like to use the REPL to import a public Java class file (part of the default package) in the current directory (Instruction.class). I tried several things but only (import '(Instruction)) didn't produce an error (it returned nil), but:
11:02Appl6user=> (Instruction. nil 100)
11:02Appl6java.lang.IllegalArgumentException: Unable to resolve classname: Instruction (NO_SOURCE_FILE:18)
11:05mrBlissAppl6: make sure it's on the class path, the proper syntax is: (import '(packagename Class))
11:06mrBlissAppl6: I advise you to look into leiningen or cake (pick one)
11:07Appl6mrBliss: It is not in a package; it's in the default package. What would I use then for "packagename"?
11:11mrBlissAppl6: I'm not sure, but I think it's not possible
11:12Appl6mrBliss: OK, thank you.
11:19cemerickmrBliss: you can also do (import 'Foo), which will work for classes in the default package.
11:19mrBlisscemerick: too bad App16 already left :-)
11:20krlis there any way to swap atoms from within calls to map?
11:32LauJensenkrl: yes, but it sounds unidiomatic. If you want sideeffects, try doseq
11:47pdk,(let [triangle (for [i (range 5)] (range i))] (for [row (count triangle)] (get triangle row)))
11:47clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer
11:48pdk,(let [triangle (for [i (range 5)] (range i))] (for [row (range (count triangle))] (get triangle row)))
11:48clojurebot(nil nil nil nil nil)
11:48pdkis this a known bug with get
11:49pdk,(let [triangle (for [i (range 5)] (range i))] (for [row (range (count triangle))] (nth triangle row)))
11:49clojurebot(() (0) (0 1) (0 1 2) (0 1 2 3))
11:49pdkcompare
11:50danlarkin,(type (for [i (range 5)] (range i)))
11:50clojurebotclojure.lang.LazySeq
11:50danlarkincan't get on a LazySeq
11:50pdkyea that seemed to explain part of it
11:51pdkhm do you just call seq on a lazy sequence to force evaluation
11:51danlarkinif you want to use get you need to turn it into an associative data type
11:51danlarkinlike a vector
11:53pdkso easiest way would just be to vec it
11:53pdkvector rather
11:54danlarkinit seems like a pretty odd example, does your real use case match what your example does?
11:54pdkwhat i'm trying to do is write a function that takes in a 2d matrix say as a vector
11:55pdkand if it's jagged or has more rows than columns/vice versa it returns a version padded with empty space until it has a square
11:55pdkso say giving it [[1 2 3]] would return something like [[1 2 3] [nil nil nil] [nil nil nil]]
11:56pdkworked on the other usage cases i gave it so i'm starting to figure i can just replace get with nth and add a not-found so it doesn't crash
11:57pdksuccess
11:57pdkcalls for a group hug
11:58pdkok
11:58pdkmaybe not success when it has more columns than rows
12:08Guest10433I am invoking my program from the command line like so: "java -cp myjar.jar clojure.main -i @/some/package/myfile.clj" but I can't figure out how to pass command line variables. Does anyone know how to do this?
12:10tonylGuest10433: just pass them after your clj file
12:10Guest10433tonyl: when i do that i get an error in "main" that it can't find the file
12:11tonylwhat file?
12:11Guest10433tonyl: for example, if i put "somearg" at the end, i get filenotfoundexception in main for file "somearg"
12:12tonylit seems that is something in the code of main that is not working right
12:12tonylcan't tell much without a snippet
12:12Guest10433ok sure, let me post it up and i'll brb
12:17Guest10433tonyl: http://pastebin.com/YgS1N97N
12:18Guest10433if I leave the "Jackson" off, it runs but doesn't print any name. if I put "Jackson" on the line, I get FileNotFoundException in main for file Jackson
12:19Guest10433this is on Windows so the 0th arg isn't the program name but the first argument
12:21tonylyeah, i tried it and mine only prints Hello, *command-line-args* is nil for some reason
12:22tonyllet me see
12:22bendlas,(if (Boolean. "false") "It's true" "It's false")
12:22clojurebot"It's true"
12:22bendlassomebody know if that is worked on?
12:22tonylonly false and nil are boolean false in clojure
12:23bendlasno, look
12:23Guest10433tonyl: are you saying that you don't get the FileNotFound if you DO put some additional arg on there?
12:23tonylGuest10433, i don't get any errors
12:23bendlas,(if (Boolean/FALSE) "It's true" "It's false")
12:23clojurebot"It's false"
12:24bendlasBoolean/FALSE is also boxed
12:24Guest10433tonyl: that's odd. i'm using 1.2 here. you?
12:24@rhickey,(identical? (Boolean. false) Boolean/FALSE)
12:24clojurebotfalse
12:24tonylI am using 1.2 too
12:24gju_can i somehow create a record without having to initialize every single field in that record?
12:25@rhickey,(identical? (Boolean. "false") Boolean/FALSE)
12:25clojurebotfalse
12:25Guest10433tonyl: on windows? i don't understand how we get different behavior
12:25tonylnot on windows
12:26tonylGuest10433: try putting (println *command-line-args*) before (hi (nth *command-line-args* 0)) see what do you get
12:27@rhickey,(identical? false Boolean/FALSE)
12:27clojurebottrue
12:28bendlasrhickey: so you're arguing that exactly one instance of Boolean (namely Boolean/FALSE) should be false in clojure?
12:28@rhickeybendlas: I'm not arguing, that's how it is
12:29bendlasindeed
12:29Guest10433tonyl: hmmm if i pass one arg, *command-line-args* prints as nil, if i pass 2 args, i see the second one
12:29Guest10433tonyl: i think this is broken on windows
12:29bendlaswhat about using ,(.equals Boolean/FALSE (Boolean. false)) instead?
12:30@rhickeybendlas: where?
12:30tonylGuest10433: u are better off then me, I passed 0 or 10 args and it is still is nil
12:31bendlasrhickey: wherever conditional forms are currently using (identical? Boolean/FALSE x)
12:31@rhickeybendlas: no way, for perf reasons
12:32tonylGuest10433: try running it without the -i just clojure.main file.clj
12:33Guest10433tonyl: doh! why didn't i try that? that is working. it's ok for you too?
12:33bendlasrhickey: same thing for an implicit (boolean x), I suppose?
12:34bendlas,(if (boolean (Boolean. "false")) "It's true" "It's false")
12:34clojurebot"It's false"
12:34tonylno, but that might be because i use a bash script to call up that command, there might be something wrong in my script
12:35Guest10433when i read the doc at clojure.org/repl_and_main i thought i needed the -i when loading a file
12:35tonylyes, but anything after -i is treated as a file to load
12:35tonyleven the args
12:36Guest10433tonyl: ok, got it. but if i do specify a file, it doesn't leave me at a repl, which is what i want in this case. anyway thanks!
12:36Guest10433with no -i i mean
12:36tonylyeah i understand the nead
12:37tonyl*need
12:37tonylyou might want to try out cake, lein, labrepl, or cljr or those scripts/programs tested to work better and simpler
12:38tonylI know i am thinking about using them now
12:39Guest10433tonyl: better and simpler than what? basically i just built an uberjar and now i want to distribute it to run on some system where i can only count on java being present. all i need to know is the invocation syntax to kick it off via a script
12:40Guest10433tonyl: everything works perfectly without the "-i" in there ;) i'll just write a simple wrapper script for the user so they don't have to type in that java command line
12:41tonylyeah, that is my mentality "if it works, fine. tune it later when you have time"
12:42Guest10433tonyl: hmm not sure i'm following since i don't see anything further to tune. are you suggesting a better way to run standalone clojure programs?
12:43tonylI am just saying there are other ways with those tools and from what i heard simpler too, but nothing from my experience
12:43bendlasrhickey: is there really no way/plan to fix this? I mean it's really one of my basic assumptions for a PL, that (if x ...) means the same as (if (boolean x) ...)
12:44Guest10433ok, sure. thanks for your input. it got me out of that rut (not thinking about removing -i)
12:46@rhickeybendlas: it's not broken. What is broken is that Java creates distinct Boolean objects when they have perfectly fine canonical ones. It is not going to change
12:47Raynesrhickey: Long time no see. Hope you had a merry Christmas. :>
12:47bendlasrhickey: ack @ java brokenness
12:47@rhickeyRaynes: thanks, you too
12:54@rhickeybendlas: if the construction is up to you, use valueOf:
12:54@rhickey(identical? (Boolean/valueOf "false") Boolean/FALSE)
12:54@rhickey,(identical? (Boolean/valueOf "false") Boolean/FALSE)
12:54clojurebottrue
12:55@rhickeybendlas: if not, chastise the producer for not using valueOf
12:55@rhickeythose Boolean ctors are evil
12:56bendlasrhickey: will do, thanks for explaining
12:59bendlasrhickey: yes, Boolean ctors should be private
13:12zvrbahow can i define a local function in clojure? like labels in CL?
13:12zvrbalet + fn ?
13:14zvrbayes, it works.
13:15mrBlisszvrba: letfn if you need to refer to a local function (= labels)
13:15bendlas,(letfn [(x [a] (inc a))] (x 5))
13:15clojurebot6
13:17amalloypersonally i use let+fn so that i don't have to remember the syntax for letfn - there's no obvious gain from using letfn unless you need mutual recursion
13:31Raynesivey: -> #sexpbot if you're around
14:27gju_when i define a record and want to fill it with data... what's the best way to do it?
14:28gju_without always re-defining something.
14:30tonylgfu_ a fn that has a default map of the values maybe?
15:45jcromartieI'm totally stumped as to how to handle nil/null in clojure.contrib.sql
15:45jcromartieI mean reading queries is easy
15:45jcromartiebut matching or updating when a column is null
15:47jcromartiein fact, I've found that text type columns and nil values totally throw c.c.sql for a loop
15:47fvhi
15:48fvI've got a simple issue, but neither google nor searching archive helped
15:48fv(ns clojurefirst
15:48fv (defn print-string [x]
15:48fv (1)
15:48fv )
15:48fv)
15:48fvCaused by: java.lang.IllegalArgumentException: Parameter declaration quote should be a vector
15:49amalloyfv: (ns blah) (defn foo [x] 1)
15:49fvexample runs perfectly in REPL, and I just have no idea why would it be something wrong with it
15:49fvthank you
15:50fvworks
15:50jcromartietjat
15:50jcromartiethat's not how you use ns
16:20sarcher|workJust got a copy of Programming Clojure. Any advice for a Java guy getting started with Clojure?
16:20sarcher|workI took Lisp in college and at some point it all made sense, but I haven't looked at a lisp since then.
16:21auser<~ from an erlang guy, I'd say don't think about objects, think in terms of functions
16:21auserex-java guy too
16:21auserbut from a long time ago
16:21auserheh
16:21sarcher|workyeah the whole idea of functional programming makes sense to me.
16:22auseroh I'd also work with clojure like it's an entirely new language
16:22auserthe java interop took me a little while to understand (I'm still learning about it, in fact)
16:22sarcher|workI just don't have any experience building stuff using that paradigm
16:22auserwrite something simple then
16:23qbgDoing some Project Euler problems may be useful.
16:23ausergood idea qbg
16:23amalloysarcher|work: if you have a handle on the "idea" of functional programming, lazy sequences are an important thing to get the hang of
16:24auseroh yeah, that's really true amalloy
16:24sarcher|workyeah I'm not familiar with that.
16:24qbgCode reviews on irc could be useful also.
16:24amalloyand yeah, project euler is a good thing to try. you can also look at Rosetta Code; it's a wiki so some of the code is pretty shoddy or poorly-documented, but it offers a great side-by-side comparison of clojure to other languages
16:25sarcher|workcool, it sounds like I just need to start building something and then see where it leads me :)
16:34amalloysarcher|work: you can also look at some open-source clojure programs on github
16:39sarcher|workthanks amalloy
16:51LeonidasI have something like (def u {"Leonidas" 3}) (def d {"Leonidas" 2}) and run (merge-with (fn [u d] {:upvotes u :downvotes d}) u d) This only works when both u and d have a Leonidas-key. Is there a way to transform it, even when one of u or d is empty?
16:53tonylLeonidas: instead of merging can't you just create the new map (def newmap {:up u :down d})
16:56mabesI have some namespaces that need to be AOT, so I have configured my project.clj (lein) to compile them.. however, I keep running into state class files when testing. Is there a way to have the compile task always run before "lein test"?
16:56mabeser.. state -> stale class files
16:56Leonidastonyl: yeah but I need to transform both u and d dicts and so far I don't even know how
16:57amalloyLeonidas: (into {} (for [user (set [(keys u) (keys d)])] {:u (u user), :d (d user)})) looks like a good start to me?
16:59Leonidas(fmap (fn [k v] [k {:downvotes v}]) d) does not work that well :/
17:00amalloy(into {} (for [user (set (mapcat keys [u d]))] {user {:u (u user) :d (d user)}}))
17:00Leonidasamalloy: returns {:u nil :d nil}
17:00amalloyLeonidas: yes, i was sorta thinking out loud. the second one will actually work
17:01Leonidasamalloy: yep, thank you. Will need a bit of time to tinker with it to understand.
17:02amalloyLeonidas: take the keys from both maps, and iterate over the distinct keys. for each key, look up that key in each map and create an entry in the new map with appropriate :u and :d entries
17:07Leonidasamalloy: thanks, I think I get it now. I modified it slightly to set 0 instead of nil for unknown keys and it works perfectly
17:07amalloysure
17:17sarcher|workwhat's the best way to add up a list of numbers in clojure?
17:17Derandersarcher|work: probably (reduce + list)
17:17amalloysarcher|work: or #(apply + [1 2 3])
17:17qbgOr (apply + coll)
17:18sarcher|workI was trying apply + coll
17:18sarcher|workand having trouble
17:18amalloysorry, no # (apply + [1 2 3])
17:18Deranderyeah, apply is probably faster
17:18sarcher|workwow the lack of parens was what was getting me
17:18amalloylol, it's getting less readable by the second. what goes wrong when you try apply?
17:18qbg+ will use reduce anyways...
17:18sarcher|worki thought you had to put + in parens
17:18sarcher|workwith a % or something
17:19Derandersarcher|work: (apply #(+) [1 2 3]) ?
17:19Deranderno
17:19sarcher|worki guess since you are passing it as an argument that makes sense that it doesn't need parenthesis though.
17:19Derander#() is the anonymous function syntax
17:21sarcher|workwhat do y'all think about this - http://pastebin.com/xNNf3j1g
17:21qbgPrefer names such as my-add and divides?
17:22sarcher|workAdd all the natural numbers below one thousand that are multiples of 3 or 5.
17:22sarcher|workyeah sorry for the names
17:22qbgisDivisibleBy is too specific
17:22Leonidascan i destructure a map somehow?
17:23qbg,(let [{:keys [a b c]} {:a 1 :b 2 :c 3}] [a b c])
17:23Leonidas(for [[k {:upvotes u}] v] k) where v is a map
17:23clojurebot[1 2 3]
17:23amalloyLeonidas: ##(let [{a :a} {:b 1 :a 1}] a)
17:23sexpbot⟹ 1
17:23qbgsarcher|work: The or should be in filter's fn
17:24sarcher|workthanks qbg
17:24amalloyqbg, sarcher|work: i'd do it differently: (defn divides-any? [x divisors] ...)
17:25Leonidasamalloy: ah, I get it. I got the syntax wrong but the general approach was good already :)
17:25amalloysarcher|work: so i think qbg and i, combined, are saying divides? should take either one factor or N, but not specifically two
17:25qbgamalloy: or (defn divides-any? [x & divisors] ...)
17:26sarcher|workyeah that makes sense
17:26amalloyqbg: yes, but i didn't want to get into & yet
17:27qbgThe (+ * %) in the apply part looks wrong
17:28qbgYou just want +
17:31BerengalIs it possible to force destructuring to match exactly?
17:33qbgBerengal: as in thrown an exception if the lengths don't match?
17:33amalloyBerengal: it's not clear what you mean. perhaps an example of what you wish worked?
17:33Berengalqbg: Yes
17:33qbgDon't think so
17:33Berengalamalloy: I'd ultimately like something like Haskell's case
17:34BerengalWith multiple paths depending on the shape of the value
17:34qbgThere are pattern matching libraries for Clojure
17:34BerengalAh, neat
17:37sarcher|workwhat are the prefered naming conventions for functions in clojure?
17:37sarcher|workdivides-any
17:37gfrlogthat sounds like a predicate
17:37gfrlogwhich end in question marks
17:37sarcher|workdash separated stuff?
17:38gfrlogyes
17:38sarcher|workusually lowercase?
17:38gfrlogyes
17:38sarcher|workso does the ? have any syntactic meaining or is it just a convention?
17:38gfrlogconvention
17:38sarcher|workah cool good to know
17:38gfrlogused when a function always returns a boolean
17:39joshua__Hmm. Having trouble finding someone that allows the selling of small files without a monthly charge.
17:41gfrlogDoes there exist a clojure templating language that functions like ERB? I'm assuming clojure.template is kind of a different thing
17:43iveygfrlog: https://github.com/mmcgrana/clj-html
17:44gfrlogwell I want to use it for latex
17:44gfrlogso I assume it would have to be simple insertion templating like ERB
17:52gfrlogI can probably write my own in 3 lines with gsub
18:12qbgNearly complete defn implementation using https://github.com/qbg/syntax-rules: https://gist.github.com/757885
18:14qbgThe error messages it produces aren't that bad also
18:15qbgNeeds more/better syntax sugar
21:06gfrlogthis templating idea is tricky
21:06gfrlogdue to the behavior of eval
21:50AWizzArdCurrently concrete implementations of protocol FNs in defrecords/types can not be closures. The docs also mention this. I am curious if this is technically not possible, because some JVM internas, or if it was intentional.
21:51AWizzArdExample: (defprotocol Foo [bar [this]]) and then: (let [x 10] (defrecord Baz [a] Foo (bar [this] (println x))))
21:51AWizzArd==> x can not be resolved in that context.
21:53cemerickAWizzArd: IIUC, that would require Baz to be an inner class, where x would be held in the outer class.
21:53cemerick(as a static field, presumably)
21:54AWizzArdAnd Baz should not be an inner class I guess.
21:55AWizzArdAnd could the closed over fields not be added as private vars to the Baz class?
21:55cemerickIt'd be particularly unfriendly if deftypes were to be alternately inner or "regular" classes, depending upon the presence of a lexical scope.
21:55gfrlog,(s2/replace "s" #"s" (fn [_] "\\node"))
21:55clojurebotjava.lang.Exception: No such namespace: s2
21:55cemerickWhat if you've got multiple defrecords in that let scope?
21:56gfrlog(clojure.contrib.str-utils2/replace "s" #"s" (fn [_] "\\node"))
21:56gfrlog,(clojure.contrib.str-utils2/replace "s" #"s" (fn [_] "\\node"))
21:56clojurebotjava.lang.ClassNotFoundException: clojure.contrib.str-utils2
21:56gfrloggosh dangit
21:56AWizzArdHmm okay, in that case the objects would be separate.
21:57amalloygfrlog: (constantly "\\node") is a simpler way to write that (fn)
21:57AWizzArdI just got used to proxy closures and liked that style :)
21:57gfrlogamalloy: I'm trying to demonstrate what appears to be a bug in s2/replace
21:57AWizzArdIt was not obvious to me why this should not work too for defrecords.
21:57cemerickAWizzArd: you're roughly looking to have static fields in your records, which almost certainly isn't going to happen. :-)
21:57gfrlogin my repl it evals to "node"
21:58cemerickAWizzArd: you can always extend Baz to Foo with a fn *shrug*
21:58amalloygfrlog: str-utils2 is way old, isn't it?
21:58gfrlogit is?
21:58gfrlogis there str-utils3 now?
21:59gfrlogooh clojure.string
21:59gfrlogI haven't gotten into that habit yet
21:59gfrlog,clojure.string/replace
21:59clojurebotjava.lang.ClassNotFoundException: clojure.string
21:59amalloy&(require '[clojure.string :as s])
21:59sexpbot⟹ nil
22:00gfrlogcan you have it eval my expr?
22:00amalloy(s/join " " ["a" "b"])
22:00AWizzArdcemerick: so the idea is to do the extend outside of the defrecord and have those bodies be closures?
22:00amalloy&(s/join " " ["a" "b"])
22:00sexpbot⟹ "a b"
22:00gfrlogmy repl has clojure.string with the same bug
22:00amalloy&(doc s/replace)
22:00sexpbot⟹ "([s match replacement]); Replaces all instance of match with replacement in s. match/replacement can be: string / string char / char pattern / (string or function of match). See also replace-first."
22:00AWizzArdcemerick: or is the idea to call closed over defns from within the bodies?
22:00cemerickAWizzArd: extend takes regular ol' functions, which are definitely closures.
22:01AWizzArdI didn’t know that, interesting. Does this come with a performance hit?
22:01gfrlog&(s/replace "s" #"s" (fn [_] "\\x"))
22:01sexpbot⟹ "x"
22:01amalloy&"\\x"
22:01sexpbot⟹ "\\x"
22:01gfrlogis there any reason to expect the string to be escaped twice?
22:01gfrlog&(s/replace "s" #"s" (fn [_] "\\\\x"))
22:01sexpbot⟹ "\\x"
22:01amalloygfrlog: oh, i see
22:02gfrlogI say it's either a bug or at least terribly counterintuitive
22:02amalloythe replacement is probably allowed to have backreferences like \1
22:02gfrlogoh I bet it is
22:02cemerickAWizzArd: compared to any other protocol dispatch, no
22:02gfrlogthat's not necessary though since the fn takes the match :(
22:02gfrlogoh well
22:02amalloyyeah
22:03gfrlogif I had ever filled out a contributer thing I'd go amend the documentation
22:03gfrlogcuz that just took me an hour to figure out
22:04cemerickgfrlog: you still can :-)
22:04gfrlog&(s/replace "s" "s" "\\x")
22:04sexpbot⟹ "\\x"
22:04gfrlogcemerick: I can fill out the form you mean?
22:04cemerickright
22:05gfrlogyou're telling me that code doesn't get written just by griping in an IRC channel?
22:05AWizzArdI thought that inner implementations and extend / extend-type / extend-protocol are all the same.
22:05cemerickAWizzArd: from the standpoint of a protocol fn invocation, they are
22:06cemerickThe former are methods bolted into the generated class though; the latter are not.
22:06AWizzArdI see.
22:07AWizzArdcemerick: thanks for your explanations :)
22:08cemerickAWizzArd: np, hope they help :-)
22:08AWizzArdyess
22:31auserhola all
22:33auserhas anyone implemented a proxy server in clojure?
22:53AWizzArdauser: can you be more specific?
22:56auserah fair enough AWizzArd... I mean... I'd like to accept socket requests on a port and route requests according to the request details to other internal ports
22:56AWizzArdauser: similar to ssh -D ?
22:57AWizzArdWhat I did was using Jetty to proxy a binary B. So, clients can send jobs to B through my rest interface.
22:57auserI've done it in erlang, ruby and c, just haven't done it in clojure yet
22:57auserI was thinking using jetty
22:57auserhttp://www.jboss.org/netty/documentation.html (Proxy Server)
22:57auseryeah, exactly
22:58AWizzArdIt’s a good choice to start with. Or netty, yes.
22:58auseris your code open-source, by chance?
22:58auseryeah
22:58AWizzArdI didn’t do Netty yet, because this targets other use cases, but in principle it’s the same.
22:58auserwhat's the difference?
22:59AWizzArdNo, this code is closed-source (for the company i work for).
22:59auserah fair enough
22:59AWizzArdNetty is good when you have a massive amount of ultra short running requests.
22:59AWizzArdJetty is for everything else.
22:59AWizzArdSo: echo server ==> Netty
22:59auserso netty is more concurrent, it sounds like?
23:00AWizzArdNetty is non-blocking.
23:00auserahh
23:01AWizzArdAlso Jetty has very nice support.
23:01ausermaybe something like this: http://efreedom.com/Question/1-1735776/Server-Programming-Clojure ?
23:01AWizzArdYou can suspend running threads
23:01ausercool
23:02AWizzArdauser: basically what I did was: setting up a resource, for example: POST: https://example.com/process and my handler sends the job to a Clojure agent which operates the Binary.
23:03AWizzArdDone with promise injection and an agent, though an ArrayBlockingQueue is an even better fit :)
23:04auserinteresting, I am using LinkedBlockingQueue
23:04AWizzArdyes, also fine of course
23:04auserrather, I'm not familiar with ArrayBlockingQueue
23:04auseryep yep
23:05AWizzArdMy point was more about using a Queue from the j.concurrent package, so, the LBQ is fine.
23:05auserah yeah
23:07AWizzArdauser: about the link that you posted — depending on what you want to do you should look into Jetty.
23:07auseryeah, that's a good thought. I'll look more heavily into Jetty
23:08AWizzArdNetty uses only a small number of threads. If one request is long running then all clients in the work-queue of that thread will have to wait, while Jetty would serve them cause its thread pool will grow.
23:09AWizzArdOnly if you plan to do 10k echo requests it would be overkill to make use of 10k threads, so this is were Netty would perform better.
23:09auseryeah, that's a good point, actually
23:09auserno, most would not be echo requests
23:10AWizzArdauser: also in Jetty you can suspend threads. So for example, if a job is coming in and you need to do IO such as writing into a DB for, say, 25 msecs, then you can suspend the Jetty worker thread for those 25 msecs.
23:11AWizzArdDuring this time it sits in the pool and is able to serve other requests. And when the DB has finished the thread can be resumed and answer the client.
23:11ausercool, that's a good idea
23:11AWizzArdSo, that allows for nice concurrency.
23:11auseryeah, definitely!
23:11auserhey, be right back
23:12AWizzArdauser|brb: you would like to read this: http://wiki.eclipse.org/Jetty/Feature/Continuations (6 minutes reading time required)
23:18auser|brbhey thanks AWizzArd
23:47auserit's possible to call (gen-class :name MyException :extends [Exception]) still, right?
23:47auserwhen I do that, I get: Unable to resolve classname
23:52auseror I could use error-kit