2009-03-07
| 00:37 | cmvkk | well if we're going to use weird characters, I think we should use the snowman. |
| 00:37 | abrooks | I say that as a member of the querty/English crowd... |
| 00:37 | abrooks | cmvkk: Oh, of course.. how could I have overlooked that. http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/;-) |
| 00:38 | abrooks | Ooops... |
| 00:38 | abrooks | cmvkk: Oh, of course.. how could I have overlooked that. /;-) |
| 00:38 | cmvkk | heh, i was hoping there was somehow a snowman i missed in that monad tutorial. |
| 00:38 | abrooks | I just need to figure out the compose key for "snowman" |
| 00:39 | abrooks | The X11 compose/multi-key is a great mechanism for accessing non-primary symbols. |
| 00:40 | abrooks | (...map... foo bar) |
| 00:40 | abrooks | Actually, I liked the =map= and =filter= myself. |
| 00:42 | abrooks | Look, if non-ascii was good enough for APL it's good enough for Clojure. ;-D |
| 00:43 | cmvkk | i think we should utilize the wide range of unicode available, and make it so that every core function is only one character long. |
| 00:44 | cmvkk | you could accomplish that with chinese characters alone! |
| 00:52 | abrooks | cmvkk: In my own code I've found it nice to use unicode symbols in Clojure (mostly Project Euler) but I think it's the right decision to keep the core language free of unicode. |
| 00:53 | abrooks | cmvkk: I know you were having fun. :) |
| 00:54 | cmvkk | of course...but i do welcome a day when unicode input is so easy that keeping non-ascii characters out of a language isn't necessary anymore |
| 00:57 | durka42 | is c.c.monads broken? |
| 01:02 | durka42 | m-lift doesn't seem to work because m-bind is nowhere to be found |
| 01:02 | durka42 | ,(use 'clojure.contrib.monads) |
| 01:02 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/monads__init.class or clojure/contrib/monads.clj on classpath: |
| 01:12 | durka42 | never mind |
| 01:35 | Raynes- | durka42: You are broken :> |
| 01:45 | replaca | Q: so, I'm updated to the lazy stuff and lazy-cons seems to be gone, but cons isn't really lazy |
| 01:45 | replaca | what's the right stategy? |
| 01:46 | replaca | *strategy |
| 01:49 | cmvkk | lazy-seq? |
| 01:49 | replaca | ahh, ok. |
| 01:50 | replaca | is there a doc that outlines the effect of the changes (or a google message)? |
| 01:50 | replaca | I wasn't paying very close attention when all that happened |
| 01:50 | cmvkk | http://clojure.org/lazy is i think the correct one |
| 01:51 | replaca | RTFM, Tom :-) |
| 01:51 | replaca | thanks, cmvkk! |
| 01:51 | cmvkk | actually, i'm not sure how you even access that page from anywhere. |
| 01:52 | brennanc | http://paste.lisp.org/display/76606 |
| 01:52 | replaca | yoou mean, besides getting someone to post a link in IRC? :-) |
| 01:52 | cmvkk | that's where I got it from... |
| 01:53 | brennanc | can someone explain this? It's from the Programming Clojure book. I don't understand what is getting passed to map and how it is even valid. |
| 01:53 | brennanc | pt is something like [5 10] |
| 01:53 | replaca | we're all part of a secret society! |
| 01:53 | cmvkk | the list being passed in is [(pt 0) (pt 1) 1 1] it seems |
| 01:53 | brennanc | ([5 10] 0) is not a valid expression though |
| 01:53 | cmvkk | and the fn is #(* point-size %) which is just (fn [x] (* point-size x)) |
| 01:53 | cmvkk | hmm |
| 01:54 | brennanc | (* point-size [5 10] 0) makes no sense to me |
| 01:54 | cmvkk | wait, what does (pt 0) return? |
| 01:54 | brennanc | pt is not a function operand so I don't get how it is even valid |
| 01:55 | brennanc | pt is passed as [5 10] in the example |
| 01:55 | cmvkk | ohhh! |
| 01:55 | replaca | brennanc: ,([5 10] 0) |
| 01:55 | replaca | ,([5 10] 0) |
| 01:55 | clojurebot | 5 |
| 01:55 | cmvkk | yeah, vectors are functions of their indexes. |
| 01:56 | replaca | I didn't know that, but guessed from context |
| 01:56 | brennanc | ahhh |
| 01:56 | replaca | pretty cool |
| 01:56 | brennanc | I never would have guessed that one, but it makes perfect sense now |
| 01:56 | replaca | brennanc: this is where the REPL helps: if it doesn't seem right just type it in and see what happens :-) |
| 02:11 | Raynes- | When a function is screwing up, I always break it down and evaluate every piece in the REPL. <3 REPLs. |
| 02:12 | brennanc | yeah, I got the result and knew it worked, just didn't understand how it was valid :) |
| 02:13 | brennanc | or what the logic was behind it |
| 02:13 | brennanc | cmvkk's explanation cleared it up instantly |
| 02:16 | Raynes | brennanc: In case you didn't know it, maps are the same way. |
| 02:17 | brennanc | yup, thanks |
| 02:17 | Raynes | ,({:akey "This is a value." :anotherkey "This is another value."} :akey) |
| 02:17 | clojurebot | "This is a value." |
| 02:17 | Raynes | That's always fun. |
| 02:17 | brennanc | anything else it works with? |
| 02:18 | Raynes | I don't think so. |
| 02:18 | brennanc | k |
| 02:20 | hiredman | ,(:key {:key 1 :a 2}) |
| 02:20 | clojurebot | 1 |
| 02:20 | brennanc | ok, got a bunch of questions about this one |
| 02:20 | brennanc | (defn move [{:keys [body dir] :as snake} & grow] |
| 02:20 | hiredman | ,('a {'a 1 'b 2}) |
| 02:20 | clojurebot | 1 |
| 02:20 | hiredman | that is hash destructuring |
| 02:21 | hiredman | which you kind find out about on the special forms page on the website under let |
| 02:21 | brennanc | where would I find docs for that? |
| 02:21 | hiredman | clojurebot: destructuring? |
| 02:21 | clojurebot | destructuring is http://clojure.org/special_forms#let |
| 02:21 | brennanc | thanks, will read |
| 02:22 | hiredman | that fuction takes a hash {:body _ :dir _} |
| 02:23 | hiredman | body is bound to (:body hash) and dir likewise, those whole hash is bound to snake |
| 02:23 | hiredman | then it takes a variable number of other arguments that are availble in a sequence bound to grow |
| 02:25 | brennanc | the & var-name is another way of saying it is optional, right? |
| 02:27 | hiredman | that and it binds to a sequence |
| 02:28 | hiredman | ,((fn [ & x ] x) 1 2 3 4) |
| 02:28 | clojurebot | (1 2 3 4) |
| 02:28 | brennanc | ,((fn [& x] x) ) |
| 02:28 | clojurebot | nil |
| 02:29 | brennanc | ,((fn [& x] x) (list)) |
| 02:29 | clojurebot | (()) |
| 02:33 | replaca | I was using nil? alot in loops to check for the empty list! :-( |
| 02:34 | brennanc | ,(identical nil ()) |
| 02:34 | clojurebot | java.lang.Exception: Unable to resolve symbol: identical in this context |
| 02:34 | brennanc | ,(identical? nil ()) |
| 02:34 | clojurebot | false |
| 02:35 | replaca | yeah, nil? foo used to work when you ran off the end of a list, but not anymore! |
| 02:35 | replaca | and the result tends to be an infinite loop/recur |
| 02:35 | hiredman | well, it still does if you (seq ...) the list |
| 02:35 | hiredman | ,(doc next) |
| 02:36 | clojurebot | "([coll]); Returns a seq of the items after the first. Calls seq on its argument. If there are no more items, returns nil." |
| 02:36 | replaca | or you can just use empty? |
| 02:36 | hiredman | :( |
| 02:36 | replaca | not good? |
| 02:37 | hiredman | asthetically unpleasing |
| 02:38 | replaca | hmm, to check the end of the list? I don't get it |
| 02:38 | brennanc | the sequence video talks about it towards the end |
| 02:38 | brennanc | ISeq interfaces will return nil if you try to get another element an there is nothing there |
| 02:39 | hiredman | erm |
| 02:39 | brennanc | ...hopefully I remembered that correctly or am saying it right |
| 02:39 | hiredman | things have changed |
| 02:39 | brennanc | lol |
| 02:39 | replaca | that went out with laziness |
| 02:39 | brennanc | yet another inconsistency |
| 02:39 | replaca | that's what was breaking in my code |
| 02:39 | hiredman | it used to be impossible to have empty sequences, if you tried you just got nil |
| 02:40 | hiredman | now it is possible |
| 02:40 | brennanc | ,(rest []) |
| 02:40 | clojurebot | () |
| 02:40 | brennanc | it used to return nil |
| 02:40 | cmvkk | ergh. |
| 02:41 | replaca | hiredman: are you suggesting that I should use next instead of rest? |
| 02:41 | cmvkk | so i have these two functions i have to call hundreds of thousands of times in a row, and they both are exactly the same but for a caching system. |
| 02:41 | hiredman | that is one way t ogo |
| 02:41 | hiredman | if you don't need full laziness |
| 02:41 | cmvkk | one uses a ref with a vector and assoc to create a ring buffer. the other stores only the immediately previous value and its number as an atom, in a vector of size 2. |
| 02:42 | replaca | hiredman: but empty? is bad? that still confuses me |
| 02:42 | hiredman | not bad |
| 02:42 | cmvkk | so the first one updates two refs and uses assoc, and the second one updates one atom and replaces the vector inside entirely. |
| 02:42 | cmvkk | but the ref one is FIVE TIMES FASTER than the atom one. |
| 02:42 | cmvkk | atoms are supposed to have less overhead than refs! |
| 02:42 | hiredman | for low contention |
| 02:42 | hiredman | (I believe) |
| 02:43 | hiredman | if you program does nothing but hit the atom a ref will perform better |
| 02:44 | cmvkk | well it grabs the previous value, does some unchecked math against it and different value, then stores the resultant value where the previous value used to be. |
| 02:44 | hiredman | actually, I should say, I don't know that for a fact |
| 02:44 | brennanc | what's the point of atoms? why can't you just call def again if you want to set it to something else? |
| 02:44 | hiredman | ick |
| 02:44 | hiredman | brennanc: def once |
| 02:44 | hiredman | and never again |
| 02:44 | cmvkk | because it might be concurrent later. |
| 02:45 | brennanc | cmvkk: what do you mean by that? |
| 02:45 | hiredman | you should only ever re-def stuff in the repl |
| 02:45 | cmvkk | re-deffing is not thread safe....is it? i don't think it is? |
| 02:45 | hiredman | and def only operates in the global space |
| 02:45 | Chouser | atoms make sure you're transitioning in a consistent way |
| 02:46 | Chouser | no read-calc-write race condition errors with atom and 'swap!' |
| 02:46 | cmvkk | in any case, i tried making a version that used two refs and did the same things as the atoms, and it was slower than the atom version. |
| 02:46 | cmvkk | so i have no idea what it is about the ring buffer version that's so much faster. |
| 02:46 | hiredman | ,(let [a (atom 0)] (swap! a inc) @a) |
| 02:46 | clojurebot | 1 |
| 02:47 | cmvkk | it's actually only a small part of the program, but it slows the thing down from 22 seconds to 97 seconds. |
| 02:48 | Chouser | re-deffing is atomic -- you're not going to end up in some broken state. but (def foo (inc foo)) has a race |
| 02:50 | brennanc | so an atom will wait until other transactions are done before it will set its value? |
| 02:51 | hiredman | functional programming is a thing of elegence and beauty, re-defing is like using a non-synthetic motor oil |
| 02:51 | hiredman | atoms set their value atomically |
| 02:51 | hiredman | compare and swap |
| 02:53 | Chouser | atoms don't cooperate with transactions. 'swap!' has a side-effect. |
| 02:54 | cmvkk | it would be nice if atoms could synchronize somehow |
| 02:54 | Chouser | then they'd be a ref. :-) |
| 02:54 | hiredman | word |
| 02:55 | cmvkk | well i'm changing the value of two different numbers, and i want to do it atomically. Should I just use two refs instead of an atom with a size-2 vector? |
| 02:55 | cmvkk | which would be faster? |
| 02:55 | hiredman | sounds like time for a profiler |
| 02:56 | cmvkk | well i'm using a 'time' thing. but like i said: refs with a ring buffer = 22 seconds, one atom with a size-2 vector = 97 seconds. |
| 02:56 | cmvkk | something seems awfully off about that. |
| 02:56 | Chouser | you've got *warn-on-reflection* on? |
| 02:57 | cmvkk | nope, let's try that. |
| 02:58 | cmvkk | haha, thanks Chouser. |
| 02:59 | Chouser | reflection hurts, eh? |
| 02:59 | cmvkk | the difference between the two fns: on the atom one, i wasn't wrapping the result of the atom deref in (int ...) |
| 02:59 | cmvkk | so unchecked-add and unchecked-divide couldn't resolve. |
| 03:01 | cmvkk | this renderer is still quite a bit slower than real time, which is disappointing, but at least it's getting there... |
| 03:01 | cmvkk | I can do 8 seconds of music in 20 seconds now. |
| 03:03 | Chouser | reflection is most punishing, but boxing and unboxing are a next. |
| 03:03 | Chouser | You're sure you're not doing either more than necessary? |
| 03:03 | Chouser | that's a somewhat tougher question to answer in my experience. |
| 03:03 | cmvkk | I have no idea. well reflection is okay. the only things left that warn about that are the parts that actually write data out to file. |
| 03:03 | cmvkk | and i know that's not the bottleneck. |
| 03:04 | Chouser | ok, that's good. |
| 03:04 | cmvkk | the way the system is designed makes it hard, i think, to make sure things are going through correctly. |
| 03:04 | cmvkk | it uses lots of functions that take closure arguments and return new closures that call the argument closures, etc |
| 03:05 | cmvkk | ints are 'supposed' to be returned a lot, but who knows. |
| 03:05 | Chouser | every clojure functions takes and returns only boxed numbers, never primitives. |
| 03:05 | cmvkk | fns never return primitives? |
| 03:05 | Chouser | right |
| 03:05 | Chouser | always Objects |
| 03:06 | cmvkk | so what DOES return primitives? just (int ...) and all those unchecked-math functions? |
| 03:06 | Chouser | in a few limited circumstances you can use a macro or better definline to factor out common code without losing primites. |
| 03:07 | Chouser | only locals and java interop can use primitives. |
| 03:07 | cmvkk | :( do you think this has a chance of changing ever? |
| 03:07 | Chouser | as soon as the JVM gets tagged numbers, which apparently won't be very soon at all. |
| 03:08 | brennanc | how popular is clojure? any companies using it yet? |
| 03:08 | cmvkk | if you call (int ...) on something that's already an int, that's not a performance hit is it? |
| 03:09 | hiredman | rich has mentioned a special function interface for return various primitives numbers |
| 03:09 | Chouser | brennanc: some companies are using it, yes. |
| 03:09 | Chouser | I was asked about it in job interview the other day. |
| 03:10 | brennanc | that's cool. my boss is a developer and thinks PHP is the best language ever. lol |
| 03:10 | Chouser | I really shouldn't be up. good night, all. |
| 03:11 | albino | heh, go php |
| 03:11 | brennanc | I'm getting sick of writing (for $i=0; $i<$something; $++) |
| 03:11 | hiredman | :( |
| 03:12 | hiredman | I started looking at some kind of "write something like clojure, compile to php" scheme |
| 03:12 | brennanc | or having to store expressions into temp variables that only get used once because it won't let put an expression in certain forms |
| 03:13 | brennanc | hiredman: so it takes a list and outputs php code? |
| 03:14 | hiredman | more or less |
| 03:14 | Chouser | brennanc: http://groups.google.com/group/clojure/msg/1d215a79a697a68a |
| 03:14 | hiredman | I have been ignoring php for a while, but when I have to deal with it again, I may start it again |
| 03:15 | hiredman | my current idea is clojure->json->interpreter written in php that "executes" json |
| 03:16 | hiredman | that way I would not have to write a parser |
| 03:16 | brennanc | I wrote some small code that is a forth like interpreter and ported it to PHP, javascript, and actionscript |
| 03:16 | brennanc | not a whole lot of api in it but got the parsing done and everything |
| 03:17 | hiredman | then you should write the clojure->php bridge |
| 03:17 | hiredman | :) |
| 03:17 | brennanc | I'd be tempted with what I have to deal with at work. :) |
| 03:18 | brennanc | only been learning clojure for about a week now. have to give it at least another week. ;) |
| 03:19 | hiredman | but it would help you learn, ask Chouser. |
| 03:21 | replaca | goodnight all! Happy late-night clojuring |
| 05:57 | Lau_of_DK | Hey guys |
| 05:58 | hoeck | hey lau |
| 05:58 | kotarak | Ol�, Se�or Lau. |
| 05:59 | Lau_of_DK | Assume I have a datastructure like ({:alpha 1 :beta 2 :gamma 3} {:alpha 4 :beta 5 :gamma 6}) and I want to export that to CSV: 1,2,3,4,5,6 in that order - is there an elegant way to accomplish that? |
| 05:59 | Lau_of_DK | Ola mon Kota |
| 05:59 | Lau_of_DK | Und mein The Hoeck :) |
| 06:00 | hiredman | mapcat vals |
| 06:00 | kotarak | ,(apply str (interpose "," (map val (concat {:alpha 1 :beta 2 :gamma 3} {:alpha 4 :beta 5 :gamma 6})))) |
| 06:00 | clojurebot | "1,2,3,4,5,6" |
| 06:02 | Lau_of_DK | ,(apply str (interpose "," (map val (concat {:zeta 1 :beta 2 :gamma |
| 06:02 | Lau_of_DK | 3} {:zeta 4 :beta 5 :gamma 6})))) |
| 06:02 | clojurebot | EOF while reading |
| 06:02 | Lau_of_DK | ,(apply str (interpose "," (map val (concat {:zeta 1 :beta 2 :gamma |
| 06:02 | Lau_of_DK | 3} {:zeta 4 :beta 5 :gamma 6})))) |
| 06:02 | clojurebot | EOF while reading |
| 06:02 | Lau_of_DK | Hmm, why the bork ? |
| 06:03 | Lau_of_DK | What Im trying to say is, that it works by the assumption that your keys are alphabetically stored, mine aren't |
| 06:03 | hiredman | (comp sort mapcat) |
| 06:03 | kotarak | ,(apply str (interpose "," (mapcat vals (list {:alpha 1 :beta 2 :gamma 3} {:alpha 4 :beta 5 :gamma 6})))) |
| 06:03 | clojurebot | "1,2,3,4,5,6" |
| 06:04 | kotarak | sorted-map? |
| 06:04 | Lau_of_DK | Funny, on my rev it gives "3,1,2,6,4,5" |
| 06:05 | kotarak | There was a change in size when array-map is used by {}, I think. |
| 06:05 | Lau_of_DK | that might be it - anyway, Im inspired, thanks |
| 06:36 | cgrand | ,(apply str (interpose "," (mapcat #(map % [:alpha :beta :gamma]) (list {:alpha 1 :beta 2 :gamma 3} {:alpha 4 :beta 5 :gamma 6})))) |
| 06:36 | clojurebot | "1,2,3,4,5,6" |
| 07:57 | Lau_of_DK | Thanks alot cgrand |
| 10:21 | RadioApeShot | Is there a predicate which returns true for anything which produces a seq when passed to the seq function? |
| 10:21 | kotarak | coll? might be a first guess. |
| 10:22 | RadioApeShot | Ah |
| 10:22 | RadioApeShot | I was using col? |
| 10:22 | RadioApeShot | That is just what I want |
| 10:22 | RadioApeShot | Thanks |
| 10:22 | kotarak | #(or (coll? %) (seq? %)) |
| 12:46 | blbrown | anybody there |
| 12:47 | kotarak | yup |
| 12:47 | durka42 | indeed |
| 12:47 | durka42 | nifty bus wi-fi |
| 12:48 | hipertracker | Do Clojure have named parameters? |
| 12:48 | blbrown | I forgot how to do this. if I have ... (let [l some-list] (some-func (fn [line] (append to list)) ... a list and then some func appends to the list. How would I append to the list. Is it just append |
| 12:48 | cmvkk | conj? |
| 12:49 | durka42 | hipertracker: yes, all parameters are named, except in anonymous lambda fns #( ... ) |
| 12:49 | cmvkk | ,(conj '(1 2 3) 4) |
| 12:49 | clojurebot | (4 1 2 3) |
| 12:49 | cmvkk | eh... |
| 12:49 | blbrown | hmm |
| 12:49 | cmvkk | ,(conj [1 2 3] 4) |
| 12:49 | clojurebot | [1 2 3 4] |
| 12:50 | kotarak | ,(concat (list 1 2 3) (list 4)) |
| 12:50 | clojurebot | (1 2 3 4) |
| 12:50 | kotarak | The use of a vector with conj is probably what you want. |
| 12:51 | cmvkk | there's not a better way to append to a list than concat and wrapping the second argument in a list, I guess. |
| 12:52 | kotarak | I'm not aware of another way. If one needs to append, one should use a vector. If one needs easy adding at the end and simple retrieval at the front, one can use a PersistentQueue. |
| 13:00 | rlb | What position (if any) does clojure take wrt exceptions? For example, is it normal for clojure functions (built-in ones in particular) to throw exceptions? |
| 13:02 | durka42 | exceptions are used kind of in the same way as java would |
| 13:02 | durka42 | ,(distinct?) |
| 13:02 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args passed to: core$distinct-QMARK- |
| 13:02 | durka42 | ,(let [1 "one"] (prn "bad")) |
| 13:02 | clojurebot | java.lang.Exception: Unsupported binding form: 1 |
| 13:03 | rlb | OK, in part, I just wanted to make sure I understood how defensive you need to be in cases where it might matter. Thanks. |
| 13:03 | durka42 | there is also chouser's error-kit in contrib |
| 13:03 | rlb | Also, am I right in assuming that if you want your own type of exception, you would probably created it via gen-class, or is there some better way? |
| 13:04 | durka42 | if you want it to have a distinct type that you can specify in a catch, then you have to gen-class it |
| 13:04 | rlb | OK, thanks. |
| 13:18 | lisppaste8 | blbrown pasted "Mutate the vector" at http://paste.lisp.org/display/76622 |
| 13:19 | cmvkk | if you want to mutate the vector |
| 13:19 | blbrown | I am assuming I need 'ref' I did this before but forgot the syntax. Is that the way to go |
| 13:19 | cmvkk | instead of [] use (atom []), and then instead of (conj vec-line ...) do (swap! vec-line conj ...) |
| 13:20 | cmvkk | you could use a ref too. but you're only working with one thing so either is okay. |
| 13:20 | blbrown | OK |
| 13:20 | cmvkk | oh and you have to use @vec-line to read it. |
| 13:21 | blbrown | I am using opennlp, pretty cool library and works flawlessly |
| 13:22 | cmvkk | what exactly is happening in that example, are you just looping through input, building that vec, then returning it? |
| 13:22 | cmvkk | because there's probably a way to do that without mutation... |
| 13:23 | blbrown | pretty much |
| 13:23 | cmvkk | you might be better off with loop/recur for rebinding then, rather than mutation. But it's hard to tell from this viewpoint whether that would make simpler syntax. |
| 13:24 | blbrown | maybe not even 'loop' but 'foreach' or whatever the call was |
| 13:24 | cmvkk | oh, yeah, for. |
| 13:24 | cmvkk | that's true too. |
| 13:24 | blbrown | I still have a Java/imperative programming style.. I will get there eventually |
| 13:25 | cmvkk | clojure is a good language for learning to code this way, because at least it makes you realize you're using mutation when you do. |
| 13:26 | blbrown | yea, it is pretty obvious isn't it |
| 13:26 | blbrown | isnt like a = 3 , b = 4, a =3 in the imperative world |
| 13:31 | zakwilson | In Haskell, it's even more obvious. The mutation shows up in the type signature. |
| 13:32 | zakwilson | You *can* hide mutations in Clojure if you try. In Haskell, I'm pretty sure you can't. |
| 13:32 | cmvkk | i thought there wasn't mutation at all in haskell. |
| 13:32 | blbrown | and Erlang pretty much has no mutations |
| 13:32 | zakwilson | There's the State monad. |
| 13:32 | cmvkk | oh okay. |
| 13:33 | blbrown | zakwilson, I am assuming you worked with Haskell, it is certainly a different style from clojure. Do you like both haskell and clojure and is there one language you would use for X task and one for another |
| 13:33 | zakwilson | I have barely touched Haskell, but it really interests me. |
| 13:34 | zakwilson | From what I know of Haskell, Clojure is better for getting things done quickly, but Haskell is better for knowing things about a program's correctness. |
| 13:34 | ayrnieu | correctness with respect to types. |
| 13:35 | zakwilson | Yes, but but things have types in Haskell that don't really in other languages. |
| 13:35 | zakwilson | An IO action, for examlpe, shows up in the type signature of a function that uses it. |
| 13:36 | blbrown | zakwilson, good description |
| 13:36 | ayrnieu | does that seem like a good example of something you'd want to check for the sake of a correct program? |
| 13:37 | blbrown | I think there is a world for clojure, haskell, scala |
| 13:37 | blbrown | s/world/architecture/g |
| 13:37 | zakwilson | In a formal sense, you could test that other ways if you're trying to prove a program correct. |
| 13:38 | zakwilson | In a real-world sense, I think it might reduce a programmer's error rate, but I haven't written anything non-trivial in Haskell, so I can't be sure about that. |
| 13:39 | rlb | Does clojure have a clever way to define a function that has only one optional argument, and where providing additional arguments is treated as an error? I know I can just check the rest list... |
| 13:39 | ayrnieu | rlb - define a multi-arity function. |
| 13:39 | blbrown | a good test framework is where you can prove correctness in a dynamic clojure world. But that takes a little extra effort, where I guess in haskell can be a little bit more automatic |
| 13:39 | hiredman | ~def max |
| 13:39 | rlb | ayrnieu: I saw that. |
| 13:40 | ayrnieu | (defn foo ([x] ...) ([x y] ...)) -- the lesser-arity function can supply the default value in a 'recursive' call to the greater-arity function. |
| 13:40 | zakwilson | blbrown: I think it's just a matter of where the effort goes. In Haskell, it's up front, when you're writing the program. |
| 13:40 | ayrnieu | zakwilson - correctness with types is 'up front', and continuous. |
| 13:40 | rlb | ayrnieu: ahh, I hadn't realized that the bindings allow them to call each other -- perfect. |
| 13:40 | rlb | (and quite nice) |
| 13:41 | zakwilson | ayrnieu: Yes. What I'm saying is that in Haskell, you have to spend more effort when you write the code, whereas with Clojure, the effort is moved to testing. |
| 13:41 | blbrown | and lets not leave scala out. If you are working with the jvm, I could see writing an architecture around clojure and scala. For example, I could see a web framework with clojure from fron end web application code and scala for database backend and server code |
| 13:42 | ayrnieu | zakwilson - you'll find that Haskell's type checking will be very useful indeed in Haskell, a language so opaque and horrible that you can hardly trust yourself to follow what your own idiomatically golfed code is doing. But to see how useful it is in general, just look at what you've been doing. |
| 13:43 | digash | blbrown: why do you see scala more useful for the backend then clojure? |
| 13:43 | zakwilson | I see ayrnieu isn't a big Haskell fan. |
| 13:44 | zakwilson | I've decided to learn it in an attempt to purify my mind after working on some really bad PHP. I don't know that I'll actually make a habit of using it. |
| 13:45 | blbrown | digash, kind of what zak was saying. You want correctness up front when writing more mission critical code. Like your server backend. But for the web application server pieces. Say in the MVC model, passing the data to the view form, you don't need for your entire application to be correct up front. Hope that makes sense |
| 13:46 | blbrown | digash, this is just my ad-hoc take on where I would use a more dynamic language like clojure and where I would use something like scala or haskell |
| 13:46 | zakwilson | I think it's more a matter of... if you know exactly (or nearly) what you're going to make, more safety up-front is nice. If you don't, it may get in the way. |
| 13:47 | ayrnieu | zakwilson - that quote makes this more relevant: http://paste.lisp.org/display/75921 |
| 13:47 | blbrown | and in a web environment, the more front end code, you are going to change what data gets displayed, what doesn't, etc, etc. Probably more often than the back-end layer. |
| 13:48 | blbrown | ayrnieu, nice words of wisdom |
| 13:54 | zakwilson | ayrnieu: Very good, and I it illustrates well one of the things I think is wrong with Arc. |
| 13:54 | blbrown | oo, you messed with arc, im sorry |
| 13:55 | zakwilson | I've done PHP for money. Arc was nice by comparison. |
| 13:55 | blbrown | I think PHP, VBBasic?, Perl are competing for the ugliest languages |
| 13:55 | ayrnieu | blbrown - http://tnx.nl/php |
| 13:56 | zakwilson | http://paste.lisp.org/display/76132 <-- and that wasn't the worst of it |
| 13:56 | blbrown | hehe |
| 13:57 | zakwilson | I inherited a project that was PHP from a Ukranian sweatshop. I thought it would be quicker to refactor it than scrap it. I was wrong. |
| 13:59 | blbrown | actually, I did create a simple file upload system for my website. I guess for quick server side apps, it can be OK |
| 13:59 | blbrown | http://botnode.com/ for example, here, I can update all of the content through my php application |
| 14:00 | blbrown | hehe http://botnode.com/dev/app/octane_flowers.php |
| 14:20 | arohner | are there any rules about code that has dependencies on third party jars going into contrib? |
| 14:20 | kotarak | arohner: there is already eg. miglayout. That also needs a third-party jar.... |
| 14:22 | arohner_ | kotarak: thanks |
| 14:23 | kotarak | arohner_: however I'm in no way authoritative! :) So you should make sure with rhickey or chouser, I guess. |
| 14:30 | Chouser | clojure.parallel is itself optional, but requires a 3rd party jar if you want to use it. |
| 14:30 | Chouser | and a couple of contrib libs require or can use a 3rd party jar |
| 14:31 | Chouser | so I guess there's no rule against it. :-) |
| 14:43 | durka42 | does this already exist in clojure? |
| 14:43 | durka42 | (defmacro comp* [outer inner] `(fn [& args#] (apply ~outer (map ~inner args#)))) |
| 14:43 | durka42 | i.e. ((comp* = first) [1 2] [1 3]) => true |
| 14:47 | Chouser | I don't think so |
| 14:47 | rlb | Is there already any easy way to "tap" a java FileOutputStream (so you can have a clojure function operated on all the data passing through it)? |
| 14:47 | rlb | s/operated/operate/ |
| 14:49 | rlb | I suppose I could just change the way I'm handling the file copy (and processing). I started off using nio (a ByteBuffer) because I was under the impression that it's substantially more efficient and this is going to handle a *lot* of data. |
| 14:52 | rlb | A simple thing to do would be to change it so that the code just presents the incoming and outgoing data as seqs of binary chunks. That'd be much easier to manipulate from clojure, but it would also (I assume) result in quite a bit of extra copying. |
| 14:53 | Chouser | durka42: another way: (defn comp*2 [a b] (comp (partial apply a) (partial map b))) |
| 14:53 | Chouser | ((comp* = first) [[1 2] [1 3]]) |
| 14:54 | durka42 | ooh, that's better. less distance between thought and code |
| 14:54 | kotarak | and no macro :) |
| 14:54 | durka42 | wonders* |
| 14:58 | hiredman | rlb: you can proxy OutputStream an have it close over your FileOutputstream |
| 14:59 | rlb | hiredman: and I'd selectively override its methods (assuming I understand both what you're saying and how clojure's methods work)? |
| 14:59 | hiredman | actually |
| 15:00 | hiredman | I guess you could just proxy FileOutputstream |
| 15:00 | hiredman | rlb: yes |
| 15:00 | durka42 | define something as a macro, then try to redefine it as a non-tail-recursive function --> error |
| 15:01 | hiredman | ~java_interop? |
| 15:01 | clojurebot | Titim gan �ir� ort. |
| 15:01 | durka42 | ~java interop is . |
| 15:01 | clojurebot | You don't have to tell me twice. |
| 15:01 | hiredman | ~java interop is http://clojure.org/java_interop |
| 15:01 | clojurebot | Ack. Ack. |
| 15:04 | rlb | hiredman: I think, at least for read-only ops, and if I want to keep from having to make more than one copy of the data, that a quick, simple solution might be to add something like (for-each-chunk [func file] ...). The func would be passed the (same) ByteBuffer after each read. Then func could just be composed of as many ops as desired. |
| 15:04 | hiredman | rlb: which ever way you want |
| 15:04 | blbrown | watch this |
| 15:04 | lightbot | I am sorry, I did not understand |
| 15:05 | blbrown | hello |
| 15:05 | lightbot | Hello, My name is light |
| 15:05 | blbrown | what is your name |
| 15:05 | lightbot | My master goes by the nick, blbrown |
| 15:05 | blbrown | thanks |
| 15:05 | lightbot | I am sorry, I did not understand |
| 15:05 | blbrown | do you want to play a game |
| 15:05 | lightbot | Yes David, I like to play games |
| 15:05 | blbrown | Hello my name is bob |
| 15:05 | lightbot | I am sorry, I did not understand |
| 15:05 | hiredman | having the bot react to ever line in the channel may get old fast in here |
| 15:05 | lightbot | I am sorry, I did not understand |
| 15:05 | blbrown | Hello my name is Bob |
| 15:05 | lightbot | My name is light |
| 15:05 | hiredman | you might want to take it to #clojurebot |
| 15:05 | rlb | hiredman: thanks, though, I'll keep your suggestion in mind, esp if I want transformational ops later. |
| 15:06 | blbrown | hiredman, yea, just testing, I have my natural language parser hooked up to it |
| 15:06 | hiredman | interesting |
| 15:06 | blbrown | that was verion 0 |
| 15:37 | rlb | Does clojure have anything like scheme's case or cond syntax, or is that sort of thing normally handled by other means? |
| 15:37 | cmvkk | condp maybe |
| 15:37 | cmvkk | and cond |
| 15:38 | rlb | Sorry, I overlooked it in the docs -- thanks. I was looking on the doc page with if, do, etc... |
| 15:47 | rlb | Is tree-seq guaranteed to traverse the children in the order provided by the provided func by any chance? |
| 15:47 | rlb | "the children func" |
| 15:48 | rlb | At least in this case, that woud be very helpful. |
| 15:48 | gnuvince_ | "the children func"... I'm sure this could get you arrested. |
| 15:49 | cmvkk | it seems like it would from the function def |
| 15:53 | rlb | cmvkk: it does seem pretty likely. Though since it's critical, I suppose I can insert some (obviously non-exhaustive) build tests, just to make sure it doesn't appear to change in future versions of clojure. |
| 15:54 | Raynes | Is there a function that takes 2 seqs and interweaves them like giving it (1,3,5,7) (2,4,6,8) would make (1,2,3,4,5,6,7,8)? |
| 15:54 | cmvkk | or since the def is only 5 lines long anyway, you could just copy it into your own source and control it that way. |
| 15:54 | cmvkk | interleave |
| 15:54 | Raynes | Hawt thanks. |
| 15:54 | cmvkk | ,(interleave [1 3 5 7] [2 4 6 8]) |
| 15:54 | clojurebot | (1 2 3 4 5 6 7 8) |
| 15:54 | rlb | cmvkk: true -- I was thinking about that. |
| 15:55 | rlb | cmvkk: I should probably check out the clojure source. |
| 15:57 | cmvkk | ~def tree-seq |
| 15:59 | Raynes | (defn children-func [num names] (apply hash-map (interleave num names))) <--Children function. |
| 16:00 | durka42 | bah i'm sorry for all the bouncing |
| 16:00 | durka42 | sketchy w-fi |
| 16:00 | durka42 | wi-fi |
| 16:08 | djkthx | hmm |
| 16:09 | djkthx | im getting a strange error |
| 16:09 | djkthx | when i start emacs |
| 16:09 | djkthx | An error has occurred while loading `/Users/ynadji/.emacs': |
| 16:09 | djkthx | File error: Cannot open load file, clojure-auto |
| 16:09 | djkthx | but i have the path to clojure-mode added in my ~/.emacs |
| 16:09 | djkthx | it's new after i switched to the google code clojure |
| 16:11 | djkthx | nevermind |
| 16:11 | djkthx | got it working |
| 16:19 | rlb | Does java have anything like (.isLink file) -- or more specifically, a (perhaps platform specific) way to get essentially all the information about a file (is it a socket, character device, etc...)? |
| 16:21 | rlb | Wow, so far, it looks like not (dating back to even 2001). If so, that's surprising... (to put it mildly). |
| 16:23 | p_l | rlb: by creating a cross-platform library, you either do it all-inclusive or lowest common denominator. Java had gone for the latter. |
| 16:23 | p_l | Common Lisp's pathname system is example of the former :) |
| 16:24 | rlb | OK, though if that's true, then I either just can't write the app I was working on in clojure, or I'll have to call out to a C or python helper application. |
| 16:24 | rlb | ...and if so, that's really too bad. |
| 16:25 | rlb | I suppose python might be the most portable thing. |
| 16:29 | rlb | Of course then the first FAQ entry will be "Q: why didn't you just write it all in python." |
| 16:31 | hiredman | http://www.idiom.com/~zilla/Xfiles/javasymlinks.html |
| 16:31 | rlb | hiredman: yeah, that's *very* disappointing. |
| 16:32 | rlb | I need everything, "is it a special file, is it a character device, what's the major and minor for the device, etc.". |
| 16:32 | rlb | (on unix at least) |
| 16:32 | rlb | I may need to re-think. |
| 16:32 | p_l | rlb: Check if there's low-level OS support library |
| 16:33 | rlb | p_l: right -- I'm going to look around a bit more. |
| 16:34 | rlb | p_l: I'm also starting to wonder if I might be able to just create something myself via JNI (or whatever), if necessary. |
| 16:34 | p_l | rlb: You might want to look at swig, then |
| 16:35 | p_l | I just lost a night playing with it :) |
| 16:35 | rlb | p_l: I have. I've used it for that before, though I may also want to see just how hard it would be to do it without the added dependency. |
| 16:35 | p_l | heh |
| 16:36 | p_l | just generate the bindings and you probably wouldn't need swig anymore, except maybe as compile-time dependency |
| 16:36 | rlb | I wonder if it would be feasible/useful to create some kind of clojure support for JNI wrappers. |
| 16:38 | rlb | I suppose messing with JNI directly is probably one way to figure that out. |
| 16:38 | cp2 | rlb: you would just need a normal java class with native method definitions |
| 16:38 | cp2 | you can do the rest from clojure |
| 16:39 | rlb | cp2: I was more thinking of some way to do something like what swig does, but from clojure. Perhaps not worthwhile, but i was just wondering... |
| 16:39 | cp2 | yeah, i dont really know |
| 16:39 | AWizzArd | rlb: I think there is all you want. Check out http://openbook.galileodesign.de/javainsel8/javainsel_14_001.htm |
| 16:39 | AWizzArd | This is in german, but anyway, just read the code and check the output |
| 16:40 | AWizzArd | Listing 14.2 ShellFolderDemo.java shows how you find out if something is a link |
| 16:42 | hiredman | AWizzArd: he wants to be able to tell if a file is a character device |
| 16:42 | dreish | I haven't tried it, but jtux looks like a good general solution. |
| 16:43 | dreish | It provides access to all the POSIX syscalls. |
| 16:43 | abrooks | rlb: I posted a JNI example a while back... let me find it. |
| 16:43 | abrooks | er.. |
| 16:43 | abrooks | JNA |
| 16:43 | rlb | dreish: haven't tried what? |
| 16:44 | dreish | rlb: jtux |
| 16:44 | abrooks | rlb: http://groups.google.com/group/clojure/browse_thread/thread/77e626c5440bf1a0 |
| 16:44 | rlb | dreish: oh, right. |
| 16:44 | abrooks | dreish: jtux seems mostly dead. |
| 16:44 | dreish | abrooks: Maybe they got it right 3 years ago and haven't had anything to fix. ;-) |
| 16:45 | rlb | abrooks: ahh, so jna is java libffi-ish? |
| 16:45 | rlb | (I think I knew that...) |
| 16:46 | abrooks | dreish: Possibly, but my experiences with software say "No." ;-D |
| 16:46 | abrooks | rlb: Yes. |
| 16:46 | dreish | More recently-updated: Posix for Java at http://www.bmsi.com/java/posix/package.html |
| 16:46 | durka42 | Jtux supplies two non-standard functions, jaddr_to_seg and jaddr_from_seg to copy data between pointers represented as longs and Java byte arrays. |
| 16:46 | durka42 | uh oh - pointers for java |
| 16:47 | abrooks | dreish: Ah, that's cool. Thanks for the link. |
| 16:47 | cp2 | durka42: there is already somethign similar to that in the jdk |
| 16:47 | cp2 | the class name is Unsafe |
| 16:48 | cp2 | and lets you set/get data based on memory address |
| 16:48 | cp2 | its one of those evil hidden classes :) |
| 16:49 | cp2 | ezbake fed trials |
| 16:49 | rlb | dreish: ahh, ok, that's interesting, and at least judging by the file mod times, it looks active. |
| 16:50 | rlb | Thanks all -- I think I'll look in to java posix a bit further. If that works out, I'll just plan to help the upstream there. |
| 17:10 | rlb | dreish: that was easy, and so far, it appears to work. It also doesn't look like it would be difficult to extend. |
| 17:11 | rlb | excellent. |
| 17:11 | dreish | rlb: Thanks, I'm glad to hear it. I think I'll want to use it too at some point. |
| 17:11 | dreish | This was the one at bmsi.com? |
| 17:11 | rlb | dreish: yes. |
| 17:14 | rlb | Hmm -- wonder about adding a debian libposix-java package. I suppose for now if it works out, I'll probably just plan to include it, but later... |
| 18:14 | arohner | clojurebot: paste |
| 18:14 | clojurebot | lisppaste8, url |
| 18:14 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 18:14 | Chouser | heh |
| 18:34 | harry__ | /past |
| 18:39 | rajarshi | Hi, a lisp newbie here and I had a question regarding loop, When using loop and recur to build up a list, how do I return the result of the last iteration? I'm always getting nil |
| 18:41 | cmvkk | (if (end-of-loop) result (recur (add-to-result) ...)) for example? |
| 18:41 | cmvkk | where you'd have a test for the end of the loop etc |
| 18:41 | rajarshi | cmvkk: ahh, missed the obvious solution. Thanks |
| 18:56 | Lau_of_DK | Good evening folk |
| 18:56 | Lau_of_DK | All but the americans have gone to bed ? |
| 18:57 | keithb | All, what is the best way to pass key/value pairs to a function? Should I use (hash-map ...) to package them into a single map? |
| 18:57 | keithb | Or, is there some kind of syntactic sugar like in Ruby, where I can just pass key/value pairs literally? |
| 18:57 | Lau_of_DK | I'd say it depends on the purpose |
| 18:58 | cmvkk | arglists for functions can do all sorts of map restructuring if you want to do that |
| 18:58 | cmvkk | destructuring, more like |
| 19:00 | keithb | I'm writing a function that creates and returns a subclass of AbstractAction. I'd like to be able to be able to pass key/value pairs for its properties (tooltip, accelerator key, etc.) into this function. |
| 19:00 | keithb | There are several of these options, and I don't want to hard code any of them. |
| 19:03 | Lau_of_DK | I'd go with one hash-map |
| 19:05 | hiredman | clojurebot: destructuring? |
| 19:05 | clojurebot | destructuring is http://clojure.org/special_forms#let |
| 19:05 | keithb | Lau_of_DK: Thanks. It is a pretty clean way to go. |
| 19:08 | Lau_of_DK | Yea I think so |
| 19:16 | digash | i see in the gen-class doc that if i add to a signature a #^{:static true} it should generate it as static, but it does not |
| 19:17 | digash | anybody has any example with static generation? |
| 19:18 | mgarriss | if i have a list of maps how do i increment some key within each map and return the coll? example: (foobar ({:x 0} {:x 0} {:x 0})) ; => ({:x 0} {:x 1} {:x 2}) |
| 19:21 | cmvkk | so every map has 0 as the value of the key already? |
| 19:21 | mgarriss | each starts with :x set to 0 |
| 19:22 | cmvkk | (map (fn [mp nv] (assoc mp :x nv)) map-list (range (count map-list))) |
| 19:23 | cmvkk | you're mapping over each map, and applying the value of an incrementing number to some specific key. |
| 19:24 | mgarriss | thx. new to clojure, this is still hard to understand |
| 19:25 | gnuvince_ | ,(map #(update-in %2 [:x] %1) (map #(fn [x] (+ x %)) (range 3)) [{:x 0} {:x 0} {:x 0}]) |
| 19:25 | clojurebot | ({:x 0} {:x 1} {:x 2}) |
| 19:28 | cmvkk | yeah, that's more general than mine. It'll add an incrementing number to the value of :x whether it starts with 0 or not. |
| 19:29 | gnuvince_ | Yours is less horrible though :) |
| 19:29 | cmvkk | whenever i try to type 'closures' now, i always accidentally type 'clojures' |
| 19:29 | gnuvince_ | I have a map with an anonymous function to generate an anonymous function ;) |
| 19:30 | gnuvince_ | cmvkk: tell me about it. |
| 19:31 | hiredman | I wish rhickey would commit something |
| 19:31 | mgarriss | now i get it, i didn't realize that map could take multiple collections |
| 19:31 | cmvkk | yep. the number of collections is equal to the number of arguments in the map function. |
| 19:32 | gnuvince_ | hiredman: like what? |
| 19:32 | gnuvince_ | mgarriss: yeah |
| 19:32 | hiredman | anything, I want to see if clojurebot's svn log -> twitter bit is working |
| 19:32 | gnuvince_ | hiredman: don't you have mock objects to test that? *wink* |
| 19:32 | cmvkk | i was about to say... |
| 19:33 | cmvkk | real world testing is hard, you're supposed to be simulating this stuff. |
| 19:33 | replaca | Q: Is replicate being dropped in favor of repeat |
| 19:33 | replaca | ? |
| 19:34 | gnuvince_ | mgarriss: Clojure has only map which can work with a variable number of arguments. If you know Haskell, you probably know zipWith through zipWith8 |
| 19:34 | hiredman | I have dones some tests, and they worked |
| 19:34 | hiredman | but I will not be sure it works until it is doing what I want it to do |
| 19:36 | cmvkk | replaca: they do seem to do the same thing. isn't it sad? replicate is the function closest in name to your handle. |
| 19:37 | replaca | cmvkk: I don't think repeat used to be there, and I thought I saw some comment that made me think that Rich was changing it over, but I was working on something else. I like repeat better, my handle aside. :-) |
| 19:37 | lisppaste8 | keithb pasted "Maps" at http://paste.lisp.org/display/76643 |
| 19:38 | keithb_ | I guess it's a little simpler to specify the { } literal ArrayMap rather than (hash-map ...), all other things being equal, and for a very small map? |
| 19:39 | hiredman | ,(class {:a 1 :b 2 :c 3 :d 4 :e 5 :f 6 :g 7 :h 8 :i 9 :i 10 :k 11 :l 12 :m 13 :n 14}) |
| 19:39 | clojurebot | clojure.lang.PersistentHashMap |
| 19:40 | ayrnieu | ,(take 5 (repeatedly #(repeat 2 (rand)) |
| 19:40 | clojurebot | EOF while reading |
| 19:40 | hiredman | I think after nine items arraymaps are auto magically turned into hashmaps |
| 19:40 | ayrnieu | so I prefer 'repeat' to 'replicate'. |
| 19:43 | keithb_ | hiredman: Interesting, thanks. |
| 19:43 | replaca | ahh, issue 55: remove replicate in favor of repeat with multiple arities |
| 19:44 | hiredman | well, repeat already has replicates functionality, it just hasn't been removed |
| 19:44 | replaca | yeah, I'm just trying to future-proof my code right now, so I guess I should remove all the replicates |
| 19:45 | ayrnieu | wishful thinking :-) |
| 19:46 | replaca | well, yes, but in this case it would help :-) |
| 19:46 | replaca | I'm generally in the midst of adapting cl-format and my pretty printer to the "lazy" world, which is a big code walk anyway, so I'm getting anything I can along the way |
| 19:50 | digash | i've got it, was putting static in the wrong place |
| 19:50 | digash | :methods [#^{:static true} [suite [] junit.framework.Test] is the right way |
| 19:51 | digash | :methods [[#^{:static true} suite [] junit.framework.Test] ; not this way :) |
| 20:01 | lisppaste8 | arohner pasted "defn-memoize" at http://paste.lisp.org/display/76644 |
| 20:01 | arohner | is that a good idea? |
| 20:02 | arohner | is there a cleaner way to write that? |
| 20:05 | cmvkk | well, does that work? |
| 20:05 | arohner | it works |
| 20:05 | arohner | just looks like it could be prettier |
| 20:05 | hiredman | `(def ~name (memoize (fn ~@body)) |
| 20:05 | cmvkk | there's that too. |
| 20:06 | cmvkk | your version will choke on docstrings maybe though |
| 20:06 | arohner | right. |
| 20:06 | ayrnieu | and for multiple-arity defns? |
| 20:06 | cmvkk | it'll work for that. |
| 20:06 | cmvkk | fns do that just like defn. |
| 20:08 | replaca | well docstrings would work with ^#{:doc "xxx..."} |
| 20:08 | arohner | yeah, but you're losing half the reason of having defn |
| 20:08 | replaca | but that's not fully defn-style |
| 20:09 | cmvkk | can defmulti take docstrings yet? |
| 20:09 | cmvkk | ah, it can. |
| 20:09 | ayrnieu | arohner - your verison is fine. |
| 20:10 | arohner | ayrnieu: thanks |
| 20:14 | arohner | since clojure is immutable, you can test to see if two arrays are equal just by comparing pointers, right? |
| 20:14 | replaca | no |
| 20:14 | replaca | objects aren't "interned" |
| 20:15 | replaca | so you can have [0 1 2] and [0 1 2] as two separate things |
| 20:15 | cmvkk | equality is defaulty by value. |
| 20:15 | cmvkk | identical? will work that way though... |
| 20:18 | replaca | you might be confused because some languages (Java, I think) use immutable strings and "intern" them so the same string will always be the same object. But that generally isn't true of immutable objects in other environments |
| 20:21 | ayrnieu | Lua and Pike do that. |
| 20:21 | hiredman | ,(= "foo" (String. "foo")) |
| 20:21 | clojurebot | true |
| 20:23 | ayrnieu | ,(identical? "foo" (String. "foo")) |
| 20:23 | clojurebot | false |
| 22:44 | brennanc | trying to figure out how to connect to mysql through clojure. I'm import clojure.contrib.sql and then did (with-connection {:user "root", :subname "localhost", :classname "com.mysql.jdbc.Driver", :subprotocol "mysql"} (println "test")) but it says "jaa.sql.SQLException no suitable driver" |
| 22:44 | brennanc | it's in the classpath and I can do (Driver.) and it creates an instance fine so I'm not sure what the problem is. Any ideas? |
| 22:45 | Chouser | http://stackoverflow.com/questions/613929/how-do-i-connect-to-a-mysql-database-from-clojure |
| 22:47 | brennanc | thanks, will try that |
| 22:47 | Chouser | I think it's step 2 that you may be missing |
| 22:47 | Chouser | the -D thing |
| 22:48 | brennanc | just tried it without step 2 and it seems to work |
| 22:48 | brennanc | I had the subname as "localhost". I needed to set it to "//localhost" for it to work |
| 22:48 | Chouser | oh, ok |
| 22:49 | brennanc | really weird. never heard that term before and it's weird to require the // in front |
| 22:49 | brennanc | oh well, easy enough, just gotta know that I guess |