#clojure log - Mar 30 2011

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:21 no_mind: in ring which of the packages have handle-dump function ?

0:50 amalloy: technomancy: ping

0:51 clojurebot: technomancy is to blame for all failures

0:51 amalloy: clojurebot: oh thanks, now he'll associate all the bad feelings he gets from you with me instead

0:51 clojurebot: Gabh mo leithscéal?

1:01 amalloy: technomancy: 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?"

1:09 no_mind: if I have a function name as string, how can I call the function ?

1:09 amalloy: ,((resolve (symbol "first")) [1 2])

1:09 clojurebot: 1

1:15 amalloy: no_mind: that one's for you, by the way :P

1:15 no_mind: k

1:33 waxrose: amalloy, Which hosting service are you using? Amazon?

1:33 amalloy: waxrose: hosting for what?

1:34 waxrose: Or recommend for a web application. I am thinking about using Google App Engine..

1:34 amalloy: *shrug* not really my department

1:34 waxrose: oh

1:34 Sorry, I just assumed you were using a certain service for your Clojure apps.

1:35 amalloy: i can barely start a ring server

1:35 waxrose: >.<

1:36 I guess I will just stick to GAE then, seems easier to get a ring set up and so forth.

1:39 tomoj: no_mind: the fact that you asked that after a ring question worries me

1:39 amalloy: hahaha

1:41 waxrose: >.<

1:58 amalloy: tomoj: i should train myself not to answer that question without a preface of "OMG DON'T DO THIS"

2:08 planet clojure has been failing to load for me for an hour or two. anyone else having trouble?

2:09 waxrose: seems down

2:10 ping fail also

2:24 brehaut: no_mind: ring-devel ring.handler.dump/handle-dump

2:28 no_mind: brehaut, 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.

2:29 brehaut: no_mind: what are you listing for your ring :dependancies ?

2:30 raek: what error? "could not find ring/handler/dump.clj on classpath" or "could not find class ring.handler.dump"?

2:30 no_mind: ring/core "0.3.7"

2:32 brehaut: no_mind: really? not ring/ring-core "0.3.7" ?

2:32 no_mind: what about in your ring-devel link in :dev-dependancies

2:33 s/dependancies/dependencies/

2:33 sexpbot: <brehaut> no_mind: what about in your ring-devel link in :dev-dependencies

2:33 no_mind: brehaut, let me post the complete project.clj

2:33 brehaut: that would be helpful

2:34 no_mind: just dont use pastie.org it never works for me

2:35 no_mind: brehaut, http://pastebin.com/p5m3gbGs

2:38 brehaut: no_mind: and what is the particular error?

2:42 no_mind: whenI give :us directive, progran fails to compile and says cannot find dump.clj

2:42 brehaut: no_mind: can you paste the specific error and the offending :use somewhere

2:43 no_mind: k

2:43 amalloy: brehaut: you don't find it more fun to debug through paraphrasing?

2:43 brehaut: amalloy: i have to do enough divining in my dayjob ;)

2:43 amalloy: what is your day job, anyway?

2:44 brehaut: i make websites (with python/django)

2:44 i dont design them though

2:44 waxrose: nice

2:44 brehaut: waxrose: all except for the ORM ;) i have many a curse for that

2:45 waxrose: I was doing Ruby/Rails for a while, but I do design also. >.<

2:46 brehaut: the design is the part that makes me really tear my hair out. but i contract to a design company :D

2:46 amalloy: ah. so your clients treat you as a black box that includes design, but you don't actually do it

2:47 brehaut: actually, my clients are the design company :) their clients treat them as a blackbox that includes development but they dont actually do it ;)

2:47 waxrose: But I will admit, last free lance work I did was for Baylor Univ, horrible experience.

2:47 So I can understand the pulling the hair out routine.

3:34 Guest40377: Knock knock

3:36 nobody here

3:36 robink: There are people here.

3:38 waxrose: floating

3:39 amalloy: more likely, none of the people here are interested in responding to "knock knock"

3:42 sadly there is no #knockknock or #knockknockjokes channel. that would make a good conclusion for my statement

3:42 waxrose: :P

3:47 Derander: amalloy: knock knock

3:48 GuySensei: discovered 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

3:49 still learning.. but i have a strong feeling i can bet my life on it :) it is beautiful

3:49 Derander: GuySensei: welcome to the club

3:49 GuySensei: thanks!

3:50 so how big is this club? worldwide? saw only 32k downloads of clojure on github

3:50 seems pretty small, for such a thing

3:50 though good for us;)

3:54 raek: I think the most common way of obtaining the clojure jars is through the maven repo

3:54 you rarely need to build the source manually

3:58 Fossi: they are great for study

3:59 amalloy: Fossi: yes, but you probably won't be downloading the zip from github to read the source

3:59 GuySensei: ok.. though i got the zip straight from github.. it contained source as well as jars.. both needed i guess.. to understand it more

3:59 amalloy: might as well clone it

3:59 Fossi: yeah, right

4:00 amalloy: GuySensei: 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

4:01 $google Raynes getting started with clojure blog

4:01 sexpbot: First out of 61 results is: An indirect guide to getting started with Clojure » Bathroom ...

4:01 http://blog.raynes.me/%3Fp%3D48

4:01 amalloy: sexpbot: that link sucks

4:01 http://blog.raynes.me/?p=48

4:02 GuySensei: amalloy: got it!

4:03 let 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! :)

4:05 amalloy: yeah, when he's not bugging me to write his code for him :)

4:05 anyway have fun. i'm off to bed

4:07 GuySensei: haha

4:07 good night!

4:24 ejackson: mornin'

4:26 GuySensei: off to watch India Pakistan cricket match! see you guys around.. adios!

4:59 fliebel: Clojure does not have continuations, does it?

5:00 mids: fliebel: https://github.com/swannodette/clj-cont

5:00 fliebel: oh, good one, dnolen! haha

5:03 $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 )

5:03 sexpbot: Message saved.

5:05 joshua__: $mail amalloy I'm able to mail you? Hacks!?!

5:05 sexpbot: Message saved.

5:06 joshua__: $mail joshua__ testing

5:06 sexpbot: Message saved.

5:06 joshua__: How do I get a message back out?

5:06 nvm

5:06 clgv: $mail help

5:06 sexpbot: Message saved.

5:07 clgv: ups lol

5:07 $help mail

5:07 sexpbot: clgv: Send somebody a message. Takes a nickname and a message to send. Will alert the person with a notice.

5:07 clgv: i think you can simply do "$mail"

5:08 joshua__: I think you get it by /msg sexpbot mail

5:08 I say this because it gave me a little IM telling me so.

5:08 clgv: both. $mail works as well

5:08 mduerksen: does sexpbot have a spam filter? ;)

5:09 mids: oh no, look what fliebel did

5:10 fliebel: mids: ?

5:10 mids: (initiating the mail spam thing)

5:21 clgv: ,(dotimes [_ 3] (println "$mail clgv test ;)"))

5:21 clojurebot: $mail clgv test ;)

5:22 $mail clgv test ;)

5:22 sexpbot: Message saved.

5:22 clojurebot: $mail clgv test ;)

5:22 sexpbot: Message saved.

5:22 Message saved.

5:22 clgv: thats evil ;)

