#clojure log - Apr 06 2011

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

0:52 amalloy: hey tomoj, feel like translating the 23 lines of clojure at https://gist.github.com/905147 into 200 lines of php for me?

0:52 waxrose: LOL

0:52 evil

0:54 amalloy: i especially (don't) look forward to translating that letfn. i expect the swap!/comp/juxt mess will just disappear, at least, when mutable state is easy to get

3:25 thorwil: hi mids! some of my recent appengine-magic problems were caused by using wrong versions, what remains is that the datastore viewer leaves out properties under certain circumstances, but now that i know, i can live with it

3:27 mids: anyway, do you have an example of a handler to be called by a task queue job? currently just a do-nothing handler that simply doesn't lead to errors would be progress here :)

3:36 amalloy: thorwil: (constantly nil) probably won't cause any problems, but i guess that's not necessarily true

3:37 ejackson: morning

3:39 amalloy: hola ejackson

3:50 thorwil: hooray for searching within source at github, this looks like it should provide a solution: https://github.com/jorisbontje/snorri-model/blob/2012a07f48ba43710cfdbb18c4854fdc5f56f30f/src/snorri_model/api.clj

3:54 alas, the problem might sit somewhere else: INFO: Web hook at http://localhost:8080/admin/tasks/delete returned status code 500. Rescheduling...

4:27 i can get app engine to shut up with (-> "OK" rsp/response constantly) as handler, but i fail to find a way to put that into a function, to first do something and then return for piece

4:34 amalloy: uh. #(when (do-actual-work) "OK")?

4:37 thorwil: amalloy: i just found the problem is not the return, but the argument of the function. it only works as non-argument function, but now i wonder how to get at my request parameters

4:41 amalloy: thorwil: https://github.com/jorisbontje/snorri-model/blob/2012a07/src/snorri_model/core.clj#L54 suggests that his package is using the ring wrap-params middleware, as one might expect. not sure how he exposes it to you, cause i don't really use ring much

4:44 thorwil: d'oh, of course i need wrap-params. i'm forgetting what i already know :/

4:45 thanks amalloy

4:47 what's interesting is that i have to remove the constantly, if i wrap the handler in wrap-params

4:50 amalloy: um, that's because you don't want to return a constant value. you want to return some function of the inputs?

4:52 anyway, i'm gonna go to bed. i'm far from a ring expert, so it's no great loss to anyone

6:43 bartj: how can one run the examples in clojure-hadoop ?

6:43 would it be as simple as: java -jar clojure-hadoop-examples.jar ClassName

6:50 clgv: bartj: you'll get a partial answer if you try ;)

6:55 bartj: clgv, I did, it was in the source file anyway :)

6:55 clgv: it did work?

6:55 bartj: yes, of course

6:56 clgv: great

6:56 bartj: but am a bit non-plussed, I don't have hadoop installed on my system

7:01 clgv, have you worked with hadoop before?

7:02 clgv: bartj: no, not at all. otherwise I should have been able to answer your initial question

7:03 bartj: clgv, no problem, thanks!

7:08 &lastseen rhickey

7:08 sexpbot: java.lang.Exception: Unable to resolve symbol: lastseen in this context

7:14 clgv: $seen rhickey

7:14 sexpbot: rhickey was last seen quitting 2 days and 19 hours ago.

7:16 dreamreal: is clojure.org responding with a domain registration page for anyone else?

7:17 clgv: dreamreal: not for me. but I heard there were problems yesterday - it was said that they were resolved

7:19 $max

7:19 sexpbot: The most users ever in #clojure is 317

7:20 dreamreal: well, phooey. Until the DNS stuff gets fixed locally - time-warner, you know - I can't see anything. :(

7:20 fogus`: dreamreal: Are you seeing one now even after a uber-refresh?

7:21 dreamreal: fogus`: yes

7:21 fogus`: dreamreal: I guess some providers have yet to get the DNS info. :-(

7:22 Chousuke_: yeah, I have the squatter page still too :/

7:22 dreamreal: fogus`: okay, flsuhing DNS and switching browsers got me the original page

7:22 chrome is still giving me the register.com page, even after DNS

7:22 Chousuke_: flushing dns?

