2009-08-27
| 00:07 | lowlycoder | this really bit me: are vars created via defn and def dynamically, rather than lexicallys coped? |
| 00:07 | lowlycoder | are bindings created via let lexically scoped, or are they somehow dynamicallys coped too? |
| 00:20 | rathore | let is lexically scoped |
| 00:21 | JAS415 | uh |
| 00:21 | JAS415 | let is lexical |
| 00:21 | JAS415 | def and defn are dynamic |
| 00:21 | JAS415 | (vars) |
| 00:21 | JAS415 | binding form can alter a var's.. binding |
| 00:31 | lowlycoder | anyone here running clojure on the mac? |
| 00:46 | tomoj | yeah |
| 00:51 | durka42 | me too |
| 00:59 | rathore | me too |
| 01:01 | rathore | development on mac, all deployments on ubuntu |
| 01:02 | durka42 | rhickey uses a mac too, doesn't he |
| 01:04 | tomoj | I've seen him use a mac in presentations |
| 01:04 | tomoj | and emacs :) |
| 01:10 | JAS415 | im use ubuntu |
| 01:51 | adityo | good morning folks |
| 01:54 | adityo | why do we use #^ before a form? reading some code, seen it in a couple of places |
| 02:00 | adityo | okie got it! works as metadata keys |
| 04:15 | tomoj_ | YEEESSS http://skitch.com/tomoj/bhhw5/terminal-java-80x24 |
| 04:15 | tomoj_ | now to get this working with clojure :D |
| 04:20 | Fossi | weird :D |
| 04:23 | tomoj_ | it's not ideal for my purposes but I think it's better than writing my own ncurses or ansi stuff |
| 04:24 | Fossi | it would be fun to port swing to that |
| 04:26 | tomoj_ | some other implementations I found sortof did that |
| 04:26 | tomoj_ | swing-like APIs |
| 04:26 | tomoj_ | couldn't get them to work |
| 04:27 | tomoj_ | I don't want swing-like anyway really |
| 04:37 | tomoj_ | :D http://skitch.com/tomoj/bhhsj/terminal-java-80x24 |
| 04:39 | noidi | cool :) |
| 04:58 | lowlycoder | since clojure only provides the ACI in ACID, what should I use for durability? |
| 05:02 | dosync | lowlycoder: Have you looked at clojure.contrib.sql for working with sql databases? |
| 05:02 | lowlycoder | i don't want to touch sql |
| 05:04 | Fossi | lowlycoder: schema free databases work pretty well for us. couchdb, google appengine datastore and such |
| 05:05 | lowlycoder | does couchdb actually require erlang to run? |
| 05:05 | Fossi | well, as much as apache requires C to run |
| 05:07 | tomoj_ | I got it running on my mac without much trouble if I remember correctly |
| 05:08 | tomoj_ | sudo port install couchdb |
| 05:08 | lowlycoder | hmm; best solution so far looks like sqljet |
| 05:08 | tomoj_ | thought you didn't want to touch sql? |
| 05:08 | lowlycoder | my bad |
| 05:08 | lowlycoder | i don't want an external server |
| 05:08 | lowlycoder | horribly said |
| 05:09 | lowlycoder | somehoq mentally i group sql with mysql and postgresql and oracle |
| 05:09 | lowlycoder | but not with sqllite |
| 05:09 | lowlycoder | my fault definitely |
| 05:09 | Fossi | ah, that's another story then |
| 05:09 | lowlycoder | oh; explain |
| 05:09 | tomoj_ | well looks like sqljet actually doesn't have a sql interface.. |
| 05:09 | tomoj_ | :) |
| 05:11 | lowlycoder | does clojure have 'builtin' serialization/deserialization? |
| 05:12 | tomoj | well.. the basic data structures are readable |
| 05:14 | tomoj | ,(read (java.io.PushbackReader. (java.io.StringReader. "[1 2 3]"))) |
| 05:14 | clojurebot | [1 2 3] |
| 05:15 | lowlycoder | ,(java.io.StringReader. "[1 2 3]") |
| 05:15 | clojurebot | #<StringReader java.io.StringReader@111c3f0> |
| 05:15 | tomoj | but you can't serialize structmaps that way yet without some extra steps |
| 05:27 | lowlycoder | why does def write to the global environment rather than the local environment? |
| 05:27 | tomoj | if I understand what you mean, the latter is impossible in clojure |
| 05:28 | tomoj | there are no local assignable variables |
| 05:28 | lowlycoder | (defn bar [] (defn foo [] ...)) |
| 05:29 | tomoj | use let or letfn |
| 05:29 | lowlycoder | why can't i have this become (defn bar[] (let [foo fn [] ...] ..)) |
| 05:29 | lowlycoder | as scheme/lisp tends to interpret it as |
| 05:29 | lowlycoder | what's the motivation behind clojure's def goes to global env? |
| 05:29 | tomoj | it looks like imperative programming |
| 05:30 | lowlycoder | clojure or scheme? |
| 05:30 | tomoj | using def in the way you want |
| 05:30 | tomoj | e.g. a clojure newbie might want to write (def x (inc x)) |
| 05:30 | tomoj | where they would write x=x+1 in an imperative language |
| 05:30 | lowlycoder | whereas in this way, when I execute bar, it redefiens foo on the fly |
| 05:30 | lowlycoder | and breaks all my code |
| 05:31 | tomoj | I'm not sure the code you wrote above makes sense |
| 05:31 | tomoj | defn returns a function, it doesn't execute the body |
| 05:31 | tomoj | (defn bar [] (defn foo [] ...)), even if it "wrote to the local env", wouldn't be equivalent to (defn bar [] (let [foo (fn [] ...)] ...)) |
| 05:32 | lowlycoder | why ot? |
| 05:32 | lowlycoder | *not* |
| 05:32 | tomoj | the latter executes the body of the let form |
| 05:32 | tomoj | the former just returns a function |
| 05:33 | tomoj | defn doesn't say "define foo to be this function and then do this with it" |
| 05:33 | tomoj | it just says "define foo to be this function and return it" |
| 05:33 | tomoj | you would need (defn bar [] (defn foo [] ...) (<something that uses foo>)) |
| 05:33 | tomoj | and that's evil |
| 05:34 | tomoj | defn is supposed to be toplevel, if you want to lexically bind something, use the lexical binding forms :) |
| 05:34 | lowlycoder | are there any besides let nad letfn? |
| 05:34 | lowlycoder | i just don't wnat the following code to be indented |
| 05:35 | tomoj | it should be indented imo |
| 05:35 | tomoj | it's in a new context |
| 05:35 | lowlycoder | scheme/lisp doesn't do it that way; old habits die hard |
| 05:35 | tomoj | loop and for do lexical binding, there may be others |
| 05:36 | tomoj | how does lisp do it? |
| 05:36 | lowlycoder | well, I can say things like |
| 05:36 | lowlycoder | (define (foo ...) |
| 05:36 | lowlycoder | (define (bar1 ...) .... ) |
| 05:36 | lowlycoder | (define (bar 2 ...) ... ) |
| 05:36 | lowlycoder | ... some code involving bar1 and bar 2 ... ) |
| 05:36 | lowlycoder | without bar1 bar2 becoming global forms |
| 05:36 | lowlycoder | whereas in clojure I have to do |
| 05:37 | lowlycoder | (define foo [...] |
| 05:37 | lowlycoder | (letfn [[bar1 [] ....] |
| 05:37 | lowlycoder | [bar2 [] ....] |
| 05:37 | lowlycoder | ] |
| 05:37 | lowlycoder | ... more code ... )) |
| 05:37 | lowlycoder | the identing just looks more uglier and mucm more to the right |
| 05:38 | _mst | common lisp is the same--you would have to use flet/labels to get the effect you're after (as in clojure) |
| 05:38 | lowlycoder | okay; scheme then :-) |
| 05:38 | tomoj | that seems evil to me |
| 05:38 | Chousuke | I suppose defn could be made context-aware. |
| 05:38 | Chousuke | but it'd be weird. |
| 05:39 | lowlycoder | why? |
| 05:39 | tomoj | I don't think it's the defn equivalent that's special in scheme, just guessing |
| 05:39 | tomoj | because apparently those defines can only come at the beginning of the body |
| 05:40 | Chousuke | hmm :/ |
| 05:40 | tomoj | let would need to be made aware that defs at the beginning of its body are really lexical bindings |
| 05:40 | tomoj | well, let and defn and etc |
| 05:40 | tomoj | but I think a form that's using lexical bindings should be contained in the forms that set up those bindings |
| 05:40 | tomoj | lowlycoder: you could always write a macro |
| 05:41 | Chousuke | well, defn could just check a bound var and emit a letfn instead of def if it is bound to true, and bind it to true if it's false |
| 05:41 | lowlycoder | i can't express this as a macro |
| 05:41 | lowlycoder | tomoj: how would this macro look like? macros have to 'contain' the parts in them |
| 05:41 | lowlycoder | the define i want needs to run to the end of the currnt environment |
| 05:41 | tomoj | you would need to use the macro at the toplevel |
| 05:41 | tomoj | e.g. use silly-defn instead of defn |
| 05:42 | tomoj | which goes through and replaces defs with lexical bindings |
| 05:42 | lowlycoder | hmm; this could be interesting |
| 05:43 | lowlycoder | looks like the keyword define isn't taken up either :-) |
| 05:43 | Chousuke | clojure has a peculiar feature btw. |
| 05:43 | lowlycoder | what's that? |
| 05:44 | lowlycoder | binding to vars rather than values? |
| 05:44 | Chousuke | user=> (def def 1) -> #'user/def, user=> def -> 1, user=> (def foo 1) -> #'user/foo |
| 05:44 | lowlycoder | wt |
| 05:44 | lowlycoder | f ... isn't clojure a lisp 1? |
| 05:45 | Chousuke | yes |
| 05:45 | tomoj | I guess you would have to go through the forms in the body and macroexpand, and take-while the car is def, then convert those into a let that you wrap around the rest of the body |
| 05:45 | lowlycoder | how does this work? |
| 05:45 | Chousuke | special forms are special only in operator position |
| 05:45 | Chousuke | otherwise, they're just symbols |
| 05:45 | Chousuke | ,let* |
| 05:45 | clojurebot | java.lang.Exception: Unable to resolve symbol: let* in this context |
| 05:46 | Chousuke | this is probably a half-bug, but rather harmless anyway |
| 05:46 | lowlycoder | (def def (fn [x] (println x))) (def 20) |
| 05:46 | Chousuke | lowlycoder: that will give an error :) |
| 05:47 | lowlycoder | not the definition, but the (def 20) |
| 05:47 | Chousuke | yeah |
| 05:47 | lowlycoder | i feel like clojure has great ideas |
| 05:47 | lowlycoder | but has some ugly hacks |
| 05:47 | Chousuke | can't avoid them sometimes. |
| 05:50 | Chousuke | purity is sacrificed for practicality if it's more beneficial than maintaining purity. |
| 05:51 | lowlycoder | why is this defn more practical? |
| 05:51 | Chousuke | well, it's easier for one. |
| 05:51 | Chousuke | to implement. |
| 05:52 | Chousuke | but also easier to use, because it doesn't have context-dependent effects. |
| 05:53 | Chousuke | though the scheme-style define is rather nice. |
| 05:53 | liwp | I find the current semantics confusing after scheme, but I guess that's cause I'm used to the scheme semantics |
| 05:54 | liwp | like lowlycoder I find the letfn forms noisy |
| 05:54 | lowlycoder | i actually thougth i had a race condition .... |
| 05:55 | liwp | I wrote a toy scheme once and I don't remember enclosed defines being any more difficult to implement than the top-level define... |
| 05:55 | lowlycoder | until I learned the real semantifs of defn today |
| 05:55 | Chousuke | I usually just do (let [foo (fn ...)] ...) |
| 05:55 | liwp | yeah, denf can really bite you |
| 05:55 | liwp | s/denf/defn |
| 05:55 | Chousuke | hmm, I don't have a scheme background so I can't relate to that. :/ |
| 05:55 | Chousuke | I just use defn on the toplevel |
| 05:56 | Chousuke | never occurred to me to use it elsewhere. |
| 05:56 | liwp | in the end it's not a big deal after you realize what the semantics are, I was just surprised |
| 05:56 | lowlycoder | (defn foo [] 3) (defn bar [] (defn foo [] 4)) ... (bar) ... (foo) -> 4 ... WTF??? :-) |
| 05:56 | liwp | Chousuke: if you have a look at SICP they use inner defines all over the place |
| 05:57 | Chousuke | I suppose common lisp people would be equally surprised by nesting defines if they had no knowledge of scheme :) |
| 05:57 | tomoj | I was |
| 05:57 | liwp | yep :) |
| 05:59 | tomoj | it would be very weird to me for defn to mean something different when it's at the beginning of a let/defn/etc body |
| 06:00 | liwp | I just think it's a really nice way to define helper functions that are not used anywhere else |
| 06:00 | lowlycoder | liwp: so how do you handle this now? just using let and letfn? |
| 06:00 | liwp | yep |
| 06:01 | liwp | to be honest I haven't really had to deal with it much |
| 06:01 | liwp | so it's not really a problem at all, just an observation |
| 06:03 | Chousuke | I suppose the extra indentation caused by letfn is unnecessary in a way, but I don't think it's that bad otherwise :) |
| 06:06 | Chousuke | lowlycoder used vectors earlier to contain the function bodies but I use the form (letfn [(foo [x y z] ...) (bar [] ...)]) |
| 06:07 | Chousuke | I like the scheme define for one other reason though, which is that the function definition looks like you're defining the value of a function call :) |
| 06:09 | Chousuke | eg. (define (f x) whatever) looks like it's defining (f x) |
| 06:09 | clojurebot | x is w |
| 06:10 | AWizzArd | xhatever? |
| 06:18 | tomoj | I like the body of letfn indented |
| 06:19 | tomoj | it shows me visually that that body is being executed within a special context |
| 06:22 | Fossi | how do i get the class for a Class? as in String.class |
| 06:22 | clojurebot | for is not used enough |
| 06:22 | Fossi | (class String) says java.lang.Class |
| 06:22 | clojurebot | ☕ |
| 06:23 | febeling | is there a way a know the name of the function that currently executes? |
| 06:24 | liwp | ,(.getClass "foo") |
| 06:24 | clojurebot | java.lang.String |
| 06:24 | liwp | is that what you want? |
| 06:24 | Fossi | liwp: i can't create the object |
| 06:24 | liwp | ,(type "foo") |
| 06:24 | clojurebot | java.lang.String |
| 06:24 | Fossi | as in, i don't have an instance |
| 06:24 | liwp | ahh |
| 06:24 | liwp | what do you have? |
| 06:24 | Fossi | a name ;D |
| 06:24 | liwp | you have to use Java's classForName magic |
| 06:25 | liwp | give me a minute |
| 06:25 | Fossi | i need to pass (DocumentListFeed.class) to an api |
| 06:26 | liwp | ,(Class/forName "java.lang.String") |
| 06:26 | clojurebot | java.lang.String |
| 06:26 | liwp | that can possibly throw all kinds of evil exceptions <http://java.sun.com/javase/6/docs/api/java/lang/Class.html#forName(java.lang.String, boolean, java.lang.ClassLoader)> |
| 06:27 | liwp | Fossi: does that help? |
| 06:27 | Fossi | it's evil (tm) ;) |
| 06:28 | liwp | indeed |
| 06:28 | tomoj | so there's no way to get from a literal classname to a class object? |
| 06:28 | liwp | I have no idea if Clojure gives you some nicer way to get the class |
| 06:28 | tomoj | (without instantiating) |
| 06:29 | liwp | tomoj: Class.forName gives you the class, no instance required |
| 06:29 | tomoj | ,(class Math) |
| 06:29 | clojurebot | java.lang.Class |
| 06:29 | tomoj | liwp: yeah, but you have to use a string |
| 06:29 | liwp | oh yeah |
| 06:29 | liwp | missed dthat |
| 06:29 | tomoj | Fossi: I guess you already tried just passing DocumentListFeed? |
| 06:35 | liwp | ,(.newInstance String) |
| 06:35 | clojurebot | "" |
| 06:36 | liwp | so it seems that class names work as class literals in clojure, cool |
| 06:36 | tomoj | seems to work fine to me |
| 06:36 | liwp | this is probably obvious if I think about it a bit... |
| 06:36 | tomoj | ,(.isAssignableFrom Number Integer) |
| 06:36 | clojurebot | true |
| 06:37 | tomoj | I don't like this idea that there's a separate class object which isn't the class itself |
| 06:39 | tomoj | I wonder how clojure gets the class object |
| 06:41 | liwp | what is (cast) good for? |
| 06:42 | tomoj | throwing exceptions I guess |
| 06:42 | liwp | yeah, that's what I think as well... |
| 06:42 | liwp | ,(source cast) |
| 06:42 | clojurebot | java.lang.Exception: Unable to resolve symbol: source in this context |
| 06:43 | liwp | urgh |
| 06:43 | achim | hmm, as far as i know, all classes are Class objects in java, there's not really a distinction. class names evaluate to Class objects in clojure |
| 06:44 | achim | ,(instance? Class Number) |
| 06:44 | clojurebot | true |
| 06:45 | tomoj | right, but class names don't evaluate to class objects in java |
| 06:45 | tomoj | that's what I don't like |
| 06:45 | liwp | tomoj: you don't like that in Java? |
| 06:45 | tomoj | calling a static method should just be calling a method on the class object |
| 06:45 | tomoj | liwp: rubyist.. |
| 06:46 | liwp | tomoj: ahh, got it |
| 06:59 | Chousuke | java has primitives in addition to classes too, which complicates things :/ |
| 07:00 | AWizzArd | Is there something like a lazy slurp in Clojure? |
| 07:00 | AWizzArd | For reading/parsing huge files? |
| 07:00 | Chousuke | well, there's line-seq |
| 07:01 | AWizzArd | but if the line separator is not \n but instead a more complex regex? |
| 07:01 | Chousuke | hmm |
| 07:02 | Chousuke | maybe you'll need your own sequence then :/ |
| 07:02 | AWizzArd | yup, oki |
| 07:30 | cschreiner | Any work done on integrating Clojure with cocoa? |
| 07:30 | cschreiner | and if not, is this interesting? |
| 07:45 | achim | cschreiner: are you thinking about a clojure port or a cocoa bridge? |
| 07:45 | cschreiner | achim: yes |
| 07:45 | cschreiner | both |
| 07:45 | cschreiner | but first, a bridge |
| 07:47 | achim | well, there's rococoa, but no clojure-specific project i know of |
| 07:47 | achim | https://rococoa.dev.java.net/ |
| 07:52 | Fossi | clojures error messages are so not helping if you have an outdated api documentation |
| 07:53 | Fossi | is there an easy way to get a classes' inherited methods? |
| 07:55 | tomoj | I think show from c.c.repl-utils might do what you want |
| 07:57 | tomoj | count is constant time on vectors, right? |
| 07:59 | Fossi | ah, excellent |
| 07:59 | Fossi | i also discovered that reading helps |
| 07:59 | achim | tomoj: yes, constant time for everything "counted?" |
| 08:00 | tomoj | achim: ah, thanks |
| 08:04 | achim | rhickey: the docs of clojure.zip/down promise to return nil if there are no children, but that doesn't seem to be guaranteed, actually |
| 08:05 | achim | ,(-> [1] clojure.zip/vector-zip clojure.zip/down clojure.zip/down) |
| 08:05 | clojurebot | java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer |
| 08:05 | achim | rhickey: may i create issue + patch for this? |
| 08:06 | Chouser | achim: is that the same as http://www.assembla.com/spaces/clojure/tickets/135 |
| 08:08 | achim | Chouser: ah, yes, this patch will fix it |
| 08:09 | Fossi | how do you read a simple string from the repl while running a program? |
| 08:13 | Chouser | achim: is that causing you an actual problem, or is it just a discrepency with the docstring? |
| 08:16 | AWizzArd | For big files (do (def x (lazy-seq (slurp "/big.file"))) (count x)) gives me a stack overflow, while the same thing without lazy-seq doesn't. Can anyone confirm/explain that please? |
| 08:21 | AWizzArd | Instead of confirming this it would also be good to know if it works for you without stack overflows. |
| 08:30 | achim | Chouser: well, it's not something i can't work around, but yes, it would make things simpler if it just returned nil on leaves |
| 08:37 | Chouser | but that patch doesn't return nil, it throws an exception. |
| 08:40 | rhickey | this was discussed here previously |
| 08:42 | Chouser | achim: http://clojure-log.n01se.net/date/2009-06-23.html#16:27b |
| 08:42 | Chouser | there you go. go for it. |
| 08:44 | rhickey | don't neglect: http://clojure-log.n01se.net/date/2009-06-23.html#17:00 |
| 08:45 | rhickey | rhickey: children could check if node is branch and throw if not |
| 08:45 | rhickey | kotarak: rhickey: should it throw or return nil? |
| 08:45 | rhickey | rhickey: throw |
| 08:45 | rhickey | Chouser: thanks for pulling that up so fast! |
| 08:46 | achim | Chouser: thanks! |
| 08:46 | Chouser | the throw is #135 which has a patch. achim's seeing the earlier issue, which the log seems to claim is #134, but that doesn't match. |
| 08:49 | Fossi | a |
| 09:15 | saml | ==> (+ 1 2) |
| 09:15 | saml | !bot |
| 09:16 | Chouser | ,(apply str (reverse "lmas")) |
| 09:16 | clojurebot | "saml" |
| 09:17 | AWizzArd | does anyone else also get an exception for counting the chars in big files that were slurped in a lazy-seq body? See my example above, from one hour ago. |
| 09:17 | saml | ,(apply str (interleave ["nicely, "] ["done"])) |
| 09:17 | clojurebot | "nicely, done" |
| 09:28 | Chouser | ,(class (first (lazy-seq "abc"))) |
| 09:28 | clojurebot | java.lang.Character |
| 09:28 | Chouser | ,(class (second (lazy-seq "abc"))) |
| 09:28 | clojurebot | java.lang.Character |
| 09:28 | Chouser | ,(class (next (lazy-seq "abc"))) |
| 09:28 | clojurebot | clojure.lang.StringSeq |
| 09:30 | Chouser | ,(class (lazy-seq "abc")) |
| 09:30 | clojurebot | clojure.lang.LazySeq |
| 09:30 | Chouser | ,(counted? (lazy-seq "abc")) |
| 09:30 | clojurebot | false |
| 09:31 | Chouser | AWizzArd: there's your problem. LazySeqs and StringSeqs are not counted, so require |
| 09:32 | Chouser | hm |
| 09:33 | liwp | is there a zip function in clojure that produces tuples? |
| 09:34 | liwp | or vectors I guess would be more appropriate |
| 09:34 | Chouser | ,(map vector '(a b c) '(d e f)) |
| 09:34 | clojurebot | ([a d] [b e] [c f]) |
| 09:34 | liwp | ah yes |
| 09:34 | liwp | why didn't i think of that... |
| 09:34 | Chouser | AWizzArd: counting a seq like that will at least be O(n), so you should do that. But I think it ought not overflow the stack. |
| 09:35 | AWizzArd | I am also surprised that it overflows. |
| 09:35 | Chouser | liwp: in clojure, map is _the_ way to walk more than one collection in lockstep. |
| 09:36 | liwp | AWizzArd: I thought that the problem might be holding on to the head of the seq with the def, but again that should cause an OOM error rather than overflow the stack |
| 09:36 | liwp | Chouser: fair enough |
| 09:37 | liwp | Chouser: I quite like the way how you can give map more than one seq to walk, unlike haskell and friends that only do one seq at a time |
| 09:37 | Chouser | liwp: I guess there are others, but it's certainly the one to reach for first. The other is loop/recur and things built on one or the other (zipmap, contrib indexed) |
| 09:37 | lpetit_ | hello |
| 09:38 | liwp | Chouser: I'm just used to looking for zip and couldn't find it so I used map, but didn't think of using vector as the map operation |
| 09:38 | Chouser | lpetit_: g'morning. |
| 09:40 | lpetit_ | brainstorming : is the general problem of coupling STM with a database transaction solved? |
| 09:40 | cemerick | Chouser: any take on this: http://groups.google.com/group/clojure/browse_frm/thread/a0f30c25122cd232 |
| 09:43 | Chouser | ,(count (lazy-seq (apply str (range 1e5)))) |
| 09:43 | clojurebot | java.lang.StackOverflowError |
| 09:44 | cgrand | AWizzArd: looks like a bug StringSeq is counted but doesn't implements count() so ASeq/count() causes the stack overflow |
| 09:45 | cgrand | Chouser: same pb if you use seq instead of lazy-seq |
| 09:45 | AWizzArd | Sounds plausible. |
| 09:45 | Chouser | cemerick: I imagine zip was writen before ::foo worked. |
| 09:46 | rhickey | Chouser: right |
| 09:47 | dmix | does anyone know of any good open source clojure apps with a command-line interface? |
| 09:47 | Chouser | cgrand: yep, you nailed it. anything that implements IndexedSeq should provide a count() method. |
| 09:48 | rhickey | patch welcome |
| 09:48 | cemerick | rhickey: seems like that should get fixed? |
| 09:48 | cemerick | oh, sure :-) |
| 09:48 | cemerick | rhickey: I didn't know if you wanted to keep those slots the way they are for compatibility purposes. |
| 09:49 | rhickey | cemerick: I meant patch welcome for StringSeq, let me look at your thing... |
| 09:50 | cemerick | ah :-) |
| 09:50 | cemerick | it's not a problem really, just a slight inconsistency |
| 09:50 | rhickey | cemerick: so you just want to use ns-ed keywords in zip? |
| 09:50 | cemerick | makes sense to me *shrug* |
| 09:51 | cgrand | rhickey: patch ready for StringSeq, I'm checking all classes implementing Counted |
| 09:51 | cemerick | there is no 'zip' ns, after all |
| 09:51 | rhickey | that's fine by me, definitely predated :: |
| 09:51 | cemerick | OK, I'll set up a ticket and patch |
| 09:52 | AWizzArd | cgrand: very nice, thanks. Good good, another bug eliminated :) |
| 09:53 | Chouser | cgrand: probably in 1.0 as well |
| 10:05 | AWizzArd | regexperts: how can i split a string on a comma when the comma is not between the markers ( and )? Example: "1,2,3,(4,5),6" should result in ["1" "2" "3" "(4,5)" "6"]. |
| 10:06 | Chouser | AWizzArd: need to handle nested parens? |
| 10:06 | AWizzArd | no |
| 10:09 | Chouser | ,(re-seq #"(?:\(.+\)|[^,]+)+" "1,2,3,(4,5),6") |
| 10:09 | clojurebot | ("1" "2" "3" "(4,5)" "6") |
| 10:09 | Chouser | that won't include an empty string if you have ,, in the input |
| 10:10 | AWizzArd | uh, thanks. Funny write-only regex |
| 10:11 | Chouser | ,(re-seq #"\(.+\)|[^,]+" "1,2,3,,(4,5),6") |
| 10:11 | clojurebot | ("1" "2" "3" "(4,5)" "6") |
| 10:11 | Chouser | that's the same, just shorter. |
| 10:11 | Chouser | bah, also broken. |
| 10:11 | Chouser | ,(re-seq #"\(.+\)|[^,]+" "1,(2,3),,(4,5),6") |
| 10:11 | clojurebot | ("1" "(2,3),,(4,5)" "6") |
| 10:12 | Chouser | ,(re-seq #"\(.*?\)|[^,]+" "1,(2,3),,4,(5,6),7,8") |
| 10:12 | clojurebot | ("1" "(2,3)" "4" "(5,6)" "7" "8") |
| 10:12 | Chouser | there |
| 10:12 | AWizzArd | danke |
| 10:12 | durka42 | "\(.*?\)" match anything between two parens, but non-greedily, so you get the shortest match possible instead of the longest. "[^,]+" match a string of things that aren't commas. "|" allow either of them. |
| 10:14 | liwp | ,(re-seq #"\(.*?\)|[^,]+" "1,(2,3),,4,(5,6)foo,7,8") |
| 10:14 | clojurebot | ("1" "(2,3)" "4" "(5,6)" "foo" "7" "8") |
| 10:14 | liwp | is that desired? (see foo) |
| 10:16 | liwp | so the first pattern should probably be something like \(.*?\)[^,]* |
| 10:16 | liwp | ,(re-seq #"\(.*?\)[^,]*|[^,]+" "1,(2,3),,4,(5,6)foo,7,8") |
| 10:16 | clojurebot | ("1" "(2,3)" "4" "(5,6)foo" "7" "8") |
| 10:17 | liwp | ,(re-seq #"\(.*?\)[^,]*|[^,]+" "1,(2,3),,4,bar(5,6)foo,7,8") |
| 10:17 | clojurebot | ("1" "(2,3)" "4" "bar(5" "6)foo" "7" "8") |
| 10:18 | Chouser | ,(re-seq #"(?:\(.*?\)|[^,()]+)+" "1,(2,3),,4,bar(5,6)foo,7,8") |
| 10:18 | clojurebot | ("1" "(2,3)" "4" "bar(5,6)foo" "7" "8") |
| 10:20 | liwp | Chouser: hmph, now I have to try to understand what that actually does ;-) |
| 10:20 | liwp | what's the ?: in the beginning? Something to do with Java's regexp support? |
| 10:20 | Chouser | hehe |
| 10:21 | Chouser | (?: ) is a non-capturing group |
| 10:21 | liwp | ah, ok |
| 10:21 | Chouser | perlism, if I had to guess. |
| 10:21 | liwp | why do you care in this case? or do you? |
| 10:21 | liwp | isn't everything related to regexps a perlism... |
| 10:22 | Chouser | I need to group so that I can say + at the end, that is any number of paren or non-comma-nor-paren sections, alternating 1 or more times |
| 10:22 | liwp | but do you care whether it captures or not? |
| 10:23 | liwp | I mean wouldn't (...) work just as well? |
| 10:23 | Chouser | I need to avoid capture because re-seq will emit seqs instead of strings if there are any captures. |
| 10:23 | liwp | ah, got it |
| 10:23 | Chouser | ,(re-seq #"(.)." "12345") |
| 10:23 | clojurebot | (["12" "1"] ["34" "3"]) |
| 10:23 | Chouser | I mean vectors. :-) |
| 10:23 | liwp | makes sense, thanks |
| 10:24 | liwp | so the regexp mathes everything that is in parens or that is not a comma or a paren |
| 10:24 | liwp | just verbalising it for myself |
| 10:46 | Chouser | (aget #^bytes buffer 0) ; will 0 be unboxed for each call? that is, would (int 0) be any better? |
| 10:48 | Chouser | my guess is that (int 0) would indeed be better. |
| 10:50 | stuartsierra | I thought all Clojure functions receive boxed argument. |
| 10:50 | Chouser | aget is inlineable |
| 10:52 | Chouser | so when called directly (not passed as an arg to something), it acts like a macro, expanding in-place to a java static method call |
| 10:52 | stuartsierra | Then I would assume the arguments to the static method call are boxed. |
| 10:52 | Chouser | in this case (clojure.lang.RT/aget #^bytes buffer 0) |
| 10:53 | Chouser | the aget method has several overloads, all of which take a primitive int as the second arg |
| 10:54 | Chouser | so that int must be unboxed before being passed to the java method. My question is whether 0 gets unboxed once at compile time, or once per call at runtime. |
| 10:59 | liwp | Chouser: IIRC people have been reporting that they get better performance with (int i) in agets |
| 11:00 | liwp | e.g. http://groups.google.co.uk/group/clojure/msg/59161c122a29233e?hl=en |
| 11:00 | danlarkin | I seem to remember a while ago there was talk of an abstract representation of a queue, with a producer & consumer, does anyone remember/know what became of that? |
| 11:03 | Chouser | liwp: ah, very good. thanks. |
| 11:07 | liwp | Chouser: there was some blog post which was a bit more informative (can't find it now), but in any case it seems that coercing indices when dealing with arrays is a good thing at the moment |
| 12:39 | liwp | ping |
| 12:39 | liwp | ~ping |
| 12:39 | clojurebot | PONG! |
| 12:49 | liwp | mock objects |
| 12:49 | liwp | piffle |
| 12:49 | liwp | ~mock objects |
| 12:49 | clojurebot | Your mock object is a joke; that object is mocking you. For needing it. -- rhickey |
| 12:49 | liwp | maybe expect should not be renamed mock after all ;-) |
| 12:50 | rhickey | Is that name under consideration? - ick |
| 12:50 | liwp | I think Stu renamed it already in contrib |
| 12:51 | cemerick | har har |
| 12:51 | cemerick | rhickey: when did you throw off that gem? |
| 12:52 | rhickey | cemerick: I don't recall - at a talk a while ago |
| 12:52 | cemerick | I've never gotten into the deep waters of testing. Seems like a *lot* of work. |
| 13:54 | maacl_ | Does anyone have example code that uses clojure-couchdb ? |
| 14:15 | wtetzner_ | if i want to use clojure code the way you would use json, can i just use the (print ...) function, or do i need to use some special printer to ensure i can read it back in? |
| 14:16 | Chousuke | I think you need to use pr |
| 14:16 | Chousuke | (doc pr) |
| 14:16 | clojurebot | "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader" |
| 14:17 | wtetzner_ | ok |
| 14:17 | wtetzner_ | thanks |
| 14:17 | wtetzner_ | (doc prn) |
| 14:17 | clojurebot | "([& more]); Same as pr followed by (newline). Observes *flush-on-newline*" |
| 14:27 | wtetzner_ | (doc pr-str) |
| 14:27 | clojurebot | "([& xs]); pr to a string, returning it" |
| 14:30 | wtetzner_ | being able to print and read clojure data structures is really nice |
| 14:30 | rathore_ | do you guys think its OK to send a clojure job posting on the google-mailing-list? |
| 14:30 | wtetzner_ | it's perfect for use as a data format in a client-server application |
| 14:32 | rathore_ | wtetzner_: i use exactly that in swarmiji - to send job information back and forth between requesters & workers |
| 14:32 | rathore_ | ,(doc pr-str) |
| 14:32 | clojurebot | "([& xs]); pr to a string, returning it" |
| 14:41 | Chouser | rathore_: there has been one or two before. I would guess it's ok. |
| 14:44 | rhickey | rathore: yes, fine by me |
| 14:46 | cemerick | heh, I didn't notice the prior job postings. Good to see :-) |
| 14:52 | rathore_ | rhickey: thanks |
| 14:56 | rhickey | rathore_: sure, glad to see it! |
| 15:27 | cemerick | are there any recommended idioms for implicit bindings established by macros? |
| 15:28 | Chousuke | other than "don't" and "document"? :P |
| 15:28 | cemerick | heh |
| 15:28 | cemerick | Chousuke: I just knew that was going to be the response. :-D |
| 15:30 | Chousuke | I'm not aware of any idioms |
| 15:30 | Chouser | do you mean dynamic bindings, like the with-* macros? |
| 15:32 | cemerick | no, implicit bindings, like 'this' in proxy method impls. |
| 16:13 | jensli | I had a job writing C# for a big, evil corporation. Now that has ended and I have placed an order for "Programming Clojure", Im going to spend my time hanging in cafes with my laptop, learning to lisp functionlly. |
| 16:15 | arbscht | good luck. perhaps you can contribute to the clojure-clr project, too :) |
| 16:19 | jensli | Im going to keep far away from clr. |
| 16:25 | Chouser | ha! delaying the middle of each finger tree also removes the threat of stack overflow. |
| 16:33 | wavister | ... so if you want to give someone the middle finger, it might take a while? |
| 18:13 | hiredman | http://www.thelastcitadel.com/images/clojurebot.png |
| 18:15 | wavister | not sure why i'm looking at your inbox... |
| 18:15 | danlarkin | it's a _wave_ |
| 18:15 | durka42 | lower right corner |
| 18:16 | danlarkin | maybe? |
| 18:16 | danlarkin | no |
| 18:16 | danlarkin | nevermind |
| 18:16 | wavister | ... xmpp transport from wave to the irc clojurebot? |
| 18:16 | danlarkin | I redact my wave comment |
| 18:20 | hiredman | no |
| 18:20 | hiredman | just clojurebot via xmpp |
| 18:22 | wavister | spiffin! |
| 18:25 | wavister | why is this so: |
| 18:25 | wavister | ,(= (long 1) 1) |
| 18:25 | clojurebot | true |
| 18:25 | wavister | ,(clojure.set/union #{(long 1)} #{1}) |
| 18:25 | clojurebot | #{1 1} |
| 18:26 | rhickey | ,(.equals (long 1) 1) |
| 18:26 | clojurebot | false |
| 18:26 | wavister | ack. is there a way to do sets using = instead of .equals? |
| 18:26 | rhickey | in order for Clojure sets to be java.util.Sets, they need to use .equals |
| 18:26 | wavister | oh |
| 18:59 | tomoj | huh? |
| 18:59 | tomoj | I don't get it |
| 18:59 | tomoj | ,(= #{1 2 3} #{3 2 1}) |
| 18:59 | clojurebot | true |
| 18:59 | tomoj | oh, you mean the elements I guess |
| 19:16 | wtetzner_ | so is java.util.Set an interface? |
| 19:17 | hiredman | ~jdoc java.util.Set |
| 19:22 | wavister | hiredman: can I add clojurebot to my friends list? |
| 19:23 | hiredman | clojurebot@thelastcitadel.com |
| 19:23 | wavister | spiff |
| 20:23 | Chouser | why people think it would be better to allow similar out-of-order definitions in .clj files is beyond me. |
| 20:29 | krumholt__ | i would like that :) |
| 20:31 | krumholt__ | i program a function than i think of some helper function i might need and then i have to write that function above the the one i am writing. i like to order my code so that i see the main functions first and can read up on the helper function when i need to |
| 20:33 | wavister | i've thought about that... you'd have to have a future pointing to a perhaps never defined function in the ns, and in parallel def your functions later to fulfill that future |
| 20:35 | krumholt__ | wavister, load-file could just order the functions before evaluating them? |
| 20:35 | cemerick | Chouser: is the haskell just masochism or something justifiable? ;-) |
| 20:35 | Chouser | it's solvable technically, but you'll end up with big ol' jumble |
| 20:35 | wavister | what if there was a with-futures function similar to the with-local-vars, which just took a list of symbols to define within the clojure |
| 20:35 | clojurebot | function is <Chouser> there is one class per fn, one instance of it per closure |
| 20:36 | Chouser | wavister: 'declare'? |
| 20:36 | wavister | in with-futures, each line would be evaluated in parallel rather than sequentially |
| 20:36 | Chouser | cemerick: trying to understand the finger-tree paper. |
| 20:37 | cemerick | ah |
| 20:37 | cemerick | I can read ML and its kin, but haskell is just unintelligible to me. |
| 20:37 | wavister | Chouser: i haven't messed with declare. maybe... |
| 20:43 | cemerick | whoa, I just typed 'disclosure' as 'disclojure' |
| 20:45 | wavister | muahaha |
| 23:37 | technomancy` | I've got a macro that generates a proxy form, but it's complaining "Caused by: java.lang.Exception: No such var: sketchbook.applet/this" when I try to bind this |
| 23:37 | technomancy` | http://p.hagelb.org/applet.clj.html |
| 23:38 | technomancy` | what's the trick to writing a macro that can do that? |
| 23:43 | technomancy` | hmm... (declare this) fixes it... but now I get an error running the macro even though running the macroexpansion works fine. I didn't think that was possible. |
| 23:44 | technomancy` | "Can't refer to qualified var that doesn't exist" when I try to run the macro. =\ |
| 23:45 | cark | did you try ~'this ? |
| 23:45 | cark | in the macro definition |
| 23:46 | technomancy` | cark: that solves the first problem; thanks |
| 23:46 | technomancy` | I think the second problem is due to the fact that my macro first defs a var and then tries to refer to the var in a defn inside the same macro |
| 23:47 | technomancy` | on second thought I don't really need the second defn to be inside the macro. |
| 23:47 | cark | i'm not sure you're right |
| 23:48 | cark | mhh |
| 23:50 | cark | the macro produces the code, then the defs are avaluated in order |
| 23:51 | cark | so that's exactly the same as having the macroexpansion in your source file |
| 23:52 | technomancy` | that's what I thought except... well... it's not the same. |
| 23:52 | cark | did you try evaluating the macro-expansion ? |
| 23:53 | technomancy` | cark: that's what I mean, the macro-expansion works |
| 23:54 | cark | mhh i would call this a bug then ... though that seems hardly possible on such common stuff |
| 23:56 | technomancy` | actually my alternate approach breaks since proxies can't have metadata. boo. |
| 23:56 | hiredman | uh |
| 23:56 | hiredman | if they proxy IMeta |
| 23:56 | hiredman | … |
| 23:57 | technomancy` | hiredman: oh, doh. |
| 23:57 | technomancy` | good call |
| 23:57 | cark | ~paste? |
| 23:57 | clojurebot | lisppaste8, url |
| 23:57 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 23:58 | lisppaste8 | cark pasted "well that works" at http://paste.lisp.org/display/86170 |