5:26 fliebel: Someone should make sexpbot do asciieyes, reporting to it's boss of course, that'd be evil.

5:32 clgv: hey but massmail is possible with that clojurebot-sexpbot-combo ;)

6:07 Cozey: Hi is anybody using clojure under a container different then jetty?

6:08 I 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.

6:09 do 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)

6:09 fliebel: Cozey: AOT'ing *everything* might work. Dunno, but I'd think Resin does not reload non-class files.

6:10 Cozey: I just did that

6:10 and i have *.class files along with *.clj files

6:11 fliebel: idk, I don't know.

6:11 Cozey: under WEB-INF/classes

6:11 i'll send a mail to resin guys, perhaps they can give a shot at it

6:12 will (require) (use) etc use a aot-compiled version first, if it's available?

6:13 fliebel: Does anyone have a good idea about implementing amb in Clojure? I guess it will involve loads of macros, atoms and lazy seqs.

6:16 clgv: amb?

6:16 clojurebot: amb is http://paste.lisp.org/display/73311

6:17 rfgpfeiffer: aren't exceptions slow?

6:17 Chousuke: no.

6:18 creating exception objects is the most costly operation in throwing one I think.

6:18 clgv: rfgpfeiffer: slow compared to what?

6:18 rfgpfeiffer: the call/cc implementations in kawa for example

6:19 Chousuke: John Rose had a nice blog post about this

6:20 http://blogs.sun.com/jrose/entry/longjumps_considered_inexpensive I think there was another one too :/

6:22 rfgpfeiffer: thanks

6:22 fliebel: Is there something like lein/cake rename?

6:25 rfgpfeiffer: fliebel: for renaming what? namespaces?

6:25 fliebel: I think cake replaces $$ with your project name when you create a new project.

6:25 I want to change the name of my project

6:27 https://github.com/ninjudd/cake/blob/master/src/cake/tasks/new.clj#L18

6:31 rfgpfeiffer: so you want to change the directory names, the namespace names, and the project.clj

6:31 fliebel: right

6:43 Cozey: what's the easiest way to make use of ant tasks (using cake)?

6:46 lancet?

6:46 clojurebot: lancet is a build system that works with ant written as an example for the Programming Clojure book.

6:47 cemerick: AFAIK, lancet is an unsupported experiment

6:47 or, was

6:51 fliebel: Uh, 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?

6:57 clgv: cemerick: how does counterclockwise progress? next release in april?

6:58 * fliebel phew

6:59 cemerick: clgv: That's up to Laurent. :-) I think the last RC is good enough to cut a final release of 0.2.0, anyway.

6:59 clgv: cemerick: ah good :)

7:16 fliebel: What is the difference between all those ref functions? alter/comute/ref-set/ensure Does JoC say anything about it?

7:24 mids: fliebel: it does, chapter 12.2

7:24 err 11.2

7:26 fliebel: mids: I see… I'm letting the complications of commute sink in.

8:04 raek: fliebel: http://java.ociweb.com/mark/stm/article.html

9:36 fliebel: Is 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?

9:38 ejackson: oh dear.... padded walls times for you fliebel

9:38 fliebel: padded walls?

9:39 waxrose: :3

9:40 mduerksen: fliebel: i didn't get what you want exactly, but could it by any change be fnil ?

9:40 *chance*

9:41 fliebel: mduerksen: No, more like ((wrapper type) 1 :a "blag") => int

9:41 ejackson: fliebel: of the sort with which they usually surround the nutty :)

9:41 too much coding for you !

9:42 fliebel: ejackson: I'd prefer a hammock to padded walls, but there might be some truth in your words.

9:43 ejackson: yes, my hammock is awaiting the summer, but this that is soon.

9:45 fliebel: There must be something better: #(type (first %&))

9:45 &(#(type (first %&)) 1 :a "blarg")

9:45 sexpbot: ⟹ java.lang.Integer

9:45 chouser: fliebel: I doubt there's anything better

9:45 fliebel: okay...

9:45 chouser: oh, this is for a dispatch function?

9:45 ejackson: has anbody got an idea how to package an uberjar for a clojure function ?

9:45 fliebel: yea :) you want me to use protocols?

9:46 ejackson: i tried one-jar without success

9:48 fliebel: chouser: but does that matter? How do you usually dispatch on the first or the first few args?

9:49 chouser: fliebel: I think you name all the args (as documentation, if for no other reason) and then call (type x) on the first one. :-P

9:50 fliebel: chouser: Well, okay… I'll just get over it and spend more than 5 characters on it.

9:54 chouser: Will the dispatches' args be used in the docs for the argument names?

9:55 chouser: um. probably not. :-(

9:56 fliebel: it;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:06 scottj: does this already exist? (I know about ->) (-0> conj ([] 1 2) 4 (5 6)) => (conj (conj (conj [] 1 2) 4) 5 6)

10:08 Raynes: fliebel: It replaces +project+, not $$

10:09 Licenser: Ping.

10:09 fliebel: Raynes: I figured, but I think it replaced +project+ in my git index as well, or something like that.

10:16 dpritchett: anyone enjoy that clojure sudoku solver vs python sudoku solver thread on HN this morning?

10:18 yazirian: been linking it around the office at work :)

10:18 big python shop, very helpful to people just learning

10:19 dpritchett: heh

10:19 just ran the tests myself

10:19 turns out the clojure example wasn't compiled

10:19 it's a wee bit faster when i compile it ;)

10:33 that said it still wasnt tremendously better... i'll execute it 1000 times without reloading and see if the JVM finds any magic

10:34 thickey1: where can (or, should) you place doc strings in extend-type?

10:37 jkkramer: dpritchett: clojure code is always compiled

10:37 hoeck: tschau

10:37 jkkramer: dpritchett: glad you enjoyed the post

10:37 dpritchett: so running it out of the repl vs running it out of an uberjar i made is the same?

10:37 coulda sworn i saw vastly different numbers when i built a jar

10:38 jkkramer: should be

10:38 dpritchett: i tried and tried to figure out ways to make the clojure jar execute faster (short of changing the algos) and came up empty

10:38 i'm still not comfy with this JVM thing :(

10:38 thanks for the post by the way, this has gotten me playing around with clojure for the first time in far too long

10:40 jkkramer: thanks, glad to hear it. i've got a stockpile of clojure experiments, so maybe i'll blog about more of them

10:41 dpritchett: i 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:42 also iirc i had to tweak the easy50 file from norvig's page to match the ======== delimiter you'd written into your code

10:42 good fun!

10:56 scottj: jkkramer: did you run with -server and try more than 99 puzzles?

10:58 jkkramer: scottj: yes

10:59 after the first few runs, hotspot didn't seem to do much

11:00 dpritchett: mine's chugging through 1000 iterations and i'm watching the logfile, doesn't seem to be speeding up

11:01 wonder if the JVM needs to take a deep breath first... i could put a wait timer in every 10th run maybe

11:01 or i could learn how the JVM works

11:01 jkkramer: if i were going for speed, i'd probably rethink the thing from scratch - using other data structures, mutation etc

11:01 dpritchett: or perhaps the fact that it's rotating through different difficulty levels makes it harder to optimize via profiling