7:22 fogus`: Weird.

7:22 dreamreal: yeah, windows. ipconfig /flushdns

7:23 Chousuke: ah, hm

7:24 dreamreal: any IDE support for clojure?

7:25 ttmrichter: dreamreal: Emacs and some not-very-stable stuff for Eclipse.

7:25 dreamreal: hmm, k

7:27 clgv: dreamreal: counterclockwise is pretty stable for eclipse. didnt have any crashes yet (since Okt 2010)

7:27 ttmrichter: I haven't even managed to get counterclockwise to install.

7:27 clgv: there will be a new stable release soon as far as I heard

7:28 ttmrichter: well that does not mean it's the projects fault ;)

7:29 ttmrichter: Well, it's probably more the Eclipse project's fault given that it's all dependency Hell.

7:29 clgv: I installed it on 4 different computers, one of them running windows 7. all went smooth

7:30 ttmrichter: I just took a "normal java development bundle" and there was no need to get any other dependencies

7:31 ttmrichter: Which version of Eclipse? I installed Helios, ran updates, then tried to install counterclockwise. No dice.

7:31 clgv: 3.6.2

7:31 ttmrichter: I did install the Java EE version, mind.

7:33 dreamreal: An eclipse plugin is not a strength. Eclipse blows.

7:33 ttmrichter: I thought it rather sucked myself.

7:33 At galactic black hole levels of suction.

7:33 clgv: dreamreal: well, that depends on your view and experiences with it...

7:34 dreamreal: clgv: Every time I use Eclipse I'm reminded of how sheeplike developers are. They're attracted by big shiny "free!" labels and ignore those silly old "will make you productive" labels.

7:34 It's slow, buggy, user-unfriendly. </opinion>

7:34 ttmrichter: Huh. Apparently there's a Netbeans plugin ("enclojure") as well.

7:35 I've never seen an IDE that made me productive, TBH.

7:35 clgv: dreamreal: which free-labels?

7:35 ttmrichter: I prefer a decent text editor and a shell.

7:35 dreamreal: ever used IDEA?

7:35 ttmrichter: Nope.

7:35 dreamreal: clgv: you know, the labels that say "oh look eclipse is freeeeeee"

7:35 ttmrichter: Never even HEARD of IDEA.

7:35 dreamreal: ttmrichter: jetbrains.com

7:35 Dunno if IDEA would be any good for clojure, though

7:36 ttmrichter: http://www.enclojure.org/

7:36 That's the Netbeans plugin.

7:36 I have no opinion on it whatsoever since I've never seen it before just about thirty seconds ago. :)

7:36 clgv: dreamreal: never seen one. I got to use eclipse while studying and experienced that it is a quite good IDE.

7:37 ttmrichter: the netbeans plugin seemed to have some more features than the eclipse one, last time I checked...

7:37 ttmrichter: OK, clgv, I'm giving CCW another shot.

7:37 First question: which particular version?

7:37 Counterclockwise Feature?

7:37 Counterclockwise Feature REPL UI Branch?

7:38 clgv: I am on the stable 0.0.64

7:38 ttmrichter: Does that give the REPL or not?

7:39 That is probably where the dependency Hell came from.

7:39 cemerick: ttmrichter: you want the newer RC's

7:39 clgv: yes. but with a different input-behaviour than the console one

7:40 ttmrichter: OK, just trying to install 0.0.64: install failed.

7:40 I'll stick to Vim + shell/REPL.

7:40 clgv: cemerick: *still waiting for that new stable release*

7:40 cemerick: ttmrichter: Did you already have a version of ccw installed?

7:40 ttmrichter: Nope.

7:40 clgv: ttmrichter: you got plenty of bad karma? ;)

7:40 ttmrichter: An error occurred while collecting items to be installed

7:40 session context was:(profile=epp.package.cpp, phase=org.eclipse.equinox.internal.p2.engine.phases.Collect, operand=, action=).

7:40 No repository found containing: osgi.bundle,ccw.branding,0.0.64.STABLE01

7:40 No repository found containing: osgi.bundle,ccw.clojure,1.2.0.STABLE12

7:40 No repository found containing: osgi.bundle,ccw.clojurecontrib,1.2.0.STABLE12

7:40 No repository found containing: osgi.bundle,ccw.core,0.0.64.STABLE01

7:40 No repository found containing: osgi.bundle,ccw.debug,1.0.5.STABLE

7:40 cemerick: ttmrichter: if you can post the log somewhere, I'll take a look

7:40 ttmrichter: No repository found containing: org.eclipse.update.feature,ccw.feature,0.0.64.STABLE01

7:41 No repository found containing: osgi.bundle,ccw.support.examples,0.0.4.STABLE01

7:41 No repository found containing: org.eclipse.update.feature,ccw.support.examples.feature,0.0.4.STABLE01

7:41 No repository found containing: osgi.bundle,ccw.support.leiningen,1.1.2.STABLE01

7:41 No repository found containing: osgi.bundle,clojure.osgi,1.2.10.STABLE002

7:41 No repository found containing: osgi.bundle,paredit.clj,0.11.1.STABLE01

7:41 No repository found containing: osgi.bundle,parsley,0.0.6.STABLE01

7:41 opqdonut_: please!

7:41 ttmrichter: Not that important, cemerick. I hate Eclipse anyway.

7:41 opqdonut_: don't paste it here

7:41 ttmrichter: Yeah, my bad.

7:41 Sorry 'bout that. Didn't see how many lines it was.

7:45 clgv: ttmrichter: lol, if you hate eclipse anyway, it doesnt make much sense for trying the clojure plugin anyway, I guess ;)

7:51 ttmrichter: clgv: I mostly tried it to see if there was any benefit to using more than vim+shell.

7:52 cemerick: ttmrichter: surely lots of benefits, but you'd need to be open to the premise, I think :-)

7:53 clgv: ttmrichter: I didn't try any vim plugins. But I don't like to develop in console texteditors if the project is bigger than an exercise assignment with one or two source files involved ...

7:53 __name__: There is alway gvim.

7:54 *always

7:54 clgv: __name__: almost identical feature set ;)

7:54 __name__: But it's not a console editor :)

7:55 clgv: putting it in a window and using menus and toolbars doesnt change it entirely to an IDE ;)

7:55 __name__: You did not say that :)

7:55 Neither did I.

7:56 clgv: indeed I didnt say that, it was implied with the texteditor statement ;)

7:56 ttmrichter: clgv: I've worked on 100,000+ line projects using just plain old text editor + shell.

7:57 clgv: not that important anyway - I have counterclokwise and am happy with it! :)

7:57 ttmrichter: I've never seen an IDE that made me "more productive" than I am with just those raw tools.

7:57 clgv: ttmrichter: if you like it and get your work done...

7:57 ttmrichter: Now to be fair I haven't done a lot of pro Java work.

7:58 It could be that Java requires such a setup.

7:58 wlangstroth: either that, or you keep the class diagrams on your cube wall

7:59 (which I have certainly done)

8:00 cemerick: More better tools are always associated with higher levels of productivity. Our habits are often the limiting factor in taking advantage of them, though.

8:01 ttmrichter: The slippery part is defining "better".

8:02 I'm sure that a "good" IDE will do marvels. I just haven't seen one yet.

8:03 cemerick: If A provides X but B does not, then it's hard to say that B is better

8:03 I'd submit that minimalism is a habit and cultural bias, not a feature.

8:04 ttmrichter: Your example presupposes that X is a desirable trait.

8:04 As an example, let me cite "autocompletion".

8:04 I've had autocompletion in IDEs and text editors and found them so frustrating I turned them off.

8:04 They caused more errors (with attendant waste of time) than they saved typing.

8:04 clgv: well, there really good autocompletion features in the meantime

8:05 +are

8:05 ttmrichter: Would you consider Eclipse's to be good?

8:05 cemerick: ttmrichter: Then you're necessarily limited to "namespaces" that you can memorize.

8:06 clgv: for what I used it yes. I'd even say the one in VS 2010 is quite good

8:06 * cemerick is thinking that it's going to be hard to find common understanding around tooling between two people that don't agree about autocompletion ;-)

8:06 ttmrichter: Well, I have no opinion on VS past 6. :)

8:17 clgv: is there a way to load all clojure files in a given directory? or all clojure files with a given namespace prefix?

8:18 like: org.algo.spec.*

8:58 bsteuber: is there a way to tell clojure how exceptions in futures should be dealt with?

8:59 because it kind of sucks to debug code without being notified of exceptions

9:15 raek: bsteuber: you do as usual when you want a certain behaviour when a exception is thrown: surround the code in a try/catch block

9:16 bsteuber: raek: yeah, but I mean the default when an uncought exception is found

9:17 raek: (catch Throwable e (.printStackTrace e))

9:17 is this for a background thread (e.g. a server)?

9:17 bsteuber: yeah but I don't want to write this each time I call future

9:18 yes sth like that

9:18 and something that doesn't return anything

9:18 because it just runs and does side effects

9:19 raek: it would be nice to have some way to send the exception to slime...

9:19 with futures, the exception is "sent back" to the creator

9:20 bsteuber: but only on deref'ing the future, right?

9:20 at least currently it just happens to be "silent fail"

9:20 raek: if you deref the future, you will get the exception wrapped in a ExecutionException

9:21 so, they are kind of more adapted to the "do some processing in the background and report back" usecase

9:21 bsteuber: so for "do sth. in the background and never report back", agents are preferred?

9:22 hm but I guess that might yield the same problem

9:22 raek: I think so too

9:23 bsteuber: for normal java threads, I can use Thread.setDefaultUncaughtExceptionHandler

9:23 but this doesn't work with futures

9:23 but I'll try agents, too

9:23 raek: in an application I'm writing now, I have a safety-net macro, which I put the code for printing the stack trace in the right stream and/or do logging

9:23 agents are built on executors too

9:23 "futures"

9:23 bsteuber: I see

9:24 raek: (a future is what you get back when you send a task to an executor)

9:25 bsteuber: so maybe sth. analogous to Thread.setDefaultUncaughtExceptionHandler for executors is a reasonable feature request?

9:26 raek: my feeling is that the Java people will tell you that a try/catch block is the solution to the problem

9:26 the executor framework is in the Java standard library

9:27 this default handling of errors make it much more simpler to communicate errors over thread boundaries

9:28 bsteuber: I see

9:28 ok thanks for your help :)

9:30 raek: (defmacro safety-net [& body] `(try ~@body (catch Throwable e# (.uncaughtException (Thread/getDefaultUncaughtExceptionHandler) (Thread/currentThread) e#))))

9:30 you can do something like that to get the Thread behaviour

9:30 kephale00: i'm blanking… what is a good way to get a function handle from the respective symbol aside from EVAL

9:31 raek: if you use slime, that will print a stack trace in the swank-clojure terminal, rather than pop up a message in slime

9:31 clgv: kephale00: (-> symb resolve var-get)

9:32 kephale00: clgv: thanks

9:32 clgv: kephale00: you can also use -?> from contrib to avoid a NullPointerException

9:33 kephale00: oOoo

9:33 clgv: kephale00: works nice with if-let or when-let, e.g. (when-let [f (-?> symb resolve var-get)] (f ...))

9:34 kephale00: phew, i haven't even been using such *-let combos yet

9:35 clgv: it's just a hint. ;)

9:35 kephale00: oh yeah, i'll get there before long!

9:49 clgv: shouldnt the following get me two matches? ##(re-matches #".*\.clj" "bla.clj.clj")

9:49 sexpbot: ⟹ "bla.clj.clj"

9:49 clgv: "bla.clj" and "bla.clj.clj" ?

9:52 (re-matches #".*?\.clj" "bla.clj.clj")

9:52 &(re-matches #".*?\.clj" "bla.clj.clj")

9:52 sexpbot: ⟹ "bla.clj.clj"

9:53 clgv: ah it's due to "greedy" vs "reluctant"

9:54 when using re-find, I mean

10:19 rplevy: how can you know (without a try/catch) if some unknown thing is Seqable ?

10:19 include something like a java ArrayList

10:20 angerman: ,(doc seq?)

10:20 clojurebot: "([x]); Return true if x implements ISeq"

10:21 rplevy: false

10:21 angerman: lol?!

10:21 rplevy: :)

10:23 (seq? (java.util.ArrayList. ))

10:23 clgv: &(seq? (java.util.ArrayList. ))

10:23 rplevy: (seq (java.util.ArrayList. ))

10:23 sexpbot: ⟹ false

10:23 opqdonut_: ,(doc clojure.contrib.seq-utils/seqable?)

10:23 clojurebot: Pardon?

10:23 clgv: it's not sequable ;)

10:23 rplevy: but I can seq it

10:23 clgv: &(seq (java.util.ArrayList. ))

10:23 angerman: clgv: yes, that's what confuses me about rplevy request as well.

10:23 sexpbot: ⟹ nil

10:24 opqdonut_: I could've sworn there was something like that

10:24 angerman: ,(doc seq)

10:24 clojurebot: "([coll]); Returns a seq on the collection. If the collection is empty, returns nil. (seq nil) returns nil. seq also works on Strings, native Java arrays (of reference types) and any objects that implement Iterable."

10:25 rplevy: so is there a predicate that returns true for all of the things listed in that doc string?

10:26 clgv: how can I resolve a directory by its name relative to the classpath?

10:26 rplevy: ,(source seq)

10:26 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

10:27 clgv: if I have no jar I need to prepend "/resources/" what doesnt work in a jar where it has to be removed

10:27 $source seq

10:27 sexpbot: seq is http://is.gd/zebspD

10:32 rplevy: there must be some function that evaluates to true for all the types of things that work in seq, or if not, there should be. this is isn't something you need often but ocassionally it is useful

10:33 cemerick: rplevy: see clojure.contrib.core/seqable?

10:34 rplevy: but as discussed above, seqable is only one of the interfaces supported by seq

10:34 cemerick: it's not a generally-answerable question at the moment

10:34 rplevy: how so?

10:36 cemerick: rplevy: because "seqable" is a protocol-esque concept that operates over a set of disparate types

10:38 When a proper seq protocol becomes available, then you'll be able to query the protocol's var for a set of types for which the protocol has implementations.

10:39 trptcolin: also, the contrib seqable? doesn't just check for Seqable - it looks for Iterable, nil, String, Map, etc. as well

10:40 cemerick: right, I guess I should have been explicit about that

10:40 rplevy: cemerick: thank you, very good to know

10:50 clgv: rplevy: just do (seq something). if it is nil, it's either empty or not sequable or you passed in nil

10:50 rplevy: trptcolin: I didn't see what you meant at first -- that solves the problem now (but the protocol version makes sense as the core solution)

10:51 clgv: actually seqable? is better because it doesn't throw exceptions you have to catch

10:51 clgv: seq does?

10:51 rplevy: yeah

10:51 clgv: when?

10:52 trptcolin: ,(seq 1)

10:52 clojurebot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Integer

10:52 clgv: ah ok ;)

10:59 pyr: hi all

10:59 i've changed my method of running ring and now use lein ring server

11:00 which is more useful, but in some cases i have some initialisation to do, how do I make sure before the service is started my init functions are called ?

11:06 clgv: pyr: do :repl-init or :repl-init-script help you? maybe not if they are only loaded when using a repl

11:09 trptcolin: pyr: you could use ~/.lein/init.clj - that gets loaded, if present, before any lein task

11:11 mefesto: pyr: this initialization is something you'd like to happen when deployed to production as well, right?

11:12 pyr: sorry away for a minute

11:13 mefesto: yep

11:13 basically i need connections to my database and such initiated

11:13 s,initiated,established

11:13 cemerick: There's a web.xml entry for that.

11:14 pyr: cemerick: ?

11:14 cemerick: Though it sounds like you're not using such things.

11:14 pyr: no, before i was using a simple -main function

11:14 cemerick: pyr: are you packaging up the webapp as a .war file?

11:14 mefesto: i think lein-ring generates a web.xml

11:14 pyr: so i could set things up, then run (jetty-server)

11:14 now with lein-ring-server my handler gets called automatically

11:14 mefesto: but it's not configurable afaik

11:14 cemerick: mefesto: ironic, given that that's all web.xml is for :-)

11:15 mefesto: cemerick: yup it'd be great if it was configurable :)

11:15 pyr: well, i'll go back to -main then

11:17 cemerick: pyr: FWIW, the element is servlet/load-on-startup in web.xml http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webapp/web_xml.html#1039287

11:18 (if you happen to want to go that route eventually)

11:18 pyr: erf ok

11:19 mefesto: there's also a ContextListener for on deploy/undeploy events

11:19 * cemerick is expecting an s-expression transcription of web.xml to come around eventually

11:19 pyr: i'm happy with load-balancing jetty servers for now

11:19 mefesto: s/ContextListener/ServletContextListener/

11:19 sexpbot: <mefesto> there's also a ServletContextListener for on deploy/undeploy events

11:19 pyr: to tell you the truth

11:19 i see no compelling reason to do otherwise

11:20 cemerick: heh, jetty is a servlet container, which by definition uses web.xml descriptors for deployment (whether you see them or not) :-)

11:21 pyr: probably :), but compojure hides that from me elegantly

