#clojure log - Dec 15 2010

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

0:04 clizzin: so python has this thing called the defaultdict which allows you to specify a default value that is returned if the given key is not found. clojure's get function allows you to do this as well, but you have to pass in the not-found value at the time you call get, whereas defaultdict allows you to specify the not-found value when you create the dict. is there a way to make a map in clojure and specify the not-found value at the time

0:04 of map creation?

0:15 amalloy: clizzin: how is that different from (fn [m default] (fn [k] (or (get m k) default)))?

0:16 i guess then it's hard to use keys, vals, assoc, etc

0:16 clizzin: amalloy: right

0:16 amalloy: you certainly could do it by implementing/proxying IPersistentMap, but that's pretty heavyweight

0:17 clizzin: if i proxy IPersistentMap, i would *only* have to proxy the get function, right?

0:18 oh, but then i'd have to play with the internals of IPersistentMap's implementation instead of using get to get the map

0:18 get the value*

0:19 amalloy: clizzin: more would be necessary. (keys foo) can't just use get

0:23 sorry, that's a silly claim, i think. it's true if you proxy IPersistentMap, but of course you'd proxy PersistentHashMap instead

0:29 clizzin: amalloy: if i proxy a java class, can i refer to clojure functions that operate on 'this', or is use of 'this' restricted to the java methods defined for that class?

0:29 technomancy: ok, time to unsubscribe to the clojure mailing list =(

0:30 got a flood of primitive hate about three months too late

0:30 or switch to digest I guess

0:31 amalloy: clizzin: you'd have to explicitly pass "this" to any subsidiary functions, i think

0:31 but i don't do a lot of proxying

0:32 clizzin: amalloy: hm, well, i think i'll just pass my not-found value down through the function calls for now and think about investigating this issue in a more involved way later. thanks for the help.

0:34 to clarify, what i'm trying to do is some naive bayes classification on document text. the log-likelihoods are stored in a map of token -> log-likelihoods, and in case i see a token i haven't seen before, i need a 'smoothing' log-likelihood. i determine this value at the time i make the map of log-likelihoods for known tokens, but the actual call for token -> log-likelihood comes later, and i didn't want to bother passing that valu

0:34 e around until that time.

0:38 amalloy: clizzin: if you're looking for lazy ways to use (abuse?) the language features, what about dynamic bindings?

0:40 clizzin: amalloy: not familiar with those, would you mind explaining further?

0:41 amalloy: ummm, i don't use them much (ever), but basically you rebind a global variable's value for the duration of a a function call, rather than within the function's lexical scope

0:43 so like (def *not-found-val* nil), then (with-bindings [*not-found-val* 10] (some-fn-that-uses-*not-found-val*))

0:49 clizzin: amalloy: oh, i see. yeah, that seems like a dirty way of going about it...i guess i prefer just passing the not-found value around.

0:54 dnolen: clizzin: you can do something like this, https://gist.github.com/741678

1:09 amalloy: dnolen: that only works if all clients are calling his get function instead of clojure.core/get; and if that's the case why not simply do (my-get [{some-map} default-val] key)? that's only a single object to pass around, and my-get can pull apart the vector for you transparently

1:11 dnolen: vectors aren't free. they also muddy up the representation at the REPL. it sounded like he wanted local behavior anyway.

4:00 LauJensen: Morning all

4:09 ejackson: salut

4:33 Licenser: morning

4:54 raek: good morning (UGT as well as CET)

5:25 ordnungswidrig: hi all

6:04 fliebel: morning

6:07 Do any of you know Haskell? And where did you learn it? I'm trying to find something that is not to basic. Most ebooks so far assume I know a little imperative and nothing more.

6:13 _ato: fliebel: I learnt it in university. They used this textbook, which isn't bad: http://books.google.com/books?id=a39QAAAAMAAJ

6:15 fliebel: _ato: This seems to be the case everywhere: "This text introduces Haskell at a level appropriate for those with little or no prior experience of functional programming."

6:16 _ato: ah yeah, it was my first properly functional language, can't help with any non-beginner stuff I'm afraid

6:17 fliebel: ok

6:19 faust45: fliebel: ask at #haskell chanel

6:20 fliebel: faust45: They pointed me at a couple, which all had a sentence like the above in the introduction. I was hoping some people who already know Cloojure had more luck in finding a suitable tut for Haskell.

6:25 mrBliss: fliebel: I used Real World Haskell, but I suppose some of the guys in #haskell will probably have suggested this one too.

6:35 ejackson: fliebel: I'm currently reading "Learn you Haskel for great good" and its totally fine

6:35 the "Gentle Introduction to Haskel 98" is also good to get a terse view

6:35 terse as in: monads rear up by page 10 I think

6:38 sadly the combinatorics of "Language X for Y programmers" is prohibitive :)

6:48 * raek just discovered that derive for a custom hierarchy returns a new one, rather than changes it

6:54 fliebel: ejackson, mrBliss: Thanks, Those are exactly which where suggested to me. I think I'll stick to LYAH.

7:26 mduerksen: /help

7:27 sorry

7:49 TobiasRaeder: hey :)

7:49 can anyone tell me why map doesn't seem to use thread-local bindings?

7:51 cemerick: TobiasRaeder: map's results are realized lazily, so your bindings are probably gone by the time it's consumed its input seqs. You'll want to wrap the map call with doall. See http://cemerick.com/2009/11/03/be-mindful-of-clojures-binding/ for more discussion.

7:52 TobiasRaeder: @cemerick ah, thanks a ton. really makes sense

7:53 GOSUB: cemerick: The whole office is watching your deployment video now. Thanks for that!

7:55 cemerick: whoa

7:55 GOSUB: I guess I'm on the hook now, huh? ;-)

7:56 GOSUB: cemerick: completely ;)

7:56 fliebel: cemerick: Your pallet vid is live?

7:57 cemerick: fliebel: no, GOSUB is referring to my screencast post

8:02 LauJensen: fliebel: Just google for 'epic deployment' :)

8:02 fliebel: I believe sexpbot can do that for me...

8:02 $google epic deployment

8:02 sexpbot: First out of 54500 results is: Web Deployment - Epic Games Forums

8:02 http://forums.epicgames.com/showthread.php%3Ft%3D706732

8:03 fliebel: $google epic deployment clojure

8:03 sexpbot: First out of 77 results is: Continuous Deployment of Clojure Web Applications: Clojure Conj ...

8:03 http://cemerick.com/2010/11/02/continuous-deployment-of-clojure-web-applications/

8:04 GOSUB: woohoo!

8:07 cemerick: $google epic clojure

8:07 sexpbot: First out of 1320 results is: Continuous Deployment of Clojure Web Applications: Clojure Conj ...

8:07 http://cemerick.com/2010/11/02/continuous-deployment-of-clojure-web-applications/

8:08 * cemerick is all that is epic about clojure, apparently

8:13 GOSUB: (swap! cemerick inc)

8:14 raek: (inc cemerick)

8:14 sexpbot: ⟹ 1

8:14 GOSUB: (inc cemerick)

8:14 sexpbot: ⟹ 2

8:14 GOSUB: hmm.

8:14 fliebel: Not a much used feature of sexpbot it seems. Evey time I tried, it returned 1.

8:15 cemerick: I don't think it's persisted. I was up to 3 at some point.

8:15 GOSUB: (inc cemerick)

8:15 sexpbot: ⟹ 3

8:16 fliebel: Maybe someone did (dec cemeric) a few times? No, can't be...

8:17 cemerick: haters gonna hate :-P

8:18 fliebel: cemerick: I don't understand that sentence… And btw, it does seem to be persisted: https://github.com/Raynes/sexpbot/blob/master/src/sexpbot/plugins/karma.clj#L9

8:19 cemerick: fliebel: it's a (probably) American meme, that I can't believe I actually repeated.

8:22 * fliebel googles it

8:26 fliebel: cemerick: Uhm, did you mean I came across rude? I didn't mean to imply people (dec)'d you, quite the opposite.

