2011-02-04
| 00:27 | datka | why does (first (map (fn [x] (println x) x) [1 2 3])) print all 3 numbers? |
| 00:28 | brehaut | datka: presumably chunked sequences |
| 00:28 | brehaut | datka: also, you can simplify that map to (map println [1 2 3]) |
| 00:29 | datka | I was trying to use filter identity and first to evaluate only the first element that returned non-nil, but it's doing too many |
| 00:30 | datka | I wanted something that wouldn't retun nil |
| 00:30 | brehaut | datka: chunked sequences realise a small portion of the whole sequence to improve performance |
| 00:30 | brehaut | if you realy only want to print the first item, how about (println (first [1 2 3])) |
| 00:31 | datka | that was just an example, the actual function does a whole lot more |
| 00:31 | brehaut | ok sure |
| 00:31 | brehaut | i have to go sorry |
| 00:31 | datka | and I really don't want to process more than I have to |
| 00:32 | brehaut | but search about chunked sequences; i believe chris houser has a dechunkifiing function somewhere? |
| 00:32 | datka | I will, thanks |
| 00:32 | brehaut | sorry i cant be more help |
| 00:33 | dnolen | datka: or if you're building the sequence to be consumed, you can force it to be one at a time. |
| 00:37 | datka | currently, the sequence is a vector stored in a ref. |
| 00:38 | dnolen | datka: if it's a vector, then it's not actually going to 'process' more than you ask for. |
| 00:38 | dnolen | datka: what I mean if you're not doing sideeffects, does it matter? I suppose the operation you're doing is expensive? |
| 00:39 | datka | actually, it looks like it's really the result of mapping over a vector |
| 00:39 | datka | There are some side effects (logging) and it's pretty expensive |
| 00:40 | datka | think processing the routes for every page in an application on every request |
| 00:43 | datka | I got it |
| 00:46 | dnolen | ,(letfn [(lazier [l] (lazy-seq (cons (first l) (lazier (next l)))))] |
| 00:46 | dnolen | (first (map (fn [x] (println x) x) (lazier [1 2 3])))) |
| 00:46 | clojurebot | EOF while reading |
| 00:46 | dnolen | ,(letfn [(lazier [l] (lazy-seq (cons (first l) (lazier (next l)))))] (first (map (fn [x] (println x) x) (lazier [1 2 3])))) |
| 00:46 | clojurebot | 1 |
| 00:46 | clojurebot | 1 |
| 00:46 | dnolen | is one way. |
| 00:47 | dnolen | probably want to use recur there. |
| 00:48 | dnolen | heh getting late, it's lazy-seq don't need recur |
| 00:48 | datka | get an error with recur |
| 00:49 | datka | perfect. That did exactly what I wanted |
| 00:51 | chouser | hm, map doesn't support chunked seqs when given more than one collection |
| 00:52 | zakwilson | What's the ETA on 1.3? Do most libs work with it yet? |
| 00:54 | chouser | ,(letfn [(lazier [coll] (map (fn [x _] x) coll (range)))] (first (map prn (lazier [1 2 3])))) |
| 00:54 | clojurebot | 1 |
| 00:55 | dnolen | chouser: heh |
| 00:55 | chouser | not sure that's any better, though |
| 00:55 | chouser | in fact, I'm pretty sure mine's worse. |
| 00:59 | dnolen | zakwilson: none that I'm aware of but who knows, a lot of documentation needs to be written up. |
| 01:15 | sritchie | edw: hey, you don't happen to be a cascalog user, by any chance |
| 01:16 | amalloy | chouser: isn't (fn [x & _] x) effectively (comp first list)? |
| 01:17 | hiredman | (fn [[x]] x) please |
| 01:18 | hiredman | (and preferably (comp first list)) |
| 01:26 | amalloy | hiredman: i always feel devious when i do something like (fn [[x]]) |
| 01:27 | hiredman | deliciously devious |
| 01:27 | amalloy | *chuckle* yeah, some of that too |
| 04:34 | neotyk | Good morning |
| 04:35 | brehaut | morning neotyk |
| 04:44 | ejackson | hey gents. |
| 04:46 | konr | hello |
| 05:01 | neotyk | in last talk by Stuart Halloway on InfoQ Clojure-Java Interop he mentioned some nice reflection/itrospection for Java classes, do you remember what was it? |
| 05:24 | no_mind | how can I append values to a vector |
| 05:24 | ejackson | conj |
| 05:25 | raek | no_mind: (conj [1 2 3] 4) (conj [1 2 3] 4 5) (into [1 2 3] [4 5]) |
| 05:25 | no_mind | thnxs |
| 05:31 | no_mind | not working... basically I want a function which returns a vector. The items of vector are generated with some logic. Any example of this ? |
| 05:31 | ejackson | (into [] (my-logic-generating-a-seq-of-values)) |
| 05:33 | no_mind | ejackson: what if I have a pre-defined vector to which I have to ad values. lets say (def vt [1 2]) . Now I want to add values to vt |
| 05:33 | Chousuke | you can't change vt |
| 05:33 | Chousuke | you can only create a new vector |
| 05:33 | Chousuke | design your code so that that is not a problem :) |
| 05:34 | no_mind | k |
| 05:34 | ejackson | yeah, so create a function that takes in vt as an argument, then conj's to it thereby creating a NEW vector which is returned by the function |
| 05:34 | Chousuke | if you really need state, you can use atoms or refs or agents |
| 05:35 | Chousuke | but *most* of your code should be stateless |
| 05:35 | Chousuke | if you have more than a couple refs, something is probably wrong |
| 05:35 | Chousuke | ie, don't wrap a vector in ref just so you can mutate it |
| 05:44 | no_mind | Chousuke: ejackson I am pulling some stuff from db and have to return it as json. The clj-json/generate-string requires a vector. What si teh best way to solve this |
| 05:47 | ejackson | no_mind: this depends on a lot of stuff. I generally use read-json which takes the string that the db returns and returns an appropriate data structure. |
| 05:47 | neotyk | no_mind: (into [] (map . .)) |
| 05:48 | no_mind | this is what I did (into [] (doseq [i (range 0 10)]{:name "test" :id i}) |
| 05:48 | no_mind | but not working |
| 05:49 | Chousuke | doseq is for side-effects |
| 05:49 | no_mind | k |
| 05:49 | Chousuke | you want for, it generates a sequence |
| 05:49 | Chousuke | ,(for [i (range 5)] (- i)) |
| 05:49 | clojurebot | (0 -1 -2 -3 -4) |
| 05:49 | neotyk | ,(doseq [i (range 0 10)] i) |
| 05:49 | clojurebot | nil |
| 05:50 | Chousuke | ,(doseq [i (range 5)] (print i)) |
| 05:50 | clojurebot | 01234 |
| 05:50 | Chousuke | see, side-effects only |
| 05:51 | Chousuke | generally anything with a do-prefix is for side-effects |
| 05:51 | Fossi | ,(print "foo") |
| 05:51 | clojurebot | foo |
| 05:51 | no_mind | ok |
| 05:51 | Fossi | ,(print ",(print \"foo\")") |
| 05:51 | clojurebot | ,(print "foo") |
| 05:51 | Fossi | smart bot |
| 05:51 | ejackson | no_mind: so just replace the doseq in your code with for, and it'll work |
| 05:52 | no_mind | k let me try |
| 05:52 | Fossi | ,(print "/msg clojurebot ,(print \"foo\")") |
| 05:52 | clojurebot | /msg clojurebot ,(print "foo") |
| 05:52 | ejackson | no_mind: you can also replace "into []" with plain "vec" |
| 05:53 | no_mind | k |
| 05:53 | Fossi | funky |
| 05:53 | Fossi | ,(print "foo") |
| 05:53 | clojurebot | foo |
| 05:54 | Fossi | i guess clojurebot has been tested against a huge amount of attackvectors in the last year :D |
| 05:59 | raek | &(print ",(print \"foo\")") |
| 05:59 | sexpbot | ⟹ ,(print "foo")nil |
| 06:00 | raek | ,(print "&(print \"foo\")") |
| 06:00 | clojurebot | &(print "foo") |
| 06:00 | sexpbot | ⟹ foonil |
| 06:08 | zoldar | hello; is there a way to pass arguments from vector while making an instance of a class? Something like (apply new clazz args) - this one does not work because "new" is a special form. Is there some way around? |
| 06:10 | raek | zoldar: you can wrap the constructor in a function if you know the number of arguments: (map #(Foo. %) [1 2 3]) |
| 06:11 | zoldar | raek, won't it create 3 different instances ? |
| 06:11 | raek | zoldar: otherwise, you have to use reflection. clojure.lang.Reflector can help you with that. |
| 06:11 | raek | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java |
| 06:11 | raek | yes, this was just an example of how you can make a constructor "function like" |
| 06:12 | zoldar | ok, so it's not possible without ugly hacks |
| 06:12 | raek | but I see that was not maybe what you needed |
| 06:12 | raek | no |
| 06:12 | clgv | zoldar: it's not an ugly hack to have a constructor method ;) |
| 06:12 | clgv | s/constructor/factory |
| 06:12 | sexpbot | <clgv> zoldar: it's not an ugly hack to have a factory method ;) |
| 06:13 | zoldar | ok, thanks |
| 06:14 | raek | when the compiler sees (Foo. x), it will look up what constructors are avaiable and compile code that uses one of those |
| 06:14 | raek | if you want to choose which constructor to use (arity, signature types) at runtime, reflection is the only option |
| 06:15 | zoldar | understood |
| 06:16 | raek | (Reflector/invokeConstructor clazz (into-array args)) |
| 06:16 | zoldar | well, on the other hand, (defmacro make-instance [clazz & args] `(new ~clazz ~@args)) should also do the job in the end |
| 06:17 | clgv | zoldar: looks like it would ;) |
| 06:17 | no_mind | is there a package to read config file in clojure ? |
| 06:17 | raek | well, you can't apply a macro, but for making the syntax prettier, yes. it would work. |
| 06:18 | zoldar | raek, crap, forgot about it |
| 06:18 | zoldar | anyways that's still some option |
| 06:19 | raek | ,(fn [] (Integer. :foo :bar :baz)) |
| 06:19 | clojurebot | java.lang.IllegalArgumentException: No matching ctor found for class java.lang.Integer |
| 06:20 | raek | yeah, the constructor needs to be found at compile-time (when using new/Class.) |
| 06:36 | zoldar | so (clojure.lang.Reflector/invokeConstructor Integer (object-array [4])) is the way to go ? |
| 06:43 | zoldar | http://paste.lisp.org/display/119370 works ok; I wonder - is it so uncommon case that it's not in core? or is it something awfully bad to do in a way I'm missing? |
| 06:53 | Chousuke | I've never had need for anything like that :/ |
| 06:55 | zoldar | ok, it must be me then |
| 06:55 | Chousuke | it'd probably be a lot faster to just have a cond with different (Class. a b c) calls in each branch |
| 06:56 | Chousuke | reflection is rather slow |
| 06:56 | Chousuke | also you don't need to name the parameter "clazz". class is just fine :) |
| 06:56 | Chousuke | the function is short enough that shadowing the class function does not matter. |
| 06:58 | zoldar | just for the record, my use case for that: http://paste.lisp.org/display/119371 |
| 06:59 | zoldar | Chousuke, right, I've just seen "clazz" a couple of times when examining some libraries and took it as a some sort of convention |
| 07:00 | Chousuke | it's probably some java habit |
| 07:00 | Chousuke | where class is a keyword that you can't use as a parameter |
| 07:00 | Chousuke | +name |
| 07:02 | Chousuke | style nitpick: your (swap! regisrtry #(...)) thing is equivalent to (swap! registry assoc listener message) |
| 07:02 | Dranik | hi all! |
| 07:03 | Dranik | I have just managed to create an example of how to automate java patterns implementation using clojure! Yahoooo! :-) |
| 07:03 | zoldar | Chousuke, right, must have overlooked this, thanks |
| 07:03 | Chousuke | zoldar: also, AFAIK the I prefix is generally not used with protocols. |
| 07:03 | Chousuke | but other than that, I guess what you're doing is fine :/ |
| 07:04 | zoldar | Chousuke: hmm, I guess I'm looking at the wrong code :) I recall seeing it in the joy of clojure |
| 07:04 | Chousuke | it doesn't look like you'll be creating very many of those listener instances |
| 07:04 | Chousuke | hmm |
| 07:04 | Chousuke | in Clojure itself I is used for interfaces. |
| 07:05 | Chousuke | and while protocols do generate an interface, it's more of an implementation detail |
| 07:05 | zoldar | Chousuke, generally, there will be only one instance of ListenerRegistry, but I can't think of some better way of putting it together |
| 07:06 | zoldar | although, there may be at some point need for more than one registry |
| 07:06 | Chousuke | also do protocols even support varargs? :/ it might've been fixed but that wasn't the case last time I checked. |
| 07:06 | zoldar | what do you mean by varargs ? |
| 07:06 | Chousuke | & args |
| 07:06 | sexpbot | java.lang.Exception: Unable to resolve symbol: args in this context |
| 07:06 | Chousuke | sexpbot: :P |
| 07:07 | zoldar | hmm, I haven't tried it yet |
| 07:08 | Chousuke | you might get weird behaviour |
| 07:08 | Chousuke | since & will actually get a parameter bound to it |
| 07:08 | zoldar | I'll fall back to a seq then |
| 07:08 | Chousuke | so your register method takes six parameters, including this :) |
| 07:08 | zoldar | not too neat but still.. |
| 07:09 | zoldar | 5 |
| 07:09 | Chousuke | no, I mean the way you've written it |
| 07:09 | Chousuke | _, owner, message, listener-class, &, and args :P |
| 07:09 | zoldar | aah |
| 07:09 | zoldar | nasty |
| 07:10 | Chousuke | the macro could probably warn about that :/ |
| 07:10 | zoldar | compiler could've warned about it |
| 07:10 | Chousuke | it seems to be a common mistake. |
| 07:12 | zoldar | I wonder - how clojure-in-clojure will cope with this whole interop mess? Will it be completely platform agnostic? |
| 07:14 | Dranik | zoldar, do you mean that somebody is developing clojure in clojure? |
| 07:15 | zoldar | Dranik, umm don't current efforts go into that direction? beyond 1.3? |
| 07:15 | zoldar | *in |
| 07:15 | Dranik | zoldar, actually I don't know much about 1.3 that's why I'm so curious |
| 07:16 | zoldar | well I'm not knowledgeable enough to give any details about this, that's just what I've heard/seen - maybe I was hallucinating ;) |
| 07:17 | Dranik | zoldar, :-) |
| 07:17 | zoldar | random search result: http://blog.n01se.net/?p=41 |
| 07:18 | Dranik | zoldar, OK, we have to wait for rhikie and ask him. Guess, he knows... |
| 07:20 | zoldar | there's even a bullet point under "Long-term" on http://clojure.org/todo |
| 07:20 | Dranik | btw, how is ClojureCLR? Is it still alive? |
| 07:20 | zoldar | Dranik: I can confirm that it is :) |
| 07:20 | Dranik | :-) |
| 07:20 | zoldar | had opportunity to get in touch with dmiller |
| 07:21 | zoldar | there was a bug in compilation procedure - he was very responsive |
| 07:21 | zoldar | even though the problem was messy, 3 days later the fix was there |
| 07:21 | Dranik | great! |
| 07:22 | Dranik | may be one day I'll code Clojure in .NET! |
| 07:23 | Dranik | zoldar, seems like the day when Clojure will be as powerfull as CL is near... |
| 07:23 | no_mind | how do I find value of a key form a hash-map |
| 07:23 | Dranik | pity, no reader macros in long terms... |
| 07:24 | zoldar | Dranik, well, I'm not the one to judge about that ;) |
| 07:24 | zoldar | Dranik - I thought that clojure actually has these already |
| 07:24 | Dranik | zoldar, its macrosystem lacks some points which CL has |
| 07:24 | zoldar | I confess, that I didn't try using these |
| 07:25 | zoldar | I talking about reader macros |
| 07:25 | zoldar | *I'm |
| 07:27 | zoldar | ok, I was wrong, it's achieveable by some sort of hackery: http://briancarper.net/blog/449/ |
| 07:29 | Dranik | zoldar, wow, that's great!! |
| 07:31 | zoldar | ,({:a 1 :b 2} :a) |
| 07:31 | clojurebot | 1 |
| 07:31 | zoldar | <== no_mind |
| 07:32 | zoldar | or maybe I misunderstood |
| 07:33 | no_mind | zoldar: thanks, I figured that out :) |
| 07:38 | ejackson | oh man, when it works, coding is such a rush ! |
| 07:40 | zoldar | ejackson, unfortunately for me it doesn't work more often than does, but that may be just sucky me |
| 07:40 | ejackson | oh me either, but its those rare and precious times that make it worthwhile |
| 09:02 | arnorhs | Is clojure usable without contrib? |
| 09:02 | jweiss_ | sure |
| 09:02 | Dranik | yep |
| 09:03 | arnorhs | but isn't there a whole lot of stuff that relies on it? |
| 09:03 | jweiss_ | any emacs user here able to tell me if I can get method signature in the repl for java method calls (in this case a constructor) |
| 09:03 | jweiss_ | by repl i mean swank |
| 09:03 | jweiss_ | slime, whatever |
| 09:03 | Dranik | arnorhs, so what's the problem? just add it to the classpath |
| 09:03 | arnorhs | no problem |
| 09:04 | arnorhs | i'm just wondering exactly what it's purpose is |
| 09:04 | arnorhs | i've always just installed it without thinking much about it |
| 09:04 | Dranik | arnorhs, it is "batteries" |
| 09:04 | arnorhs | isn't it a library? |
| 09:04 | Vinzent | jweiss_, if clojure, you can use smth like clojure.contrib.repl-utils/show |
| 09:04 | Dranik | yep, its a library |
| 09:05 | arnorhs | does eg. compojure rely on it? |
| 09:05 | jweiss_ | Vinzent: i mean a builtin emacs function, to show the signature in the minibuffer space |
| 09:05 | Dranik | arnorhs, guess so, bcs contrib has lots of good stuff |
| 09:05 | zoldar | is there a way to avoid writing macro in case when the only thing i need is unquote splice (~@) operator ? |
| 09:06 | Vinzent | jweiss_, don't think that slime have java support |
| 09:06 | pdk | zoldar, apply |
| 09:06 | zoldar | isn't do a special form ? |
| 09:06 | arnorhs | I've just never thought much about it, I might start a new vm and see how far I can go without it |
| 09:06 | pdk | (apply + 1 2 [3 4 5]) -> (+ 1 2 3 4 5) |
| 09:06 | zoldar | i mean (apply do body) instead of ~@body |
| 09:07 | pdk | i don't see why you'd do it that way |
| 09:07 | Dranik | zoldar, write a macro which transforms your quoted code |
| 09:07 | Dranik | zoldar, sorry, not macro but a function |
| 09:07 | arnorhs | what about the java build tools, ant & maven. Would most clojure apps work without them? Doesn't lein depend on those? |
| 09:07 | Vinzent | zoldar, you can use ` in fns |
| 09:08 | pdk | ~ ` and ~@ can be used outside of macro definitions |
| 09:08 | clojurebot | macro are just a game with symbols |
| 09:08 | zoldar | Vinzent, ok I'll try |
| 09:08 | pdk | basically anywhere you could use ' |
| 09:10 | zoldar | ok, got it, neat |
| 09:17 | mattmitchell | how can i do a file path join? |
| 09:18 | zoldar | mattmitchell, clojure.contrib.duck-streams/file-str |
| 09:18 | sgronblo | Any vim users? Is there an easy way to get these rainbow parentheses and syntax highlighting without these slime-whatevers? |
| 09:18 | mattmitchell | zoldar: thanks! |
| 09:18 | zoldar | mattmitchell, but it seems to return java.io.File already |
| 09:21 | fliebel | $seen tonyl |
| 09:21 | sexpbot | tonyl was last seen talking on #clojure 2 days and 16 hours ago. |
| 09:23 | pdk | easiest way is probably just to intall vimclojure sgronblo |
| 09:23 | fliebel | pdk: easy? it took me hours to figure out all the conflicting instructions for the config and nailgun. |
| 09:24 | pdk | i kinda gave up on the nailgun part of it too |
| 09:24 | pdk | though if he just wants a more clojure friendly text editor the base plugin does the job |
| 09:24 | sgronblo | pdk: but you can install vimclojure without bothering with this nailgun and stuff |
| 09:24 | sgronblo | ? |
| 09:24 | fliebel | you can |
| 09:25 | pdk | i just ignored nailgun since i already had back luck trying to make emacs + slime work on windows |
| 09:25 | pdk | either that or i'm that bad with emacs :p |
| 09:25 | pdk | bad luck even |
| 09:25 | zoldar | when I want to set an atoms contents to a completely new value, should I use reset! ? or are there cases where using (swap! foo #(fn [_] newval)) is preferred? |
| 09:25 | pdk | reset! is more concise |
| 09:25 | pdk | maybe if the fns you're using to alter the atom are being generated on the fly |
| 09:26 | fliebel | zoldar: reset!, but if you wanted to do what you did, you'd use constantly. |
| 09:26 | pdk | ,((constantly 1)) |
| 09:26 | clojurebot | 1 |
| 09:27 | zoldar | (swap! foo constantly 1) ? |
| 09:28 | fliebel | zoldar: That would swap foo with a function that returns… the previsou valua and 1 or whatever. |
| 09:28 | pdk | (constantly x) is shorthand for creating a function that just returns the same x every time |
| 09:28 | pdk | ,(constantly 1) |
| 09:28 | fliebel | &(swap! (atom 2) (constantly 1)) |
| 09:28 | sexpbot | ⟹ 1 |
| 09:28 | clojurebot | #<core$constantly$fn__3551 clojure.core$constantly$fn__3551@223be4> |
| 09:28 | pdk | ,#(1) |
| 09:28 | clojurebot | #<sandbox$eval108$fn__109 sandbox$eval108$fn__109@497536> |
| 09:28 | zoldar | ok, it seems that it doesn't make sense anyway; I just recall someone somewhere advising for using swap! over reset! in some cases. I can't recall the detials |
| 09:28 | zoldar | ok, got it |
| 09:29 | pdk | we've seen a few insane suggestions from blog posts linked here before :p |
| 09:29 | zoldar | that's why I'm asking - to set the record straight :) |
| 09:29 | fliebel | zoldar: If you look at the source, it uses atomicreference. swap uses compareAndSet, whule reset! just uses set. |
| 09:30 | fliebel | this means that reset! will have a lot less overhead. |
| 09:30 | pdk | swap! is p much for making changes to the atom relative to its current value |
| 09:30 | pdk | things like adding 1 to it etc, stuff where the original value is going to be an operand |
| 09:31 | pdk | ,(let [x |
| 09:31 | clojurebot | EOF while reading |
| 09:31 | pdk | ,(let [x (atom 1)] (swap! x inc) x) |
| 09:31 | clojurebot | #<Atom@d0005e: 2> |
| 09:32 | zoldar | I know, I just thought that maybe there's some merit to this, which I could be missing, like some marginal case in highly concurrent situations, but I see it isn't so |
| 09:33 | fliebel | zoldar: 2 paralel changes might leave behind a different result depending if you use swap or reset. |
| 09:33 | zoldar | fliebel, but it isn't predictable anyway |
| 09:33 | fliebel | with reset, the last change wins, while with swap, the first retries. |
| 09:40 | semperos_ | say I have a merge-with like this |
| 09:40 | semperos_ | (merge-with (fn [v1 v2] (if (= "foo" v1) v1 v2)) m1 m2) |
| 09:40 | semperos_ | how would I use that function within a (dosync (alter...)) ? |
| 09:43 | semperos_ | I can understand the syntax for something like assoc-in, where the ref is the first param |
| 09:43 | semperos_ | (dosync (alter my-ref assoc-in [:foo :bar] "baz")) |
| 09:43 | jweiss_ | is there really no help from slime to see the method signature of a java class's constructor? do i have to open up the source? |
| 09:44 | jweiss_ | for instance if i type "(String. " |
| 09:44 | jweiss_ | and i want to see all the types the string constr will take? |
| 09:45 | jweiss_ | i notice the inspector gives sigs but not for constructors |
| 09:45 | jweiss_ | i was thinking more like the minibuffer with clojure fns |
| 09:45 | jweiss_ | that shows what args it takes |
| 09:45 | pjstadig | jweiss_: patches welcome :) |
| 09:46 | semperos_ | I don't know how, but considering java classes can have a whole bunch of constructors, I just keep the javadoc handy |
| 09:46 | jweiss_ | hm ok. i'd love to submit a patch, but not sure if i'm up to the task. just wanted to check that it hasn't been done so i can stop searching google :) |
| 09:52 | shortlord | there is nothing like a reverse operation of 'frequencies' built-in, is there? |
| 09:53 | semperos_ | maybe a more general question is, how do I use functions with (alter) that take the value of the ref as the second param, instead of the first? |
| 09:54 | fliebel | shortlord: What would that do? |
| 09:54 | shortlord | fliebel: {:a 2, :b 1} -> (:a :a :b) |
| 09:55 | fliebel | shortlord: But maps are unordered… wel le me see... |
| 09:55 | zoldar | semperos_ : (alter foo #(somefun arg1 %)) ? |
| 09:56 | fliebel | &(mapcat #(repeat (val %) (key %)) (frequencies [:a :b :c :b :c :c])) |
| 09:56 | sexpbot | ⟹ (:a :b :b :c :c :c) |
| 09:56 | semperos_ | zoldar: trying... |
| 09:57 | fliebel | shortlord: ^ |
| 09:57 | shortlord | fliebel: yep, that's what I came up with as well, just wanted to make sure that there is nothing like that built in |
| 09:58 | fliebel | shortlord: I don't think so. Why would you need that? |
| 10:00 | shortlord | fliebel: well, the same question applies to frequencies, doesn't it? it's not too complex either, but is included in clojure.core. So I was wondering if something with the reverse effect was maybe included as well |
| 10:01 | fliebel | shortlord: Why do _you_ need it? I used frequencies a number of times, but never wondered if the opposite would be possible. |
| 10:01 | semperos_ | zoldar: trying to use merge-with within (alter) |
| 10:02 | semperos_ | (dosync (alter my-ref (fn [m] (merge-with my-func m another-m)))) |
| 10:02 | semperos_ | is what your suggestion looks like with that, but not working |
| 10:02 | zoldar | is another-m also a ref ? |
| 10:02 | semperos_ | no, it's just a map |
| 10:03 | semperos_ | plain (merge-with my-func m1 m2) works fine, with regular maps |
| 10:03 | semperos_ | trying to get it right within a doref alter, because I want to use it with a ref |
| 10:03 | semperos_ | *dosync alter |
| 10:04 | shortlord | fliebel: I guess I don't really need it. I wanted to figure out the total number of ordered things (the map stores ordered things + amount), but that could also be done using reduce |
| 10:04 | zoldar | semperos_, what error do you get ? |
| 10:04 | semperos_ | java.lang.String cannot be cast to java.util.Map |
| 10:04 | shortlord | if something like the reverse frequencies would have existed, I could have done (count (rev-frequencies map)) |
| 10:04 | semperos_ | stupid me |
| 10:05 | semperos_ | thanks for asking that, made me look harder |
| 10:05 | zoldar | so probably ref is string |
| 10:05 | semperos_ | nah |
| 10:05 | zoldar | i mean contents |
| 10:05 | bartj | why is this an infinite loop ? |
| 10:05 | semperos_ | another-m was a vector |
| 10:05 | bartj | , (doseq [i (range 10) j (range)] (println i j)) |
| 10:05 | zoldar | uh |
| 10:05 | fliebel | shortlord: Ah, right. Yea, it seems all the data you might want out of the unfrequenced list is contained in the map. |
| 10:05 | clojurebot | Execution Timed Out |
| 10:05 | semperos_ | I had used zipmap to create a new map from a couple of vectors |
| 10:05 | semperos_ | was mistakenly passing in the old vector (instead of the new map from zipmap) as the second map |
| 10:05 | semperos_ | thanks z |
| 10:06 | semperos_ | thanks zoldar |
| 10:06 | zoldar | semperos_, anyway you can use #(..) form instead of (fn [_] ...) |
| 10:06 | semperos_ | yeah |
| 10:06 | semperos_ | but I already had an anonymous function inside my merge-with |
| 10:06 | semperos_ | was getting a bit hard to read :) |
| 10:06 | zoldar | ah |
| 10:06 | fliebel | bartj: doseq loops the inner range first, which is infinite. |
| 10:06 | bartj | oh :( |
| 10:06 | shortlord | fliebel: yep, right now I am using (reduce #(+ %1 (val %2)) 0 map-with-products) |
| 10:06 | bartj | I'll just move it to the first then :) |
| 10:06 | bartj | fliebel, the same is with for, I guess |
| 10:07 | fliebel | bartj: doseq and for are nested, not parallel. |
| 10:07 | bartj | oh |
| 10:07 | bartj | double oh |
| 10:07 | bartj | how can I iterate parallely, and then stop when one of them gets over ? |
| 10:07 | fliebel | sot i't go like 0,0 0,1 0,2 … 1,0 1,1 ... |
| 10:07 | fliebel | map? |
| 10:07 | clojurebot | map is lazy |
| 10:07 | bartj | yeah |
| 10:07 | pdk | (doc dorun) |
| 10:07 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. dorun can be used to force any effects. Walks through the successive nexts of the seq, does not retain the head and returns nil." |
| 10:08 | pdk | (doc doall) |
| 10:08 | clojurebot | "([coll] [n coll]); When lazy sequences are produced via functions that have side effects, any effects other than those needed to produce the first element in the seq do not occur until the seq is consumed. doall can be used to force any effects. Walks through the successive nexts of the seq, retains the head and returns it, thus causing the entire seq to reside in memory at one time." |
| 10:08 | fliebel | &(map println [1 2 3] [4 5 6 7 8]) |
| 10:08 | sexpbot | ⟹ (1 42 5nil 3 6nil nil) |
| 10:08 | pdk | you could iterate over the seq returned by map with doseq and execute the bulk of what you wanted to do each step in the body |
| 10:09 | bartj | yeah, I could do that |
| 10:09 | fliebel | &(map + [1 2 3] [4 5 6 7 8]) |
| 10:09 | sexpbot | ⟹ (5 7 9) |
| 10:10 | bartj | is there "no" way apart from a map ? |
| 10:10 | fliebel | loop/recur... |
| 10:11 | bartj | I am returning stuff lazily |
| 10:11 | fliebel | bartj: What is wrong with map? |
| 10:11 | bartj | and loop/recur will require me to artificially create a new variable and store stuff in it |
| 10:14 | fliebel | bartj: ^ |
| 10:14 | bartj | fliebel, I am trying that |
| 10:14 | fliebel | ok |
| 10:14 | bartj | fliebel, thank you for your time and answers |
| 10:15 | fliebel | :) have fun |
| 10:24 | edw | Anyone here use the ZeroMQ glue for Clojure? The destroy-socket fn throws an exception because there's no underlying destroy method on the Socket object. There is a close method. I do not have a lot of confidence is the clojure-zmq module, for this and other reasons... |
| 10:42 | bartj | |
| 10:42 | clojurebot | java.lang.Exception: Unable to resolve symbol: mail in this context |
| 10:45 | bsteuber | Hi everyone |
| 10:45 | Dranik | bsteuber, hello! |
| 10:45 | bsteuber | do you think it might be clever to make ^"foo" behave like ^{:doc "foo"} ? |
| 10:46 | bsteuber | seems reasonable to assume a string is mosten often used for documentation |
| 10:48 | wolverian | cd .. |
| 10:48 | wolverian | ack. |
| 10:49 | edw | Is there a simple way to export constants in a namespace that are taken from a Java class? |
| 10:51 | bartj | edw, import-static ? |
| 10:51 | bartj | grr, why does sexpbot say I have a message |
| 10:51 | bartj | and how do I view it ? |
| 10:53 | edw | bartj: Hmm. I need them to be public. I'll just ask people to also import the Java classes in their code. |
| 10:59 | fliebel | bartj: type $mail, and he'll show you. |
| 10:59 | bartj | |
| 11:00 | jweiss_ | is there a simple way to call a java method given a list of args, similar to using a apply on a clojure fn? |
| 11:01 | bartj | fliebel, thank you |
| 11:01 | jweiss_ | ,(apply System/getProperty ["a" "g"]) |
| 11:01 | clojurebot | java.lang.Exception: Unable to find static field: getProperty in class java.lang.System |
| 11:01 | bartj | looks like someone sent me a mail |
| 11:01 | bartj | how about sending someone an email here? |
| 11:01 | bartj | that can be done using clojurebot ? |
| 11:01 | raek | jweiss_: clojure.lang.Reflector/invokeInstanceMethod |
| 11:01 | raek | https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Reflector.java#L23 |
| 11:02 | jweiss_ | raek, what about static methods |
| 11:02 | fliebel | $mail bartj it is the same command. |
| 11:02 | sexpbot | Message saved. |
| 11:02 | raek | bartj: $mail is a feature of sexpbot, not clojurebot |
| 11:02 | jweiss_ | raek: ah looks like that's in there too |
| 11:02 | raek | yup |
| 11:02 | bartj | |
| 11:03 | bartj | fliebel, cool |
| 11:06 | raek | looks like there is a clojure.reflect.java namespace in 1.3. interesting. |
| 11:07 | jweiss_ | ,(clojure.lang.Reflector/invokeStaticMethod System "getProperty" ["a" "b"]) |
| 11:07 | clojurebot | java.lang.IllegalArgumentException: No matching method found: invokeStaticMethod |
| 11:07 | jweiss_ | what's weird about this ^ is that the stack trace shows this exception is thrown BY invokeStaticMethod |
| 11:07 | jweiss_ | i'd sorta understand if it said "no matching method: getProperty" |
| 11:09 | raek | ,clojure.lang.Reflector |
| 11:09 | clojurebot | clojure.lang.Reflector |
| 11:10 | raek | jweiss_: I think you need to call invokeStaticMethod with an array |
| 11:11 | jweiss_ | raek: ah right. still that error message sucks |
| 11:11 | raek | there's also invokeStaticMehtodVariadic |
| 11:12 | raek | but it's true... the reflector tried to find a suitable invokeStaticMethod method, but could not find any with a compatible type signature... ;-) |
| 11:12 | raek | in this case, that method is involved on two different levels |
| 11:13 | mefesto | ,(clojure.lang.Reflector/invokeStaticMethod "java.lang.System" "getProperty" (into-array ["a" "b"])) |
| 11:13 | clojurebot | java.security.AccessControlException: access denied (java.util.PropertyPermission a read) |
| 11:13 | jweiss_ | mefesto: yeah i got it to work, i just don't understand how the call to public static Object invokeStaticMethod(Class c, String methodName, Object[] args) throws Exception |
| 11:13 | jweiss_ | worked at all when i passed it a vector. |
| 11:14 | jweiss_ | afaik a vector is not an array. |
| 11:14 | jweiss_ | oh wait |
| 11:14 | mefesto | it worked with a vector? |
| 11:14 | jweiss_ | no |
| 11:14 | jweiss_ | but i thought the error message sounded wrong |
| 11:15 | jweiss_ | but raek is right, the invokeStaticMethod was actually used to call itself. |
| 11:15 | jweiss_ | the inner invocation is what failed |
| 11:19 | jkdufair | how would i include a '.' in a GET request to a compojure route? I tried urlencoding it and also tried to read the clout src, but couldn't quite get it |
| 11:19 | jkdufair | i.e. http://localhost:8080/person/new/TheName/foo@bar.baz |
| 11:20 | jkdufair | it wants to treat the dot in the email as a separator |
| 11:30 | Vinzent | jkdufair, maybe "/person/new/:name/*" |
| 11:30 | mattmitchell | any opinions on clojure.test vs midje for testing? |
| 11:30 | fbru02_ | mattmitchell: i use lazytest |
| 11:30 | jkdufair | Vinzent: thx. I'll try that |
| 11:32 | fliebel | mattmitchell: have you considered clojure.core/test? < joke; I have no idea what the function is doing ##test |
| 11:32 | fliebel | &(doc test) |
| 11:32 | sexpbot | ⟹ "([v]); test [v] finds fn at key :test in var metadata and calls it, presuming failure will throw exception" |
| 11:34 | fliebel | What is the difference between all those testing frameworks? I mean, you but a bunch of assertions in a file, and see if they work. |
| 11:36 | semperos_ | fliebel: here's stuart sierra's thoughts on his work on clojure.test and then lazytest: http://stuartsierra.com/2010/07/05/lazytest-status-report |
| 11:37 | semperos_ | he's blogged about it more than once, so that's one place to read |
| 11:37 | jkdufair | Vinzent: worked! thank you. also makes me realize i need to understand defroutes even better |
| 11:39 | Vinzent | jkdufair, np :) |
| 11:40 | edw | If you've written some simple glue to project foo, what should one call the code? clj-foo? clojure-foo? |
| 11:43 | jkdufair | looks like a custom regex is my friend for this problem: ["/user/:id", :id #"[0-9]+"] |
| 11:47 | Vinzent | btw, I have a trouble with appengine-magic. When saving new entity, I'm passing nil as a value of the key, and both save! and retrieve works fine, but key of retrieved entities still contains nil. Am I doing something wrong? |
| 11:47 | Vinzent | an example: http://paste.lisp.org/+2K2Q |
| 11:50 | jkdufair | I'm just letting appengine generate its own ids for me. perhaps try capturing the result of the save! shouldn't it provide you an id? |
| 11:59 | Vinzent | jkdufair, no, it's nil too. It's weird that I can retrieve entity by the key, so entity saved properly, but value of the key field in retrieved record not setted. Looks like a bug, isn't it? |
| 12:00 | jkdufair | Vinzent: yeah it does, actually |
| 12:01 | jkdufair | does it happen in your local as well as at google? |
| 12:02 | Vinzent | haven't tested it yet |
| 12:04 | jkdufair | i'll try it on mine and see if it's doing the same here |
| 12:10 | Vinzent | jkdufair, same thing with dev_appserver.sh |
| 12:11 | jkdufair | ok. trying it out here |
| 12:14 | jkdufair | same thing here. can retrieve by id, but the :id slot is nil |
| 12:15 | jkdufair | btw, how do you run your tests using appengine-magic? |
| 12:16 | Vinzent | (use-fixtures :each (local-services)) just as sayed in readme |
| 12:18 | jkdufair | Vinzent: thx. missed that one |
| 12:48 | mduerksen | hmm, when i defrecord with a field named size, odd things can happen (clj1.3): when retrieving field like this, everything is fine: (:size obj). but when retrieving the field directly, it returns the number of fields: (.size obj) |
| 12:50 | amalloy | mduerksen: the . notation is overloaded between no-arg methods and fields |
| 12:52 | mduerksen | amalloy: shouldn't i be prevented from defining a record like this, or at least get a warning? |
| 12:54 | amalloy | mduerksen: maybe. i thought i saw somewhere a mechanism for resolving the difference, but i can't find it anymore |
| 12:55 | mduerksen | ok thanks amalloy. should i report this? |
| 12:55 | amalloy | but really i don't think you're supposed to be using (.field foo) notation for records anyway if you can help it |
| 12:56 | mduerksen | hmm, i like the . notation because its fast (and i need the speed in this case) |
| 12:56 | amalloy | mduerksen: so is (:field foo) |
| 12:57 | mduerksen | oh, so (:field foo) uses the records accessor? |
| 12:57 | amalloy | if the record is type-hinted, the compiler will resolve it for you; even if it's not, i believe there's some call-site caching that optimizes into (.field foo) until such time as you pass in a different class |
| 12:57 | mduerksen | that's interesting |
| 13:00 | amalloy | mduerksen: hm, for a trivial microbenchmark it looks like i might be wrong. a type-hinted record :field takes ~300% as long as .field |
| 13:00 | amalloy | ask hiredman though, he's always telling me how i'm wrong about records |
| 13:01 | mduerksen | woah! when not type-hinted, (.field foo) is a magnitude *slower* than (:field foo) - i guess its because (.field foo) needs casting |
| 13:01 | amalloy | mduerksen: it doesn't just need casting |
| 13:01 | amalloy | it needs reflection |
| 13:01 | amalloy | it's horrible |
| 13:01 | mduerksen | thanks, thats what i meant |
| 13:02 | chouser | type hinting won't help :field, I'm pretty sure. |
| 13:03 | amalloy | but yeah, mduerksen, it looks like hinted .foo is 3 times faster than :foo, which is...2000x faster than an unhinted .foo |
| 13:03 | mduerksen | my microbenchmark looked like this: (defrecord Test [mine]) (def t (Test. 5)) (time (dotimes [n 1e6] (:mine t))) vs. (time (dotimes [n 1e6] (.mine t))) |
| 13:03 | amalloy | so you get most of the benefit just using :foo |
| 13:04 | amalloy | mduerksen: yes, mine too |
| 13:06 | mduerksen | so it would be (.field foo) unhinted = 2000x (:field foo) = 6000x (.field foo) hinted. in that case, i will use (:field foo) normally and hinted (.field foo) in bottlenecks |
| 13:07 | hiredman | be sure not to just run it once for benchmarks, run it a few thousand times |
| 13:08 | mduerksen | hiredman: 1e6 should be enough to be stable |
| 13:16 | mefesto | anyone using clj-http ? |
| 13:42 | brehaut | mefesto: yeah |
| 13:51 | mefesto | brehaut: im trying to fetch binary data from a url any tips? |
| 13:51 | mefesto | brehaut: seems like it keeps sending it to me as a string |
| 13:52 | edw | What does doing an HTTP HEAD on the URL return, content-type wise? |
| 13:53 | mefesto | edw: application/pdf |
| 13:54 | edw | Hmm. What are you using to fetch the URL? |
| 13:54 | mefesto | (client/get url {:query-params {"id" "blah"}}) |
| 13:56 | mefesto | hoping for an input-stream like in clj-apache-http |
| 13:56 | benreesman | i appreciate this is sort of a weird question for this channel, but does anyone have a suggestion for which php web framework will be most comfortable for someone coming from a clojure mindset? |
| 13:57 | edw | Why aren't you using clojure.contrib.http.agent? |
| 13:58 | mefesto | edw: no reason, just thought i'd give this lib a try |
| 13:58 | brehaut | edw: if you are also using ring, clj-http is a good fit |
| 13:58 | technomancy | isn't contrib's http client deprecated? |
| 13:59 | edw | I'm not surprised that a random HTTP client library stringifies ecerything. |
| 13:59 | brehaut | edw: ring is the clojure web dev / http stack |
| 13:59 | mefesto | it's also v0.1.3 so maybe this is a bug ... although this is my first crack as using it so it's more likely my fault |
| 13:59 | brehaut | edw https://github.com/mmcgrana/ring |
| 14:00 | edw | Ah. I hope to never write another web app again. |
| 14:00 | mefesto | that's one thing that made me look at clj-http since middleware in ring is so handy and clj-http uses the same design i believe |
| 14:00 | brehaut | mefesto: it does |
| 14:01 | brehaut | mefesto: the default clj-http.client/get etc wrap up a core api with a heap of common middlewares for you |
| 14:01 | sritchie | has anyone here used leiningen with textmate? |
| 14:02 | sritchie | I use SLIME and emacs, but I need to ease a couple of guys into clojure, and they currently code in python, using textmate |
| 14:02 | mefesto | brehaut: just curious but is there an example of how one could wire up their own middleware into the request/response pipeline? |
| 14:02 | sritchie | any ideas on easing the learning curve? |
| 14:02 | brehaut | mefesto: https://github.com/getwoven/clj-http/blob/master/src/clj_http/client.clj |
| 14:02 | pdk | textmate has a clojure plugin |
| 14:02 | brehaut | mefesto: i think that page speaks for itself |
| 14:02 | pdk | failing that eclipse/netbeans/intelliJ all have their own as well |
| 14:02 | sritchie | pdk: it looks good, for the syntax, it just uses cake |
| 14:03 | sritchie | pdk: sorry, I mean it uses cake, not leiningen |
| 14:04 | brehaut | mefesto: i wonder if the wrap-output-coercion middleware is converting it to a string |
| 14:04 | mefesto | brehaut: so if i had my own middleware function (e.g. myns/wrap-custom) is there a way to get that into the chain? or do i have to update the client/request in a binding? |
| 14:04 | brehaut | mefesto: if you pass :as :byte-array in your request options, does it work? |
| 14:04 | brehaut | mefesto: make your own request, dont update the library binding |
| 14:04 | mefesto | brehaut: still a string |
| 14:05 | brehaut | thats surprising |
| 14:06 | mefesto | oh wait.. |
| 14:07 | mefesto | that works... sorry, i put :as :byte-array in the wrong place |
| 14:07 | mefesto | clj-apache-http style :-\ |
| 14:07 | brehaut | ah right. phew. |
| 14:07 | mefesto | brehaut: thanks for the help |
| 14:08 | brehaut | mefesto: no worries. i just read the code ;) |
| 14:16 | fliebel | I'm looking to split a url of unlimited length into pairs into a map. Would it be best to write a quick string split directly onto Ring, or does one of those router libs offer this? |
| 14:19 | fliebel | so a/url/of/pairs -> ["a" "url" "of" "pairs"] -> {:a "url", :of, "pairs"} |
| 14:23 | amalloy | *baffled* what websites use the url that way instead of using ?query parameters? |
| 14:23 | fliebel | amalloy: wordpress? |
| 14:24 | fliebel | no, not exactly that way... |
| 14:25 | fliebel | they do tag/blah or something similar. I want to extend that to multiple criteria. |
| 14:28 | fliebel | Is (apply array-map) a idiomatic way to turn a flat seq into a map? (into {}) expects pairs. |
| 14:29 | chouser | sure, apply array-map or hash-map |
| 14:30 | fliebel | chouser: Thanks. Please remember me of the difference. Something with guaranteed order and small lenghts? |
| 14:31 | fliebel | I think someone told me before, but I can;t find it. |
| 14:32 | technomancy | fliebel: array-maps grow into hash-maps when they get large enough; array-maps preserve order |
| 14:32 | technomancy | but in general you shouldn't care about the distinction between the two |
| 14:34 | amalloy | fliebel: (into {} (partition 2 blah)) if you wanted to let the runtime figure out whether to use arrays or hashes |
| 14:34 | fliebel | technomancy: Interesting idea… Around what length? Are we talking around hundreds of items, or just anything larger than a shopping list? |
| 14:35 | amalloy | fliebel: ten |
| 14:35 | amalloy | &(class (into {} (partition 2 (range 8)))) |
| 14:35 | sexpbot | java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.Map$Entry |
| 14:35 | fliebel | amalloy: ten? not even 32? 32 is still the chunk size, is it? |
| 14:35 | clojurebot | amalloy: therfor I return [previous] if rest is empty |
| 14:36 | fliebel | amalloy: Same problem here ;) |
| 14:36 | amalloy | right, maps don't like seqs, they want vectors :P |
| 14:36 | amalloy | &(class (into {} (map vec (partition 2 (range 8))))) |
| 14:36 | sexpbot | ⟹ clojure.lang.PersistentArrayMap |
| 14:36 | amalloy | &(class (into {} (map vec (partition 2 (range 22))))) |
| 14:36 | sexpbot | ⟹ clojure.lang.PersistentHashMap |
| 14:37 | fliebel | nice |
| 14:37 | fliebel | but, ugh, what a fuss to to get the map |
| 14:37 | amalloy | indeed. for urls, array-map is probably the way to go |
| 14:37 | fliebel | I figured so to. |
| 14:37 | amalloy | clojurebot: thanks for your suggestion, but as usual it is irrelevant |
| 14:37 | clojurebot | Ik begrijp |
| 14:37 | technomancy | clojure will do the right thing either way |
| 14:38 | amalloy | technomancy: ? |
| 14:38 | fliebel | & |
| 14:38 | sexpbot | java.lang.Exception: EOF while reading |
| 14:38 | fliebel | &(class (apply array-map (range 1000))) |
| 14:38 | sexpbot | ⟹ clojure.lang.PersistentArrayMap |
| 14:39 | fliebel | but assoc-ing that returns a hash-map |
| 14:39 | fliebel | I'm going to stare at the implementation for a while, to figure out why there is this distinction. |
| 14:40 | fliebel | static final int HASHTABLE_THRESHOLD = 16 |
| 14:40 | jcromartie | So I've been reading Out of the Tar Pit. |
| 14:41 | jcromartie | (uh oh) |
| 14:42 | semperos_ | using an atom to store a map; I run two swap!s, one after the other |
| 14:42 | semperos_ | the first swap changes the value of a key in the map |
| 14:43 | fliebel | hm, array-map does what it says on the tin. a map backed by a plain old array. now, over to hash-map, to see why array-map is needed. |
| 14:43 | semperos_ | the second does a merge-with to merge on a new map; the function passed to merge-with makes sure that, if a key has a particular value, it keeps that value instead of being replaced by the new map's |
| 14:43 | semperos_ | when I do this step-by-step at teh repl, it works fine |
| 14:43 | amalloy | fliebel: a linear scan is faster than the hashing overhead for small-enough maps |
| 14:44 | semperos_ | when I do it within a (let) in a function, it fails, the merge-with function doesn't do anything, a plain merge is performed |
| 14:44 | semperos_ | any thoughts? |
| 14:44 | mefesto | semperos_: what if you combined both actions into a single function and just called that with swap! ? |
| 14:44 | fliebel | amalloy: I think you are right. |
| 14:44 | raek | semperos_: can you post the code somewhere? |
| 14:44 | amalloy | fliebel: i know i am right :) |
| 14:44 | semperos_ | I can |
| 14:45 | semperos_ | mefesto: going to try your suggestion first |
| 14:45 | jcromartie | It seems like Clojure draws a lot from "Tar Pit" but there are no libs for the declarative languages used to define state, logic, and accidental useful state or control |
| 14:46 | fliebel | amalloy: I meant to say I was not even going to doubt it, the source code looks long, complicated, and mentions papers. |
| 14:46 | raek | if you want to keep the old values, can't you just do (merge new-map old-map)? |
| 14:47 | semperos_ | raek: yes, actually; I was caught up thinking about the fact that swap! and friends all take the derefed value as a first argument |
| 14:47 | semperos_ | but I can just use an anon fn and move it |
| 14:47 | semperos_ | raek: thanks |
| 14:47 | semperos_ | still curious why merge-with wasn't working though |
| 14:48 | raek | (swap! a #(merge %2 %1) m) (swap! a #(merge % m)) (swap! a (partial merge m)) |
| 14:48 | semperos_ | yep |
| 14:48 | semperos_ | needed fresh eyes, thanks |
| 14:50 | jaskirat | hey guys, i have been trying to understand recursive macros with this exaple in the practical clojjure book, but i cant seem to get it right. |
| 14:51 | raek | macros where the expansion contains the macro symbol? |
| 14:51 | jaskirat | i am trying to write a simpe macro to convert (++ 1 2 3 4) to (+ 1 (+ 2 (+ 3 4))) |
| 14:51 | jaskirat | can you help me point out why this doesnt work |
| 14:51 | jaskirat | (defmacro ++ [& e] (if (>= 2 (count e)) `(+ ~@e) `(+ ~@(first e) (++ ~@(rest e))))) |
| 14:51 | amalloy | jaskirat: macros are really just functions that operate on, and return, lists |
| 14:51 | jaskirat | yep |
| 14:52 | fliebel | jaskirat: Have a look at the source of -> for inspiration. |
| 14:52 | jaskirat | oops |
| 14:52 | jaskirat | (defmacro ++ [& e] (if (>= 2 (count e)) `(+ ~@e) `(+ ~@(first e) (++ ~@(rest e))))) |
| 14:52 | jaskirat | links? |
| 14:52 | raek | so you want (++ 1 2 3 4) to expand into (+ 1 (++ 2 3 4)) and then into (+ 1 (+ 2 (++ 3 4))) and so on? |
| 14:53 | amalloy | $source -> |
| 14:53 | sexpbot | -> is http://is.gd/KrdckN |
| 14:53 | jaskirat | raek: yes |
| 14:53 | jaskirat | amalloy: thanks |
| 14:53 | raek | jaskirat: have you used macroexpand-1 ? |
| 14:54 | raek | it's very useful for seing what your macro actually does |
| 14:54 | jaskirat | raek: yep it runs into a Don't know how to create ISeq from: java.lang.Integer |
| 14:54 | raek | jaskirat: I think ~@(first e) should be ~(first e) |
| 14:55 | jaskirat | raek: oh yeah ! because first doesnt return a list |
| 14:55 | jaskirat | raek: let me try! |
| 14:55 | mattmitchell | i have a quoted list like: '(double :key) and i'd like to grab the :key keyword, use it as a key on a hash that contains a number, and then apply it to double. How do I "eval" or execute double (the function) from a quoted form? |
| 14:55 | amalloy | &(reduce (partial list `+) [1 2 3 4]) |
| 14:55 | sexpbot | ⟹ (clojure.core/+ (clojure.core/+ (clojure.core/+ 1 2) 3) 4) |
| 14:56 | jaskirat | raek: awesome :) |
| 14:56 | jaskirat | raek: thanks a lot |
| 14:56 | fliebel | amalloy: Nice one :) |
| 14:56 | mattmitchell | i found that eval works, but is that the right way? |
| 14:56 | amalloy | jaskirat: my version expands in the opposite direction, but you might find it useful |
| 14:56 | raek | mattmitchell: you could do something like [double :key] or (list double :key) |
| 14:57 | jaskirat | amalloy: thanks , i was just learning about macros and trying em out |
| 14:57 | raek | then you will have the double function as the first element, rather than the symbol 'double |
| 14:57 | amalloy | mattmitchell: you'll need to eval if it's in a quoted list. is there a reason you can't have [double :key] instead, storing the actual function "double"? |
| 14:58 | mattmitchell | amalloy raek: ahh ok. no, i didn't think about doing it like that. |
| 14:58 | raek | mattmitchell: it's not very common to need to use eval (in my experience). most of the time, there is a more simple way |
| 14:58 | mattmitchell | raek: ok good then. my instincts were on to something. |
| 14:59 | raek | ,(let [pair [double :a], m {:a 1, :b 2}] (let [[f k] pair] (f (get m k)))) |
| 15:00 | clojurebot | 1.0 |
| 15:01 | amalloy | jaskirat: for sure, it's just good to keep in mind that you can write macros with list-manipulation functions as well as syntax-quote, especially when the latter will look convoluted |
| 15:03 | jaskirat | amalloy: i am very new to clojure, so i am not really aware of all list manipulation functions as of yet. That was new to me. |
| 15:04 | amalloy | jaskirat: there are a lot of such functions; it takes a lot of time to know "all" of them. but reduce, map, and iterate will get you most of the way |
| 15:04 | jaskirat | amalloy: that example that i was trying to solve was straight out of "practical clojure" and was wrong in the book but i could not figure out the bug |
| 15:05 | fliebel | Hm, I'm planning to do a XML DSL tomorrow. Core idea is that tags are lists with :namespaced/keywords and metadata. It'll be implemented on top of SAX. If you have ideas to share or want to nudge me into the right/a more sane direction, now is the time :) |
| 15:07 | jaskirat | amalloy: actually i was aware of map / reduce but your combination of partial along with this was particularly new. |
| 15:07 | amalloy | jaskirat: yeah, partial is crazy |
| 15:08 | fliebel | amalloy: Why and when do you use partial over an anonymous function? I like partial, but I had some discussions with people who prefer @() at all times. |
| 15:08 | fliebel | #() I mean |
| 15:09 | amalloy | fliebel: meh. you can't nest #() |
| 15:09 | amalloy | partial is overly verbose and prone to abuse, so i don't use it too often, but it seemed appropriate here |
| 15:10 | amalloy | i could have written instead ##(reduce #(list '+ %2 %1) [1 2 3 4]) and gotten the expansion order right, i think |
| 15:10 | sexpbot | ⟹ (+ 4 (+ 3 (+ 2 1))) |
| 15:10 | fliebel | amalloy: What abuse? |
| 15:12 | mattmitchell | how do you test whether or not something is a function? etc.. (function? (fn [])) => true |
| 15:12 | amalloy | mattmitchell: fn? or ifn? |
| 15:12 | amalloy | fliebel: if you start writing things like (map (partial map (partial apply +) ...)) your code gets to be unreadable |
| 15:12 | mattmitchell | amalloy: arg sorry :) i tried fun? func? and function? but not fn? |
| 15:12 | fliebel | mattmitchell: Beware of ifn though ##(ifn :a) |
| 15:12 | sexpbot | java.lang.Exception: Unable to resolve symbol: ifn in this context |
| 15:13 | fliebel | &(ifn? :a) |
| 15:13 | sexpbot | ⟹ true |
| 15:13 | amalloy | better to break it up into a couple explicit functions |
| 15:14 | amalloy | $findfn first true |
| 15:14 | sexpbot | java.lang.Exception: Unreadable form |
| 15:14 | amalloy | *blink* |
| 15:14 | amalloy | well, bugger that, i guess i have some debugging to do |
| 15:14 | fliebel | what would that do? |
| 15:14 | amalloy | fliebel: search for functions that return true when called on clojure.core/first |
| 15:15 | fliebel | amalloy: Does it do some clerer introspection, or does it try 500 functions to find ones that return true? |
| 15:15 | amalloy | the latter |
| 15:15 | fliebel | expensive... |
| 15:15 | amalloy | fliebel: not really |
| 15:16 | amalloy | $findfn [1 2 4 8] [8 4 2 1] |
| 15:16 | sexpbot | [clojure.core/rseq clojure.core/reverse] |
| 15:16 | fliebel | neat! |
| 15:16 | amalloy | see? takes less than a second, when it's not broken :P |
| 15:17 | sgronblo | heh thats pretty cool |
| 15:17 | fliebel | So next time I have someone ask for a function that transforms x into y, I can let sexpbot figure that out. |
| 15:17 | fliebel | amalloy: Does it work for multiple arguments? |
| 15:17 | amalloy | fliebel: indeed, but it's still pretty limited. it won't find partition for turning a list into a group of pairs, because it needs an additional 2 |
| 15:18 | amalloy | $findfn 1 2 3 6 |
| 15:18 | sexpbot | [clojure.core/+ clojure.core/*] |
| 15:19 | jaskirat | $findfn [1 2 3] 6 |
| 15:19 | sexpbot | [] |
| 15:19 | fliebel | amalloy: Yea, so it's limited to 1:1 matches, not the slightest fiddling. |
| 15:19 | amalloy | fliebel: yeah. i've pondered improving it somehow, but nothing seems clear or easy |
| 15:20 | jaskirat | $findfn [1 2 3] [6] |
| 15:20 | sexpbot | [] |
| 15:21 | fliebel | $findfn + [1 2 3] 6 |
| 15:21 | sexpbot | java.lang.Exception: Unreadable form |
| 15:21 | fliebel | hrm... |
| 15:21 | amalloy | fliebel: i think it doesn't like functions |
| 15:22 | amalloy | and i think i know why too; i'll poke around at it |
| 15:22 | fliebel | $findfn #(+ %1 %2) [1 2 3] 6 |
| 15:22 | sexpbot | java.lang.Exception: Unreadable form |
| 15:22 | Raynes | chouser: ping |
| 15:23 | amalloy | fliebel: if we're going to be spamming with sexpbot we should do it in #sexpbot |
| 15:37 | defn | any sign of stuart halloway's talk at clojure conj? |
| 15:39 | chouser | Raynes: pong |
| 15:43 | defn | yay for an activerecord-esque lib for clojure |
| 15:44 | Raynes | chouser: I've not yet been told how No Starch chooses tech reviewers, but the editor mentioned it, so I pointed out that you would be a good option if you were interested. Just thought I'd ask if you are and if so, if you could give me an email address to pass along, assuming they take my advice. |
| 15:44 | Raynes | No pressure to do so. You were just the first person that came to mind. |
| 15:48 | chouser | Raynes: to review your book? |
| 15:48 | Raynes | Right. |
| 15:48 | Raynes | They need a "hardcore Clojure guy". |
| 15:48 | Raynes | I'm not sure if they pay reviewers, but they probably do. |
| 15:49 | Raynes | At least, O'Reilly does. |
| 15:50 | chouser | Raynes: I use gmail -- you can guess my username. I'd like to know how long it is and when I would be able to start. |
| 15:52 | Raynes | chouser: I doubt the book will ever surpass 300 pages. The current draft is around 150 pages. At least, it is with my formatting. No clue what it'll be when they do whatever they do with it. I'll pass along your email address, and if he is interested, I'm sure he'll fill you in more throughly. |
| 15:53 | chouser | Raynes: thanks. |
| 15:58 | TobiasRaeder | hi :) |
| 15:59 | TobiasRaeder | can anyone explain to me when someone would use comp instead of ->/->>? comp seems to do the same (atleast to me) |
| 15:59 | chouser | -> and ->> are macros. comp is a function. |
| 15:59 | amalloy | TobiasRaeder: comp is a function, -> are macros |
| 15:59 | TobiasRaeder | good point :) |
| 15:59 | amalloy | chouser: that's what i get for pausing to confirm before i hit enter |
| 16:00 | chouser | heh |
| 16:00 | chouser | TobiasRaeder: http://blog.fogus.me/2010/09/28/thrush-in-clojure-redux/ |
| 16:00 | amalloy | TobiasRaeder: eg, (map (comp square inc) (range)) is hange |
| 16:00 | amalloy | hande |
| 16:00 | amalloy | handy. damn it |
| 16:00 | fliebel | And… comp can't take extra arguments, unless with #(), right? |
| 16:01 | amalloy | fliebel: shhhhh, you'll awaken a monad evangelist |
| 16:01 | TobiasRaeder | :D thanks for the infos |
| 16:02 | sgronblo | me too |
| 16:03 | amalloy | they're generalizations at a level more abstract than function composition. i still haven't gotten my head around when they would be useful in my code |
| 16:03 | amalloy | you can find a zillion tutorials of varying quality online |
| 16:03 | hiredman | a monad can be deconstructed into a protocol for passing arguments between functions and a protocol for binding names to values (which are really the same thing) |
| 16:04 | fliebel | Yea, there are to much monad tutorials out there. Maybe I should write one. |
| 16:04 | Chousuke | I wrote a toy protocol based monad interface once I think it's still somewhere on the internet :P |
| 16:04 | Chousuke | +. |
| 16:05 | amalloy | fliebel: nah. they're just like burritos |
| 16:05 | amalloy | $google monads are like burritos |
| 16:05 | sexpbot | First out of 252 results is: The Universe of Discourse : Monads are like burritos |
| 16:05 | sexpbot | http://blog.plover.com/prog/burritos.html |
| 16:05 | amalloy | fliebel: mexican food. tacos |
| 16:06 | fliebel | oh, well, second paragraph, and he used another word I don;t know LO |
| 16:06 | fliebel | (I need to stretch my fingers more when I reach to the right) |
| 16:07 | amalloy | facetious ~= joking |
| 16:08 | fliebel | amalloy: I was talking about functor |
| 16:08 | amalloy | fliebel: man, that's like the *third* paragraph |
| 16:08 | fliebel | amalloy: Dude, zero-indexed, you know ;) |
| 16:13 | jcromartie | Don't blubify Clojure by saying that you couldn't imagine why monads are useful :) |
| 16:14 | LauJensen | Morning guys |
| 16:16 | TobiasRaeder | hey lau :) |
| 16:16 | LauJensen | hey Tobias |
| 16:16 | fliebel | hey |
| 16:18 | fliebel | LauJensen: How vulnerable is CQL to SQL injection? Are all strings I use escaped, or ca I use literal SQL in there? |
| 16:18 | LauJensen | fliebel: ClojureQL keeps you 100% safe. It automatically parameterizes all queries |
| 16:18 | fliebel | good :) |
| 16:19 | fliebel | I asume there is a function for weird cases where you need real sql? |
| 16:19 | LauJensen | fliebel: Whereever possible I support literal strings, but if you need some really funky SQL, you need to submit a compiler for that backend |
| 16:20 | LauJensen | But it really does do most things |
| 16:21 | fliebel | okay :) I don't expect to encounter any of those cases with my limited sql knowledge. I have been meaning to try cql for a while now, but haven't done so yet. :( |
| 16:23 | LauJensen | I regularily get emails from people telling me how much they love it, so I assume its good :) |
| 16:23 | fliebel | :) |
| 16:44 | dnolen | I see two problems now w/ monads 1) not particularly efficient 2) inherently single-threaded. 1) seems like a hard problem to solve in the general case 2) can't do anything about that |
| 16:51 | Chousuke | dnolen: both 1 and 2 are false, unless you're talking about a specific implementation |
| 16:52 | Chousuke | any monad is free to combine operations in whichever manner it's programmed to do, and that includes running the ops in parallel. |
| 16:53 | Chousuke | at least, as far as I can tell, I'm not a monad expert either. :/ |
| 16:54 | hiredman | the new composable async Task stuff in C# and VB.Net is built on a monadic interface |
| 16:55 | brehaut | point #2 is one rhickey has made before |
| 16:56 | hiredman | well, that is not correct |
| 16:56 | brehaut | http://clojure-log.n01se.net/date/2010-02-12.html#i70 |
| 16:57 | hiredman | whats the link for? |
| 16:57 | brehaut | thats the previous discussion on the same |
| 16:58 | hiredman | if you are trying to convince me that rhickey said it, I believe you, but just because he said it, that does not make it correct |
| 16:59 | brehaut | of course it doesnt |
| 16:59 | hiredman | https://github.com/hiredman/die-geister is my take on the async Task stuff from C# |
| 16:59 | hiredman | (also F# has async too) |
| 17:00 | brehaut | F#'s async is great |
| 17:01 | hiredman | right, the reason you can compose async tasks is Task is a monad |
| 17:01 | brehaut | yes. |
| 17:01 | hiredman | (I think the f# paper on them calls them joinads) |
| 17:05 | brehaut | amalloy: monads are more about generalised function application than composition; arrows are the generalised composition |
| 17:06 | opqdonut | isn |
| 17:06 | opqdonut | 't Applicative generalised function application? |
| 17:06 | brehaut | depends how far you want to generalise |
| 17:06 | opqdonut | mhmm |
| 17:06 | hiredman | https://github.com/jduey/conduit |
| 17:07 | opqdonut | oh, this was #clojure |
| 17:07 | opqdonut | thought for a moment I was in #haskell |
| 17:07 | hiredman | :D |
| 17:08 | brehaut | its the armchair categorists meetup today |
| 17:08 | hiredman | (conduit is built on arrows) |
| 17:09 | brehaut | frightening and awesome :) |
| 17:09 | hiredman | we use it at work for our async messaging |
| 17:09 | hiredman | actually clojurebot uses it now too |
| 17:10 | hiredman | for streaming processing in clojurebot's case, not async messaging |
| 17:17 | brehaut | i dont know how i missed jim duey's stream articles |
| 17:17 | brehaut | they are really good |
| 17:24 | dnolen | http://www.mail-archive.com/haskell-cafe@haskell.org/msg71116.html |
| 17:24 | dnolen | monads are sequenced, not commutative. |
| 17:26 | dnolen | http://www.valuedlessons.com/2008/03/why-are-my-monads-so-slow.html |
| 17:26 | hiredman | dnolen: if I disgree more, will you spend more time googling about it? |
| 17:27 | dnolen | hiredman: why google when you can point me to better articles? |
| 17:28 | hiredman | dnolen: why would I do that? |
| 17:29 | dnolen | async ops still implied explicit sequencing, and that not a general concurrent framework anyhow. |
| 17:29 | dnolen | or rather it has a lot of assumptions about ho to solve the problem right? |
| 17:30 | hiredman | if you look at die-geister it allows you to join multiple async tasks into a single async task |
| 17:30 | hiredman | while not explicitly a monad the implementation is very similar to something like, uh, whats it called, fmap? for the list monad |
| 17:30 | brehaut | functor |
| 17:32 | dnolen | for example commute in Clojure's STM is an interesting solution to some problems, a monad can't capture that as far as I can tell. |
| 17:33 | hiredman | commute is not functional, why would you want to use that in a functional construct like a monad? |
| 17:36 | dnolen | hiredman: except people use monads to model state |
| 17:36 | hiredman | dnolen: they use monads to model state in a functional setting |
| 17:37 | hiredman | refs are mutable and not functional, so why would you do that? |
| 17:37 | Chousuke | state is not all monads are good for. |
| 17:37 | dnolen | Chousuke: I know that. |
| 17:37 | hiredman | (actually haskell's STM is exposed in a monad because they hide all mutable things in monads) |
| 17:40 | brehaut | hiredman: i think geister might be closer to an applicative than functor? |
| 17:40 | dnolen | http://www.mail-archive.com/haskell-cafe@haskell.org/msg82109.html |
| 17:41 | hiredman | brehaut: *shrug* |
| 17:41 | dnolen | in anycase, monads - big tradeoffs as with all things. |
| 17:42 | brehaut | the difference is that as well as being able to apply functions to thinks in the async context, it also has a way to apply functions that are in async contexts to other async contexts resulting in a new async context? |
| 17:42 | hiredman | dnolen: the issue there is the haskell type system doesn't express the constraits of being communicative |
| 17:42 | hiredman | brehaut: that is ultimately bind |
| 17:43 | hiredman | bind is like a protocol for binding names to values |
| 17:43 | brehaut | hiredman: its slightly less than bind i thing |
| 17:43 | hiredman | it is less then bind because I can't enforce the type |
| 17:43 | brehaut | hiredman: in haskell applicative is also less than bind even though they can enforce type |
| 17:44 | hiredman | I see |
| 17:44 | hiredman | but I want to enforce the type |
| 17:44 | hiredman | I just can't |
| 17:44 | brehaut | the type of yeh applicative operator (<*>) is f (a -> b) -> f a -> f b |
| 17:44 | brehaut | vs bind which is m a -> (a -> m b) -> m b |
| 17:45 | hiredman | if you are looking at the die-geister source I am very proud of blet and Bindable |
| 17:45 | hiredman | realizing I could do that as a protocol was so cool |
| 17:45 | brehaut | i am and agreed |
| 17:45 | brehaut | i liek the extension of deref to bindable too |
| 17:46 | brehaut | i cant find blet though |
| 17:46 | hiredman | maybe I never commited it |
| 17:47 | hiredman | it's a macro that expands to a let that calls bind on everything before binding it to a name |
| 17:48 | hiredman | (with the default extension of Bindable to Object being identity) |
| 17:48 | dnolen | my miniKanren work also made me suspect things like this - http://www.haskell.org/haskellwiki/Performance/Monads |
| 17:48 | dnolen | unrolling monads |
| 17:49 | brehaut | dnolen: even simple state-m definitions explode into frightening amounts of funcalling; adding any transformers on top is even more horrific |
| 17:50 | hiredman | I am by no means advocating monads everywhere, I am just saying they are extremely useful as a basis for library writers to ensure the composability of their code |
| 17:50 | hiredman | and that monads do not imply single threads of execution |
| 17:57 | brehaut | hiredman: re: applicitve and monad, i think monadic for can be defined for any applicative in terms as a >>= f = (pure f) <*> a. |
| 17:57 | brehaut | which muddies the waters between applicative and monad even more |
| 17:57 | brehaut | (pure being the applicative function to take something and put it into the appropriate applicative type0 |
| 19:53 | sritchie | does anyone have any advice on how to encode a float array as a byte array? |
| 19:54 | sritchie | I can map the array to a seq -- I'm just not sure how to get a byte representation of my float, for the map |
| 20:04 | amalloy | sritchie: make a ByteArrayOutputStream, wrap it in a DataOutput, write floats to it, then read them as bytes; or do the equivalent with buffers |
| 20:04 | amalloy | would be my hacky solution |
| 20:04 | sritchie | amalloy: this is sort of a hack, in any case -- hadoop can stream byte arrays, but not float arrays |
| 20:05 | sritchie | amalloy: I'll go check out io for outputstream |
| 20:06 | amalloy | i don't think c.j.io will have the necessary tools, you'll have to actually use java.io.XXX stuff |
| 20:06 | sritchie | amalloy: yeah, looks like it |
| 20:06 | sritchie | amalloy: it's odd, I'm searching all over, and this doesn't seem to be something anyone's been vocal about yet |
| 20:07 | sritchie | passing anything but byte arrays or heavy custom objects around |
| 20:07 | sritchie | or maybe it's considered trivial, who knows |
| 20:07 | amalloy | sritchie: hadoop will handle floats for you, won't it? |
| 20:08 | sritchie | amalloy: yes, but not float arrays |
| 20:08 | sritchie | amalloy: byte arrays can be wrapped in BytesWritable quite easily, |
| 20:08 | amalloy | but the underlying hadoop model is that most parts of the system deal with "data" they don't know anything about, which is what BytesWritable is for |
| 20:08 | amalloy | "here is a chunk of data, sritchie plz deal with it cause it is too confusing for the hadoop internals" |
| 20:10 | sritchie | amalloy: yeah, that's true - I do that for an inputformat I wrote that takes a single file at a time, rather than cutting text into lines, etc |
| 20:10 | sritchie | by opening a stream, and using IOUtils.readFully |
| 20:11 | sritchie | amalloy: so it sounds like your suggestion is the way to go, just copying that approach by streaming out these floats |
| 20:12 | sritchie | amalloy: that's hadoop's IOUtils, btw |
| 20:13 | amalloy | sritchie: hadoop's, or apache commons? it surprises me that hadoop would expose a way to read a file fully, with its "big data" approach |
| 20:13 | sritchie | hadoop's, actually -- http://bit.ly/h1JYXT |
| 20:13 | amalloy | fair enough |
| 20:38 | sritchie | amalloy_: so it looks like cascading does support byte arrays natively -- one just has to add the serialization beforehand |
| 20:38 | sritchie | now, I just need to find out how to do that in cascalog |
| 21:28 | joshua__ | $findfn nil false |
| 21:28 | sexpbot | [clojure.core/keyword? clojure.core/chunked-seq? clojure.core/sequential? clojure.core/fn? clojure.core/not= clojure.core/string? clojure.core/sorted? clojure.core/false? clojure.core/true? clojure.core/symbol? clojure.core/number? clojure.core/integer? clojure.core/... http://gist.github.com/812141 |
| 22:24 | trptcolin | so i'm teaching a clojure course in april - geared more towards the beginner end of the spectrum than most in the #clojure irc crowd |
| 22:24 | trptcolin | any tips on promotion? |
| 22:26 | trptcolin | details: http://8thlight.com/courses/2-clojure-functional-programming-on-the-jvm |
| 22:29 | amalloy | trptcolin: i wrote a blog post with that target audience last month; you might find some stuff you can use at http://hubpages.com/hub/What-is-Clojure |
| 22:30 | trptcolin | nice, that looks great! |
| 22:31 | amalloy | trptcolin: go spread links all over the internet; my coworker (at hubpages) needs to be constantly reminded that clojure generates more traffic than his silly hobbies :) |
| 22:31 | trptcolin | i do think i have a decent approach/handle on getting the material across once in the class, it's mostly getting people *to* the class i'm unsure about |
| 22:32 | trptcolin | good point. i don't want to come across as spammy though |
| 22:32 | amalloy | trptcolin: i kid, i kid. don't spam me |
| 22:32 | amalloy | or for me, rather |
| 22:32 | trptcolin | LOL |
| 22:34 | brehaut | trptcolin: just stay clear of fact and fib ;) |
| 22:35 | trptcolin | what? but how will i teach the joys of avoiding StackOverflowError ;) |
| 22:36 | brehaut | haha |
| 22:36 | amalloy | brehaut: haskell has spoiled you so much that you don't think (defn ! [n] (reduce * (range 1 (inc n)))) is elegant? |
| 22:37 | brehaut | amalloy: i love a good hylomorphism as much as the next nerd, but i dot think FP noobs care :P |
| 22:37 | amalloy | aha. yes, that is certainly true |
| 22:37 | trptcolin | oh snap you brought out the *morphism in #clojure |
| 22:37 | amalloy | lol |
| 22:37 | brehaut | it was worse earlier |
| 22:38 | amalloy | trptcolin: brehaut is from the wrong side of the tracks |
| 22:38 | brehaut | there was a spontaneous meeting of the armchair categorists |
| 22:38 | brehaut | yeah python and javascript ;) |
| 22:39 | brehaut | amalloy: also, you can hardly talk. all that point free? thats certainly from the dark side ;) |
| 22:44 | brehaut | amalloy: talking of point free, have you looked at conduit ? |
| 22:45 | amalloy | brehaut: i caught a link to it from twitter on the bus ride home, but barely glanced at it. the readme isn't very compelling :P |
| 22:45 | brehaut | hah |
| 22:46 | brehaut | its comp and juxt souped up with nos and a rocket booster |
| 22:57 | amalloy | brehaut: you should see the absolutely disgusting parsing functions i wrote for my markov bot. i really need to learn fnparse or parsec or something |
| 22:57 | brehaut | you absolutely do. parsec is the most elegant but fnparse looks solid |
| 22:58 | brehaut | i wrote a parser combinator library for python (its easy to write excruciatingly slow parser) and it made a bunch of day to day tasks a world easier |
| 23:00 | brehaut | need to find the time to learn fn-parse myself |
| 23:16 | amalloy | brehaut: when you do, please write up some cliff notes for me |
| 23:16 | brehaut | sure thing :) |
| 23:16 | amalloy | cause you're clearly my secretary |
| 23:16 | brehaut | clearly |
| 23:17 | brehaut | it'll makea good blog post anyways |