11:22 cemerick: which is OK until you need to fiddle something in your web.xml file

11:23 Anyway; I actually think the abstraction is being provided by the lein ring plugin, not compojure (which actually knows nothing about such things)

11:24 pyr: yeah, agreed

11:24 i'll just have to stick to starting with a -main for now to get my DB connections setup

12:13 angerman: does anyone speak dutch?

12:14 ejackson: angerman: sorry, I lost wifi there....

12:15 angerman: ejackson: pardon me?

12:15 ejackson: you asked a question, I answered and then prompty was disconnected

12:15 if I missed a response, could you repost it, please

12:16 angerman: ejackson: no no, I missed your response

12:16 * ejackson is is coding in his garden, which stresses the wifi a little

12:16 ejackson: angerman: aaah, my response is that I speak Afrikaans which is often servicable for Dutch

12:17 * ejackson notes that an English garden is optimal for coding on account of the total lack of bugs. *snarf* *snarf*

12:17 angerman: I'm looking for someone who'd translate me 5 lines :D

12:17 ejackson: into, our out of, Dutch

12:17 angerman: https://gist.github.com/905947

12:17 -> Dutch

12:18 The other way is usually pretty simple for me, (Speaking German and coming from the coastal region of Germany)

12:18 ejackson: sorry, can't help that way.

12:18 angerman: ejackson: no worries, thanks anyway :D

12:18 ejackson: whoever read it would think you were a total idiot :)

12:19 angerman: I am :D

12:19 * ejackson notes further, upon seeing a thrush in his garden, that prehaps combinators are the answer to his current issue...

12:20 * ejackson takes final note of the hammock swinging under the tree..... This really is the ideal setting for Clojure development

12:20 angerman: lol

12:33 sritchie: angerman: appirater's great

12:34 angerman: sritchie: well, memmons fork is :D

12:39 devn: I have something like this: (with-open [zstream (java.util.zip.GZIPInputStream. (input-stream "/path/to/foo.gz")))

12:39 missing a ] on there, but that's basically what I start with

12:39 what I need to do is write the zstream contents out to a file

12:45 dakrone: devn: check out clojure.java.io/copy

12:51 devn: dakrone: you nailed it -- thank you

12:53 dakrone: devn: you're welcome

12:57 duncanm: is there a way to get a literal string syntax in the sexpr reader?

12:57 I don't want to escape strings

12:57 technomancy: duncanm: it's been discussed. there's been push-back.

12:57 duncanm: technomancy: ahh

12:58 i liked that in C#, @"...." is literal

12:58 can i implement that as a reader macro?

12:59 sigh, #"...." is already taken

13:00 trptcolin: duncanm: no, in fact you can't implement *anything* as a reader macro - that power is reserved for the language itself

13:38 Borkdude: Programming a dynamically typed language is like playing fretless guitar.

13:38 So much more expression ;-).

14:40 fliebel: Good morning. Would it be okay to expose a transient to the outer world?

14:40 chouser: fliebel: no

14:41 :-)

14:41 fliebel: chouser: Okay. Why? I mean, it does not feel right, but I can't see a direct problem with it.

14:41 amalloy: only if the outer world consists solely of co-conspirators (ie, is actually the inner world)

14:41 chouser: fliebel: it's mutable

14:42 if they try to pass it to another thread, it will fail. many functions that work on collections will fail on transients.

14:43 fliebel: hm, yea, threading.

14:45 amalloy: fliebel: iirc it's not just "threading could cause bugs", it's "transients intentionally throw an exception when used on a thread other than the one they were created on"

14:45 fogus`: who is the outer world?

14:45 fliebel: amalloy: I know, a bit like io! right?

14:46 amalloy: fliebel: uhhhh. maybe? a bit? io! is something you have to opt into; transients just refuse to work

14:46 and threading is far from the only issue

14:47 fliebel: fogus`: People writing a game with my library. I do think using a transient in the main game loop would be a lot faster, but would expose that to the game.