8:27 cemerick: fliebel: no, you weren't rude at all. :-)

8:27 I'm sure there are some (many?) that would (dec) me, though. My comment was just me saying "oh well".

8:28 I actually discovered someone that's blocked me on twitter, which was surprising (since I'm not a spammer, etc). Apparently, I'm objectionable to at least one guy, so I'm sure there's others.

8:29 fliebel: "How wude!" - Jar-Jar Binks :P

8:29 GOSUB: fliebel: hehe

8:32 cemerick: fliebel: I think Elmer Fudd laid claim to "how wude" about 50 years before jar-jar ;-)

8:34 jweiss: anybody here use https://github.com/technomancy/durendal (or some other way of syntax highlighting clojure in slime)?

9:01 mrBliss: jweiss: https://github.com/mrBliss/dotfiles/blob/master/.emacs.d/custom-clojure.el

9:03 jweiss: mrBliss: cool, how do i use this? (sorry i'm an elisp newb) - just (load "custome-clojure.el" in .emacs?

9:05 mrBliss: jweiss: add it to your load path and (require 'custom-clojure) in your .emacs

9:05 jweiss: ok thanks

9:54 lpetit: Hello guys

9:54 ejackson: hey Laurent

9:54 lpetit: I'd like to introduce a ring based extension to my current web application, "by the back door", if you will

9:55 "by the backdoor" implies in my head : no AOT, just one or two deps in my pom.xml, and hopefully the declaration of a servlet in my web.xml, giving this servlet an init param containing the symbol name for the ring handler to use

9:55 does this make sense ? does it exist ? what would you do ?

9:56 My goal is very simple: I want to serve a server file in the most straightforward way, and thought it could be "interesting" to leverage ring's static file middleware.

9:56 I'm now listening to the ring experts :)

9:59 Not everybody at the same time pliz ;-)

10:00 jweiss: mrBliss: is there a way for me to tweak the colors in defcljface "live" without restarting emacs?

10:00 evaling w C-x C-e doesn't change the color

10:04 ejackson: lpetit: :)

10:04 lpetit: ejackson: sorry if this seems a stupid question, i'm a noob in web dev in clojure, have not followed the trend

10:04 yet

10:05 ejackson: lpetit: pah - I'm don't do web stuff either...

10:07 mrBliss: jweiss: maybe executing (tweak-clojure-syntax 'slime-repl-mode) ;; or 'clojure-mode.

10:08 ordnungswidrig: lpetit: I don't see the problem yet?

10:09 lpetit: the servlet can lookup function by the symbol / name and use that as the ring handler function and pass the request on to it

10:10 lpetit: ordnungswidrig: maybe I've missed something evident in the doc.

10:11 ordnungswidrig: lpetit: so where exactly are you struggling?

10:12 mrBliss: jweiss: What I mentioned doesn't work. If you have your own color-theme, add for instance (clojure-brackets ((t (:foreground "#ff0000")))) to it, eval the theme with C-M-x and apply it with M-x color-theme-NAME.

10:13 jweiss: mrBliss: hm. ok i'll see what i can do. i don't think i have my own theme. i just changed the default fg and bg colors for the default theme. i think.

10:14 lpetit: ordnungswidrig: from the doc, i cannot see how to do in a "good old java webapp" where I have to define and configure the servlet manually in the web.xml

10:14 ordnungswidrig: lpetit: ok, you want to reconfigure during runtime?

10:14 lpetit: the handler impl. why not, but not the number of handlers, etc.

10:14 mrBliss: jweiss: (set-face-foreground 'clojure-brackets "#ff0000") works for me

10:15 jweiss: mrBliss: ah cool thanks

10:15 ordnungswidrig: lpetit: where do you want to give the input for the reconfiguration?

10:15 lpetit: ordnungswidrig: I don't even understand the question !

10:15 ordnungswidrig: lpetit: anyways suppose there is a ref @handler containing the name of the hander function

10:15 mrBliss: jweiss: there's also (set-face-attribute 'face-name :underline t :bold t)

10:15 lpetit: I don't know the options

10:16 ordnungswidrig: lpetit: ok, use a ref to hold the desired handler, I'll paste sth...

10:16 lpetit: ok

10:16 thx!

10:20 ordnungswidrig: the missing piece (at least the idea I'm making about what the missing piece is) is an example somewhere without (run-jetty ...) at the end : a piece of clojure code, what to add in my existing web.xml (since it's a tiny addition to an existing webapp I want to do).

10:21 ordnungswidrig: lpetit: so you need to make a servlet?

10:21 lpetit: Well, as stated in my initial question ^^^, yes, somehow. But I don't want to use AOT.

10:21 ordnungswidrig: ^^

10:22 ordnungswidrig: lpetit: you'll need a AOT-compiled ring-handler-servlet which dispatches to a non-AOT-ring handler which is configurable at runtime?

10:23 bhenry: can i stop a pending future?

10:23 ordnungswidrig: bhenry: people tried and failed ;-)

10:23 bhenry: or where you refering to a clojure future?

10:23 bhenry: yes a clojure future

10:24 lpetit: ordnungswidrig: I hoped ring was already delivering such a generic servlet (plain java would be good enough), configurable via its init-param attributes in web.xml ?

