#clojure logs

2011-03-30

00:21no_mindin ring which of the packages have handle-dump function ?
00:50amalloytechnomancy: ping
00:51clojurebottechnomancy is to blame for all failures
00:51amalloyclojurebot: oh thanks, now he'll associate all the bad feelings he gets from you with me instead
00:51clojurebotGabh mo leithscéal?
01:01amalloytechnomancy: i guess a ping is silly, when all i have to say is: "are you interested in https://github.com/amalloy/clojure-mode/commit/7207ee18507c95005305665a5f662f73fad37019?"
01:09no_mindif I have a function name as string, how can I call the function ?
01:09amalloy,((resolve (symbol "first")) [1 2])
01:09clojurebot1
01:15amalloyno_mind: that one's for you, by the way :P
01:15no_mindk
01:33waxroseamalloy, Which hosting service are you using? Amazon?
01:33amalloywaxrose: hosting for what?
01:34waxroseOr recommend for a web application. I am thinking about using Google App Engine..
01:34amalloy*shrug* not really my department
01:34waxroseoh
01:34waxroseSorry, I just assumed you were using a certain service for your Clojure apps.
01:35amalloyi can barely start a ring server
01:35waxrose>.<
01:36waxroseI guess I will just stick to GAE then, seems easier to get a ring set up and so forth.
01:39tomojno_mind: the fact that you asked that after a ring question worries me
01:39amalloyhahaha
01:41waxrose>.<
01:58amalloytomoj: i should train myself not to answer that question without a preface of "OMG DON'T DO THIS"
02:08amalloyplanet clojure has been failing to load for me for an hour or two. anyone else having trouble?
02:09waxroseseems down
02:10waxroseping fail also
02:24brehautno_mind: ring-devel ring.handler.dump/handle-dump
02:28no_mindbrehaut, that was throwing error. I had added ring-devel in :dev-dependencies of project.clj . Though ring-devel was installed in the dev folder under lib, but clojure could not see the package.
02:29brehautno_mind: what are you listing for your ring :dependancies ?
02:30raekwhat error? "could not find ring/handler/dump.clj on classpath" or "could not find class ring.handler.dump"?
02:30no_mindring/core "0.3.7"
02:32brehautno_mind: really? not ring/ring-core "0.3.7" ?
02:32brehautno_mind: what about in your ring-devel link in :dev-dependancies
02:33brehauts/dependancies/dependencies/
02:33sexpbot<brehaut> no_mind: what about in your ring-devel link in :dev-dependencies
02:33no_mindbrehaut, let me post the complete project.clj
02:33brehautthat would be helpful
02:34brehautno_mind: just dont use pastie.org it never works for me
02:35no_mindbrehaut, http://pastebin.com/p5m3gbGs
02:38brehautno_mind: and what is the particular error?
02:42no_mindwhenI give :us directive, progran fails to compile and says cannot find dump.clj
02:42brehautno_mind: can you paste the specific error and the offending :use somewhere
02:43no_mindk
02:43amalloybrehaut: you don't find it more fun to debug through paraphrasing?
02:43brehautamalloy: i have to do enough divining in my dayjob ;)
02:43amalloywhat is your day job, anyway?
02:44brehauti make websites (with python/django)
02:44brehauti dont design them though
02:44waxrosenice
02:44brehautwaxrose: all except for the ORM ;) i have many a curse for that
02:45waxroseI was doing Ruby/Rails for a while, but I do design also. >.<
02:46brehautthe design is the part that makes me really tear my hair out. but i contract to a design company :D
02:46amalloyah. so your clients treat you as a black box that includes design, but you don't actually do it
02:47brehautactually, my clients are the design company :) their clients treat them as a blackbox that includes development but they dont actually do it ;)
02:47waxroseBut I will admit, last free lance work I did was for Baylor Univ, horrible experience.
02:47waxroseSo I can understand the pulling the hair out routine.
03:34Guest40377Knock knock
03:36Guest40377nobody here
03:36robinkThere are people here.
03:38waxrosefloating
03:39amalloymore likely, none of the people here are interested in responding to "knock knock"
03:42amalloysadly there is no #knockknock or #knockknockjokes channel. that would make a good conclusion for my statement
03:42waxrose:P
03:47Deranderamalloy: knock knock
03:48GuySenseidiscovered clojure some 5 days back.. after 5 years of java... its a revelation.. i was trying to make a framework in java and it turned out clojure exists :D
03:49GuySenseistill learning.. but i have a strong feeling i can bet my life on it :) it is beautiful
03:49DeranderGuySensei: welcome to the club
03:49GuySenseithanks!
03:50GuySenseiso how big is this club? worldwide? saw only 32k downloads of clojure on github
03:50GuySenseiseems pretty small, for such a thing
03:50GuySenseithough good for us;)
03:54raekI think the most common way of obtaining the clojure jars is through the maven repo
03:54raekyou rarely need to build the source manually
03:58Fossithey are great for study
03:59amalloyFossi: yes, but you probably won't be downloading the zip from github to read the source
03:59GuySenseiok.. though i got the zip straight from github.. it contained source as well as jars.. both needed i guess.. to understand it more
03:59amalloymight as well clone it
03:59Fossiyeah, right
04:00amalloyGuySensei: raek's point is that you don't need to download anything. (warning: gross oversimplification coming) the general flow is to create a maven project with clojure as a dependency. then when maven fetches the deps for you, it gets clojure as well
04:01amalloy$google Raynes getting started with clojure blog
04:01sexpbotFirst out of 61 results is: An indirect guide to getting started with Clojure » Bathroom ...
04:01sexpbothttp://blog.raynes.me/%3Fp%3D48
04:01amalloysexpbot: that link sucks
04:01amalloyhttp://blog.raynes.me/?p=48
04:02GuySenseiamalloy: got it!
04:03GuySenseilet me check out raynes blog.. just bumped into a good question of his on stackoverflow when he was a newbie.. good to know he is even writing a blog on it now! :)
04:05amalloyyeah, when he's not bugging me to write his code for him :)
04:05amalloyanyway have fun. i'm off to bed
04:07GuySenseihaha
04:07GuySenseigood night!
04:24ejacksonmornin'
04:26GuySenseioff to watch India Pakistan cricket match! see you guys around.. adios!
04:59fliebelClojure does not have continuations, does it?
05:00midsfliebel: https://github.com/swannodette/clj-cont
05:00fliebeloh, good one, dnolen! haha
05:03fliebel$mail dnolen What are your sinister logic constraint scheme plans with clj-cont? (btw, check this: http://www.ccs.neu.edu/home/dorai/t-y-scheme/t-y-scheme-Z-H-16.html#node_chap_14 )
05:03sexpbotMessage saved.
05:05joshua__$mail amalloy I'm able to mail you? Hacks!?!
05:05sexpbotMessage saved.
05:06joshua__$mail joshua__ testing
05:06sexpbotMessage saved.
05:06joshua__How do I get a message back out?
05:06joshua__nvm
05:06clgv$mail help
05:06sexpbotMessage saved.
05:07clgvups lol
05:07clgv$help mail
05:07sexpbotclgv: Send somebody a message. Takes a nickname and a message to send. Will alert the person with a notice.
05:07clgvi think you can simply do "$mail"
05:08joshua__I think you get it by /msg sexpbot mail
05:08joshua__I say this because it gave me a little IM telling me so.
05:08clgvboth. $mail works as well
05:08mduerksendoes sexpbot have a spam filter? ;)
05:09midsoh no, look what fliebel did
05:10fliebelmids: ?
05:10mids(initiating the mail spam thing)
05:21clgv,(dotimes [_ 3] (println "$mail clgv test ;)"))
05:21clojurebot$mail clgv test ;)
05:22clojurebot$mail clgv test ;)
05:22sexpbotMessage saved.
05:22clojurebot$mail clgv test ;)
05:22sexpbotMessage saved.
05:22sexpbotMessage saved.
05:22clgvthats evil ;)
05:26fliebelSomeone should make sexpbot do asciieyes, reporting to it's boss of course, that'd be evil.
05:32clgvhey but massmail is possible with that clojurebot-sexpbot-combo ;)
06:07CozeyHi is anybody using clojure under a container different then jetty?
06:08CozeyI have a problem with dynamic reloading: i use Resin (caucho.com) application server, and when you give it a new version of app.war, it will "redeploy" it - unpack it's contents and reload the classes. this works for java, but seems to not reload clojure code properly.
06:09Cozeydo You have any pointers to what i could do with this? (perhaps disabling dynamic reloading in java, i'm not sure, howevere, how to do it)
06:09fliebelCozey: AOT'ing *everything* might work. Dunno, but I'd think Resin does not reload non-class files.
06:10CozeyI just did that
06:10Cozeyand i have *.class files along with *.clj files
06:11fliebelidk, I don't know.
06:11Cozeyunder WEB-INF/classes
06:11Cozeyi'll send a mail to resin guys, perhaps they can give a shot at it
06:12Cozeywill (require) (use) etc use a aot-compiled version first, if it's available?
06:13fliebelDoes anyone have a good idea about implementing amb in Clojure? I guess it will involve loads of macros, atoms and lazy seqs.
06:16clgvamb?
06:16clojurebotamb is http://paste.lisp.org/display/73311
06:17rfgpfeifferaren't exceptions slow?
06:17Chousukeno.
06:18Chousukecreating exception objects is the most costly operation in throwing one I think.
06:18clgvrfgpfeiffer: slow compared to what?
06:18rfgpfeifferthe call/cc implementations in kawa for example
06:19ChousukeJohn Rose had a nice blog post about this
06:20Chousukehttp://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive I think there was another one too :/
06:22rfgpfeifferthanks
06:22fliebelIs there something like lein/cake rename?
06:25rfgpfeifferfliebel: for renaming what? namespaces?
06:25fliebelI think cake replaces $$ with your project name when you create a new project.
06:25fliebelI want to change the name of my project
06:27fliebelhttps://github.com/ninjudd/cake/blob/master/src/cake/tasks/new.clj#L18
06:31rfgpfeifferso you want to change the directory names, the namespace names, and the project.clj
06:31fliebelright
06:43Cozeywhat's the easiest way to make use of ant tasks (using cake)?
06:46Cozeylancet?
06:46clojurebotlancet is a build system that works with ant written as an example for the Programming Clojure book.
06:47cemerickAFAIK, lancet is an unsupported experiment
06:47cemerickor, was
06:51fliebelUh, oh… I re-run a hacked version of the Cake code to rename my stuff, but I managed to corrupt my git index file. :( Any ideas what to do now?
06:57clgvcemerick: how does counterclockwise progress? next release in april?
06:59cemerickclgv: That's up to Laurent. :-) I think the last RC is good enough to cut a final release of 0.2.0, anyway.
06:59clgvcemerick: ah good :)
07:16fliebelWhat is the difference between all those ref functions? alter/comute/ref-set/ensure Does JoC say anything about it?
07:24midsfliebel: it does, chapter 12.2
07:24midserr 11.2
07:26fliebelmids: I see… I'm letting the complications of commute sink in.
08:04raekfliebel: http://java.ociweb.com/mark/stm/article.html
09:36fliebelIs there a function? (I almost hit enter, I'm sleeping) Is there a function that takes.. oh wait, probably comp… no, that takes a single args fn and turns it into a vararg fn and disposes those args?
09:38ejacksonoh dear.... padded walls times for you fliebel
09:38fliebelpadded walls?
09:39waxrose:3
09:40mduerksenfliebel: i didn't get what you want exactly, but could it by any change be fnil ?
09:40mduerksen*chance*
09:41fliebelmduerksen: No, more like ((wrapper type) 1 :a "blag") => int
09:41ejacksonfliebel: of the sort with which they usually surround the nutty :)
09:41ejacksontoo much coding for you !
09:42fliebelejackson: I'd prefer a hammock to padded walls, but there might be some truth in your words.
09:43ejacksonyes, my hammock is awaiting the summer, but this that is soon.
09:45fliebelThere must be something better: #(type (first %&))
09:45fliebel&(#(type (first %&)) 1 :a "blarg")
09:45sexpbot⟹ java.lang.Integer
09:45@chouserfliebel: I doubt there's anything better
09:45fliebelokay...
09:45@chouseroh, this is for a dispatch function?
09:45ejacksonhas anbody got an idea how to package an uberjar for a clojure function ?
09:45fliebelyea :) you want me to use protocols?
09:46ejacksoni tried one-jar without success
09:48fliebelchouser: but does that matter? How do you usually dispatch on the first or the first few args?
09:49@chouserfliebel: I think you name all the args (as documentation, if for no other reason) and then call (type x) on the first one. :-P
09:50fliebelchouser: Well, okay… I'll just get over it and spend more than 5 characters on it.
09:54fliebelchouser: Will the dispatches' args be used in the docs for the argument names?
09:55@chouserum. probably not. :-(
09:56fliebelit;s a sad world we live in, where sleepy programmers are put in padde wals an multimethods don't show the args of their dispatcher in the docs.
10:06scottjdoes this already exist? (I know about ->) (-0> conj ([] 1 2) 4 (5 6)) => (conj (conj (conj [] 1 2) 4) 5 6)
10:08Raynesfliebel: It replaces +project+, not $$
10:09RaynesLicenser: Ping.
10:09fliebelRaynes: I figured, but I think it replaced +project+ in my git index as well, or something like that.
10:16dpritchettanyone enjoy that clojure sudoku solver vs python sudoku solver thread on HN this morning?
10:18yazirianbeen linking it around the office at work :)
10:18yazirianbig python shop, very helpful to people just learning
10:19dpritchettheh
10:19dpritchettjust ran the tests myself
10:19dpritchettturns out the clojure example wasn't compiled
10:19dpritchettit's a wee bit faster when i compile it ;)
10:33dpritchettthat said it still wasnt tremendously better... i'll execute it 1000 times without reloading and see if the JVM finds any magic
10:34thickey1where can (or, should) you place doc strings in extend-type?
10:37jkkramerdpritchett: clojure code is always compiled
10:37hoecktschau
10:37jkkramerdpritchett: glad you enjoyed the post
10:37dpritchettso running it out of the repl vs running it out of an uberjar i made is the same?
10:37dpritchettcoulda sworn i saw vastly different numbers when i built a jar
10:38jkkramershould be
10:38dpritchetti tried and tried to figure out ways to make the clojure jar execute faster (short of changing the algos) and came up empty
10:38dpritchetti'm still not comfy with this JVM thing :(
10:38dpritchettthanks for the post by the way, this has gotten me playing around with clojure for the first time in far too long
10:40jkkramerthanks, glad to hear it. i've got a stockpile of clojure experiments, so maybe i'll blog about more of them
10:41dpritchetti wrapped your clojure code in a leiningen project and gave it a command line argument to allow me to execute it an arbitrary number of times i.e. j$ java -jar sudoku-clj-1.0.0-SNAPSHOT-standalone.jar 1000 > 1000_runs_clj.txt
10:42dpritchettalso iirc i had to tweak the easy50 file from norvig's page to match the ======== delimiter you'd written into your code
10:42dpritchettgood fun!
10:56scottjjkkramer: did you run with -server and try more than 99 puzzles?
10:58jkkramerscottj: yes
10:59jkkramerafter the first few runs, hotspot didn't seem to do much
11:00dpritchettmine's chugging through 1000 iterations and i'm watching the logfile, doesn't seem to be speeding up
11:01dpritchettwonder if the JVM needs to take a deep breath first... i could put a wait timer in every 10th run maybe
11:01dpritchettor i could learn how the JVM works
11:01jkkramerif i were going for speed, i'd probably rethink the thing from scratch - using other data structures, mutation etc
11:01dpritchettor perhaps the fact that it's rotating through different difficulty levels makes it harder to optimize via profiling
11:02dpritchettthat is maybe if i ran easy-only for 1000 iterations or hard-only for 1000 iterations it would show some improvement
11:04scottjI think hotspot waits till 10,000 invocations of a method before compiling it to native
11:05scottjI haven't looked at the code but I guess some of the helper methods could easily do that in a couple games.
11:05clgvscottj: I dont think so. I tried with less invocations and didnt see any effect from manually inlining one of my functions since the jvm did a pretty good job already
11:14mattmitchellI'm attempting to mock a function in one of my tests. I'm using midje. Could someone give me a clue as to how I can mock an entire function?
11:19DantasIm looking forward to read "the joy of clojure". When will be available for .mobi/Kindle devices ?
11:22dpritchettfogus blogged on Monday that print orders direct from manning would include a mobi "when available"
11:22dpritchetthttp://blog.fogus.me/2011/03/28/joy-of-clojure-in-print/
11:22clojurebotI think you mean gnir.
11:25Dantasdpritchett: thanks !
11:26Dantasdpritchett: im wainting for the .mobi . ( kindle )
11:27clgv$findfn " " true
11:27sexpbot[clojure.string/blank? clojure.core/== clojure.core/string? clojure.core/distinct? clojure.core/boolean clojure.core/< clojure.core/= clojure.core/> clojure.core/>= clojure.core/<= clojure.contrib.string/blank?]
11:27dpritchettI have never tried mobi but I really like reading epubs on the Stanza app on my phone. HTML-based formats are kinder on my old hardware.
11:27clgv&(doc clojure.string/blank?)
11:27sexpbot⟹ "([s]); True if s is nil, empty, or contains only whitespace."
11:28dpritchettwhen compared to PDF i mean
11:28midsreading the PDF is doable on the kindle v3
11:29mids(after the usual rotation and zooming)
11:29dpritchettreading the JoC meap pdf on my iphone 3g via goodreader is doable but not exactly enjoyable
11:29dpritchetti tried it on my granddad's ipad and it looked just fine, scrolling and page turns were snappy too
11:30ejackson"my grandad's ipad" that's cool.
11:31dpritchettit was a gift from his kids. he prefers his two (three?) and his laptop(s)
11:31dpritchettHe really likes downloading powertoys and freeware and then hosing his machine and then reformatting or buying a clean new machine
11:32ejackson:)
11:34fliebelWhere do you people put examples in a lein project?
11:35midstest/
11:36scottjor an examples dir in src
11:36fliebelis test on the cp?
11:37mids(that is, after turning the examples into automated tests)
11:38fliebelmids: I was thinking about complex examples, more like integration tests.
11:42mattmitchellaye, how do you mock a function in a different namespace?
11:43fliebelmattmitchell: mock?
11:43mattmitchellfliebel: well, i'm kinda struggling with how to write one of my tests
11:44fliebelmattmitchell: probably binding?
11:44zerokarmalefthttp://www.youtube.com/watch?v=8mjky2QE9DA <= haha, Gnome Chompski: The Game
11:44zerokarmaleftoops, wrong chan
11:46mattmitchellfliebel: i have the function i'm testing., which passes callback fn to another function, which is in a diff namespace. the function in the other namespace, loops thru a vector, and calls the callback fn for every item. I want to mock the function in the other namespace, and call the callback fn in my test. Did that make sense?
11:48midsafaik binding works for that too
11:48midsor change your API and expose the callback-fn as argument
11:50mattmitchellsince my explanations are never as good as code: https://gist.github.com/894643
11:50mattmitchellmids: ok i'll looking into binding, haven't tried that yet.
11:51mids(binding [clojure.string/reverse identity] (clojure.string/reverse "123"))
11:58mattmitchellmids: thanks!
12:20yazirianhas anyone seen memory-leak-like problems when pushing large amounts of stuff around with clojure-contrib/sql? I'm trying to load a table in a postgres instance from a table in an oracle instance, and it blows out of heap space on tables with more than a few tens of thousands of rows
12:20yaziriani've taken three cracks at it so far https://gist.github.com/894704
12:21yazirianeverything in there looks suitably lazy, using resultset-seq and the like, and i am using doseq which shouldn't be holding the head or anything
12:22yazirianbut it's choking to death on a table with 93k rows or so, and jvisualvm is showing it's hanging onto a lot of char[] stuff
12:22hiredmandoseq isn't, but with-query-results is
12:22hiredman(hanging on to the head
12:23yaziriani thought resultset-seq was the part that took care of that?
12:23hiredmanwhat do you mean?
12:23yazirianhttps://github.com/richhickey/clojure-contrib/blob/6a0483d9e216ca00fc648a4b3673996b76a2785a/src/main/clojure/clojure/contrib/sql/internal.clj#L178
12:23hiredmanwith-query-results binds the results to a name for the scope of the with-query-results expression
12:24yazirianhmm
12:25hiredmanI maybe wrong given that with-query-results uses a function like that internally
12:27yazirianIt clearly IS holding onto something somewhere, but what's confusing me is that it doesn't LOOK like it should be.
12:32fliebelyazirian: I don;t know if this is the case, but doing a substring keeps the old string around… since you mentioned char[]...
12:32jweiss_,(comment {:a 0 :a 0})
12:32clojurebotDuplicate key: :a
12:32jweiss_i don't like this
12:32fliebeljweiss_: You're not the only one.
12:33dnolenthere needs to be a navigator for all of Clojure interfaces.
12:33amalloy&(comment TODO: make this work)
12:33sexpbotjava.lang.Exception: Invalid token: TODO:
12:33fliebelyazirian: I recal reading abotu certain DB interfaces having the substring "leak" calling (String.) on the result gets you a fresh string.
12:34sritchiehey all -- do any clojure.contrib.* functions exist for pretty printing xml?
12:34amalloyjweiss_: i wrote a patch to add #|....|# style comments, but it was rejected as undesirable
12:34jweiss_amalloy: i'd be happy if the reader went into "just find the closing paren" mode after (comment
12:34fliebelsritchie: Can't the standard xml lib print indented?
12:35amalloyfliebel: prxml does
12:35jweiss_or i suppose it could still tokenize. but checking a map for dup keys? what a waste of CPU
12:36amalloyjweiss_ if it tokenizes, it has to call (read)
12:36amalloyand that has to complain about duplicate keys
12:36amalloythat's why i wanted #|
12:36jweiss_amalloy: not if the reader behavior were changed, right?
12:37jweiss_i like the (comment ) format just fine, i just don't want to have to go that far to make sure it's 'working' code
12:37yazirianfliebel: i suppose that could exist internally to the postgres jdbc driver, but i'm just taking the rows i'm given and jamming them straight in
12:39amalloyjweiss_: (comment) is just a macro
12:39amalloy$source comment
12:39sexpbotcomment is http://is.gd/xjRdPI
12:39amalloyno way the reader behavior for it will ever change
12:39amalloyafk a bit while you mull that over
12:40jweiss_ah didn't realize it was implemented that way
13:38fliebelWhy can;t I do this? ##(let [s java.lang.String] (new s))
13:38sexpbotjava.lang.IllegalArgumentException: Unable to resolve classname: s
13:39amalloyfliebel: if it were allowed with that syntax, all (new) operations would be slow
13:39amalloy,(let [s String] (.newInstance s))
13:39clojurebot""
13:40Rayneshttp://stackoverflow.com/questions/3748559/clojure-creating-new-instance-from-string-class-name
13:40fliebelamalloy: Can I do .newInstance to any class? Is there a Clojure way to do it to deftypes and defrecords?
13:41Raynesfliebel: Read the accepted answer.
13:41fliebelreading...
13:46scottjimplementation of macro I asked about earlier, would be curious if anyone knows of a better way to implement ->f http://jaderholm.com/paste/thread-function.html
13:49amalloyscottj: i'm inclined to write it as a reduce
13:56no_mindEnlive by default looks for a template in src directory. is it possible to change this ?
13:57amalloyscottj: https://gist.github.com/d5f584322d133395bcf9 is a first draft. the way i'm splitting out the first arg is pretty gross; i'm pretty sure it could be improved
14:00sritchiehey all -- I'm trying to figure out how to write a macro that defines a function, but adds a new gensymmed variable at the beginning of the supplied arg vector
14:00sritchieone sec, I'll post a gist --
14:00raekno_mind: it looks for it in the classpath. thus you can also put the templates in resources/ (which leingingen puts on the classpath (but you might need to restart the clojure instance if it did not exist when you started it)
14:01amalloysritchie: gensymmed? then the user would have no choice but to ignore the arg. is that your intent?
14:01sritchieamalloy: yeah
14:01sritchiethere's a pattern in pallet where a "request" variable is always threaded through the body
14:02sritchieso, lots of functions have the pattern of (defn config-files [request arg1 arg2] (let .... (-> request (func1 args... )))
14:02sritchieetc
14:02raekno_mind: it might be possible to pass it a File object (representing a file path), but I haven't tried it
14:02amalloy(defmacro with-ignore [name args & body] `(defn ~name ~(vec (cons (gensym) args)) ~@body))
14:02no_mindk testing
14:02amalloysprinkle in some docstrings if you like
14:03sritchieamalloy: awesome! I do need to retain a reference to the gensym, though --
14:04sritchieso the last part can be (fn [request#] (-> request# ~@body))
14:08maaclIs there any reason why this https://gist.github.com/894901 should fail using Clojure 1.2.0? (it is an example from page 186 in Practical Clojure).
14:13hiredmanmaacl: yes, it is wrong
14:13hiredmanI suggest you complain to the authors
14:14dpritchettsubmit errata here http://apress.com/book/errata/1312#correx
14:18CozeyWhen i use reify, do I have to tag first argument with ^Type ?
14:19Cozeyor will clojure figure this out automagically
14:23dnolenCozey: I believe you don't have to typehint w/ reify as long as your extending to a protocol, not an interface.
14:23Cozeyi'm extending an interface
14:24dnolenCozey: then you need a type hint yes to avoid reflection when calling that method.
14:24Cozeyok, thanks!
14:25dnolenfliebel: ping
14:26fliebeldnolen: pong
14:26dnolenfliebel: sorry missed you message from earlier. clj-cont -> delimc. It's only tangentially related at this point to logos, but maybe applicable.
14:28fliebeldnolen: Would it be possible to implement that Scheme thing in Clojure with delimc?
14:29dnolenfliebel: the amb operator? Dunno. The amb operator might turn out to be useful or maybe not.
14:31fliebeldnolen: It seem in itself a very nice tool for constraint finite domain stuff. (+ 4 (apply amb (range 9)))
14:35dnolenfliebel: could be could be. I never looked any more closely at amb then the stuff in SICP and The Art of the Propagator.
14:36dnolenfliebel: I got interested in delimc again because of Dybvig's paper on Subcontinuations, seems related somehow to fork/join to me.
14:37fliebelOr even (assert (+ 4 (apply amb (range 9))) 12)
14:37jolyI really enjoyed using amb on some Project Euler solutions back when I was messing with PLT Scheme. I've missed having it in Clojure
14:38fliebelOnce I understand how contionuations work (in delimc), I might try to make that work :)
14:39TimMcamb?
14:39clojurebotamb is http://paste.lisp.org/display/73311
14:40amalloyTimMc: looks fine to me!
14:40fliebelTimMc: Some magic continuations thing in scheme that lets you use a few values and let it figure out which one work.
14:40jolyIt's a function that makes an "amb"iguous choice among its arguments that magically ends up being a non-failing choice
14:41fliebelamalloy: That macro does not work across multiple amb statements.
14:41jolyOften implemented behind the scenes with continuations and/or backtracking
14:41fliebelor… does it?
14:41amalloyfliebel: hell if i know. i'd never heard of amb until now. but it looks like a relevant link
14:41fliebeljoly: often? How else?
14:42amalloyfliebel: scheme interpreters might just be good guessers
14:42sritchieamalloy: hey, sorry to disappear -- one last quick question -- is there a quick way to tweak this to work? https://gist.github.com/894884
14:42jolynon-deterministic computers, still to be build ;)
14:42dnolenfliebel: thats's definitely an advantage of delimc, you can jump to different points. It's not magic, it just applies CPS to your code by walking it.
14:42sritchieso that request# is cons-ed into the args vector, but can still be accessed in the body
14:42jolybuilt*
14:42amalloysritchie: yes, by not using the auto-gensym feature
14:43fliebeldnolen: Can I macroexpand it? I'm curious how that looks.
14:43amalloy(let [req (gensym "request")] `(defn ... ~(vec (cons req args)) (-> ~req ~@body)))
14:44fliebeldnolen: one big advantage of amb over miniKanren is that you can use regular Clojure functions.
14:44sritchieamalloy: awesome,thanks!
14:45dnolenfliebel: that is an advantage, but it's also a big disadvantage as well.
14:45fliebeltrue
14:45jolyI don't think you can do cuts or similar with amb
14:46dnolenfliebel: if you write a amb operator using delimc, it would be interesting to compare performance.
14:46dnolenfliebel: delimc generates a crazy amount of functions, much crazier than the miniKanren macros.
14:46fliebel:(
14:47dnolenfliebel: but for simple operations, might have better perf. If so, it would be cool to switch to amb in miniKanren if we know a var is ground.
14:48dnolennot sure if that would work at all, but something to think about ...
14:48fliebeldnolen: I think it'd be faster to just do something recursive with a few atoms ruling out wrong answers.
14:50dnolenfliebel: that's basically what I think. My idea is to build a constraint propagator using fork/join, when the state stop changing switch to miniKanren/amb to search. propagate more constraints on each choice, etc. Just like Norvig's Sudoku solver but generalized.
14:51fliebelsounds good
15:11pdk(doc fork)
15:11clojurebotHuh?
15:11pdk(doc join)
15:11clojurebotexcusez-moi
15:11pdkwhere are these magical pieces
15:12dnolenpdk: you need OpenJDK 7
15:46wwmorganis there a library or contrib function that will tell me whether one map is a "submap" of the other, i.e. (= map-a (dissoc map-b k1 k2 k3 ...)) for some set of keys?
15:48amalloywwmorgan: maybe clojure.set has it? it sounds a lot like intersect/subset
15:49raekhrm, but for maps...
15:50amalloy&(let [map-a {:a 1} map-b {:a 1 :b 2}] (clojure.set/subset? (keys map-a) (keys map-b))
15:50sexpbotjava.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IFn
15:50amalloyhuh, keys doesn't return a set. i guess that makes sense but it makes me sad
15:50raek(defn map-subset? [container containee] (= container (merge container containee)))
15:51amalloy&(let [map-a {:a 1} map-b {:a 1 :b 2}] (clojure.set/subset? map-a map-b))
15:51sexpbot⟹ false
15:51fliebel$findfn even? [1 3 5 4 7] 4
15:51sexpbot[]
15:51amalloyfliebel: join the club. we all want this function :P
15:52fliebelamalloy: I suppose it;s in your utils?
15:52amalloychouser called it ffilter by analogy with ffirst
15:52amalloyit's not, actually. good point
15:52fliebel(comp first filter)
15:53amalloyyes
15:54wwmorganraek: beautiful. thanks
15:55fliebellol, now I have a piece of code that looks like ((comp blah foo) (comp bar baz) (comp bee boo) (comp first range) ... )
15:55fliebeloh, I fogot the juxt...
15:55amalloyfliebel: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils.clj#L27 - it's there now
15:57fliebelamalloy: How do you use that stuff, you just add it as a dependency?
15:57amalloyyeah
15:57amalloyi'll push an update to clojars now if you want to use ffilter
15:58fliebelamalloy: That's a lot of code in a lot of projects for a lto of small wins.
15:58amalloyfliebel: that's a lot of words for something i don't quite understand :)
15:59fliebelamalloy: Okay, point taken *goes to bed* ohnoe, I need to finish this!
16:00fliebelI meant to say that you add a lot of code to your projects you probably don't use.
16:00amalloyi couldn't tell if you were complaining that including amalloy-utils would be adding a lot of code for little benefit, or saying "hey cool i can get a lot of small wins for not much code"
16:00amalloyfliebel: *shrug* code is cheap. clojure.core contains a lot more code i never use than amalloy-utils does
16:00fliebela bit of both...
16:00amalloycontrib, even more so
16:01fliebelamalloy: it has been modularized, hanslt it?
16:01amalloyhm. my project.clj asks for clojure 1.2.1 at the moment. probably not very friendly as a library dependency
16:01fliebelamalloy: version ranges to the resqueue
16:02amalloyindeed
16:02amalloyi had it written that way before, but was fiddling with it while i tried out the cdt
16:03fliebelamalloy: You know… I have a mental barrier for using your utils because they are called *amalloy*-utils
16:04fliebelMyabe I should just fork, name it pepijn-utils and start using it...
16:04amalloyfliebel: nothing to do with my name. it's an acronym, a definition for which i am likely to invent shortly in order to convince you to use them
16:04fliebelhaha, I'll keep you to it :)
16:04amalloyalternative macro and lazy libraries of yours
16:04fliebel(wait, can I say that or is that denglish)
16:05amalloyfliebel: i think we'd say "hold you to it", but it's a trivial distinction
16:06fliebelalternative macro and lazy libraries of your utils?
16:06amalloyperhaps yuseful utils. i was never good at spelling
16:07amalloyfliebel: ninjudd has clojure-useful; i'm sure ffirst is in there under some name or other, and he didn't name it after himself
16:07fliebelamalloy: key presses are cheaper than googling for ffirst.
16:14joshua__What is this amazing marvelous awesome liberating library of yours? ')
16:14joshua__;)
16:16CozeyHey, This is not so much clojure-centric question, but there are a lot of design freaks here, so i'll ask: in a web application environment, what should be a better approach: to implement a daemon process (doing some background job) as a thread inside the main webapp, or as another webapp (separate WAR)? There is no state shared between them; they communicate via a message queue
16:19dnolen,(let [a (atom 5)] (take @a (range 9)))
16:19clojurebot(0 1 2 3 4)
16:20amalloyjoshua__: it's not that awesome. i just suggest that everyone put together their own utils library for use in multiple projects so they don't keep rewriting the same generic functions
16:20amalloymine happens to be at https://github.com/amalloy/amalloy-utils
16:21joshua__amalloy, I actually just read through it.. maybe you didn't notice but the amazing awesome etc was your name expanded ;p
16:24amalloyhahaha
16:24amalloyhow did i miss that
16:24amalloyit clearly sounded too natural
16:36Netfeedp/win 9
16:38CozeyWhat's better? (concat (list (foo ..)) (map ... )) or (cons (foo ...) (map ....)) ?
16:39amalloyCozey: cons seems way better
16:39amalloyconcat often signals a mistake anyway
16:40Cozeyand how does cons handle various types of second parameter? it can be a vector, list, whatever. does cons convert it? or does it just keep CAR and CDR pointers as in 70ties? does it matter?
16:40Cozeysignals?
16:40brehaut&((juxt identity type) (cons 1 [2]))
16:40sexpbot⟹ [(1 2) clojure.lang.Cons]
16:41amalloyCozey: cons probably just implements an ISeq whose first is (the first thing) and rest is (the other thing)
16:41amalloyso not exactly the same as car/cdr - clojure doesn't have those - but very similar
16:42Cozeyright, this seems obvious
16:42Cozeybut perhaps if i'd cons a lot, i would get a 'loose' structure compared to a vector
16:42amalloyCozey: loose?
16:42Cozeywhich would be worse performance wise, right?
16:43Cozeyloose, like a linked list
16:43brehautCozey: giant bag of 'it depends'
16:43Cozey:-D
16:43amalloyCozey: *shrug* depends what you want to do. if you want to iterate through it, a cons chain is fine
16:43Cozeyok
16:44amalloyCozey: for example, ##(drop 2 (range 10)) is a lazy sequence with cons cells underneath
16:44sexpbot⟹ (2 3 4 5 6 7 8 9)
16:46Cozeylike most lazy-seq's - so nothing to be afraid here
16:46Cozeythanks
16:48dnolenamalloy: is that true? Cons is a specific data structure. LazySeqs are something quite different I thought.
16:49Cozeyas i've seen in bvarious sources, lazy-seq's are usually implemented as (cons currently-computed (lazy-seq (recurent-call ... ))
16:51dnolen,(concat [1 2 3] [4 5 6])
16:51clojurebot(1 2 3 4 5 6)
16:51dnolenCozey: ^ is common
16:52Cozeyin lazy-seq? is concat lazy?
16:52Cozeyyes.
16:52Cozeyit is.
16:53brehautif concat is lazy (and a quick 'type' agrees), how does it differ from lazy-cat ?
16:54dnolenrange actually used ChunkedCons underneath, not sure if the features of Cons apply to them (hopefully someone else will chime in)
16:54amalloybrehaut: it isn't. lazy-cat is old and should be consigned to the rubbish bin as far as i know
16:54amalloylazy-cat was for before we had lazy-seq
16:55amalloydnolen: right, range is a bad example
16:55dnolenamalloy: not true, lazy-cat is macro, so you don't thunk up concats when you have a lot of sequences.
16:55amalloy$source lazy-cat
16:55sexpbotlazy-cat is http://is.gd/76pvOk
16:56amalloydnolen: (lazy-cat (lazy-cat ...)) looks like it would have the same problems, since it expands to a call to concat
16:58dnolenamalloy: yeah, I'm wrong, the purpose of lazy-cat is to lazily process the arguments.
16:59amalloyright. there aren't really that many uses for lazy-cat, as far as i've seen
17:09duncanmi think it's is a really cute post: http://funcall.blogspot.com/2011/03/tail-recursion-and-debugging.html
17:09amalloy&(seq (lazy-seq nil))
17:09sexpbot⟹ nil
17:09duncanmhey amalloy, Raynes
17:09amalloy&(seq (lazy-seq (lazy-seq nil)))
17:09sexpbot⟹ nil
17:10Raynesduncanm: Hey.
17:11sorenmacbethcould someone help me with an idomatic clojure solution to the following problem?
17:11duncanmRaynes: i read the Scala Swing design document again, they have decided to merge the containers and layout mgr distinction in Swing
17:12duncanmRaynes: so they have things like BoxPanel and FlowPanel, which are JPanels with the appropriate LayoutManager
17:12duncanmRaynes: i wonder if that's similar to the approach 'shoes' took
17:12Raynesduncanm: No clue.
17:12duncanmmaybe Monkeybars from JRuby is also interesting to look at
17:13duncanmhttp://en.wikibooks.org/wiki/Ruby_Programming/GUI_Toolkit_Modules#Swing_wrappers
17:13duncanmsorenmacbeth: what's the prob?
17:13sorenmacbethgiven a sequence of words like ("a" "b" "c"), i'd like something like [["a" "b"] ["a" "c"] ["b" "a"] ["b" "c"] ["c" "a"] ["c" "b"]]
17:14sorenmacbetheach item paired up with every other item expect itself
17:14amalloyyou want...all permutations of length two?
17:15brehautclojure.contrib.combinatorics/permutations ?
17:15Raynes&(clojure.contrib.combinatorics/permutations ["a" "b" "c"])
17:15sexpbotjava.lang.ClassNotFoundException: clojure.contrib.combinatorics
17:15RaynesThanks, sexpbot.
17:15RaynesAnyways, that's a start.
17:15brehautRaynes: you need a n
17:15duncanmooh ooh ooh
17:15amalloypermutations doesn't take an n
17:15amalloyas written
17:15duncanm&(clojure.contrib.combinatorics/permutations 2 ["a" "b" "c"])
17:15sexpbotjava.lang.ClassNotFoundException: clojure.contrib.combinatorics
17:15duncanmboo
17:15brehautoh right, im tihnking of combinations
17:16Raynesbrehaut: No I don't.
17:16RaynesYou need an N. Keep your Ns to yourself.
17:16Raynes;)
17:16brehautRaynes: aha
17:18duncanm(remove (fn [[x y]] (= x y)) (selections [ "a" "b" "c" ] 2))
17:18duncanm(("a" "b") ("a" "c") ("b" "a") ("b" "c") ("c" "a") ("c" "b"))
17:21brehautor as a simple comprehension: ##(let [s #{"a" "b" "c"}] (for [a s b (disj s a)] [a b]))
17:21sexpbot⟹ (["a" "b"] ["a" "c"] ["b" "a"] ["b" "c"] ["c" "a"] ["c" "b"])
17:22amalloynice, brehaut
17:24duncanmhmm
17:24sorenmacbethduncanm: thanks!
17:24duncanmi can't think of a way to write (fn [[x y]] (= x y)) in terms of partial and every?
17:25brehautamalloy: i can write tidy code sometimes!
17:25amalloyduncanm: (partial apply =)
17:25sorenmacbethbrehaut: awesome!
17:25duncanmahh
17:26duncanm(remove (partial apply =) (selections [ "a" "b" "c" ] 2)) ;; even better
17:26duncanmamalloy: my first attempt was (partial every? =)
17:26amalloy&(doc distinct?)
17:26sexpbot⟹ "([x] [x y] [x y & more]); Returns true if no two of the arguments are ="
17:26amalloyyou could also use (filter distinct?)
17:27amalloybut i guess that wants varargs
17:27duncanmamalloy: i think it's funny that i see people define (defn sum [xs] (reduce + 0 xs)) quite often
17:27sritchiedoes anyone have a good example of clojure.contrib.dev/name-with-attributes?
17:28duncanmamalloy: when (apply + xs) would suffice
17:28sritchieI'm writing a "defphase" macro that should accept an optional docstring
17:28amalloyduncanm: so would (reduce + xs)
17:28duncanmamalloy: in this case, i prefer apply over reduce
17:28amalloyso do i
17:28duncanmbut that's because + is varidisic (sp?)
17:29amalloyit's an easy example for when you're still getting the hang of higher-order functions and still want every function you call to be globally defined
17:29amalloyvariadic
17:29duncanmbooo
17:29duncanmvariadic
17:29duncanmarity, variable-arity, variadic
17:32devnariable-varity
17:33duncanmi guess there's an impulse to write a variadic function when the func is associative and commutative
17:33duncanmor you use reduce ;-P
17:34duncanmi look at IFn last night, it's funny that there are variants of apply up to 20 arguments
17:34duncanmand no more
17:34duncanmi wonder what made Rich go to 20, and stop at 20
17:34sritchiehere's what I could come up with for that macro example -- https://gist.github.com/895353
17:34duncanmif it were me, i think i might stop at like, 6?
17:35duncanmoverloads of apply
18:46duncanmpdlogan: i'm looking at your nconc repo, and i can't find any js files
18:46duncanmoh
18:47duncanmit's in a different dir
18:47pdloganyeah - they're under public.
18:47pdloganin fact shell scripts are there too. sigh. it was easy.
18:47duncanmpdlogan: it's cool talking to you, i've been a subscriber to your blog for quite a few years
18:48pdloganoh - thanks. I've recently weened myself off twitter and back to the blog.
18:48duncanmpdlogan: i really liked the esh scheme and fidget-with-widget links that you bring up once in a while
18:48duncanmthose were cool projects
18:49duncanmpdlogan: and i liked the smalltalk mentions too
18:49pdloganyeah, "don't fidget with widgets, draw!" is one of my favorites.
18:49duncanmi dabbled in Squeak for a while
18:49scottjsritchie_: is the example in that gist really 3 or is it 2?
18:49duncanmpdlogan: it's like AJAX before the web ;-P
18:50pdloganif I get around to it, I have 1/2 a mind to do a "don't fidget" using ncon and xmpp and html5 canvas.
18:50duncanmpdlogan: unified in one lang/system, instead of html/css/js
18:50duncanmhmm
18:50duncanmpdlogan: i've been playing with xmpp, it's pretty easy to get started with smack
18:51pdloganso any app back in any data center can interact with a drawing in any browser
18:52duncanmpdlogan: whenever i think about using html canvas, i think to Lively Kernel and see how sluggish it could be, then that reminds me of how much snappier Squeak is, and then a i weep a little inside ;-P
18:52pdloganyeah I've been using strophe in js which is pretty good. and a while back one in C whose name escapes me.
18:52pdloganyeah, lively is getting faster all the time though.
18:52duncanmpdlogan: smack + clojure is easy
18:53duncanmis it even being maintained/developed nowadays?
18:53pdkyo don't be talkin smack man
18:53pdkrespeck
18:53duncanmbooyakasha
18:53pdloganI'll have to try it, although I'm less interested in java/jvm based languages than I was a few months ago.
18:53pdlogansmack? I think it has languished for the last year or two.
18:54duncanmpdlogan: they had a new release 2 weeks ago
18:54duncanmpdlogan: i think you'll like this: http://funcall.blogspot.com/2011/03/tail-recursion-and-debugging.html
18:54pdloganoh really? hrm - but dangit I gave up the jvm for lent.
18:55duncanmSmack 3.2.0 Beta has been released on February 3, 2011.
18:55duncanmand i updated my openfire server recently, the last release was 4 weeks ago
18:55duncanmso i'm a little off
18:56pdloganduncanm: oh were you refering to lively being maintained? the email list is not super active and that's all I've been tracking - so dunno.
18:56duncanmyeah, i was referring to lively
18:56duncanmoh oh
18:57duncanmmiscommunication
18:57duncanmeither way, the tail-call post is really funny
18:57technomancyduncanm: that's hilarious
18:57pdloganduncanm: tail recursion and debugging - ho hum? my response would be turn it off to debug or debug some other way.
18:58duncanmpdlogan: oh... i'd keep it on, just so that i *can* debug ;-) you really should load up the page
19:00pdlogan"my understanding that the Java creators specifically chose not to implement this, as it makes resultant code hard to debug (if not impossible)."
19:00duncanmpdlogan: wow, you almost didn't post at all during 2010... wow
19:01pdlogan^my understanding is most language creators eave it out because 9 times out of 10 someone will be doing an assignment with the result to a variable.
19:02hiredmanhttp://projectfortress.sun.com/Projects/Community/blog/ObjectOrientedTailRecursion
19:03brehautfrom memory C#3+ does tail call optimisation on 'release' builds by default
19:03Caffeinehiredman: Cool, I'll certainly read this when I get 2 sec.
19:03duncanmi have worked on Scheme code where there are multiple nested named-lets, and the recursion happens without scoping - that code really was hard to understand
19:03hiredmanthe jvm guys made a mistake not including it in their otherwise very nice vm
19:03technomancymy understanding is John Rose wants to implement tail calls, but his bosses want him to work on other things.
19:04duncanmhiredman: the typography used by Fortress always turns me off a little
19:04duncanmit's a cute idea, but my eyes never seem to be able to focus on the code-proper
19:04brehautduncanm: click the 'show ascii' buttons then :P
19:04hiredmanλ λ hey!
19:04duncanmbrehaut: that's what i'm doing
19:05duncanmhiredman: i'm okay with that one, but clojure has shown that 'fn' is a decent substitute for 'lambda'
19:06duncanmi need to read that William Cook paper again, i read it a few months ago, and i thought i understood it
19:06duncanmand now it's been completely erased from my mind, i don't remember a single thing ;-P
19:14Caffeineduncanm: The math/code parts are messed up in an interesting way, I have to agree with you on that. >.< ... Fixing the font size would be great.. Oh no, wait, it wouldn't be great, it's a necessity.
19:17duncanmCaffeine: right
19:42TimMcMy kingdom for a ulong type.
20:02TimMcI'm writing a partial instruction set simulator for MIPS-32, and dealing with unsigned 4-byte memory addresses is annoying.
20:03brehautTimMc: any reason you cant just do the normal JVM cludge there and just use a 64 bit signed int and pretend 31 of the bits dont exist?
20:04TimMc64 bit int?
20:04brehautits probably a long?
20:05amalloyyes, longs are 8 bytes
20:06TimMcOh! Dammit, so confused.
20:06amalloyfinding an unsigned eight-byte type is hard in java, but unsigned four-byte types are easy
20:06amalloy(you use a signed eight-byte type instead)
20:06TimMcSo, longs take up two registers on a 32-bit machine?
20:06amalloyTimMc: java is unconcerned with registers
20:06amalloybut a long is guaranteed to be 64 bits
20:07TimMcI know, I'm just thinking about ISAs.
20:07TimMc...since I'm trying to simulate a processor.
20:08amalloyso? your program wants unsigned 4-byte ints for some reason that isn't really important
20:08amalloyan 8-byte signed int will stand in for that; just do a modulo operation before you write it back
20:10TimMcYeah, I think I've had the idea in my head for a long time that a Java long fits in one 32-bit register.
20:10TimMc...which obviously isn't the case, now that I look at it.
20:10amalloyindeed
20:10TimMcThanks for setting me straight. :-)
20:14TimMcI'll have to redo my ALU now.
20:14amalloybecause you were assuming overflow or something?
20:14TimMcnumeric tower + bitwise operations is tricky
20:15amalloyTimMc: can you just store as ints, do most of the operations in int-space, and only come out to longs when you have to do something sign-related, like a less-than?
20:15TimMc,(long (inc Long/MAX_VALUE))
20:15clojurebotjava.lang.ArithmeticException: integer overflow
20:16TimMc,(long (+ Long/MAX_VALUE 1))
20:16clojurebot-9223372036854775808
20:16TimMcamalloy: Yes, but that means storing more than just a function in my ALU op map.
20:17amalloyTimMc: not necessarily. i agree it's probably best, but functions can do anything :P
20:17TimMcIn that case, the functions will need to do their own checks and casts, or be passed to HOFs in the map.
20:40carllerchecan anonymous functions return references to themselves?
20:40amalloycarllerche: yes!
20:40carllercheis there a keyword for that? not sure how one would do it
20:40amalloy(fn myfn [] (comp foo myfn))
20:40carllercheah... i guess you just need to name them then
20:41amalloycarllerche: it's semi-anonymous
20:41carllerchethat's fine
20:41carllerchethanks
20:41amalloywelcome
20:43Deranderhaha
20:43Derandersemi-anonymous
20:43Derandersorry, that tickles me
20:44amalloyDerander: it's better than "named anonymous"
20:44DeranderI know :-)
20:44Deranderthat also occurred to me and made me giggle
20:46amalloyi see people writing (letfn [(foo [args] (... (foo something)))] (foo base-args)) and i'm like "noooo, just write ((fn foo [args] (... (foo something))) base-args)"
21:01seancorfieldamalloy: in reference to letfn vs named anonymous functions, are there times when letfn is the right choice?
21:01amalloyseancorfield: yes
21:02amalloybut not, imo, when all you do is call it once
21:02amalloyletfn allows for mutually-recursive functions (all the names are bound before any of the functions are compiled), and it allows you to refer to the function from the letfn body. if you need neither of those, don't bother
21:03seancorfield'k
21:05amalloy&(letfn [(odd? [x] (and (not (zero? x)) (not (even? (dec x))))), (even? [x] (or (zero? x) (not (odd? (dec x)))))] (map even? (range 10)))
21:05sexpbot⟹ (true true true true true true true true true true)
21:05amalloybah
21:05amalloyanyway you get the idea
21:05amalloyi had too many not's in there, i think
21:06TimMcShouldn't have nots on the decs.
21:06amalloy&(letfn [(odd? [x] (and (not (zero? x)) (even? (dec x)))), (even? [x] (or (zero? x) (odd? (dec x))))] (map even? (range 10)))
21:06sexpbot⟹ (true false true false true false true false true false)
21:06amalloyyeah
21:07pdk`if you think about it
21:07pdk`))))) is much more common in code than (((
21:09TimMc$findfn + "_PLUS_"
21:09sexpbot[]
21:09TimMc$findfn + "clojure.core$_PLUS_"
21:09sexpbot[]
21:09amalloyTimMc: two _s, i think
21:09amalloypdk`: much, yes
21:11TimMcamalloy: That's not what my REPL shows.
21:11amalloy&(class +)
21:11sexpbot⟹ clojure.core$_PLUS_
21:11amalloyokay, you're right
21:11TimMchah
21:11TimMc,(:name (meta +))
21:11clojurebot+
21:12amalloy&(+ 1 2)
21:12sexpbot⟹ 3
21:12amalloywonder why findfn isn't trying class
21:12amalloyoh duh
21:13amalloyclass returns a class, not a string:
21:13amalloy$findfn + clojure.core$_PLUS_
21:13sexpbot[clojure.core/class clojure.core/type]
21:13TimMcAh!
21:13dnolenbut then again I've been doing a lot of Scheme.
21:16cgrayhi, anyone else here doing compojure on google app engine? I'm having real trouble with latency when a new instance starts...
21:18brehautcgray: it seems unlikely that compojure would be the cause of your problems
21:20cgraybrehaut: no, I realize that. I assume that I'm loading too many classes at startup...
21:21cgraybut I'm not sure how to avoid that
21:22amalloybrehaut: he's got to have at least *one* problem caused by compojure. i don't think i've ever used a software package that didn't come with a problem
21:23brehautamalloy: no doubt, but it seems highly unlikely that compojure (a couple of hundred lines of fairly straight forward clojure) would cause startup time issues
21:24cgraybrehaut: of course it's not *just* compojure, it's also hiccup, sandbar, ring, clj-oauth, and all of their dependencies
21:24scottjcgray: what kind of latency are you talking about, 3 seconds?
21:24cgrayscottj: more like on the order of 10 seconds
21:25cgrayscottj: the last one was 25 seconds...
21:26brehautcgray: if i were to stab wildly in the dark, i would guess that clojure.core would be a bigger overhead than all the rest of your app in terms of class loading
21:27cgraybrehaut: so i'm screwed?
21:27brehautcgray: rough count has 1700 classes in clojure-1.2.0.jar
21:27scottjare you using appengine-magic? I don't know if it does any optimizing
21:27brehautcgray: i dont know much at all about tuning GAE or appengine-magic sorry
21:27cgrayscottj: yes
21:28cgrayscottj: but only one feature of it
21:28scottjcgray: you could deploy a bare bones and then add in features to see what effect they ahve
21:29scottjmaybe you can do that locally even
21:29cgraythat's a good idea
21:29cgraynow that i have it basically written
21:29brehautscottj: i believe that the local dev enviroment for GAE just starts a jetty
21:30brehautcgray: have you considered asking on the ring list?
21:30cgraybrehaut: no, i'm not on any of the lists... it's a good idea though
21:32cgrayanyway, thanks for the help, it's supper time for me :)
21:32brehautcgray: good luck
21:34TimMc,(long (+ Long/MAX_VALUE 1))
21:34clojurebot-9223372036854775808
21:34TimMc,(int (+ Integer/MAX_VALUE 1))
21:34clojurebotjava.lang.IllegalArgumentException: Value out of range for int: 2147483648
21:34TimMcSo casting to long truncates, and casting to int throws.
21:35TimMc...and (inc SomeNumeric/MAX_VALUE) always gives overflow, I think.
21:42Caffeineyou can always recover with something like (inc (BigInteger/valueOf Integer/MAX_VALUE)) .. I think... dunno if that can help you
21:44TimMcYeah, there are a bunch of tricks... it's just confusing.
21:55mecwhats the best way to take a random number of items from a collection without getting duplicates?
21:55devndistinct + take rand-int
21:57devn,(take (rand-int 10) (distinct [1 1 22 2 2 3 4 4 4 55 5 5 6 6 6 6 6 6 7 7 7 7 8 8 8 9]))
21:57clojurebot(1)
21:57devn,(take (rand-int 10) (distinct [1 1 22 2 2 3 4 4 4 55 5 5 6 6 6 6 6 6 7 7 7 7 8 8 8 9]))
21:57clojurebot(1 22 2 3 4 55 5 6 7)
21:58tomojwtf, how have I never learned distinct?
21:58devntomoj: clearly you're a failure
21:58devn;)
21:59amalloythat is *not* an efficient way to do it for large N. fliebel and i did a little "study" on this a while ago
21:59mec,(take 10 (distinct (repeatedly #(rand-nth (range 100)))))
21:59clojurebot(98 73 39 34 66 52 18 4 0 95)
21:59devnthere's another way
21:59devnanyway, you want uniques => distinct
21:59devnyou want random? rand-*
22:00devnplenty of ways to do that
22:00amalloyhttp://stackoverflow.com/questions/3944556/what-if-anything-is-wrong-with-this-shuffling-algorithm-and-how-can-i-know/5238130#5238130
22:00devnheh, "how can i know"
22:00devnwithout reading the article: "measure it."
22:02devn,(int (rand 100))
22:02clojurebot82
22:02devnanother way you could do it
22:03devnyou could generate a random sort-by function , etc. etc. etc.
22:03amalloydevn: that's actually not uniformly random. i read an interesting article about how sort-by rand is skewed
22:04seancorfield,(doc distinct)
22:04clojurebot"([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"
22:04amalloybecause the sorting algorithms assume (compare a b) will never change, and will always be the opposite of (compare b a). not sure where the article is though
22:06TimMcIn fact, your sort might not terminate.
22:09tomojwith 0 probability?
22:09devnseancorfield: hola
22:09devnseancorfield: i emailed you back btw
22:10devnamalloy: that being the case, his question was very general and i think there are many solutions to give him a random of his choosing
22:10devnsometimes less random is a good random
22:12amalloydevn: you're right; you answered the question he actually asked. the question he asked is so unusual that i thought he'd asked a much more common question (indeed, still think that's what he intended)
22:12amalloy"take a random number of elements" vs "take a number of random elements"
22:13seancorfielddevn: yup, i replied with my skype / aim / gtalk handles
22:13mecamalloy: how do those 2 not mean the same
22:14amalloyum. the first is "get me the first ten, fifteen, or one hundred elements in the collection" and the second is "i want ten items at random from the collection"
22:14mecoh lol
22:15mecwell now that my brain is working i meant "take a number of random elements"
22:17amalloynaturally. see my SO link for some interesting different answers
22:18seancorfieldso which of the following do folks prefer (and why)?
22:18seancorfield(take 10 (repeatedly #(rand-int 10)))
22:18seancorfield(take 10 (map rand-int (repeat 10)))
22:18seancorfield,(take 10 (map rand-int (repeat 10)))
22:18clojurebot(5 3 6 1 0 8 6 4 5 4)
22:19seancorfield,(take 10 (repeatedly #(rand-int 10)))
22:19clojurebot(9 4 0 8 8 1 5 7 7 9)
22:19seancorfield(and are there cleaner / more idiomatic ways to do that?)
22:19amalloywell, now that you've said them twice in different orders i can't say "the first one" anymore :). i like repeatedly
22:20brehauti think repeatedly is clearer
22:20mecrepeatedly says more to what you're doing in that case
22:20seancorfieldheh, you should have seen my early attempts _before_ i went digging around in the docs :)
22:21amalloyseancorfield: the second version could be improved to (map rand-int (repeat 10 10))
22:21amalloybut it's still grosser
22:22seancorfieldgrosser... more gross... :) thanx for the input... when i find so many ways to do stuff i often wonder what's more idiomatic
22:22mecmost grossest
22:23seancorfieldand i'll have to teach / justify this stuff to my team mates soon, once they have to start using clojure (or at least reading my clojure code!)
22:23amalloyThere's More Than One Way To Do It (but only one of them is right!)
22:45seancorfieldany gems of advice for introducing clojure to a team of programmers that don't know any functional programming stuff (and don't really know OOP all that deeply either)
22:47brehautseancorfield: start simple and write a simple 'real' program as soon as possible?
22:48trptcolin_<shamelessplug>clojure koans are fun :)</shamelessplug>
22:48trptcolin_though they're certainly not real :)
22:48brehauttrptcolin_: i think that would be a great second step
22:51trptcolin_seancorfield: are they doing much concurrent stuff? obviously that's a killer feature to pull them in
22:52brehautseancorfield: another killer feature could be a simple json web service with ring and your choice of moustache or compojure and either an in memory data store or say clojureql
22:52seancorfieldtrptcolin_: only insofar as web applications involve concurrency :) (and thread safety issues due to shared mutable state - one of the problems i'm trying to remove)
22:53seancorfieldbrehaut: we have a massive web application - we'll be replacing lower layers with clojure (to create code we can easily reuse from other places)
22:54seancorfieldthe high-level part of the app is good... great templating, nice convention-based MVC framework in place... just looking to swap out parts of the model
22:55trptcolin_one of my teammates was the most psyched about breaking down OO concepts into their fundamental benefits like stuart halloway talks about here: http://thinkrelevance.com/blog/2009/08/12/rifle-oriented-programming-with-clojure-2.html
22:55seancorfieldultimately, i want all of the model to migrate to clojure
22:57amalloyseancorfield: did you watch the conj talk/video about simplicity?
22:59seancorfieldamalloy: yeah, pretty sure i have watched that... let me just double-check
22:59amalloyit wanders around for a while trying to find a topic, but it does include some talk about a la carte OO features
23:00mecIs there some better way to write this, it seems overly wordy: (let [a (foo)] (if bar? (shmoo a) a))
23:01scottj((if bar? shmoo identity) (foo))
23:01trptcolin_hawt
23:01amalloyscottj: good luck with that
23:01amalloybar? will always be true because it's a function: you're not calling it
23:01scottjwho's to say bar? isn't a var?
23:02trptcolin_well, is it? (def bar? true)
23:02amalloyoh sorry
23:02amalloyi misread the question
23:02seancorfieldamalloy: yeah, now i've started watching stu's video, i remember it :)
23:02trptcolin_probably an "unconvential" naming tho :)
23:03amalloymec: trptcolin_'s answer is good assuming bar is a local. if you want to test (bar? (foo)) at some point, you might like https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils/transform.clj#L4
23:04trptcolin_scottj gets the credit there
23:04amalloyer, dang it, it's scottj's
23:04trptcolin_amalloy: that's pretty smooth
23:04trptcolin_(the link)
23:04trptcolin_i love fns that take multiple fns as args
23:05amalloytrptcolin_: thanks. i find myself using (postwalk (transform-if seq? vec) some-coll) often for macros
23:06amalloy(open to suggestions for a better name)
23:10mecapply-if ?
23:10scottjI thought of that too but where's the collection? :)
23:12mecoh for your postwalk
23:12mecvecify
23:12amalloyno, i meant for transform-if
23:12amalloyi ended up calling the postwalk macro-data, which is also not so hot
23:16scottjifp?
23:18scottjanyone have a better implementation/name for an ensure-list/vec/set/etc than http://jaderholm.com/paste/ensure.html
23:18amalloyscottj: i don't think your impl works
23:18amalloy&(isa? [] [])
23:18sexpbot⟹ true
23:19amalloyomg it does
23:19amalloy&(doc isa?)
23:19sexpbot⟹ "([child parent] [h child parent]); Returns true if (= child parent), or child is directly or indirectly derived from parent, either via a Java type inheritance relationship or a relationship established via derive. h must be a hierarchy obtained from make-hierarchy,... http://gist.github.com/895758
23:19scottjamalloy: always the skeptic :)
23:19amalloyscottj: haha yeah, apparently
23:19amalloy&(isa? [] [1])
23:19sexpbot⟹ false
23:19amalloyah
23:19amalloyno, i was right this time
23:20amalloyyou probably want something more like (isa? (class t) x)
23:20amalloyor i guess (instance? (class t) x)
23:22scottjthanks
23:22amalloyscottj: anyway, i'd probably call it coerce, and then change the nested-if into a cond
23:22scottjmain thing I don't like is that (ensure () [1 2]) => (2 1)
23:23amalloy(cond (instance? (class t) x) x, (coll? x) (into (empty t) x), :else (conj (empty t) x))
23:23amalloyempty is unnecessary if you'll always be given empty colls, but you might find it handy one day to say "make x into the same kind of object that y already is"
23:24scottjyeah, I like both changes
23:24jkkramer,(instance? (class []) (subvec [1 2 3] 1))
23:24clojurebotfalse
23:24amalloyoh ouch, jkkramer to the rescue
23:25jkkramer^ probably more edge cases
23:25jkkramer,(class (subvec [1 2 3] 1))
23:25clojurebotclojure.lang.APersistentVector$SubVector
23:26amalloysomething i might try, though it feels like overengineering and/or premature optimization, is turn it into a builder for coercion functions: (let [vec-maker (coerce [])] (vec-maker '(1 2)))
23:27dnolen,(vector? (subvec [1 2 3] 1))
23:27clojurebottrue
23:28scottjdoes (into [] (subvec [1 2 3] 1)) actually do anything? not sure how subvec breaks
23:28amalloyscottj: it's O(n) is all, when it could be O(1)
23:30scottjwith into [] it's 0(n) and how can it be 0(1)?
23:30scottjwith vec?
23:31jkkramersubvec is O(1)
23:31amalloyscottj: with identity
23:31amalloyor with subvec
23:31amalloyvec is O(n) even on vectors though
23:33amalloybtw scottj, that's a capital o, not the number zero
23:34scottjhehe, I didn't notice I typed that, this font sucks
23:58mec_(defn mapmap [f & colls] (apply map (partial map f) colls))