14:47 fogus`: I see.. then I agree with chouser and amalloy

14:48 fliebel: Okay, then we're four already :)

14:50 Next opportunity to go fast is Threads :) Is there any way seque might break when used with transactions? It did not seem to queue at all.

14:51 I noticed it uses an agent, which might cause it to wait on the transaction, but I havn;t figured out how that affects the queueing.

14:51 $source seque

14:51 sexpbot: seque is http://is.gd/Ggbm1u

14:54 fliebel: Weird implementation...

14:54 Pisketti: Silly question:

14:55 Is there a way to reduce an infinite seq by somehow using a stop condition?

14:55 I can't use take to get a non-lazy seq and reduce that because I don't know how many elements I need.

14:55 fliebel: take-while

14:57 Pisketti: Okay, that's exactly what I need. Thanx. :)

15:16 fliebel: Wheee! I had my engine running at 200% cpu for a moment there. But now it got completely stuck. What was that option for seeing what the GC is doing?

15:19 Ah, -XX:-PrintGC, now I need to put that to lein

15:26 Not good! [Full GC 126911K->120090K(126912K), 0.5707135 secs]

15:27 I wonder if it's the head-holding all over again, or some Swing thing I'm holing onto.

15:30 amalloy: fliebel: i think your full GCs should aim to collect a larger percentage of your memory :)

15:31 fliebel: amalloy: I think so to… :( First it does a lot of normal ones, abut later it repeatedly does the full one.

15:31 I'm trying visualVM now to see what is using the memory.

15:37 It's 44MB worth of Ducks and another 43MB worth of Longs.

15:41 amalloy: sounds like time to cook some duck soup

15:41 fliebel: amalloy: duck is a defrecord.

15:56 Yea, classic head-holding again -,-

16:12 okmijnoob: hi ll

16:12 +a

16:31 fliebel: How do I test Swing code? (assert "Did you see a duck?") does not seem to be the right way.

16:33 raek: I tried Abbot once in a lab in a testing course: http://sourceforge.net/projects/abbot/

16:36 fliebel: raek: Thanks… *considers the effort*

16:38 cemerick: fliebel: any automated approach is bloody difficult.

16:39 at least 10x tougher than web stuff via e.g. selenium

16:40 fliebel: cemerick: Yea, and I only have 10 lines of Swing stuff copies straight from the docs. So maybe I should just wrote a few dummy objects and leave the real Swing stuff.

16:40 *write

16:41 cemerick: I'd never consider even attempting it.

16:41 fliebel: :)

16:41 cemerick: Thick client UI toolkits are a boon for the tester QA employment levels.

16:41 s/tester/manual

16:41 sexpbot: <cemerick> Thick client UI toolkits are a boon for the manual QA employment levels.

16:41 cemerick: feh

16:43 fliebel: Anyway, I've had enough dentistry for today. I'll see if I can get at least *some* test tomorrow.

16:43 thanks all, and have a good night/day :)

16:56 bobo_: is there any way to make clojuresque to not evaluate al the code when doing a war file for example? so i can have a (run-jetty ...) in one namespace for repl/swank and still be able to create a war with gradle?

16:57 tomoj: why do you want a top-level run-jetty for repl/swank?

16:58 bobo_: its kinda handy for it to run when i require the namespace, its not something i live and die for but still

16:58 or to be able to eval a buffer for it to run

17:00 lein jar for example has no problem with it

17:00 cemerick: lein jar doesn't do AOT; perhaps clojuresque does?

17:01 In any case, I'll bet gradle or clojuresque sets a system property you can use in a guard around the (run-jetty) call

17:01 bobo_: you can turn of aot in clojuresque, but from what i understand, it then does require on them instead

17:01 and true, maybe using a guard is the best way.

17:02 tomoj: with a top-level run-jetty, you can only eval the buffer once, right? or do you have top-level logic for checking whether a server is already running?

17:02 bobo_: defonce

17:02 tomoj: ah, right. does sound handy I guess

17:03 shouldn't the effect of alter-var-root on a var in some other namespace be visible to all the code in that namespace?

17:04 raek: yes

17:04 tomoj: hrm.. I'm removing :link from enlive's self-closing-tags, but <link>s still emit differently than <lin>s

17:04 raek: (unless some other thread is using 'binding' on it)

17:04 tomoj: also tried just binding, no effect

17:05 no bindings in enlive afaict

17:06 raek: bobo_: my approach would be to put all "startup" code in a (defn -main [] ...) and then call it

17:06 one more step to do, though...

17:07 bobo_: yeh i thought about that aswell

17:08 doesnt look like clojuresque sets a property, but i could add that i guess

17:08 raek: top-level side-effects like those tends to be hard to combine with AOT compilation too

17:09 (since the server would be started when the code is compiled, rather than executed)

17:09 tomoj: maybe *compile-files* is enough?

17:10 raek: the nowadays built-in "lein run" task uses the -main fn approach

17:10 (in contrast to the old lein run plugin, which simply loaded the file)

17:10 bobo_: yes well it doenst seem like an unsolvable problem atleast. but im to tired now :-(

17:11 tomoj: oh, d'oh, enlive is parsing this as html

17:50 devn: hello gents

18:06 pdk: ,(rationalize 3.0)

18:06 clojurebot: 3

19:04 gfrlog: any guesses about the expressive power of alpha-numeric-less clojure?

19:09 cemerick: gfrlog: what, APL in sexprs?

19:10 gfrlog: cemerick: sort of...

19:10 TimMc: gfrlog: Clojure with all alphanumeric-containing fn names removed?

19:10 You could still do lambda calculus. :-)

19:10 gfrlog: TimMc: could you?

19:10 do we have alphanumericless variable names?

19:11 TimMc: gfrlog: #( % ) stuff

19:11 gfrlog: TimMc: that won't nest very far

19:11 TimMc: oops, right

19:11 cemerick: You'll always have to cope with what the special forms are named.

19:11 gfrlog: I've figured out a surprising amount in Ruby

19:11 cemerick: Sounds painful in any case.

19:12 gfrlog: one man's pain is another man's

19:12 cemerick: powerful beauty, I know :-)

19:12 TimMc: gfrlog: masturbation?

19:12 gfrlog: either would work. I stopped adding words to the sentence when I realized it already parsed the way it was

19:12 but I didn't really mean it that way

19:13 TimMc: I can express an infinite loop.

19:13 gfrlog: go

19:14 TimMc: (#(% %) #(% %))

19:14 ,(#(% %) #(% %)) ; let's see if I got that right

19:14 clojurebot: java.lang.StackOverflowError

19:14 TimMc: Omega combinator, IIRC.

19:14 gfrlog: that's so weird, because I figured that out myself about a year ago

19:14 and somehow didn't think of it in this context

19:15 TimMc: The underlying basis for recursion in a language without self-reference.

19:15 devn: hello all

19:15 gfrlog: can you get an expression that evaluates to an integer?

19:15 TimMc: eep

19:16 ,(*)

19:16 clojurebot: 1

19:16 TimMc: So I can get all of them.

19:16 gfrlog: dangit

19:17 once again, I've done that before

19:17 I'm not thinking today

19:17 okay

19:17 so now what about alphabetic strings?

19:17 TimMc: I'm looking at the top line of http://clojure.github.com/clojure/

19:17 I can also get booleans, via equality.

19:17 gfrlog: ah yes

19:18 I can get "TimMc" in ruby

19:18 TimMc: haha

19:19 gfrlog: I'm gonna bet something like that is not possible

19:19 all we have is ints, booleans, ratios, and infinite recursion

19:19 TimMc: If I can catch an exception, I can get alphanumerics... maybe not.

19:20 Man, I can't even index into a string yet.

19:20 OK, metadata... that can get me what I want.

19:21 ,^#'*

19:21 clojurebot: Metadata must be Symbol,Keyword,String or Map

19:21 gfrlog: haha

19:21 TimMc: Shoot, we can't pull metadata like that in 1.2

19:23 Time to check out the reader macro page.

19:24 ,(+ \* \*)

19:24 clojurebot: java.lang.ClassCastException: java.lang.Character cannot be cast to java.lang.Number

19:24 TimMc: dammit

19:24 gfrlog: it's tough

19:24 TimMc: ::*

19:24 ,::*

19:24 clojurebot: :sandbox/*

19:24 TimMc: bingo?

19:25 gfrlog: lol

19:25 TimMc: Nah, still can't iterate over that.

19:25 I want to extract chars.

19:25 gfrlog: it's something new at least

19:25 we can get at least two papers out of that

19:26 TimMc: haha

19:26 gfrlog: even if you could get some chars, could you do anything with them?

19:27 TimMc: regex... can we call/iterate on those?

19:27 gfrlog: prolly not...

19:27 ,(#" " "tommy")

19:27 clojurebot: java.lang.ClassCastException: java.util.regex.Pattern cannot be cast to clojure.lang.IFn

19:27 TimMc: Oh man, we can't even use %2

19:28 brb, pasta

19:28 gfrlog: oh dangit pasta

19:31 TimMc: Can you think of anything that will stringify stuff?

19:31 ...and we don't have macros.

19:32 gfrlog: more generally seqifying would be nice

19:33 TimMc: we have... syntax quote and unquote, including splicing unquote

19:34 gfrlog: but no syntax to give it :)

19:37 what about non-alphanumeric variables? definitely not allowed?

19:37 TimMc: hmm?

19:37 clojurebot: hmm, maybe my repl is out of wack

19:37 gfrlog: wait a minute they're definitely allowed

19:37 what am I talking about

19:37 we can do lambda calc

19:37 no we can't

19:38 cuz we can't write 'fn'

19:38 nevermind

19:38 TimMc: We can do Church numerals, though.

19:38 And regular ones. :-P

19:39 gfrlog: how?

19:39 clojurebot: with style and grace

19:39 hiredman: gfrlog: http://en.wikipedia.org/wiki/SKI_combinator_calculus

19:40 gfrlog: hiredman: ah ha, I think you've sent me here before

19:40 I still don't think we can do anything interesting without nested fns

19:40 TimMc: gfrlog: ##(* (+ (*)(*)(*)) (+ (*)(*)) (+ (*)(*)(*)(*)(*)(*)(*)))

19:40 sexpbot: ⟹ 42

19:41 gfrlog: yeps

19:43 hiredman: λ expressions can be transformed into combinators, infact I believe the wiki gives an algorithm for such a transform

19:44 gfrlog: TimMc: I thought I had even blogged that exact expression, but it seems not

19:44 hiredman: we don't need nested fns for that?

19:44 TimMc: currying might be possible

19:45 hiredman: "next fns"

19:45 combinators don't have fns

19:45 nested

19:46 nested fns doesn't seem to mean anything unless you'd care to define it

19:46 gfrlog: sorry

19:46 (fn [a] (#(% %) a))

19:46 i.e., a fn in the body of another fn

19:47 hiredman: in a combinator calculus you generally just have combinators, like in a pure λ calculus you just have λ forms (and build numbers out of them)

19:47 so no λ in the combinator calculus and so no nested fns

19:47 gfrlog: I think it will take me more than some moments to digest the article

19:49 devn: TimMc: please explain how the hell that worked

19:49 the (* (+ (*)(*)...)

19:49 hiredman: ,(+)

19:49 clojurebot: 0

19:49 hiredman: ,(*)

19:49 clojurebot: 1

19:49 gfrlog: ,(/)

19:49 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-SLASH-

19:49 gfrlog: ,(-)

19:49 clojurebot: java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-

19:49 TimMc: devn: Identity rules.

19:49 hiredman: gfrlog: I thought you were busy reading the article

19:50 gfrlog: hiredman: I've put it off because my wife just about has dinner ready. So please don't wait on me.

19:50 * TimMc foods

19:50 devn: hmph -- ##(*)

19:50 sexpbot: ⟹ 1

19:50 devn: weird.

19:50 gfrlog: hiredman: there are chicken tacos I think.

19:51 devn: I guess I still don't see how it follows that * with no args constitutes 1

19:52 gfrlog: devn: it doesn't have to be that way, but it makes the definition a bit shinier

19:52 devn: ,(+ (*) (*))

19:52 clojurebot: 2

19:52 devn: gfrlog: shiny in what sense?

19:52 hiredman: devn: (= (* x 1) x)

19:53 gfrlog: devn: 0 is the additive identity, 1 is the multiplicative identity

19:53 devn: it lets you define them recursively

19:54 devn: does (+) == 0 make sense to you?

19:55 * gfrlog off to dinner

19:55 devn: gfrlog: yes

19:55 (+) makes sense

19:56 (*) not so much

19:56 hiredman: why?

19:56 clojurebot: why not?

19:56 devn: nevermind, hiredman explained it well -- just needed to meditate for a moment on that

19:56 hiredman: clojurebot: I know where you live

19:57 clojurebot: Titim gan éirí ort.

19:57 devn: hiredman: because for my entire life * has been between two values, otherwise it was invalid

19:57 so when I see *, i do not assume (* something 1)

19:57 TimMc: SOmething with %& could give us currying or multi-arg fns

20:02 ,(#(* (% (+)) (% (+(*))) (% (+(*)(*)))) [11 5 3])

20:02 clojurebot: 165

20:02 TimMc: \o/ Multiarg functions.

20:05 devn: It's the same as why 5^0 is 1. :-)

20:08 amalloy: TimMc: that's a cute way to get multiple args

20:09 gfrlog: TimMc: NICE

20:12 TimMc: So we can do some destructuring that way.

20:12 This gives us lambda calc, yeah?

20:14 What if we passed around a large vector of functions as the first arg to every function, and explcitly pulled them out by number for use?

20:15 hiredman: λ calculus doesn't have vectors, or numbers in vectors or + or *

20:15 TimMc: hiredman: Sure, but we can emulate it now.

20:15 amalloy: &(#(% (*)) #(+ % (*)))

20:15 sexpbot: ⟹ 2

20:16 amalloy: TimMc: higher-order functions^

20:16 TimMc: But we still don't have binding. I think my big ol' vector approach is as close as we can get. :-(

20:16 hiredman: TimMc: all you need to emulate the λ calculus is SKI

20:17 you just have to apply the transform

20:22 technomancy: clojurebot: tell me about church numerals

20:22 clojurebot: Pardon?

20:47 gfrlog: I'm glad to see I inspired so much productivity

20:48 malkomalko: for the peeps who use paredit, I can't find any docs on wrapping []'s.. say I have [1 2 3] I can't figure out how to make this [[1 2 3]] since everytime I open up a bracket it auto closes it

20:49 brehaut: malkomalko: C-right inside a [] will make it capture the next expression on the right

20:49 devn: ,````''(+)

20:49 clojurebot: (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/seq)) (clojure.core/list (clojure.core/seq (clojure.core/concat # # #)))))

20:50 TimMc: Whoa, what are those #'s doing in there?

20:50 gfrlog: and why are there 3 different function calls?

20:50 TimMc: Recursion exceeded in printing?

20:50 gfrlog: all alternating and stuff...

20:50 &````''(+)

20:50 sexpbot: ⟹ (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/seq)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/concat)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/li... failed to gist: Connection reset

20:50 gfrlog: &````''(+)

20:50 sexpbot: ⟹ (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/seq)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/concat)) (clojure.core/list (clojure.core/seq (clojure.core/concat (clojure.core/li... failed to gist: Connection reset

20:51 gfrlog: clojurebot: plug sexpbot back in

20:51 clojurebot: Counterclockwise aka ccw at http://code.google.com/p/counterclockwise/

20:51 pjstadig: i don't think clojurebot acknowledges sexpbots existence

20:53 gfrlog: ,(println "Say I'm pretty! ##(printlin \"Even if I don't mean it?\")")

20:53 clojurebot: Say I'm pretty! ##(printlin "Even if I don't mean it?")

20:53 sexpbot: java.lang.Exception: Unable to resolve symbol: printlin in this context

20:53 pjstadig: &(partition 0 [])

20:53 sexpbot: ⟹ ()

20:55 gfrlog: somebody needs to alter one of the bots so that we're sufficiently motivated to construct a boomerang quine

20:57 TimMc: pjstadig: Pretty sure the bots do not explicitly ignore each other.

20:57 pjstadig: &(partition 0 [:a])

20:57 sexpbot: Execution Timed Out!

20:57 TimMc: ,(str \# \# "(+ 1 2)")

20:57 clojurebot: "##(+ 1 2)"

20:57 sexpbot: ⟹ 3

20:57 TimMc: pjstadig: ^

20:58 pjstadig: TimMc: i was speaking metaphorically

20:58 TimMc: heh

20:58 gfrlog: I just realized these bots are open source

20:58 pjstadig: in my mind they are feuding with each other

20:58 TimMc: Now, getting it to go the other way is a challenge. I don't think I've been able to get clojurebot to respond to sexpbot, partly because clojurebot doesn't have an inline eval trigger, and partly because sexpbot prefixes its responses.

20:58 $source

20:58 sexpbot: Source not found.

20:58 TimMc: source?

20:58 clojurebot: source is http://github.com/hiredman/clojurebot/tree/master

20:59 TimMc: &source

20:59 sexpbot: java.lang.Exception: Unable to resolve symbol: source in this context

20:59 TimMc: nvm

20:59 gfrlog: TimMc: I'm looking at patching one or the other

20:59 pjstadig: sexpbot blames clojurebot for the evils that his family perpetrated against his ancestors

20:59 and clojurebot looks down on sexpbot as an inferior being

21:00 the tension is building toward an epic battle

21:00 gfrlog: clojurebot is hard to run

21:00 let's see if Raynes can do better

21:01 ah, lein instead of ant. That's a start.

21:02 hiredman: clojurebot is built with lein, and runs by pointing the uberjar at a config file (example in repo)

21:02 gfrlog: hiredman: what happened when I did 'ant' then?

21:03 I looked at the readme and it mentioned tricky policy files -- will it run w/o sandbox by default?

21:03 hiredman: gfrlog: who told you to run ant?

21:03 gfrlog: hiredman: I saw a build.xml=

21:03 hiredman: so?

21:03 gfrlog: they scream "run ant!" at me

21:04 aw...the sexpbot build failed. Back to hiredman's idea

21:04 technomancy: that's funny, they scream "run away" to me

21:04 buuuuuurn

21:04 gfrlog: technomancy: as I always refer to myself in the third person as "ant", that's exactly what I just said

21:05 technomancy: o_O

21:06 gfrlog: or maybe I meant that "build.xml" files always refer to me as "ant"...or...never mind

21:06 pjstadig: your codez talk to you?

21:07 gfrlog: no, just project maintenance files

21:07 okay, I was confused and clojurebot is the one that failed to resolve deps

21:07 hiredman: gfrlog: you must be doing it wrong

21:08 gfrlog: hiredman: likely; I did "lein deps"

21:08 hiredman: sounds wrong to me

21:10 gfrlog: lein uberjar says it is missing conduit-irc jar

21:11 TimMc: gfrlog: With [^0-9a-z], can you get me the first element of a list?

21:11 gfrlog: TimMc:

21:11 um

21:11 there's no way to destructure is there :(

21:12 TimMc: I'm trying to convert it into a vector or something, or maybe apply to a fn.

21:12 gfrlog: I'm skeptical

21:13 TimMc: Can't index into a list either.

21:13 gfrlog: I just don't think clojure was built for these tasks

21:13 ah, cause the vector gives you indexing

21:13 right-

21:15 pjstadig: ,([:first :second] (+))

21:15 clojurebot: :first

21:15 TimMc: Javaswcript is way better at this: http://sla.ckers.org/forum/read.php?24,32930

21:16 gfrlog: holy cow

21:16 TimMc: :-)

21:17 gfrlog: TimMc: would you happen to have a ruby 1.9.2 prompt lying around?

21:17 TimMc: dunno

21:18 1.8

21:18 gfrlog: oh well

21:18 I haven't figured out something that works for 1.8 yet

21:18 TimMc: Same with the server at school.

21:18 ,`(~@"$\"#")