10:24 jweiss: mrBliss: (set-face-attribute 'clojure-brackets :underline t :bold t) doesn't work for me

10:24 Debugger entered--Lisp error: (wrong-type-argument frame-live-p :underline)

10:24 internal-set-lisp-face-attribute(face-name nil :bold :underline)

10:24 bhenry: i was trying to test the laziness of something with a future, in hopes that i could stop the future if it wasn't as lazy as i thought, and then i wouldn't have to restart swank.

10:25 mrBliss: jweiss: (set-face-attribute 'clojure-brackets (selected-frame) :underline t :bold t)

10:25 jweiss: mrBliss: (set-face-attribute 'clojure-brackets nil :underline nil :bold t) also worked

10:26 ordnungswidrig: lpetit: i would adjust ring.util.servlet/servlet to accept an constructor function

10:26 lpetit: ordnungswidrig: I see that ring.util.servlet has the function for creating a servlet proxy to a handler

10:27 ordnungswidrig: but still, since ring.util.servlet/servlet creates a proxy at runtime, how do I reference it in my web.xml ?

10:29 ordnungswidrig: lpetit: you can only reference to a aot compile servlet in web.xml

10:30 lpetit: ordnungswidrig: I know that. But no, you can reference any .class servlet, of course, not necessarily AOT.

10:34 ok, assume I'm missing something obvious. And also let's take my AOT aversion apart for the time being. How do I go from the "use ring.util.servlet/servlet function" to "create a gen-class and AOT it so you can reference it in your web.xml" ?

10:37 ordnungswidrig: in other words, to sum up my current understanding : why should I start from ring.util.servlet/servlet and use this in my gen class, and not make-service-method ?

10:39 cemerick: lpetit: Haven't been following your discussion with ordnungswidrig, but I'd point you to http://github.com/cemerick/clojure-web-deploy-conj for just about the simplest AOT'ed and jar'ed webapp possible (just ignore the jclouds/pallet stuff if you want).

10:40 ordnungswidrig: lpetit: you simple must use defservice foo.bar/dispatcher and compile that one. then you can use foo.bar.dispatcher in web.xml as the servlet class

10:41 lpetit: cemerick: and without AOT ? wouldn't it be a great addition to have delivered with ring an already compiled-to-.class (AOT or proxy written in java, I don't care at all) generic proxy servlet ?

10:42 cemerick: this way, I could add a bit of clojure in my webapp without to introduce too much in my pom: just a dependency to ring, not also clojure-maven-plugin, which would make my little addition much more visible

10:42 cemerick: Well, it'd have to be AOT to ensure a stable name. Assuming one could get a string to that class at runtime so it could resolve your top-level handler's var, then yeah, that seems like a good idea.

10:45 lpetit: and it looks like <servlet><init-param> in web.xml is just the ticket for that. I'd post to the ring mailing list (http://groups.google.com/group/ring-clojure) with that idea. Seems like an easy way to make things easier. :-)

10:46 lpetit: cemerick: no, written in plain java could suffice. A little bit of RT.var("clojure.core", "require").invoke("'" + handlerQualifiedName.split()[1])) in the init() of the servlet for requiring the namespace of the handler, one more such line for getting an storing a Var with the service method via make-service-method, and voila , just call the Var from the service() of our generic servlet ?

10:46 cemerick: exactly, init-param, as I said ^^

10:47 * lpetit is the new AOT hater

10:47 cemerick: well, I suspect it'd be written in clojure anyway, but sure

10:56 joshua-choi: I've got a conceptual question. If you have a ref containing a big map, is it good practice to deref it as little as possible, or should I deref it whenever I want to read something in the map?

10:56 lpetit: cemerick: ok, so for the moment (here at work), I'll stick with plain java, and if time permits, tonight, suggest a contribution to the ring's group

10:59 cemerick: joshua-choi: the cost of dereferencing a ref is constant (and incredibly small)

11:00 joshua-choi: cemerick: Okay. But if I need to guarantee that a bunch of values I get are consistent with one time, then I need to use one deref, right?

11:01 cemerick: "consistent with one time"?

11:02 lpetit: joshua-choi: no, you need to do it inside a transaction

11:03 joshua-choi: lpetit: Okay, I think

11:03 ordnungswidrig: re

11:04 lpetit: joshua-choi: but of course there are functions to change the "in-transaction value" of the ref, and in the same transaction, subsequent calls will always give the the current "in-transaction value", not the value at the start of the transaction

11:05 joshua-choi: but your initial question "questions" me: if you find yourself derefencing the same thing too often, then probably you're propagating the transactional world over too much of your code.

11:06 joshua-choi: Propagating what? The var's changes?

11:06 (I'm really new to Clojure's reference; I've never really needed them until recently)

11:06 *references

11:07 jaley: hey guys! where does the quote function live? (if that's what ' is equivalent to?)

11:07 joshua-choi: jaley: It's a special form, I think

11:07 So no namespace

11:07 jaley: joshua-choi: ohhh... damn, that's why i can't pass it to map then

11:08 lpetit: ordnungswidrig: sorry for the late answer. Ok, I saw your explanation on defservice,and I now understand the full "AOT" story. But as discussed with you and cemerick, I'll post a suggestion for simplifying this scenario to the ring ml

11:08 ,(doc quote)

11:08 clojurebot: excusez-moi

11:08 lpetit: (doc quote)

11:08 clojurebot: Pardon?

11:08 lpetit: grr

11:08 jaley: lpetit: returns nil

11:08 joshua-choi: It'll just tell you to "refer to clojure.org/special_forms" anyway

11:09 lpetit: yes, it's a special form

11:10 joshua-choi: I suggest you read carefully the pages concerning refs in clojure.org. (I needed to read them several times, each word is important)

11:10 ordnungswidrig: lpetit: https://gist.github.com/847630a9e5cf25d03421

11:10 lpetit: s/pages/page/

11:10 sexpbot: <lpetit> joshua-choi: I suggest you read carefully the page concerning refs in clojure.org. (I needed to read them several times, each word is important)

11:11 joshua-choi: lpetit: Okay, thanks

11:14 ordnungswidrig: lpetit: you can then refer to "servlet" in web.xml and call set-handler-from-name to set the name of the actual handler function to use

11:14 jaley: so seeing as i can't use (map quote ...), how can i turn [x (+ 1 2)] into ['x '(+ 1 2)] easily?

11:15 sorry, forgot to quote the first vector. it's been bound to a parameter in a macro

11:15 joshua-choi: It's already quoted, but you're trying to surround it with a list with `quote

11:16 So, (map #(list `quote %) '[x (+ 1 2)])

11:19 lpetit: ordnungswidrig: thanks. I guess I still prefer an approach via init-param configuration, though.

11:19 ordnungswidrig: lpetit: yes, that is possible as well

11:20 lpetit: ordnungswidrig: and I think that by taking care of "wiring" the handler var and not the handler fn, it'll allow dynamic development even within the production server, if a nrepl server is started inside the webapp server ... ?

11:21 jaley: joshua-choi: thanks that's what i wanted

11:21 joshua-choi: No problem

11:27 ordnungswidrig: lpetit: yes, by using a var you can modify it at runtime however you want. remote repl is a lispy-way to tweak things. I would encapsule this by a function list (set-handler-fn! [f]) or (set-handler-fn-name! [name])

11:54 amalloy: &(doc quote)

11:54 sexpbot: ⟹ "Special Form: Please see http://clojure.org/special_forms#quote"

11:54 amalloy: lpetit - you seemed to be looking for this a while ago

11:57 ohpauleez: Raynes: So I've made some tweaks to your github api stuff

11:57 I have a few more I want to do, but I'll ping you when I push them to my fork and we can cut over anything you want

11:58 amalloy: ohpauleez: anything interesting? i'm using his api a little too

11:59 ohpauleez: I added label support, and updated some of the function names to the names used in the api

11:59 I'm going to update some of the dependencies

12:00 I'm writing a project metrics tool and visualizer on top of it, so I might push some of that stuff into the api repo as well

12:01 amalloy: ohpauleez: ooo. i like github's graphs. make pretty ones

12:02 ohpauleez: yeah, that's the idea. Zoomable, clickable, inspect-able network graphs

12:02 with burn down, burn up, and velocity information

12:02 "Show me all the commits related to this label, and also show me the velocity on that label split up in 1 week iterations"

12:02 amalloy: ohpauleez: i don't know what that means, but the network graph is my favorite

12:03 ohpauleez: it's how many tickets/issues are left in an iteration, how many you did in an iteration so far, and typically how many you can expect to do in an iteration

12:03 fliebel: I like the commit punchcard best, for its uselessness, and for showing the average programmer day :)

12:03 ohpauleez: burn down, burn up, velocity

12:04 haha, yeah, that is a good one

12:07 defn_: fliebel: got a link to a commit punchcard?

12:07 ive never used one

12:08 fliebel: defn_: https://github.com/pepijndevos/utterson/graphs/punch_card

12:08 Mine are all rather boring.

12:10 Ah, this one has quite a few commits: https://github.com/pepijndevos/PyMouse/graphs/punch_card

12:15 defn_: oh right! i thought you meant like a physical punchcard

12:15 fliebel: defn_: What would that do?

12:16 defn_: Add a bit of ceremony?

12:17 amalloy: fliebel: useful when running CVS on a mainframe in the 60s, maybe?

12:19 fliebel: Yea, they could be used instead of my RSA key maybe...

12:20 I have 5 of them on GitHub, while I only have 2 computers. I suspect 4 are from my laptop. One punchcard would beat them all.

12:23 defn_: You where talking about a "top secret" baker a while back. Any progress with that?