11:02 that is maybe if i ran easy-only for 1000 iterations or hard-only for 1000 iterations it would show some improvement

11:04 scottj: I think hotspot waits till 10,000 invocations of a method before compiling it to native

11:05 I haven't looked at the code but I guess some of the helper methods could easily do that in a couple games.

11:05 clgv: scottj: 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:14 mattmitchell: I'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:19 Dantas: Im looking forward to read "the joy of clojure". When will be available for .mobi/Kindle devices ?

11:22 dpritchett: fogus blogged on Monday that print orders direct from manning would include a mobi "when available"

11:22 http://blog.fogus.me/2011/03/28/joy-of-clojure-in-print/

11:22 clojurebot: I think you mean gnir.

11:25 Dantas: dpritchett: thanks !

11:26 dpritchett: im wainting for the .mobi . ( kindle )

11:27 clgv: $findfn " " true

11:27 sexpbot: [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:27 dpritchett: I 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:27 clgv: &(doc clojure.string/blank?)

11:27 sexpbot: ⟹ "([s]); True if s is nil, empty, or contains only whitespace."

11:28 dpritchett: when compared to PDF i mean

11:28 mids: reading the PDF is doable on the kindle v3

11:29 (after the usual rotation and zooming)

11:29 dpritchett: reading the JoC meap pdf on my iphone 3g via goodreader is doable but not exactly enjoyable

11:29 i tried it on my granddad's ipad and it looked just fine, scrolling and page turns were snappy too

11:30 ejackson: "my grandad's ipad" that's cool.

11:31 dpritchett: it was a gift from his kids. he prefers his two (three?) and his laptop(s)

11:31 He really likes downloading powertoys and freeware and then hosing his machine and then reformatting or buying a clean new machine

11:32 ejackson: :)

11:34 fliebel: Where do you people put examples in a lein project?

11:35 mids: test/

11:36 scottj: or an examples dir in src

11:36 fliebel: is test on the cp?

11:37 mids: (that is, after turning the examples into automated tests)

11:38 fliebel: mids: I was thinking about complex examples, more like integration tests.

11:42 mattmitchell: aye, how do you mock a function in a different namespace?

11:43 fliebel: mattmitchell: mock?

11:43 mattmitchell: fliebel: well, i'm kinda struggling with how to write one of my tests

11:44 fliebel: mattmitchell: probably binding?

11:44 zerokarmaleft: http://www.youtube.com/watch?v=8mjky2QE9DA <= haha, Gnome Chompski: The Game

11:44 oops, wrong chan

11:46 mattmitchell: fliebel: 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:48 mids: afaik binding works for that too

11:48 or change your API and expose the callback-fn as argument

11:50 mattmitchell: since my explanations are never as good as code: https://gist.github.com/894643

11:50 mids: ok i'll looking into binding, haven't tried that yet.

11:51 mids: (binding [clojure.string/reverse identity] (clojure.string/reverse "123"))

11:58 mattmitchell: mids: thanks!

12:20 yazirian: has 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:20 i've taken three cracks at it so far https://gist.github.com/894704

12:21 everything 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:22 but 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:22 hiredman: doseq isn't, but with-query-results is

