2010-01-08
| 00:01 | mebaran151 | heh, it's sort of sad that the Internet actually has so little commerce on it |
| 00:01 | defn` | i hereby ban everyone from using -> as a way of showing the return value of some function |
| 00:01 | defn` | use => or die |
| 00:01 | mebaran151 | what's the difference? |
| 00:01 | defn` | -> is in clojure, => isn't |
| 00:02 | mebaran151 | that's what I figured |
| 00:02 | mebaran151 | what do you have against the arrow? |
| 00:02 | defn` | nothing really, it just looks kind of like it could potentially br part of the source in certain contexts |
| 00:02 | defn` | be |
| 00:03 | mebaran151 | oh you mean in comments |
| 00:03 | defn` | like (let [var1 flat [[a [b]] c [[[d]]]] tree]) -> ("flat" "one" "two" "three" "four") |
| 00:03 | mebaran151 | ah yeah |
| 00:03 | mebaran151 | => is a lot clear |
| 00:03 | mebaran151 | *more clear |
| 00:04 | defn` | or maybe ~> |
| 00:04 | defn` | something that's not in clojure anyway |
| 00:04 | mebaran151 | nah ~> looks like a cool dereferencing macro |
| 00:04 | defn` | :) |
| 00:04 | somnium | maybe >>--> would be better |
| 00:04 | mebaran151 | -> brings back semi-fond memories of C |
| 00:04 | defn` | ooooo i like that somnium |
| 00:04 | mebaran151 | ++ |
| 00:05 | defn` | im working on getclojure.org and am trying to standardize on some bits of the example code |
| 00:05 | somnium | though it might be better to keep that for macros too :/ |
| 00:05 | defn` | http://getclojure.org/docs/_accessor |
| 00:05 | mebaran151 | defn, you should implement a repl like tryruby |
| 00:05 | defn` | mebaran151: someone did it already :) |
| 00:06 | mebaran151 | oh |
| 00:06 | mebaran151 | where's? |
| 00:06 | defn` | http://github.com/weavejester/clojure-over-ajax |
| 00:06 | JonSmith | horay! |
| 00:06 | mebaran151 | yeah it would be him |
| 00:07 | defn` | what do you guys think, is ;=> blah |
| 00:07 | mebaran151 | this looks way old and way overly complex |
| 00:07 | defn` | a good way of representing the output |
| 00:07 | defn` | mebaran151: it is definitely old |
| 00:07 | JonSmith | ; is a comment |
| 00:07 | defn` | i know JonSmith, see the above link |
| 00:07 | mebaran151 | somebody should steal clojurebots code and mod that |
| 00:07 | defn` | is that readable to you? |
| 00:07 | JonSmith | oh |
| 00:08 | JonSmith | yeah that looks fine |
| 00:08 | JonSmith | looks like a repl output |
| 00:08 | mebaran151 | => is far clearer |
| 00:08 | mebaran151 | to me at least |
| 00:08 | mebaran151 | because it's like the repl told me it |
| 00:08 | JonSmith | could even make it user=> or clojure=> |
| 00:08 | mebaran151 | that or a simple #, like in terminal tutorials |
| 00:08 | defn` | i need to edit the css of my code highlighter to treat comments a bit differently |
| 00:08 | JonSmith | or whatever the namespace is |
| 00:08 | mebaran151 | I'd just keep it => |
| 00:09 | JonSmith | yeah i think its readable |
| 00:09 | defn` | so it will add a bit of padding around a ; |
| 00:09 | JonSmith | to actually answer the question |
| 00:09 | mebaran151 | parsing clojure is probably pretty simple, just a bunch of s-expressions |
| 00:09 | defn` | JonSmith: k |
| 00:09 | mebaran151 | shouldn't you be using a straight fixed-width font |
| 00:10 | mebaran151 | and ~ is unquote |
| 00:10 | defn` | mebaran151: who me? |
| 00:11 | mebaran151 | yeah |
| 00:11 | mebaran151 | so ~> is actually legit clojure |
| 00:11 | defn` | mebaran151: sort of |
| 00:11 | defn` | ,~> |
| 00:11 | clojurebot | java.lang.IllegalStateException: Var clojure.core/unquote is unbound. |
| 00:11 | mebaran151 | it is in a defmacro |
| 00:11 | mebaran151 | if you wanted to buid some sort of custom comparator |
| 00:12 | defn` | nod |
| 00:12 | somnium | ,'~> |
| 00:12 | clojurebot | (clojure.core/unquote >) |
| 00:12 | defn` | indeed |
| 00:13 | somnium | ,(let [+ -] (+ 2 2)) |
| 00:13 | clojurebot | 0 |
| 00:14 | mebaran151 | I'm also trying to think of a good way to wrap netty |
| 00:14 | mebaran151 | to make it more clojure esque |
| 00:14 | somnium | mebaran151: if you do I will be a customer |
| 00:14 | mebaran151 | ah, you have any ideas |
| 00:14 | mebaran151 | I want to learn to netty to implement a nice socket server |
| 00:15 | mebaran151 | I basically get the system now |
| 00:15 | mebaran151 | I just need to figure out a way to make it pretty |
| 00:15 | mebaran151 | I have a basic wrapping that looks like bad Java |
| 00:15 | mebaran151 | (ie make-handler, tie-handler, make-pipeline) |
| 00:16 | somnium | hmm |
| 00:16 | mebaran151 | and I just want to wrap it something dare I say higher order |
| 00:16 | mebaran151 | for neo4j, it was natural just to use nested maps |
| 00:16 | mebaran151 | but I haven't found quite as clear a fit |
| 00:17 | somnium | ive this impression that clojure maps well to low level interfaces, since its so good at building abstractions |
| 00:17 | mebaran151 | well they're good when you have key values |
| 00:17 | mebaran151 | I was thinking of maybe a vector representing a pipeline |
| 00:17 | somnium | but it always seems more awkward to plug into a 'middle-level' java-api |
| 00:18 | mebaran151 | oh maps well as in relates well |
| 00:18 | mebaran151 | heh |
| 00:18 | mebaran151 | I read that as Clojure maps work well with |
| 00:18 | mebaran151 | (I've been programming too much today)( |
| 00:19 | mebaran151 | yeah midlevel java-apis always have a very strong flavor of their own |
| 00:19 | mebaran151 | but I haven't quite grok'ed java.nio yet |
| 00:20 | mebaran151 | it's not quite like the event based io I'm used to |
| 00:20 | somnium | I was never a java-dev, but Ive been trying to use nio for a tcp-ip client thing |
| 00:20 | somnium | nettys reviews were great but the annotations and javadocs ... |
| 00:20 | mebaran151 | netty is pretty powerful |
| 00:21 | mebaran151 | you can just plugin a handler and make it run |
| 00:21 | somnium | hmm |
| 00:21 | mebaran151 | the first thing I've done is created two gen-class to over the two annotation cases |
| 00:21 | mebaran151 | *to cover |
| 00:21 | mebaran151 | I haven't quite gotten everything to work yet |
| 00:22 | mebaran151 | usually I like to develop a representation and then code to make that work |
| 00:22 | somnium | Ill have to look at it again |
| 00:22 | somnium | or wait for you to make in work |
| 00:22 | mebaran151 | but it's whole stream model and channelhandler interface is just begging for Clojure functions |
| 00:23 | mebaran151 | what I want is a performant way to hook a the input of buffer and the output of a buffer into the input of a function and the output of a function |
| 00:23 | mebaran151 | i think that's the most functional way |
| 00:23 | somnium | that sounds cool, would make a very pleasant api |
| 00:23 | mebaran151 | with special ops :open and :close to represent opening and closing the channel |
| 00:24 | mebaran151 | (because there isn't any data there) |
| 00:26 | mebaran151 | should I pass clojure people the raw buffers or should I coerce to string? |
| 00:27 | somnium | anyway to parameterize it? raw buffers would be nice for perf in some cases I would guess |
| 00:29 | mebaran151 | yeah |
| 00:29 | mebaran151 | I'll think about these sorts of things |
| 00:29 | somnium | Ill watch for it |
| 00:30 | somnium | need to sleep for now |
| 00:30 | somnium | cheers |
| 00:31 | mebaran151 | thanks for your input |
| 01:04 | tomoj | hmm |
| 01:04 | tomoj | I forsee increased pressure to make clojure happy with dalvik |
| 01:09 | chouser | I thought it worked (a bit) already? |
| 01:31 | defn | hmm wtf error: java.lang.NoClassDefFoundError: javax/servlet/ServletOutputStream (core.clj:1) |
| 01:31 | defn | this was just working on OSX at home, but not here at work |
| 01:32 | defn | nvm figured it out |
| 01:59 | mebaran151 | is there any quick way to turn an inputstream into a ChannelBuffer |
| 02:00 | mebaran151 | sorry I mean ByteBuffer |
| 02:00 | mebaran151 | I'd like to read an InputStream into a bytebuffer |
| 02:09 | Puzzler | Anyone know whether Java 1.7 will introduce the kinds of numeric features that will allow Rich to speed up Clojure's number handling? |
| 03:41 | hiredman | lisppaste8: url |
| 03:41 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 03:42 | praptak | Is let* different than let? |
| 03:43 | lisppaste8 | hiredman pasted "inputstream -> bytebuffer" at http://paste.lisp.org/display/93138 |
| 03:45 | hiredman | praptak: let is actually a macro implemented using let* |
| 03:47 | praptak | hm |
| 03:47 | praptak | Ok, I'll check the source |
| 03:47 | hiredman | ,(macroexpand '(let [[a b] [1 2]] [a b])) |
| 03:47 | clojurebot | (let* [vec__6245 [1 2] a (clojure.core/nth vec__6245 0 nil) b (clojure.core/nth vec__6245 1 nil)] [a b]) |
| 03:47 | Chousuke | ~def let |
| 03:47 | praptak | Thanks |
| 03:47 | hiredman | ,(let [[a b] [1 2]] [a b]) |
| 03:47 | clojurebot | [1 2] |
| 03:48 | Chousuke | the destructure function is quite a monster :P |
| 03:49 | hiredman | I've never looked at it, but it would have to be |
| 03:50 | hiredman | kind of scary, it lurks beneath the most innocuous looking code |
| 03:50 | Chousuke | heh |
| 03:50 | Chousuke | but it works. |
| 03:50 | Chousuke | so you can forget that it exists :) |
| 03:51 | hiredman | until you get some head holding |
| 03:51 | Chousuke | that shouldn't be such of a problem anymore I think |
| 03:52 | hiredman | *shurg* |
| 03:52 | hiredman | new isn't even master yet |
| 03:52 | Chousuke | since Rich introduced the early locals clearing |
| 03:53 | praptak | Ok, so let is basically let* with added support for destructuring assignments? |
| 03:54 | praptak | ,(let* [[a b] [1 2]] (+ a b)) |
| 03:55 | clojurebot | java.lang.IllegalArgumentException: Bad binding form, expected symbol, got: [a b] |
| 03:55 | praptak | ,(let [[a b] [1 2]] (+ a b)) |
| 03:55 | clojurebot | 3 |
| 03:57 | praptak | err, assignments->bindings |
| 04:04 | Chousuke | ,(#'clojure.core/destructure '[[a b] [c d]]) |
| 04:04 | clojurebot | [vec__6261 [c d] a (clojure.core/nth vec__6261 0 nil) b (clojure.core/nth vec__6261 1 nil)] |
| 04:04 | Chousuke | basically let just feeds that to let* |
| 04:19 | defn | ,(doc let) |
| 04:19 | clojurebot | "([bindings & body]); Evaluates the exprs in a lexical context in which the symbols in the binding-forms are bound to their respective init-exprs or parts therein." |
| 04:26 | praptak | ,(doc let*) |
| 04:26 | clojurebot | It's greek to me. |
| 04:29 | Chousuke | it's a secret :) |
| 04:30 | hiredman | let* has no var to hang a docstring on |
| 04:34 | Chousuke | you could easily define one, though |
| 04:35 | Chousuke | the special form takes precedence though, but it might work for adding a docstring |
| 04:36 | hiredman | or you could add some special mechanism to doc, which I think there already is |
| 04:37 | hiredman | of course clojurebot has its own 'doc' so... |
| 04:51 | LauJensen | ~source let* |
| 04:51 | clojurebot | I don't understand. |
| 04:56 | hiredman | let* is in java somewhere |
| 04:57 | LauJensen | Strange, I felt I had a memory of seeing it in core once |
| 04:58 | hiredman | it's used in core, sure |
| 04:59 | LauJensen | I meant the definition |
| 05:01 | hiredman | well, it's not, as a special form it must be implemented in the implementation language |
| 05:06 | AWizzArd | though after bootstrapping it can be written in Clojure too :) |
| 05:07 | hiredman | nope |
| 05:07 | Chousuke | why not? :P |
| 05:07 | AWizzArd | Why not? |
| 05:07 | hiredman | it's almost by definition that special forms are written in the implementation language |
| 05:07 | Chousuke | the plan is to do that. |
| 05:07 | AWizzArd | Yes, but the implementation language for Clojure will be Clojure. |
| 05:07 | Chousuke | since the implementation language will be Clojure :D |
| 05:08 | hiredman | sure, but it will be sort of Clojure and Clojure' |
| 05:08 | AWizzArd | in some sense yes |
| 05:08 | hiredman | the let* in Clojure' will be written in Clojure |
| 05:10 | hiredman | the distinction between implemented lisp and implementing lisp is fairly common |
| 05:10 | hiredman | sicp does it, lisp in small pieces does it, etc |
| 05:11 | Chousuke | Clojure might just do it so that any new versions of Clojure are compiled with an earlier version, though. |
| 05:11 | hiredman | the main reason I said "nope" was most likely over a different understanding of "bootstrapping" |
| 05:12 | hiredman | Chousuke: sure, the ealier version of Clojure being Clojure, and the version being built would be Clojure' |
| 05:12 | Chousuke | bootstrapping is not easy though. I tore many hairs trying to make my reader work :P |
| 05:12 | hiredman | I took "after bootstrapping" to mean after the bootstrapping section of core.clj |
| 05:15 | Chousuke | heh |
| 05:15 | hiredman | I don't think my post to the dev group about it got a single reply |
| 05:15 | Chousuke | I should work on mine, too. |
| 05:15 | hiredman | *shrug* |
| 05:15 | Chousuke | it's a bit hackish right now |
| 05:16 | hiredman | yours would undoubtly be more interesting, as it's not just a port |
| 05:17 | Chousuke | I'm not sure how to incorporate all the features I want while keeping the definition of reader macros natural AND the design (somewhat) functional. hmmh. |
| 05:17 | Chousuke | Should do some reading about Lisp readers I guess. |
| 05:20 | hiredman | I dunno, the literature doesn't seem to overflow with reader examples |
| 05:20 | hiredman | which is odd given how much work is sort of off loaded on to them in a modern lisp implementation |
| 05:21 | Chousuke | I could go read some scheme implementation for inspiration. |
| 05:22 | hiredman | it annoys be sometimes that I can't have a name X' |
| 05:22 | Chousuke | heh |
| 05:22 | Chousuke | haskellish :P |
| 05:22 | hiredman | I need some other way to indicate the successor to X |
| 05:22 | Chousuke | I guess that's what the * is for. |
| 05:22 | hiredman | :/ |
| 05:23 | hiredman | should find some unicode glyph |
| 05:24 | Chousuke | ’ <-here's a full width apostrophe |
| 05:24 | Chousuke | at least I think that's supposed to be one |
| 05:24 | hiredman | ,x’ |
| 05:24 | clojurebot | java.lang.Exception: Unable to resolve symbol: x’ in this context |
| 05:24 | hiredman | ,(let [x 1 x’(inc x)] x’) |
| 05:24 | clojurebot | 2 |
| 05:24 | hiredman | how evil is that |
| 05:25 | Chousuke | very |
| 05:25 | Chousuke | I need my japanese input method to even type that character. |
| 05:25 | Chousuke | ,(let [x 1 x’ (inc x)] x’) this is eviler though |
| 05:25 | clojurebot | 2 |
| 05:26 | hiredman | I wonder if there is some key combo I can do for that |
| 05:27 | Chousuke | well, in emacs you could just bind a key to the needed elisp function to produce whatever you want :P |
| 05:38 | hiredman | xev-1.0.3.tbz |
| 05:38 | hiredman | er |
| 05:39 | hiredman | gah, I can use the compose key to insert it everywhere except gnome-terminal apparently |
| 06:16 | ordnungswidrig | hum, since when exists defprotocol/deftype? in 1.1.0-alpha I cannot find it |
| 06:17 | hiredman | only in the 'new' branch |
| 06:19 | ordnungswidrig | not in 1.1? |
| 06:20 | hiredman | nope |
| 06:20 | ordnungswidrig | I see. |
| 06:21 | ordnungswidrig | Is it available on clojars? |
| 06:22 | hiredman | no idea |
| 06:42 | AWizzArd | clojurebot: max people |
| 06:42 | clojurebot | max people is 240 |
| 07:33 | RCampbell | when you type a map literal into the REPL, like {:a 1}, Clojure automatically selects the concrete map impl to use, for example array-map for small maps or hash-map for larger maps. What happens when you do (def x (array-map {a: 1})) but then you add a couple million key/val pairs? will it remain an array-map, or will Clojure somehow convert it automatically to a hash-map? |
| 07:37 | AWizzArd | It will become a hashmap |
| 07:38 | AWizzArd | clojure.lang.PersistentHashMap |
| 07:50 | RCampbell | So to be clear, Clojure will monitor a map and when it grows beyond a certain level it will switch its type? that seems wild |
| 07:51 | RCampbell | even when it's explicitly instantiated using (array-map |
| 07:56 | AWizzArd | RCampbell: yes, the functions that can grow (assoc, conj) a map will check if there are, say, more than 8 elements in the map. If so, it will be a hashmap. |
| 07:56 | AWizzArd | But dissoc will not do such a check. The reason is that a "big arraymap" performs worse than hashmaps. But small hashmaps can perform a little bit worse than arraymaps. |
| 07:57 | RCampbell | AWizzArd: thank you for the explanation. That's pretty cool functionality |
| 07:58 | AWizzArd | The developer will always work with the concept of a map, and Clojure will try to ensure under the hood that a useful implementation will be used. |
| 07:59 | RCampbell | AWizzArd: then why even have (array-map) and (hash-map) functions? when would you select one of the other? Clojure controls the underlying impl, so it seems a bit misleading |
| 08:00 | AWizzArd | ,(class (array-map)) |
| 08:00 | clojurebot | clojure.lang.PersistentArrayMap |
| 08:00 | AWizzArd | ,(class (hash-map)) |
| 08:00 | clojurebot | clojure.lang.PersistentArrayMap |
| 08:01 | AWizzArd | If you understand your data and problem well you may want to have a bigger array-map. |
| 08:02 | RCampbell | yeah, but you're saying if I do (array-map ; some massive data here) it will store it as a hash map |
| 08:03 | AWizzArd | also: when you type {:a 1, :b 2} into your repl, then Clojure would like to construct a array-map for you. So it is nice to have a function available for that purpose. |
| 08:03 | RCampbell | what I mean is, if Clojure is selecting the impl on its own based on the size, why both with array-map and hash-map constructors, and why not just make one (persistant-map) |
| 08:03 | AWizzArd | Calling array-map results in a clojure.lang.PersistentArrayMap |
| 08:03 | AWizzArd | ,(class (apply array-map (range 2000))) |
| 08:03 | clojurebot | clojure.lang.PersistentArrayMap |
| 08:04 | RCampbell | yeah, but you just showed (hash-map) creates an array map too |
| 08:04 | AWizzArd | ,(class (assoc (apply array-map (range 2000)) :a :b)) |
| 08:04 | clojurebot | clojure.lang.PersistentHashMap |
| 08:04 | AWizzArd | RCampbell: because you sometimes know more than the compiler does |
| 08:05 | AWizzArd | you can safely forget about array-map and just use hash-map to construct your maps |
| 08:05 | RCampbell | (class (hash-map)) -> clojure.lang.PersistentArrayMap is saying the opposite: that the compiler knows more than me. It's a lie, isn't it? |
| 08:05 | RCampbell | i understand that part - that I can ignore it - but then I don't see why the two constructors exist. |
| 08:05 | AWizzArd | hash-map does not guarantee that the returned object will be a PersistentHashMap |
| 08:06 | RCampbell | then why itsn't there just (persistent-map) |
| 08:06 | RCampbell | since in the end, the compiler decides |
| 08:06 | AWizzArd | hash-map may call array-map if only a few elements are added |
| 08:06 | AWizzArd | RCampbell: the compiler will not decide when you call array-map |
| 08:06 | RCampbell | aha |
| 08:06 | AWizzArd | see my example above, where I put 2k elements into an ArrayMap |
| 08:06 | RCampbell | yes, i see that |
| 08:07 | AWizzArd | ,(class clojure.lang.PersistentHashMap/EMPTY |
| 08:07 | clojurebot | EOF while reading |
| 08:08 | AWizzArd | ,(class clojure.lang.PersistentHashMap/EMPTY) |
| 08:08 | clojurebot | clojure.lang.PersistentHashMap |
| 08:08 | RCampbell | okay so array-map always returns an array-map, but later additions via assoc, conj, can convert it to a hash-map |
| 08:08 | AWizzArd | yes |
| 08:08 | RCampbell | hash-map will return an array-map for small stuff or a hash-map for big stuff |
| 08:08 | AWizzArd | yes, where "big" is around 8-10 elements |
| 08:08 | RCampbell | oh that's not so big. interesting |
| 08:08 | RCampbell | okay |
| 08:22 | chouser | ,(class (hash-map 1 2 3 4)) |
| 08:22 | clojurebot | clojure.lang.PersistentHashMap |
| 08:22 | chouser | doesn't look like an array-map to me |
| 08:23 | chouser | I think the important thing is to not rely on the concrete type. |
| 08:33 | _fogus_ | ,(class {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16}) |
| 08:33 | clojurebot | clojure.lang.PersistentArrayMap |
| 08:33 | _fogus_ | ,(class {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18}) |
| 08:33 | clojurebot | clojure.lang.PersistentHashMap |
| 08:33 | _fogus_ | But, what chouser dsaid |
| 08:33 | chouser | right. for literals. |
| 08:34 | chouser | there's no promise about the concrete type of literals or of what's returned by assoc, dissoc, etc. |
| 08:34 | _fogus_ | nor should there be... but people get tripped up on that |
| 08:34 | chouser | I do think that when you use a named factory fn like hash-map or array-map, you can rely on getting an object of that type. |
| 08:35 | chouser | _fogus_: hey good morning. :-) |
| 08:35 | _fogus_ | chouser: Good morning sir! |
| 08:35 | chouser | if we keep this up, they could rename this channel to #joyofclojure |
| 08:36 | _fogus_ | I think there was a time when I liked snow... but I've sent lost that childhood joy. :( |
| 08:36 | _fogus_ | That might not be a bad idea anyway. ;) |
| 08:37 | RCampbell | chouser: that's what I was talking about. To me it seems a bit misleading |
| 08:37 | chouser | RCampbell: what's misleading? |
| 08:37 | RCampbell | chouser: when you say (hash-map) you expect a hashmap, no? |
| 08:37 | RCampbell | ,(class (hash-map)) |
| 08:37 | clojurebot | clojure.lang.PersistentArrayMap |
| 08:38 | chouser | ah |
| 08:38 | chouser | well |
| 08:38 | RCampbell | I agree that you shouldn't depend on the concrete types, and I love that they're managed for me, but if that's the case I just think (persistant-map) would have been better than these two |
| 08:39 | chouser | heh, I hadn't seen that. The thing is, what's the difference between an empty array-map and an empty hash-map? |
| 08:39 | RCampbell | chouser: true enough |
| 08:39 | chouser | when you actually give it some parameters, each function will return the specific type you request. |
| 08:39 | RCampbell | but then my question was, why do we have these two constructors? |
| 08:40 | chouser | ,(class (apply array-map (range 2e5))) |
| 08:40 | clojurebot | clojure.lang.PersistentArrayMap |
| 08:40 | RCampbell | true, but then you risk losing that type whenever you pass it to a assoc, conj, etc |
| 08:40 | chouser | so there's an array-map with a hunderd thousand key/value pairs, guaranteed to keep the order I gave them. |
| 08:40 | chouser | right, yes you do. |
| 08:40 | _fogus_ | RCampbell: Why does it matter which map class you receive after some op(s)? |
| 08:41 | RCampbell | i suppose it doesn't, although it would depend on how you access your map, no? |
| 08:42 | RCampbell | I'm sure certain algos would operate faster on one type versus another based on how the data is accessed |
| 08:42 | RCampbell | i suppose you could always cast from one to another though |
| 08:44 | chouser | RCampbell: I understand what you're saying. I think the most dangerous detail there is that key-matching semantics are slightly different between array-map and hash-map. |
| 08:45 | RCampbell | chouser: could you come up with a nice example? I'm going to add it to my stackoverflow answer concerning commons mistakes beginners make in clojure |
| 08:46 | chouser | RCampbell: hm... my attempts at an example are failing. perhaps that's been fixed. |
| 08:47 | chouser | _fogus_: array-maps are order-n-ouch |
| 08:52 | RCampbell | ,(array-map (range 100)) |
| 08:52 | clojurebot | 1 |
| 08:52 | RCampbell | ,(hash-map (range 100)) |
| 08:52 | clojurebot | java.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@5c8e6fb3 |
| 08:52 | RCampbell | why? |
| 08:53 | RCampbell | array map uses the index as the key by default? |
| 08:53 | _fogus_ | RCampbell: Thanks for filling out some of that information on SO... that thread is getting some nice answers |
| 08:54 | RCampbell | _fogus_: np. Mostly I'm remembering all the WTF moments I've had along the way |
| 08:54 | AWizzArd | Does a lookup in an PAM traverse the full underlying tree until it finds the key? |
| 08:55 | RCampbell | I'm trying to compile all the bits from the three books, mailing list, stackoverflow, and this irc channel that help me get past it |
| 08:55 | _fogus_ | RCampbell: Eventually it would be nice to gather those WTF moments and put them somewhere on the Clojure site... but that's probably just a dream |
| 08:56 | RCampbell | fogus: it should be easy enough; the content on StackOverflow is GLP I believe, and Jeff does a content dump every so often |
| 08:57 | RCampbell | AWizzArd: that's a good question |
| 09:03 | chouser | AWizzArd: there's no underlying tree. Underlying a array-map is an array. And yes, it's walked linearly until a match is found. |
| 09:06 | chouser | RCampbell: array-map and hash-map fns both expect an even number args for the key/value pairs |
| 09:07 | chouser | RCampbell: so (hash-map x) is an error regardless of the value of x. But array-map doesn't do many extra consistency checks, so you managed to get away with something thre. |
| 09:07 | chouser | there |
| 09:08 | RCampbell | chouser: okay that makes sense |
| 09:08 | RCampbell | although (range 100) is even |
| 09:08 | RCampbell | ,(count (range 100)) |
| 09:08 | clojurebot | 100 |
| 09:09 | chouser | it's a single object |
| 09:09 | chouser | if you want the contents of the range to be the contents of the map, you have to use 'apply' |
| 09:10 | chouser | ,(apply hash-map (range 100)) |
| 09:10 | clojurebot | {0 1, 32 33, 64 65, 96 97, 2 3, 34 35, 66 67, 98 99, 4 5, 36 37, 68 69, 6 7, 38 39, 70 71, 8 9, 40 41, 72 73, 10 11, 42 43, 74 75, 12 13, 44 45, 76 77, 14 15, 46 47, 78 79, 16 17, 48 49, 80 81, 18 19, 50 51, 82 83, 20 21, 52 53, 84 85, 22 23, 54 55, 86 87, 24 25, 56 57, 88 89, 26 27, 58 59, 90 91, 28 29, 60 61, 92 93, 30 31, 62 63, 94 95} |
| 09:11 | chouser | I think that once upon a time there were objects that were .equal but their .hashCode was different. Has that been fixed now? |
| 09:12 | RCampbell | i dunno, in Java you define your own impls (unlike in clojure) so developers can still screw up |
| 09:13 | RCampbell | chouser: i don't know any history of that in clojure |
| 09:14 | chouser | well, if that's been fixed then perhaps array-map and hash-map now have sufficiently similar matching semantics. |
| 09:36 | AWizzArd | chouser: okay, this is what I guessed from the names |
| 09:44 | the-kenny | liebke: Which "incanter" should I use in leiningen? |
| 09:46 | liebke | the-kenny: the latest version isn't up on Clojars yet, so use 1.0-master-SNAPSHOT for now |
| 09:47 | the-kenny | liebke: "incanter-full" or "incanter" |
| 09:47 | the-kenny | If I use incanter, requiring throws an exception :( |
| 09:47 | liebke | eventually incanter full, but that didn't get uploaded correctly (apparently), so use incanter |
| 09:48 | the-kenny | "No value supplied for key: true" |
| 09:48 | liebke | I've been having problems with Clojars lately. Unfortunately, I'd recommend using the github repository |
| 09:48 | liebke | hmmm |
| 09:48 | liebke | try the 1.0-SNAPSHOT version then |
| 09:54 | rrc7cz | do you guys use letfn a lot? it's generally agreed that keeping declarations close to where you use them is a good thing, as is lowering the scope of something when it's possible |
| 09:54 | rrc7cz | but I don't see it used a lot |
| 09:56 | chouser | I more often use let when defining local functions than letfn. |
| 09:57 | rrc7cz | why? |
| 09:57 | chouser | with let I can mix fn and other locals |
| 09:57 | rrc7cz | okay that makes sense |
| 09:57 | chouser | I use letfn when I need mutual recursion and/or have only fns to define |
| 10:15 | LauJensen | What the general use-case for mutual recursion ? |
| 10:16 | Chousuke | state machines? |
| 10:18 | arohner | cause it's cool? |
| 10:24 | rrc7cz | fogus: I totally didn't make the connection between your stackoverflow question and my answer |
| 10:24 | rrc7cz | fogus: I just noticed your name now. Thats pretty funny. I guess it's a small community |
| 10:27 | _fogus_ | rrc7cz: A small, but growing community. :-) |
| 10:31 | rrc7cz | fogus: I like your pre/post article; I had a question about doing design by contract in clojure and I was psyched for this functionality |
| 10:33 | Chousuke | pre and post might be a bit problematic with libraries though. they are only checked if *assert* is bound, and the decision is made during compile time |
| 10:33 | Chousuke | so if you AOT-compile your library for distribution, you need to decide for the users whether to enforce asserts or not :/ |
| 10:34 | rrc7cz | Chousuke: so why was assert used as the underlying mechanism? why not switch it to an if or something? |
| 10:35 | Chousuke | rrc7cz: I guess it was intended that pre- and postconditions are only checked when debugging, and compiled away for production code. |
| 10:35 | rrc7cz | oh |
| 10:35 | chouser | I don't like AOT-compiling anyway. |
| 10:36 | chouser | if you don't AOT-compile, your users can maintain control with *assert* |
| 10:37 | _fogus_ | rrc7cz: Actually, Devlin's follow-up to my :pre/:post uhhhh post, is much better |
| 10:37 | Chousuke | I guess that's the best choice for libraries |
| 10:40 | rrc7cz | I was looking for a way of translating some of the AssertionErrors into IllegalArgumentException which makes a lot more sense when validating arguments, but I suppose if :pre/:post were meant for debugging and not prod runtime, there isn't much point |
| 10:42 | Chousuke | you can always make an assert-args macro. there actually is one in core, but it's private ;/ |
| 10:45 | rrc7cz | Chousuke: it seems odd to make something that useful private |
| 10:48 | Chousuke | rrc7cz: well, it's just a trivial helper macro in core. I don't think any significant design effort was put into it. |
| 10:51 | esbena | I want to apply a side-effect function to every element of a seq, what is the name of that function (not 'map') ?? |
| 10:51 | chouser | esbena: doseq or dorun |
| 10:52 | Chousuke | doseq is a macro, though, and dorun just forces a seq. :) |
| 10:52 | Chousuke | but those will do what you want. |
| 10:52 | chouser | Chousuke: ok then, what's you're answer? :-P |
| 10:53 | Chousuke | but the answer of course is (comp dorun map) |
| 10:53 | ordnungswidrig | Is there a way to quickly fail in clojure. Like throw new Exception("message") |
| 10:53 | chouser | Chousuke: :-) |
| 10:53 | Chousuke | ordnungswidrig: (throw (Exception. "message")) |
| 10:53 | ordnungswidrig | Chousuke: *g* something more idiomatic? |
| 10:54 | Chousuke | return nil? |
| 10:54 | Chousuke | an exception is the only way to have a non-tail exit though. |
| 10:54 | ordnungswidrig | (defn fail [] (throw Exception. "message") |
| 10:55 | Chousuke | some parens missing, but yeah. |
| 10:55 | Chousuke | you could also use error-kit from contrib if you want fancy errors :P |
| 11:12 | defn | I have a question about paths |
| 11:13 | defn | (System/getProperty "user.dir") |
| 11:13 | mebaran151 | paths? |
| 11:13 | defn | so let's say i have a .clj file that's nested in a lein project |
| 11:14 | defn | If (System/getProperty "user.dir") is called from that file, i assume it will get the path that the file is living in, yes? |
| 11:17 | mebaran151 | I'm actually not quite sure |
| 11:17 | mebaran151 | user.dir is tricky |
| 11:18 | mebaran151 | sometimes it gets where the jvm is stored |
| 11:18 | mebaran151 | I find it unreliable |
| 11:20 | chouser | I think user.dir is usually the cwd when the jvm was started. And you can't change it. |
| 11:22 | defn | chouser: that's correct, just tested it |
| 11:22 | defn | it's where you run the jar from |
| 11:22 | defn | mebaran151: what else would you use? |
| 11:23 | defn | I don't want to force people to use absolute paths and edit a config file just to run this |
| 11:23 | mebaran151 | I tend to rely on user.home very heavily |
| 11:23 | mebaran151 | and I copy lots of things there |
| 11:24 | defn | hmmmm, i dont like mucking with a user's home dir if it's not necessary |
| 11:24 | defn | and in this case im sure it's not |
| 11:24 | defn | it's not like im writing a utility or an application they will want to store a local config file for |
| 11:24 | defn | it's something which needs to just be contained by itself |
| 11:26 | defn | me needs a java version of pygments |
| 11:27 | mebaran151 | oh then what do you need user.dir for? |
| 11:27 | defn | to get the project root |
| 11:27 | defn | which is where the jar is built |
| 11:28 | mebaran151 | are you on unix? |
| 11:28 | defn | yes |
| 11:28 | defn | but not everyone will be |
| 11:28 | chouser | surely you can be in some other directory when you launch the thing, which might mess up your user.dir |
| 11:28 | defn | chouser: yeah, but im okay with that as I suspect most will run it from it's build directory |
| 11:28 | defn | if they dont, well, too bad for them |
| 11:29 | mebaran151 | hmmm I'm trying to consider if some env variable will help you |
| 11:29 | defn | in unix it might, but idk, i think this is fine for now |
| 11:29 | defn | it's better than the absolute path |
| 11:30 | mebaran151 | you probably could wrap it in a small shell script |
| 11:30 | defn | someone just msg'd me on github asking why they couldnt run it, and it's because of the absolute path |
| 11:30 | mebaran151 | that would either pass the cwd as an argument to your proram |
| 11:30 | defn | i told them to edit it, but it seems like a stupid step to force people into |
| 11:31 | defn | anyway, now im on the hunt for a way to do markdown + code highlighting |
| 11:31 | defn | specifically clojure code syntax highlighting |
| 11:32 | defn | pygments + markdown.py and the codehilite extension which is bundled with it do a wonderful job, but that means people have to get friggen python deps for a clojure project, which is lame as hell |
| 11:32 | hiredman | defn: I think user.dir will be fine |
| 11:32 | defn | hiredman: i agree |
| 11:33 | defn | hiredman: any ideas for clojure syntax highlighting which outputs as HTML? |
| 11:33 | defn | something java? |
| 11:33 | hiredman | none |
| 11:33 | defn | bummer |
| 11:34 | hiredman | can't you just use some kind of javascript deal? |
| 11:34 | hiredman | isn't that the latest and greatest in web syntax hilighting? |
| 11:34 | LauJensen | defn: htmlize :) |
| 11:35 | defn | LauJensen: in clojure? |
| 11:35 | LauJensen | oh, no thats Emacs |
| 11:35 | defn | yessir :) |
| 11:35 | defn | hiredman: nice! i think you pointed me in the right direction with your comment: http://alexgorbatchev.com/wiki/SyntaxHighlighter |
| 11:37 | LauJensen | defn: I think a cocktail between compojure's html function and then just doing some kind of .replaceAll with the functions in core would get you quite far |
| 11:38 | defn | LauJensen: could you be more specific about what you're replacing? |
| 11:38 | defn | LauJensen: as in writing my own markdown processor? |
| 11:38 | LauJensen | With the above approach, you'd be highlighting functions and macros |
| 11:39 | LauJensen | defn you're writing a Clojure program which reads clojure code and emits highlighted html right ? |
| 11:40 | defn | LauJensen: close -- it reads markdown which contains code blocks, which need to be highlighted as clojure |
| 11:40 | LauJensen | Yea, almost the same |
| 11:40 | LauJensen | Gotta boot |
| 11:41 | defn | markdown.py does a slick thing wherein it let's you specify at the top of a code block: :::clojure\n (defn omg [arg1 arg2]\n (+ arg1 arg2)) |
| 11:42 | hiredman | you might even be able to use scriptjure to write custom js highlighting stuff in clojure and translate it to javascript |
| 11:42 | Licenser | aloa |
| 11:42 | defn | hiredman: not a bad idea at all |
| 11:42 | mebaran151 | that would be way meta |
| 11:42 | hiredman | so I would forget about generating hilighted html |
| 11:42 | mebaran151 | then you could highlight the scriptjure source in js |
| 11:44 | defn | http://attacklab.net/showdown/ |
| 11:44 | defn | maybe? |
| 11:47 | hiredman | the markdown renders to html right? |
| 11:48 | hiredman | so you just have the javascript highlight the code blocks in the html |
| 11:48 | defn | how do i know im highlighting a code block though? |
| 11:49 | hiredman | magic |
| 11:49 | hiredman | by magic I mean <code></code> |
| 11:49 | hiredman | or whatever markdown dumps the code into |
| 11:49 | defn | is that what markdown renders? |
| 11:50 | hiredman | I don't know, you should check |
| 11:50 | defn | lol |
| 11:51 | djork | wow, Enlive looks very nice |
| 11:52 | djork | I assume cgrand-rec in here is the dev? |
| 11:55 | chouser | I think -rec is his bot. |
| 12:35 | nuttycom1 | Does anyone have a good reference for how to embed a Clojure interpreter (or compiler that can be dynamically invoked and return something callable) in a Scala (or Java) app? |
| 12:36 | kotarak | nuttycom1: import clojure.lang.RT; import clojure.lang.Var; Var pr = RT.var("clojure.core", "println"); pr.invoke("Hello, World!"); |
| 12:38 | nuttycom1 | kotarak: thanks |
| 12:47 | nuttycom1 | Hmmm... are there any javadocs for jvm.clojure.lang.* or do folks just consult the sources on github? |
| 12:47 | chouser | there are no official docs for the .java code. So yes, the sources. |
| 12:48 | chouser | they're all going away eventually anyway. ;-) |
| 12:48 | nuttycom1 | ah, I think I heard about that - what's the timeframe on self-hosting? |
| 12:49 | Chousuke | will deftype/reify be the last piece needed before the actual compiler work can begin? :/ |
| 12:49 | nuttycom1 | moreover, what can I expect with respect to my goal of having an embedded interpreter (or runtime compiler) for use from within another app? |
| 12:49 | Chousuke | or is there still something |
| 12:50 | nuttycom1 | I've been using Groovy for this purpose up until now, but clojure is much more appealing. |
| 12:50 | Chousuke | nuttycom1: but the compiler *is* a runtime one? what do you mean :/ |
| 12:50 | chouser | clojure's got a runtime compiler built right in. read-string, eval. |
| 12:50 | Chousuke | there is no interpreter though :) |
| 12:51 | chouser | Chousuke: I think a way of doing volatile fields is still missing. |
| 12:51 | defn | Chousuke: do you have the ability to add members to the assembla project |
| 12:51 | Chousuke | I don't think so. hmm. |
| 12:51 | defn | i gave rich my signed agreement and am listed on the contributers page |
| 12:51 | defn | err i meant chouser |
| 12:51 | defn | but my account on assembla is still Watcher |
| 12:52 | Chousuke | did you post to the dev group asking for a bump? |
| 12:52 | defn | I didn't -- I thought I'd just need to get the agreement signed and he'd handle getting me added |
| 12:52 | defn | but I can do that |
| 12:52 | nuttycom1 | Chousuke: basically, I've got an app written in Scala running on Glassfish. I need to provide a small scripting language for part of that app. I can go the parser-combinator route in Scala, but that seems like a bit heavyweight for my situation - so instead I want to use clojure, where the resulting artifact can be executed in the current classloader (or a child, of course) |
| 12:53 | chouser | defn: I think you need to ask. I think only rhickey can do it. |
| 12:53 | defn | chouser: Chousuke: thanks |
| 12:54 | hiredman | I don't know much about classloaders, but my impression is clojure still has some modularity issues on that front |
| 12:54 | hiredman | (no direct experience, just sort of half rememebered stuff on the internet) |
| 12:56 | chouser | nuttycom1: so you may have to play with the classloaders a bit, but the raw materials should all be there. 'read' to convert text to a tree of clojure objects, 'eval' to run it. |
| 13:37 | mebaran151 | hey somnium, so I've got some basic proxy netty stuff working if you want to play with it |
| 13:38 | somnium | mebaran151: cool, sure. on github? |
| 13:38 | mebaran151 | not yet |
| 13:38 | mebaran151 | it's just a gist so far |
| 13:38 | somnium | url? |
| 13:38 | mebaran151 | turns out the annotations in netty are simply documentation |
| 13:39 | mebaran151 | http://gist.github.com/272271 |
| 13:39 | mebaran151 | it basically works the way I described |
| 13:40 | mebaran151 | takes the output of a function and writes it to the buffer, either an array of ints or a good ol' fashion bytestring |
| 13:41 | mebaran151 | I keep around the context vars in bindings in case you wanted to do something fancy with them |
| 13:42 | somnium | mebaran151: should I use 3.15? |
| 13:42 | mebaran151 | I was going against 3.2 alpha |
| 13:42 | mebaran151 | but I don't do anything particularly adventurous |
| 13:43 | somnium | ok |
| 13:45 | mebaran151 | I was looking for good protobuffers in clojure, but the design doesn't seem to fit the clojure mentality well |
| 13:47 | mebaran151 | it works as a basic telnet echo, but I haven't done much more with it yet |
| 13:48 | the-kenny | mebaran151: Maybe write a nice wrapper about the java version of the protobufs? |
| 13:48 | mebaran151 | but protobufs is so classy |
| 13:48 | mebaran151 | like heavily classy |
| 13:48 | mebaran151 | it's probably a bad binary fit for clojure at the moment |
| 13:49 | chouser | google protobufs, or something else? |
| 13:49 | mebaran151 | google protobufs |
| 13:49 | chouser | I use them a lot at work, from Clojure and C++ |
| 13:49 | the-kenny | In fact, I have never really needed a binary protocol. I always use simple json |
| 13:50 | chouser | so I've got fns to convert back and forth between clojure nested maps and protobufs |
| 13:50 | mebaran151 | there's a certain mechanical elegance to a good binary protocol |
| 13:51 | chouser | I need them to iterop with other services. The choice to use protobufs was not mine. :-) |
| 13:54 | mebaran151 | but if clojure itself were to have a nice easy binary protocol that handled vectors, maps, strings, and numbers, I think that might be useful, actually even outside the clojure community |
| 13:54 | mebaran151 | I wonder if a protocol with that much flexibility though would be anymore efficient than regular ol' JSON |
| 14:00 | somnium | mebaran151: the pet project I want to use netty for is a BSON client (http://www.mongodb.org/display/DOCS/BSON), which seems to be an attempt at being more efficient than regular 'ol JSON (or maybe just a mild case of NIHS, cant be sure) |
| 14:01 | mebaran151 | oh I was looking into BSON as well |
| 14:01 | mebaran151 | it seemed like it would be cool to switch between JSON and BSON |
| 14:17 | somnium | hmm, how do you add a repository in a project.clj? (cant seem to find an example and Im maven challenged :/) |
| 14:19 | knuckolls | i'm just learning clojure and i'm having a real hard time conceptualizing this. I have a file with records separated into sets of three lines, then an empty line. I want to load these into memory but I can't figure out how to pull from the seq 4 lines at a time and store them in a map. any pointers to the functions i should be using? |
| 14:20 | chouser | ,(parition 4 (range 12)) |
| 14:20 | clojurebot | java.lang.Exception: Unable to resolve symbol: parition in this context |
| 14:20 | chouser | ,(partition 4 (range 12)) |
| 14:20 | clojurebot | ((0 1 2 3) (4 5 6 7) (8 9 10 11)) |
| 14:20 | chouser | that might help |
| 14:20 | the-kenny | knuckolls: (partition 4) will partition a seq in seqs of 4 items |
| 14:20 | knuckolls | yes. that helps quite a bit. this is the first i've seen partition |
| 14:20 | knuckolls | wonderful. |
| 14:21 | knuckolls | yep that does the trick. thanks. |
| 14:25 | robwolfe | somnium: IIRC it's something like this: ":repositories [["rep name" "url"]]" |
| 14:25 | somnium | robwolfe: ah thanks |
| 14:27 | hiredman | somnium: I am pretty sure it's a map |
| 14:28 | hiredman | {"google" "url"} |
| 14:28 | somnium | hiredman: I found a gist with a map, and that worked, then just tried the vector, and that seemed to work too (though maybe it already added the repo?) |
| 14:28 | hiredman | but it must get walked via the seq functions which sees it as the same thing as [["name" "url"]] |
| 14:29 | hiredman | ,(seq {"google" "url"}) |
| 14:29 | clojurebot | (["google" "url"]) |
| 14:29 | robwolfe | hiredman: there is "concat" and it works for vector and map |
| 14:31 | hiredman | robwolfe: I am just hypothesizing on why a map and a nest set of vectors both work for :repos |
| 14:31 | robwolfe | hiredman: in Leingen there is used "concat" for joining "default repos" with defined |
| 14:32 | robwolfe | that's why it works I guess |
| 14:32 | somnium | presumably a map would work for :dependencies too? ah, maybe not? |
| 14:32 | somnium | *shrug* whatever works is fine with me |
| 14:32 | robwolfe | somnium: we can try ;) |
| 14:34 | hiredman | http://gist.github.com/272330 <-- makes me sad |
| 14:40 | arj | I have a very imperative part of my program. More or less a state machine. Any hints as to code this in clojure? |
| 14:45 | stuartsierra | arj: loop/recur |
| 14:48 | arj | hmm interesting |
| 14:48 | arj | I'll have a look |
| 14:48 | arj | thanks |
| 14:48 | _fogus_ | arj: mutual recursion might map well also, but it takes some practice to get right |
| 15:01 | ynniv | is there an elegant way to break a hash map apart and reconstruct it? |
| 15:01 | kotarak | ynniv: breaking apart in which way? |
| 15:01 | ynniv | i'm using mongo, and my DBObject acts like a hash map, but isn't close enough to work with some of the api |
| 15:02 | ynniv | i'd like to convert it to a real hash-map elegantly |
| 15:02 | kotarak | ynniv: does it support seq? (into {} your-object) |
| 15:02 | ynniv | hah! perfect :) |
| 15:03 | ynniv | i haven't used "into" yet |
| 15:05 | ynniv | i probably write the worst clojure code, but even that works out better for me than great code in other languages |
| 15:09 | {newbie} | ,(into {} [:foo "bar"]) |
| 15:09 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Keyword |
| 15:10 | somnium | ynniv: if you don't mind a shameless suggestion, congomongo on github might make the mongo-java-driver somewhat more pleasant to work with |
| 15:10 | ynniv | ,(into {} [[:foo "bar"]]) |
| 15:10 | clojurebot | {:foo "bar"} |
| 15:11 | {newbie} | :\ okay :D |
| 15:11 | ynniv | somnium: I considered it, but I'm doing so little interaction with mongo that I'm not ready to switch libs yet |
| 15:11 | ynniv | i have a couple of .find's :) |
| 15:16 | somnium | ynniv: just a shameless suggestion :) |
| 15:16 | ynniv | I have considered it, and will keep it in mind ;) |
| 15:17 | ynniv | i'm working in a mongo - clojure - REST - SproutCore stack, and i've been spending all my recent time on the right side of that |
| 15:17 | ynniv | but i'll revisit the left sometime soon |
| 15:20 | somnium | ynniv: cool, Ive had my eye on Sproutcore, but the docs are worse that dojo's (which Im reasonably familiar with) |
| 15:20 | hiredman | http://andialbrecht.wordpress.com/2009/05/09/when-merging-fails/ <-- hah! |
| 15:22 | the-kenny | hiredman: I want this for git! |
| 15:24 | robwolfe | hiredman: I want it for missing jars on classpath ;) |
| 15:24 | AlexS_ | I seem to be getting an java.util.concurrent.RejectedExecutionException when trying to use a very simple agent in the slime/swank repl. Everything works fine from a non-swank repl. Anyone else encountered this? Or be willing to try an reproduce? |
| 15:26 | hiredman | AlexS_: most likely means you shutdown the agent threadpools |
| 15:27 | AlexS_ | hiredman: This was a brand new session started with the lein swank command. |
| 15:35 | ynniv | somnium: SC is a tough framework to get involved with. I have the benefit of a 9 month head start learning, but even so, a lot has changed in that time. |
| 15:44 | I314159 | hi |
| 15:44 | I314159 | I have a struct which looks like this: (defstruct book :title :author) |
| 15:44 | I314159 | I also have a list which looks like this: (let mybook [("my title" "my author")]) |
| 15:44 | I314159 | I want to turn this into a book struct, but doing this: (struct book mybook) gets this: |
| 15:44 | I314159 | (:title ("my title" "my author") :author nil) |
| 15:44 | I314159 | any tips on on what I'm doing wrong? |
| 15:45 | the-kenny | (apply struct book (first mybook)) |
| 15:45 | the-kenny | struct doesn't exspect a list but single arguments |
| 15:45 | I314159 | ahh -- thanks |
| 15:46 | Chousuke | also you would need to quote the lists like that :P |
| 15:46 | Chousuke | more idiomatic in clojure is to use a vector |
| 15:49 | dataangel | Is there a paper or site somewhere that describes how clojure implements persistent data structures? I know from Hickey's presentations that there's some hashing going on, that somehow affects indexing into some multilayer tree, and that CAS lets you quickly swap out elements, but I haven't seen a real description of the algorithm anywhere. I'm not a Java dev so the source code has a high barrier to entry for me ;p |
| 15:51 | chouser | dataangel: http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/ |
| 15:52 | chouser | dataangel: but don't just into that until you're ready -- it'll just destory the magic for you. :-) |
| 15:52 | chouser | don't jump |
| 16:32 | leafw | any fn to flatten a list of lists ? |
| 16:32 | leafw | I am sure there is one ... |
| 16:32 | chouser | one level, or recursive? |
| 16:32 | kotarak | leafw: flatten? |
| 16:32 | leafw | one level |
| 16:32 | chouser | (apply concat x) |
| 16:33 | leafw | chouser: although recursive would be nice too. |
| 16:33 | kotarak | c.c.seq-utils/flatten |
| 16:33 | chouser | ,(apply concat [[1 2 3] [4 5 6] [7] [8 9]]) |
| 16:33 | clojurebot | (1 2 3 4 5 6 7 8 9) |
| 16:33 | leafw | clojure.contrib, that unknown treasure pit |
| 16:33 | leafw | thanks |
| 16:33 | chouser | heh |
| 16:33 | chouser | "treasure pit |
| 16:33 | kotarak | I hope my memory doesn't play bad tricks on me, though... |
| 16:34 | chouser | "treasure pit" seems more accurate that "standard lib" |
| 16:34 | chouser | than |
| 16:34 | chouser | treasures, sure. Also, a pit. |
| 16:34 | ohpauleez | haha |
| 16:35 | leafw | it's just too hard to ever get a general idea of what is where and how did it change recently |
| 16:35 | ohpauleez | That's why I hang out in #clojure |
| 16:36 | Chousuke | We have contrib excavators here. |
| 16:36 | Chousuke | Some people also occasionally go ahead and deepen the pit, hiding more treasures. |
| 16:37 | ohpauleez | it's all in the name of bringing game theory to clojure development |
| 16:37 | ohpauleez | :) |
| 16:37 | leafw | xD |
| 16:38 | technomancy | now that clojars exists it might be worth thinking about spinning libraries back out of contrib if they aren't intended for future inclusion in core |
| 16:38 | Chousuke | All is okay as long as complexity does not approach that of Go |
| 16:38 | technomancy | at least, that's what I would be considering if I had authored a library that had been included in contrib |
| 16:38 | hiredman | technomancy: I was just thinkging that |
| 16:38 | technomancy | clojure.contrib.logging would benefit from that IMHO |
| 16:38 | kotarak | Ah! Go. :D Hmmm... |
| 16:39 | kotarak | Whatever happens with contrib, I'd like to see a more modular build. |
| 16:40 | kotarak | 3.5Megs for c.c.def.... bleh. |
| 16:40 | technomancy | hiredman: we analyzed our codebase at work, and 60% of contrib usage was IO (duck-streams/java-utils) and 25% was logging. |
| 16:41 | hiredman | is clojure.io still in motion? |
| 16:41 | technomancy | then a handful of shell-out and str/seq-utils invocations |
| 16:42 | technomancy | hiredman: stuart S seemed to think rich had some plans up his sleeve |
| 16:42 | hiredman | *shrug* |
| 16:42 | technomancy | I was waiting to hear more about that, but it sounds like that's not going to happen |
| 16:43 | hiredman | there is a lot of chum in the water |
| 16:43 | chouser | one of the values of contrib is the low barrier for bug fixes from people other than the original author |
| 16:44 | technomancy | chouser: maybe, but stuff outside contrib doesn't have to go through the ticket+patch dance |
| 16:44 | technomancy | authors can pull directly from others' git repos, which is much more convenient |
| 16:44 | chouser | neither does stuff inside contrib when the patch is written by a committer. |
| 16:45 | technomancy | it's true that having multiple committers solves some problems |
| 16:45 | chouser | do I have to clone someone else's repo on my dev machine before doing a pull? |
| 16:45 | technomancy | but with clojars if you've got a bug fix you want to use, it's easy to push your own version with the fix if you can't wait for inclusion |
| 16:45 | technomancy | chouser: not at all |
| 16:45 | ordnungswidrig | is there a pendant to reduce where you provide a single initial value and a list of functions f1 f2 f3 so that is returns (f3 (f2 (f1 x))) |
| 16:46 | technomancy | chouser: just add them as a remote, fetch from them, and create a branch based on theirs. then review changes and merge if you like 'em. |
| 16:46 | chouser | technomancy: ok, thanks. |
| 16:46 | kotarak | ordnungswidrig: (reduce #(%2 %1) 0 [inc inc dec dec]) |
| 16:47 | ordnungswidrig | kotarak: ah fine |
| 16:47 | ohpauleez | ordnungswidrig: it sounds like you want to do monadic functions or composition (comp) |
| 16:47 | technomancy | you don't even need to create a branch based on theirs actually, you can check theirs out directly if you don't think you'll need to modify it at all. |
| 16:47 | chouser | ordnungswidrig: (-> x f1 f2 f3) |
| 16:47 | ohpauleez | or that, lacing is a good way too |
| 16:48 | kotarak | ... if f1 and friends are known at compile time. |
| 16:48 | ordnungswidrig | ohpauleez: ((reduce comp [f1 f2 f3]) x) ? |
| 16:48 | chouser | ordnungswidrig: or what ohpauleez said. ((apply comp [inc inc inc]) 2) |
| 16:48 | kotarak | ordnungswidrig: ((apply comp [f1 f2 f3]) x) |
| 16:49 | chouser | actually [f3 f2 f1] |
| 16:50 | ordnungswidrig | ok, I see why it didn't work for me. f is not f :: A -> A but f :: A -> B -> b where B shall be passed through. I think I can throw in some currying |
| 16:51 | somnium | ~haskell |
| 16:51 | clojurebot | haskell is Yo dawg, I heard you like Haskell, so I put a lazy thunk inside a lazy thunk so you don't have to compute while you don't compute. |
| 16:55 | knuckolls | ,((apply comp [inc inc inc]) 2) |
| 16:55 | clojurebot | 5 |
| 16:55 | knuckolls | ,((reduce comp [inc inc inc]) 2) |
| 16:55 | clojurebot | 5 |
| 16:55 | knuckolls | what is the difference? |
| 16:55 | hiredman | reduce generates more functions |
| 16:56 | knuckolls | how so? |
| 16:56 | hiredman | reduce is (comp (comp inc inc) inc) |
| 16:56 | knuckolls | ah |
| 16:56 | mebaran151_ | what's the best way to get clojureql |
| 16:57 | mebaran151_ | clojars have the right version? |
| 16:57 | hiredman | lein! |
| 16:57 | kotarak | mebaran151_: from clojars. |
| 16:57 | chouser | comp has some unrolling that makes up to three args a bit faster |
| 16:57 | hiredman | I bet clojars has like five versions |
| 16:57 | kotarak | or gradle :P |
| 16:57 | mebaran151_ | clojars actually only has 2 |
| 16:57 | hiredman | chouser: eh> |
| 16:57 | mebaran151_ | one a coworker patched of an older version |
| 16:57 | mebaran151_ | and this unofficial snuxoll package |
| 16:58 | kotarak | mebaran151_: http://gitorious.org/clojureql/clojureql for the adventurous |
| 16:58 | hiredman | (people who can be bothered installing yet another build system) |
| 16:58 | ordnungswidrig | pff, is there a cheap way to reverse the seq of fs? |
| 16:58 | chouser | ordnungswidrig: 'reverse' :-) |
| 16:59 | kotarak | ordnungswidrig: reverse ;p |
| 16:59 | hiredman | hardly cheap |
| 16:59 | ordnungswidrig | (apply comp (reverse (map #(partial g %) fs))) |
| 16:59 | kotarak | Or rseq if you have a vector |
| 16:59 | ordnungswidrig | atm the list is rather short. |
| 17:00 | ordnungswidrig | so if the list of functions is long I think I'll do it with a reduce |
| 17:00 | mebaran151 | I wish the dependencies for clojars didn't pull down the world of sql |
| 17:00 | mebaran151 | seems as though you should get to choose which jdbc adapter you want to compile in |
| 17:00 | kotarak | mebaran151: I working on that. |
| 17:00 | kotarak | I'm |
| 17:01 | kotarak | There will be finer dependencies in the future. |
| 17:01 | mebaran151 | while I put out my wishlist, have you guys considered adding h2 |
| 17:01 | mebaran151 | it's like a nicer version of derby, with builtin lucene integration |
| 17:02 | mebaran151 | I'd be willing to help contribute an adapter if the process were simple enough |
| 17:02 | kotarak | Is that HSQL? patches welcome. ;) |
| 17:03 | ordnungswidrig | nice: (reduce #(exe %2 %1) fs) works in my case. |
| 17:03 | hiredman | mebaran151: there is some kind of exclude option for lein |
| 17:03 | mebaran151 | it's more hsql2 |
| 17:03 | mebaran151 | I'm not sure how you guys would want to integrate the fulltext search option |
| 17:04 | mebaran151 | it's something I've always thought an SQL db shoudl have |
| 17:05 | leafw | a simple question: a fn to update a value in a map, without knowing f the key already exists? |
| 17:06 | kotarak | (update the-map [the-key] (fnil f the-default)) |
| 17:06 | leafw | cool |
| 17:06 | kotarak | leafw: fnil was on the google group, posted by Rich |
| 17:06 | kotarak | Just a sec |
| 17:07 | kotarak | leafw: http://groups.google.com/group/clojure/msg/f251cfd9baab440a |
| 17:07 | hiredman | depending on the implementation of fnil you might getaway with (update the-map [the-key] fnil f the-default) |
| 17:08 | knuckolls | say i'm loading a huge file in slime but i want to stop the load and get back to the repl, how would i do that in slime? |
| 17:08 | the-kenny | C-c C-c |
| 17:08 | knuckolls | or really, kill any currently running s-exp. like ctrl-c |
| 17:08 | knuckolls | aha, tricky |
| 17:09 | the-kenny | Maybe you can also kill a possible-existing worker-thread |
| 18:07 | mebaran151 | how do you insert in ClojureQL? |
| 18:08 | kotarak | with insert. |
| 18:08 | kotarak | Just a sec |
| 18:09 | kotarak | mebaran151: http://gitorious.org/clojureql/clojureql/blobs/master/src/clojureql/demos/common.clj |
| 18:09 | kotarak | mebaran151: there are some examples |
| 18:10 | mebaran151 | okay |
| 18:10 | mebaran151 | thanks! |
| 18:11 | mebaran151 | what namespace does sql refer to? |
| 18:13 | hiredman | http://github.com/hiredman/clojurebot/blob/master/hiredman/triples.clj |
| 18:14 | kotarak | mebaran151: clojureql |
| 18:21 | mebaran151 | hiredman, have you looked at neo4j's triple support? |
| 18:21 | mebaran151 | I'm planning on wrapping it when I get the chance |
| 18:24 | hiredman | mebaran151: I just through a rock and hit derby, I didn't look at anything else for clojurebot |
| 18:28 | KirinDave | Does anyone here have experience with compojure? |
| 18:28 | KirinDave | Specifically, trying to get sessions to work but the docs are kinda sketchy on what they actually want here. |
| 18:29 | ctdean | I used an earlier version of compojure w/ sessions, what are you trying to do? |
| 18:32 | KirinDave | ctdean: Just save some values in a dang session |
| 18:32 | ctdean | Let me see if I can paste a quick example |
| 18:32 | KirinDave | https://gist.github.com/bcac547ff8ebfde2c982 |
| 18:33 | ctdean | wrap the routes in with-session |
| 18:33 | KirinDave | All of them? |
| 18:34 | KirinDave | There is only 1 where I am trying to get it to work. |
| 18:34 | KirinDave | And also |
| 18:34 | KirinDave | Do you see I wrap main-app with (with-session) ? |
| 18:34 | ctdean | Ah, I see. I missed that |
| 18:34 | mebaran151 | hiredman, it might be interesting to play with |
| 18:34 | mebaran151 | what's the best way to create table if not exists in clojureql |
| 18:35 | kotarak | mebaran151: there are also examples for create table in the previously posted link. However create-table is currently in flux. Just a sec. |
| 18:35 | ctdean | one sec |
| 18:36 | kotarak | mebaran151: http://gitorious.org/clojureql/pages/CreateTableSyntax |
| 18:38 | ctdean | The only thing I can see different is that I used {:type :memory :expires (* 60 5)}) instead if the default |
| 18:38 | KirinDave | Where? |
| 18:38 | ctdean | So, (with-session thing {:type :memory :expires (* 60 5)}) |
| 18:39 | KirinDave | How are you supposed to set it? |
| 18:39 | somnium | KirinDave: I think you need to return a map with a session key so the session middleware sees it, like {:session {:user "some-guy"} :body "..."} |
| 18:39 | KirinDave | Ahah |
| 18:39 | KirinDave | I didn't realize I had to assoc onto their session |
| 18:40 | mebaran151 | kotarak, how do I get the if not exists behavior? |
| 18:41 | mebaran151 | also any easy way to create index on a table? |
| 18:41 | kotarak | mebaran151: no indexes, yet. |
| 18:42 | ctdean | Ah yes there is a (session-assoc :x 1) call you need to do |
| 18:42 | mebaran151 | but what about if not exists, or what would be the best way to check if a table existed? |
| 18:43 | kotarak | mebaran151: you have to do (drop-table foo :if-exists) (create-table foo) |
| 18:43 | mebaran151 | what if I don't want to drop the table |
| 18:43 | mebaran151 | I just want to create it if not exist |
| 18:43 | mebaran151 | can create-table have an :if-not-exists option? |
| 18:44 | kotarak | mebaran151: if the backends support it... Nicolas is currently working on create-table. |
| 18:44 | mebaran151 | ah |
| 18:45 | kotarak | eg. Derby does not support drop-table if-exists, so no support there. |
| 18:45 | kotarak | eg. Postgres does, so the support is available. |
| 18:46 | Licenser | I've some seriouse problems with swank clojure and os x it just refuses to connect to the projects repl :/ |
| 18:46 | Licenser | I get 'Polling "/var/folders/b5/b5QOdd5jGfmy7oTg2xxwEU+++TI/-Tmp-/slime.2875".. (Abort with `M-x slime-abort-connection'.)' and a few thousand attempts but it kind of just keeps doing that |
| 18:49 | mebaran151 | kotarak, do you guys supply any mechanism to query the schema? |
| 18:59 | joshua-choi | Question: What is the purpose of separating the array-map and hash-map functions? Is there a time when I should use one and not the other? |
| 19:04 | mebaran151 | kotarak, how does one open a db transaction? |
| 19:04 | technomancy | joshua-choi: I get the feeling that's an implementation detail leaking; I don't think you ever want to call array-map |
| 19:05 | technomancy | array-maps have the odd property of allowing duplicate keys, which you really don't want. |
| 19:05 | joshua-choi | technomancy: Well, the {...} syntax creates array maps or hash maps, depending on the number of elements inside, right? |
| 19:06 | joshua-choi | I'm not sure how it decides, though |
| 19:06 | technomancy | if it's 8+ entries, it's a hash map |
| 19:06 | technomancy | ,{:a "A" :b "B" :a "C"} |
| 19:06 | clojurebot | {:a "A", :b "B", :a "C"} |
| 19:06 | joshua-choi | ,(type {:a 3}) |
| 19:06 | clojurebot | clojure.lang.PersistentArrayMap |
| 19:07 | joshua-choi | ,(type {1 2 3 4 5 6 7 8 9 0 123 529 59 293 12 32 98 10}) |
| 19:07 | clojurebot | clojure.lang.PersistentHashMap |
| 19:08 | joshua-choi | Is there any function that imitates the {...} notation? |
| 19:08 | joshua-choi | Something like the vec or set functions for maps |
| 19:08 | technomancy | ,(type (hash-map)) |
| 19:08 | clojurebot | clojure.lang.PersistentArrayMap |
| 19:08 | technomancy | not sure what to think of that |
| 19:09 | technomancy | I guess just use hash-map and be sure not to have any duplicate values in your literals. |
| 19:09 | joshua-choi | That's so weird |
| 19:09 | joshua-choi | Okay, thanks for the advice |
| 19:09 | technomancy | as long as you don't have duplicate keys in your literals, you'll never notice the difference |
| 19:09 | joshua-choi | ,(type (array-map 1 2 3 4 5 6 7 8 9 0 123 529 59 293 12 32 98 10)) |
| 19:09 | clojurebot | clojure.lang.PersistentArrayMap |
| 19:09 | joshua-choi | Hmm |
| 19:10 | technomancy | assoc and friends won't allow duplicates even on array-maps |
| 19:10 | technomancy | it's only the constructors that do |
| 19:10 | mebaran151 | also, I'm getting a strange error, java.sql.SQLException, Resultset not open |
| 19:11 | somnium | ,(type (assoc (array-map 1 2 3 4 5 6 7 8 9 0 123 529 59 293 12 32 98 |
| 19:11 | somnium | 10) :a :a)) |
| 19:11 | clojurebot | EOF while reading |
| 19:11 | joshua-choi | And it seems like array-map always returns array maps, while hash-map may return either array or hash maps |
| 19:12 | technomancy | I don't think it's ever an issue in real life, but it's interesting to peek under the covers |
| 19:12 | somnium | bah, array-maps automatically get made to hash-maps as they grow |
| 19:12 | technomancy | the only time it bites people is when you're using transients incorrectly (bashing in place) and an array-map grows into a hash-map |
| 19:13 | joshua-choi | Oh, can that happen? I haven't tried map transients yet |
| 19:14 | technomancy | which is actually a feature! since it gives you an opportunity to learn what transients are actually all about. =) |
| 19:23 | dysinger | skeptomai: I come to see opscode again in jan 25-29 timeframe :) I'll have to infect opscode with some clojure |
| 19:23 | dysinger | we should actually get some chef recipes going in clojure ;) |
| 19:24 | skeptomai | dysinger: totally |
| 19:24 | skeptomai | I have it running with slime, et al, but haven't had time to do anything cool |
| 19:40 | ctdean | what dep should I use in lein to get the compojure jars ? |
| 19:42 | tomoj | as far as I know there isn't a good one yet |
| 19:43 | tomoj | all the ones I saw didn't include all the deps, as far as I could tell |
| 19:45 | tomoj | I made my own, org.clojars.tomo/compojure |
| 19:45 | tomoj | but I can't remember if I've gotten it working perfectly yet |
| 19:46 | ctdean | ok thanks |
| 19:46 | tomoj | eventually the compojure people will provide one, I would hope |
| 19:51 | erikcw | M-x swank-clojure-project doesn't seem to do anything. I setup that path with a lib directory with my extra jars, but "(println (seq (.getURLs (java.lang.ClassLoader/getSystemClassLoader))))" doesn't seem to change. Am I missing something? |
| 19:53 | tomoj | erikcw: do you use leiningen? |
| 19:53 | erikcw | tomoj: not yet |
| 19:53 | erikcw | I'm just getting started |
| 19:54 | tomoj | oh, I think I remember having a problem where lein tricked swank-clojure-project into not finding my jars |
| 19:54 | tomoj | but I'm not sure |
| 19:54 | erikcw | is lein the recommended "method" |
| 19:56 | tomoj | it is getting there |
| 19:56 | tomoj | but I still use swank-clojure project sometimes |
| 19:56 | tomoj | (and it still picks up my jars) |
| 19:57 | tomoj | what version of swank-clojure are you using? |
| 19:57 | erikcw | do I need any directories other than lib? |
| 19:57 | tomoj | src/ and lib/ are all I usually use |
| 19:58 | erikcw | I'm 1.1.0 |
| 19:58 | tomoj | oh, mine is outdated |
| 19:58 | erikcw | out of package-list-packages... |
| 19:58 | tomoj | now my package-list-packages isn't even working |
| 20:15 | tomoj | mebaran151: why? |
| 20:24 | mebaran151 | getting errors like |
| 20:25 | mebaran151 | no multimethod for integer embedconn |
| 20:25 | mebaran151 | resultset not open |
| 20:25 | mebaran151 | I can't get it to do anything basic |
| 20:25 | JonSmith | what is the it that is broken |
| 20:27 | mebaran151 | query |
| 20:28 | mebaran151 | so I think the table gets created (it returns an EmbedStatement) |
| 20:28 | mebaran151 | #<EmbedSQLException java.sql.SQLException: ResultSet not open. Operation 'next' not permitted. Verify that autocommit is OFF.> |
| 20:28 | mebaran151 | that's the error |
| 20:28 | mebaran151 | sure there should be no rows |
| 20:28 | mebaran151 | but I have no idea how to fix it |
| 20:30 | tomoj | maybe if the owner comes around he will have an idea |
| 20:38 | JonSmith | is there a good explanation of how the 'shared structure' works in clojure |
| 20:40 | mebaran151 | http://gist.github.com/272648 << if anybody knows clojureql, maybe I'm just doing it wrong so to speak |
| 20:40 | JonSmith | I'm thinking about using a vector of hash-maps to represent state changes, where each is incrementally changed version of the next |
| 20:40 | JonSmith | wondering if that will be hugely memory intensive |
| 20:41 | mebaran151 | each hash-map? |
| 20:41 | mebaran151 | that shouldn't be |
| 20:41 | mebaran151 | only hash-map modifications are recorded |
| 20:41 | mebaran151 | the vectors still point to the same basic structures |
| 20:42 | JonSmith | yeah each hash map |
| 20:42 | JonSmith | i was thinking it would be a good way to represent user state in a web app |
| 20:43 | mebaran151 | hmmm |
| 20:43 | mebaran151 | interesting |
| 20:51 | JonSmith | yeah i was thinking of it as a hybrid between rest and cps frameworks |
| 20:51 | hiredman | mebaran151: the results from clojureql are in a lazy seq that is closed when you leave the scope of whatever form that is |
| 20:51 | hiredman | cql/run |
| 20:52 | hiredman | or the result of the query that is used to generate the lazy-seq is closed |
| 20:52 | hiredman | basically you have to use doall everywhere |
| 20:52 | hiredman | very much a pain |
| 21:10 | mebaran151 | hmmm? |
| 21:10 | mebaran151 | do hiredman, is my createtable statement okay? |
| 21:11 | LordMetroid | hm clojure seems very tempting, why are no one adopting it? |
| 21:12 | LordMetroid | *why are so few adopting it? |
| 21:12 | JonSmith | seems like a lot are? |
| 21:13 | JonSmith | #clojure pop is only 100 less than #lisp pop |
| 21:14 | LordMetroid | mmm, but I don't see the popularization of the language on such scale as Erlang for example. |
| 21:19 | JonSmith | oh |
| 21:19 | JonSmith | idk its pretty young so we'll see |
| 21:21 | LordMetroid | mmm, it sure seems to have a well progressing early adopters rate |
| 21:22 | mebaran151 | http://gist.github.com/272668 |
| 21:22 | mebaran151 | that's my create-table method |
| 21:22 | hiredman | erlang has been around *forever* |
| 21:22 | mebaran151 | is it technically correct? |
| 21:23 | mebaran151 | erlang hails from the late 80's doesn't it |
| 21:25 | hiredman | erlang also is used to address a current problem (distributed systems) while clojure is aimed at a still developing problem (leveraging multicore) |
| 21:25 | hiredman | mebaran151: as far as I can tell |
| 21:26 | mebaran151 | I should be able to run (query users *) afterwards |
| 21:26 | mebaran151 | however when I try to run it |
| 21:26 | mebaran151 | I get ... brokenness |
| 21:27 | mebaran151 | Resultset has no next ('cause there are no results) |
| 21:27 | hiredman | most likely because you are try to examine the resultset after it has been closed |
| 21:28 | mebaran151 | (doall (dosql (query users *))) |
| 21:28 | mebaran151 | that doesn't work |
| 21:28 | mebaran151 | I can't figure out a single construct that does |
| 21:28 | hiredman | you have to put the doall inside |
| 21:29 | hiredman | the resultset is closed after leaveing the 'run' macro |
| 21:29 | mebaran151 | order doesn't matter |
| 21:29 | hiredman | are you sure? |
| 21:29 | mebaran151 | putting the doall inside the dosql doesn't do anything |
| 21:30 | mebaran151 | (run *conn-info* (doall (query users *))) << this doesn't work |
| 21:30 | hiredman | *shrug* |
| 21:35 | cark | (run *conn-info* (doall (dosql (query users *)))) not working either ? |
| 21:35 | ctdean | What are folks using for Amazon S3 access these days? |
| 21:35 | hiredman | dosql expands into a call to run |
| 21:35 | mebaran151 | yeah |
| 21:36 | mebaran151 | just embeds *conn-info* |
| 21:40 | mebaran151 | do I have to do something special with the embedpreparedstatement the statement creator returns? |
| 21:42 | LordMetroid | hiredman: Erlang was constructed to solve concurrency and reliability |
| 21:43 | LordMetroid | hiredman: It was developed by the company Ericsson AB to run their telephone systems, which demands reliability and concurrency |
| 21:43 | mebaran151 | cark, no matter where I put the doall I get an error |
| 21:43 | mebaran151 | and I can't insert |
| 21:43 | mebaran151 | I'm gonna try building from source |
| 21:44 | LordMetroid | hiredman: as a side effect of them solving concurrency using hyper-lightweight processes and message passing rather than shared state Erlang is well suited for multicore deployment as well |
| 21:45 | LordMetroid | hiredman: as of lately the Erlang VM development has been focusing on optimizing multicore executions |
| 21:56 | mebaran151 | I'm gonna try to run the demos |
| 22:01 | JonSmith | erlang is a little slower distributed because of tcp connections and message passing and stuff |
| 22:03 | hiredman | LordMetroid: sure, because everyone can seen it on the horizon, but clojure is targeted at it right now |
| 22:03 | LordMetroid | well, it is running on the JVM so I wouldn't exactly say it is developed for multicore deployment |
| 22:17 | mebaran151 | this ResultSet not open is beginning to annoy me to hell |
| 22:26 | hiredman | LordMetroid: have you seen the specially built jvm boxes? |
| 22:26 | LordMetroid | hiredman: no, what do you mean? |
| 22:26 | hiredman | azul |
| 22:27 | hiredman | the jvm can do multicore just fine |
| 22:27 | LordMetroid | I see |
| 22:27 | mebaran151 | now I got inserts working, I just can't get queries to ... stay open |
| 22:28 | LordMetroid | okay time to get some sleep before the sun rises |
| 22:28 | JonSmith | you have to do everything in the dosql right? |
| 22:28 | JonSmith | its like a transaction or something? |
| 22:28 | JonSmith | or am i wrong |
| 22:29 | JonSmith | just kind of wondering |
| 22:31 | hiredman | it's a macro he wrote |
| 22:31 | JonSmith | oh that isn't native to the library |
| 22:32 | mebaran151 | I've tried it with run |
| 22:32 | mebaran151 | and I get the same results |
| 22:33 | mebaran151 | (doall (sql/run *conn-info* (sql/query users * (= username "mebaran")))) |
| 22:33 | mebaran151 | this too fails |
| 22:34 | mebaran151 | as with the doall in front for the query |
| 22:34 | mebaran151 | this resultset refuses to stay open |
| 22:34 | hiredman | did you look at the examples from clojurebot? |
| 22:34 | mebaran151 | yep |
| 22:34 | hiredman | well, you must not have been paying attention :P |
| 22:34 | JonSmith | (sql/run *conn-info* (doall (sql/query users * (= username "mebaran")))) |
| 22:34 | JonSmith | did you try that? |
| 22:35 | mebaran151 | same beans |
| 22:35 | hiredman | http://github.com/hiredman/clojurebot/blob/master/hiredman/triples.clj#L50 <-- what is different in this call to run? |
| 22:35 | mebaran151 | {:jdbc-url "jdbc:derby:.gate/db;create=true", :username nil, :password nil} << mode string |
| 22:35 | mebaran151 | ah ha |
| 22:36 | JonSmith | hiredman wrote it? |
| 22:36 | mebaran151 | oh |
| 22:36 | mebaran151 | I just have to bind it to something in scope |
| 22:36 | mebaran151 | let's try this huzzah |
| 22:36 | JonSmith | that's interesting |
| 22:37 | JonSmith | i guess its like a with-open macro |
| 22:37 | mebaran151 | oh my |
| 22:37 | mebaran151 | it worked |
| 22:37 | mebaran151 | yay |
| 22:38 | hiredman | it's rather distateful |
| 22:38 | hiredman | it looks like a binding form, but isn't |
| 22:38 | hiredman | if you just want to use the result seq you have to call doall everywhere |
| 22:38 | hiredman | etc |
| 22:39 | hiredman | there was a blog post criticizing the use (abuse?) of syntax quote and unquote |
| 22:40 | hiredman | but it works, I guess, which is good... |
| 22:40 | mebaran151 | I thought syntax quote was okay |
| 22:40 | mebaran151 | it made me realize that it was quoting the sql |
| 22:40 | mebaran151 | I read the post |
| 22:43 | hiredman | I have a query api I was working on for the appengine datastore, which is much simpler than sql, but i think I did a nicer job of looking like clojure |
| 22:43 | hiredman | (qfilter (= 1 :count) (query :counter-things)) |
| 22:48 | mebaran151 | it looks almost rubyish |
| 22:48 | mebaran151 | you have to check the result to be a seq |
| 22:48 | mebaran151 | (defmacro dosql |
| 22:48 | mebaran151 | [& forms] |
| 22:48 | mebaran151 | `(sql/run [*conn-info* results#] ~@forms (if (seq? results#) (doall results#) results#))) |
| 22:48 | mebaran151 | I think it should run somewhat like that |
| 22:49 | mebaran151 | call doall for you |
| 22:49 | hiredman | anyway, we need scopes |
| 22:50 | mebaran151 | I ran into this problem with my neo4j bindings (I want to close the resultset of nodes but I can't) |
| 22:51 | mebaran151 | do scopes have to be built into clojure proper or could sufficiently advanced macro fu emulate them? |
| 22:51 | hiredman | I have such a macro |
| 22:51 | hiredman | http://github.com/hiredman/clojurebot/blob/master/hiredman/horizon.clj |
| 22:52 | hiredman | ~scopes |
| 22:52 | clojurebot | I don't understand. |
| 22:52 | hiredman | ~scope |
| 22:52 | clojurebot | scope is at http://paste.lisp.org/display/73838 |
| 22:54 | mebaran151 | but you'd have to stay within and explicit scoping construct |
| 22:54 | mebaran151 | it seems like a more general with-open |
| 22:54 | hiredman | sure |
| 22:54 | hiredman | exactly |
| 22:55 | mebaran151 | I'd love to be able to give a lazy-seq to some caller, and then when they are done with it, have something like IDispose get called |
| 22:55 | hiredman | that is the idea behind scopes |
| 22:56 | hiredman | if F produces a lazy seq one some resource that needs to be closed, it can register a thunk to do the closing |
| 22:57 | hiredman | and then just return the lazy-seq and not worry about it |
| 22:57 | mebaran151 | but you still have to act within the scope |
| 22:57 | mebaran151 | as in the caller has to setup the scope right? |
| 22:57 | hiredman | sure |
| 22:57 | mebaran151 | I would like a super finally |
| 22:58 | mebaran151 | finally that gets called after a variable goes out of scope permanently |
| 22:58 | hiredman | no variables |
| 22:58 | hiredman | names bound to values |
| 22:59 | hiredman | when a name goes out of scope |
| 22:59 | mebaran151 | yeah |
| 23:00 | mebaran151 | it seems like something I'd almost want a :post on functions to handle |
| 23:00 | hiredman | but the called function can't know what (or if) it's result will be bound to |
| 23:00 | mebaran151 | yeah |
| 23:00 | mebaran151 | I guess it's like transactions for refs: if you want to work with a construct, you have to be prepared to inform the construct where you're working with it |
| 23:06 | mebaran151 | so I guess inside that scope you'd like say, read all the nodes you want, copy them to the outside scope space and get to close the iterator |
| 23:35 | mebaran151 | couldn't a sufficiently smart compiler know? |
| 23:35 | mebaran151 | when a name would no longer be applicable, and therein dispose of the resource |
| 23:39 | hiredman | for some subset of cases |
| 23:40 | hiredman | it would have to be really really smart |
| 23:43 | mebaran151 | this is true |