12:25 (does this graph work for anyone? it doesn't for me: https://github.com/pepijndevos/PyMouse/network)

12:28 amalloy: fliebel: weird. it's taking forever to load for me, but https://github.com/Raynes/sexpbot/network normally works and is also broken now. i'm guessing your graph is fine but something is wrong with their server

12:30 ordnungswidrig: both url stall here

13:42 Raynes: amalloy: Oh no! Not the network graph!

13:44 amalloy: Raynes: the network graph looks really simple right now. we need more branches

13:46 alexyk: what network graph are you talking about, sexpbot masters?

13:46 amalloy: alexyk: https://github.com/Raynes/sexpbot/network

13:46 alexyk: looks pretty flat to me

13:47 Raynes: I like to code in a straight line.

13:55 fliebel: Hah, beat this network graph, I did some weird things there: https://github.com/pepijndevos/utterson/network

13:56 amalloy: fliebel: see early- to mid-november on https://github.com/Raynes/sexpbot/network

13:58 fliebel: amalloy: mine has more branches and only myself.

13:59 amalloy: fliebel: only because you're not deleting old branches when you're done with them

14:00 fliebel: hm, true. So would it be flat if I deleted those?

14:00 amalloy: of course, comparing complexity of network graphs is silly. they're fun to look at, but not really a meaningful competition

14:14 LauJensen: Is there an overview of what defrecords implements vs deftype anywhere?

14:15 amalloy: You must have that memorized by now

14:17 amalloy: LauJensen: i think the difference is deftype allows you to add methods not mentioned in any superclass, and defrecord allows you to treat your object as a map? i don't use either very much

14:17 LauJensen: No no, you've got it all wrong :(

14:17 fliebel: LauJensen: I think defrecord implements PersistentHasmap?

14:17 LauJensen: defrecord is esentially a deftype, but with many standard interfaces implemented for you. Now I just want a list of those interfaces

14:18 amalloy: (filter (complement (set (supers <some defclass thing>))) (supers <some defrecord thing))?

14:19 LauJensen: bingo, thanks

14:19 (clojure.lang.IPersistentMap clojure.lang.ILookup clojure.lang.IMeta clojure.lang.IObj clojure.lang.Seqable java.lang.Iterable clojure.lang.Associative clojure.lang.IPersistentCollection java.util.Map java.io.Serializable clojure.lang.Counted clojure.lang.IKeywordLookup)

14:20 fliebel: Nice

14:35 LauJensen: Any examples floating around of how to implement java.io.Serializable? I imagined: java.io.Serializable (writeObject [this out] ....), but that throws a "Cannot implement function not in interface", according to the javadocs, the interface has both writeObject and readObject

14:35 private void writeObject(java.io.ObjectOutputStream out)

14:35 throws IOException

14:35 private void readObject(java.io.ObjectInputStream in)

14:35 throws IOException, ClassNotFoundException;

14:35

14:37 fliebel: LauJensen: I suppose you might have some luck with defrecord? https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj

14:38 LauJensen: yea its right there https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L211

14:39 requires a bit of concentration to read though

14:40 amalloy: LauJensen: serializable is a hacky "tag" interface with no methods, like cloneable

14:40 LauJensen: ?

14:41 amalloy: http://download.oracle.com/javase/1.4.2/docs/api/java/io/Serializable.html

14:41 if you have readObject and writeObject defined, the serialization library calls them magically, via reflection

14:41 is what i recall

14:42 LauJensen: So why does Clojure complain that its not in the interface which that javadoc says it is?

14:42 amalloy: LauJensen: this javadoc says it's not. there are no methods listed there

14:43 LauJensen: Im reading it wrong then

14:44 amalloy: what i'm getting at is, those are "magic" methods that aren't part of the interface from java's point of view

14:44 they're just mentioned in the docstring

14:44 compare eg http://download.oracle.com/javase/1.4.2/docs/api/java/io/ObjectOutput.html which shows what actual interface methods look like

14:45 that said, i think what you want to implement may be http://download.oracle.com/javase/1.4.2/docs/api/java/io/Externalizable.html

14:46 LauJensen: I might also be down the totally wrong trail. The problem Im seeing with my type, is if you enter its name in the repl it will blow-up. Im guessing its because its not printing correctly

14:47 amalloy: LauJensen: not sure i understand what you mean. gist?

14:47 LauJensen: (deftype mytype [fields] .........)

14:48 (def m (mytype. x y z))

14:48 user> m

14:48 ** Blow up

14:48 Where if m was a record, it would print its fields in a special format

14:50 amalloy: weird. but this doesn't look related to serialization, to me. this prints fine for me with a no-method deftype; are you implementing some methods that might be related?

14:52 LauJensen: No I dont think so. But you can clone ClojureQL yourself and exchange defrecord for deftype and see what happens

14:56 amalloy: If you clone it, eval the core.clj file, and in the repl type (table :test)

14:56 That will work for a record but try to compile/execute with a type

14:57 amalloy: LauJensen: IDeref is the culprit

14:57 LauJensen: how so ?

14:58 amalloy: https://gist.github.com/fcb633325567f677f3bd

14:58 clojure thinks it knows how to print any IDeref: you deref it, then print the thing

14:59 LauJensen: aaaha

14:59 So it assumes...

14:59 amalloy: you can define a custom print function for your type, but i don't know the details

15:00 LauJensen: got a doc, link, on it ?

15:00 amalloy: $google clojure print-dup

15:00 sexpbot: First out of 1220 results is: Serializing Clojure data structures - Lisp - Snipplr Social ...

15:00 http://snipplr.com/view/13559/serializing-clojure-data-structures/

15:01 amalloy: best i can come up with

15:01 LauJensen: thanks

15:01 Well you've outdone yourself today, thanks :)

15:02 ohpauleez: amalloy: I see you read the same thread on getopts/clargon :) you beat me too it, I was holding off until the weekend

15:02 amalloy: welcome!

15:02 ohpauleez: i was the first responder to that thread too :P

15:02 ohpauleez: Ah, I rarely look at the names of those that reply

15:03 amalloy: ohpauleez: well, i take the confusing stance of being amalloy on irc and Alan on google :P

15:04 feel free to contribute to cljopts, though. i've got the GetOpt engine working, and a function for reading the user's options, but they're not connected yet and it's not trivial

15:04 ohpauleez: ah cool, I might look into that, I'm just writing some tests right now for clj-github

15:04 joshua__: So if one of you were building a stack overflow clone in clojure what might you be using on the backend. (wiki, nested comments, posts, tagging, searching)>

15:06 ohpauleez: I would probably use the latest Postgres and/or Mongo, plus SOLR

15:06 I'd tell nginx to cache static data, and I'd use a CDN where possible

15:07 roll it out on Rackspace cloud or AWS, then get some monitoring in place... maybe ganglia and/or monit

15:08 using pallet to do deploys

15:08 joshua__: ^

15:09 joshua__: ohpauleez: Thank you so much ;).

15:09 ohpauleez: welcome

15:10 btw0: (map #(conj % "|") (partition-all 3 (range 10)))

15:11 guess the output

15:11 hugod: pallet can configure nginx, postgres, and ganglia - mongo and solr crates would be welcome contributions :)

15:12 amalloy: ((| 0 1 2) (| 3 4 5) (| 6 7 8) (| 9))?

15:12 btw0: i got (("|" 0 1 2) ("|" 3 4 5) ("|" 6 7 8) ("|" 9))

15:12 ohpauleez: hugod: If I find some free cycles, I might take you up on that

15:12 amalloy: what were you expecting?