21:18 clojurebot: (\$ \" \#)

21:19 TimMc: I can take apart strings...

21:19 gfrlog: O_O

21:19 TimMc: oh!

21:20 ,`[~@```!]

21:20 clojurebot: [clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote sandbox/!)))]

21:20 TimMc: ,(`[~@```!] (+))

21:20 clojurebot: clojure.core/seq

21:20 TimMc: ...but that's still a symbol

21:20 gfrlog: `[~@"$\"#"]

21:20 ,`[~@"$\"#"]

21:20 clojurebot: [\$ \" \#]

21:21 TimMc: ,(eval "#=(+ 2 3)")

21:21 clojurebot: DENIED

21:21 TimMc: ,(read-string "#=(+ 2 3)")

21:21 clojurebot: java.lang.RuntimeException: java.lang.Exception: EvalReader not allowed when *read-eval* is false.

21:21 gfrlog: ,(eval "(eval \"#=(+ 2 3)\")")

21:21 clojurebot: DENIED

21:22 gfrlog: if we wrap it enough times it's gotta work eventually

21:23 hiredman: you understand eval doesn't take strings?

21:23 gfrlog: I do

21:23 TimMc: hiredman: Oh hah, right...

21:23 gfrlog: $google slartibartfast

21:23 sexpbot: First out of 17700 results is: Slartibartfast - Wikipedia, the free encyclopedia

21:23 http://en.wikipedia.org/wiki/Slartibartfast

21:24 hiredman: gfrlog: actions indicate otherwise

21:24 gfrlog: hiredman: and so it goes

21:24 TimMc: ,`*#

21:24 clojurebot: *__4879__auto__

21:26 gfrlog: the only reason I was able to get alphanumerics into ruby was the string ranges

21:26 malkomalko: brehaut: C-right didn't seem to do anything inside a [1 2 3]

21:26 TimMc: malkomalko: [|][1 2 3]

21:26 then C-right

21:27 Or try C-left where you are now

21:28 ,(`[~@`#(5)] (+))

21:28 clojurebot: fn*

21:28 malkomalko: hmm, weird, isn't working

21:28 will check to see if I have an older plugin or something

21:28 gfrlog: holy jackwagon

21:28 TimMc: malkomalko: You're in both paredit and clojure-more?

21:28 malkomalko: yes

21:29 TimMc: malkomalko: Try C-h k C-right

21:29 gfrlog: TimMc: can we make fns out of that?

21:29 TimMc: It should tell you that's paredit-slurp-forward or whatever.

21:29 gfrlog: We can make syntax, but we can't eval.

21:30 gfrlog: hrmph

21:30 TimMc: If you allowed a single "eval" we could do whatever.

21:30 Can we resolve a symbol to a value?

21:30 malkomalko: yah it doesn't... I'll check my .emacs, although I didn't really do anythin gwith it

21:31 gfrlog: TimMc: can you get a 'eval somehow?

21:31 TimMc: gfrlog: How would that help?

21:31 gfrlog: I have no idea

21:33 TimMc: Given a symbol, can we get a var? vars can be derefed.

21:33 gfrlog: ,#'+

21:33 clojurebot: #'clojure.core/+

21:33 TimMc: ,(type @#'str)

21:33 clojurebot: clojure.core$str

21:33 gfrlog: ,#(first ['+])

21:33 clojurebot: #<sandbox$eval4888$fn__4889 sandbox$eval4888$fn__4889@549ed0>

21:34 tomoj: note that barfs and slurps have arrow-key-less bindings by default as well

21:37 gfrlog: is (apply partial (repeat partial)) an infinite-order function?

21:38 TimMc: I think I've almost got soemthing...

21:39 Shit, no.

21:39 ,(apply partial (repeat partial))

21:39 clojurebot: #<core$partial$fn__3684 clojure.core$partial$fn__3684@1a00355>

21:40 TimMc: ,((apply partial (repeat partial)) 5)

21:40 clojurebot: #<core$partial$fn__3684 clojure.core$partial$fn__3684@487600>

21:40 TimMc: haha

21:40 It will absorb infinitely many arguments!

21:41 gfrlog: TimMc: well any function can take an infinite number of args

21:41 but it will keep returning functions, right?

21:41 TimMc: ,(trampoline (apply partial (repeat partial)))

21:41 clojurebot: java.lang.StackOverflowError

21:42 TimMc: *infinitely many calls

21:42 gfrlog: clever

21:43 if I said "boomerang quine" recently, I probably meant "trampoline quine"

21:43 TimMc: ,`@(var ~'eval) ; if we had eval, we could get eval :-P

21:43 clojurebot: DENIED

21:43 TimMc: ,`@(var ~'str) ; huh

21:43 clojurebot: (clojure.core/deref (var str))

21:43 gfrlog: ah, that's the missing piece

21:44 mec: ,(fn forevar [& args] forevar)

21:44 clojurebot: #<sandbox$eval4900$forevar__4901 sandbox$eval4900$forevar__4901@583f4c>

21:44 mec: ,(trampoline (fn forevar [& args] forevar))

21:44 clojurebot: Execution Timed Out

21:44 gfrlog: mine actually keeps the args, doesn't it?

21:44 mec: orly

21:45 gfrlog: so it'd run out of memory if it had an infinite stack?

21:45 mec: i think so

21:45 TimMc: ,(loop [] (recur))

21:45 gfrlog: BORING

21:45 clojurebot: Execution Timed Out

21:46 mec: ok i see why mine times out instead of stack overflow, but why does the partial overflow

21:46 TimMc: ,(time (loop [] (recur))) ##(time (loop [] (recur)))

21:46 sexpbot: Execution Timed Out!

21:46 clojurebot: Execution Timed Out

21:46 brehaut: ,(first (take-while (constantly true) (drop-while (constantly true) (range))))

21:46 TimMc: Oh duh, of course timing wouldn't work.

21:46 clojurebot: Execution Timed Out

21:47 TimMc: brehaut: Now with juxt!

21:48 brehaut: haha not today

21:48 gfrlog: ,(count range)

21:48 clojurebot: java.lang.UnsupportedOperationException: count not supported on this type: core$range

21:48 gfrlog: ,(count (range))

21:48 clojurebot: Execution Timed Out

21:48 mec: ,(count (range 1 10))

21:49 clojurebot: 9

21:49 TimMc: gfrlog: Can we get any alphanumeric char?

21:50 gfrlog: doubt it

21:50 I'm the skeptic in this endeavor

21:50 TimMc: I haven't been able to use math on chars.

21:50 tomoj: is it disallowed to use chars?

21:51 TimMc: tomoj: We're trying to do it without using alphanumerics in the code at all.

21:51 With that restriction, we can get lambda calculus, rational numbers, and some symbols and keywords.

21:52 tomoj: I see

21:52 TimMc: If we can figure out how to convert a symbol into the corresponding var's value, we'll probably win.

21:53 win = arbitrary code

21:53 gfrlog: arbitrary code = win

21:54 I wonder how the sandboxes would react

21:54 tomoj: wtf is that (`[~@`#(5)] (+))

21:55 gfrlog: he creates a vector

21:55 tomoj: oh

21:55 gfrlog: then pulls out the index-0 element

21:55 tomoj: I forgot (+) is 0

21:55 gfrlog: the ~@ turns something into a seq

21:55 TimMc: the 5 is random junk

21:56 gfrlog: the 5 stands for the 6th church numeral

21:56 TimMc: :-P

21:56 tomoj: won't you need another approach besides building resolve, for special forms?

21:57 or do you think you can use special forms somehow if you have resolve?

21:57 TimMc: I don't think we need special forms.

21:57 gfrlog: I think he's trying to get a reference to eval

21:57 mec: ,(+ (*) (*))

21:57 clojurebot: 2

21:57 TimMc: exactly

21:58 mec: ##(* (+ (*)(*)(*)) (+ (*)(*)) (+ (*)(*)(*)(*)(*)(*)(*)))

21:58 sexpbot: ⟹ 42

21:58 mec: nice

22:00 gfrlog: TimMc: can you get a float?

22:00 mec: (/ (*))

22:00 (/ (+ (*)(*)))

22:00 TimMc: mec: We can get rationals.

22:00 mec: ,(/ (+ (*)(*)))

22:00 clojurebot: 1/2

22:01 TimMc: I think I can get many letters. \c, \o, \n, \a, \t, \s, \e, \q, \v, \r

22:01 No, wait... I can't stringify yet.

22:03 I can get symbols containing those letters, though.

22:03 mec: too bad (+ "" (*)) doesnt work

22:04 gfrlog: ,(.nextProbablePrime 1234567890987654321)

22:04 clojurebot: java.lang.ExceptionInInitializerError

22:05 not-timm1: ooh, my main connection is lagging

22:09 TimMc: I'm trying to figure out if Java-land can help us, but all the Java method names have alphanumerics in them.

22:10 tomoj: and . is special :1

22:10 TimMc: tomoj: No problem, it isn't alphanumeric.

22:11 Now, if String just happened to have a useful _BANG_ method or something... :-P

22:11 tomoj: I mean, even if you can make symbols like, say, maybeResolveIn, you can't use them with .

22:11 because it's special

22:11 or maybe you can, but I don't see how

22:11 TimMc: ,("" ! (+))

22:11 clojurebot: java.lang.Exception: Unable to resolve symbol: ! in this context

22:11 TimMc: ,(. "" ! (+))

22:11 clojurebot: java.lang.IllegalArgumentException: No matching method found: _BANG_ for class java.lang.String

22:12 TimMc: Like that.

22:12 tomoj: eh?

22:14 TimMc: Oh, I see what you're saying... yeah, it would have to be something we could write literally.

22:15 gfrlog: k my day is over

22:15 I hope this comes to a happy conclusion

22:16 * gfrlog exits stage front

22:22 TimMc: OK, so if anybody can figure out a way to stringify keywords and symbols using what we have so far, I will give them a cookie.

22:23 flea__: Hello

22:23 TimMc: ,(ancestors (type :foo))

22:23 clojurebot: #{java.io.Serializable clojure.lang.Named java.lang.Runnable clojure.lang.IFn java.util.concurrent.Callable java.lang.Object :clojure.contrib.generic/any java.lang.Comparable}

22:24 flea__: ,(1 2 3)

22:24 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

22:24 flea__: `oic

22:25 I just wanted to say that this project is kind of mind boggling

22:25 you effectively rewrote lisp, a language with macros and closures, in Java, which has neither ...

22:27 tomoj: is your lisp macros and closures all the way down?

22:27 flea__: like turtles?

22:27 pdk: we're just plain magic

22:28 flea__: you are indistinguishable from magick

22:29 i assume that clojure supports full lambda syntax?

22:29 TimMc: flea__: All Lisps are implemented in machine code at some level.

22:30 ,(let [foo (fn [x y] (+ x y))] (foo 4 5))

22:30 clojurebot: 9

22:30 flea__: ,`(a list test)

22:30 clojurebot: (sandbox/a clojure.core/list clojure.core/test)

22:31 TimMc: flea__: Clojure is a lisp http://clojure.org/lisp -- and here are some differences between it and some others: http://clojure.org/lisps

22:32 pdk: note also that , is whitespace in clojure

22:32 ~ and ~@ respectively take the role that , and ,@ had in cl

22:32 clojurebot: add-classpath is Fraught with Peril!

22:33 flea__: oic

22:33 is ` still quote ?

22:33 TimMc: syntax-quote yeah

22:33 and ' is non-namespace-resolving quote

22:33 ,'juxt

22:33 clojurebot: juxt

22:34 TimMc: ,`juxt

22:34 clojurebot: clojure.core/juxt

22:34 TimMc: The second link I gave you is pretty thorough regarding stuff like that.

22:34 flea__: reading through it now

22:35 TimMc: The difference that really threw me is that clojure's let is like Scheme's let*.

22:35 pdk: i only really studied cl

22:35 flea__: I don't know scheme

22:35 only cl

22:35 pdk: so do tell about what makes scheme let* unique

22:35 iirc cl let* simply allowed symbols referring to each other

22:35 TimMc: pdk: Scheme's `let` binds in parallel, but `let*` binds in series.

22:36 pdk: ie (let* (a (+ b 1) b 5)) sorta stuff

22:36 hm

22:36 isn't it basically the same in cl but in reverse

22:36 with let* being parallel

22:36 criminy now i even forget cl let syntax

22:36 TimMc: Sort of. let* in Clojure is a helper macro. I think it doesn't have destructuring.

22:37 pdk: should it be (let* (a (1+ b) b 5))

22:37 TimMc: It's an unfortunate coincidence of naming for beginners.

22:37 pdk: criminy i didnt know let* carried over

22:37 ,(let [a (inc b) b 5] a)

22:37 clojurebot: java.lang.Exception: Unable to resolve symbol: b in this context

22:37 pdk: ,(let* [a (inc b) b 5] a)

22:37 clojurebot: java.lang.Exception: Unable to resolve symbol: b in this context

22:37 pdk: ACCURSED BOT

22:38 TimMc: Naw, you can't do that.

22:38 b isn't bound when a's init-expr is eval'd

22:38 pdk: granted!

22:39 flea__: does let still return a closure?

22:39 TimMc: You could do that with letrec if there was delayed evaluation, such as being a reference inside a closure.

22:39 mec: where is let* even defined in clojure?

22:39 TimMc: flea__: ##(macroexpand `(let [a 1] a))

22:39 sexpbot: ⟹ (let* [clojure.core/a 1] clojure.core/a)

22:40 pdk: criminy

22:40 so little lets so little time

22:40 let can still do closures flea

22:40 TimMc: mec: flea__: Hard to say. I think let* is actually a compiler form.

22:40 $source let*

22:40 sexpbot: Source not found.

22:41 TimMc: https://github.com/clojure/clojure/blob/1.2.x/src/jvm/clojure/lang/Compiler.java#L41

22:42 Yeah, it's a compiler form.

22:43 amalloy: flea__: "does let still return a closure" is a weird question. in any lisp, you can implement let by using a closure behind the scenes, but to say that it returns a closure would be misleading

22:43 tomoj: TimMc: must it start from clojure.core?

22:43 i.e. if you want something else, you've gotta figure out how to require it without alphanums?

22:44 TimMc: tomoj: I think that's the idea, yeah.

22:44 amalloy: tomoj: if that restriction didn't exist it would be trivial

22:44 TimMc: amalloy: Would it?

22:44 amalloy: def everything you need in some other library, then require it

22:44 tomoj: naturally there could be other restrictions

22:45 like "only core/contrib" or "only core" (which is not really the same as "only clojure.core" I think)

22:45 TimMc: amalloy: Do you think there's anything in clojure.contrib that would help, for instance?

22:45 amalloy: *shrug*

22:48 flea__: amalloy: isn't the body-form of let a closure?

22:49 ,(let ((x 10) (y 12)) (list x y))

22:49 clojurebot: java.lang.IllegalArgumentException: let requires a vector for its binding

22:49 flea__: oO

22:49 ic

22:50 mec: ,(let [x 10 y 12] [x y])

22:50 clojurebot: [10 12]

22:50 flea__: that returns a vector

22:51 mec: its normal to use vectors instead of lists for data

22:51 flea__: ,(let [x 10 y 12] (list [x] [y]))

22:51 clojurebot: ([10] [12])

22:51 flea__: :)

22:54 TimMc: flea__: let has a body of 0 or more expressions. There's an implicit "do" form around the expressions.

22:54 ,(let [x 5] (println "x is" x) (* 2 x))

22:54 clojurebot: x is 5

22:54 10

22:55 flea__: :/

22:55 TimMc: Oh hey, will any Boston-area Clojurians be at the BarCamp this weekend?

22:56 flea__: ,(setf a 10)

22:56 clojurebot: java.lang.Exception: Unable to resolve symbol: setf in this context

22:56 flea__: o

22:57 that's .... interesting

22:57 ,(mapcar)

22:57 clojurebot: java.lang.Exception: Unable to resolve symbol: mapcar in this context

22:58 flea__: I should download and have a play

22:59 TimMc: flea__: You'll probably want the Leiningen build tool. It's got a REPL command so you don't have to screw with classpath.

23:00 Also, I highly recommend clojuredocs.org

23:01 pdk: you don't say car/cdr in clojure cause lists aren't actually implemented with conses internally anymore

23:01 ataggart: ,(map inc [1 2 3])

23:01 clojurebot: (2 3 4)

23:01 pdk: but cons can still compose lists much in the way it used to

23:01 iirc clojure map = cl mapcar

23:01 and all the clojure builtin data structures are immutable and persistent

23:01 so there isn't really a mapcan :p

23:04 TimMc: flea__: Clojure abstracts the ideas of lists and lambdas past what Lisps generally have.

23:04 Instead, you have these generic first, rest, conj functions for sequences and collections. Also, many things can be used as functions. :-)

23:04 pdk: clojure prefers first/rest/next instead of car/cdr

23:05 ,(doc next)

23:05 clojurebot: "([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil."

23:05 pdk: ,(doc rest)

23:05 clojurebot: "([coll]); Returns a possibly empty seq of the items after the first. Calls seq on its argument."

23:05 flea__: ,(doc set)

23:05 clojurebot: "([coll]); Returns a set of the distinct elements of coll."

23:06 flea__: so how do I setf?

23:06 pdk: you don't

23:06 mec: if you want a good in depth but beginner friendly intro i suggest http://java.ociweb.com/mark/clojure/article.html

23:06 pdk: symbols defined with def are also immutable unless you just def them again

23:07 if you want to store something and use it in a way that lets you treat it like it's mutable then you'd store it in an agent/atom/ref

23:08 flea__: so lists are not mutable?

23:08 TimMc: flea__: Right.

23:08 None of the native Clojure data structures are, except for the reference types.

23:09 brehaut: TimMc, flea__: (and transients)

23:09 TimMc: Oh, there are transients, but those are a different topic.

23:09 flea__: ,(doc push)

23:09 clojurebot: Excuse me?

23:09 pdk: the reference types each work in slightly different ways to ensure atomic updates and thread safety

23:09 transients basically exist for xtreme optimizing and java interop iirc

23:09 mec: ,(let [x [1 2 3]] [x (conj x 4) x])

23:09 clojurebot: [[1 2 3] [1 2 3 4] [1 2 3]]

23:10 flea__: ,(doc remove-if)

23:10 clojurebot: It's greek to me.

23:10 flea__: lol

23:10 mec: ,(doc filter)

23:10 clojurebot: "([pred coll]); Returns a lazy sequence of the items in coll for which (pred item) returns true. pred must be free of side-effects."

23:10 pdk: filter and remove are the closest to remove-if

23:10 filter keeps everything for which the predicate is true

23:10 remove keeps everything for which the predicate is false

23:11 flea__: ,(filter 1 (list 1 2 3))

23:11 clojurebot: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

23:11 pdk: dunno what you mean by filter 1 there

23:11 flea__: ok, so the basic collection is a vector, not a list, right?

23:12 pdk: if you mean filtering the ones that are equal to 1

23:12 flea__: sry

23:12 pdk: realistically you have 4 basic collection types :p

23:12 sequences exist as an abstraction over all four basically

23:12 flea__: ok

23:13 pdk: ,(next {1 2 3 4})

23:13 clojurebot: ([3 4])

23:13 pdk: ,(next #{1 2 3 4})

23:13 clojurebot: (2 3 4)

23:13 pdk: right there using sequence functions on maps (hash tables) and sets

23:13 so they still support iteration with functions that work on sequences

23:14 also without cons cells being used in the backend there are no dotted lists anymore

23:15 flea__: ,(filter #'(lambda(x) (= 1 x)) #{1 2 3})

23:15 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.Symbol

23:16 pdk: lambda is replaced with fn

23:16 amalloy: &(filter #(= 1 %) [1 2 3])

23:16 sexpbot: ⟹ (1)

23:16 pdk: # is used as a shorthand syntax for anonymous fns

23:16 amalloy: &(filter (fn [x] (= 1 x)) [1 2 3])

23:16 sexpbot: ⟹ (1)

23:16 amalloy: &(filter #{1} [1 2 3])

23:16 sexpbot: ⟹ (1)

23:16 TimMc: flea__: Argument lists use vector syntax.

23:16 pdk: also the argument list for a function or macro is a vector instead of a list

23:17 so (fn [x] (= 1 x)) is what you're thinkin of

23:17 or #(= 1 %), or #{1}, or (partial = 1) etc etc etc :p

23:17 TimMc: flea__: You might want to watch rhickey's presentation of Clojure at a Lisp conference -- he does a great job of explaining the abstractions.

23:18 flea__: got url?

23:18 pdk: i think clojure.blip.tv should have them

23:18 * flea__ does a youtube search

23:20 flea__: found a bunch of videos on YT

23:21 mec: clojure for lisp programmers part 1: http://clojure.blip.tv/file/1313398/ part 2: http://clojure.blip.tv/file/1313503/

23:21 flea__: thanks mec

23:22 mec: also some good ones here http://www.infoq.com/author/Rich-Hickey

23:22 flea__: looks like I have a busy afternoon :)

23:23 mec: i could watch infoq all day long, and some days i have ;p

23:23 flea__: lol

23:29 ataggart: "Are We There Yet" is a great talk

23:29 tomoj: unrelated awesome infoq: http://www.infoq.com/presentations/Searching-Without-Objectives

23:31 mec: how the jvm jit works and how current cpus work are good ones, no idea where they were tho

Logging service provided by n01se.net