12:22 (hanging on to the head

12:23 yazirian: i thought resultset-seq was the part that took care of that?

12:23 hiredman: what do you mean?

12:23 yazirian: https://github.com/richhickey/clojure-contrib/blob/6a0483d9e216ca00fc648a4b3673996b76a2785a/src/main/clojure/clojure/contrib/sql/internal.clj#L178

12:23 hiredman: with-query-results binds the results to a name for the scope of the with-query-results expression

12:24 yazirian: hmm

12:25 hiredman: I maybe wrong given that with-query-results uses a function like that internally

12:27 yazirian: It clearly IS holding onto something somewhere, but what's confusing me is that it doesn't LOOK like it should be.

12:32 fliebel: yazirian: I don;t know if this is the case, but doing a substring keeps the old string around… since you mentioned char[]...

12:32 jweiss_: ,(comment {:a 0 :a 0})

12:32 clojurebot: Duplicate key: :a

12:32 jweiss_: i don't like this

12:32 fliebel: jweiss_: You're not the only one.

12:33 dnolen: there needs to be a navigator for all of Clojure interfaces.

12:33 amalloy: &(comment TODO: make this work)

12:33 sexpbot: java.lang.Exception: Invalid token: TODO:

12:33 fliebel: yazirian: I recal reading abotu certain DB interfaces having the substring "leak" calling (String.) on the result gets you a fresh string.

12:34 sritchie: hey all -- do any clojure.contrib.* functions exist for pretty printing xml?

12:34 amalloy: jweiss_: i wrote a patch to add #|....|# style comments, but it was rejected as undesirable

12:34 jweiss_: amalloy: i'd be happy if the reader went into "just find the closing paren" mode after (comment

12:34 fliebel: sritchie: Can't the standard xml lib print indented?

12:35 amalloy: fliebel: prxml does

12:35 jweiss_: or i suppose it could still tokenize. but checking a map for dup keys? what a waste of CPU

12:36 amalloy: jweiss_ if it tokenizes, it has to call (read)

12:36 and that has to complain about duplicate keys

12:36 that's why i wanted #|

12:36 jweiss_: amalloy: not if the reader behavior were changed, right?

12:37 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:37 yazirian: fliebel: 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:39 amalloy: jweiss_: (comment) is just a macro

12:39 $source comment

12:39 sexpbot: comment is http://is.gd/xjRdPI

12:39 amalloy: no way the reader behavior for it will ever change

12:39 afk a bit while you mull that over

12:40 jweiss_: ah didn't realize it was implemented that way

12:40 * jweiss_ would've thought comments were handled by the reader... like other comments

13:38 fliebel: Why can;t I do this? ##(let [s java.lang.String] (new s))

13:38 sexpbot: java.lang.IllegalArgumentException: Unable to resolve classname: s

13:39 amalloy: fliebel: if it were allowed with that syntax, all (new) operations would be slow

13:39 ,(let [s String] (.newInstance s))

13:39 clojurebot: ""

13:40 Raynes: http://stackoverflow.com/questions/3748559/clojure-creating-new-instance-from-string-class-name

13:40 fliebel: amalloy: Can I do .newInstance to any class? Is there a Clojure way to do it to deftypes and defrecords?

13:41 Raynes: fliebel: Read the accepted answer.

13:41 fliebel: reading...

13:46 scottj: implementation 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:49 amalloy: scottj: i'm inclined to write it as a reduce

13:56 no_mind: Enlive by default looks for a template in src directory. is it possible to change this ?

13:57 amalloy: scottj: 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:00 sritchie: hey 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:00 one sec, I'll post a gist --

14:00 raek: no_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:01 amalloy: sritchie: gensymmed? then the user would have no choice but to ignore the arg. is that your intent?

14:01 sritchie: amalloy: yeah

14:01 there's a pattern in pallet where a "request" variable is always threaded through the body

14:02 so, lots of functions have the pattern of (defn config-files [request arg1 arg2] (let .... (-> request (func1 args... )))

14:02 etc

14:02 raek: no_mind: it might be possible to pass it a File object (representing a file path), but I haven't tried it

14:02 amalloy: (defmacro with-ignore [name args & body] `(defn ~name ~(vec (cons (gensym) args)) ~@body))

14:02 no_mind: k testing

14:02 amalloy: sprinkle in some docstrings if you like

14:03 sritchie: amalloy: awesome! I do need to retain a reference to the gensym, though --

14:04 so the last part can be (fn [request#] (-> request# ~@body))

14:08 maacl: Is 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:13 hiredman: maacl: yes, it is wrong

14:13 I suggest you complain to the authors

14:14 dpritchett: submit errata here http://apress.com/book/errata/1312#correx

14:18 Cozey: When i use reify, do I have to tag first argument with ^Type ?

14:19 or will clojure figure this out automagically

14:23 dnolen: Cozey: I believe you don't have to typehint w/ reify as long as your extending to a protocol, not an interface.

14:23 Cozey: i'm extending an interface

14:24 dnolen: Cozey: then you need a type hint yes to avoid reflection when calling that method.

14:24 Cozey: ok, thanks!

14:25 dnolen: fliebel: ping

14:26 fliebel: dnolen: pong

14:26 dnolen: fliebel: sorry missed you message from earlier. clj-cont -> delimc. It's only tangentially related at this point to logos, but maybe applicable.

14:28 fliebel: dnolen: Would it be possible to implement that Scheme thing in Clojure with delimc?

14:29 dnolen: fliebel: the amb operator? Dunno. The amb operator might turn out to be useful or maybe not.

14:31 fliebel: dnolen: It seem in itself a very nice tool for constraint finite domain stuff. (+ 4 (apply amb (range 9)))

14:35 dnolen: fliebel: could be could be. I never looked any more closely at amb then the stuff in SICP and The Art of the Propagator.

14:36 fliebel: I got interested in delimc again because of Dybvig's paper on Subcontinuations, seems related somehow to fork/join to me.

14:37 fliebel: Or even (assert (+ 4 (apply amb (range 9))) 12)

14:37 joly: I 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:38 fliebel: Once I understand how contionuations work (in delimc), I might try to make that work :)

14:39 TimMc: amb?

14:39 clojurebot: amb is http://paste.lisp.org/display/73311

14:40 * TimMc eyes clojurebot doubtfully

14:40 amalloy: TimMc: looks fine to me!

14:40 fliebel: TimMc: Some magic continuations thing in scheme that lets you use a few values and let it figure out which one work.

14:40 joly: It's a function that makes an "amb"iguous choice among its arguments that magically ends up being a non-failing choice

14:41 fliebel: amalloy: That macro does not work across multiple amb statements.

14:41 joly: Often implemented behind the scenes with continuations and/or backtracking

14:41 fliebel: or… does it?

14:41 amalloy: fliebel: hell if i know. i'd never heard of amb until now. but it looks like a relevant link

14:41 fliebel: joly: often? How else?

14:42 amalloy: fliebel: scheme interpreters might just be good guessers

14:42 sritchie: amalloy: hey, sorry to disappear -- one last quick question -- is there a quick way to tweak this to work? https://gist.github.com/894884

14:42 joly: non-deterministic computers, still to be build ;)

14:42 dnolen: fliebel: 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:42 sritchie: so that request# is cons-ed into the args vector, but can still be accessed in the body

14:42 joly: built*

14:42 amalloy: sritchie: yes, by not using the auto-gensym feature

14:43 fliebel: dnolen: Can I macroexpand it? I'm curious how that looks.

14:43 amalloy: (let [req (gensym "request")] `(defn ... ~(vec (cons req args)) (-> ~req ~@body)))

14:44 fliebel: dnolen: one big advantage of amb over miniKanren is that you can use regular Clojure functions.

14:44 sritchie: amalloy: awesome,thanks!

14:45 dnolen: fliebel: that is an advantage, but it's also a big disadvantage as well.

14:45 fliebel: true

14:45 joly: I don't think you can do cuts or similar with amb

14:46 dnolen: fliebel: if you write a amb operator using delimc, it would be interesting to compare performance.

14:46 fliebel: delimc generates a crazy amount of functions, much crazier than the miniKanren macros.

14:46 fliebel: :(

14:47 dnolen: fliebel: 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:48 not sure if that would work at all, but something to think about ...

14:48 fliebel: dnolen: I think it'd be faster to just do something recursive with a few atoms ruling out wrong answers.

14:50 dnolen: fliebel: 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:51 fliebel: sounds good

15:11 pdk: (doc fork)

15:11 clojurebot: Huh?

15:11 pdk: (doc join)

15:11 clojurebot: excusez-moi

15:11 pdk: where are these magical pieces

15:12 dnolen: pdk: you need OpenJDK 7

15:46 wwmorgan: is 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:48 amalloy: wwmorgan: maybe clojure.set has it? it sounds a lot like intersect/subset

15:49 raek: hrm, but for maps...

15:50 amalloy: &(let [map-a {:a 1} map-b {:a 1 :b 2}] (clojure.set/subset? (keys map-a) (keys map-b))

15:50 sexpbot: java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IFn

15:50 amalloy: huh, keys doesn't return a set. i guess that makes sense but it makes me sad

15:50 raek: (defn map-subset? [container containee] (= container (merge container containee)))

15:51 amalloy: &(let [map-a {:a 1} map-b {:a 1 :b 2}] (clojure.set/subset? map-a map-b))

15:51 sexpbot: ⟹ false

15:51 fliebel: $findfn even? [1 3 5 4 7] 4

15:51 sexpbot: []

15:51 amalloy: fliebel: join the club. we all want this function :P

15:52 fliebel: amalloy: I suppose it;s in your utils?

15:52 amalloy: chouser called it ffilter by analogy with ffirst

15:52 it's not, actually. good point

15:52 fliebel: (comp first filter)

15:53 amalloy: yes

15:54 wwmorgan: raek: beautiful. thanks

15:55 fliebel: lol, now I have a piece of code that looks like ((comp blah foo) (comp bar baz) (comp bee boo) (comp first range) ... )

15:55 oh, I fogot the juxt...

15:55 amalloy: fliebel: https://github.com/amalloy/amalloy-utils/blob/master/src/amalloy/utils.clj#L27 - it's there now

15:57 fliebel: amalloy: How do you use that stuff, you just add it as a dependency?

15:57 amalloy: yeah

15:57 i'll push an update to clojars now if you want to use ffilter

15:58 fliebel: amalloy: That's a lot of code in a lot of projects for a lto of small wins.

15:58 amalloy: fliebel: that's a lot of words for something i don't quite understand :)

15:59 fliebel: amalloy: Okay, point taken *goes to bed* ohnoe, I need to finish this!

16:00 I meant to say that you add a lot of code to your projects you probably don't use.

16:00 amalloy: i 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:00 fliebel: *shrug* code is cheap. clojure.core contains a lot more code i never use than amalloy-utils does

16:00 fliebel: a bit of both...

16:00 amalloy: contrib, even more so

16:01 fliebel: amalloy: it has been modularized, hanslt it?

16:01 amalloy: hm. my project.clj asks for clojure 1.2.1 at the moment. probably not very friendly as a library dependency

16:01 fliebel: amalloy: version ranges to the resqueue

16:02 amalloy: indeed

16:02 i had it written that way before, but was fiddling with it while i tried out the cdt

16:03 fliebel: amalloy: You know… I have a mental barrier for using your utils because they are called *amalloy*-utils

16:04 Myabe I should just fork, name it pepijn-utils and start using it...

16:04 amalloy: fliebel: 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:04 fliebel: haha, I'll keep you to it :)

16:04 amalloy: alternative macro and lazy libraries of yours

16:04 fliebel: (wait, can I say that or is that denglish)

16:05 amalloy: fliebel: i think we'd say "hold you to it", but it's a trivial distinction

16:06 fliebel: alternative macro and lazy libraries of your utils?

16:06 amalloy: perhaps yuseful utils. i was never good at spelling

16:07 fliebel: 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:07 fliebel: amalloy: key presses are cheaper than googling for ffirst.

16:10 * fliebel goes to bed for real

16:14 joshua__: What is this amazing marvelous awesome liberating library of yours? ')

16:14 ;)

16:16 Cozey: Hey, 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:19 dnolen: ,(let [a (atom 5)] (take @a (range 9)))

16:19 clojurebot: (0 1 2 3 4)

16:20 amalloy: joshua__: 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:20 mine happens to be at https://github.com/amalloy/amalloy-utils

16:21 joshua__: amalloy, I actually just read through it.. maybe you didn't notice but the amazing awesome etc was your name expanded ;p

16:24 amalloy: hahaha

16:24 how did i miss that

16:24 it clearly sounded too natural

16:36 Netfeed: p/win 9

16:38 Cozey: What's better? (concat (list (foo ..)) (map ... )) or (cons (foo ...) (map ....)) ?

16:39 amalloy: Cozey: cons seems way better

16:39 concat often signals a mistake anyway

16:40 Cozey: and 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:40 signals?

16:40 brehaut: &((juxt identity type) (cons 1 [2]))

16:40 sexpbot: ⟹ [(1 2) clojure.lang.Cons]

16:41 amalloy: Cozey: cons probably just implements an ISeq whose first is (the first thing) and rest is (the other thing)

16:41 so not exactly the same as car/cdr - clojure doesn't have those - but very similar

16:42 Cozey: right, this seems obvious

16:42 but perhaps if i'd cons a lot, i would get a 'loose' structure compared to a vector

16:42 amalloy: Cozey: loose?

16:42 Cozey: which would be worse performance wise, right?

16:43 loose, like a linked list

16:43 brehaut: Cozey: giant bag of 'it depends'

16:43 Cozey: :-D

16:43 amalloy: Cozey: *shrug* depends what you want to do. if you want to iterate through it, a cons chain is fine

16:43 Cozey: ok

16:44 amalloy: Cozey: for example, ##(drop 2 (range 10)) is a lazy sequence with cons cells underneath

16:44 sexpbot: ⟹ (2 3 4 5 6 7 8 9)

16:46 Cozey: like most lazy-seq's - so nothing to be afraid here

16:46 thanks

16:48 dnolen: amalloy: is that true? Cons is a specific data structure. LazySeqs are something quite different I thought.

16:49 Cozey: as i've seen in bvarious sources, lazy-seq's are usually implemented as (cons currently-computed (lazy-seq (recurent-call ... ))

16:51 dnolen: ,(concat [1 2 3] [4 5 6])

16:51 clojurebot: (1 2 3 4 5 6)

16:51 dnolen: Cozey: ^ is common

16:52 Cozey: in lazy-seq? is concat lazy?

16:52 yes.

16:52 it is.

16:53 brehaut: if concat is lazy (and a quick 'type' agrees), how does it differ from lazy-cat ?

16:54 dnolen: range actually used ChunkedCons underneath, not sure if the features of Cons apply to them (hopefully someone else will chime in)

16:54 amalloy: brehaut: it isn't. lazy-cat is old and should be consigned to the rubbish bin as far as i know

16:54 lazy-cat was for before we had lazy-seq

16:55 dnolen: right, range is a bad example

16:55 dnolen: amalloy: not true, lazy-cat is macro, so you don't thunk up concats when you have a lot of sequences.

16:55 amalloy: $source lazy-cat

16:55 sexpbot: lazy-cat is http://is.gd/76pvOk

16:56 amalloy: dnolen: (lazy-cat (lazy-cat ...)) looks like it would have the same problems, since it expands to a call to concat

16:58 dnolen: amalloy: yeah, I'm wrong, the purpose of lazy-cat is to lazily process the arguments.

16:59 amalloy: right. there aren't really that many uses for lazy-cat, as far as i've seen

17:09 duncanm: i think it's is a really cute post: http://funcall.blogspot.com/2011/03/tail-recursion-and-debugging.html

17:09 amalloy: &(seq (lazy-seq nil))

17:09 sexpbot: ⟹ nil

17:09 duncanm: hey amalloy, Raynes

17:09 amalloy: &(seq (lazy-seq (lazy-seq nil)))

17:09 sexpbot: ⟹ nil

17:10 Raynes: duncanm: Hey.

17:11 sorenmacbeth: could someone help me with an idomatic clojure solution to the following problem?

17:11 duncanm: Raynes: i read the Scala Swing design document again, they have decided to merge the containers and layout mgr distinction in Swing

17:12 Raynes: so they have things like BoxPanel and FlowPanel, which are JPanels with the appropriate LayoutManager

17:12 Raynes: i wonder if that's similar to the approach 'shoes' took

17:12 Raynes: duncanm: No clue.

17:12 duncanm: maybe Monkeybars from JRuby is also interesting to look at

17:13 http://en.wikibooks.org/wiki/Ruby_Programming/GUI_Toolkit_Modules#Swing_wrappers

17:13 sorenmacbeth: what's the prob?

17:13 sorenmacbeth: given 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:14 each item paired up with every other item expect itself

17:14 amalloy: you want...all permutations of length two?

17:15 brehaut: clojure.contrib.combinatorics/permutations ?

17:15 Raynes: &(clojure.contrib.combinatorics/permutations ["a" "b" "c"])

17:15 sexpbot: java.lang.ClassNotFoundException: clojure.contrib.combinatorics

17:15 Raynes: Thanks, sexpbot.

17:15 Anyways, that's a start.

17:15 brehaut: Raynes: you need a n

17:15 duncanm: ooh ooh ooh

17:15 amalloy: permutations doesn't take an n

17:15 as written

17:15 duncanm: &(clojure.contrib.combinatorics/permutations 2 ["a" "b" "c"])

17:15 sexpbot: java.lang.ClassNotFoundException: clojure.contrib.combinatorics

17:15 duncanm: boo

17:15 brehaut: oh right, im tihnking of combinations

17:16 Raynes: brehaut: No I don't.

17:16 You need an N. Keep your Ns to yourself.

17:16 ;)

17:16 brehaut: Raynes: aha

17:18 duncanm: (remove (fn [[x y]] (= x y)) (selections [ "a" "b" "c" ] 2))

17:18 (("a" "b") ("a" "c") ("b" "a") ("b" "c") ("c" "a") ("c" "b"))

17:21 brehaut: or as a simple comprehension: ##(let [s #{"a" "b" "c"}] (for [a s b (disj s a)] [a b]))

17:21 sexpbot: ⟹ (["a" "b"] ["a" "c"] ["b" "a"] ["b" "c"] ["c" "a"] ["c" "b"])

17:22 amalloy: nice, brehaut

17:24 duncanm: hmm

17:24 sorenmacbeth: duncanm: thanks!

17:24 duncanm: i can't think of a way to write (fn [[x y]] (= x y)) in terms of partial and every?

17:25 brehaut: amalloy: i can write tidy code sometimes!

17:25 amalloy: duncanm: (partial apply =)

17:25 sorenmacbeth: brehaut: awesome!

17:25 duncanm: ahh

17:26 (remove (partial apply =) (selections [ "a" "b" "c" ] 2)) ;; even better

17:26 amalloy: my first attempt was (partial every? =)

17:26 amalloy: &(doc distinct?)

17:26 sexpbot: ⟹ "([x] [x y] [x y & more]); Returns true if no two of the arguments are ="

17:26 amalloy: you could also use (filter distinct?)

17:27 but i guess that wants varargs

17:27 duncanm: amalloy: i think it's funny that i see people define (defn sum [xs] (reduce + 0 xs)) quite often

17:27 sritchie: does anyone have a good example of clojure.contrib.dev/name-with-attributes?

17:28 duncanm: amalloy: when (apply + xs) would suffice

17:28 sritchie: I'm writing a "defphase" macro that should accept an optional docstring

17:28 amalloy: duncanm: so would (reduce + xs)

17:28 duncanm: amalloy: in this case, i prefer apply over reduce

17:28 amalloy: so do i

17:28 duncanm: but that's because + is varidisic (sp?)

17:29 amalloy: it'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:29 variadic

17:29 duncanm: booo

17:29 variadic

17:29 arity, variable-arity, variadic

17:32 devn: ariable-varity

17:33 duncanm: i guess there's an impulse to write a variadic function when the func is associative and commutative

17:33 or you use reduce ;-P

17:34 i look at IFn last night, it's funny that there are variants of apply up to 20 arguments

17:34 and no more

17:34 i wonder what made Rich go to 20, and stop at 20

17:34 sritchie: here's what I could come up with for that macro example -- https://gist.github.com/895353

17:34 duncanm: if it were me, i think i might stop at like, 6?

17:35 overloads of apply

18:46 pdlogan: i'm looking at your nconc repo, and i can't find any js files

18:46 oh

18:47 it's in a different dir

18:47 pdlogan: yeah - they're under public.

18:47 in fact shell scripts are there too. sigh. it was easy.

18:47 duncanm: pdlogan: it's cool talking to you, i've been a subscriber to your blog for quite a few years

18:48 pdlogan: oh - thanks. I've recently weened myself off twitter and back to the blog.

18:48 duncanm: pdlogan: i really liked the esh scheme and fidget-with-widget links that you bring up once in a while

18:48 those were cool projects

18:49 pdlogan: and i liked the smalltalk mentions too

18:49 pdlogan: yeah, "don't fidget with widgets, draw!" is one of my favorites.

18:49 duncanm: i dabbled in Squeak for a while

18:49 scottj: sritchie_: is the example in that gist really 3 or is it 2?

18:49 duncanm: pdlogan: it's like AJAX before the web ;-P

18:50 pdlogan: if 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:50 duncanm: pdlogan: unified in one lang/system, instead of html/css/js

18:50 hmm

18:50 pdlogan: i've been playing with xmpp, it's pretty easy to get started with smack

18:51 pdlogan: so any app back in any data center can interact with a drawing in any browser

18:52 duncanm: pdlogan: 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:52 pdlogan: yeah I've been using strophe in js which is pretty good. and a while back one in C whose name escapes me.

18:52 yeah, lively is getting faster all the time though.

18:52 duncanm: pdlogan: smack + clojure is easy

18:53 is it even being maintained/developed nowadays?

18:53 pdk: yo don't be talkin smack man

18:53 respeck

18:53 duncanm: booyakasha

18:53 pdlogan: I'll have to try it, although I'm less interested in java/jvm based languages than I was a few months ago.

18:53 smack? I think it has languished for the last year or two.

18:54 duncanm: pdlogan: they had a new release 2 weeks ago

18:54 pdlogan: i think you'll like this: http://funcall.blogspot.com/2011/03/tail-recursion-and-debugging.html

18:54 pdlogan: oh really? hrm - but dangit I gave up the jvm for lent.

18:55 duncanm: Smack 3.2.0 Beta has been released on February 3, 2011.

18:55 and i updated my openfire server recently, the last release was 4 weeks ago

18:55 so i'm a little off

18:56 pdlogan: duncanm: 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:56 duncanm: yeah, i was referring to lively

18:56 oh oh

18:57 miscommunication

18:57 either way, the tail-call post is really funny

18:57 technomancy: duncanm: that's hilarious

18:57 pdlogan: duncanm: tail recursion and debugging - ho hum? my response would be turn it off to debug or debug some other way.

18:58 duncanm: pdlogan: oh... i'd keep it on, just so that i *can* debug ;-) you really should load up the page

19:00 pdlogan: "my understanding that the Java creators specifically chose not to implement this, as it makes resultant code hard to debug (if not impossible)."

19:00 duncanm: pdlogan: wow, you almost didn't post at all during 2010... wow

19:01 pdlogan: ^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:02 hiredman: http://projectfortress.sun.com/Projects/Community/blog/ObjectOrientedTailRecursion

19:03 brehaut: from memory C#3+ does tail call optimisation on 'release' builds by default

19:03 Caffeine: hiredman: Cool, I'll certainly read this when I get 2 sec.

19:03 duncanm: i 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:03 hiredman: the jvm guys made a mistake not including it in their otherwise very nice vm

19:03 technomancy: my understanding is John Rose wants to implement tail calls, but his bosses want him to work on other things.

19:04 duncanm: hiredman: the typography used by Fortress always turns me off a little

19:04 it's a cute idea, but my eyes never seem to be able to focus on the code-proper

19:04 brehaut: duncanm: click the 'show ascii' buttons then :P

19:04 hiredman: λ λ hey!

19:04 duncanm: brehaut: that's what i'm doing

19:05 hiredman: i'm okay with that one, but clojure has shown that 'fn' is a decent substitute for 'lambda'

19:06 i need to read that William Cook paper again, i read it a few months ago, and i thought i understood it

19:06 and now it's been completely erased from my mind, i don't remember a single thing ;-P

19:14 Caffeine: duncanm: 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:17 duncanm: Caffeine: right

19:42 TimMc: My kingdom for a ulong type.

20:02 I'm writing a partial instruction set simulator for MIPS-32, and dealing with unsigned 4-byte memory addresses is annoying.

20:03 brehaut: TimMc: 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:04 TimMc: 64 bit int?

20:04 brehaut: its probably a long?

20:05 amalloy: yes, longs are 8 bytes

20:06 TimMc: Oh! Dammit, so confused.

20:06 amalloy: finding an unsigned eight-byte type is hard in java, but unsigned four-byte types are easy

20:06 (you use a signed eight-byte type instead)

20:06 TimMc: So, longs take up two registers on a 32-bit machine?

20:06 amalloy: TimMc: java is unconcerned with registers

20:06 but a long is guaranteed to be 64 bits

20:07 TimMc: I know, I'm just thinking about ISAs.

20:07 ...since I'm trying to simulate a processor.

20:08 amalloy: so? your program wants unsigned 4-byte ints for some reason that isn't really important

20:08 an 8-byte signed int will stand in for that; just do a modulo operation before you write it back

20:10 TimMc: Yeah, 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:10 ...which obviously isn't the case, now that I look at it.

20:10 amalloy: indeed

20:10 TimMc: Thanks for setting me straight. :-)

20:14 I'll have to redo my ALU now.

20:14 amalloy: because you were assuming overflow or something?

20:14 TimMc: numeric tower + bitwise operations is tricky

20:15 amalloy: TimMc: 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:15 TimMc: ,(long (inc Long/MAX_VALUE))

20:15 clojurebot: java.lang.ArithmeticException: integer overflow

20:16 TimMc: ,(long (+ Long/MAX_VALUE 1))

20:16 clojurebot: -9223372036854775808

20:16 TimMc: amalloy: Yes, but that means storing more than just a function in my ALU op map.

20:17 amalloy: TimMc: not necessarily. i agree it's probably best, but functions can do anything :P

20:17 TimMc: In that case, the functions will need to do their own checks and casts, or be passed to HOFs in the map.

20:40 carllerche: can anonymous functions return references to themselves?

20:40 amalloy: carllerche: yes!

20:40 carllerche: is there a keyword for that? not sure how one would do it

20:40 amalloy: (fn myfn [] (comp foo myfn))

20:40 carllerche: ah... i guess you just need to name them then

20:41 amalloy: carllerche: it's semi-anonymous

20:41 carllerche: that's fine

20:41 thanks

20:41 amalloy: welcome

20:43 Derander: haha

20:43 semi-anonymous

20:43 sorry, that tickles me

20:44 amalloy: Derander: it's better than "named anonymous"

20:44 Derander: I know :-)

