#clojure logs

2009-10-28

00:00somniumLicenser: heyyy
00:00hiredmanrewriting syntax-quote-reader so it actually works is the only implentation let, after that I just need to clean my reader up, and figure out a nice way to include it in the build process
00:00LicenserI forked you :P muhahah
00:00somniumLicenser: almost got 0.1 ready
00:00somniumalready?
00:00somniumits about to change a lot, for the better
00:00Licenseryea wanted to try it ^^
00:00somniumgot a working little ClojureDBObject java class that does all that tree walking work
00:01somniumcleaning up the core so its actually readable now, dropping coerce.clj entirely
00:01hiredmanhttp://rubyrags.com/products/10
00:01Licensernice
00:01Licensersomnium: I found a few things I needed and figured it's a good chance to try out github :P
00:01somniumits funny, after a night's sleep that java didn't look so bad
00:02LicenserWhat did you do before sleeping finish up a bottle vodka alone?
00:02somniumI'm considering doing an immutable proxy, itll be interesting to benchmark and see how much overhead using a ref involves
00:03Licenserheh yup that would be interesting
00:04somniumLicenser: a corner, a stuffed animal, and a bottle of vodka
00:04Licenserah okay that explains a lot
00:05somniumalso switch to 1.0 core and contrib, and I'll put the needed mongodb-drivers in the jar
00:05somniumhopefully itll be more plug and play
00:05somniumits never good when something can blow up on build
00:06Licensertrue
00:06somniumLicenser: did you manage to do anything with it in any case?
00:06Licenseryes it is working quite well, biggest problem I had was that object-to-map did ont work on recursive objects
00:06somniumyeah, its tricky
00:07Licenserwell that one I fixed :P
00:07somniumthere are some things to do with encodings, but its broken right now and presumably the dev's are sleeping
00:07somniumcool
00:07somniumwith a walker?
00:07somniumits hard to find non-recursive solutions to nesting problems
00:07somniumthats what the little java class helps with
00:07Licensersomnium: actually I borke it again ... narf
00:08Licenserwell I just recursively called the function
00:08somniumand keywords for keys again
00:08LicenserOh you removed keywards as keys again?
00:08somniumI did before because it was broken
00:08somniumnow they're back
00:09somniumthe proxy class is a hashmap, you can bang on them in java
00:09Licenserheh Okay then I had the string version which brakes my code :P that is why I'm so confused
00:09somniumdefault is to convert stuff to clojure, but if you want to optimize something its right there
00:09somniumhmm, I would push but only fetch is working now, if youll be around for an hour it might be ready to try out
00:10LicenserI'll be
00:14somniumwhat do you think about a defschema macro? I don't think the keys on most leaf nodes won't vary too much, and that way the deserializer knows what to do with each key
00:15qedchouser: are you around?
00:15qedchouser: im wondering if you could explain some stuff about your problem 59 on proj. euler
00:15Licenserdefschema? I've a older version I think
00:16Licenserthis one still uses defcoercion
00:16somniumyeah, its orthogonal
00:17somniumhttp://paste.lisp.org/display/89409 <- sneak preview, more readable?
00:17Licenserso there isn't any defschema in the version I forked
00:17somniumyeah, I haven't added it yet
00:18somniumbut I think most of the low level problems are almost done, so can start adding more ORMy features
00:18Licenserone thing, you should decide if you call it col or coll ;)
00:18Licenserthat was one of the things I changed :P
00:18somniumah, in the arguments?
00:19Licenseryap the functions are called *-coll the arguments are called col
00:19LicenserI found that kind of confusing in the beginning, since I wasn't sure if you refer to different things that start with col* there
00:19somniumI don't like using coll in arguments cause that's name clojure uses for collections
00:20somniumand collection is too many keystrokes
00:20somniummaybe Ill change it to 'c'
00:20Licenserthen name the functions -col too ;)
00:20somniumok
00:20Licenseroh and I changed every argument that was named map to m
00:20somniumlook at the paste
00:20Licenserwhen you call an argument map, it hides the map function in the rest of the body :P
00:20somniumthat function is what coerce.clj was
00:21Licenseroh wow
00:21somniumand it even does more :)
00:21LicensertoClojureKeywordArrayMap is sneaky
00:21somniumthe keywords are kind of a hack, mongodb has no default way to recognize them
00:22somniumif I can get the encoding bug sorted tomorrow it might be possible
00:22LicenserI know they use string keys
00:22somniummongodb supports custom binary types
00:22somniumthe java driver doesn't support it, but eliot said it would be trivial to add
00:22Licenseryes but storing keywords in a custom binary, isn't it easyer to store them in strings
00:22somniumit is if a fast little java class does it for you
00:23LicenserBah java classes
00:23somniumit'll be possible to create custom binary types for any arbitray class
00:23RaynesBah, Java.
00:23somniumand that means defschema could gen-class a struct map, all kinds of cool and efficient automagic become possible
00:25Licenser=) yea I was wondering if you could use a structmap to represent the data since most of the time you've at least a subset of keys that are always there
00:26somniumyeah, and if you have embedded document slot the deserializer just has to know, know reflection, no tree walking
00:26qeddamn you euler!
00:26qedoiler = euler
00:26qedcoincidence
00:26somniumer, no reflection
00:26Licensernice
00:35LicenserI really see forward to the next version :P
00:37somniumI'm glad your helping test it, I want to make a good impression of mongo + clojure when I start encouraging people to try it :)
00:38somniummaybe you could write a mongo-compojure todo example :D
00:39Licensersomnium: I will once I get it working ;)
00:40Licenserand I'll wait till you have it half way beta
00:40somniumyeah, I'm actually planning to use it for a prototype due next week
00:41somniumso I really want to get something worthy of 0.1 finished tonight
00:41Licenserheh
00:41Licensersee and it's not much sense to write a how to when you change everything away under my ass while I write it .P
00:41somniumtrue
00:41somniumthe readme I did was mostly an exercise in learn markdown :)
00:42Licenser^^
00:43Licensermongo is a lot easyer then SQL once you get the things actually working o.O
00:44somniumyeah, the only place it falls down is if you need complex transactions
00:44Licensertrue but at least I don't need them
00:44somniumthough to be honest I can't recall the last time I needed them for a web app
00:44Licenserexactly :P
00:45somniumer, that should be never
00:45Licenseralso I'm pretty sure you could wrap them in a clojure transaction and bunch commit
00:45somniumtrouble is its all side effecty
00:45somniumthe dbobjects, server messaging
00:45somniumno way the stm can help with that
00:46somniummongo has to support it server-side
00:46Licensertrue
00:46somniumhrm, does it support transactions at all?
00:49Licenserno mongo is non transactional
00:49somniumtheres an 'update-if-current' command
00:51somniumif x = y, set x to z, else fail
00:51somniumthat can lock an entire document
00:51somniumgood enough for me :)
00:51Licenserheh
00:52Licenserhrm
00:53adityoGood morning all
00:53adityo:)
00:54Licensermorning adityo
00:54Licensersomnium: but I see your point mongodb destroys the nice concurrency of clojure, at least makes it not so easy :(
00:54Licensernot that one needs it for a web app :P
01:00somniumwho knows, mongo is developing rapidly, the dev team is awesome
01:00somniumevery time I ask how to do something they say if its a bug we'll fix it, if not we'll try to add it
01:00somniumer, ask for something not supported (in the java driver anyway)
01:01somniumand within 10 minutes there's a fresh push to github
01:01Licenseryap
01:01Licenserthey seem cool
01:01LicenserI was in the channel to ask a few questions and the peopel really helped me
01:01Licensermy experience is that for underdog projects it's easyer to get help the more prominent a project is the less friendly are the people
01:02Licensertry to ask a VB questions - no chance :P
01:02somniumheh
01:02Licenserseriousely, even the ruby community got gess friendly the more prominent the language became - at least it is my impression
01:03LicenserFor Solaris people try to help you for most linux distributions you get just told RTFM
01:03somniumIve seen people be pretty rude in the ruby channels
01:04Licenseryes but it hasn#t beent that way some time ago (like in the area of years), at least I haven't seen it there
01:04Licenserhrm I've a seriouse problem
01:04somnium?
01:04Licenserupdate kills my db entry
01:05somniumthats no good
01:05Licenserif I don't pass all arguments to update it just removes the others o.O that is very odd
01:05somniumI would say paste the before and after, but its all getting rewritten
01:05somniumLicenser: ah, look at the code then, its meant to be used with all three arguments
01:05somniumthe shorter versions should carry warnings
01:06somniumthey're convenient if they do exactly what you want (or that was the intention)
01:06Licenserhmm but it's a mongo thing
01:06somniumreally?
01:06Licenseryes it's scarry
01:07somniumsomething like {:match :this} (merge old-map {:change :this}) should work?
01:07Licensernot for bulk updates
01:07somniumah, I haven't tried those
01:07somniumdoing javascript?
01:08Licenseryes I tried it from the console now
01:08Licenserto see if it is a problem with mongo, or with something between my app and mongo
01:08Licensersince it happens on the DB it seems that it is a problem with mongo :P
01:09Licenserah I've to use $set
01:09Licensersneaky
01:10somniumthere's a thread on the mailing list saying its not supported until 1.1.3
01:10LicenserI have 1.1.3
01:10Licenserso I really would expect update to update not replace
01:11Licenserow
01:11somniumwell, as long as its just surprising and not broken
01:14Licenserit tells me: when using $ modifiers, apply has to be false
01:15Licenserseems like a problem in your driver :P *hides*
01:16Licenserhrm not good
01:17Licenserodd
01:17somniumhmm
01:18somniumwhat command exactly?
01:18somniumI took out the '> shortcuts for now
01:18Licenserupdate but diggind deeper it seems to come from java
01:18Licensernah I sed $set in the update statment
01:18Licenserjava.lang.IllegalArgumentException: when using $ modifiers, apply has to be false
01:18Licenserthat is what it says
01:19somnium{ :x { "$set" : "this" } } ?
01:20somniumhmm, I know the java-driver better than I know how to use mongo at this point :(
01:20Licenser{$set: {:x "this"}}
01:20Licenserthis one
01:20Licenser{"$set" {:x "this"}}
01:20Licenserrather that
01:21somniumI think it should be {:x {"$set" ... } } no?
01:21somniumyoure right
01:21Licenserworks on the console like this: > db.map.update({x: 5, y: 5}, {$set: {"owner.id": 42}})
01:22Licenserso this apply thing has to do with the java driver, which I've no clue off
01:22somniumah I know
01:22somniumthere's a flag on update
01:22somniumcheck the source, update sends true true at the end
01:22somniumusually you want apply, it adds _ns and _id if they're missing
01:22Licenserthere are two flags, one says upsert the other multi
01:23somniumon the java call
01:23LicenserI know was the first thing I looked at but the API says those two are upsert and multi nothing with apply
01:23somniumI know I saw it somewhere
01:24somniummaybe BasicDBObject? or DBCollection?
01:24Licenserit is a function of the Collection
01:25Licenserthere is a apply function in the collection but I don#t see it called anywhere
01:25somniumwill definitely need more granular control of cursors and collections in the api
01:26somniumis there a setter? setDoApply or something?
01:26Licensernope only 3 methonds, apply, apply and doapply
01:27somniumhmm, I'm out of my depth
01:27Licenserme too sadly
01:31somniumLicenser: you can go low level for the time being, until the Mongo devs wake up
01:31Licensersomnium: hm?
01:32Licenseroi a new one: No matching method found: updateMulti for class com.mongodb.DBApiLayer$MyCollection
01:32Licenserwhile that is in the API documentation o.O
01:32somniumyeah the API Docs aren't totally reliable
01:32somniumthere's a missing fetch with skip, limit options too
01:32somniumforgot to ask about that
01:32somniumit'll help if youre asking questions about the java driver too :)
01:32Licenserah wait no it's in the wrong doc
01:32Licenser*g*
01:33somniumDB has an eval method
01:33somniumyou can send javascript, though I'm not quite sure how it works
01:33somniumhopefully anything broken in the driver can get through there when things like this happen
01:34Licenserah sneaky
01:39Licenseroh fork
01:39Licenserof cause the DB does not know eval :P
01:40somniumthe db object in *mongo-config* is actually a DBTCP, you might have to get a hold of a lower level class
01:41somniumjust read the javadoc!
01:41somnium* hides *
01:42Licensersomnium: sadly DBTCP isn't documented :P
01:42somniumthe DB class is, that's where eval lives
01:42Licenseractually it si
01:43somniumI was creating the DB object through Mongo which return a DBTCP object
01:43somniumbut you can also go through the DB class? no idea, there's way too many classes in that damn package
01:43Licenserbut it should have eval
01:43Licensersomnium: yes there are
01:43Licenserand I hate javadoc :P
01:43Licenserit's the same problem as with every inline documentation
01:43somniumif the design is good and the package structure is good, they can be very useful
01:43somniumnot the case here
01:44Licenserwhen you see the code of the function a half line doc might be helpful, if you don't it is often not
01:44somniumreally, should ByteEncoder and BasicDBObject live in the same package?
01:44Licenserheh
01:45Licensersadly eval isn't documentaed at all
01:45somniumyeah, it sucks, no idea what the Object argument is supposed to be
01:46Licenser*nods* I skpped it since I found ... means 0 or more :P now I'll just pass #^Object nil
01:47somniumcool
01:47Licenserdoes not really work either
01:48somniumhmm
01:48somniumdoseq update till the devs wake up?
01:48Licenserand netbeans seem to ahve a very odd idea about reloading
01:49somniumif youre feeling adventurous you could look at Message... classes
01:49Licenserheh
01:49Licensersoon I can go and grab breakfast :P
01:50Licenseruser=> (mongo-eval! "db.map.update({x: 5, y: 5}, {$set: {'owner.name': 'Test Owner'}})")
01:50Licenser#<BasicDBObject { "retval" : null , "ok" : 1.0 , "_ns" : "$cmd"}>
01:50Licenserwooh!
01:50somniumawesome
01:50somniumcould you paste mongo-eval! ?
01:50Licenserthat works
01:50Licensersure
01:50somniumI'll definitely add that as a backdoor
01:50somniumit'll always need to be there :)
01:51somniumsweet
01:51Licenserwooh now I contributed :P
01:52somnium! :)
01:52somniumhuh, so it did work on DBTCP after all
01:52Licenseryap just you need a nil in there
01:55Licenserokay this is so horribly going to break ...
01:55somnium?
01:56Licenserthe hacked together eval stuff :P
01:56somniumcontrib.json might help
01:57LicenserI used the mongo one
01:57somniumI'm hoping to get a hook into the JSON writer too
01:58somniumor, actually there's one now, but it's broken
01:58Licenserheh
01:58Licenserokay I will use contrib.json
01:58somniumit speaks native clojure at least
02:00kanakWhich is better (more idiomatic/faster/etc): doing something like (reduce * [1 2 3]) or (apply * [1 2 3]) ?
02:00somniumkanak: reduce
02:01kanakthanks. is it because it signals the intention more clearly?
02:01Licenserapply is better
02:01Licenserat least I find it
02:01somniumthey do different things
02:01somniumit would be easier to say with something other than *
02:02Licenseryes but for this case it's faster to do (* 1 2 3) then (* (* 1 2) 3)
02:02somniumkanak: apply = unpack this list, reduce means create a single value from this collection
02:02somniumkind of
02:03somnium,(time (apply + (take 10000 (iterate inc 1))))
02:03clojurebot50005000
02:03clojurebot"Elapsed time: 56.728 msecs"
02:03Licenserwoha yea!
02:03somnium,(time (reduce + (take 10000 (iterate inc 1))))
02:03clojurebot50005000
02:03clojurebot"Elapsed time: 28.939 msecs"
02:03somniumsee its faster :)
02:04kanakcool :)
02:04Licenserokay now I'm impressed AND confused
02:04kanakis reduce a left-fold or a right-fold?
02:04Licenserhmm but I think that is because the list is unpacked the first time
02:05Licenserhrm how again could I force a lazy seq to unlasy?
02:05kanakit'd be interesting if we could compare the space usage of the reduce vs apply.
02:06Licenserreduce will have less space usage
02:06Licenserbecause it only needs 2 elements from the list
02:06Licenserand if your list isn't static but a lazy seq they will be GC'ed at some point
02:07kanakLicenser: by 2 elements, you mean the "answer so far" and the the first element from the list. right?
02:07somniumyeah, reduce is a shortcut for loop
02:07somniumunless you need mutual recursion
02:08somnium^^ doall and dorun, depending on what you want it to return
02:08Licenserkanak: yap
02:09Licensersomnium: I wanted to have the expendet list in the end :P
02:09LicenserI want to see if reduce is faster because it's faster or because the test case is a lazy seq
02:10somniumwell, I don't know what the byte code did, but the test apply was like make a list with (* and those 10000 numbers)
02:10somniumactual limit is capped at 18 or so
02:10kanakIs this correct: since reduce, take and iterate are working lazily, when reduce needs the next element, it asks take, which asks iterate. So at each point we only have one element (i.e. the whole list is never in memory at any time)?
02:11somniumyou have the answer so far and the next item in each iteration
02:11somniumuntil no more items
02:12kanakwhat about the previous items (i.e. items whose values have already been used)? They're simply discarded, and will be GCd right?
02:13somniumyeah, the current item only every exists as a local variable in the last stack frame
02:13somniumthe previous version of the list too
02:13somniumso it handles memory well
02:13Licenserkanak: since noone knows what the GC does it can't be guaranteed
02:14kanakI see. thank you both :)
02:14somniumfor small operations like that its probably on the stack
02:14Licenserbut the list will never flood your memory
02:15somniumjust dont do this
02:15somnium,(iterate inc 1)
02:15clojurebotEval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space
02:15Licenser:P
02:15kanakheh. that's evil
02:15LicenserI think the problem is the print
02:15Licenser,(def x (iterate inc 1))
02:15clojurebotDENIED
02:15somniumyeah, poor little guy tried to print the answer
02:15Licensernarf
02:16Licenser,(second x (iterate inc 1))
02:16clojurebotjava.lang.Exception: Unable to resolve symbol: x in this context
02:16Licenser,(second (iterate inc 1))
02:16clojurebot2
02:16Licenserthere we go
02:16Licenserdidn't took much time to calculate all numbers :P
02:17somnium,(nth (iterate inc 7) 4242)
02:17clojurebot4249
02:17Licenserhmm somnium the eval works fine, my project is running so far
02:17somniumLicenser: good to hear it
02:17somniumhmm
02:17Licenserhmm hmm
02:17Licenserdo you wonder what I wonder?
02:19somnium(nth (iterate #(+ 7 %) 0) 4242)
02:19somnium,(nth (iterate #(+ 7 %) 0) 4242)
02:19clojurebot29694
02:19somniumhe counts pretty fast
02:19Licenserif you catch a hold of the mongodb dev people, could you ask them about the update thing? I'll not be around for the day since I've to head to wokr in 30 min
02:19hiredman~clojurebot
02:19clojurebotclojurebot is amazing
02:19hiredman~clojurebot
02:19clojurebotclojurebot is not a benchmarking platform
02:19somniumsure
02:19somniumlol
02:19Licensersomnium: comon it are only 4242 numbers
02:20Licensereven ruby does it instantly
02:21Licenser~hiredman
02:21somniumcould you paste what was broken? I'm not sure I know quite what to ask
02:21clojurebothiredman is slightly retarded
02:21Licenser:P
02:21hiredmanclojurebot: watch it
02:21clojurebotHuh?
02:22hiredmanclojurebot: you heard me
02:22clojurebothiredman: I'm just giving you a second chance
02:22somnium~botsnack
02:22clojurebotthanks; that was delicious. (nom nom nom)
02:22hiredmanclojurebot: why I outta!
02:22clojurebotwhy not?
02:23somniumhiredman: shouldn't (nom nom nom) come before he says delicious?
02:23Licenserand with
02:23Licenser*
02:23Licensernot (
02:23Licenseractions are classically indicated with * IRC isn't lisp
02:23Licenser~somnium
02:23clojurebotNo entiendo
02:24hiredmanthe nom nom thing is just another factiod, someone told it that was the proper response to "botsnack"
02:24hiredmanclojurebot: seen somnium
02:24clojurebotsomnium was last seen in #clojure, 1 minutes ago saying: hiredman: shouldn't (nom nom nom) come before he says delicious?
02:25Licenserclojurebot: do you want cookies?
02:25clojurebotGabh mo leithscéal?
02:25Licenserwho set the bit to spanish o.o
02:25somniumhiredman: well I suppose that's true
02:25hiredman~google Gabh mo leithscéal
02:25clojurebotFirst, out of 2180 results is:
02:25clojurebotUrban Dictionary: gabh mo leithscéal
02:25clojurebothttp://www.urbandictionary.com/define.php?term=gabh%20mo%20leithsc%C3%A9al
02:25somnium~php
02:25clojurebotGabh mo leithscéal?
02:26somniumhe really should have something to say about that
02:26somnium~microsoft
02:26clojurebotNo entiendo
02:26somnium~java
02:26clojurebot
02:28somnium~scheme
02:28clojurebotExcuse me?
02:30hiredmanclojurebot: programmer is <reply>"There has to be something a little wrong with you for you to be a really good programmer." -- L Peter Deutsch
02:30clojurebotRoger.
02:30somnium~self loathing
02:30clojurebotTitim gan éirí ort.
02:30somnium~google Titim gan éirí ort.
02:30clojurebotFirst, out of 850 results is:
02:30clojurebotIrish phrases in the Gaelic language - Irish sayings
02:30clojurebothttp://www.ireland-information.com/irishphrases.htm
02:32adityo~lisp
02:32clojurebotLisp isn't a language, it's a building material.
02:32adityo~perl
02:32clojurebotExcuse me?
02:32Licenseri notice that there is a time X in every IRC channel where peopel start to play with the bot. I bet they have kind of cute kittens sitting on the PC's as IRC bots, it's the only explenation for the enormouse interest and affection they can raise in people
02:35hiredmanI'd love to get clojure going on a pleo or an aibo
02:35somniumaibo was discontinued :(
02:36hiredmanwas the pleo for a bit, and now it's back
02:36somniuma lot of soldiers grow very attached to their bomb disarming robots
02:36somniumis it? good
02:36hiredmanmaybe even a little netbook+rc car
02:36Licenserno don't send the robot! I will go, we can't let him get hurt!
02:37somniumthey've run into exposed areas to save them
02:37Licensero.O
02:37somniumthe designers apparently try to make them as unlikeable as possible
02:38Licenserwow that is crazy
02:38Licenserhiredman: what is pleo?
02:39somnium~google pleo
02:39clojurebotFirst, out of 1100000 results is:
02:39clojurebotPleoWorld: The Home of Pleo, the Robotic Baby Dinosaur from Innvo Labs
02:39clojurebothttp://www.pleoworld.com/
02:39arsatikiit'd b cool to equip a pleo with a bluetooth receiver
02:40arsatikiso it could start following people who have their phones with them
02:41somnium~gumstix
02:41clojurebotPardon?
02:44Licenserhaha that thing looks funny
02:45Licenserbut no shipping to germany, narf
02:57Licenserokay peopel I need to go to work, take care and don't brake tne interwebs
02:58somniumcheers
02:58kanakis it more idiomatic to use memfn or to use an anonymous function?
02:58somnium(doc memfn)
02:58clojurebot"([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."
03:01kanakThe programming clojure book claims that anonymous fns should be preferred to memfn, which sounds a little odd. (pg 87)
03:02hiredman#() fn literals are used far more often than memfn
03:02hiredmanmemfn was created before #() existed, if I recall
03:03kanakI see.
03:03kanakhiredman: do you know of any projects with idiomatic clojure that is suitable for someone who is "intermediate" in clojure?
03:04somniumkanak: IMO the source code in contrib excellent for learning clojure idioms
03:05somniumkanak: core for that matter
03:05kanaksomnium: any libraries in particular?
03:05somniumthere's so many, the ones I use? :)
03:05somniumtry using contrib.repl-utils/show on the functions you already know
03:05kanaksorry. i meant are there any particular ones you're thinking of
03:06somniumer, source, not show
03:07somniumcore is best for 'idioms' probably
03:07somniumvery generic operations
03:07somniumcontrib is all specialized
03:07hiredmancore.clj is very readable
03:09kanakthank you both for your help. :)
03:10hiredmanhttp://delicious.com/clojurebot/pastbin+rhickey
03:10hiredmanhttp://delicious.com/clojurebot/pastbin+chouser
03:11somniumwow, hes already got a working prototype for defclass?
03:11somniumor is that a 'syntax prototype' ?
03:12hiredmanhttp://delicious.com/clojurebot/pastbin+technomancy
03:12hiredmansomnium: I think it works, I haven't checked
03:12somniumI have to say, its exciting to watch a project develop with such speed
03:19hamzahey guys, URLConnection getHeaderFields returns an UnmodifiableMap how can i turn this in to a clojure map? (hash-map fields) returns illeagelArgumentException?
03:22hiredmanhamza: (into {} fields) ?
03:25hamzathx that worked..
03:26hamzabut some now some vals are wrapped in UnmodifiableRandomAccessList do i have to iterate all and build it my self?
03:31hiredmanyes
03:32G0SUBwhat is the best way to manage settings for dev/production envs in a clojure app?
03:40hiredmanwell, you have a reader, so you can make a dev.clj and a production.clj
03:43G0SUBhiredman: how do I make sure one of the files is loaded automatically? (I am in Emacs/SLIME)
03:45hiredman(cond (.exists (File. "dev.clj")) (read (reader "dev.clj")) ...production.. ..testing...)
03:45hiredmandev.clj has a map in it, so that is in a function that returns a map containg your settings
03:48hiredmanyou could use a properties file if you want to be java about it
03:49hiredmanhttp://java.sun.com/javase/6/docs/api/java/util/Properties.html
04:06G0SUBhiredman: so, for production env, I will have to delete the dev.clj file?
04:07Fossihi
04:14hiredmanG0SUB: sure
04:14hiredmanw
04:14hiredmanhuh, this ain't vim
04:18G0SUBhiredman: the thing is, I was to keep both the files, but would want to selectively load one depending on one system property
04:27felzixHow do I find the intersection of two lists?
04:27felzixThe function "intersection" doesn't appear to actually exist in the 1.0 release.
04:27adityofelzix: might be useful if you convert them in to hash-sets
04:28adityohow will i merge a list of maps ({} {} {}) into a {}
04:28felzixhmm
04:28felzixwhat version did intersection get introduced?
04:29felzixnvm, I see
04:30adityo,(doc clojure.set/intersection)
04:30clojurebot"([s1] [s1 s2] [s1 s2 & sets]); Return a set that is the intersection of the input sets"
04:30hiredman,(reduce into {} '({:a 1} {:b 2} {:c 3}))
04:30clojurebot{:a 1, :b 2, :c 3}
04:30felzixIt keeps telling me that it can't resolve the symbol "intersection"
04:31felzixthe same is true of other set functions
04:31adityocool thanks hiredman :)
04:31hiredmanfelzix: are you using the clojure.set namespace?
04:31adityofelzix do a use or require
04:31felzixoh, I have to explicitly add it? I thought it came along with everything else
04:31felzixthat works! thanks!
04:31hiredmanit's included in the clojure jar
04:32hiredmanbut you have to require or use it or load it like every other namespace
05:49felzixThis function's return value isn't getting printed: (defn get-pos [tags]
05:49felzix (filter #(= (first %) \+)
05:49felzix tags))
05:49felzixany idea why?
05:50Chousukeprinted where? in the repl?
05:51Chousukealso, what is "tags"
05:51felzixI'm running a script containing (println (get-pos rest))
05:51felzixit's a vector of strings
05:53Chousuke,(println (filter (comp (partial = \+) first) ["+100" "100" "+50"]))
05:53clojurebot(+100 +50)
05:54Chousukethat would look a lot better in haskell :/
05:54felzixlol
05:55felzixoh. actually, it doesn't print anything after that call, even constant strings
05:55felzixso something else is amiss ;_;
05:56Chousukeweird.
05:56Chousukemaybe *out* is bound to something weird?
05:56felzixnah, printing works immediately before that call
05:56Chousukehuh
05:57felzixI get weird problems like this in clojure a lot. I suspect I'm misusing laziness somehow.
05:57Chousuketry using (doall (filter ...))
05:57felzixI tried that
05:57Chousukethough laziness really shouldn't affect this.
05:57Chousukeprintln will force the seq anyway
05:59Chousukefelzix: try adding (flush) after then printlns :/
05:59Chousukethe*
06:01felzixawesome!
06:02felzixit works. thank you!
06:03felzixso now at least I know the real problem is elsewhere
06:42yuraswhen I need to read X characters from BufferedReader. I see the way to do it by loop-ing: reading into characters array available bytes amount then converting to string, recur-ing until i have read X characters. maybe is there a better way? can I seq BufferedReader somehow?
06:43yurasIm sorry for my bad English.
06:52yuraslooks like i can utilize slurp* from duck-streams
07:06Fossiwe have the odd case that it seems that compojure is rendering faster if we put the "html-dsl" into a vector instead of leaving it in layz seqs
07:07Fossifrom what i have thought it should be slower because the list is traversed twice instead of only once during the render
07:07Fossisomebody got a clue why that could be?
07:11spuzHello, why is pos? called pos? What is that an abbreviation of?
07:12spuzAlso, why is (seq col) preferred over (not (empty? x))?
07:15liebkespuz: pos? is an abbreviation for positive?
07:15spuzah ok :)
07:30Chousukespuz: for the latter... seq is shorter :)
07:31spuzChousuke: but not so readable :p
07:31Chousukespuz: it's only not readable if you know nothing about clojure :)
07:31spuzor you don't know about seq
07:32Chousukewell, everyone should :P
07:32Chousukeanyway, that usage of seq is idiomatic, so all clojure programmers are expected to understand it :)
07:32spuzYeah, it's fair enough if it's a commonly used idiom
07:33Chousukekind of like if (!someptr) ... in C
07:34spuzwell that's C... :)
07:34Chousukethe idiom is still good
07:37spuzI find it interesting that sometimes Clojure appears to advocate making code easy to understand with its functional style, but other times seems to forgo readability for concision or elegance
07:38spuzI guess it comes down to what different people understand when looking at a piece of code
07:39spuzfor some people, the less code, the easier it is to understand. For someone with no background knowledge it's the complete opposite
07:39cgrandspuz: plus the truth value of seq means more than the truth value of empty?. With empty? you wouldn't be able to write (if-let [[x & xs] (seq coll)] ...) because there's nothing more to extract from "true this coll is empty".
07:40spuz(I'm going to have to look up if-let in order to understand that)
07:43spuzcgrand: I don't understand why you would want to do something like that.
07:43spuzwhat are you trying to do?
07:44cgrandusually when you check if a collectin is empty or not, the next thing you are going to do is to process it
07:44cgrandand if-let allow you to destructure the collection when it isn't empty
07:45gerry_hello
07:46gerry_i'm doing clojure socket read/writer test, don't konw why it not work
07:46gerry_i have attached reader and writer to one remote socket
07:47spuzcgrand I see, so that destructuring is an alternative to empty? first and rest ?
07:47gerry_first try readLine from socket it worked, but when i write to it, it always return nil to me
07:48gerry_(def socket (Socket. "igs.joyjoy.net" 6969))
07:49cgrandspuz: yes this if-let could be rewritten (if (empty? coll) (do something) (let [x (first coll) xs (rest coll)] do domething else)))
07:49cgrandor, using destructuring, (if (empty? coll) (do something) (let [[x & xs] coll] do domething else)))
07:49gerry_(def ins (reader (.getInputStream socket)) (def ous (writer (.getOutputStream socket))
07:50gerry_that's it
07:50gerry_(.readLine ins) work (.println ous "oops") not work
07:50spuzcgrand: that's nice :)
07:50gerry_i have tested it with telnet, it worked on both read and write
07:51gerry_what's wrong?
07:51gerry_telnet igs.joyjoy.net 6969 works
07:52cgrandspuz: another point of view of this argument is that there are more non-empty collections than empty collections, and, in clojure, there are more trues than falses (anything that isn't false or nil). So it feels righter to map the frequent cases (non-empty colls and trues) together. Hence it allows to return something more meaningful than simply "true".
07:52shmichaelHi everyone. Is there any way to determine in code if a given symbol is a macro?
07:53gerry_i can get one login: prompt from ins readLine
07:53cgrand(meta #'if-let)
07:53cgrand,(meta #'if-let)
07:53clojurebot{:macro true, :ns #<Namespace clojure.core>, :name if-let, :file "clojure/core.clj", :line 1166, :arglists ([bindings then] [bindings then else & oldform]), :doc "bindings => binding-form test\n\n If test is true, evaluates then with binding-form bound to the value of test, if not, yields else"}
07:53cgrandshmichael: see :macro true in the meta
07:53shmichaelcgrand: awesome, thank you
07:54cgrand,(-> #'when meta :macro)
07:54clojurebottrue
07:54cgrand,(-> #'map meta :macro)
07:54clojurebotnil
07:54shmichaelcgrand: yes, that is exactly what I need
07:54gerry_hmm
08:01gerry_does telnet directly output string to socket?
08:23shmichael,(-> #'when let :macro)
08:23clojurebotjava.lang.IllegalArgumentException: let requires a vector for its binding
08:24gerry_when-let?
08:26shmichaelI am trying to test if symbols are macros
08:26shmichaelBut this test fails for let
08:29avital-,(meta let)
08:29clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/let
08:30gerry_,(meta (var let))
08:30clojurebot{:macro true, :ns #<Namespace clojure.core>, :name let, :file "clojure/core.clj", :line 2851, :arglists ([bindings & body]), :doc "Evaluates the exprs in a lexical context in which the symbols in\n the binding-forms are bound to their respective init-exprs or parts\n therein."}
08:31chouser,(-> #'let meta :macro)
08:31clojurebottrue
08:31chouserlooks right
08:31gerry_,(-> #'let meta)
08:31clojurebot{:macro true, :ns #<Namespace clojure.core>, :name let, :file "clojure/core.clj", :line 2851, :arglists ([bindings & body]), :doc "Evaluates the exprs in a lexical context in which the symbols in\n the binding-forms are bound to their respective init-exprs or parts\n therein."}
08:33avital-,(-> {:a {:b 3}} :a :b)
08:33clojurebot3
08:33avital-nice
08:34gerry_,(def socket (Socket. "igs.joyjoy.net" 6969))
08:34clojurebotDENIED
08:34shmichaelgerry_: thanks
08:35shmichael,(-> let meta :macro)
08:35clojurebotjava.lang.Exception: Can't take value of a macro: #'clojure.core/let
08:35shmichael,(-> (var let) meta :macro)
08:35clojurebottrue
08:36gerry_#'let = (var let)
08:36AWizzArdchouser: I find you also are one :)
08:38chouserAWizzArd: but you're *named* like one. I can't compete with that.
08:41AWizzArdTrue. Although I have a double z (while I am aware there should be only one).
08:44yurashow to convert "1234" -> 1234?
08:44AWizzArd,(Integer/parseInt "1234")
08:44clojurebot1234
08:44yurasonly java way, no built-in fun?
08:45notallamawell, you could also use the reader.
08:45yurasah ok
08:45AWizzArdyuras: this is not the Java way, it is the JVM way.
08:45rhickey,(read-string "1234")
08:45clojurebot1234
08:46rhickeybut
08:46AWizzArdThis would also work for very big numbers. But it does not document the code so well.
08:47rhickey,(read-string "foo1234")
08:47clojurebotfoo1234
08:47rhickey,(Integer/parseInt "foo1234")
08:47clojurebotjava.lang.NumberFormatException: For input string: "foo1234"
08:47yurasno questions. thanks
08:47AWizzArd,(BigInteger. "999999999999999999999999999999999999999999999") ; also works for possibly huge numbers
08:47clojurebot999999999999999999999999999999999999999999999
08:48AWizzArdand this is 5x faster than read-string
08:49yuras,(BigInteger. "foo123")
08:49clojurebotjava.lang.NumberFormatException: For input string: "foo123"
08:50eevar2,(read-string "99999999999999999999999999999999999999999999999999999")
08:50clojurebot99999999999999999999999999999999999999999999999999999
08:50rhickey,(bigint "1234123732198712398732178123987")
08:50clojurebot1234123732198712398732178123987
08:50AWizzArd,(BigInteger. "abc123" 16)
08:50clojurebot11256099
08:51AWizzArd,(BigInteger. "lfvegohplhcowhgpvlw0923857pn3w9207p" 36)
08:51clojurebot1760061993066943724720314159425702321837801663530174101
08:51AWizzArd:)
08:52arsatikiyou just never know when you're gonna need something in base 19 :)
08:54gerry_bigint not recognize other than 10base,right?
08:55AWizzArd,30rRIGHT
08:55clojurebot22370939
08:56djorkwow nice
08:58gerry_what's 30rRIGHT?
08:58notallamabase 30
08:58arsatikithe number RIGHT in base 30
08:58gerry_oh
09:00gerry_,16rabcd
09:00clojurebot43981
09:04gerry_,(-> 1 (+) (-) (*) (/))
09:04clojurebot-1
09:05gerry_,(into {} [:a 1 :b 2])
09:05clojurebotjava.lang.IllegalArgumentException: Don't know how to create ISeq from: Keyword
09:06AWizzArd,(into {} [[:a 1], [:b 2]])
09:06clojurebot{:a 1, :b 2}
09:07notallama,(apply hash-map [:a 1 :b 2])
09:07clojurebot{:a 1, :b 2}
09:07gerry_nice
09:08gerry_i donot figure out "into"
09:09gerry_(into {} '(:a 1 :b 2))
09:09chouser(into a b) is essentially (reduce conj a b)
09:10gerry_,(conj {} '(:a 1))
09:10clojurebotjava.lang.ClassCastException: clojure.lang.Keyword cannot be cast to java.util.Map$Entry
09:10notallama,(seq {:a 1, :b 2})
09:10clojurebot([:a 1] [:b 2])
09:10notallamamap elements are pairs. that's your trouble.
09:11gerry_ok
09:12gerry_,(conj {} [:a 1])
09:12clojurebot{:a 1}
09:13gerry_thx
09:16rhickeyso, in looking at defclass/deftype extensibility, I see 3 options: a) none, b) add extension fields explicitly (api tbd) assoc throws if key not present, c) implicit extension via assoc of not present key
09:17rhickeymy current feeling is that references (get/assoc) t fields not present should throw, just like fields access to fields not present throws, or vector index out of bounds
09:17chouserpicking too high a letter has worse consequences than picking too low a letter
09:19gerry_chouser: you mean a?
09:19rhickeyyes, although these would just be defaults, could opt out or for something else
09:19rhickeyI wonder how often field extensibility will be used, and in what ways
09:20rhickeyI've decided you'll always get metadata support
09:20chousergerry_: I mean if (a) is implemented, it would be easy to move to (b) or (c) later. If (c) is deployed, moving to (a) or (b) will be a breaking change.
09:20gerry_oic
09:21chouserI think (a) is pretty reasonable -- let people get used to these new constructs and see if there's much demand for expando and what those use cases look like.
09:21rhickeyeven with a), there's still a question of throw on get of non-field
09:23chouserI can imagine the assumption-checking of a throw on a bad get being helpful, esp. if there's no expando support at all.
09:24rhickeyaargh, is a mismatch with vector:
09:24chouseronce fields can be added on the fly the throw on a bad get seems like it might get annoying.
09:24rhickey,(get [0] 1)
09:24clojurebotnil
09:24rhickey,([0] 1)
09:24clojurebotjava.lang.IndexOutOfBoundsException
09:24rhickeychouser: really, you think the dynamic fields make a difference?
09:25rhickeyin my view, these structures are not like collections, so it's semantically less 'lookup' than 'access'
09:26gerry_i vote for expando support
09:26chouserI think so -- if a particular type has a fixed set of fields, looking up something other than one of those is a programming error frequently detectable (in theory) at compile time, so a throw at runtime seems to fit.
09:27chouserBut if one objects of that type can have different fields from each other (b or c) then you're going to want to start asking if an object has field :foo or not, and (:foo obj) is the most common way to test for that -- would be annoying if it threw
09:29gerry_i think if expend field, the type of object should change also,old object should be discard
09:29rhickeypeople have asked for a throwing getx already, could just be a general function
09:30rhickeygerry_: that's a whole different thing - you could just pour it into a map then
09:30rhickeyexpando is about retaining the type
09:31rhickeybut you can't dissoc a base field and retain the type
09:32rhickeyif get threw then you could use (get x k not-found) for speculative reads
09:32chouserthese are real types, right? With a set of interfaces implemented. Having that change when you do an assoc or dissoc would be unfortunate.
09:33chouser(x k nil)
09:33gerry_then i agree with chouser :)
09:33chouser(:k x nil) ... either way isn't too bad I suppose.
09:33rhickeychouser: defclass is a fixed type, deftype is an anonymous type, but with a stable type tag
09:34rhickeyI think if the not-found version doesn't throw, then you are set
09:35rhickeysince you'll have to know what you want if it's not there anyway
09:35rhickeyif we go with b), need an api for add-field/key
09:36chouseryeah, I could live with (x k nil). seems like a idiom change, but not a onerous one.
09:37rhickeyI think the vast majority of code manipulating these things will be using known fields
09:37chouserwhat's the benefit of (b) over (c)?
09:37rhickeysame - protection against accident. people that don't want expando, but are getting it by default, really don't want accidental expansion
09:38cemerickwhere might I look at the menu?
09:38rhickeyrhickey: so, in looking at defclass/deftype extensibility, I see 3 options: a) none, b) add extension fields explicitly (api tbd) assoc throws if key not present, c) implicit extension via assoc of not present key
09:39rhickeymenu^^
09:39chouserbut if it's easy to turn off the default expando support, you have protection right there. is it worth a new api for people who want to keep expando support but want protection from it?
09:40rhickeyalso - should (get x k) throw if k not present on a defclass/deftype thingy (new word for thingy desired)
09:40chouser"should (get x k) throw if k not present on a clabango"
09:41cemerickprobably not IMO, although that makes nil values tricky
09:41rhickeychouser: if (get x not-present-k) throws then b) seems symmetrical
09:41cemerickand I'd prefer C, FWIW
09:41chouserto be clear, if (get x bad-k) throws for one of these instances, would it also throw for regular maps?
09:41gerry_C
09:42rhickeythe whole point of these things is to replace classes/structs/ADTs etc
09:43rhickeychouser: the existing apis are collection oriented, not structure oriented, this is coming from the other end - small fixed things
09:43rhickeydynamic typing still means typing, i.e. some runtime check for correct use
09:44rhickeyits correct to add and lookup arbitrary things in a collection, not so for enumerated structs
09:44chouserthat sounds like (a)
09:45rhickey(deftype Foo [a b c]) (let [f (Foo 1 2 3)] (:d f)) is just a plain mistake
09:45cemerickI strongly disagree. Without C, miscellaneous or orthogonal data will drift into meta, which is often not desirable semantically.
09:45cemerickor structs will grow a near-universal "properties" slot.
09:45chouserfor (b) we'd need a new assoc, so a new conj would also be desirable and therefore a new into
09:46rhickeycemerick: that doesn't demand c), b) would work ass well
09:46rhickeyas well
09:46cemerickrhickey: does B buy anything w.r.t. perf, or is it just a "protective" policy
09:46cemerick?
09:47rhickeychouser: I'm not sure. At some point where you will be using assoc not for 'setting' an existing key but for establishing a new one, well, I think you are doing that more explicitly with these things than with collections. assoc for setting existing key wtill works fine
09:48rhickeythere's definitely an analogy to the associativity of vectors, where you can't get a new index by merely associng into space, you need to conj
09:48rhickeycemerick: dunno
09:49rhickeyi.e. assoc on vectors only works for existing 'keys'
09:49rhickeyuser=> (assoc [0] 0 1)
09:49rhickey[1]
09:49rhickeyuser=> (assoc [0] 4 1)
09:49rhickeyjava.lang.IndexOutOfBoundsException (NO_SOURCE_FILE:0)
09:49chouserbut at least 'into' still works on vectors. sounds like B would allow into to work only for pre-defined keys, not for expando? feels weird.
09:50rhickeychouser: conj could be the way to expand
09:50cemerickunless there's a specific benefit that warrants the mental overhead of managing whatever API comes with B, it doesn't seem worth it.
09:51rhickeycemerick: the benefit is that these things work like classes, not collections, since that will be their overwhelmingly primary useage
09:51chouserheh. cemerick and I are on the same side unless B gets rules out.
09:52chouserso (conj o [:new-key x]) might work but (assoc o :new-key x) might throw?
09:52rhickeyI think you have to ask - why use these things rather than, say, just maps?
09:53rhickeychouser: yes, same as vectors
09:53chouserhmph.
09:53cemerickrhickey: Because you have a set of standard, defined slots, and then a set of optional slots that are context-dependent, for example.
09:54cemerickand, having better-than-map perf for those standard slots is a huge benefit
09:54rhickeyone reason is to be able to implement interfaces, but you could do that with proxy, the other is that you weren't even using maps and couldn't, you were writing Java, There, you got compile-time enforcement of - can't access non-field 'd'
09:55rhickeynow you are going to move that code and not even get runtime enforcement of same
09:57chouserallowing (conj o [:new-key x]) hardly seems like enforcement
09:58rhickeychouser: it teases out the difference between set-existing and expansion, assoc sometimes does both (only for arbitrarily indexable things), conj always expands
09:58rhickeyset-existing is super important for straight data structures
09:59cemerickHum. Programming with map-like things is Good. Getting field-like perf on pre-defined map slots is even better. Having to jump through hoops to expand the map-like thing is bad.
10:00chouser(into o {:all 'new :keys 'here}) is hardly jumping through hoops though
10:00cemerickthe hoops here being having to ask "do I have a map or a deftype-thing?" any time one wants to push a value into an object.
10:00rhickeycemerick: conj is sitting right there
10:00cemerickchouser: on every assoc you might want to do?
10:01chouserbut if you actually mean to set a particular pre-defined key, knowing that (assoc o :good-key x) will catch typos might be helpful
10:01rhickeycemerick: I grant that moving exisitng map-based code onto b) is a problem
10:02chouserand it's so much less ugly than (set! (.good_key o) x)
10:02cemerickI know, but I still don't see the point of setting up the obstacle course. assoc works over *here*, but not over *there*, etc.
10:02cemericktypos? Surely a useful piece of functionality isn't going to get lopped off to "prevent typos". :-/
10:02rhickeycould be that the stricter put could get a new name
10:04rhickeycemerick: the typo becomes an undetectable error, these are dynamic 'types' not bags of stuff
10:04rhickeywe already have bags of stuff
10:04rhickeyand they are great
10:05cemerickindeed. I'm just saying that the opportunity appears to be available to have a 1 + 1 = 3 situation.
10:05rhickeybut they are substantially less definite than what people expect from types
10:06rhickeycemerick: I'm not sure b) isn't 3
10:06rhickeythese semantics are already in place (i.e. assoc might fail on invalid index, conj adds)
10:07rhickeyand these types might want to distinguish
10:07cemerickIt's probably a 2.3 or something. Catching typos or trying to maintain the integrity of a type, etc., seem pretty hand-wavey to me as reasons not to ensure that all map-like things share as many semantics as possible.
10:07rhickeyas possible
10:09cemerickRight -- vectors aren't sparse, so associng count + N simply can't succeed. maps and deftype-things don't have that hard restriction, tho.
10:09ttmrichterI'm going through the "Programming Clojure" book and hit a weird snag. The code that renames keys in maps doesn't seem to exist anymore. Using it gives me errors and trying (doc rename) also gives me an exception. What has the function name been changed to since the book's writing?
10:09rhickeycemerick: they do when backed by a non-expando class
10:10rhickeyor a bean, say
10:10cemerickrhickey: well, that's something that the programmer decided upon (or had decided for them, based on other decisions about framework usage, etc).
10:11djorkttmrichter: are you sure rename is not defined somewhere else in the book?
10:12chouserttmrichter: page 118 just under "Functions on Sets" sneaks in a (use 'clojure.set) that you need to call.
10:12tmountainis there a builtin way to print to stderr? right now I'm using a macro to wrap a *out* to *err* binding.
10:13rhickeycemerick: didn't you argue against dissoc for structs?
10:13ttmrichterchouser: I seem to be reading a different book than you. Page 118 isn't functions on sets for me.
10:13chouserttmrichter: hmph.
10:14djork,(defn rename [map key new-key] (let [value (map key)] (assoc (dissoc map key) new-key value))) (rename {:foo :bar} :foo :blah)
10:14clojurebotDENIED
10:14djorkwut
10:14ttmrichterchouser: I know whereabouts to look though, I think. I'm scanning quickly.
10:14djork,1 2
10:14clojurebot1
10:14cemerickrhickey: indeed, because removing a defined slot is a violation of an established type contract in a way that an addition of an arbitrary, undefined slot isn't.
10:14cemerickClearly IMO, of course. :-)
10:14chouserttmrichter: well, just try (use 'clojure.set) and then see if the examples you're trying to run work.
10:15ttmrichterchouser: 138 for me. It seems I have 20 extra pages somewhere. :D
10:15chouserdjork: that's clojure.set/rename-keys which is not quite the same as clojure.set/rename
10:15ttmrichterchouser: Thanks for the pointer. That would have driven me nuts for a while!
10:15djorkk
10:15chouserttmrichter: weird. I heard there was a second printing -- I wonder if that's what you have?
10:15djorkjust farting around, don't mind me
10:16ttmrichterchouser: I have no idea, honestly. I've got the PDF here. The hardcopy is (literally) on the slow boat to China.
10:16chouserttmrichter: heh. ok.
10:17ttmrichterIs this generally true for the data structure-specific functions: a (use 'foo) clause is needed for them?
10:18chouserttmrichter: no, clojure.set is the only one with its own lib
10:18chouserttmrichter: and it's mostly about relational sets-of-maps, not just plain sets of values.
10:18rhickeyin the end this is less about assoc than it is about get. If a defthing is non-expando (this will still be possible), then assoc on non-field will have to fail. get of non-key should fail as well, stronger (dynamic) type checking all around. Introduce expansion, then the question is should get move to more relaxed as does assoc? Or is there just an a/b/c knob?
10:19ttmrichterchouser: Yes, i'm gathering that looking at the examples. It's kind of cool to see the primitives of a relational-like database being made before my eyes here. Good book.
10:19rhickeyin most expando systems, get on missing fails, set on missing creates
10:20cemerickrhickey: fails with error, you mean, or just nil?
10:20rhickeyerror
10:21rhickeya completely different way of looking at this is that deflcass defines classes with ordinary fields. You can access them with .field. Saying .missing is a throwing error
10:22cemerickhuh. In all three languages I've used that had 'expando', get misses return nil (js, python, and clojure)
10:22rhickeybut defclass requires AOT, and you want more flexibility, so you move to deftype and :field
10:22cemerickI don't think there's any conflict in saying .missing is an error, but (get foo :missing) returns nil.
10:23rhickeynull or missing/undefined
10:23rhickey?
10:24cemerickwell, python only has None
10:25cemerickI'm pretty sure js returns its nil
10:25cemerickyeah, js returns null from document["blah"]
10:26chouserjs has too many nulls
10:26cemerickI think it has an Undefined as well, but I'm not clear on where it's used.
10:27chouserx["missing"] actually returns undefined
10:29cemerickhrm, maybe firebug is screwing with me
10:30cemerickchouser: are you sure? Object()["foo"] == null here
10:30djorkanybody here using LWJGL with Clojure?
10:30chouserfirebug's console shows undefined as nothing at all
10:30chousercemerick: undefined == null :-(
10:31chousercemerick: but undefined !== null
10:31djorkin JS you can just do undefined = x
10:31cemerickhuh. OK...well, Object()["foo"] == null as a single expression returns true *shrug*
10:31djorkundefined is not a keyword
10:31djorkundefined just happens to be undefined most of the time
10:32chousercemerick: Object()["foo" ] === null returns false
10:32chousercemerick: Object()["foo" ] === undefined returns true
10:34cemerickhahhaha
10:34chouserdjork: I did not know that. ...so horrible.
10:35djorkObject().x == undefined; // true
10:35djorkundefined = "haha"; Object().x == undefined; // false
10:36rhickeyum, I think it's obvious we don't want to mimic js :)
10:37djorkindeed :)
10:37djorkI like my languages to inspire confidence.
10:37djorkJavaScript is fine, but man does it make me paranoid.
10:38djorkspeaking of JS, if you haven't already seen it do check out Safari's recent JS console... it's pretty much the nicest I've seen anywhere
10:38djorkcompletion and automatic pretty-print of objects
10:39fogus31415926535Oh I don't know... there may be a market for a "Clojure: The Good Parts" book. ;)
10:40djorkjust print /api
10:40djorkdone
10:42chouserbut python might be interesting to look at -- they've moved some extendable-objects to faster-objects I think, I just can't remember the details.
10:43rhickey>>> x = "foo"
10:43rhickey>>> x.foo
10:43rhickeyTraceback (most recent call last):
10:43rhickey File "<stdin>", line 1, in <module>
10:43rhickeyAttributeError: 'str' object has no attribute 'foo'
10:44chouser>>> object().x = 5 AttributeError: 'object' object has no attribute 'x'
10:45vyIs there a `prog1' equivalent in Clojure?
10:46chouser>>> class Foo(object): pass
10:46chouser>>> Foo().x = 5 # no error
10:47chouser>>> foo=Foo(); foo.x = 5; foo.x # returns 5
10:47rhickey>>> class Foo(object): pass
10:47rhickey...
10:47rhickey>>> Foo().x
10:47rhickeyTraceback (most recent call last):
10:47rhickey File "<stdin>", line 1, in <module>
10:47rhickeyAttributeError: 'Foo' object has no attribute 'x'
10:48chouserso an error to get non-existant, but setting is ok after which getting is ok
10:49rhickeythat's what I meant before: "rhickey: in most expando systems, get on missing fails, set on missing creates"
10:49chouser>>> class Foo(object): __slots__ = ["a", "b"]
10:50chouser>>> Foo().x = 5 # AttributeError: 'Foo' object has no attribute 'x'
10:50chouserso you can turn off python's expando for a particular class.
10:51rhickeybut every time I've built an exception into something I've regretted it, since you can always build a throwing thing on a non-throwing, but not the other way round without ugliness, so I'd be ok with a getx which you could build on (get x k notfound)
10:51rhickeyassoc will have to fail for non-expando
10:51fogus31415926535In Python get on missing doesn't always fail if there is some magic in __getattr__ to handle
10:51cgrandvy: "do"
10:53vycgrand: I think you're confusing it with `progn'.
10:53rhickeyvy: no prog1
10:53chouservy: (let [x foo] ... x)
10:55cgrandvy: sorry, I read too quickly
10:55rhickeymore controversy - keywords only for defthing keys, even expando?
10:55chouseroh, wow.
10:57rhickeymight not be necessary for expando, but definitely for base fields
10:57chouserright. any name restrictions on the base fields?
10:57chouser- converted to _ ?
10:57rhickeychouser: I'm not doing any munging right now, but should be subject to standard munging
10:58rhickey,(clojure.lang.Compiler/munge "foo-bar*baz")
10:58clojurebot"foo_bar_STAR_baz"
10:58chouserIsn't a) just terribly tempting?
10:59rhickeychouser: yeah - I'd so be done right now :)
10:59lisppaste8fogus pasted "__getattr__" at http://paste.lisp.org/display/89435
11:02rhickeyso Im shooting for (deftype/class Name [fields] [interfaces] & methods), where interfaces and methods optional
11:03rhickeystill need a good way to say no thanks to specific auto-interfaces, thinking about #^{:disable [IThis IThat]} [interfaces], but would require a dummy [] if you weren't specifying any
11:04cemerickjust to refresh my memory -- are assoc, conj, et al. protocols in the new regime?
11:04rhickeycemerick: will be
11:04kanakcan someone help me understand what this means: "Vars - isolated changes within threads." Are these the same threads as Java Threads or something different?
11:05rhickeybut will be based on interfaces, meaning implementing the interface gets you into the protocol
11:05rhickeykanak: same
11:05cemerickIn that case, adding Associative onto deftype implemented using option A should be pretty straightforward.
11:06kanakso if i have two threads and one of the vars changes the value, the other thread won't see it. right?
11:06kanak*one of the threads changes the value of a var
11:07rhickeycemerick: really - where would the extension map live?
11:07rhickeyprotocols can't add/require more data slots
11:08cemerickno, there'd have to be a macro for it
11:08rhickeycemerick: these things are just macros now anyway (deftype/defclass), and not large ones
11:08rhickeyso creating similar things will be easy
11:09rhickeybut I'd like to get two good defaults in place
11:10rhickeywhich is driving an interface for dynamic types that will provide sufficient reflection/access to writing similar things won't even require something as involved as defclass/deftype
11:10rhickeyso writing
11:14rhickeyopinions - keywords only for defthing keys?
11:16cemerickyeah, that seems perfectly reasonable.
11:16fogus31415926535here here
11:17chouserthat's consistent with them being for small relatively-fixed things rather than large collections.
11:19fogus31415926535sorry if i missed this, but what would ::x vs. :x mean in the body of a defthing?
11:20maaclCan anyone give me a hint on how to convert any of the Clojure quicksorts on Rosetta Code http://rosettacode.org/wiki/Quicksort#Clojure to use recur or make them lazy?
11:20chousermaacl: generally to avoid stack-consuming recursion you have to rework the code to use an explicit accumulator.
11:21rhickeyfogus31415926535: vs what?
11:21rhickeyfogus31415926535: ::x is a namespace-qualified keyword
11:21rhickey,::x
11:21clojurebot:sandbox/x
11:25maaclchouser: but that is a bit hard for a sort that relies on splitting a sequence recursively
11:25maaclor am I missing somthing
11:25chouserI think "a bit hard" is accurate. :-)
11:26maaclchouser: ok, any hints on the direction to take - other than an accumulator
11:28fogus31415926535understood. perhaps i'm behind the curve. if the defthing key keywords be on access and definition, then how does one specify something like self.x in the body of an associated method?
11:28AWizzArdDo all agents share the same thread pool?
11:30maaclchouser: is the Scheme version http://rosettacode.org/wiki/Quicksort#Scheme anything to emulate?
11:36chousermaacl: hm, I guess I can't read scheme well enough to know for sure, but it looks promising
11:36maaclchouser: at least there is no direct recursion
11:37stuartsierraHow could sort be lazy?
11:37chouseris (let loop ...) defining a function?
11:41fogus31415926535let loop defines a named loop... kinda like a recur point but can be called from anywhere -- not just tail
11:42chouserok, so that ought to translate pretty directly if not necessarily idiomatically.
11:43chousernope, scratch that -- that scheme version uses the stack too
11:44chouser(let q ... (append (q ...) (q ...)))
11:47duncanmdum de dum
11:48rhickeythere's nothing inherently wrong with using the stack, tree-based things do it all the time, as long as depth not prohibitive
11:48duncanmhow does SORTED-KEY know how to sort the elements?
11:48chouseryes, but that was maacl's question. there are stack-consuming Clojure examples on that site, but none that don't.
11:49rhickeysorry, missed that
11:50falkorHi, can anyone explain what is wrong with this: (let [x '.toUpperCase] (println (x "a"))) ?
11:50falkorI just want to be able to decide, in runtime, which Java method to call...
11:50duncanmfalkor: write a macro
11:51maaclchouser: and they blow up sorting 1000 ints, which makes them not very useful
11:51AWizzArdIt could be helpful during development to have a optionally a configurable message being printed when doing a (in-ns ...).
11:52chousermaacl: the sort function works really well if all you want is "useful" :-)
11:52AWizzArd,(let [x #(.toUpperCase %)] (println (x "a"))
11:52clojurebotEOF while reading
11:52stuartsierraAWizzArd: the ns macro has a :verbose flag
11:52maaclchouser: :-) it's just and exercise
11:53chouseryeah
11:53AWizzArdfalkor: (let [x #(.toUpperCase %)] (println (x "a")))
11:53AWizzArd,(let [x #(.toUpperCase %)] (println (x "a")))
11:53clojurebotA
11:53duncanmAWizzArd: i think he wants to be able to change the ".toUpperCase" method call based on some input, for that, you'd be a macro, right?
11:53AWizzArdIf you want to forward native jvm methods wrap them into a #()
11:54duncanmyou'd need to write a macro
11:54duncanmi can't type today
11:54AWizzArdTho I would like to be a macro from time to time.
11:54AWizzArdstuartsierra: thx
11:54falkorduncanm , correct!
11:54duncanmrhickey: i see that there's a proposal for SORTED-KEY-BY, is that to be incorporated soon?
11:55rhickeyduncanm: what proposal?
11:55duncanmhttp://www.assembla.com/spaces/clojure/tickets/79
11:56AWizzArdfalkor: how will you make this descision? Do you know the set of methods that you potentially want to call during coding time?
11:56duncanmoh, the last diff was only submitted on the 20th, so i guess it's not fully baked yet
11:58rhickeyduncanm: yes
11:59yuraswhen I execute clojure script passing its name to java .. clojure.main, can it :use some of my sources without compiling to classes? is there any rules about that?
12:01AWizzArdstuartsierra: do you have a minimal example that shows how to use the :verbose flag in (ns ...)?
12:02stuartsierra(ns hello :verbose)
12:02hiredmanyuras: yes
12:04yurasclj sources should be in class to be visible for the "script"?
12:04yurasin the classpath*
12:05AWizzArdstuartsierra: maybe this is a recent addition? For me this throws an "IllegalArgumentException: Don't know how to create ISeq from: Keyword"
12:05stuartsierramaybe it was (use ...), not (ns...)
12:06AWizzArdInteresting would be if I could configure a message that gets printed when I (in-ns into-my-namespace).
12:06AWizzArdprinting a to-do list, or anything that i want to remember, something like that
12:07stuartsierraTry putting a watcher on *ns*
12:07stuartsierraDon't know if that will work, but it would be interesting to try.
12:08chousermaacl: the ones on the wiki work fine for *random* collections up to at least 10000 -- but it pivots on the first item so (range ...) is worst-case
12:13yuraslooks like path to sources should be in the classpath. adding "." solved my problem :)
12:31lisppaste8chouser pasted "tail-recursive qsort" at http://paste.lisp.org/display/89442
12:32chouserI'm sure that can be cleaned up
12:33chouserIt seems that it could be made lazy which would allow you to get the first of the sorted list in O(n) time, which is somewhat interesting.
12:43jasappsomnium: you around?
12:48drewrgzip-file http://gist.github.com/220607
12:48drewrI'm trying to figure out why this fails for large files
12:49drewrit doesn't fail technically, but it doesn't successfully gzip
13:00hiredmanhah!
13:01hiredmanmy reader no longer has dependencies on LispReader and it builds clojure and runs all the clojure tests with no errors or failures
13:02tmountaindrewr: could it have anything to do with fixing your buffer size at 8192?
13:03drewrtmountain: I suppose so, though I don't see how to read() and write() without it
13:05Chousukehiredman: neat.
13:05drewrtmountain: if I reduce my test file to under 8k it works
13:05drewrso I'm not using that buffer correctly
13:07Chousukehiredman: I still get that completely weird error :/
13:09ChousukeI think it might have something to do with my syntax-quote macro
13:09Chousukebut, hm
13:11ChousukeI guess I could test. :)
13:12yuras what great software written using clojure can I examine and learn from?
13:12AnniepooClojure! 8cD
13:12lpetityuras: clojure :)
13:13ChousukeClojure is 80% java though :P
13:13Chousuke~github
13:13clojurebothttp://github.com/richhickey/clojure/tree/master
13:13chousernot for long
13:13yurasclojure itself does not account, but its great dont argue :)
13:13ambientyeah, clojure is definitely the best software to learn clojure :)
13:13ambientat least for me
13:14Chousukeoh, only 74%
13:14Anniepooactually, if you want to look at good Clojure, I'd suggest many of the clojure-contrib libs
13:14ambientreading through the sources
13:14Chousukehttp://github.com/richhickey/clojure/graphs/languages
13:14lpetityuras: though you will learn more for "programming in the small" than "programming in the large". Though this may not be totally correct, since "programming in the small" with higher order functions is an open door to "programming in the large" :-)
13:14Anniepoothey're often more accessible and feel more like application programming
13:16AnniepooAnybody know if they've put enclojure on a netbeans plugin server somewhere?
13:16lpetityuras: probably (though I did not look at it myself), Stuart Sierra altLaw project
13:16drewrtmountain: I wasn't capturing the length that read() returns
13:16drewrupdated gist
13:16Anniepoo(as in, I'm lazy and don't want to compile it, I just want to use it)
13:17tmountaindrewr: does it work now?
13:17drewrtmountain: yep
13:17yurasbut i need to learn some more general patterns, like making servers and building infrastructure, designing resusable server is a bit hard for me using lisp-1 language. atm im building json rpc server and looking for idea what is the best way to "pass" exported functions to the server. for example python uses dispatch function for simple XMLRPC server. any directions to the book are welcome :)
13:17drewrthough I don't care for the duplicate read()
13:19yuras i feel like my bad english does not allow me to explain what i need :)
13:19Chousukehmmh.
13:20hiredmanyou want to do dispatch?
13:20yuras basically i has problem building simple and easy interface for json rpc server
13:20hiredmanthere are many ways to do that, the simplest is just a map of whatever to functions
13:20Anniepooyou might look at webjure
13:21hiredman,(-> "addition" {"addition" +} (apply [1 2]))
13:21clojurebot3
13:21yurasyeah, but what if programmer will need more than just simple map from names to function. then should i provide ability to use dispatch, right?
13:22hiredmandepends
13:22Chousukehiredman: you should use a bit more whitespace in your reader :P
13:22hiredman:P
13:22hiredmannow is the hard part
13:22Chousukehiredman: for example, between all the functions in the huge letfn
13:22yurasany other ways to do it? just hit me with them, i will dig further myself
13:22hiredmanclean it up
13:23hiredmanChousuke: hey, I put some comas at the end of the function bodies, that's whitespace!
13:23hiredmanmultimethods
13:24yurasso interface in that case would be passing name of multimethod to the server, right?
13:24hiredmanyou could just use vars, but that throws things a little wider open then you usually want to allow
13:24hiredmanyuras: no, the server would be a multimethod, basically
13:25hiredmanthe multimethod's dispatch function would get whatever input and decide which method in the multimethod to dispatch to
13:25hiredman:/
13:25AnniepooIf I shadow a binding in a let, how securely is the old value 'not available'?
13:25AnniepooBecause I'm making a remote agent system, outsider passes me clojure code, I execute it in a sandbox
13:26hiredmandepends on the binding type of the old name => value
13:26hiredmanif it is another let I don't think there is anything you can do
13:26qedIs there a way to create a function that can act on what is mapped to it in a hash map?
13:26hiredmanAnniepoo: not secure at all for actual security purposes
13:26qedlike (defn a [x] (do something to x where x is the value that a is mapped to in a hash map))
13:26qed(a 1)
13:27hiredmansure
13:27qedhow do you do that?
13:27hiredmana function is a object
13:27hiredmanyou can use it as a key in a hashmap
13:27qedhiredman: right i know this, but can i make the symbol a use the value in that hashmap as its input
13:28Anniepoolike (let [a (random) b #(somefun a) a nil] .... in here ...)
13:28hiredmanum
13:28AnniepooI want to provide access to b but not the raw a
13:28qedi should have fixed my above code
13:29qed(defn a [x] (do something to x))
13:29qed{a 1}
13:29qedwhere 1 is the input to a
13:29Anniepoo(I'll hold for qed's discussion, this'll get confusing)
13:29hiredmanno
13:29qedso there's no "placeholder" like there is in an anonymous function
13:29qedthat can reference the value that a key is mapped to
13:30hiredmanqed: I really have trouble understanding what you are trying to ask
13:30qedheh me too
13:30qedthe above code pretty much sums it up: (defn a [x] (do something to the value that a is the key for))
13:30qed{a 1}
13:31hiredmanqed: no
13:31qedokay, thanks
13:31Anniepoook, back to me.
13:31Anniepooit'd be cool to have a canned 'sandbox'
13:32hiredman~sandbox
13:32clojurebotsandbox is http://calumleslie.blogspot.com/2008/06/simple-jvm-sandboxing.html
13:32Chousuke~def with-meta
13:32lisppaste8Chouser annotated #89442 "lazy tail-recursive qsort" at http://paste.lisp.org/display/89442#1
13:32hiredmanclojurebot has a sandbox.clj based on that site
13:33Anniepooah, lovely
13:33chouserclojurebot: tell maacl about http://paste.lisp.org/display/89442#1 when he gets back
13:33qedhiredman: pardon me for poking, but, do you know why that's not possible?
13:33qedit seems like it could be if you worked some magic
13:33Anniepooyah, I'm thinking it's a great way to do IPC if you're clojure on both ends (or even if you're not),
13:33hiredmanqed: map literals are tied to specific map types
13:34hiredmanAnniepoo: in that case I think it would be better to write a mini clojure interpreter
13:34KjellskiHi there, good evening!
13:34hiredmanmuch easier to restrict
13:34qedhiredman: how does that preclude me from referencing some potential value that a key may refer to?
13:35djorkhowdy Kjellski
13:35hiredmanqed: function application is not part of maps
13:35qedyou could build a map that would work though, no?
13:36hiredmanlike I said, you don't make much sense, so I might be misinterpreting what you want
13:36Kjellskidjork : howdy!
13:36hiredmansure, I don't see why though
13:36qedhiredman: i just want a way of referencing the value of my "self", where self is a key
13:36hiredman,(-> {:a 1} (update-in [:a] inc))
13:36clojurebot{:a 2}
13:37hiredmanqed: self of what?
13:37qedokay, so i have this function, and i know that this function will be the key in a hashmap later on
13:37hiredmanok, is it a def'ed function?
13:37qeddefn
13:38qedyes
13:38hiredmanthen just use it's name as the key
13:38qedright, but now that it is the key
13:38qedis there a way of knowing what it is mapped to, once it's mapped
13:38Anniepoohiredman: well, I was thinking inside the sandbox should be applet restrictions + ability to do whatever I say
13:38hiredman,(-> + {+ 3} (* 2))
13:38clojurebot6
13:38Kjellskidjork: I´ve solved that problem for a small enough problem size, but as I´ve recognized, my try to a solution was a bit dumb... I think the approach I took was not that neat, just because it would be pretty hard to hold 1,000,000,000,000 integers in a vec... ^^
13:38hiredmanqed: yes, it's called looking up the value in the map
13:38drewrnewgen lisp machine? http://research.sun.com/projects/dashboard.php?id=185
13:38hiredman,(get {:a 1} :a)
13:38clojurebot1
13:39qedhiredman: no, i want a function {a}, to take as its input, the value it is mapped to
13:39hiredmansun has a research metacircular vm
13:39djorkKjellski: hmm, yeah you could get away with some shortcuts like using a map
13:39djorkif you just wanted to keep count
13:39hiredmanqed: then apply the function to the value it is mapped to
13:40qedlike (defn a [value-of-a] (some way of referencing a future value-of-a))
13:40hiredmandrewr: yeah, project guest vm uses the metacircular jvm
13:40Chousukehmm, okay, so the problem is not with my syntax-quote
13:40Kjellskidjork: a map over what? If my Problemsize is big enough, it´s just stupid to represent bacteria via integers isn´t it?
13:41hiredmanqed: it's not a value of a
13:41hiredmanit's a value a maps to in some map
13:42qedhiredman: right, is there some way of referencing the value 'a' maps to, in some future map
13:42hiredmanChousuke: I started to rewrite my syntaxquote, but it was such a big undertaking instead I just stepped through my broken verion until it worked
13:42djorkKjellski: I mean a map data structure {}
13:43hiredman~google clojure reference types
13:43clojurebotFirst, out of 3810 results is:
13:43clojurebotClojure - atoms
13:43clojurebothttp://clojure.org/atoms
13:44qedlike (defn a [future-mapping] #(+ % 1))
13:44qed{a 1} => 2
13:44qedwhere % is the future-mapping
13:44qedi dont know, i might be talking crazy talk
13:45Kjellskidjork : I thing I misunderstood you. What I meant was, if I represent a bac by an int, that would be stupid, just because whatever data structure I use, that would blow the memory. So I have to find a way to do the calculus on one single int or something...
13:46qedi guess what im trying to determine in the most basic sense, is if i can talk about a value i map to, without being mapped to anything yet -- with the understanding that when i do map to something, i will use it as my input
13:46djorkKjellski: I mean a map like { 1 count-for-ones 2 count-for-twos }
13:47Kjellskidjork : there we go... now I got it.
13:51KjellskiA general question. I want to prepare a presentation about Clojure for a seminar at university, what do you think needs to get in there? (max. 30min)
13:53chouserKjellski: don't try to cover everything. I think clojure has 4 or 5 killer features. Pick one or maybe two that you think your audience will "get" -- cover those deeply enough for them to get it. only mention the others.
13:54chouserpersistent collections, seq library, reference types, macros+java interop
13:54Kjellskichouser : That´s what I thought. But which should I pick from e.g. http://clojure.org/features for students that at maximum discovered functional programming in there free time...
13:54Kjellskichouser : Okay. That´s a good start.
13:55chouserhm, I forgot multimethods and the REPL. :-)
13:55chouserI'd probably go with either the collections and seq library or maybe macros and interop.
13:56qedchouser: maybe im crazy here, but it seems possible: Can I define some function (defn a [input]...), and somehow reference what a will map to in some future hash map?
13:56chouserqed: I've been seeing your questions and I don't think I understand yet.
13:56Kjellskichouser : I wanted to definitely stunn them with the example from Stuarts book, where he shows the apache.common.indexOfAny in clojure...
13:57qedso by doing something like {a 1}, a can take 1 as its input, simply by virtue of it being mapped to it
13:57qedwithout any other business
13:57chousera literal {} will not call a function.
13:58chouser({} :x) will call a method of hash-map, but there's no way to hook your own code in there
13:58qedchouser: ahh, that makes more sense
13:59qedthank you :)
13:59chouserqed: it does? well ... good, I guess.
14:00qedi was just watching rich's screencast about data structures, and when he showed that you can add symbols like (defn a) to a hash map {a 1}, I wondered if there was some way of talking about what a maps to at some future scenario where it is in a hash map
14:00hiredmanif maps are immutable, any future map is not the present map
14:00qedlike some placeholder variable or something, that would describe the connection between a and its value
14:01hiredmanthere are promises and delays and futures and etc etc etc
14:01chouserqed: I seriously can't wrap my head around what you're saying. Maybe if we work on some terms a bit...
14:01chouser(defn a) doesn't create a symbol
14:02chouser(defn a [x y] (+ x y)) creates a fn and stores it in a Var named by the symbol a
14:03chouserif you then eval {a 1}, that's the same as eval'ing {(fn [x y] (+ x y)) 1}
14:03chouserthat is, you get a hash-map with a single key (a function) and a single value (1)
14:03chousernow ... what do you want to do?
14:05qedmanipulate the single value (1) with that single key (a function) -- the question is whether or not there is some way of writing a function that will understand how to "talk to" a value it is mapped to
14:05kanakWhat is the time complexity of doing a last on a sorted-map? (I'm trying to see if a sorted-map with "priority" as key could be a decent implementation for a heap)
14:05qedwithout it being mapped to something in the first place
14:05hiredman
14:05hiredmankanak: n
14:06qedam i just talking crazy talk here?
14:06kanakhiredman: thanks. So what data structure would be the best if i need priority-queue type operations ?
14:06qed(defn a [var] [let var be the value this function is mapped to])
14:06hiredmanfingertree
14:06tomoj"the value this function is mapped to"?
14:07qed{a 1}, the function is mapped to 1
14:07chouserkanak: you might look at subseq
14:07tomojin (defn a ...), a is not a map
14:08qedtomoj: right, im talking about a future scenario where it is mapped to something, can you discuss the behavior of the function in a future context inside of that function?
14:08tomojyou're saying you want the function to behave differently depending on what the function is mapped to in some map elsewhere?
14:09rstehwiengot notification that "Clojure in Action" book early access program is open http://bit.ly/aNJnj . Whoho! another clojure book
14:09chouserqed: (defn apply-map [f m] (f (m f))) (apply-map inc {inc 1}) ==> 2
14:09qedtomoj: not really, im saying more like: if this function is found in a map, it will behave like this, if it is found in a vector, it will behave like this
14:09kanakchouser: Could you explain that a little more?
14:09chouserqed: is that roughly what you're looking for?
14:10tomojqed: what if it's in a map and a vector? and which map or vector?
14:10tomojthe function doesn't know where you've put it, if that's what you mean
14:10tomojrstehwien: that link doesn't say anything about clojure for me :(
14:10qedtomoj: that's pretty much where i was going with this
14:10tomojwhy in the world would you want to do that?
14:11tomojthat would destroy everything that is good about clojure
14:11tomojand make me cry
14:11qedhaha, im just thinking -- im not saying its useful or a good idea or anything
14:11tomojoh, ok
14:11qedi was just wondering if there is anyway to define a function that understands what it is mapped to
14:11chouserqed: did you see what I posted?
14:11qedbefore it is mapped to something
14:12tomojno, it could be mapped to any number of things in any number of different maps
14:12rstehwientomoj: http://www.manning.com/rathore/ is the clojure book. odd that my email had that link but the repost our discount link didn't
14:12qedchouser: yeah, im thinking on it for a second, not sure if thats what i was thinking or not
14:12tomoja function is just a value and you can put it anywhere
14:12tomojvalues don't know where you've put them
14:12tomojrstehwien: thanks
14:13tomojif you're passing the map into the function, then sure, it can just look itself up. guess I still don't understand what you really mean
14:14KjellskiWhere can I get the latest build of clojure? is it github or google code?
14:14qedtomoj: how does it look itself up?
14:14chouserkanak: actually, nevermind subseq. calling first on a sorted map or set should be O(log n)
14:15tomojqed: (defn a [the-map] (the-map a))
14:15chouserkanak: then removing that item should also be O(log n), I think, as should adding items.
14:16chouserkanak: so that's not too bad O(log n) for add and remove.
14:16chouserkanak: finger trees if we had them should give you O(1) insert and O(log n) remove. Or vice-versa, I suppose, as you see fit.
14:17qedtomoj: chouser: thanks for the patience, maybe ill figure out a better way to explain and try again later
14:17qedciao
14:18kanakchouser: hmm. does that mean that a finger tree would give me even better performance than a binomial heap?
14:18tomojfunctions that return themselves are weird
14:24chouserkanak: sorry, don't know about binomial heaps
14:25kanakchouser: thank you for your help. Is your implementation of finger-tree "ready" to be used?
14:25chouserbut performance is about more than just big-O, there are also the constant factors which are as yet still hounding my finger trees.
14:25chouserkanak: not really. no docs, for example.
14:26kanakhmm might be fun to play with it anyway :)
14:27chouserfor some value of "fun", sure. :-) The core is feature complete, and it's got some tests that show how it can be used.
14:27chouserThe API needs some improvement and it currently requires the 'new' branch of clojure to work at all.
14:29kanakchouser, are there any new data structures that might get added to the core? or will newer data structures (if any) get added to contrib (if at all)
14:30chouserkanak: I don't know. rhickey has said things that lead me to believe it's possible finger trees might make it in to core. I haven't heard even that about any others.
14:32chouserkanak: are there other persistent structures you'd like to see?
14:33kanakchouser: something that would allow efficient heap implementation would be nice to have. But i guess that could be had with a good finger tree.
14:35kanakOkasaki's book has implementations for Binomial and leftist heaps, which might be fun to implement in clojure.
14:39chouserhm. (:foo non-collection) just returns nil
14:39chouserIn this case I would have really appreciated an exception.
14:40tomojthat happened to me too :(
14:41chouserin this case I had a reference type and was forgetting to deref it
14:46rhickeyaargh - contrib has deftype?
14:46chouserheh
14:46chouserwhere?
14:47rhickeyclojure.contrib.types
14:47chousertypes
14:48chouserhuh, I've never looked at that one. I guess I knew vaguely it was there.
14:48chouser"Algebraic types" anyway.
14:50chouserpush to master?
14:50rhickeychouser: no way, up to new
14:50chouser:-) ok
14:55rhickeyok - have fun, feedback needed: http://github.com/richhickey/clojure/commit/5f090a0925f3dcbd3fa8b7104cd59b6d4c087413
14:55cemerickis clojure.contrib.types getting a hasty refactoring?
14:55rhickeycemerick: not bey me
14:55rhickeyby me
14:56rhickeyso new branch incompatible with compiling contrib at present
14:56cemerickhrm, I guess c-c should have a new branch too
14:56chousernah
14:57rhickeycemerick: I have been building contrib and running its tests all along with new branch, this name conflict first problem
14:57Chousukehmm, I think I have got the unreading behaviour working now in my reader.
14:57chouserjust exclude deftype from contrib types for now
14:57Chousukestate is evil :(
14:57rhickeyprobably just need an :exclude in contrib.types
14:58chousergithub knows how to color letfn
14:58rhickeyI'm sure the defthing docs need a lot of work, as questions come in I'll clarify them
14:59chouserheh. create-defclass* bears striking similarities in structure with make-digit
15:01chouserhttp://tinyurl.com/ylx4j3k/finger_tree.clj#LID83
15:02chouserthat is, new-new like thing generate by macro.
15:14rhickeychouser: yeah, inevitably
15:17bradfordI'm having a hell of a time building something nice for remote repl over ssh.
15:17bradford(defn read-command-output [in buffer-size time-out poll-interval]
15:17bradford (let [buffer (make-array Byte/TYPE buffer-size)
15:17bradford bos (java.io.ByteArrayOutputStream.)
15:17bradford exit-status 0
15:17bradford end-time (+ (System/currentTimeMillis) time-out)]
15:17bradford (while (< (System/currentTimeMillis) end-time)
15:17bradford (while (> (.available in) 0)
15:17bradford (let [next-block (.read in buffer 0 buffer-size)]
15:17bradford (if (< count 0) break
15:17bradford (do
15:17bradford (.write bos buffer 0 count)
15:17bradford (if (.isClosed channel)
15:17technomancy,lisppaste
15:17clojurebotjava.lang.Exception: Unable to resolve symbol: lisppaste in this context
15:17bradford (do (println (str "exit-status: " (.getExitStatus channel)))
15:18bradford break))
15:18technomancy~lisppaste
15:18clojurebotI don't understand.
15:18bradford (Thread/sleep poll-interval))))))
15:18bradford (.toString bos)))
15:18technomancybradford: lisppaste.org dude
15:18bradfordtrying to figure out how to port some nasty jsch code to clojrue and deal with the breaks in these nested while loops
15:18danlarkinthis is an inappropriate amount of pasting
15:18bradfordtechnobancy: i know...let me finally set it up :-)
15:18G0SUB,lisppaste8
15:18clojurebotjava.lang.Exception: Unable to resolve symbol: lisppaste8 in this context
15:18bradfordyea - my bad :-)
15:18G0SUBlisppaste8
15:19G0SUBtechnomancy: I have a problem with completion on a clojure buffer. can you help?
15:19bradfordhttp://paste.lisp.org/display/89458
15:20G0SUBtechnomancy: completion on a clojure buffer does not work at all. it used to work on the repl, but that too broke somehow recently. (i made no changes to emacs files)
15:20bradfordthere is the lisppaste- i usually use gists, but whatever
15:20technomancyG0SUB: unfortunately at the present moment I only have time to complain about IRC usage and not actually be helpful; catch me later in the day?
15:21G0SUBtechnomancy: sure.
15:21bradfordcan peeps have a look at this ssh exec horror:
15:21bradfordhttp://paste.lisp.org/display/89458
15:22danlarkinbradford: did you not catch george's socket-repl presentation at the SF clojure meetup a few weeks ago? :(
15:22bradfordnope, please forward me the goodness
15:23bradfordis the stuff in clojure.contrib?
15:24dysingery
15:24danlarkinbradford: hunting it down..
15:25bradforddysinger: clojure.contrib.server-socket?
15:25dysingery
15:31bradfordreading server-socket.clj ...
15:39Licenseraloa
15:42ysmolskyhow to test particular symbol, if it is a function?
15:43danlarkinysmolsky: there's ifn? and fn?
15:44chousersymbols are always functions, but that's probably not what you meant.
15:44ysmolskyi mean user defined ones as (defn ..)
15:44chouser,('foo '{foo 5, bar 5})
15:44clojurebot5
15:44ysmolskyseems like fn? is the answer
15:44Licensersomnium: I found more problems :P
15:44chouser,(fn? 'foo)
15:44clojurebotfalse
15:44chouser,(ifn? 'foo)
15:44clojurebottrue
15:45AWizzArdrhickey: nice, thanks for the new checkin :)
15:45chouser,(-> 'filter resolve deref ifn?)
15:45clojurebottrue
15:45chouser,(-> 'i-just-made-this-up resolve deref ifn?)
15:45clojurebotjava.lang.NullPointerException
15:46AWizzArd,(resolve 'filter)
15:46clojurebot#'clojure.core/filter
15:46rhickeyAWizzArd: did you try it?
15:46AWizzArdrhickey: no, just saw the email and now looking at the diffs
15:47chouser,(when-let [v (resolve 'made-this-up)] (fn? @v))
15:47clojurebotnil
15:47chouser,(when-let [v (resolve 'resolve)] (fn? @v))
15:47clojurebottrue
15:47AWizzArdBut tomorrow at work I can give it a try and see if I can get my tokenization example running.
15:48AWizzArdchouser: can one simply checkout the "new" branch from git and compile it like the master? Or are other steps needed?
15:48chouserAWizzArd: that should do it
15:49AWizzArdAs I understand it then deftype is more for endusers like me.
15:49AWizzArdwhile with defclass one can even implement things like Clojures maps and vectors.
15:50AWizzArdor finger trees
15:51chouserno, I think deftype and defclass are designed with very similar syntax so you can start with deftype and if you need that extra bit of performance or named Java classes (and don't mind losing a bit of dynamism and doing the AOT setup) you can easily switch to defclass.
15:52cemerickis there a perf difference? I didn't realize there was one.
15:52rhickeycemerick: defclas will let you do (.field x)
15:52rhickeydefclass
15:53rhickey(.field x) from outside of the method bodies
15:53cemerickah. is that a field access or invoking a getter called field?
15:53rhickeyinside the method bodies you can just use x, same perf for newnew/deftype/defclass
15:53rhickeycemerick: field access
15:54AWizzArdand outside of method bodies for deftypes?
15:54rhickeynext up for me is to add a perfect-hash based case construct to Clojure, will be used in the implementation of valAt (get)
15:55rhickeyAWizzArd: outside, both support (:field x)
15:55duncanmhow do i get all the keys from a set of maps?
15:55AWizzArd,(keys {:a 1, :b 2})
15:55clojurebot(:a :b)
15:55duncanmAWizzArd: a set
15:55arohner(map keys set-of-maps)
15:55rhickeymapcat
15:55duncanmooh
15:56duncanm(map keys #{{'a 'b} {'c 'd}}) -> ((a) (c))
15:56AWizzArdrhickey: some days ago someone postet a microsoft paper or so, of perfect hashes. Will you use some of that stuff?
15:56drewr,(mapcat keys #{{:foo 1 :bar 2} {:baz 3 :quux 4}})
15:56clojurebot(:baz :quux :foo :bar)
15:56duncanmnice
15:57rhickeyAWizzArd: tht paper was about 3d hashes, but other papers. The case thing will bottom out on a JVM tableswitch bytecode
15:59ysmolskyis there a way to handle optional arguments like "a" and "c" inside of function by keywords? (for arg1 :some a :bar c)
15:59AWizzArdsounds lowlevel ;-) are those hashes also needed for Clojure in Clojure?
16:00chouserysmolsky: see clojure.contrib.def/defnk
16:00rhickeyAWizzArd: it will look like cond, not low level in use, but very fast match given compile-time constant keys
16:00AWizzArdysmolsky: you can manually do this in your own functions, or you can accept a map as argument
16:00AWizzArdi see
16:00cemerickysmolsky: or, you can use map destructuring with an :or map containing defaults
16:00rhickeyAWizzArd: (case x :a (do-this) :b (do-that) ...)
16:01rhickeybut unlike (condp = x :a (do-this) :b (do-that) ...) it won't try every choice sequentially
16:01AWizzArdi am just looking at http://www.artima.com/underthehood/flowP.html as they say a bit about tableswitch
16:04duncanmit'd be nice if i can supply my own comparator in clojure.set/difference
16:10chouserAWizzArd: thanks for that link
16:13hiredmanwould anyone be interested in a reworked build.xml? specificly one that doesn't blow away and recompile everything everytime you run ant?
16:14hiredman http://gist.github.com/220784
16:14chouserit used to now blow everything away, but would sometimes mess up and fail to rebuild something, resulting in weird runtime errors
16:15chouserused to not blow everything away
16:15hiredmanwell, hving it blow everything away when you call the compile-clojure target is annoying if you want to call that target twice
16:16hiredmanand the java task to call Compile should fork
16:17hiredmanor else, again, calling the compile-clojure task twice doesn't work
16:18cemerickFWIW, we just check clojure jars into our fork of the repo. Building clojure as a direct ant build dependency doesn't seem worthwhile.
16:20hiredmanof course, but for actual developement work on clojure, it's nice to have a nicer build process
16:20Dawgmatixare there any tools to generate wrappers for c libraries for clojure ?
16:20chouserDawgmatix: I've had success with both swig and jna
16:21arohnerDawgmatix: I like JNA
16:21arohnerit's a little slower, but the convenience is nice
16:21tomojautogenerated clojure wrappers for C would be weird
16:21chouseryeah, I'd recommend JNA if the libs are plain C
16:22chouserfor C++ swig has worked out well.
16:22Dawgmatixokay arohner will look at jna
16:22chousertomoj: swig comes very close to autogenerated, and yes it's a bit weird.
16:22Dawgmatixwhy is it weird ?
16:22tomojit would be weird to me because I don't want my clojure to look like C
16:23Dawgmatixhehe :)
16:23chouserit's weird to me because frequently so frictionless and doesn't seem like it should be.
16:23tomojand if I'm going to write a wrapper around the wrapper I might as well just use an autogenerated java wrapper and wrap that in clojure
16:23chouserDawgmatix: http://github.com/Chouser/clojure-jna
16:24Dawgmatixso whats the alternative for wrapping things like opengl ?
16:24chouserthere are gl libs for java
16:24Dawgmatixjogl ?
16:24arohnerif the gl lib didn't exist, JNI
16:24tomojchouser: ok, that's pretty cool
16:25arohnerit's similar to writing c-ruby or c-python extensions, but an even bigger pain
16:25arohnerbecause the JVM is fussier
16:25chouserswig makes generating JNI code relatively painless
16:32hiredmananyone want a clojure.jar with a slower reader, that happens to be written in clojure :P
16:34chouserheh
16:34hiredmanhttp://gist.github.com/220805 same buid.xml as earlier but with my reader dropped in
16:35hiredmanso it builds clojure once with LispReader, uses clojure to build my reader, then deletes clojure and rebuilds it using my reader
16:35hiredmanby clojure I mean the compiled clj files
16:35chouserI imagine will need a build setup like that for cinc in general
16:36hiredmanyeah
16:37emit_what does the M suffix mean next to an integer. like (= 3156M 3156) is true
16:37hiredmanI am going to send an "anouncement" email about my reader to -dev once I get it working nicely in a fairly vanilla clojure tree
16:37arohneremit_: bignum
16:37chouser,(map class [3156 3156M])
16:37clojurebot(java.lang.Integer java.math.BigDecimal)
16:38hiredmanI had to make a lot of stuff public instead of class private
16:38hiredmanbits of RT and the Compiler
16:41emit_ok... thanks
16:41chouserhiredman: yeah, that's not surprising. I had to do the same for ClojureScript, though likely not exactly the same stuff
16:46hiredmanugh
17:04KjellskiAnyone already using a LaTeX-Highlight Listing for clojure?
17:05hiredmanhttp://markmail.org/message/emngybncqtlcsunb <-- oh lord
17:05technomancyhiredman: we all have posts like that... some are just better-hidden than others =)
17:06djorkheh heh
17:06djorkyes
17:10Kjellskinoone?
17:11hiredmanso far I have yet to embed code in of my latex documents
17:11hiredmanbut am I interested, just have nothing ov value to contribute at the moment
17:12KjellskiOkay... so maybe I´ll just post my listings defines if you want?
17:12hiredmansure
17:14hiredmanI mean, if I had some way of embedding syntax hilighted clojure code in my latex documents I guess I would practically have to
17:15chouserheh
17:15KjellskiI´ll send you a minimal example when I´m done... ^^
17:16hiredmanhttp://github.com/hiredman/clojurebot/blob/master/clojurebot.pdf I started on a clojurebot slidedeck
17:17danlarkinKjellski: what is i you're sending at the end of each line? I can't decode it
17:17tomojI wonder if there are any general output-independent highlighters
17:17Licenserhiredman: I don't understand the message
17:17hiredmanmessage?
17:18Licenserthe mail thingy
17:19LicenserI am just not getting it
17:19hiredmanoh, I sent and email to the mailing list because I couldn't find 'mod'
17:20Licenserah, I had that problem too :P I gave up
17:22Kjellskidanlarkin : huh? Sorry... might be the miranda irc client?
17:23hiredmanI don't see anything weird at the end of Kjellski's lines
17:23danlarkinI see ^^ [incompatible encoding] after each one
17:24hiredmanweird
17:24danlarkinno biggie
17:24hiredmanuh, I know he did end one line with ^^
17:24Licensergood night people, and danlarkin set the channel encoding to UTF8 or something
17:24tomojhmm.. how would you write a function which does like iterate, but alternates between applying two functions?
17:24danlarkinIt is already set to utf-8
17:24tomoj(besides tail-recursion with a toggling counter or integer mod 2... wondering if there's a cool way)
17:24technomancychannels don't actually have encoding; it's up to the clients to agree on them =)
17:25Licensertomoj: tail recusion with 2 function arguments that alter place in the call
17:25Licenser(loop [f1 f2] ... (recur f2 f1))
17:25tomojok, that's better than toggling
17:25tomojbut I meant without loop, really
17:25tomojlike with seq-fu
17:25hiredmantomoj: not really, because iterate uses the same function over and over
17:25KjellskiSorry about that... sometimes I can´t resist my smiley reflexes.
17:26hiredman~def iterate
17:26hiredmanhuh
17:26arohnertomoj: (source iterate)
17:26arohnermake your version of iterate take two functions
17:27arohnerswap f1 and f2 in the recursive call
17:27tomojarohner: yeah, that's a good way too
17:27tomojI was curious if there is an "even more lazy" way
17:27arohnerI think that's about as lazy as it gets
17:27tomojas in the kind of thing the clojure book does
17:28arohnerthe original iterate is completely lazy
17:28arohnerso is the version I suggested
17:28tomojrecursion -> lazy-seq -> combining builtin seq fns
17:28Licenserbut buildin seq fns usually are recursive :P
17:28tomojsure, but the recursion is hidden away and you don't have to think about it
17:29Licenserheh when you write a interalternate or how you call it, it would be hidden for the rest of the world too :P
17:29Licenseranyway I', off to be,d take care everyone!
17:29arohneryou could make an infinite-seq of the fns to call, in order
17:29arohnerthen reduce it
17:29arohneri.e. (reduce #() [f1 f2 f1 f2 f1...])
17:29hiredmanwell, reduce isn't lazy
17:30arohnerah, right
17:30tomojwould need reductions
17:31arohnerI like my first way
17:31tomoj,(take 10 (interleave (repeat 'f1) (repeat 'f2)))
17:31clojurebot(f1 f2 f1 f2 f1 f2 f1 f2 f1 f2)
17:31tomojI still don't understand your "reduce #()", but, thanks
17:32djorkhow could I convert a raw byte array to a string within clojure?
17:32djorka hex string that is
17:34tomojwell
17:34tomojI think signedness can screw you up
17:35hiredman,(.getBytes "foo")
17:35tomojif you try to use java's toHex stuff, that is
17:35clojurebot#<byte[] [B@db8155>
17:35hiredman~jdoc String
17:36djorkoh bit-and
17:36tomojone way would be to have a map of ints to hex chars
17:36hiredmaninteger has a toHexString method
17:36tomojyeah and then (bit-shift-right ) I suppose
17:36tomojhiredman: yes but it's signed
17:37hiredmanwell
17:37hiredmanall java primitives are signed
17:37tomojso you'd have to find someway to make the byte an int that doesn't keep the sign
17:37djorkOK so
17:37AWizzArdyou want to convert a byte array into a hex num sequence correctly?
17:37tomoj,(Integer/toHexString (.intValue (byte 130)))
17:37clojurebot"ffffff82"
17:38AWizzArdno, use bit-and
17:38djork,(let [bytes (.getBytes "byte me")] (bit-and (aget bytes 0) 0xFF))
17:38clojurebot98
17:38AWizzArd,(bit-and -128 255)
17:38clojurebot128
17:38hiredman,(-> \h int Intager/toHexString)
17:38clojurebotjava.lang.Exception: No such namespace: Intager
17:38hiredman,(-> \h int Integer/toHexString)
17:38clojurebot"68"
17:38AWizzArd(map #(bit-and % 255) (range 256))
17:38hiredman,(-> \hlint Integer/toHexString)
17:38clojurebotUnsupported character: \hlint
17:39tomojAWizzArd: then what do you do with that?
17:39tomojI was thinking bit-and with 0xf to get one char, then shift right 4 and do it again for the second char
17:39AWizzArdthen you can use Integer/toHexString
17:39tomojno..
17:39djorkhmm, nibble at a time?
17:39djorkthere's no such thing AWizzArd
17:40tomojoh, hmm
17:40AWizzArdsay you do a sha-256 hash, you will get a byte[]
17:40djorkyeah that's what I'm doing
17:40djorksha
17:40tomojbit-and plays nicely with signed bytes, you're right
17:40AWizzArdbut if you want to print out that hash code then you display it a hex
17:41AWizzArd(apply str (map #(Integer/toHexString (bit-and % 255)) (sha "hello moon")))
17:41woobyis there something like contains? for seqs?
17:42AWizzArdfind-first
17:42arohner,(doc some)
17:42clojurebot"([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return true if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"
17:42djorkhmm I guess Integer/toHexString exists
17:42djork,Integer/toHexString
17:42clojurebotjava.lang.Exception: Unable to find static field: toHexString in class java.lang.Integer
17:42arohnerwooby: that's a linear scan
17:42djorkI'm doing it wrong™
17:42AWizzArd,(apply str (map #(Integer/toHexString (bit-and % 255)) (range 150 160)))
17:42clojurebot"969798999a9b9c9d9e9f"
17:43AWizzArddjork: it is a Java method and so you can't return a function object of Integer/toHexString
17:43AWizzArd,#(Integer/toHexString %)
17:43clojurebot#<sandbox$eval__4362$fn__4364 sandbox$eval__4362$fn__4364@b5c292>
17:46djorkI think I've got it
17:47djork(Integer/toHexString 0)
17:47djork,(Integer/toHexString 0)
17:47clojurebot"0"
17:47djorknot cool
17:47AWizzArddjork: please compare the output of your program with the example here: http://en.wikipedia.org/wiki/SHA_hash_functions#Examples_and_pseudocode
17:48djorkwill do
17:50djorkworking fine
17:50djorkjust need to pad my zeroes
17:52AWizzArdformat
17:53AWizzArdbtw, I think format can also do toHexString for you
17:54djorkhttp://gist.github.com/220900
17:55djorkformat would be better I think
17:56AWizzArddjork: yes, good example code, this is how it works
17:56AWizzArdonly thing that I personally would change is "SHA-1" ==> "SHA-512" :-)
17:58AWizzArdso, how can one give fill chars to format?
17:58AWizzArd,(format "%h" 255)
17:58clojurebot"ff"
17:58AWizzArd,(format "%2h" 0)
17:58clojurebot" 0"
17:59AWizzArdCan one make it output "00"?
17:59hiredmanhttp://java.sun.com/j2se/1.5.0/docs/api/java/util/Formatter.html
18:00djorkOK this is better
18:00djorkhttp://gist.github.com/220900
18:00djork,(format "%02x" 1)
18:00clojurebot"01"
18:01djorkyou know what would be cool... gist loading in clojurebot
18:01hiredman:/
18:01AWizzArd,(format "%02x" 255)
18:01clojurebot"ff"
18:02hiredmanfyi clojurebot is xmpp too: clojurebot@thelastcitadel.com
18:02rstehwiendawgmatrix: for opengl in java there is jogl and lwjgl . The game libs Slick (2d) and JMonkeyEngine (3d) use jogl and/or lwjgl (the default seems to be using lwjgl in the java game world)
18:03woobywhat would be the preferred way to convert a number to a seq of its digits?
18:03woobyi'm doing this now: (map #(Integer/parseInt (Character/toString %)) (str n))
18:03AWizzArd,(seq (str 123))
18:03clojurebot(\1 \2 \3)
18:03woobyoh duhhh
18:03woobythank you
18:04AWizzArdno, those are chars
18:04AWizzArdnot digits
18:04woobyi see
18:04AWizzArd,(map int "123")
18:04clojurebot(49 50 51)
18:04AWizzArdah ;)
18:04hiredman:P
18:04wooby,(map irc://irc.freenode.net/#(Integer/parseInt (Character/toString %)) (str 123))
18:04clojurebotjava.lang.ClassNotFoundException: irc://irc.freenode.net
18:05AWizzArdwooby: Character/toString ==> str
18:06woobyah yes
18:06AWizzArd,(map #(Integer/parseInt (str %)) (str 123))
18:06clojurebot(1 2 3)
18:06woobythat's better, thanks
18:07hiredman(-> 123 str ((partial map str)) ((partial map read-string)))
18:07hiredman,(-> 123 str ((partial map str)) ((partial map read-string)))
18:07clojurebot(1 2 3)
18:07woobyfancy
18:08hiredman,(->> 123 str (map str) (map read-string))
18:08clojurebot(1 2 3)
18:09woobywow what's going on there
18:09wooby->>?
18:10hiredman,(doc ->>)
18:10clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
18:10woobymindblowing
18:17woobyi see
18:17woobyso (map read-string (map str (str 123))) is equivalent
18:17wooby,(map read-string (map str (str 123)))
18:17clojurebot(1 2 3)
18:18AWizzArd,(use 'clojure.contrib.pprint)
18:18clojurebotnil
18:19piccolinoIs there some function built-in that can take a sequence of strings, and return the string of all of them concatenated with a separator between them?
18:19div-what would be the benefit of ->> ?
18:19div-besides "being possible"
18:20div-hiredman: any opinion ? :)
18:20arohnerdiv-: it reduces the nesting of function calls, and (can) make things more readable
18:20AWizzArd,(apply str ["string 1" "XXX" "ABC"])
18:20clojurebot"string 1XXXABC"
18:21AWizzArdif you need a separator you can map it
18:22piccolinoMap it?
18:22div-arohner: okay, but it seems like it would be sporadically used, and if so, wouldn't really make things more readable, right ?
18:22notallamais ->> in core?
18:22hiredmanyeah
18:22arohnernotallama: yes
18:22hiredmanit's newish
18:22arohner->> is easier to understand if you start with ->
18:22arohnerwhich has been around for a long time
18:22AWizzArd,(apply str (map #(str % "/") ["abc" "xyz"]))
18:22clojurebot"abc/xyz/"
18:23notallamathreading/composition is fun stuff.
18:23div-,(doc ->)
18:23clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
18:23arohnerthink of a java function call
18:24arohnerfoo().bar().baz()
18:24arohnernow let's add arguments
18:24piccolinoAh, but that sticks a pointless separator on the end.
18:24arohnerfoo(x).bar().baz()
18:24tomoj,(apply str (interpose '/ ["foo" "bar" "baz"]))
18:24clojurebot"foo/bar/baz"
18:24arohner(-> x foo bar baz)
18:24piccolinoAh, there we go. Thanks.
18:24tomojstr-join is in str-utils I believe
18:25piccolinoAh, that too, nice. Thank you.
18:25div-hm, interesting
18:25notallamacomp is a bit irritating because it's backwards compared to my intuition. so i made >>> as a reverse-ordered comp.
18:26tomoj((>>> foo bar) x) is (bar (foo x)) ?
18:26notallamayeah
18:27AWizzArdwhat is >>>?
18:27tomoj...
18:27tomojsee 4 lines up
18:28notallamafunction in here: http://github.com/hclarke/pointfree-clojure just a reversed comp.
18:30AWizzArdnotallama: yeah, a function (pipe ...) would be nice, like comp but in reverse order :)
18:31woobyor (apply str (interpose "/" ["foo" "bar"]))
18:32hiredman-> and ->> are similar to the thrush combinator
18:33hiredman,(->> ["foo "bar"] (interpose "/") (apply str))
18:33clojurebotEOF while reading string
18:34hiredman,(->> ["foo" "bar"] (interpose "/") (apply str))
18:34clojurebot"foo/bar"
18:36hiredman,(->> "bar" (conj []) (into ["foo"]) (interpose "/") (apply str))
18:36clojurebot"foo/bar"
18:36notallamai'm kindof a licencing noob. what's one that basically says "do whatever you want, but put my name somewhere"?
18:36hiredmanhmm
18:37hiredmanMIT/X11
18:37notallamathanks
18:37hiredman,(-> [] (conj "foo" "bar") (->> (interpose "/") (apply str)))
18:37clojurebot"foo/bar"
18:38div-haha
18:40div-i suppose it takes some getting used to mentally mapping the evaluation scheme when encountering -> and ->> :}
18:41notallamait's a lot easier if it's formatted vertically, i find.
18:41hiredman,(pl (↕map (replicate 3 (↕apply vector $ (↕map range $ 10 inc · inc · inc) call · ⌽* $ 10 · call · (⌽+ -2) map)) shuffle)))
18:41clojurebot((40 100 90 70 30 10 60 20 80 50) (100 60 50 80 40 10 20 30 90 70) (80 10 20 100 60 40 90 50 30 70))
18:42notallama..what?
18:42hiredman:)
18:43hiredman,(pl (λx (inc x) 1))
18:43clojurebot2
18:44somnium,(doc pl)
18:44clojurebot"([& forms]); replaces a $ b with (a b) walking right to left replaces a · b with (comp a b) left to right ⌽a with (uncurry a) left to right ↕a with (flip a) left to right"
18:45hiredmanoutdated docstring
18:45hiredmanbut mostly correct
18:45somniumhiredman: have you been teaching clojurebot dialect?
18:45notallamahuh, fancy
18:46hiredmanand of course uncurry actually curries a function
18:46notallamawell of course.
18:46cemerickwow, that looks painful
18:47hiredmandone with zippers, I guess I should look into redoing it with clojure.walk now that I am aware of it
18:54somniumI hope some form of heredoc emerges eventually, it would be wonderful to be able write macros that can see whitespace and arbitrary characters.
18:54somniumI guess its not much of a priority with all the progress on cinc
18:55tomojwriting macros that can see whitespace and arbitrary characters sounds horrid to me
18:56tomojmacros are already bad enough when you get to work with forms, can't imagine what they'd be like if you had to work with raw strings
18:56notallamayou could write a macro to inline perl in your code, though.
18:56somniumtomoj: strings are easy to make into forms, except when you can't see all the characters :)
18:57somniumtomoj: it would be easy to imbed any kind of parser anywhere, like notallama said ^^
18:57tomojok, if you happen to have a perl parser lying around
18:58tomojI guess if you want to go through the trouble to write a parser it would be pretty cool
18:58tomojmacros are awesome because you don't :)
18:58tomoj(have to go through the trouble, I mean)
18:59somniumtomoj: not a full language parser, but some kind of yaml-like declarative syntax would be convenient for dsl designs
18:59somniumright now # % ^ probably others choke the reader
18:59hiredmanyou can do that if you reall want
18:59somniumand plain strings have their own limitations
18:59hiredmanjust use reflection to get at the two reader macro tables
19:00somniumhiredman: I saw something about that
19:00tomojyou can add reader macros?
19:00somniumI don't want to add reader macros so much as be able to turn off the reader on occasion
19:00hiredmantomoj: the reader looks up reader macros in a private array, so it is technically possible to get at the table and add your own
19:01somniumturn off the existing reader macros I mean
19:01hiredmanbut that would be very bad and you should not do it
19:01tomojindeed
19:01tomojstill I didn't know it was even possible
19:02hiredmanmy reade uses condp as a switch so you can't do that any more
19:02somniumsomething like (#no-reader-macros macrosym & raw-string-input)
19:03hiredmansomnium: is basically what a reader macro's view of the world is
19:04hiredmana reader macro is called with the pushbackreader and last chracter read as arguments
19:04tomojso the reader macro sees whitespace?
19:04tomoj(but just ignores it?)
19:04hiredmansure
19:04hiredmanreader macros see the reader
19:05somniumhmm
19:05hiredmanhttp://github.com/hiredman/clojure/blob/readerII/src/jvm/clojure/lang/LispReader.java#L365
19:05somniumwell I guess its not gonna happen then :)
19:05hiredmanthat is a reader macro
19:05hiredmanactually, it is a reader dispatch macro
19:06somniuma heredoc would be close enough though
19:06hiredmanbut uh, they are not that different
19:06somniumit wouldn't quite as seamless, but it will still make it easy to imbed yaml or whatever
19:06tomojhow is a heredoc any less seamless than (#no-reader-macros ...)?
19:06hiredmanhttp://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj#L306 clojure version
19:06somniumbecause the user has to delimit the input
19:07somniumbut its a very minor quibble
19:07tomojI don't understand
19:07somniuma heredoc would be fully satisfying
19:07tomojyou have to delimit the input with #no-reader-macros too
19:07somniuminstead of (yaml-parser ... ...)
19:07tomojooh, I see what you mean
19:07somnium(yaml-parser """ ... ... """)
19:08tomojI don't like (yaml-parser ...) at all
19:08somniumyeah, it is disconcerting for someone reading it
19:08somniumwho doesn't know what its doing
19:08tomojand very hard to indent properly, I'd think
19:09tomojunless your editor crawls through and finds all these weird macros, I guess
19:09somniumits kind of possible now, you just cut up to the first newline, and then build a tree from whitespace
19:09tomojparedit would have a fit
19:09somniumbut strings have all kinds of escape issues
19:09somniumtrue, a heredoc would solve that though
19:10tomojyeah
19:10tomojhow often are you wanting to parse literal yaml in your source files?
19:10tomojseems a very strange thing to do
19:11hiredmanword
19:11hiredmanthis is clojure, we have map literals
19:12Chousukehiredman: java written in clojure is less readable than Java written in Java :(
19:12somniumI'm building a mongodb driver right now, and wanting to define schemas and validations with something yaml-like would be very nice
19:13hiredmansomnium: a clojure mongodb drive should use clojure map literals, not yaml
19:13somniumbut its already possible to get very ceremony declarative code
19:13hiredmanChousuke: regex-reader isn't really that bad
19:14hiredmanhttp://github.com/hiredman/clojure/blob/readerII/src/clj/clojure/reader.clj#L225 fn-reader
19:14somniumhiredman: glance at the api at http://github.com/somnium/congomongo
19:15hiredmanwhy?
19:15somniumhiredman: it does use map literals, and it could be reduced a lot more
19:15somnium...
19:15hiredmanwell, then use less map literals
19:16somniumok
19:16Chousukehiredman: I guess it's not bad if you compare it to the surroundings :/
19:16tomojlooks fine to me
19:16Chousukebut the shape is all wrong.
19:16tomojexcept I'd use keywords instead of strings
19:16hiredmanshape?
19:16Chousukenested ifs look awful :(
19:16somniumtomoj: there are some issues with the current java driver
19:16Chousukeyeah. it's too deep.
19:16somniumtomoj: but they're almost worked out
19:16tomojI don't use mongodb
19:17hiredmanyeah, well, the java code is a bunch of if(x) return w
19:17Chousukeyeah :/
19:17tomojI just mean the map literals on your readme look OK to me and I don't see how yaml would make them better
19:17somniumok
19:17ChousukeClojure is horrible at stuff like that :)
19:17Chousukewhich is a good things
19:17Chousuke-s
19:17hiredmanalot of that could be collapsed into conds I guess
19:18hiredmanI did go a little wild, I think I may have 3 or 4 deep nested letfns
19:18ChousukeI wish I could just fix the bug in my reader
19:18Chousukebut it persists
19:18somniumare letfns similar to definline, or just a convenience for let [f (fn ...)]?
19:19tomojsomnium: what are you using for json?
19:19hiredmankeep plugging away, over the weekend I felt like I might never get mine in shape
19:19tomojsomnium: the latter
19:19somniumtomoj: the parts of the java driver that work, and contrib.json for the rest
19:19hiredmanletfns also make names visible to all other fns
19:19hiredmanin the letfn
19:19Chousukethe Compiler might be making some assumptions that are no longer true with my reader :/
19:19somniumthe java one is almost certainly faster, but its taken some patches to make it easily modifiable at runtime
19:19tomojoh I hadn't realized there was json in contrib
19:20tomojI had found http://github.com/danlarkin/clojure-json and was poking around in that
19:20hiredmanChousuke: :(
19:20Chousukebut I'm pretty sure I don't "overconsume" the source stream anymore.
19:20hiredmanwell the compiler is my next stop
19:20tomojwhy do you need to modify your json stuff at runtime?
19:20Chousukeplease don't java-translate that :P
19:20somniumthe java driver is very java-the-language centric unfortunately, but its been a good learning experience at how to mold java to clojure's view of the world
19:20hiredmanChousuke: :P
19:21somniumtomoj: doesn't have to be done at runtime, but instead of modifying the driver source they've been adding hooks to change its behavior
19:21somniumtomoj: so at startup clojure teaches it to handle clojure and then its all good
19:21ChousukeI might actually mod my reader at some point to be restartable.
19:21tomojbut I mean, what needs to change about java json?
19:22hiredmanI think the compiler might have less of a bootstrapping problem
19:22somniumtomoj: its java centric, it likes objects, and it likes to create objects
19:22tomojah :(
19:22tomojdamn objects
19:22hiredmanbut, uh, I haven't looked yet
19:22somniumindeed
19:22Chousukeie. that you can just feed stuff into it and it either gives you back items and/or a function that you can call with more input :)
19:22tomojgonna work on couchdb stuff so gotta figure out what to do about json
19:24somniumtomoj: take a look at a comparison of mongodb and couchdb if you have time, they're different animals in interesting ways
19:27tomoj"proprietary binary protocol"
19:27tomojthat just means it's not a protocol mongo shares with other software, right?
19:27somniumtomoj: I guess so, BSON?
19:28tomojdunno, just reading http://www.mongodb.org/display/DOCS/Comparing+Mongo+DB+and+Couch+DB
19:28somniumits compressed JSON for all intents and purposes, so its indexable and searchable
19:31tomojbased on that I'm stickin with couch
19:35scottjI ran into the problem where I had a map in my source code that got too big so I had to put it into a separate file and I'm reading it in and then running read on it to store it in a variable, and now all my newlines appear to be doubled up, where in emacs I see the newline and a ^M character. Any ideas what step I missed?
19:36scottjemacs = slime in this case
19:36scottjand newlines = newlines in strings in values of my map
19:38tomojscottj: windows?
19:39tomoj^M is what the carriage return looks like, right?
19:41scottjtomoj: yeah windows
19:42scottjtomoj: ok, I changed file endings to Unix on that filename and now the ^M's don't show up.
19:53technomancyc.c.shell-out/sh looks like it doesn't support streaming output from subprocesses; is that correct?
20:01technomancychouser: what would you think of a patch to add this?
20:05rlbtechnomancy: looks like it to me
20:05rlb(that it doesn't)
20:07technomancyit's pretty easy to implement, but I've had contrib patches languish for a long time, so I don't want to move forward unless I've got buy-in from committer =)
20:07rlbeventually it'd be nice to be able to easily build process pipes
20:31miltonsilvahi
20:31miltonsilvahttp://paste.lisp.org/display/89475
20:31savanniQuick question...
20:32savanniI'm wanting to attach documentation to an entire namespace. Just a multi-paragraph explanation of what the namespace is about. How can I do that?
20:32rhickey_jeez, there's deftypes all over contrib
20:32miltonsilvaI'm having a bit of trouble understanding why my code (above link) doesnt work
20:37chousersavanni: I think most contrib libs have namespace doc strings you could mimic.
20:40rhickey_I wonder if all these contrib deftypes could become new deftypes
20:40savanniOkay, I'll grab one of those.
20:41rhickey_or do I have to rename deftype?
20:42cemerickrhickey: how many are there?
20:44rhickey_accumulators, complex, pprint, probabilities, stream utils, types
20:45cemerickI'd say anyone naming anything def* is accepting the risk of being compelled to change up down the road.
20:46rhickey_pprint's is its own
20:48rhickey_well, they could all be changed to either qualify use or refer-clojure with exclude
20:49rhickey_deftype seems like too good a name to give up
20:49rhickey_and types/deftype merely approximates what deftype does
20:49cemerickrhickey_: shouldn't the maintainers of those libs decide on what to do in each case?
20:50rhickey_cemerick: yeah, I'll ask on dev
20:54rhickey_has anyone tried deftype/defclass?
20:56cemerickrhickey_: I'll hopefully get to it on Friday. I'm up against it, as usual. :-(
20:57cemerickIn some profiling, about 20% of our overall app runtime is map/struct slot access, so I'm pretty enthusiastic to get something better in there. :-)
20:58rhickey_cemerick: deftype is better than defstruct already, at least with few fields, but I am hoping for much better with case
20:59rhickey_and of course, you can now go to defclass and get field access perf
20:59cemerickrhickey_: well, the three key structs in that 20% are totally fixed, so defclass is appropriate there
20:59cemerick:-)
21:00rhickey_defclass supports expando too, so you can mix fixed .field access with :expansion-field access
21:00cemerickrhickey_: option B or C?
21:00rhickey_C
21:01cemerick:-D
21:02rhickey_you might have missed - I decided I always regret building in an exception, since you can build a throwing api on a non-throwing but not vice-versa, so we can define getx anytime
21:02rhickey_we'll see if Konrad et al get riled up or not :)
21:03rhickey_I feel like I heard from the dynamic camp today, and argued for the missing static camp
21:03cemerickI'm all for that. Let the man on the ground decide what's best.
21:04rhickey_well, it should be obvious where Clojure's heart lies - flexibility
21:04cemerickI think C is a perfect blend of both, especially as people can get all B&D with their def-closed-type-really-I-mean-it forms built on deftype.
21:05rhickey_people have asked for throwind get and assoc, both can be written today if needed (maybe are already in contrib :)
21:05rhickey_throwing
21:05cemerickyuck
21:05cemerickthrowing assoc on what, structs?
21:05rhickey_yeah
21:06rhickey_or anything, just key must be present
21:06cemerickoh, I see
21:06rhickey_use a factory to create and then avoid mistakes
21:06rhickey_very many maps are never expanded
21:06cemerickeh. That's what testing is for.
21:07cemerickours accrete stuff in their travels frequently, like so many snowballs. :-)
21:08chouserheh
21:08rhickey_well, I'm sure will still like the new deftype
21:08rhickey_Konrad et al
21:08cemerickHe's on the list mostly, right?
21:08rhickey_now just case and protocols
21:09cemerickI've let it build up again... > 750 msgs
21:09rhickey_cemerick: yeah, he did the ADT stuff, and - deftype :)
21:09cemerickrhickey_: is expando implemented with a map off to the side, or are you doing some field-injection-magic?
21:09rhickey_a map
21:10chouserin a volatile field? (eventually?)
21:10rhickey_too expensive to recompile class on assoc
21:10rhickey_chouser: no, real immutability like all the other stuff
21:10chouseroh oh, right. sorry.
21:11chouserslipped the clutch there
21:11rhickey_we need some print/read support too...
21:11cemerickchouser: man, that's me every day in here ;-)
21:11chouser:-)
21:12rhickey_#:Foo{:a 1 :b 2} for deftypes?
21:13rhickey_#:org.clojure/Foo{:a 1 :b 2}
21:14rhickey_or adt style #:Foo[1 2]
21:15cemerickwas this on the list before? Seems familiar...
21:20chouserI sure like the brevity of the latter, but it seems fragile over time.
21:21cemerickYeah: what if you've got a type with 9 numeric slots (or whatever)? Not a fun debugging exercise.
21:22rhickey_welcome to Haskell
21:22rhickey_that's my beef with ADTs - positional, constantly have to relabel in pattern matches
21:22cemerickheh. You missed the discussion of ->> vs >>> vs |||| earlier.
21:23rhickey_OTOH, out of the box defype give you positional factory fn/ctor only
21:23rhickey_subsequent to construction, you have labeled access
21:26st3fanis there a string->number ?
21:26st3fanwhere do i look for functions like that?
21:26tomojjava I guess?
21:27chouser,(Integer/parseInt "5")
21:27st3fanoh like (Integer. "123") ?
21:27clojurebot5
21:27chouser,(read-string "123M") ; or the clojure way
21:27clojurebot123M
21:27chousertake your pick.
21:28tomojhmm
21:28tomojis read-string dangerous?
21:28Raynes<3 read-string
21:28chousertomoj: yep, unless you turn off *read-eval*
21:28st3fanwell the string comes from a regex that matches a number
21:28st3fanso i doubt there will be 'lisp injection' errors :-)
21:29chouserprobably good enough.
21:30chouser,(read-string "#=(java.lang.System/exit 0)")
21:30clojurebotjava.lang.RuntimeException: java.lang.Exception: EvalReader not allowed when *read-eval* is false.
21:35st3fanwhen i have a .clj file open in emacs with slime and clojure-mode, how do i compile the whole file?
21:35st3fanC-c C-c only seems to compile the last form in the file
21:36Raynesst3fan C-c C-l, if you want to load the entire file into the REPL. If that's what you mean.
21:37st3fanis that a good way to do 'edit, compile, test-in-repl' ?
21:37RaynesIt's how I do it.
21:38somniumC-c C-k recompiles it if it's already loaded
21:38st3fancool
21:39Raynesst3fan: You can also evaluate a single sexp if you put the cursor just after the last closing paren and do C-x C-e.
21:39st3fanahhh good one
21:40somniumit doesn't add in new vars after recompilation, have to do (use ... :reload), existing vars get instantly updated though
21:40st3fanright
21:41RaynesIncidentally, I just always use C-c C-l.
21:41st3fanwhat is the advantage over C-c C-k ?
21:42RaynesI'm not sure why you would use C-c C-k. Maybe somnium can help us out on this one.
21:42st3fanit works on the current buffer .. skips the query for the file?
21:43st3fanis there a logging library for clojure? or some simple wrapper?
21:46somniumRaynes: well, with compojure for example, jetty is off spinning in another thread, you can recompile the code and it immediately responds
21:47st3fanyeah that is cool
21:47somniumthough perhaps its the same with load file? I've gotten into the habit of using recompile
21:49hiredmanst3fan: there is something in contrib
21:49hiredman(that I really should try out)
21:59st3fanhmm is there a way to load a jar file from the repl? i don't want to restart emacs
22:01hiredmanthere is add-classpath
22:01hiredmanbut uh, don't make a habit of using it
22:02st3fani have no idea how to package clojure apps yet :-)
22:02hiredman*shrug*
22:02hiredmanadd-classpath is not about packaging
22:02st3fani know
22:02hiredmanit's about adding a jar/directory to the classpath
22:03st3fanbut i know my app depends on some jars
22:03somniumyou can just put .clj files in a jar and put in the classpath when you start clojure
22:03st3fanright
22:04st3fanlittle shell script wrapper to setup the classpath and start the app?
22:04somniumyeah, if you always ./lib and ./src ... you can use the same one everywhere
22:05somniumhave you used clojure-project or swank-clojure-project in slime?
22:05somniumthat's what they do
22:09Raynessomnium: clojure-project? What's this voodoo you speak of?
22:10somniumRaynes: eh? it comes with one of the clojure...el files
22:10somniumRaynes: you use ant right?
22:10RaynesMhm.
22:10somniumI changed it to work ant if you want to try the function
22:10RaynesI tried M-x clojure-project - Nothing happened. :>
22:10somniumit was built to use maven but one xml dialect is enough for me
22:12ambienti find classpath annoying :/
22:12ambientautomatically adding project root, from whence the source file is ran from, to the classpath would be nice
22:12ambientdont know if that is possible with JVM
22:14st3fanman i love how much i get done with a bunch of small functions
22:14somniumRaynes: http://paste.lisp.org/display/89477
22:14st3fanwithout the infrastructure that a regular java app would need
22:14somniumits pretty much a copy of the original but it looks for build.xml instead of a pom
22:15somniumand I keep stuff in ~/.clojure, so if you decide to try it change the relevent paths
22:16RaynesThanks. <3
22:19st3fanquestion .. what does the & mean in (insert-records table & records) ? does it mean records is like a vararg?
22:19st3fanlike (insert-records :mytable {} {} {}) ?
22:20hiredmanyeah
22:20st3fanhmm what if i have a list of maps? can i do something like python's (insert-records :mytable *listofmaps) ?
22:21chouser(apply insert-records :mytable listofmaps)
22:22st3fanahh i remember this from practical common lisp :-)
22:23cemerickman, dealing with agent errors can get tricky
22:23st3fancool it works :-)
22:26chousercemerick: there's ticket for that
22:31technomancychouser: thanks for committing my deletion patch for contrib!
22:37chousertechnomancy: finally. :-) You're welcome. You saw my note?
22:40technomancychouser: if it was a note in IRC I missed it; closed my client indiscriminately after work.
22:41chousertechnomancy: no, on assembla
22:42technomancyoh, I see; the windows question
22:49cemerickIt seems a little absurd that StackOverflowError is an error.
22:49chouserinstead of?
22:51cemerickI consider it to be an app-level failure, especially these days and with current languages.
22:52cemerickor, current popular idioms, I should say
22:54technomancychouser: sorry; crap connection here. will try to test in a windows VM
22:54chousertechnomancy: thanks.
22:55technomancyappreciate the attention to the tickets. =)
22:58djorkso I've been playing with verifiable objects
22:59tomojwhat are verifiable objects?
23:00djorklet's say you have a map or a vector
23:00djorkand you want to share it
23:00djorkbut you don't want someone to be able to modify it
23:03cemerickheh, where were you when rhickey was trying to represent the static type folk? ;-)
23:04chousernobody can modify any of Clojure's maps or vectors. :-)
23:05djorkhttp://gist.github.com/220900
23:05djorkso you set your salt on a server, for instance
23:05djorkand you can store large data structures in other places
23:06djorkI guess it's not that special but it was fun to think about
23:07woobyhey all, working on project euler prob 92... came up with this: http://gist.github.com/221079
23:07woobyfor some reason that last line doesn't terminate, for any size range
23:07djorkI was thinking about this in the context of MMO games where maybe you don't want to store every piece of data ever generated by players, or you could let players store unique items etc
23:07woobyany help very welcome
23:08tomojdjork: so that would mean a player couldn't forge an item?
23:08tomojpretty cool
23:09djorkyup
23:09tomojdoes giving out a large number of hashes using the same salt expose you?
23:10cemericksha-1 isn't doing its job in that case, no?
23:11djorksha-1 is probably fine
23:11djorkthe salt could be anything
23:11tomojwhy does authlogic for example use a different salt for every user?
23:11cemerickright, I'm sure it is, I was just saying that if we can't depend on sha-1, then a lot of stuff is in trouble :-)
23:11tomojI guess maybe that's so you can't tell that two passwords are the same
23:11tomojin this case that doesn't matter
23:11djorkit's better to change up the salt
23:12djorkbut it isn't super critical
23:12djorkin a password situation you want a different salt because it means a rainbow table is ineffective against any other password
23:13djorkso maybe a secret permutation of some part of what you're hashing would be good
23:15tomojwell rainbow tables etc don't matter at all in this case, right?
23:15tomojbecause they already have the object
23:52hiredmanclojure is so cool
23:53woobycan't agree more
23:53hiredman http://gist.github.com/221130 <-- check for files added/removed on an ftp directory and message me on jabber with the differences
23:54woobythat's insanely awesome