2010-12-15
| 00: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 |
| 00:04 | clizzin | of map creation? |
| 00:15 | amalloy | clizzin: how is that different from (fn [m default] (fn [k] (or (get m k) default)))? |
| 00:16 | amalloy | i guess then it's hard to use keys, vals, assoc, etc |
| 00:16 | clizzin | amalloy: right |
| 00:16 | amalloy | you certainly could do it by implementing/proxying IPersistentMap, but that's pretty heavyweight |
| 00:17 | clizzin | if i proxy IPersistentMap, i would *only* have to proxy the get function, right? |
| 00:18 | clizzin | oh, but then i'd have to play with the internals of IPersistentMap's implementation instead of using get to get the map |
| 00:18 | clizzin | get the value* |
| 00:19 | amalloy | clizzin: more would be necessary. (keys foo) can't just use get |
| 00:23 | amalloy | sorry, that's a silly claim, i think. it's true if you proxy IPersistentMap, but of course you'd proxy PersistentHashMap instead |
| 00: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? |
| 00:29 | technomancy | ok, time to unsubscribe to the clojure mailing list =( |
| 00:30 | technomancy | got a flood of primitive hate about three months too late |
| 00:30 | technomancy | or switch to digest I guess |
| 00:31 | amalloy | clizzin: you'd have to explicitly pass "this" to any subsidiary functions, i think |
| 00:31 | amalloy | but i don't do a lot of proxying |
| 00: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. |
| 00:34 | clizzin | 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 |
| 00:34 | clizzin | e around until that time. |
| 00:38 | amalloy | clizzin: if you're looking for lazy ways to use (abuse?) the language features, what about dynamic bindings? |
| 00:40 | clizzin | amalloy: not familiar with those, would you mind explaining further? |
| 00: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 |
| 00:43 | amalloy | so like (def *not-found-val* nil), then (with-bindings [*not-found-val* 10] (some-fn-that-uses-*not-found-val*)) |
| 00: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. |
| 00:54 | dnolen | clizzin: you can do something like this, https://gist.github.com/741678 |
| 01: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 |
| 01:11 | dnolen | vectors aren't free. they also muddy up the representation at the REPL. it sounded like he wanted local behavior anyway. |
| 04:00 | LauJensen | Morning all |
| 04:09 | ejackson | salut |
| 04:33 | Licenser | morning |
| 04:54 | raek | good morning (UGT as well as CET) |
| 05:25 | ordnungswidrig | hi all |
| 06:04 | fliebel | morning |
| 06:07 | fliebel | 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. |
| 06:13 | _ato | fliebel: I learnt it in university. They used this textbook, which isn't bad: http://books.google.com/books?id=a39QAAAAMAAJ |
| 06: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." |
| 06:16 | _ato | ah yeah, it was my first properly functional language, can't help with any non-beginner stuff I'm afraid |
| 06:17 | fliebel | ok |
| 06:19 | faust45 | fliebel: ask at #haskell chanel |
| 06: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. |
| 06:25 | mrBliss | fliebel: I used Real World Haskell, but I suppose some of the guys in #haskell will probably have suggested this one too. |
| 06:35 | ejackson | fliebel: I'm currently reading "Learn you Haskel for great good" and its totally fine |
| 06:35 | ejackson | the "Gentle Introduction to Haskel 98" is also good to get a terse view |
| 06:35 | ejackson | terse as in: monads rear up by page 10 I think |
| 06:38 | ejackson | sadly the combinatorics of "Language X for Y programmers" is prohibitive :) |
| 06:54 | fliebel | ejackson, mrBliss: Thanks, Those are exactly which where suggested to me. I think I'll stick to LYAH. |
| 07:26 | mduerksen | /help |
| 07:27 | mduerksen | sorry |
| 07:49 | TobiasRaeder | hey :) |
| 07:49 | TobiasRaeder | can anyone tell me why map doesn't seem to use thread-local bindings? |
| 07: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. |
| 07:52 | TobiasRaeder | @cemerick ah, thanks a ton. really makes sense |
| 07:53 | GOSUB | cemerick: The whole office is watching your deployment video now. Thanks for that! |
| 07:55 | cemerick | whoa |
| 07:55 | cemerick | GOSUB: I guess I'm on the hook now, huh? ;-) |
| 07:56 | GOSUB | cemerick: completely ;) |
| 07:56 | fliebel | cemerick: Your pallet vid is live? |
| 07:57 | cemerick | fliebel: no, GOSUB is referring to my screencast post |
| 08:02 | LauJensen | fliebel: Just google for 'epic deployment' :) |
| 08:02 | fliebel | I believe sexpbot can do that for me... |
| 08:02 | fliebel | $google epic deployment |
| 08:02 | sexpbot | First out of 54500 results is: Web Deployment - Epic Games Forums |
| 08:02 | sexpbot | http://forums.epicgames.com/showthread.php%3Ft%3D706732 |
| 08:03 | fliebel | $google epic deployment clojure |
| 08:03 | sexpbot | First out of 77 results is: Continuous Deployment of Clojure Web Applications: Clojure Conj ... |
| 08:03 | sexpbot | http://cemerick.com/2010/11/02/continuous-deployment-of-clojure-web-applications/ |
| 08:04 | GOSUB | woohoo! |
| 08:07 | cemerick | $google epic clojure |
| 08:07 | sexpbot | First out of 1320 results is: Continuous Deployment of Clojure Web Applications: Clojure Conj ... |
| 08:07 | sexpbot | http://cemerick.com/2010/11/02/continuous-deployment-of-clojure-web-applications/ |
| 08:13 | GOSUB | (swap! cemerick inc) |
| 08:14 | raek | (inc cemerick) |
| 08:14 | sexpbot | ⟹ 1 |
| 08:14 | GOSUB | (inc cemerick) |
| 08:14 | sexpbot | ⟹ 2 |
| 08:14 | GOSUB | hmm. |
| 08:14 | fliebel | Not a much used feature of sexpbot it seems. Evey time I tried, it returned 1. |
| 08:15 | cemerick | I don't think it's persisted. I was up to 3 at some point. |
| 08:15 | GOSUB | (inc cemerick) |
| 08:15 | sexpbot | ⟹ 3 |
| 08:16 | fliebel | Maybe someone did (dec cemeric) a few times? No, can't be... |
| 08:17 | cemerick | haters gonna hate :-P |
| 08: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 |
| 08:19 | cemerick | fliebel: it's a (probably) American meme, that I can't believe I actually repeated. |
| 08:26 | fliebel | cemerick: Uhm, did you mean I came across rude? I didn't mean to imply people (dec)'d you, quite the opposite. |
| 08:27 | cemerick | fliebel: no, you weren't rude at all. :-) |
| 08:27 | cemerick | I'm sure there are some (many?) that would (dec) me, though. My comment was just me saying "oh well". |
| 08:28 | cemerick | 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. |
| 08:29 | fliebel | "How wude!" - Jar-Jar Binks :P |
| 08:29 | GOSUB | fliebel: hehe |
| 08:32 | cemerick | fliebel: I think Elmer Fudd laid claim to "how wude" about 50 years before jar-jar ;-) |
| 08:34 | jweiss | anybody here use https://github.com/technomancy/durendal (or some other way of syntax highlighting clojure in slime)? |
| 09:01 | mrBliss | jweiss: https://github.com/mrBliss/dotfiles/blob/master/.emacs.d/custom-clojure.el |
| 09:03 | jweiss | mrBliss: cool, how do i use this? (sorry i'm an elisp newb) - just (load "custome-clojure.el" in .emacs? |
| 09:05 | mrBliss | jweiss: add it to your load path and (require 'custom-clojure) in your .emacs |
| 09:05 | jweiss | ok thanks |
| 09:54 | lpetit | Hello guys |
| 09:54 | ejackson | hey Laurent |
| 09:54 | lpetit | I'd like to introduce a ring based extension to my current web application, "by the back door", if you will |
| 09:55 | lpetit | "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 |
| 09:55 | lpetit | does this make sense ? does it exist ? what would you do ? |
| 09:56 | lpetit | 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. |
| 09:56 | lpetit | I'm now listening to the ring experts :) |
| 09:59 | lpetit | 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 | jweiss | 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 | lpetit | 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 | ordnungswidrig | 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 | lpetit | thx! |
| 10:20 | lpetit | 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 | lpetit | 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 | ordnungswidrig | 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 | jweiss | Debugger entered--Lisp error: (wrong-type-argument frame-live-p :underline) |
| 10:24 | jweiss | 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 | lpetit | 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 | lpetit | 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 | lpetit | 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 | lpetit | 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 | cemerick | 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 | lpetit | cemerick: exactly, init-param, as I said ^^ |
| 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 | lpetit | 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 | joshua-choi | (I'm really new to Clojure's reference; I've never really needed them until recently) |
| 11:06 | joshua-choi | *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 | joshua-choi | 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 | lpetit | ,(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 | lpetit | 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 | jaley | 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 | joshua-choi | 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 | ohpauleez | 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 | ohpauleez | I'm going to update some of the dependencies |
| 12:00 | ohpauleez | 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 | ohpauleez | with burn down, burn up, and velocity information |
| 12:02 | ohpauleez | "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 | ohpauleez | haha, yeah, that is a good one |
| 12:07 | defn_ | fliebel: got a link to a commit punchcard? |
| 12:07 | defn_ | ive never used one |
| 12:08 | fliebel | defn_: https://github.com/pepijndevos/utterson/graphs/punch_card |
| 12:08 | fliebel | Mine are all rather boring. |
| 12:10 | fliebel | 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 | fliebel | 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 | fliebel | defn_: You where talking about a "top secret" baker a while back. Any progress with that? |
| 12:25 | fliebel | (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 | LauJensen | 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 | LauJensen | (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 | LauJensen | private void writeObject(java.io.ObjectOutputStream out) |
| 14:35 | LauJensen | throws IOException |
| 14:35 | LauJensen | private void readObject(java.io.ObjectInputStream in) |
| 14:35 | LauJensen | throws IOException, ClassNotFoundException; |
| 14:35 | LauJensen | |
| 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 | LauJensen | 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 | amalloy | if you have readObject and writeObject defined, the serialization library calls them magically, via reflection |
| 14:41 | amalloy | 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 | amalloy | they're just mentioned in the docstring |
| 14:44 | amalloy | 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 | amalloy | 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 | LauJensen | (def m (mytype. x y z)) |
| 14:48 | LauJensen | user> m |
| 14:48 | LauJensen | ** Blow up |
| 14:48 | LauJensen | 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 | LauJensen | amalloy: If you clone it, eval the core.clj file, and in the repl type (table :test) |
| 14:56 | LauJensen | 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 | amalloy | clojure thinks it knows how to print any IDeref: you deref it, then print the thing |
| 14:59 | LauJensen | aaaha |
| 14:59 | LauJensen | 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 | sexpbot | http://snipplr.com/view/13559/serializing-clojure-data-structures/ |
| 15:01 | amalloy | best i can come up with |
| 15:01 | LauJensen | thanks |
| 15:01 | LauJensen | 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 | amalloy | 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 | amalloy | 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 | ohpauleez | I'd tell nginx to cache static data, and I'd use a CDN where possible |
| 15:07 | ohpauleez | roll it out on Rackspace cloud or AWS, then get some monitoring in place... maybe ganglia and/or monit |
| 15:08 | ohpauleez | using pallet to do deploys |
| 15:08 | ohpauleez | 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 | btw0 | 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 | amalloy | &(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 | ohpauleez | but then went to vector |
| 15:19 | ohpauleez | not realizing it's keep the seq |
| 15:19 | ohpauleez | 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 | ohpauleez | :) |
| 15:19 | ohpauleez | 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 | sexpbot | 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 | jweiss | i want myfn to have 2 arities |
| 16:06 | jweiss | 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 | jweiss | (fn ([x] (println x)) ( [x y] (println x y))) |
| 16:10 | jweiss | 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 | LauJensen | You gotta love clojure.test |
| 16:40 | LauJensen | 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 | LauJensen | 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 | joshua__ | 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 | joshua__ | 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 | cemerick | 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 | cemerick | 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 | cemerick | 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 | _schulte_ | 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 | LOPP | I'm using Enlive, but I have problem getting it to read non-ascii characters from websites correctly |
| 18:00 | LOPP | 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 | raek | 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 | LOPP | :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 | LOPP | 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 | LOPP | 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 | LOPP | 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 | raek | 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 | LOPP | and I read a random site |
| 18:08 | LOPP | 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 | jk_ | 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 | raek | 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 | raek | 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 | raek | http://home.ccil.org/~cowan/XML/tagsoup/ |
| 18:12 | LOPP | :) |
| 18:12 | raek | jk_: well, that's what futures are for |
| 18:12 | raek | 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 | raek | (I have considered porting that myself) |
| 18:14 | raek | 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 | jk_ | 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 | raek | one way could perhaps be to create the handler function in the scope where the future is bound to a local |
| 18:20 | raek | so that it keeps a reference to the future in its closure |
| 18:21 | jk_ | oh! duh! a closure |
| 18:21 | jk_ | never mind...mild case of brain death here |
| 18:21 | jk_ | 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 | jk_ | 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 | jk_ | oh never mind |
| 19:37 | jk_ | amalloy: you're newly creating lookupfn since comp returns the new function |
| 19:38 | amalloy | right |
| 19:38 | amalloy | &(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 | jk_ | 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 | cemerick | Rich is definitely the benevolent dictator, though. |
| 20:17 | Lajla | They must be homosexual, there is no other explanation |
| 20:17 | Lajla | Why else would you contribute to Rich's core. |
| 20:17 | Lajla | All dictators style themselves as benevolent. |
| 20:18 | Lajla | 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 | danlarkin | 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 | Lajla | You are impersonating me. |
| 20:23 | Lajla | You're being my secret sockpuppet. |
| 20:23 | Lajla | 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 | joshua__ | so like (fn [(transform x)] .. ) |
| 20:24 | joshua__ | or is that not possible? |
| 20:25 | Lajla | cemerick, yes, answer for thy sins. |
| 20:25 | Lajla | That, or buy an indulgiance. |
| 20:25 | Lajla | either is cool |
| 20:25 | Lajla | 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 | joshua__ | [root-link root-page (rl-fetch-url root-link)] |
| 20:28 | joshua__ | 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 | amalloy | 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 | amalloy | 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 | bendlas | can someone confirm a stacktrace when doing |
| 20:49 | bendlas | lein install org.clojure/clojure 1.3.0-master-SNAPSHOT |
| 20:50 | bendlas | ? |
| 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 | bendlas | 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 | joshua__ | 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 | amalloy | 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 | joshua__ | 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 | joshua__ | 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 | amalloy | 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 | amalloy | 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 | joshua__ | 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 | joshua__ | oops |
| 21:24 | joshua__ | *wishes his teachers in college were more like the people in IRC* |
| 21:24 | joshua__ | gah, w/e, I don't know how to /emotes |
| 21:24 | amalloy | lol |
| 21:24 | amalloy | it's /me |
| 21:25 | joshua__ | .. thanks .. ;p |
| 21:26 | joshua__ | amalloy, so what do you mean by not gluing together the def and the fn? |
| 21:26 | joshua__ | 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 | amalloy | 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 | joshua__ | (what-func-given-this-input :some {:some "abc" :thing 123}) would produce this output -> {:thing 123} |
| 22:14 | joshua__ | &(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 | amalloy | 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 | brehaut | 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 | brehaut | 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 | tomoj | unfortunately ns-unmap appears to come first in clojure.core's ns-publics |
| 22:45 | tomoj | 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 | tomoj | :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 | brehaut | 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 | cemerick | 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 | joshua__ | [Thrown class java.lang.RuntimeException] isn't getting caught |
| 23:01 | amalloy | joshua__: that's probably a compile-time error |
| 23:01 | amalloy | attempting to destructure something that's not a list while expanding a macro |
| 23:02 | amalloy | 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 | technomancy | 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 | technomancy | joshua__: which is nonsense, but Clojure doesn't stop you from trying it =) |
| 23:14 | technomancy | 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 | joshua__ | 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 | joshua__ | &(-> + 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 | Lajla | Namespaces, right? |
| 23:23 | amalloy | &(macroexpand '#'when) |
| 23:23 | sexpbot | ⟹ (var when) |
| 23:24 | Lajla | I hate you |
| 23:24 | Lajla | 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 | Lajla | ~ 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 | Lajla | Ah |
| 23:27 | Lajla | amespaces |
| 23:27 | amalloy | Lajla: no. ` quotes with namespaces |
| 23:28 | amalloy | &`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 | Lajla | does it then break and? |
| 23:29 | Lajla | Because if has a different scope |
| 23:30 | Lajla | &(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 | Lajla | &(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 | Raynes | I know the problem, but I've been sick. |
| 23:33 | Raynes | 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 | joshua__ | (doseq [x (ns-publics (the-ns `clojure.core))] |
| 23:34 | joshua__ | (try |
| 23:34 | joshua__ | (if (= outputs (apply |
| 23:34 | joshua__ | (second x)) |
| 23:34 | joshua__ | inputs)) |
| 23:35 | joshua__ | (println (first x))) |
| 23:35 | joshua__ | (catch Exception _))))) |
| 23:35 | joshua__ | I've almost got it working. |
| 23:35 | joshua__ | 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 | joshua__ | https://gist.github.com/743037 |
| 23:36 | joshua__ | Help me to fix it? =)? |
| 23:36 | amalloy | joshua__: find-ns is trying print and println |
| 23:36 | amalloy | er, find-fn |
| 23:37 | joshua__ | OH. |
| 23:37 | joshua__ | I get it. |
| 23:37 | joshua__ | Okay that makes a lot of sense. |
| 23:37 | joshua__ | 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 | amalloy | $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 | joshua__ | 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 | joshua__ | bit-or |
| 23:46 | joshua__ | bit-xor |
| 23:46 | joshua__ | + |
| 23:46 | joshua__ | unchecked-add |
| 23:46 | joshua__ | nil |
| 23:46 | joshua__ | are the results |
| 23:46 | joshua__ | gisting the newest attempt |
| 23:47 | amalloy | joshua__: nice. that's like perfect |
| 23:47 | amalloy | 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 | joshua__ | 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 | amalloy | 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 | joshua__ | 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 | technomancy | niiice |