15:12 btw0: i expected ((0 1 2 (3 4 5) ("|" 6 7 8) ("|" 9))

15:13 hugod: ohpauleez: shout in #pallet if you do :)

15:13 btw0: sorry

15:13 ohpauleez: will do

15:13 btw0: i expectrd "|" at the end of each sub list

15:13 amalloy: btw0: conj adds to wherever it's convenient/fast. for lazy seqs like those returned from partition, that's the front

15:15 &(map #(conj % 1 2) [[0] '(0)])

15:15 sexpbot: ⟹ ([0 1 2] (2 1 0))

15:16 ohpauleez: btw0: you could vec, sort of ugly: ##(map #(vec % "|") (partition-all 3 (range 10)))

15:16 sexpbot: java.lang.IllegalArgumentException: Wrong number of args (2) passed to: core$vec

15:16 amalloy: if you want add-end semantics, try converting to a vector first: ##(map #(conj (vec %) "|") (partition-all 3 (range 10)))

15:16 sexpbot: ⟹ ([0 1 2 "|"] [3 4 5 "|"] [6 7 8 "|"] [9 "|"])

15:16 ohpauleez: thanks, forgot the paren

15:16 btw0: thanks guys, i will do some research on google about this, its surprising to me

15:16 amalloy: ohpauleez: no, you misused vec

15:17 ohpauleez: right, the parens (vec %)

15:17 amalloy: #(vec %) is just vec, and how were you going to add "|" using just vec?

15:19 ohpauleez: this is what I had on my repl: (map #(conj (vec %) "|") (partition-all 3 (range 10)))

15:19 but then went to vector

15:19 not realizing it's keep the seq

15:19 and then copied the wrong line

15:19 amalloy: ah. well, you pasted without the conj, apparently

15:19 ohpauleez: right, up arrow, delete letters, "tor"

15:19 :)

15:19 paste... wrong line

15:24 btw0: is this documented somewhere? it's really not that obvious

15:24 amalloy: $google higher order persistent vector

15:24 sexpbot: First out of 130000 results is: Understanding Clojure's PersistentVector implementation | Higher-Order

15:24 http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/

15:25 btw0: going to read that, thanks

15:25 amalloy: btw0: probably more detail than you need, but it's what i have handy

16:01 LauJensen: Once, I thought Clojure was an elegant language... Then I read emit-defrecord: https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj#L134

16:06 jweiss: how does one use extend on a protocol like (defprotocol P (myfn [x] [x y])) (extend P MyRec {:myfn [x] (blah)}

16:06 i want myfn to have 2 arities

16:06 but i can only add it to the map once.

16:08 hiredman: well, you aren't adding it to the map correctly, so I would work on that first

16:09 jweiss: hiredman: i think the solution must be to make the value a function with multiple arities?

16:09 (fn ([x] (println x)) ( [x y] (println x y)))

16:10 something like that

16:27 amalloy: LauJensen: clearly not looking for style points there

16:37 dnolen: LauJensen: Imagine writing the Java to write that Java, and I think Clojure wins on style points by a huge margin ;) That said, getting something like syntax-rules would really clean macros up.

16:37 LauJensen: dnolen: The java might actually end up looking cleaner

16:40 You gotta love clojure.test

16:40 actual: (not (= "SELECT users.* FROM users" "SELECT users.* FROM users"))

16:41 dnolen: LauJensen: I serious doubt that, it require defining at least 5 unnecessary classes and involving ANTLR ;)

16:42 LauJensen: :)

16:42 Okay - I guess as long as we can keep Maven out of the discussion I should be happy

16:44 brehaut: LauJensen: it seems that there should be a corollary to godwin's law about maven

16:44 LauJensen: Indeed :)

17:18 joshua__: So a question.. should I care about avoiding Godwin's law in a discussion of Eugenics?

17:19 Nevermind. From the wikipedia article:The law and its corollaries would not apply to discussions covering genocide, propaganda, eugenics (racial superiority) or other mainstays of Nazi Germany, nor, more debatably, to discussion of other totalitarian regimes, since a Nazi comparison in those circumstances may be appropriate.

17:19 Looks like I'm in the clear.

17:26 cemerick: It seems that an extension to the Associative interface allowing for varargs on assoc would be a good addition -- that would enable multiple assoc's on a value to produce only one new instance when multiple k/v pairs are provided (rather than reducing through each pair).

17:26 Would be particularly helpful with records.

17:27 amalloy: cemerick: Associative is a java interface, right?

17:27 cemerick: Yes.

17:28 _schulte_: stupid question, what is the name of the latest clojure to use in project.clj for lein? I've tried all variations of [org.clojure/clojure "1.3.0"] without success.

17:29 cemerick: "1.3.0-alpha4" IIRC

17:29 or "1.3.0-SNAPSHOT" if you want to run against the absolute freshest out of hudson (which may or may not break your stuff).

17:29 amalloy: cemerick: probably possible if you changed the interface to varargs only, then; i don't think you can come up with signatures that will work for a single interface with optional varargs

17:30 _schulte_: still getting "Unable to resolve artifact: Missing:" for alpha4 and SNAPSHOT

17:31 cemerick: amalloy: assoc(Object, Object, Object...) would work just fine

17:31 leaving the existing (Object, Object) signature as-is

17:32 amalloy: cemerick: i guess that's true. not sure what problem i thought i was anticipating

17:33 cemerick: _schulte_: it's definitely 1.3.0-alpha4, but the snapshot is actually 1.3.0-master-SNAPSHOT

17:33 _schulte_: oh, never mind, clojure is working with "1.3.0-alpha4", it was clojure-contrib that is throwing errors now

17:33 cemerick: amalloy: it'd be a problem if one were to add an (Object, Object...) overload. Ambiguity.

17:33 _schulte_: cemerick: thanks

17:44 ah, looks like I should use alpha3 if I want to use swank-clojure

17:54 gtrak: ~clojure

17:54 clojurebot: clojure is the bestest programming language available.

18:00 LOPP: hey

18:00 I'm using Enlive, but I have problem getting it to read non-ascii characters from websites correctly

18:00 how do chose the encoding it uses to read the website

18:02 raek: LOPP: this is how I did it once: http://raek.se/trattern/src/se/raek/scraping/baljan.clj

18:03 I passed a reader that uses the desired coding to html-resource

18:03 LOPP: what's defvar again?

18:03 raek: rather letting html-resource create a reader automagically

18:04 LOPP: (automagically is a ruby buzzword)

18:04 :P

18:04 raek: LOPP: (defvar- foo value "docs") --> (def ^{:private true, :doc "docs"} foo value)

18:04 LOPP: I figured it had to be something like that

18:04 that's 1.3 clj?

18:04 raek: no, contrib

18:05 LOPP: btw what does private do

18:05 raek: if you try to take the value of the var from another namespace, an exception will be throen

18:06 LOPP: about encodings and HTML

18:06 jk_: using the "future" function, what is considered a good practice for hanging onto the future in order to cancel it at some time in the future?

18:06 LOPP: do I have to read the encoding from some header

18:07 or can I just choose UTF-8 on the reader and problem solved

18:07 amalloy: LOPP: automagically has been around for a lot longer than ruby

18:07 LOPP: I know :)

18:07 ruby community is just using it a lot :D

18:08 raek: LOPP: well, there are multiple places where it can be specified

18:08 LOPP: may I present you a lazy solution? https://github.com/raek/utf8-with-fallback

18:08 LOPP: yes...but let's say I specify the reader to be UTF-8

18:08 and I read a random site

18:08 could I have a problem

18:08 jk_: LOPP: what if it's not UTF-8 encoded? i don't know how you could tell if it's not in a meta tag

18:09 LOPP: it won't work if you access a site in another encoding

18:09 raek: the encoding can be specified with the "charset" attribute in the "Content-Type" HTTP header, or in a meta tag

18:10 jk_: raek: and i guess having it in a meta tag is kind of a chicken and egg problem :)

18:10 LOPP: even as content type

18:10 raek: LOPP: the charset that I linked will treat the data as UTF-8 if it is valid UTF-8 and as Latin1 otherwise.

18:10 jk_: indeed.

18:11 LOPP: I generally let other code handle content-type and http request headers

18:11 raek: I think that's a part of tagsoup that hasn't been coded yet

18:11 jk_: what about my question with futures? does anyone do this?

18:11 raek: "

18:11 You can also supply an AutoDetector that peeks at the incoming byte stream and guesses a character encoding for it. Otherwise, the platform default is used. If you need an autodetector of character sets, consider trying to adapt the Mozilla one; if you succeed, let me know."

18:11 http://home.ccil.org/~cowan/XML/tagsoup/

18:12 LOPP: :)

18:12 raek: jk_: well, that's what futures are for

18:12 to have something to hold on to that represents a computation that happens somewhere

18:12 LOPP: I'd rather have enlive author implement something that would try to get encoding

18:12 raek: in order to wait for it to finish or to tell it to abort

18:12 jk_: raek: my question is HOW does one typically hold onto that if you need to cancel it later?

18:12 LOPP: :)

18:13 jk_: with a global var?

18:13 LOPP: how do you hold on to any other variable?

18:13 raek: LOPP: enlive is basically a wrapper for tagsoup in this aspect

18:13 jk_: LOPP: in a typical pure functional style, you don't

18:13 LOPP: jk_ depends on scope where you might want to cancel it

18:13 jk_: LOPP: it would be after a "let" returns

18:13 raek: LOPP: the author of tagsoup is aware of the problem (see the quote) and has proposed a piece of cod eto port