20:44 that also occurred to me and made me giggle

20:46 amalloy: i 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:01 seancorfield: amalloy: in reference to letfn vs named anonymous functions, are there times when letfn is the right choice?

21:01 amalloy: seancorfield: yes

21:02 but not, imo, when all you do is call it once

21:02 letfn 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:03 * seancorfield hasn't needed letfn yet

21:03 seancorfield: 'k

21:05 amalloy: &(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:05 sexpbot: ⟹ (true true true true true true true true true true)

21:05 amalloy: bah

21:05 anyway you get the idea

21:05 i had too many not's in there, i think

21:06 TimMc: Shouldn't have nots on the decs.

21:06 amalloy: &(letfn [(odd? [x] (and (not (zero? x)) (even? (dec x)))), (even? [x] (or (zero? x) (odd? (dec x))))] (map even? (range 10)))

21:06 sexpbot: ⟹ (true false true false true false true false true false)

21:06 amalloy: yeah

21:07 pdk`: if you think about it

21:07 ))))) is much more common in code than (((

21:09 TimMc: $findfn + "_PLUS_"

21:09 sexpbot: []

21:09 TimMc: $findfn + "clojure.core$_PLUS_"

21:09 sexpbot: []

21:09 amalloy: TimMc: two _s, i think

21:09 pdk`: much, yes

21:11 TimMc: amalloy: That's not what my REPL shows.

21:11 amalloy: &(class +)

21:11 sexpbot: ⟹ clojure.core$_PLUS_

21:11 amalloy: okay, you're right

21:11 TimMc: hah

21:11 ,(:name (meta +))

21:11 clojurebot: +

21:12 amalloy: &(+ 1 2)

21:12 sexpbot: ⟹ 3

21:12 amalloy: wonder why findfn isn't trying class

21:12 oh duh

21:13 class returns a class, not a string:

21:13 $findfn + clojure.core$_PLUS_

21:13 sexpbot: [clojure.core/class clojure.core/type]

21:13 TimMc: Ah!

21:13 * dnolen prefers letfn for readability.

21:13 dnolen: but then again I've been doing a lot of Scheme.

21:16 cgray: hi, anyone else here doing compojure on google app engine? I'm having real trouble with latency when a new instance starts...

21:18 brehaut: cgray: it seems unlikely that compojure would be the cause of your problems

21:20 cgray: brehaut: no, I realize that. I assume that I'm loading too many classes at startup...

21:21 but I'm not sure how to avoid that

21:22 amalloy: brehaut: 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:23 brehaut: amalloy: 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:24 cgray: brehaut: of course it's not *just* compojure, it's also hiccup, sandbar, ring, clj-oauth, and all of their dependencies

21:24 scottj: cgray: what kind of latency are you talking about, 3 seconds?

21:24 cgray: scottj: more like on the order of 10 seconds

21:25 scottj: the last one was 25 seconds...

21:26 brehaut: cgray: 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:27 cgray: brehaut: so i'm screwed?

21:27 brehaut: cgray: rough count has 1700 classes in clojure-1.2.0.jar

21:27 scottj: are you using appengine-magic? I don't know if it does any optimizing

21:27 brehaut: cgray: i dont know much at all about tuning GAE or appengine-magic sorry

21:27 cgray: scottj: yes

21:28 scottj: but only one feature of it

21:28 scottj: cgray: you could deploy a bare bones and then add in features to see what effect they ahve

21:29 maybe you can do that locally even

21:29 cgray: that's a good idea

21:29 now that i have it basically written

21:29 brehaut: scottj: i believe that the local dev enviroment for GAE just starts a jetty

21:30 cgray: have you considered asking on the ring list?

21:30 cgray: brehaut: no, i'm not on any of the lists... it's a good idea though

21:32 anyway, thanks for the help, it's supper time for me :)

21:32 brehaut: cgray: good luck

21:34 TimMc: ,(long (+ Long/MAX_VALUE 1))

21:34 clojurebot: -9223372036854775808

21:34 TimMc: ,(int (+ Integer/MAX_VALUE 1))

21:34 clojurebot: java.lang.IllegalArgumentException: Value out of range for int: 2147483648

21:34 TimMc: So casting to long truncates, and casting to int throws.

21:35 ...and (inc SomeNumeric/MAX_VALUE) always gives overflow, I think.

21:42 Caffeine: you can always recover with something like (inc (BigInteger/valueOf Integer/MAX_VALUE)) .. I think... dunno if that can help you

21:44 TimMc: Yeah, there are a bunch of tricks... it's just confusing.

21:55 mec: whats the best way to take a random number of items from a collection without getting duplicates?

21:55 devn: distinct + take rand-int

21:57 ,(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:57 clojurebot: (1)

21:57 devn: ,(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:57 clojurebot: (1 22 2 3 4 55 5 6 7)

21:58 tomoj: wtf, how have I never learned distinct?

21:58 devn: tomoj: clearly you're a failure

21:58 ;)

21:59 amalloy: that is *not* an efficient way to do it for large N. fliebel and i did a little "study" on this a while ago

21:59 mec: ,(take 10 (distinct (repeatedly #(rand-nth (range 100)))))

21:59 clojurebot: (98 73 39 34 66 52 18 4 0 95)

21:59 devn: there's another way

21:59 anyway, you want uniques => distinct

21:59 you want random? rand-*

22:00 plenty of ways to do that

22:00 amalloy: http://stackoverflow.com/questions/3944556/what-if-anything-is-wrong-with-this-shuffling-algorithm-and-how-can-i-know/5238130#5238130

22:00 devn: heh, "how can i know"

22:00 without reading the article: "measure it."

22:02 ,(int (rand 100))

22:02 clojurebot: 82

22:02 devn: another way you could do it

22:03 you could generate a random sort-by function , etc. etc. etc.

22:03 amalloy: devn: that's actually not uniformly random. i read an interesting article about how sort-by rand is skewed

22:04 seancorfield: ,(doc distinct)

22:04 clojurebot: "([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"

22:04 amalloy: because 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:06 TimMc: In fact, your sort might not terminate.

22:09 tomoj: with 0 probability?

22:09 devn: seancorfield: hola

22:09 seancorfield: i emailed you back btw

22:10 amalloy: 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:10 sometimes less random is a good random

22:12 amalloy: devn: 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:12 "take a random number of elements" vs "take a number of random elements"

22:13 seancorfield: devn: yup, i replied with my skype / aim / gtalk handles

22:13 mec: amalloy: how do those 2 not mean the same

22:14 amalloy: um. 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:14 mec: oh lol

22:15 well now that my brain is working i meant "take a number of random elements"

22:17 amalloy: naturally. see my SO link for some interesting different answers

22:18 seancorfield: so which of the following do folks prefer (and why)?

22:18 (take 10 (repeatedly #(rand-int 10)))

22:18 (take 10 (map rand-int (repeat 10)))

22:18 ,(take 10 (map rand-int (repeat 10)))

22:18 clojurebot: (5 3 6 1 0 8 6 4 5 4)

22:19 seancorfield: ,(take 10 (repeatedly #(rand-int 10)))

22:19 clojurebot: (9 4 0 8 8 1 5 7 7 9)

22:19 seancorfield: (and are there cleaner / more idiomatic ways to do that?)

22:19 amalloy: well, now that you've said them twice in different orders i can't say "the first one" anymore :). i like repeatedly

22:20 brehaut: i think repeatedly is clearer

22:20 mec: repeatedly says more to what you're doing in that case

22:20 seancorfield: heh, you should have seen my early attempts _before_ i went digging around in the docs :)

22:21 amalloy: seancorfield: the second version could be improved to (map rand-int (repeat 10 10))

22:21 but it's still grosser

22:22 seancorfield: grosser... more gross... :) thanx for the input... when i find so many ways to do stuff i often wonder what's more idiomatic

22:22 mec: most grossest

22:23 seancorfield: and 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:23 amalloy: There's More Than One Way To Do It (but only one of them is right!)

22:45 seancorfield: any 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:47 brehaut: seancorfield: start simple and write a simple 'real' program as soon as possible?

22:48 trptcolin_: <shamelessplug>clojure koans are fun :)</shamelessplug>

22:48 though they're certainly not real :)

22:48 brehaut: trptcolin_: i think that would be a great second step

22:51 trptcolin_: seancorfield: are they doing much concurrent stuff? obviously that's a killer feature to pull them in

22:52 brehaut: seancorfield: 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:52 seancorfield: trptcolin_: 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:53 brehaut: 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:54 the 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:55 trptcolin_: 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:55 seancorfield: ultimately, i want all of the model to migrate to clojure

22:57 amalloy: seancorfield: did you watch the conj talk/video about simplicity?

22:59 seancorfield: amalloy: yeah, pretty sure i have watched that... let me just double-check

22:59 amalloy: it wanders around for a while trying to find a topic, but it does include some talk about a la carte OO features

23:00 mec: Is there some better way to write this, it seems overly wordy: (let [a (foo)] (if bar? (shmoo a) a))

23:01 scottj: ((if bar? shmoo identity) (foo))

23:01 trptcolin_: hawt

23:01 amalloy: scottj: good luck with that

23:01 bar? will always be true because it's a function: you're not calling it

23:01 scottj: who's to say bar? isn't a var?

23:02 trptcolin_: well, is it? (def bar? true)

23:02 amalloy: oh sorry

23:02 i misread the question

23:02 seancorfield: amalloy: yeah, now i've started watching stu's video, i remember it :)

23:02 trptcolin_: probably an "unconvential" naming tho :)

23:03 amalloy: mec: 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:04 trptcolin_: scottj gets the credit there

23:04 amalloy: er, dang it, it's scottj's

23:04 * amalloy gives up

23:04 trptcolin_: amalloy: that's pretty smooth

23:04 (the link)

23:04 i love fns that take multiple fns as args

23:05 amalloy: trptcolin_: thanks. i find myself using (postwalk (transform-if seq? vec) some-coll) often for macros

23:06 (open to suggestions for a better name)

23:10 mec: apply-if ?

23:10 scottj: I thought of that too but where's the collection? :)

23:12 mec: oh for your postwalk

23:12 vecify

23:12 amalloy: no, i meant for transform-if

23:12 i ended up calling the postwalk macro-data, which is also not so hot

23:16 scottj: ifp?

23:18 anyone have a better implementation/name for an ensure-list/vec/set/etc than http://jaderholm.com/paste/ensure.html

23:18 amalloy: scottj: i don't think your impl works

23:18 &(isa? [] [])

23:18 sexpbot: ⟹ true

23:19 amalloy: omg it does

23:19 &(doc isa?)

23:19 sexpbot: ⟹ "([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:19 scottj: amalloy: always the skeptic :)

23:19 amalloy: scottj: haha yeah, apparently

23:19 &(isa? [] [1])

23:19 sexpbot: ⟹ false

23:19 amalloy: ah

23:19 no, i was right this time

23:20 you probably want something more like (isa? (class t) x)

23:20 or i guess (instance? (class t) x)

23:22 scottj: thanks

23:22 amalloy: scottj: anyway, i'd probably call it coerce, and then change the nested-if into a cond

23:22 scottj: main thing I don't like is that (ensure () [1 2]) => (2 1)

23:23 amalloy: (cond (instance? (class t) x) x, (coll? x) (into (empty t) x), :else (conj (empty t) x))

23:23 empty 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:24 scottj: yeah, I like both changes

23:24 jkkramer: ,(instance? (class []) (subvec [1 2 3] 1))

23:24 clojurebot: false

23:24 amalloy: oh ouch, jkkramer to the rescue

23:25 jkkramer: ^ probably more edge cases

23:25 ,(class (subvec [1 2 3] 1))

23:25 clojurebot: clojure.lang.APersistentVector$SubVector

23:26 amalloy: something 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:27 dnolen: ,(vector? (subvec [1 2 3] 1))

23:27 clojurebot: true

23:28 scottj: does (into [] (subvec [1 2 3] 1)) actually do anything? not sure how subvec breaks

23:28 amalloy: scottj: it's O(n) is all, when it could be O(1)

23:30 scottj: with into [] it's 0(n) and how can it be 0(1)?

23:30 with vec?

23:31 jkkramer: subvec is O(1)

23:31 amalloy: scottj: with identity

23:31 or with subvec

23:31 vec is O(n) even on vectors though

23:33 btw scottj, that's a capital o, not the number zero

23:34 scottj: hehe, I didn't notice I typed that, this font sucks

23:58 mec_: (defn mapmap [f & colls] (apply map (partial map f) colls))

Logging service provided by n01se.net