18:14 (I have considered porting that myself)

18:14 but there are two few hours on the day

18:18 jk_: raek: what i'm getting at is the handler function for my service might have to shut down the listener. but to do that, it needs to see the future object that was returned when i first started the service

18:18 raek: i'm trying to figure out if i need to bind it to a global var to make sure it's accessible

18:19 raek: I guess this is a very general problem

18:20 one way could perhaps be to create the handler function in the scope where the future is bound to a local

18:20 so that it keeps a reference to the future in its closure

18:21 jk_: oh! duh! a closure

18:21 never mind...mild case of brain death here

18:21 thanks raek

18:21 raek: np :)

19:21 jk_: raek: i'm pretty new to clojure. it just didn't occur to me that i could define new functions in the body of a let.

19:29 raek: jk_: eye opening, isn't it..? :-)

19:29 jk_: yes indeed!

19:33 raek: i guess the key insight i was missing was that "def" always applies to the root binding.

19:35 amalloy: jk_: you can define new functions without using (fn), too. higher-order functions like comp are often enough to do the job: ##(let [lookupfn (comp :b :a)] (lookupfn {:a {:b 10} :c 1}))

19:35 sexpbot: ⟹ 10

19:37 jk_: amalloy: well... only when you're using pre-existing functions thought right? like the fact that keys are functions of their maps?

19:37 oh never mind

19:37 amalloy: you're newly creating lookupfn since comp returns the new function

19:38 amalloy: right

19:38 &(let [f (fn [x] (+ 2 x)), newfn (comp f *)] (newfn 5 8))

19:38 sexpbot: ⟹ 42

19:39 amalloy: using one builtin and one fresh user-supplied function there, jk_

19:39 jk_: amalloy: got it

19:40 gotta run. thanks for the info amalloy, raek

20:14 Lajla: cemerick, how is da progress going?

20:14 cemerick: Lajla: with?

20:15 Lajla: cemerick, my named recur

20:16 cemerick: Lajla: heh, no progress, just an idea at this point. You should post a message to the clojure-dev mailing list so that others can comment and Rich can see it.

20:16 Lajla: cemerick, so clojure has nly one developer basically?

20:17 cemerick: no, there's at least a dozen people that make regular contributions to core stuff.

20:17 Rich is definitely the benevolent dictator, though.

20:17 Lajla: They must be homosexual, there is no other explanation

20:17 Why else would you contribute to Rich's core.

20:17 All dictators style themselves as benevolent.

20:18 Including Arcturus Mengsk

20:21 cemerick: Lajla: why do you spout such jibberish so often?

20:22 danlarkin: cemerick: don't feed the troll

20:23 just /ignore him

20:23 Lajla: cemerick, formal thought disorder.

20:23 joshua__: Alright, I have a problem I just solved with a regular expression, but it has led to another problem.

20:23 cemerick: danlarkin: I actually don't think I've ever /ignored anyone…

20:23 hiredman: ignoring him works well, until someone starts talking to him...

20:23 Lajla: cemerick, neither did I.

20:23 You are impersonating me.

20:23 You're being my secret sockpuppet.

20:23 admit it.

20:23 joshua__: I think maybe something related to destructuring might be useful. How so do you take an argument to a function and apply a transformation to it

20:24 * cemerick apologizes to everyone :-/

20:24 joshua__: so like (fn [(transform x)] .. )

20:24 or is that not possible?

20:25 Lajla: cemerick, yes, answer for thy sins.

20:25 That, or buy an indulgiance.

20:25 either is cool

20:25 Catholic church needs their money yo. Lot's of parents to pay to shut up.

20:27 joshua__: This isn't working out either: (defn build-tree

20:27 [root-link root-page (rl-fetch-url root-link)]

20:28 Should I just toss in a let after the function has been called?

20:30 cemerick: joshua__: what are you trying to do, exactly? You can't put arbitrary forms in an argspec like that.

20:32 joshua__: I know you can do something like that in a let binding, I thought it was possible to do it in a defn binding as well.

20:32 amalloy: joshua__: you can only do it in the value half of a let binding

20:33 joshua__: I've been having dreams of programming on clojure using a huge binding to ensure that I'm not being very functional :P

20:35 amalloy: joshua__: what you're imagining is the equivalent of (let [(name x) foo]), which is clearly crazy - you want (let [x (name foo)])

20:36 you can achieve that either by calling name inside of your defn, or by calling name before you call your defn - the one place you can't do it is in the arglist for your defn

20:41 joshua__: I know it is crazy, but I thought this was clojure =( sorry

20:45 amalloy: lol, i love it. it's true, a lot of crazy things are possible

20:45 you could, in fact, write your own magic-defn macro that would behave this way, but it would be pretty complicated

20:49 bendlas: hi, folks

20:49 can someone confirm a stacktrace when doing

20:49 lein install org.clojure/clojure 1.3.0-master-SNAPSHOT

20:50 ?

20:50 technomancy: bendlas: that variant of lein install is meant for leiningen plugins

20:50 bendlas: OIC

20:50 technomancy: err--rather, for leiningen projects that include a shell wrapper

20:51 bendlas: thanks

20:51 great tool, btw

20:51 technomancy: thanks

20:59 joshua__: agreed on lein being an amazing tool. It makes me happy in the same way the python-install and apt-get utilities make me happy =) you save me hours so frequently =)

21:01 amalloy: OMG your right. I half meant that last remark as a joke and you just showed me it isn't really a joke.. o.0. Wow.

21:05 amalloy: joshua__: well, in the general case it's quite hard, since how can you know which symbols are args and which are functions to apply to those args? you'd be more or less forced to have a convention like "argument symbols named A!foo should be converted to foo inside the defn body; other symbols will be treated as transformations to apply to the actual arguments before binding them to foo"

21:11 but yes, in general it's possible: lisps encourage you to build your own language, though imo this wouldn't be a good extension

21:11 joshua__: amalloy: I agree.

21:12 amalloy: I got to try my hand at that recently and it has been useful! I made a macro to force a function to be rate limited. =)

21:12 amalloy: you helped.

21:13 amalloy: rate-limited?

21:13 joshua__: Like lets say you have a function that you don't want to be called more than 14 times a second.

21:13 amalloy: oh, i see. called at most N times per T time

21:13 hm. that sounds like a task better-suited for a function than a macro

21:14 gertalot: ,(into '() (cons 1 [2 3]))

21:14 clojurebot: (3 2 1)

21:14 joshua__: (defrl new-func func-to-limit x-times per-y)

21:14 amalloy: (defn rate-limited-fn [f rate] (fn [& args] (while (still-too-soon)) (apply f args))

21:16 joshua__: this way you can rate-limit even a function someone passes you as a parameter, and you can manage it however you want without having to pollute your namespace with it

21:16 joshua__: amalloy: I can do that to a function that is passed as a parameter. The macro is a skin over the function.

21:17 amalloy: It was an attempt at learning macros in a way that I hoped I might use.

21:17 amalloy: joshua__: mind gisting the macro? i don't really see what the benefit to having a skin over something so thin is

21:19 joshua__: amalloy, http://pastebin.com/MSSDABCH

21:20 amalloy: heh, well, fair enough. your function is general enough, and presumably you want to (def) often enough that a macro is useful

21:22 tomoj: seems weird to have defrlf for defns

21:22 amalloy: if you'd glued together the (def) and the (fn) i was going to scold you

21:22 tomoj: oh, no its not, you give them a new name

21:23 joshua__: amalloy, *wishes his teachers in college were more like the people in irc*

21:23 oops

21:24 *wishes his teachers in college were more like the people in IRC*

21:24 gah, w/e, I don't know how to /emotes

21:24 amalloy: lol

21:24 it's /me

21:25 joshua__: .. thanks .. ;p

21:26 amalloy, so what do you mean by not gluing together the def and the fn?

21:26 Like using the same rate limit let for multiple functions?

21:27 amalloy: i mean, your macro includes a def, but you provide a way to create rate-limited functions without having to def anything, by using the function and not bothering with the macro

21:28 if it were impossible to get a rate-limited function without (def)ing something, that would be a pretty bad tool

21:30 joshua__: amalloy: I see your point now. It brings to mind a question though, can you undef things?

21:30 amalloy: joshua__: yeah, but there's rarely a good reason: ##(doc ns-unmap)

21:30 sexpbot: ⟹ "([ns sym]); Removes the mappings for the symbol from the namespace."

21:32 amalloy: &[*ns* ns-unmap]

21:32 sexpbot: ⟹ [#<Namespace sandbox6362> #<core$ns_unmap clojure.core$ns_unmap@efba6d>]

21:40 joshua__: $source ns-unmap

21:40 sexpbot: ns-unmap is http://is.gd/iOSfD

21:41 joshua__: &(.substring "hello" 1 2)

21:42 sexpbot: ⟹ "e"

21:43 joshua__: $source the-ns

21:43 sexpbot: the-ns is http://is.gd/iOSCi

21:54 joshua__: fortune

21:54 amalloy: $fortune

21:54 sexpbot: DID YOU SAY FORTRAN?

22:06 joshua__: That is the one I added =).

22:13 (what-func-given-this-input :some {:some "abc" :thing 123}) would produce this output -> {:thing 123}

22:14 &(doc dissoc)

22:14 sexpbot: ⟹ "([map] [map key] [map key & ks]); dissoc[iate]. Returns a new map of the same (hashed/sorted) type, that does not contain a mapping for key(s)."

22:15 joshua__: &(dissoc {:some "abc" :thing 123} :some)

22:15 sexpbot: ⟹ {:thing 123}

22:15 joshua__: yeay!

22:25 amalloy: joshua__: apparently there's something like a function-finder in smalltalk, to discover dissoc for you. people are always saying clojure could use one, and i totally agree; not sure why it's so hard that nobody's done it yet

22:27 famous last words, of course, but it seems like it wouldn't take more than an hour or two

22:28 brehaut: amalloy: what does the function finder do?

22:29 amalloy: brehaut: (find-this-fn {:foo 10} {:foo 10 :bar 9} :bar) should return dissoc

22:29 brehaut: that sounds like it does magic?!

22:30 amalloy: does it actually take your inputs and run everything function over it till it produces the output you have specified?

22:31 amalloy: brehaut: search (ns-publics (the-ns clojure.core)), and try every one of them on the input to see if it matches the output

22:31 brehaut: or is there some smarts i cant concieve of?

22:31 huh

22:31 amalloy: doesn't seem too hard, right?

22:32 brehaut: your right, famous last words ;) but yeah seems managable

22:44 tomoj: (find-this-fn + *ns* '+)

22:45 unfortunately ns-unmap appears to come first in clojure.core's ns-publics

22:45 good luck with that :)

22:45 brehaut: hah

22:46 tomoj: I guess it's the user's responsibility not to pass it anything that could be dangerous?

22:46 brehaut: tomoj: kinda hard to know if you are searching a namespace you dont know though right? presumably if you know a NS then you wouldnt need to find-fn it

22:47 tomoj: (find-this-fn (range) inc 0)

22:47 :P

22:48 brehaut: haha

22:48 tomoj: no infinite seqs allowed

22:48 cemerick: If pure functions had appropriate metadata on them (a perfectly reasonable thing to want for a variety of reasons), then you might have a fighting chance.

22:49 brehaut: i miss hoogles search :(

22:50 is it reasonable to think that an inferencet could heuristically guess if a fun was pure based on what it calls?

22:51 cemerick: brehaut: probably not

22:51 brehaut: (and presumably have some meta for pureness to let you annotate that if it cant work it out)

22:51 cemerick: There's io!, but most fns don't use it.

22:52 brehaut: cemerick: is that a meta annotation?

22:53 cemerick: no, it's a macro that tosses an exception if it's run within the scope of an STM transaction

22:53 brehaut: oh right

22:55 cemerick: Now, if pure fns in the stdlib were annotated as pure with suitable metadata, then you could do some interesting things.

22:55 brehaut: cemerick: im tempted to go fill out the contributers form and go do that grunt work just to let smarter people do those interesting things

22:56 cemerick: brehaut: that would be a fantastic addition, as I think about it more

22:56 Sneaking towards forms of static analysis though, which may creep some people out.

22:57 brehaut: cemerick: clojure already does light weight inference though right?

22:57 cemerick: only as an optimization on interop calls

22:59 joshua__: Will (catch Exception e nil) catch all exceptions and do nothing with them?

22:59 cemerick: yes

22:59 amalloy: joshua__: yes, and the nil isn't even necessary

23:00 joshua__: java.lang.UnsupportedOperationException: nth not supported on this type: Integer

23:00 [Thrown class java.lang.RuntimeException] isn't getting caught

23:01 amalloy: joshua__: that's probably a compile-time error

23:01 attempting to destructure something that's not a list while expanding a macro

23:02 you could (try (macroexpand '(whatever)) (catch Exception _))

23:06 dnolen: brehaut: if you had the patience to learn logic programming, you could help me with miniKanren :) type inferencing, abstract interpretation, syntax-rules all possible.

23:09 brehaut: dnolen: ive been watching the stream of commits on logos; its on my list of projects to dig into more over christmas

23:09 joshua__: How do you send just one sexp to slime rather than the whole file?

23:10 dnolen: brehaut: cool!

23:10 brehaut: dnolen: ever since studying prolog at uni ive been both fascinated and a bit baffled by logic programming :)

23:10 technomancy: joshua__: C-M-x if it's a top-level expression

23:10 C-x e for the expression behind the point

23:13 joshua__: &(apply (macroexpand `+) [1 2])

23:13 sexpbot: ⟹ 2

23:13 joshua__: Why not 3?

23:13 dnolen: brehaut: it's frustrating and very fun. Certainly the longest I've ever worked on what amounts to 300 LOC.

23:14 joshua__: technomancy: first lein and now this, your saving me so much time!

23:14 technomancy: joshua__: '+ is a symbol. calling a symbol like a function is equivalent to (get '+ [1 2])

23:14 joshua__: which is nonsense, but Clojure doesn't stop you from trying it =)

23:14 or rather (get '+ 1 2)

23:14 joshua__: How do you check whether or not something is a symbol compared to a macro

23:15 or w/e

23:15 technomancy: which tries to look up the '+ symbol in the map 1 (never mind that 1 isn't a map) and falls back to 2 as the default not-found value

23:15 brehaut: joshua__: technomancy is the third of the rooms trio of bots

23:15 technomancy: brehaut: only outside PST work hours. =)

23:16 brehaut: technomancy: hah :) that must coincide quite well with NZST work hours

23:16 joshua__: technomancy: so it took clojure to build an ai like you, capable of passing the touring test.

23:16 technomancy: joshua__: is it because of your mother that you say capable of passing the touring test?

23:16 joshua__: &technomancy: is there an ifmacro?

23:16 sexpbot: java.lang.Exception: Invalid token: technomancy:

23:16 brehaut: (inc technomancy)

23:16 sexpbot: ⟹ 3

23:17 amalloy: &(macro? #'when)

23:17 sexpbot: java.lang.Exception: Unable to resolve symbol: macro? in this context

23:17 amalloy: &(-> #'when meta :macro)

23:17 sexpbot: ⟹ true

23:18 joshua__: $(-> + meta :macro)

23:18 &(-> + meta :macro)

23:18 sexpbot: ⟹ nil

23:18 paul`: &#'when

23:18 sexpbot: ⟹ #'clojure.core/when

23:18 technomancy: joshua__: in general quoted functions like that are used in the context of a macro, and that handles eval-ing the symbol into an actual function

23:23 Lajla: What's #' ?

23:23 Namespaces, right?

23:23 amalloy: &(macroexpand '#'when)

23:23 sexpbot: ⟹ (var when)

23:24 Lajla: I hate you

23:24 Proving me wrong sohuld be awared the death penalty, just like journalism.

23:26 amalloy: &(macroexpand '~when)

23:26 sexpbot: ⟹ (clojure.core/unquote when)

23:26 Lajla: Ahh

23:26 ~ unquotes with namespace right?

23:26 clojurebot: amespaces are (more or less, Chouser) java packages. they look like foo.bar; and corresponde to a directory foo/ containg a file bar.clj in your classpath. the namespace declaration in bar.clj would like like (ns foo.bar). Do not try to use single segment namespaces. a single segment namespace is a namespace without a period in it

23:26 Lajla: I'm still not sure how namespaces work here

23:27 Ah

23:27 amespaces

23:27 amalloy: Lajla: no. ` quotes with namespaces

23:28 &`inc

23:28 sexpbot: ⟹ clojure.core/inc

23:28 Lajla: And this works to give hygienic macros right?

23:29 amalloy: more or less

23:29 arbscht: brehaut: you're in nz?

23:29 Lajla: amalloy, do elaborate

23:29 brehaut: arbscht: yes

23:29 arbscht: brehaut: cool! do you know http://lisp.geek.nz?

23:29 Lajla: amalloy, like

23:29 brehaut: arbscht: i dont belive so

23:29 Lajla: say I use (let [if 3] (and x y z))

23:29 does it then break and?

23:29 Because if has a different scope

23:30 &(macroexpand '(let [if 3] (and x y z)))

23:30 sexpbot: ⟹ (let* [if 3] (let* [and__3468__auto__ x] (if and__3468__auto__ (let* [and__3468__auto__ y] (if and__3468__auto__ z and__3468__auto__)) and__3468__auto__)))

23:30 amalloy: Lajla: well, if is a special form so this will just barf

23:30 arbscht: brehaut: now you do :) feel free to sign up to the mailing list -- there are physical meetings too, but mainly in auckland for now

23:30 brehaut: arbscht: cool. im in muggy ham

23:30 Lajla: &(let [if 3] if)

23:30 sexpbot: ⟹ 3

23:31 amalloy: whoa, no kidding?

23:31 joshua__: Alright I'm going through a for loop printing stuff and getting (nil nil nil thingiwant nil nil nil nil)..

23:31 Lajla: &(let [if 3] (and x y z))

23:31 sexpbot: java.lang.Exception: Unable to resolve symbol: x in this context

23:31 joshua__: How can I do that without getting a bunch of nils?

23:31 Lajla: Ehh

23:31 &(let [if 3] (and 1 2 3))

23:31 sexpbot: ⟹ 3

23:31 Lajla: Hmm

23:31 arbscht: brehaut: ah, not too far then. we have an irc channel too, #lisp-nz

23:31 joshua__: &(for [x (range 3)] (if (= x 2) (println x)))

23:31 sexpbot: java.lang.IllegalStateException: Var clojail.core/tester is unbound.

23:31 Lajla: &(macroexpand '(let [if 3] (and 1 2 3)))

23:31 sexpbot: ⟹ (let* [if 3] (let* [and__3468__auto__ 1] (if and__3468__auto__ (let* [and__3468__auto__ 2] (if and__3468__auto__ 3 and__3468__auto__)) and__3468__auto__)))

23:32 amalloy: joshua__: for is lazy

23:32 Lajla: &(macroexpand '(let [if 3] (+ 1 2 3)))

23:32 sexpbot: ⟹ (let* [if 3] (+ 1 2 3))

23:32 Lajla: Hmm

23:32 joshua__: What should I do instead of for to avoid having a ton of nils?

23:32 amalloy: Raynes: clojail showing through again ^^

23:32 Lajla: &(let [if 3] (and 1 2 5))

23:32 sexpbot: ⟹ 5

23:32 amalloy: joshua__: ##(doc doseq)

23:32 sexpbot: ⟹ "Macro ([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

23:33 Raynes: amalloy: ?

23:33 amalloy: &(for [x (range 3)] (if (= x 2) (println x)))

23:33 sexpbot: java.lang.IllegalStateException: Var clojail.core/tester is unbound.

23:33 Raynes: amalloy: Oh, I haven't fixed that yet.

23:33 I know the problem, but I've been sick.

23:33 Cut me some slack, man.

23:34 amalloy: eh, i think i know the issue too. but i don't want to fix clojail for fear of setting a precedent; i don't want you making me fix everything

23:34 Raynes: I'll fix it as soon as I can type more than two sentences without blowing my nose and moaning.

23:34 joshua__: &(defn find-fn

23:34 sexpbot: java.lang.Exception: EOF while reading

23:34 joshua__: [inputs outputs]

23:34 (doseq [x (ns-publics (the-ns `clojure.core))]

23:34 (try

23:34 (if (= outputs (apply

23:34 * Raynes goes back to bed.

23:34 joshua__: (second x))

23:34 inputs))

23:35 (println (first x)))

23:35 (catch Exception _)))))

23:35 I've almost got it working.

23:35 Only problem that lets say you do (find-fn [1 2] 3)

23:35 amalloy: omg joshua__ plz gist/pastie that

23:35 joshua__: you get back add, bitxor, and than a few 1 2s.

23:36 https://gist.github.com/743037

23:36 Help me to fix it? =)?

23:36 amalloy: joshua__: find-ns is trying print and println

23:36 er, find-fn

23:37 joshua__: OH.

23:37 I get it.

23:37 Okay that makes a lot of sense.

23:37 How do you stop that though?

23:37 amalloy: you can rebind *in* and *out* while you're calling the functions

23:37 joshua__: Alright how do I do that?

23:38 amalloy: &(doc with-out-str)

23:38 sexpbot: ⟹ "Macro ([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."

23:39 cky: Woo! An abbreviated name for with-output-to-string. :-P

23:41 joshua__: with-out-str won't work it returns the string not the call.

23:42 amalloy: oh right

23:42 $source with-out-str

23:42 sexpbot: with-out-str is http://is.gd/iPa25

23:43 technomancy: ,(let [v (promise)] (with-out-str (deliver v (do (println "DISREGARD THAT I SUCK") :value))) @v)

23:43 clojurebot: :value

23:43 amalloy: joshua__: (binding [*out* java.io.StringWriter.] (blah))

23:43 technomancy: tada!

23:45 joshua__: does that work technomancy?

23:45 amalloy: I'm getting a class not found java.lang.stringwrite exception with that.

23:45 technomancy: joshua__: clojurebot seems to think so.

23:45 amalloy: joshua__: java.io.StringWriter

23:46 joshua__: kk its working

23:46 technomancy: promises are underrated

23:46 joshua__: (find-fn [1 2] 3)

23:46 bit-or

23:46 bit-xor

23:46 +

23:46 unchecked-add

23:46 nil

23:46 are the results

23:46 gisting the newest attempt

23:47 amalloy: joshua__: nice. that's like perfect

23:47 though i'd do it with filter, rather than doseq/println

23:48 joshua__: amalloy lol.. quoting you =) joshua__: ##(doc doseq)

23:48 sexpbot: ⟹ "Macro ([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."

23:48 joshua__: don't mean that in a bad way though heh

23:48 its funny because really the channel wrote that function.. I had to ask for everything related to heavy lifting

23:48 amalloy: yeah, i know. you asked how to do (for) with side effects, not how to find things matching a predicate :P

23:53 anyway, that's how you write things in clojure anyway. talk about an idea, and ask someone else (library functions, or #clojure) to do all the work

23:54 joshua__: amalloy: That is how I write it or how you write things in general?

23:55 amalloy: things in general. farm out all the heavy lifting

23:55 joshua__: amalloy, (I know the first one is true at the very least lmfao, was so much better about that in other languages but things took a lot longer)

23:55 Going to hack at that function again. I want it to look elegant.

23:55 amalloy: hurrah

23:58 technomancy: http://twitter.com/#!/SeanTAllen/status/15259440336867328 <= OH at the nyc clojure meetup: 'It is so nice to be with a group of people where everyone knows that CAPSLOCK should be mapped to CONTROL.'

23:58 niiice

Logging service provided by n01se.net