2009-10-29
| 00:04 | qed | whats the quickest way to make (a .. z) |
| 00:04 | qed | (\a \b \c \d \e \f \g \h..\z) |
| 00:05 | hiredman | ,(int \a) |
| 00:05 | clojurebot | 97 |
| 00:05 | hiredman | ,(map char (range 97 (+ 97 25))) |
| 00:05 | clojurebot | (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y) |
| 00:05 | hiredman | ,(map char (range 97 (+ 97 26))) |
| 00:05 | clojurebot | (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y \z) |
| 00:06 | hiredman | ,(->> [\a \z] (map int) (apply range) (map char)) |
| 00:06 | clojurebot | (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y) |
| 00:06 | qed | hiredman: thanks |
| 00:06 | qed | hiredman: is that the thrush combinator? |
| 00:06 | qed | ive never seen it with the >> |
| 00:07 | hiredman | sort of |
| 00:07 | mwoelker | ,(map char (range (int \a) (int \z))) |
| 00:07 | clojurebot | (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y) |
| 00:07 | qed | hiredman: what's ->> called |
| 00:07 | mwoelker | darn |
| 00:07 | hiredman | it could also be the thrush, just slightly different |
| 00:08 | hiredman | ->> puts stuff in the last arg position, -> in the first |
| 00:08 | tomoj | wooby: suppose a chain ends in 1 |
| 00:08 | tomoj | then it enters an infinite loop of 1's |
| 00:08 | hiredman | (function _ arg arg etc) vs (function arg arg etc _) |
| 00:08 | tomoj | searching through it for 89 will never terminate |
| 00:08 | adityo | ~ good morning |
| 00:08 | clojurebot | Pardon? |
| 00:08 | adityo | ~good morning |
| 00:08 | clojurebot | Huh? |
| 00:09 | hiredman | :D |
| 00:09 | adityo | :) |
| 00:09 | hiredman | ,((comp (partial map char) (partial apply range) (partial map int) list) \a \z) |
| 00:09 | clojurebot | (\a \b \c \d \e \f \g \h \i \j \k \l \m \n \o \p \q \r \s \t \u \v \w \x \y) |
| 00:09 | tomoj | "ends in 1" is misleading |
| 00:10 | tomoj | because "ends in 1" really means "has an infinite number of ones as a tail" |
| 00:10 | wooby | tomoj: thanks, i figured it out earlier |
| 00:10 | tomoj | ah |
| 00:10 | wooby | tomoj: that's exactly what was happening |
| 00:10 | Dawgmatix | any clojure reading material recommendations ? pointers to both code and tuts appreciated |
| 00:11 | wooby | tomoj: i fixed and it's running, est. 20 hours to answer :) |
| 00:11 | tomoj | I always forget, will counting a lazy seq allow it to be garbage collected as it counts? |
| 00:11 | tomoj | haha |
| 00:11 | tomoj | yeah I expect you have to come up with some clever solution |
| 00:11 | hiredman | Dawgmatix: you seen the rhickey videos? |
| 00:11 | Dawgmatix | hired yes I saw those |
| 00:12 | wooby | tomoj: i wrote a has-89 function that recurs and checks for 1 |
| 00:13 | tomoj | I just wrote something which returns either 1 or 89 |
| 00:13 | tomoj | also seems very slow |
| 00:13 | wooby | oh wow, it got it |
| 00:13 | wooby | renice for the win |
| 00:13 | hiredman | http://delicious.com/clojurebot is all the urls pasted to the channel, so you might dig through those |
| 00:14 | tomoj | wooby: are you doing (count (filter ..)) ? |
| 00:14 | wooby | tomoj: http://gist.github.com/221142 |
| 00:14 | tomoj | ok, so I guess count will allow a lazy seq to be garbage collected |
| 00:14 | wooby | it appears so |
| 00:15 | Dawgmatix | thankoo hired |
| 00:15 | Dawgmatix | will look through those |
| 00:15 | wooby | tomoj: although an earlier version ran out of memory |
| 00:15 | tomoj | I wonder how fast your digits-of is compared to mine |
| 00:15 | wooby | tomoj: what does yours look like? |
| 00:16 | hiredman | Dawgmatix: all of the urls rhickey pasted are tagged with rhickey or rhickey_ |
| 00:17 | tomoj | wooby: https://gist.github.com/1b2c0b1a7fb5807caa3d |
| 00:17 | tomoj | my digits is 4 times slower than your digits-of |
| 00:17 | tomoj | I guess because of all the function calls? |
| 00:17 | Dawgmatix | okay hired |
| 00:18 | tomoj | well, and arithmetic in general |
| 00:19 | tomoj | for some reason I thought math would be faster than dealing with strings |
| 00:20 | wooby | you would think |
| 00:20 | wooby | probably the fastest would be bit shifting |
| 00:20 | piccolino | How would one write "(require 'clojure.contrib.str-utils2 :as s])" in the form of :require for use in ns? I am getting compile errors no matter how I try to do it. |
| 00:20 | tomoj | but how would you use bit shifting for base 10? |
| 00:21 | hiredman | well, uh, you have a dangling ] there |
| 00:21 | tomoj | (:require [clojure.contrib.str-utils2 :as s]) |
| 00:21 | piccolino | Oops, that [ is there in my code. |
| 00:22 | piccolino | Hm. Then it gives me a compile error : No such var: s/map-str. |
| 00:23 | hiredman | ,(require '[clojure.contrib.str-utils2 :as s]) |
| 00:23 | clojurebot | nil |
| 00:23 | hiredman | ,s/map-str |
| 00:23 | clojurebot | #<str_utils2$map_str__7819 clojure.contrib.str_utils2$map_str__7819@90d0ea> |
| 00:24 | hiredman | clojurebot: works on my machine |
| 00:24 | clojurebot | http://haacked.com/images/haacked_com/WindowsLiveWriter/IConfigMapPathIsInaccessibleDueToItsProt_1446B/works-on-my-machine-starburst.png |
| 00:24 | wooby | tomoj: something along the lines of digit = (number % (int)pow(10,++place)) |
| 00:25 | piccolino | Hm, OK. |
| 00:25 | wooby | tomoj: in a do/while, checking for digit == number where number is the input |
| 00:27 | tomoj | oh, wow. when I say 4x slower, that was a math error |
| 00:27 | tomoj | it's more like 40x slower |
| 00:28 | tomoj | but using (int (quot n 10)) instead of (int (/ n 10)) gives a 10x speedup, so now it is 4x slower |
| 00:32 | tomoj | seems like (zero? n) is also significantly faster than (== n 0) |
| 00:33 | hiredman | makes sense |
| 00:42 | wooby | tomoj: it's weird, you'd really think it would be faster |
| 00:42 | wooby | tomoj: maybe it just boils down to function size :) |
| 00:43 | hiredman | less code to execute is less code |
| 00:43 | Hecktor | Is there a builtin function that returns the first not nil item in a sequence? |
| 00:43 | tomoj | I guess read-string is very fast on single digits |
| 00:44 | tomoj | and no math involved |
| 00:44 | tomoj | you get all the modulos by powers of ten automatically because it's a string |
| 00:44 | hiredman | ,((comp first (partial drop-while nil?)) [nil nil 1 2 3 4]) |
| 00:44 | clojurebot | 1 |
| 00:45 | tomoj | hmm |
| 00:45 | tomoj | is there any real difference between (first (remove nil? ..)) and (first (drop-while nil? ..)) |
| 00:45 | hiredman | huh |
| 00:45 | wooby | ,(first (drop-while #(nil? %) [nil nil 1])) |
| 00:45 | clojurebot | 1 |
| 00:45 | tomoj | since you're only asking for the first I guess they do the same |
| 00:46 | hiredman | wooby: nil? is a function, you don't need to rewrap it like that |
| 00:46 | piccolino | hiredman: Ah, the problem is that map-str was not in str-utils2 1.0-compatible. |
| 00:46 | hiredman | tomoj: right |
| 00:46 | wooby | hiredman: oh right, thanks |
| 00:46 | wooby | ,(first (drop-while nil? [nil nil 1])) |
| 00:46 | clojurebot | 1 |
| 00:46 | Hecktor | cool |
| 00:46 | somnium | ,(some #(or % %) [nil nil nil 1]) |
| 00:46 | clojurebot | 1 |
| 00:47 | hiredman | :( |
| 00:47 | qed | hiredman: sorry i lost my buffer |
| 00:47 | qed | what is ->>? |
| 00:47 | hiredman | ,(some identity [nil nil 1]) |
| 00:47 | clojurebot | 1 |
| 00:47 | wooby | fancy |
| 00:47 | somnium | I always forget about identity |
| 00:47 | tomoj | ,(some identity [nil false nil 1]) |
| 00:47 | clojurebot | 1 |
| 00:47 | hiredman | qed: ->> is like -> but it puts the arg in the last spot instead of the first |
| 00:48 | hiredman | (f _ arg2 arg3) vs (f arg1 arg2 _) |
| 00:48 | somnium | ,(str (count "identity") (count #(or % %))) |
| 00:48 | clojurebot | java.lang.UnsupportedOperationException: count not supported on this type: sandbox$eval__4819$fn__4821 |
| 00:48 | qed | hiredman: i think i maybe misunderstood how the thrush combinator works |
| 00:48 | hiredman | erm |
| 00:48 | qed | it reverses computability right? |
| 00:48 | wooby | ,(some identity [nil false 1]) |
| 00:48 | clojurebot | 1 |
| 00:48 | hiredman | it's like Tax = xa |
| 00:49 | qed | I don't know that |
| 00:49 | qed | what is T |
| 00:50 | hiredman | the thrush |
| 00:50 | hiredman | so (-> a b) = (b a) |
| 00:50 | wooby | seems like it's function un-nesting kinda |
| 00:50 | qed | hiredman: right, reverses computability |
| 00:51 | hiredman | (->> a b) = (b a) |
| 00:51 | hiredman | but (-> a (b c)) = (b a c) and (->> a (b c)) = (b c a) |
| 00:51 | wooby | so (->> a b c) = (c (b a)) ? |
| 00:52 | hiredman | without args -> and ->> are identical |
| 00:52 | qed | i gotcha |
| 00:52 | qed | thats a neat little structure |
| 00:52 | hiredman | it is |
| 00:52 | qed | i like it |
| 00:52 | qed | tbh i feel like im sort of cheating by using it |
| 00:53 | tomoj | did I read that rhickey doesn't like autocurrying? |
| 00:53 | hiredman | you just get this sort of flow data through your functions |
| 00:53 | tomoj | well I don't expect you to know whether I read that or not, but I mean, is that true? |
| 00:53 | hiredman | tomoj: dunno |
| 00:54 | hiredman | I would love to have autocurrying, that is the main reason I want metadata on functions |
| 00:55 | hiredman | to keep track of arity information |
| 00:55 | tomoj | hmm |
| 00:55 | tomoj | what about functions with overloaded arity |
| 00:55 | hiredman | it's tricky |
| 00:56 | qed | who asked about autocurrying? |
| 00:56 | tomoj | <- |
| 00:56 | qed | tomoj: http://groups.google.com/group/clojure/msg/d20660b459abffeb |
| 00:56 | tomoj | why thank you |
| 00:56 | qed | :) |
| 00:59 | tomoj | I just noticed the example in clojure.http.resourcefully uses https |
| 00:59 | tomoj | so I guess clojure.http.client can do https? someone was asking about that the other day |
| 01:18 | chouser | ~seen maacl |
| 01:18 | clojurebot | maacl was last seen quiting IRC, 788 minutes ago |
| 01:21 | hiredman | ,(int (/ 788 60 60)) |
| 01:21 | clojurebot | 0 |
| 01:21 | hiredman | ,(int (/ 788 60)) |
| 01:21 | clojurebot | 13 |
| 01:21 | hiredman | ,(int (/ 788 60 24)) |
| 01:21 | clojurebot | 0 |
| 01:21 | hiredman | ,(double (/ 788 60 24)) |
| 01:21 | clojurebot | 0.5472222222222222 |
| 01:21 | chouser | hiredman: ah, thanks. |
| 01:21 | chouser | :-) |
| 01:43 | wavis_ | ,clojure.contrib.seq-utils |
| 01:43 | clojurebot | java.lang.ClassNotFoundException: clojure.contrib.seq-utils |
| 01:43 | hiredman | ,(require '[clojure.contrib.seq-utils :as seq-utils]) |
| 01:43 | clojurebot | nil |
| 01:44 | felzix | is there any way to get more information out of a NullPointerException? |
| 01:44 | felzix | line number would be awesome |
| 01:45 | hiredman | depends on what is generating it |
| 01:45 | felzix | is there a way to determine that? |
| 01:45 | tomoj | I hate when I don't get line numbers |
| 01:45 | hiredman | well, if there is a way to get a line number you will get one |
| 01:45 | hiredman | so if you aren't getting one, well, :( |
| 01:46 | tomoj | clojure backtraces are largely still mysterious to me |
| 01:46 | felzix | I mean, I know the general location of the problem |
| 01:46 | hiredman | tomoj: have you seen clojure.stacktrace? |
| 01:46 | tomoj | hiredman: no. I will investigate |
| 01:46 | tomoj | I've just been peering at what slime gives me |
| 01:47 | hiredman | it may be similar to what you get from slime |
| 01:47 | tomoj | bunch of extra crap you don't care about? |
| 01:47 | hiredman | I don't use slime |
| 01:47 | tomoj | I mean, usually what I would expect to be at the top of the backtrace is buried deep down somewhere |
| 01:47 | tomoj | under a bunch of internal crap |
| 01:49 | hiredman | http://gist.github.com/221188 |
| 01:49 | wavis_ | ,seq-utils |
| 01:49 | clojurebot | java.lang.Exception: Unable to resolve symbol: seq-utils in this context |
| 01:50 | hiredman | wavis_: seq-utils is just an alias for the clojure.contrib.seq-utils namespace now |
| 01:50 | tomoj | yeah, like that crap |
| 01:51 | hiredman | uh, that is nice cleaned up stack trace |
| 01:51 | tomoj | well, when I do something like that in a file, the line number I do it on is not on the top of the trace |
| 01:51 | tomoj | (and sometimes isn't there at all) |
| 01:52 | hiredman | I almost always get a line number from a loaded file |
| 01:52 | tomoj | for example your second attempt doesn't have a NO_SOURCE_FILE:XX |
| 01:52 | hiredman | but if I am just dumping stuff into the repl |
| 01:52 | Raynes- | My heavens, how did I ever life without Paredit. |
| 01:52 | tomoj | Raynes-: :D |
| 01:53 | hiredman | second attempt? |
| 01:53 | tomoj | when you just do (e) or whatever it was |
| 01:53 | hiredman | (e) is a sort of prettyprinter for *e |
| 01:53 | hiredman | comes with clojure.stacktrace |
| 01:53 | tomoj | ooh, I get it |
| 01:53 | Raynes | I've never used Paredit before. Just straight Emacs. My life has been empty up until this point. |
| 01:53 | tomoj | I thought that was causing another error |
| 01:55 | tomoj | https://gist.github.com/9f0155f80915338175ad |
| 01:56 | tomoj | maybe swank is screwing it up |
| 01:57 | tomoj | it doesn't show the file in which the exception occurs at all |
| 01:58 | hiredman | well, makes me feel good about not using emacs |
| 01:58 | hiredman | what is the file name? |
| 02:00 | tomoj | .../clojure/contrib/json/read.clj |
| 02:00 | tomoj | I changed something around in there to intentionally cause an error |
| 02:00 | tomoj | maybe next time I have a real error with a bad stacktrace I will try it in a pure repl and see if swank is the problem |
| 02:00 | tomoj | if so that really needs to be fixed |
| 02:01 | hiredman | maybe talk to technomancy |
| 02:01 | tomoj | it seems like the top section of the stacktrace might be missing or something |
| 02:02 | tomoj | so far I have yet to have a nasty debugging session in clojure anyway :) |
| 02:05 | mikehinchey | tomoj: hit 1 to see the cause |
| 02:05 | tomoj | mikehinchey: wat |
| 02:05 | mikehinchey | tomoj: on the slime stacktrace screen |
| 02:05 | tomoj | yeah I understood |
| 02:05 | tomoj | that was my "wat" of disbelief |
| 02:05 | tomoj | thank you! |
| 02:06 | tomoj | I don't think I ever even read the second restart |
| 02:06 | hiredman | I almost always end up with (prn x) and (doto x prn) sprinkled around |
| 02:06 | tomoj | I hate when I start doing that |
| 02:06 | mikehinchey | I liked it better when the cause was shown on the same screen instead of a "restart" |
| 02:07 | tomoj | I'm just happy I can see the cause now at all |
| 02:07 | tomoj | now I just have to figure out how to get slime debuggers for compile errors |
| 03:07 | wavis_ | does anyone know if there is a library out there for composing math expressions and treating them as numbers? |
| 03:09 | wavis_ | for example |
| 03:09 | wavis_ | ,(/ (+ 1 (Math/sqrt 5)) 2) |
| 03:09 | clojurebot | 1.618033988749895 |
| 03:11 | wavis_ | would instead give just a composed expression |
| 03:11 | arsatiki | There's clojuratica for interfacing with mathematica |
| 03:12 | wavis_ | hmm... does mathematica run headless on linux? |
| 03:12 | wooby | silly question, how can i test if a number is whole? |
| 03:13 | arsatiki | wavis: I have not used clojuratica myself, but I assume it just uses the mathematica kernel, not the GUI |
| 03:14 | wavis_ | i will look into that then. thanks! |
| 03:15 | wavis_ | i could always do something like (list / (list + 1 (list #(Math/sqrt %) 5)) 2) |
| 03:16 | wavis_ | ... or not |
| 03:16 | felzix | wooby: You mean test if a float or double is a whole number? |
| 03:17 | wavis_ | ,(= 0 (rem 4.5 1)) |
| 03:17 | clojurebot | false |
| 03:17 | wavis_ | ,(= 0 (rem 4.0 1)) |
| 03:17 | clojurebot | true |
| 03:17 | felzix | you could do (= (int 1.1) 1) |
| 03:17 | felzix | ,(= (int 1.1) 1) |
| 03:17 | clojurebot | true |
| 03:17 | felzix | hmm |
| 03:18 | felzix | nvm.. |
| 03:18 | felzix | ah, duh. (= (int 1.1) 1.1) |
| 03:22 | Licenser | ,(= (int 1.1) 1.1) |
| 03:22 | clojurebot | false |
| 03:22 | felzix | but ,(= (int 1.0) 1.0) |
| 03:22 | felzix | ,(= (int 1.0) 1.0), |
| 03:22 | clojurebot | true |
| 03:23 | Licenser | that makes sense |
| 03:23 | Licenser | they have the same value |
| 03:23 | felzix | ,(int 1.0) |
| 03:23 | clojurebot | 1 |
| 03:23 | felzix | it just means floats can be usefully compared against integers |
| 03:23 | Licenser | side quetion, is there a ofline documentation for clojure? |
| 03:24 | Licenser | and that is good |
| 03:24 | felzix | Best I know of is downloading the api html file. |
| 03:24 | Licenser | narf |
| 03:25 | felzix | wooby: does that answer your question? |
| 03:25 | arsatiki | L: you can always use the doc in REPL :) |
| 03:25 | Licenser | arsatiki: I know, but it's not as nice as a document you can work with |
| 03:27 | wooby | felzix: sure does, thank you |
| 03:27 | wooby | i don't think i've ever had as much fun programming as i do with clojure |
| 03:27 | wooby | what's with this language! |
| 03:28 | Licenser | wooby: did you try ruby? |
| 03:28 | Licenser | but I agree clojure is fun, yet it gets very frustrating when you start to get java exeptions :/ |
| 03:28 | arsatiki | true |
| 03:28 | wooby | Licenser: yeah :\ |
| 03:29 | wooby | the java interop is awesome but dealing with java stuff comes with its own shenanigans |
| 03:29 | Licenser | which is currently the one but issue I have with clojure, that and a sometimes less then helpful documentation |
| 03:29 | Licenser | but it's still a really incredible language |
| 03:30 | Licenser | and considering it is only 2 years old, it is just amazing |
| 03:30 | wooby | it really is |
| 03:30 | wooby | ruby, that's the dynamically typed scala variant isn't it? ;) |
| 03:31 | Licenser | teehee I think ruby is older then scala and is't a functional language either |
| 03:32 | wooby | i'm kiddn', yeah its much older... but it does have nice functional bits |
| 03:32 | wooby | stuff just all uses smalltalk names |
| 03:32 | Licenser | I know you can do functional programming in ruby me thinks, and it is a joy to program too most of the time |
| 03:33 | Licenser | One thing that gets me sad so is that you have a hard time as soon as you want to do anything in paralell |
| 03:33 | Licenser | Which is the reason why I'm here :P so good that ruby has a horrible concurrency support, I'd have missed a lot |
| 03:37 | wooby | is there something like split-between, like for splitting the seq [1 2 3 3 2 1] between 3 and 3 given a comparator like (fn [a b] (== a b))? |
| 03:37 | wooby | or just (== %1 %2) i suppose |
| 03:38 | Licenser | don't forget the # but I#ve no clue |
| 03:39 | hiredman | ,(doc split-with) |
| 03:39 | clojurebot | "([pred coll]); Returns a vector of [(take-while pred coll) (drop-while pred coll)]" |
| 03:39 | wooby | hiredman: it seems like your pred is only fed 1 element at a time though |
| 03:40 | hiredman | correct |
| 03:40 | Licenser | what would you expect to happen when you encouther [1 2 3 4 3 2 1]? |
| 03:40 | wavis_ | you could (partition 2 1 %) your list and get the index with which to split the original |
| 03:42 | wooby | Licenser: it would return the whole seq |
| 03:43 | Licenser | hmm partitioning won't work sice it might partition with 2 3 and then 3 2 |
| 03:43 | Licenser | wooby: you have a tricky question |
| 03:44 | hiredman | it's not tricky, but the clojure sequence library is designed for laziness, so nothing scans more than one element at a time, so if you want that you have to roll your own |
| 03:44 | Licenser | I say reduce is the way |
| 03:44 | Licenser | there you can know the last element |
| 03:44 | Licenser | but it'd be ugly slow I think |
| 03:45 | wooby | yeah |
| 03:45 | Licenser | hmm actually not soo much |
| 03:45 | hiredman | why would you need to know the last element? |
| 03:45 | Licenser | as you store the lists in reverse order |
| 03:45 | wooby | i'm going with take-while since i'm only concerned about the first chunk |
| 03:45 | wavis_ | ,(let [l [1 2 3 3 2 1] p (partition 2 1 l)] (split-at (count (first (split-with #(= %1 %2) p))) l)) |
| 03:45 | clojurebot | java.lang.RuntimeException: java.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--4944$fn |
| 03:45 | hiredman | oh |
| 03:45 | hiredman | last as in previous |
| 03:45 | Licenser | wavis_: take 1 2 3 4 4 3 2 1 as list it breaks it already |
| 03:45 | Licenser | hiredman: yap |
| 03:47 | Licenser | the make a new list thing is the tricky part but that code would work I think |
| 03:48 | wooby | ah, yeah a fold left |
| 03:48 | Licenser | I think I slowly get the hang of lisp |
| 03:52 | hiredman | ,((juxt :a :b :c) {:a 1 :b 2 :c 3}) |
| 03:52 | clojurebot | [1 2 3] |
| 03:53 | Licenser | ,(doc juxt) |
| 03:53 | clojurebot | "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]" |
| 03:53 | Licenser | what the hel is a juxta position? |
| 03:55 | hiredman | it means, uh, sort of side by side |
| 03:56 | hiredman | ~google define juxtaposition |
| 03:56 | clojurebot | First, out of 60900 results is: |
| 03:56 | clojurebot | juxtaposition - definition of juxtaposition by the Free Online ... |
| 03:56 | clojurebot | http://www.thefreedictionary.com/juxtaposition |
| 03:56 | hiredman | yeah |
| 03:58 | wavis_ | ,(let [l [1 2 3 3 2 1] p (partition 2 1 l)] |
| 03:58 | wavis_ | (split-at (inc (count (first (split-with #(not (= (first %) (first (rest %)))) p)))) l)) |
| 03:58 | clojurebot | EOF while reading |
| 03:59 | wavis_ | ,(let [l [1 2 3 3 2 1] p (partition 2 1 l)] (split-at (inc (count (first (split-with #(not (= (first %) (first (rest %)))) p)))) l)) |
| 03:59 | clojurebot | [(1 2 3) (3 2 1)] |
| 03:59 | Licenser | ,(let [l [1 2 3 4 4 3 2 1] p (partition 2 1 l)] (split-at (inc (count (first (split-with #(not (= (first %) (first (rest %)))) p)))) l)) |
| 03:59 | clojurebot | [(1 2 3 4) (4 3 2 1)] |
| 03:59 | Licenser | nice |
| 04:00 | wavis_ | needs more testing, like with zero length seqs etc... |
| 04:00 | wavis_ | g'night all |
| 04:03 | Licenser | okay very strange question, how can I join the clojure google group w/o a google account? |
| 04:22 | Licenser | bye people |
| 04:22 | Licenser | see you when I'm back home :D |
| 04:23 | Fossi | hi |
| 04:32 | hiredman | ,(-> (->> [1 2 3 3 2 1] (partition 2) (split-with (comp not (partial apply =))) (map (partial apply concat)) ((juxt identity identity)) ((flip update-in) (juxt first (comp (partial take 1) second)) [0])) (update-in [0] (partial apply concat)) (update-in [1] (comp rest first rest))) |
| 04:32 | clojurebot | [(1 2 3) (3 2 1)] |
| 04:32 | hiredman | hmm |
| 04:33 | hiredman | ,(-> [1 2 3 3 2 1] (->> (partition 2) (split-with (comp not (partial apply =))) (map (partial apply concat)) ((juxt identity identity)) ((flip update-in) (juxt first (comp (partial take 1) second)) [0])) (update-in [0] (partial apply concat)) (update-in [1] (comp rest first rest))) |
| 04:33 | clojurebot | [(1 2 3) (3 2 1)] |
| 04:33 | hiredman | flip is not in core though :( |
| 04:35 | hiredman | oh |
| 04:53 | tomoj | clojure.contrib.http.agent gives me an InputStream for the response body |
| 04:53 | tomoj | I wrap this in an InputStreamReader and then a PushbackReader |
| 04:53 | tomoj | reading from the PushbackReader gives -1 (eof) immediately |
| 04:53 | tomoj | while if I don't wrap and just read from the InputStream, I get the expected bytes from the response body |
| 04:53 | tomoj | ideas? |
| 04:55 | tomoj | oh, actually, that's not what's happening |
| 04:55 | tomoj | it's just that calling stream inside the handler gives a different input stream, and that input stream eofs immediately for some reason |
| 04:55 | tomoj | hmm |
| 05:22 | ordnungswidrig | *knock* *knock* |
| 06:04 | Licenser | wow they've free wifi at the airport wooh! |
| 06:06 | wooby | wooties |
| 06:07 | wooby | http://gist.github.com/221336 fruits of the evenings efforts |
| 06:11 | adityo | wooby: cool |
| 06:11 | arsatiki | wooby: since keywords act as functions, you can just say (map :leg triangles) |
| 06:15 | ysmolsky | how to get access to meta reader data from runtime? |
| 06:16 | wooby | arsatiki: oh awesome thanks |
| 06:16 | ysmolsky | i want to pass function a to a function b and from inside of the function b to read actual reader meta data of function a |
| 06:21 | Licenser | clojure is really really dense, I'm impressed I've started to write a map application as web page and it has < 200 lines |
| 06:22 | Licenser | hmm since there are two ways to access map keys (:key map) and (map :key) which is the preffered one? |
| 06:23 | ysmolsky | which is read better in the context i guess |
| 06:25 | Licenser | hmm so no guideline |
| 06:28 | ysmolsky | (defn a [x] x) |
| 06:28 | ysmolsky | (defn b [fun] (extract real name of "fun", arguments "fun" has, return it)) |
| 06:28 | ysmolsky | (b a) -> {:name "a", :args [x]} |
| 06:28 | ysmolsky | how do i make function b? :) |
| 06:31 | Chousuke | you can get the args via reflection, but you can't get the name in all cases |
| 06:32 | Chousuke | (b (fn [] foo)) <- what is the name? :) |
| 06:32 | ysmolsky | i need only for non anonymous cases. just cannot figure out how to make without macros. |
| 06:32 | arsatiki | ysmolsky: if you have access to the var, then you can find the information inside the metadata |
| 06:33 | ysmolsky | i know, but how to access it? |
| 06:33 | ysmolsky | (defn expand-method [m] |
| 06:33 | ysmolsky | (let [mmeta ^#'m] |
| 06:33 | ysmolsky | mmeta)) |
| 06:33 | ysmolsky | gives me exception: Unable to resolve var: m in this context |
| 06:33 | Chousuke | that won't work :) |
| 06:34 | Chousuke | var takes a symbol as a parameter. it's not evaluated |
| 06:34 | ysmolsky | ah.. well, which direction to look for? |
| 06:34 | Chousuke | I must first question the purpose of this endeavour ;) |
| 06:35 | Chousuke | you really shouldn't depend on the names of things :/ |
| 06:35 | ysmolsky | ok. answer will be long. i want to make life easy for one who will use my rpc server, so one can pass just functions to the server fun like this: |
| 06:35 | ysmolsky | (create-jsonrpc {:host "localhost" |
| 06:35 | ysmolsky | :port "3000" |
| 06:35 | ysmolsky | :methods [foo bar baz]}) |
| 06:36 | Chousuke | and they need to know those "foo" "bar" "baz" strings? |
| 06:36 | ysmolsky | after that i need to create map like name of function to real functions symbols |
| 06:36 | ysmolsky | those foo bar are funtcions |
| 06:36 | Chousuke | symbols? why symbols? |
| 06:36 | Chousuke | why not just the functions? :P |
| 06:37 | ysmolsky | oh not symbols, but functions |
| 06:37 | ysmolsky | just to be able to call them by the "string" |
| 06:37 | Chousuke | right. so pass in a map of name -> fn instead |
| 06:38 | ysmolsky | i know, but i like challenges :) |
| 06:38 | Chousuke | there's no way for you to win this challenge |
| 06:38 | arsatiki | or you could pass the vars :methods [#'foo #'bar ...] |
| 06:38 | arsatiki | but that is sucky. |
| 06:38 | Chousuke | and would fail with anonymous functions. |
| 06:39 | Chousuke | just let the user pass in a map |
| 06:39 | arsatiki | yeah |
| 06:39 | Chousuke | that way, it'll be more flexible. |
| 06:39 | ysmolsky | i see. just wanted to get know how far reflection of clojure goes :) |
| 06:39 | Chousuke | functions don't know their names because in most cases they don't have one. |
| 06:39 | ysmolsky | ok |
| 06:39 | Chousuke | or might have multiple. or one name might map to multiple functions. |
| 06:40 | Chousuke | (because of closures) |
| 06:40 | Licenser | ysmolsky: do you have a page about your RPC server? |
| 06:40 | Licenser | I'd be interested in such a thing |
| 06:40 | ysmolsky | anyway, i still to get to know the count of arguments of the function. is there a way? |
| 06:40 | Chousuke | you can use reflection for that. |
| 06:40 | Chousuke | it's tricky though. |
| 06:40 | ysmolsky | Licenser: not yet, but i will drop url here when its in github |
| 06:41 | Chousuke | I think chouser had some code for it somewhere. |
| 06:41 | Licenser | thanks |
| 06:41 | Chousuke | clojurebot: pastes |
| 06:41 | clojurebot | No entiendo |
| 06:41 | Chousuke | hm |
| 06:42 | arbscht | a function doesn't necessarily have one count of arguments |
| 06:42 | Chousuke | yeah. |
| 06:42 | ysmolsky | i know that i could just try to apply whatever user send to function and see if it thrown exception, but, it would be great to know it in advance.. or maybe not |
| 06:43 | ysmolsky | ok, i will try exception way for the beginning |
| 06:44 | Chousuke | using reflection involves taking advantage of implementation details, too, so I guess the exception method is safer. |
| 06:44 | Licenser | what is your JSON RPC based on? Restful HTTP? |
| 06:46 | ysmolsky | well, i want to make 1st version more general, but i'm planning to add restful too .. |
| 06:47 | ysmolsky | do you have any example of well designed restful lib for java/python? |
| 06:48 | Licenser | Nope sadly not but I was thinking about something like that, a easy way to export resources / functions on a REST interface |
| 06:49 | shmichael | Hello everyone. I am trying to test if symbols in my code are macros. I tried writing a macro? function. |
| 06:49 | shmichael | (defn macro? [exp] (-> exp var meta :macro)) |
| 06:50 | shmichael | This yields #<CompilerException java.lang.Exception: Unable to resolve var: exp in this context (NO_SOURCE_FILE:265)> |
| 06:51 | ysmolsky | hehe, same problem |
| 06:51 | shmichael | If I explicitly use a specific symbol, the expression is valid |
| 06:51 | shmichael | ,(-> let var meta :macro) |
| 06:51 | clojurebot | true |
| 06:51 | Licenser | ysmolsky: but this is clojure you don't need to bother about java or pyhtin |
| 06:53 | ysmolsky | Licenser: just.. I have never used restful libs, so gotta to see how thats done in popular libs, not only python or java, maybe ruby, whatever actually |
| 06:53 | Chousuke | shmichael: the var special form doesn't evaluate its argument, which is your problem |
| 06:53 | Chousuke | shmichael: you're always asking for the var named "exp" |
| 06:53 | shmichael | Chousuke: Is this a flaw in var or am I doing something wrong? |
| 06:53 | Chousuke | shmichael: it's not a flaw in var |
| 06:53 | Chousuke | shmichael: you need to make your macro? a macro :) |
| 06:54 | Chousuke | OR you can have it take a symbol as an argument |
| 06:54 | Licenser | ysmolsky: my idea was basing it on compojure you can create a REST-Full HTTP frontend with that |
| 06:55 | Chousuke | like: (defn names-a-macro? [sym] (-> (resolve sym) meta :macro)) |
| 06:55 | Chousuke | ,(:macro ^(resolve '->)) |
| 06:55 | clojurebot | true |
| 06:55 | Chousuke | ,(:macro ^(resolve 'foo)) |
| 06:55 | clojurebot | nil |
| 06:55 | Licenser | back when I tried I had barely any idea of clojure or compojure so it went horrible wrong, I quite to work with clojure for 2 weeks :P |
| 06:55 | ordnungswidrig | Licenser: uh, I hear REST on top of compojure. Did I miss anything? Is there still a library? |
| 06:55 | Licenser | hm? |
| 06:55 | ordnungswidrig | s/still.*y/a library yet/ |
| 06:56 | shmichael | Chousuke: thanks, I will try it out |
| 06:56 | Licenser | Compojure is needed to take care of the HTTP part, (you can use anything else too I guess) but the REST protocoll is up to the user to implement |
| 06:57 | Licenser | you can just use the default compojure routes to make a restufll interface |
| 06:57 | ordnungswidrig | Licenser: do you know erlang's webmachine? |
| 06:57 | Licenser | ordnungswidrig: nope, never worked with erlang |
| 06:57 | ysmolsky | Licenser: I see your point. when I will have some general json rpc server I can add more specified solutions.. |
| 06:57 | Licenser | ysmolsky: mongodb and with that somniums mongodb driver for clojure might be interesting |
| 06:57 | ordnungswidrig | Licenser: making a correct restful interface is hard. implementing correct HTTP is hard. compojure / ring are very basic. |
| 06:58 | ordnungswidrig | Licenser: Take a look at webmachine, at least at the monster flow diagram. |
| 06:58 | ordnungswidrig | Licenser: this was very enlighting to me. |
| 06:58 | ordnungswidrig | Licenser: http://bitbucket.org/justin/webmachine/wiki/WebmachineMechanics |
| 06:58 | ordnungswidrig | Licenser: http://bitbucket.org/justin/webmachine/wiki/BigHTTPGraph |
| 06:59 | Licenser | I know that it's hard but it wraps the webserver icely for clojure quite nicely |
| 06:59 | Licenser | :P |
| 06:59 | ordnungswidrig | Licenser: yes, but the decision on E-Tag, how to negotiate content-types and so on is what compojure doesn't for you. |
| 07:00 | Licenser | I've no idea what E-Tag is :P |
| 07:00 | Licenser | and yes that's true |
| 07:01 | Licenser | ordnungswidrig: good greif that is a graph |
| 07:01 | ordnungswidrig | Licenser: You see, speaking good HTTP is very hard. I'm doing web based development for 10+ years now. I remember a time where the only interaction was something like a "query" field in HTML and CGI for the NCSA server. Yet, since webmachine I know I spoke only a whimsy dialect of pidgin HTTP. |
| 07:02 | shmichael | OK, for the record here is my macro? implementation: |
| 07:02 | shmichael | (defmacro macro? [exp] (if (symbol? exp) `(:macro ^(resolve '~exp)) false)) |
| 07:03 | Licenser | ordnungswidrig: I know HTTP is horrible complex |
| 07:03 | ordnungswidrig | Licenser: for a project I'm currently sketching a REST library on top of compojure. For every resource you define some multimethods which represent the decision nodes in webmachines graph. |
| 07:04 | Licenser | oi cool will it be OpenSource? |
| 07:05 | ordnungswidrig | Licenser: so, for a simple resource which is available with GET in a singe content type, you'll be able to do sth. like |
| 07:06 | ordnungswidrig | (defmethod clojure-rest/content-types-provided ::article |
| 07:06 | ordnungswidrig | [_ _ _] |
| 07:06 | ordnungswidrig | { "text/html" (fn [_ request context] |
| 07:06 | ordnungswidrig | (let [id (urldecode ((request :route-params ) :id))] |
| 07:06 | ordnungswidrig | (str "Hello, article no." id ". The message is: " ( context :message ) )))}) |
| 07:06 | ordnungswidrig | |
| 07:06 | wooby | ordnungswidrig: are you doing it state machine style? |
| 07:06 | Licenser | looks nice |
| 07:07 | ordnungswidrig | wooby: I try to avoid state ;-) The "context" will be passed along when working on a request |
| 07:08 | Licenser | hmm isn't one of the 'issues' with http that it is stateless? |
| 07:08 | avital- | ,(symbol? let) |
| 07:08 | clojurebot | java.lang.Exception: Can't take value of a macro: #'clojure.core/let |
| 07:08 | ordnungswidrig | Licenser: Btw. I'll be happy when I pushed the whole shebang to github and I merge the first improvement from a person completely foreign to me. Yes, it will be opensource. At least I hope it will be good enough. |
| 07:08 | ordnungswidrig | Licenser: yes, http is stateless |
| 07:09 | ordnungswidrig | Licenser: what do you mean by issue? Positive or negative? |
| 07:09 | Licenser | That depends on what you do :P |
| 07:09 | Licenser | somtimes it is negative, sometimes positiv |
| 07:09 | ordnungswidrig | Licenser: you started the issue on stateless, so you decide :-) |
| 07:09 | wooby | Licenser: a state machine is an abstraction of a system that transitions between various 'states' |
| 07:10 | Licenser | and glad to hear that, I'll look into it once it is gitted |
| 07:10 | Licenser | ordnungswidrig: what I mean is, it isn't either negative nor positve in general, at least not in my eyes :P that sometimes is a issue, then it's negative |
| 07:10 | ordnungswidrig | wooby: If you want, it is a statemachine. But a DAG of states. And the state is held by the "instruction pointer" :-) |
| 07:10 | Licenser | and sometimes it does not matter then it's positive |
| 07:10 | wooby | lol |
| 07:11 | wooby | ordnungswidrig: thanks, i like the idea now ;) |
| 07:11 | ordnungswidrig | wooby: a state machine in the sense of "very-big-bunch-of-ifs-and-conds" |
| 07:12 | ordnungswidrig | to unknot the pile-of-ifs I'm looking still for a good abstraction. Something like an Either Monad. |
| 07:13 | Licenser | ordnungswidrig: you're from germany? |
| 07:14 | wooby | maybe a like a formal grammar, which your request handler evaluates input against? |
| 07:14 | avital- | ,(resolve 'map) |
| 07:14 | clojurebot | #'clojure.core/map |
| 07:15 | ordnungswidrig | Licenser: Neu-Ulm, Germany |
| 07:15 | avital- | ((fn [map] (resolve 'map)) 2) |
| 07:15 | Licenser | We should start to make a german Clojure community, you're the 3rd german I find here |
| 07:15 | hoeck1 | Licenser: +1 |
| 07:15 | Licenser | then hoeck1 is the 4th I find :P |
| 07:16 | avital- | ,((fn [map] (resolve 'map)) 2) |
| 07:16 | clojurebot | #'clojure.core/map |
| 07:16 | wooby | i too am from germany |
| 07:17 | hoeck1 | Licenser: sth like a clojure-de channel would be nice, but I suspect it would get much traffic |
| 07:17 | wooby | born in munster, moved to US when 2, more fluent in clojure than german :\ |
| 07:18 | Licenser | Poor you wooby ;) you missed out on some darn good ruladen |
| 07:18 | ordnungswidrig | wooby: have a look at webmachines http diagramm. currently the imlementation is like (if-not (valid-method? resource request context) [501 "not implemented"] (if-not (content-type-accepted? resource request context) [415 "Unsupported media type"] (generate-body resource request context))) |
| 07:19 | ordnungswidrig | btw +1 for a german clojure user group geclug |
| 07:19 | Licenser | hoeck1: noone stops us to make a clojure-de channel but all the smart guys hang out here so I'm not sure if it would make much sense |
| 07:19 | hoeck1 | Licenser: exactly |
| 07:19 | Licenser | or we teach them german |
| 07:20 | ordnungswidrig | Licenser: that'll be harder than lerning some clojure |
| 07:20 | Licenser | true |
| 07:20 | Licenser | we could make a clojure to german translator in clojure |
| 07:20 | ordnungswidrig | anybody know how to set the line width in ERC? |
| 07:26 | hoeck1 | ordnungswidrig: maybe: m-x customize-variable [ret] erc-fill-column |
| 07:28 | ordnungswidrig | hoeck1: let's set 123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789.123456789. |
| 07:28 | ordnungswidrig | |
| 07:28 | ordnungswidrig | hurray |
| 07:28 | ordnungswidrig | is there a state-monad available in clojure? |
| 07:29 | wooby | you could do that fairly simply, no? |
| 07:30 | ordnungswidrig | wooby: i'm lazy :) |
| 07:30 | Chousuke | ordnungswidrig: clojure.contrib.monads |
| 07:31 | ysmolsky | tests facility was moved to clojure.core? |
| 07:32 | wooby | awesome, state-m-until |
| 07:34 | Chousuke | ysmolsky: yes. |
| 07:34 | Chousuke | it's now clojure.test |
| 07:40 | gerry_ | (deftype person [name age]) |
| 07:41 | gerry_ | (person "gerry" 18) |
| 07:41 | gerry_ | java.lang.StackOverflowError |
| 07:41 | gerry_ | ?? |
| 07:42 | gerry_ | hello to all |
| 07:44 | Chousuke | is that the new deftype? |
| 07:45 | Chousuke | heh. |
| 07:45 | gerry_ | yes |
| 07:46 | gerry_ | i dont know what's wrong |
| 07:47 | ordnungswidrig | ok, paredit together with viper is somewhat confusing |
| 07:48 | gerry_ | (doc deftype) |
| 07:48 | gerry_ | ------------------------- |
| 07:48 | gerry_ | clojure.core/deftype |
| 07:48 | gerry_ | ([name [& fields] & [[& interfaces] & methods]]) |
| 07:48 | gerry_ | Macro Dynamically generates compiled bytecode for an anonymous class with the given fields, and, optionally, interfaces and methods. The Name will be used to create a dynamic type tag keyword of the form :current.ns/Name. This tag will be returned from (type an-instance). |
| 07:48 | clojurebot | "clojure.contrib.types/deftype;[[type-tag constructor-name docstring? attr-map?] [type-tag constructor-name docstring? attr-map? constructor] [type-tag constructor-name docstring? attr-map? constructor deconstructor]]; Define a data type by a type tag (a namespace-qualified keyword) and a symbol naming the constructor function. Optionally, a constructor and a deconstructor function can be given as well, the defaults being |
| 07:48 | gerry_ | A factory function of current.ns/Name will be defined, overloaded on 2 arities, the first taking the designated fields in the same order specified, and the second taking the fields followed by a metadata map (nil for none) and an extension field map (nil for none). |
| 07:48 | gerry_ | See defclass for a description of methods and generated interfaces. Note that overriding equals and hashCode is not supported at this time for deftype - you must use the generated versions. |
| 07:50 | gerry_ | clojurebot? ;( |
| 07:51 | gerry_ | any ideas? |
| 07:52 | ordnungswidrig | is there a if-not-let |
| 07:56 | gerry_ | no |
| 07:56 | gerry_ | if-let not work? |
| 07:57 | ordnungswidrig | gerry_: yes, but there is a if-not as well. but I look for something else: |
| 07:58 | raek | what is the preferred way to convert a string to an int? |
| 07:58 | adityo | Integer/parseInt |
| 07:58 | raek | (Integer/decode s) ? |
| 07:58 | raek | kthx |
| 07:58 | wooby | ,(read-string "5352") |
| 07:58 | clojurebot | 5352 |
| 07:59 | raek | ah, that's neat |
| 07:59 | raek | ,(read-string "900000000000000000000000000000000000000") |
| 07:59 | clojurebot | 900000000000000000000000000000000000000 |
| 08:00 | hoeck1 | gerry_: the type creation works, but the printing fails |
| 08:00 | raek | ,(Integer/parseInt "900000000000000000000000000000000000000") |
| 08:00 | clojurebot | java.lang.NumberFormatException: For input string: "900000000000000000000000000000000000000" |
| 08:00 | adityo | cool |
| 08:00 | gerry_ | hoeck1: type not support print yet? |
| 08:02 | ordnungswidrig | gerry_: if have a test function that returns [true, value] or [false, value] and I'd like to handle it nicely. (foo test if-form else-form) where if-form and else-form are beeing passed the value. |
| 08:02 | hoeck1 | gerry_: it should be printed somehow, so I think its a bug |
| 08:02 | ysmolsky | ,(BigInteger. "990") |
| 08:02 | clojurebot | 990 |
| 08:02 | ysmolsky | (BigInteger. "abc" 16) |
| 08:03 | ysmolsky | ,(BigInteger. "abc" 16) |
| 08:03 | clojurebot | 2748 |
| 08:03 | ysmolsky | ,(BigInteger. "ff123") |
| 08:03 | ysmolsky | ,(BigInteger. "ff123") |
| 08:03 | clojurebot | java.lang.NumberFormatException: For input string: "ff123" |
| 08:03 | ysmolsky | BigInteger is faster than read-string |
| 08:04 | gerry_ | Person |
| 08:04 | gerry_ | #<user$Person__22 user$Person__22@1a897a9> |
| 08:04 | gerry_ | type can be printed, but not for objects |
| 08:05 | gerry_ | (Person 1 1) => got stackoverflowerror |
| 08:07 | gerry_ | hoeck1: right, object exists,i can test it |
| 08:07 | gerry_ | (def me (Person "gerry" 18)) |
| 08:08 | gerry_ | (:age me) -> 18 |
| 08:09 | hoeck1 | you also could do a (defmethod print-method :user/person [the-person writer] (print-method (str the-person) writer)) |
| 08:10 | raek | hmmm, I can't get my clojure script working |
| 08:10 | raek | it just quits without printing anything |
| 08:10 | gerry_ | hmm, permethod for perobject |
| 08:11 | adityo | ,(time (Float/parseFloat "123.75243")) |
| 08:11 | clojurebot | 123.75243 |
| 08:12 | clojurebot | "Elapsed time: 0.222 msecs" |
| 08:12 | raek | what are the differences between an ordinary clojure program and a clojure script? |
| 08:12 | adityo | ,(time (read-string "123.75243")) |
| 08:12 | clojurebot | 123.75243 |
| 08:12 | clojurebot | "Elapsed time: 0.19 msecs" |
| 08:13 | ambient | raek there are differences? |
| 08:13 | ysmolsky | adityo: dont' benchmark on single call |
| 08:14 | raek | like (ns your-ns (:gen-class)) and (defn -main [& args] ...) |
| 08:14 | adityo | ysmolsky: true! |
| 08:14 | raek | but I don't know if I have to use those |
| 08:14 | tomoj | if you want an executable jar, you do |
| 08:15 | raek | oh, wait |
| 08:15 | raek | java -cp clojure.jar clojure.lang.Script script.clj |
| 08:15 | raek | not |
| 08:15 | raek | java -cp clojure.jar clojure.lang.Script < script.clj |
| 08:15 | tomoj | clojure.main |
| 08:17 | raek | ok, got it working now |
| 08:17 | hoeck1 | gerry_: it seems that the problem is, that there is no print-method defined for the generated type |
| 08:17 | raek | thank you all |
| 08:18 | gerry_ | hoeck1: yes |
| 08:18 | hoeck1 | gerry_: and the :default print-method tries to remove the :type tag from the object |
| 08:18 | gerry_ | oh? |
| 08:19 | hoeck1 | gerry_: for which type would then return a java object, so it could be printed at least as a plain java object |
| 08:19 | jagguli | adityo, G0SUB: hi |
| 08:20 | gerry_ | (deftype [#^int age]) |
| 08:20 | hoeck1 | gerry_: but the generated type has no :type attribute and so the :default print-method is invoked again trying to remove the type-tag ... stackoverflow |
| 08:20 | G0SUB | jagguli |
| 08:20 | gerry_ | java.lang.IllegalArgumentException: Wrong number of args passed to: core$deftype (NO_SOURCE_FILE:0) |
| 08:20 | gerry_ | oops |
| 08:21 | gerry_ | (deftype a [#^int age]) |
| 08:21 | gerry_ | java.lang.UnsupportedOperationException: Can't type hint a primitive local (NO_SOURCE_FILE:22) |
| 08:21 | gerry_ | primitive int cant be type hint |
| 08:22 | gerry_ | hoeck1: ic |
| 08:22 | gerry_ | does deftype support primitive fields? |
| 08:28 | adityo | jagguli: hey |
| 08:29 | gerry_ | defclass Person [name age]) |
| 08:29 | gerry_ | nil |
| 08:29 | gerry_ | user=> (new Person "gerry" 18) |
| 08:29 | gerry_ | java.lang.IllegalArgumentException: Unable to resolve classname: Person (NO_SOURCE_FILE:24) |
| 08:31 | chouser | gerry_: I think for deftype you just call Person as a function to create new ones |
| 08:32 | gerry_ | chouser: yes, but for defclass i have to use new |
| 08:34 | gerry_ | need i compile it at first or something? |
| 08:34 | hoeck1 | gerry_: for defclass, yes |
| 08:35 | gerry_ | hoeck1: so i need put it into one clj file, and compiling it before using it? |
| 08:35 | hoeck1 | gerry_: right, just like gen-class |
| 08:39 | gerry_ | from datatypes wiki, deftype could support primitive type and imporove perf , is that right? |
| 08:42 | chouser | gerry_: I think that's right. |
| 08:42 | gerry_ | but deftype not support primitive type hints |
| 08:44 | chouser | I see that. I think it's probably just a bug. |
| 08:46 | gerry_ | chouser: deftype and defclass still underway, so it's not a bug :) |
| 08:47 | gerry_ | maybe not finished yet |
| 08:48 | chouser | well, sure. but I mean I think the support is there and there was probably a small oversight that is breaking it |
| 08:49 | gerry_ | include type object printing |
| 08:58 | fabe | hi |
| 08:59 | fabe | im currently learning clojure and found the http://clojure.org/Atoms example confusing |
| 08:59 | ysmolsky | how to thrown exception of custom class from clojure? |
| 09:00 | chouser | ysmolsky: avoid it if possible, otherwise you have to create your custom class using gen-class and compile ahead-of-time. |
| 09:00 | fabe | it suggestes the memoizer momoized the call before (def fib (memoize fib)) |
| 09:01 | chouser | ysmolsky: there are also a couple compromise solutions in contrib: condition, error-kit, except |
| 09:02 | chouser | fabe: that example tries out 'fib' once before it's memoized so you can see how long it would normally take. |
| 09:02 | chouser | oh, you mean that the first call after 'memoize' is already faster? Did you try it yourself? |
| 09:04 | ysmolsky | ok. what is the best way to wrap situation like this? i thought about returning keywords like this to replace situation when keyword cannot be found: |
| 09:04 | ysmolsky | (defn fun-dispatch [table] |
| 09:04 | ysmolsky | (fn [method args] |
| 09:04 | ysmolsky | (if-let [f (table method)] |
| 09:04 | ysmolsky | (apply f args) |
| 09:04 | ysmolsky | :notfound))) |
| 09:05 | fabe | i know what it does im juste saying its easy to missunderstand it |
| 09:08 | chouser | ysmolsky: returning 'nil' is pretty common. The 'get' function allows you to pass in a "not-found" value to return instead if you want to detect the difference between nil and not-found. |
| 09:09 | rhickey | gerry_: fixed |
| 09:09 | gerry_ | cool |
| 09:12 | gerry_ | rhickey: type object printing seems not fixed? |
| 09:13 | gerry_ | i still got stackoverflowerror |
| 09:14 | chouser | he fixed the primitive support |
| 09:14 | gerry_ | yes, i just tried it |
| 09:19 | ysmolsky | how do you think reading Seibel's PCL worth anything applied to clojure? does it have some pattern or idioms useful for clojure programmer? |
| 09:20 | gerry_ | ysmolsky: that's for cl, i don't think that's much helpful, but just my personal thought |
| 09:22 | gerry_ | and if you compare cl and common lisp syntax, you will hate verbose of common lisp :) |
| 09:22 | faux | ysmolsky: http://blog.thinkrelevance.com/2008/09/16/pcl-clojure |
| 09:26 | gerry_ | s/clojure/cl |
| 09:26 | gerry_ | s/cl/clojure oops |
| 09:26 | gerry_ | :) |
| 09:36 | gerry_ | (-> me :meta :type) => nil |
| 09:36 | gerry_ | (:type me) => nil |
| 09:36 | chouser | gerry_: (type me) ? |
| 09:37 | gerry_ | :usr/Person |
| 09:44 | AWizzArd | I try to start slime with the NEW branch of Clojure. I get: java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (pprint.clj:1) |
| 09:44 | AWizzArd | What does this mean? |
| 09:44 | chouser | AWizzArd: it means you need to rebuild contrib and other libs you may be trying to load |
| 09:46 | AWizzArd | ok |
| 09:49 | AWizzArd | Maybe Clojure Contrib is not compatible with the current NEW branch? |
| 09:50 | chouser | oh, right. sorry. http://groups.google.com/group/clojure-dev/browse_thread/thread/91ca1a8b524b7349?hl=en |
| 09:50 | chouser | so for now just don't use contrib. |
| 09:50 | AWizzArd | One example Exception: Name conflict, can't def deftype because namespace: clojure.contrib.pprint.PrettyWriter refers to:#'clojure.core/deftype (PrettyWriter.clj:51) |
| 09:51 | gerry_ | deftype name conflict exists |
| 09:51 | AWizzArd | yes, I see |
| 09:52 | AWizzArd | but well, for testing purposes I could just modify my own checkout of contrib, maybe by fully qualifying those few cases |
| 09:53 | chouser | or just add (:refer-clojure :exclude [deftype]) |
| 09:53 | ysmolsky | what special name can i use to test that this file is being run through clojure.main? something *...* |
| 09:57 | jdz | ,(find-doc "compiling") |
| 09:57 | clojurebot | ------------------------- clojure.core/*compile-files* nil Set to true when compiling files, false otherwise. ------------------------- clojure.core/gen-class ([& options]) Macro When compiling, generates compiled bytecode for a class with the given package-qualified :name (which, as all names in these parameters, can be a string or symbol), and writes the .class file to the *compile-path* directory. When not compiling, d |
| 10:12 | AWizzArd | Is there already a code example of where deftype is used? |
| 10:18 | gerry_ | i think no |
| 10:20 | gerry_ | you may use it as defstruct at least |
| 10:24 | haptiK | hi |
| 10:25 | AWizzArd | rhickey: I tried: (deftype person [name age]) And when I then do (person 1 2) I get: No message. [Thrown class java.lang.StackOverflowError] |
| 10:26 | gerry_ | :) |
| 10:27 | chouser | AWizzArd: printing doesn't work at the moment. do (def p (person 1 2)) then you can use p, just don't print it. |
| 10:28 | lpetit | chouser: can printing already be extended via protocols ? :-) |
| 10:30 | chouser | heh |
| 10:33 | chouser | (defmethod print-method :user/Person [o w] (.write w (str "#<Person " (:title o) " " (:age o) ">"))) |
| 10:37 | AWizzArd | yes |
| 10:38 | rhickey | printing is todo |
| 10:39 | rhickey | will eventually be a protocol once there are protocols |
| 10:40 | AWizzArd | rhickey: In my tokenization module I had to make only small fixes at two places and got a 40% speedup. Thank you!! *handshaking* |
| 10:40 | rhickey | so, today I think even less of ASsociative support being the default. If I still had defstruct available I'd probably have a 3rd version deftype/class/struct, although you might want expando classes and types. In any case, I think opt in might be better than opt out |
| 10:40 | rhickey | AWizzArd: that's great! |
| 10:41 | rhickey | AWizzArd: this vs defstructs? |
| 10:41 | AWizzArd | In other places I still use maps instead of deftyped objects, so I can speed up it even more. So far the results look all correct and I can't see a problem. |
| 10:41 | AWizzArd | Yes |
| 10:41 | chouser | AWizzArd: you're using deftype or defclass? |
| 10:41 | AWizzArd | The main container was changed. In the next days I can try to replace other throw-away objects by types. Looks really promising I must say. |
| 10:42 | AWizzArd | deyftype |
| 10:42 | AWizzArd | deftype |
| 10:42 | chouser | so cool. |
| 10:42 | AWizzArd | I just don't have so much time today, and it already took some time to get Slime running, and to compile contrib. But now I made the most obvious test. |
| 10:43 | cemerick | AWizzArd: whoa, good to know |
| 10:43 | AWizzArd | deftype/defclass is exactly the functionality we needed to speed up the very important core routines. Now I will see where I can stil use it. |
| 10:44 | AWizzArd | But this is a real nice speedup, with basically no real changes. |
| 10:44 | cemerick | rhickey: can I lobby you for a deftype-time flag or somesuch, rather than the conj > assoc, getx morass? |
| 10:45 | rhickey | cemerick: ? |
| 10:45 | cemerick | rhickey: w.r.t. opt-in expando |
| 10:46 | rhickey | opt-in just means that deftype won;t give you expando by default, but when you get expando (how tbd) it will be just like now (which is just like defstruct) |
| 10:46 | rhickey | no morass |
| 10:46 | gerry_ | AWizzArd: do you use primitive type in your module with deftype? |
| 10:48 | shmichael | I'm trying to check performance for an implementation of a fibonacci sequence. However, it seems I am not getting a linear computation time. |
| 10:48 | shmichael | (def fib (lazy-seq (for [x (iterate inc 0)] (if (< x 2) x (+ (nth fib (- x 2)) (nth fib (- x 1))))))) |
| 10:48 | shmichael | This is odd, since lazy-seq should cache values |
| 10:49 | shmichael | On the other hand, the following implementation demonstrates linear time: |
| 10:49 | shmichael | (def fib-seq (lazy-cat [0 1] (map + (rest fib-seq) fib-seq))) |
| 10:49 | jdz | shmichael: nth is linear time |
| 10:49 | jdz | shmichael: and you have 2 of them |
| 10:49 | AWizzArd | gerry_: well, as I understand it deftype gives my indeed a pojo. But I did not have to write a .java file. |
| 10:49 | chouser | In (lazy-seq (for ...)), lazy-seq isn't doing anything for you. 'for' already returns a lazy seq |
| 10:50 | shmichael | jdz: that would make the running time 2n |
| 10:50 | AWizzArd | Before deftype I had to write a class in Java for my short lived objects. I need to create millions of those, and it just is a bit expensive to create the powerful Clojure structs. |
| 10:50 | jdz | shmichael: not if you do that for every next number in your sequence |
| 10:52 | shmichael | jdz: Agreed. So I have to use a hash-map? |
| 10:52 | jdz | shmichael: why? why don't you use the second version you pasted? |
| 10:53 | shmichael | jdz: Because I'm trying to understand all the nooks and crannies |
| 10:53 | shmichael | It's just educational |
| 10:55 | rhickey | primitives don't help deftype when used with :field access |
| 10:56 | cemerick | oh, that's a good point |
| 10:56 | chouser | maybe help with memory usage or cache lines, just not avoiding box/unbox? |
| 10:56 | cemerick | rhickey: does that change with the planned case support? |
| 10:56 | AWizzArd | better (. field my-object)? |
| 10:56 | cemerick | no, probably not |
| 10:57 | chouser | AWizzArd: yes, but you only get that with defclass not deftype |
| 10:57 | chouser | (.field my-objecT) |
| 10:57 | rhickey | primitives might help inside any methods defined |
| 10:57 | rhickey | cemerick: which help, primitives? - no, case is about the keyword lookup |
| 11:00 | gerry_ | rhickey: could i just compile defclass in repl with (compile (defclass ...)) and not put it to file? |
| 11:01 | gerry_ | shortcut compile |
| 11:03 | rhickey | gerry_: that's not how compile works |
| 11:05 | gerry_ | put compiled class file to default/setting Dir and i can use it just like in java.lang or something alike? |
| 11:06 | rhickey | gerry_: I don't want to talk about premature optimization :) |
| 11:07 | gerry_ | just my fancifulness :) |
| 11:09 | rhickey | so, I can auto-gen accessors even for deftype, that internally use .field, for another 15-20% boost, but would like to do that with deterministic names, like Foo-a, Foo-b etc rather than make you do that manually or having a bunch of naming options |
| 11:09 | rhickey | at that point there might not be a significant benefit to case, or even to .field directly |
| 11:10 | rhickey | the only caveat being that on re-eval, the Foo-a accessors will no longer work on old instances |
| 11:11 | rhickey | does anyone want this? |
| 11:13 | cemerick | hard to know at this point. The re-eval issue is unfortunate, since deftype should be re-eval safe otherwise. |
| 11:15 | rhickey | cemerick: right, it is otherwise (but old instances won't have new fields etc), of course no one is forcing you to call these |
| 11:15 | gerry_ | 15-20% boost is worth |
| 11:16 | rhickey | but I imagine this explicit accessor use might be limited to module internals... still won't help old instances |
| 11:17 | cemerick | of course, the first thing I'd do is redef Foo-a to just about anything else. ;-) |
| 11:18 | rhickey | cemerick: like what? |
| 11:19 | srader | no way to have .field access with deftype? |
| 11:19 | cemerick | rhickey: hrm, perhaps not. There'll likely be multiple types in each namespace. I've got my head stuck in gen-class. |
| 11:19 | rhickey | srader: no |
| 11:20 | rhickey | srader: but this accessor Foo-a I have been talking about will do that for you |
| 11:21 | srader | the speed up sounds good |
| 11:21 | rhickey | CL has a :conc-name option to set a prefix (other than the default struct name) for all accessors |
| 11:23 | cemerick | yeah, I vaguely remember a bewildering set of options for defclass in CL |
| 11:23 | rhickey | cemerick: oh yeah, defclass even worse than defstruct |
| 11:24 | cemerick | I thankfully only lost ~6 mo. to that years ago. |
| 11:24 | rhickey | but standard names have value in that they are predictable, given a Type T you know how to create/access |
| 11:25 | cemerick | definitely. I'm always a little shy of autogenerated names, though of course it's unavoidable sometimes. |
| 11:25 | rhickey | well, I've got it written already, so I'll put them in |
| 11:26 | rhickey | would like so input on how people would like to opt-in for Associative/struct-map-like |
| 11:26 | rhickey | some input |
| 11:27 | AWizzArd | Could this be a parameter for deftype? :eval-safe true |
| 11:33 | rhickey | AWizzArd: what would that mean? |
| 11:34 | notallama | a choice between the fast version and the reeval-safe version, i'm assuming |
| 11:35 | AWizzArd | The auto-generated accessors that you can offer even with deftype that internally use .field |
| 11:36 | rhickey | notallama: :field is re-eval safe, accessors wrapping :field when eval-safe? |
| 11:36 | rhickey | I hate having lots of options |
| 11:37 | rhickey | and the most important right now is opt-in for expando |
| 11:38 | AWizzArd | so you will keep the :field accessor |
| 11:38 | rhickey | AWizzArd: oh yes, this is not instead of that |
| 11:38 | AWizzArd | k, that is configurable enough imo |
| 11:40 | rhickey | Foo:a for accessors? so when you want to speed up (:field x) code just do (Foo:field x) |
| 11:41 | chouser | I still have an inappropriate affinity for little bits of syntax like that. |
| 11:41 | rhickey | chouser: is that a positive statement? :) |
| 11:42 | chouser | heh |
| 11:42 | AWizzArd | So (:field x) will make a little lookup and (.field x) will only work for the latest evaled version, but may be 10-20% faster. |
| 11:43 | rhickey | AWizzArd: .field is not a deftype feature |
| 11:43 | rhickey | (Foo:field x) |
| 11:44 | chouser | (user/Foo:field x) ? |
| 11:44 | chouser | oh, sure it's still just in whatever namespace, so either wya |
| 11:44 | chouser | way |
| 11:44 | rhickey | chouser: outside of the namesapce, yes |
| 11:45 | srader | why not just have :field use the accessor function? |
| 11:46 | ordnungswidrig | is it good style for a function to return either a string or a map? The function will be passed as a handler-type-function in my rest library. |
| 11:47 | ordnungswidrig | a handler-function shall be allowed to either return a body or a map with {:headers {..} :body the-body-value} |
| 11:47 | rhickey | srader: (:field x) ==> (get x :field), it's inherently a lookup |
| 11:48 | ordnungswidrig | the calling function will have to analyze the type of the returned value. This smells, I think. But I have no better idea. |
| 11:48 | gerry_ | (Foo-field x) maybe better ,x:y:z could be reserved |
| 11:48 | cemerick | rhickey: the question is, do you have other, better plans for colon-delimited symbols? |
| 11:48 | cemerick | I do like the colon better than a dash. |
| 11:49 | AWizzArd | so, (Foo:field x) for a deftype would be as efficient like a (.field x) for a defclass? |
| 11:49 | rhickey | AWizzArd: tbd if HotSpot does something different with them, one being wrapped |
| 11:50 | AWizzArd | Can you make (Foo:field x) also available for defclasses? |
| 11:50 | rhickey | cemerick: opened up a while ago - http://clojure.org/reader - "A symbol can contain one or more non-repeating ':'s." |
| 11:50 | AWizzArd | cemerick: yes, I also like the colon better. |
| 11:56 | The-Kenny | hm... will it be possible to use defclass in the repl? (Without compiling the sources etc.) |
| 12:01 | rhickey | The-Kenny: use deftype |
| 12:02 | rhickey | does someone want to do simple (non-readable) print while I do case? |
| 12:15 | mikehinchey | rhickey: I have a patch that fixes contrib, by adding exclude deftype to all of the broken namespaces. Would that be easier than getting individual authors? |
| 12:16 | rhickey | mikehinchey: sure, I'll try it |
| 12:16 | rhickey | could you please post it on assembla? |
| 12:17 | djork_ | ,"yay for clojurebot from my phone" |
| 12:17 | clojurebot | "yay for clojurebot from my phone" |
| 12:17 | djpowell | I'm a bit confused. (.field o) currently works on deftype instances. Is that just an accident? |
| 12:18 | rhickey | djpowell: that will use reflection |
| 12:18 | rhickey | and thus be much slower than (:field o) |
| 12:18 | djpowell | ah - cause o can't easily be type hinted once it crosses function boundaries and stuff? |
| 12:19 | djpowell | cause it uses an anonymous class |
| 12:19 | rhickey | djpowell: the type is anonymous, generated anew each time you evaluate the deftype |
| 12:20 | djpowell | yeah, I see now |
| 12:22 | rhickey | so more syntax options for those playing along: |
| 12:23 | rhickey | case will basically look like this: |
| 12:23 | rhickey | (case x |
| 12:23 | rhickey | :k (foo) |
| 12:23 | rhickey | :j (bar) |
| 12:23 | rhickey | (baz)) |
| 12:23 | chouser | yummy |
| 12:23 | rhickey | where :j and :k can be at leasy symbols/keywords/string, but possibly others like vectors etc |
| 12:24 | rhickey | however sometimes you want more than one constant to map to the same outcome |
| 12:24 | rhickey | thus they need to be grouped |
| 12:24 | mikehinchey | rhickey: I put it on assembla for clojure, exclude-deftype.patch |
| 12:25 | rhickey | mikehinchey: thanks! |
| 12:25 | rhickey | mikehinchey: where? |
| 12:25 | rhickey | oh, assembla for clojure, not contrib? |
| 12:26 | mikehinchey | yes, contrib would have made more sense |
| 12:27 | chouser | do you have a plan for how the deftype obj will hook into print-method |
| 12:27 | djpowell | sry, what is case? is this something related to deftype? |
| 12:29 | chouser | rhickey: like will deftype types all derive from :clojure.core/deftype? or just provide .toString on the deftype? |
| 12:30 | Chousuke | what about C-switch-style fall-through for case? The proposed syntax wouldn't support it, but... hmm. |
| 12:30 | rhickey | mikehinchey: applied -thanks very much! |
| 12:30 | Chousuke | it'd get repetitive to write (case :x a :y a :z :a :w :b :default) |
| 12:30 | Chousuke | with the actual variable there :P |
| 12:31 | hiredman | so :z :a :w :b all fall through? |
| 12:32 | mikehinchey | rhickey: you're welcome |
| 12:32 | Chousuke | no |
| 12:32 | rhickey | chouser: should be inside the deftype/defclass, generate print-method based on type tag or class respectively |
| 12:32 | Chousuke | hiredman: I meant you should have been able to write something like (case x [:x :y :z] a, ...) |
| 12:32 | Chousuke | but that would mean x can |
| 12:32 | Chousuke | can't be a vector |
| 12:33 | rhickey | chouser: in general, it will be bad to base anything off of implementation detail class of generated deftype/classs since they are being used by users to define classes with their own semantics |
| 12:35 | AWizzArd | rhickey: will this case construct be used for hashes? |
| 12:35 | chouser | rhickey: ok, so a custom defmethod for each deftype |
| 12:35 | rhickey | chouser: I think so |
| 12:36 | rhickey | there can be some implementation helper function |
| 12:36 | chouser | sure |
| 12:36 | rhickey | (print-me me fields) |
| 12:37 | rhickey | should just print #:Foo{:a 1 :b 2 :c 3 :extra1 4 :extra2 5} |
| 12:37 | rhickey | so, back to case: |
| 12:37 | rhickey | (case x |
| 12:37 | rhickey | (:i :k) (foo) |
| 12:37 | rhickey | :j (bar) |
| 12:37 | rhickey | (baz)) |
| 12:38 | rhickey | here, is (:i :j) a single data structure or a group of 2 keys? |
| 12:38 | rhickey | presuming we definitely want case for vectors if any aggregate |
| 12:39 | Chousuke | what about a set? |
| 12:39 | Chousuke | does order matter if the end result is going to be the same? |
| 12:39 | djork | just curious here. what's the case for having both (:foo some-map) and (some-map :foo) be valid |
| 12:39 | rhickey | Chousuke: whatever aggregate is used for grouping will no longer be available for switching |
| 12:40 | rhickey | djork: well, some maps are not keyed by keywords, so you have to have (map akey) |
| 12:40 | djork | right |
| 12:41 | Chousuke | and :foo as a function works for sets/java maps too, right? |
| 12:41 | djork | or can a keyword be a function of other types? |
| 12:41 | rhickey | but some maps are used more like objects than collections, where (field-of x) makes more sense than (find-in-x key) |
| 12:42 | hiredman | a keyword can be a function of any ILookup, right? |
| 12:43 | AWizzArd | rhickey: one option for case could be to add explicit separators. That may be useful anyway to make it visually more clear where the "when" part is and where the "then" part is. |
| 12:43 | rhickey | AWizzArd: sounds icky |
| 12:43 | hiredman | ~def c.l.RT |
| 12:43 | Raynes | Is there anyway to 'unuse' something in the REPL? |
| 12:44 | hiredman | around like 616 is the get method keywords use |
| 12:44 | AWizzArd | Raynes: you an ns-unmap things |
| 12:44 | rhickey | hiredman: right now the promise is vague |
| 12:44 | Raynes | Thanks. :) |
| 12:44 | chouser | (case x (:a a) (:a :b :c a-or-b-or-c)) |
| 12:45 | hiredman | not overspecified |
| 12:45 | rhickey | actually it promises get, but I'd like to narrow that |
| 12:45 | rhickey | chouser: aargh, the grouping parens are back! |
| 12:45 | rhickey | I got rid of them everywhere else |
| 12:45 | chouser | yes. but only one level -- don't others do 2? |
| 12:46 | chouser | no, I hate it nevermind. |
| 12:46 | chouser | at least use vectors there if anything |
| 12:46 | chouser | (case x [:a a] [:a :b :c a-or-b-or-c]) |
| 12:46 | Chousuke | yeah. looks like function calls :( |
| 12:46 | rhickey | chouser: I hate always grouping like that |
| 12:47 | rhickey | so, let's presume we want to avoid it |
| 12:47 | rhickey | It's a matter of sacrificing some data structure, sets or lists would be prime candidates in my book |
| 12:48 | rhickey | (case x |
| 12:48 | rhickey | #{:i :k} (foo) |
| 12:48 | rhickey | :j (bar) |
| 12:48 | rhickey | (baz)) |
| 12:49 | rhickey | we haven't used sets as syntax yet |
| 12:52 | gerry_ | if x itself is one set? |
| 12:52 | rhickey | gerry_: you wouldn't be able to case on sets |
| 12:53 | wooby | it's cool to be a fly on the wall and watch awesomeness unfold, the case form looks fantastic |
| 12:54 | gerry_ | then, use sets not bad |
| 12:58 | chouser | #{#{:i :k}} could match a set |
| 12:58 | chouser | in which case I'd vote for vectors instead |
| 12:58 | chouser | and suddenly this sounds very familier. |
| 12:59 | chouser | (case [:a :b] [[:a :b] [:b :c]] ab-or-bc) |
| 13:01 | rhickey | chouser: how would you match a set of one set/ vector of one vector? |
| 13:01 | mikehinchey | or: (case [:a :b] ([:a :b] [:b :c]) ab-or-bc) |
| 13:01 | chouser | like (case [[:a]] ...) right? |
| 13:01 | Raynes | I thought deftype was in Clojure now? |
| 13:02 | chouser | Raynes: 'new' branch only |
| 13:02 | rhickey | right |
| 13:02 | Raynes | Oh, I see. |
| 13:02 | AWizzArd | (case x [:a -> 1] [:b -> 2] [:c :d -> 3] [[:x :y] -> 4] [[1 2 #{3 4}] :clojure -> 5]) |
| 13:02 | chouser | I know I've done this, I just can't find where. |
| 13:02 | rhickey | Raynes: snatch latest contrib as well |
| 13:03 | Raynes | rhickey: Already did. :) |
| 13:03 | chouser | anyway, the logic is: case will wrap an implied [] around every test expression unless it's already a vector |
| 13:03 | chouser | so, (case [[:a]] [[[:a]]] got-it) |
| 13:03 | mikehinchey | I meant: (case :a a ([:a :b] [:b :c]) ab-or-bc) - the () doesn't conflict with any data structure |
| 13:04 | chouser | mikehinchey: it conflicts with lists. plus it looks like you're looking something up in the [:a :b] vector unless you look carefully to see this is an unevaluated from in a case expression. |
| 13:04 | chouser | unevaluated form in a case form |
| 13:04 | rhickey | chouser: I know we've had this conversation before, but I wouldn't want to have to explain that |
| 13:05 | chouser | I just explained it. one line! |
| 13:05 | chouser | :-) |
| 13:05 | chouser | I guess that might be an argument for using literal set intead of vector -- just less likely you'll be using it for anything other than grouping your tests. |
| 13:06 | mtm | hmm, I'm not seeing deftype in my latest pull from github; is this on a different branch than 'master'? |
| 13:06 | chouser | one way of looking at it is that you can pretend that collection type can't be matched, but if you really need to you actually can do it. |
| 13:06 | rhickey | chouser: the problem is (case [[:a]] [[[:a]]] got-it) will haveto be explained over and over, even if it is one line |
| 13:06 | somnium | (case x :a : 1 :b : 2 [:c :d] : 3 #{:e :f} : :g) |
| 13:06 | rhickey | but yes, I see sets as much less likely |
| 13:07 | chouser | maybe inside case "," is not whitespace. |
| 13:07 | chouser | :-) :-) |
| 13:07 | chouser | (case x :a 1, :b 2, :c :d :e 3) |
| 13:10 | rhickey | chouser: so, set of one set to match a set? |
| 13:11 | rhickey | all questions go to you? :) |
| 13:11 | rhickey | using sets, it may never come up |
| 13:11 | chouser | they all do anyway, don't they? ;-) |
| 13:11 | chouser | right |
| 13:12 | chouser | with vectors people are going to trip over it |
| 13:12 | chouser | ...be surprised that (case [:a :b] [:a :b] match) fails |
| 13:12 | Licenser | hmm a curiose question, the clojure book says: Clojure does not optimize tail recursion because java can't do that. But as it strikes me can't the optimisation be done before java ever sees the bytecode? |
| 13:13 | rhickey | chouser: I think so, vectors probably the most popular aggregate-as-key |
| 13:13 | chouser | rhickey: right. |
| 13:13 | chouser | lists would not match vectors in a case? |
| 13:14 | Raynes | mtm: It's on the 'new' branch. |
| 13:14 | chouser | (case x '(:a) :list [:a] :vector) ? |
| 13:14 | rhickey | actually they will, it will be based on hash for table lookup, then equals for confirmation |
| 13:14 | mtm | Raynes: thanks |
| 13:14 | Raynes | Hrm. It appears that the new branch breaks slime. |
| 13:14 | Raynes | Or kind of breaks something related to slime. |
| 13:14 | kefka | I've got a question: what Errors can be thrown by a clojure function (assume I haven't created new Exception or Error classes) that should not be caught, but require process shutdown? |
| 13:15 | kefka | OutOfMemoryError is obviously fatal, while StackOverflowError is not, for example. |
| 13:15 | rhickey | chouser: the quote not need - keys are unevaluated, must be constants |
| 13:15 | kefka | (the fn that caused the StackOverflow is terminated, but the process keeps running) |
| 13:15 | rhickey | but who uses lists? |
| 13:15 | chouser | Licenser: yes, clojure could take some occurances of self-calls and turn them into 'recur'. But it would make (foo a b) behave differently depending on where it appears in a single function -- would actually be *more* confusing that current behavior. |
| 13:16 | ordnungswidrig | kefka: anything that extends java.lang.Error is considered unrecoverable |
| 13:16 | Licenser | hmm so how is tail call optimisation actually done usually? |
| 13:16 | Licenser | and chouser thanks for the answer ;) |
| 13:16 | chouser | rhickey: if lists match vectors, then lists could actually be used for grouping tests -- the only drawback then being it looks like a call. |
| 13:16 | rhickey | I knew you would say that :) |
| 13:16 | mikehinchey | :) |
| 13:16 | chouser | rhickey: of course you did. |
| 13:17 | rhickey | that was the first grouping example I posted, but you didn't take the bait |
| 13:17 | mikehinchey | and if lists are unevaluated, not used for grouping, they also look strange |
| 13:18 | somnium | would the set notation only be used to distinguish groupings? (case x :a 1 :b 2 #{:c :d} 3 :e 4)? |
| 13:18 | kefka | ordnungswidrig: How unrecoverable? For example, if a thread goes off and does a computation, and that computation throws StackOverflowError, the computation should die, but does the whole process need to be killed? |
| 13:19 | chouser | arg. gah. grrrr. () is better than the other options is so many ways... |
| 13:19 | chouser | in so many |
| 13:19 | Raynes | http://gist.github.com/221618 with 'new' Clojure. It then polls slime forever. Not sure if I'm the only one who got this. Just throwing it out there. |
| 13:20 | chouser | (case x (one-of :a :b) a-or-b) |
| 13:20 | chouser | hehe |
| 13:20 | ordnungswidrig | kefka: javadoc says: "An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it. " |
| 13:20 | chouser | Raynes: welcome to the experimental branches. -) |
| 13:20 | rhickey | chouser: I think a lot of the groups will look like obvious non-functions -> (:a :b :c) ([1 2] [3 4]) |
| 13:21 | Raynes | chouser: I'm not complaining. Just letting you guys know that it does that, in case you didn't know about it. :) |
| 13:21 | chouser | I think AWizzArd said he got slime working |
| 13:23 | mikehinchey | Raynes: slime works for me, but my swank-clojure is old. is it looking for pprint, or something else in contrib? |
| 13:23 | ordnungswidrig | kefka: this might be enlighting: http://stackoverflow.com/questions/951635/how-to-handle-stackoverflowerror-in-java/951672#951672 |
| 13:23 | chouser | fn arity overloads, letfn, proxy, defclass, deftype, case |
| 13:23 | kefka | ordnungswidrig: Thanks |
| 13:23 | Raynes | mikehinchey: I think so. |
| 13:25 | kefka | ordnungswidrig: And certainly the point is relevant that AssertionFailedErrors and StackOverflowErrors won't occur in reasonable code. |
| 13:25 | kefka | On the other hand, I don't want to do a System shutdown when they occur. |
| 13:26 | ordnungswidrig | What is the recommented cure against let/if/let/if/let staircasing? |
| 13:26 | drewr | ordnungswidrig: there's if-let |
| 13:27 | drewr | if you're staircasing that then you probably need to break your fn apart |
| 13:27 | Licenser | hrm fnparse is broken :/ |
| 13:27 | chouser | got it. double parens. that looks even less like a fn call |
| 13:27 | ordnungswidrig | drewr: can if-let destructurize? |
| 13:27 | chouser | (case x ((:a :b)) aorb) |
| 13:27 | chouser | or maybe (case x ([(:a :b)]) aorb) |
| 13:28 | Chousuke | ergh |
| 13:28 | drewr | ,(if-let [foo false] :foo :bar) |
| 13:28 | clojurebot | :bar |
| 13:28 | drewr | ,(if-let [[foo bar] [false true]] :foo :bar) |
| 13:28 | clojurebot | :foo |
| 13:28 | krumholt | hi i have a question. i wanted to make a stream that only one agent would print on. i implemented it like this http://paste.lisp.org/display/89509 the agents value is the stream it should write on. but it is not writing on the correct stream. can anyone see an obvious error? |
| 13:28 | somnium | what if one is an expression? (case x (((:a {:a 1}))) 2) ? |
| 13:28 | drewr | ordnungswidrig: it depends on what you're trying to express |
| 13:28 | ordnungswidrig | ,(if-let [[foo bar] [false :qux]] bar :baz) |
| 13:28 | clojurebot | :qux |
| 13:29 | ordnungswidrig | ,(if-let [[foo bar] [true :qux]] bar :baz) |
| 13:29 | clojurebot | :qux |
| 13:29 | mikehinchey | Raynes: did you get the recent commit for contrib to fix for new? |
| 13:29 | chouser | krumholt: use 'binding' not 'let' |
| 13:30 | krumholt | i'll try that |
| 13:30 | chouser | rhickey: I gotta get lunch, but think on ([()]) ...it'll grow on you, I'm sure of it. |
| 13:31 | Raynes | mikehinchey: Yep. |
| 13:31 | ordnungswidrig | drewr: I have (let [[t val] (f)] (if-not t :fail (let [[t val2] (g val)] (if t :fail-other val2)))) |
| 13:31 | AWizzArd | if you want to allow case that it can on the one hand allow complex structures as keys, such as the vector [1 2 3], but on the other hand also allow the user to list many keys on which a "then" part can fire, then a separating construct would be needed. |
| 13:32 | rhickey | AWizzArd: not so, see above |
| 13:32 | hiredman | it occurs to me that a MetaException might be useful |
| 13:33 | djpowell | hmm, defclass can't extend classes? is that temporary? |
| 13:33 | hiredman | an exception that supports the alter-meta! |
| 13:33 | hiredman | (I'd really like to get rid of ReaderException) |
| 13:34 | krumholt | is it possible that if you use (println) in an agent it is not printing to *out*? |
| 13:35 | mikehinchey | rhickey: a quoted vector or set? so the case macro looks for quote. Or maybe ~ unquote would be more clear. |
| 13:35 | hiredman | *out* might have a different value in the thread the agent action is running on |
| 13:36 | AWizzArd | A very efficient (case ...) construct might get us a step closer to pattern matching. |
| 13:36 | rhickey | mikehinchey: then you can't match a list starting with quote |
| 13:36 | hiredman | AWizzArd: you've seen the match macro? |
| 13:37 | krumholt | hiredman: i thought of that and did (binding [*out* my-stream] ...) in the agent but it's still printing to the wrong stream |
| 13:37 | AWizzArd | hiredman: no |
| 13:37 | mikehinchey | but unquote isn't legal unless the macro looks for it to use it |
| 13:37 | hiredman | ~google clojure pattern matching |
| 13:37 | clojurebot | First, out of 1700 results is: |
| 13:37 | clojurebot | brool » Pattern Matching In Clojure |
| 13:37 | clojurebot | http://www.brool.com/index.php/pattern-matching-in-clojure |
| 13:38 | mikehinchey | (case x :a a ~[:b :c] b-or-c) |
| 13:38 | rhickey | (case '(unquote ...) ...) |
| 13:39 | rhickey | a copiler might have that |
| 13:39 | rhickey | compiler |
| 13:39 | AWizzArd | anyway, i was aiming a bit at the efficiency. |
| 13:40 | AWizzArd | rhickey: would this case construct be used in conjunction with perfect hashes? |
| 13:45 | drewr | ordnungswidrig: I don't immediately see a way to clean that up |
| 13:45 | Licenser | Woooh I managed to join the google group with my own email address |
| 13:51 | Licenser | ordnungswidrig: does (f) always return only 2 values? |
| 13:57 | fabe | hi |
| 13:58 | fabe | how do i best access a value of a primitave java array? |
| 13:58 | somnium | ,(doc aget) |
| 13:58 | somnium | ,(doc aget) |
| 13:58 | clojurebot | "([array idx] [array idx & idxs]); Returns the value at the index/indices. Works on Java arrays of all types." |
| 13:59 | chouser | fabe: http://clojure.org/java_interop#toc27 |
| 13:59 | fabe | thx |
| 14:10 | somnium | is it possible to define type-overloaded methods with gen-class? |
| 14:11 | somnium | or only object || one type hint? |
| 14:14 | Fossi | clojurebot: gen-class |
| 14:14 | clojurebot | No, Fossi, you want gen-interface + proxy |
| 14:14 | Fossi | somnium: there you have it ;) |
| 14:17 | somnium | :) |
| 14:18 | somnium | I can't wait for 1.1 ... |
| 14:19 | Raynes | (doc aget) |
| 14:19 | clojurebot | "([array idx] [array idx & idxs]); Returns the value at the index/indices. Works on Java arrays of all types." |
| 14:20 | Raynes | somnium: When doing (doc ..), it appears you can leave out the comma. |
| 14:21 | somnium | ah, creature of habit I guess |
| 14:21 | wooby | trying to compile fnparse, get "Could not find clojure.lang.Compile" whilst clojure.jar is most definitely on my classpath... anyone know whats up? |
| 14:24 | somnium | I think someone else mentioned that ^^ |
| 14:28 | duncanm | hmm, how do i use condp again? |
| 14:28 | duncanm | ,(let [s "foo"] |
| 14:28 | duncanm | (condp #(.equals s %2) |
| 14:28 | duncanm | "foo" "Win" |
| 14:28 | duncanm | :else "Lose")) |
| 14:28 | clojurebot | EOF while reading |
| 14:28 | duncanm | hmm |
| 14:28 | duncanm | why didn't that work? |
| 14:29 | duncanm | in emacs, i get :else |
| 14:29 | somnium | he can't handle newlines |
| 14:29 | duncanm | oh |
| 14:29 | duncanm | , (let [s "foo"] (condp #(.equals s %2) "foo" "Win" :else "Lose")) |
| 14:29 | clojurebot | :else |
| 14:29 | duncanm | oh |
| 14:30 | duncanm | aha |
| 14:30 | duncanm | ,(let [s "foo"] (condp #(.equals s %2) s "foo" "Win" :else "Lose")) |
| 14:30 | clojurebot | "Win" |
| 14:31 | rhickey | ,(let [s "foo"] (condp = s "foo" "Win" :else "Lose")) |
| 14:31 | clojurebot | "Win" |
| 14:31 | duncanm | oh nice |
| 14:33 | rhickey | ,(let [s "foo"] (condp = s "foo" "Win" "Lose")) |
| 14:33 | clojurebot | "Win" |
| 14:33 | duncanm | heh |
| 14:33 | rhickey | ,(let [s "foops"] (condp = s "foo" "Win" "Lose")) |
| 14:33 | clojurebot | "Lose" |
| 15:00 | duncanm | is there a reason why I can't use vars this way? http://gist.github.com/221708 |
| 15:00 | duncanm | it says Exception in thread "main" java.lang.IllegalArgumentException: Invalid assignment target (FileMonitor.clj:135) |
| 15:00 | duncanm | oh, there's a stray unref there, i was trying out refs |
| 15:04 | hiredman | duncanm: I am pretty sure set! is only for setting fields (java interop) |
| 15:04 | duncanm | hiredman: it says "Note - you cannot assign to function params or local bindings. Only Java fields, Vars, Refs and Agents are mutable in Clojure." |
| 15:04 | hiredman | yeah |
| 15:04 | duncanm | hiredman: for this sort of thing, what's the more idiomatic way of doing it? |
| 15:04 | hiredman | mutable doesn't mean you can use set! |
| 15:04 | duncanm | use a ref? |
| 15:05 | hiredman | what is workers? |
| 15:05 | hiredman | oh |
| 15:05 | duncanm | monitor and pyramid are SwingWorkers |
| 15:05 | hiredman | workers is nil |
| 15:05 | hiredman | nothing |
| 15:05 | hiredman | so you can do nothing to it |
| 15:05 | duncanm | oh, but if it's an empty list |
| 15:06 | hiredman | so? |
| 15:06 | hiredman | lists are immutable |
| 15:06 | duncanm | right |
| 15:06 | hiredman | and nil is not an empty list |
| 15:06 | hiredman | no is nothing |
| 15:06 | hiredman | nil |
| 15:07 | duncanm | hiredman: so what's the idiomatic way to do something like this in clojure? |
| 15:07 | wooby | hiredman: how do i start clojurebot? i'd like to run it on a different network |
| 15:07 | hiredman | wooby: rlwrap java -server -Djava.security.manager -cp $CLASSPATH:./clojurebot/ clojure.main -i clojurebot/hiredman/clojurebot.clj -r |
| 15:08 | namor | Is there a library to transform/simplify boolean terms in Clojure? |
| 15:08 | hiredman | duncanm: I don't know what you are doing |
| 15:08 | wooby | hiredman: thank you, is there some way to configure it? |
| 15:09 | duncanm | hiredman: i want to toggle these workers, when i call this function the first time, it'll start the workers, if i call it again, it'll terminate the workers |
| 15:09 | hiredman | wooby: clojurebot/hiredman/clojurebot.clj |
| 15:09 | Chousuke | duncanm: you need a global ref holding the workers |
| 15:09 | wooby | hiredman: got it, thanks again |
| 15:10 | hiredman | :( |
| 15:11 | hiredman | wooby: there is alot of #clojure specific stuff |
| 15:13 | hiredman | the list of all the required namespaces in clojurebot.clj are almost all different plugins, when you load the plugin's namespace it registers it wires in |
| 15:13 | hiredman | so by taking things out of that list, you can disable plugins |
| 15:13 | wooby | i see |
| 15:13 | wooby | it sure does a lot of stuff, holy crap man |
| 15:14 | hiredman | :D |
| 15:16 | hiredman | a lot of stuff is bit rot, like the svn stuff |
| 15:16 | hiredman | the twitter stuff, I should find something to do with clojurebot's twitter account |
| 15:18 | Chousuke | duncanm: http://gist.github.com/221716 something like this? |
| 15:18 | Chousuke | oops, forgot the stars from one 'workers' :/ |
| 15:19 | duncanm | Chousuke: i made it work without a global |
| 15:19 | Chousuke | well, a closed-over ref will do too I guess. |
| 15:19 | duncanm | Chousuke: http://gist.github.com/221718 |
| 15:19 | duncanm | right |
| 15:20 | Chousuke | those multiple dereferencing operations are somewhat dangerous |
| 15:20 | duncanm | Chousuke: why is that? |
| 15:21 | hiredman | you should turn the whole thing into a single transaction |
| 15:21 | wooby | hiredman: woo runninng! had to excise a lot of clojurebot's brain though |
| 15:21 | Chousuke | if you run the function simultaneously in multiple threads you will likely get a non-empty result from the first deref, but an empty one from the next. |
| 15:21 | hiredman | wooby: yeah |
| 15:21 | Chousuke | hiredman: can't. it has side-effects. |
| 15:21 | wooby | hiredman: it's awesome though, what a cool program, thanks |
| 15:21 | hiredman | Chousuke: send the side effects off to an agent |
| 15:22 | Chousuke | or you could just read the ref once so there's no problem :/ |
| 15:22 | hiredman | hmm |
| 15:23 | hiredman | or, you could make two functions |
| 15:23 | Chousuke | actually, I'm not sure if that model for queuing workers is good. |
| 15:23 | hiredman | one that returns a vector of spun up workers |
| 15:23 | Chousuke | it looks like you should use an agent or something :/ |
| 15:23 | hiredman | and another that spins down a vector of workers |
| 15:23 | Chousuke | and send it "stop" and "go" :P |
| 15:24 | duncanm | hmm, actually, it'd be fun to write a blog post detailing how to use the techniques of clojure's STM for writing GUI programs |
| 15:25 | hiredman | well, you can treat the EDT sort of like an agent |
| 15:25 | duncanm | hiredman, Chousuke: i'm sure what i'm doing now (having a toggle button that fires off some job) is a pretty common thing to do in GUI programs. |
| 15:25 | Chousuke | duncanm: I would use an agent for that. |
| 15:25 | Chousuke | or just a thread. |
| 15:25 | Chousuke | that runs and then dies. |
| 15:25 | duncanm | SwingWorker is some sort of thread, right? |
| 15:25 | hiredman | and you use blockingqueues for eventhandlers |
| 15:26 | Chousuke | is there a need to store the swingworkers somewhere? |
| 15:26 | hiredman | and you turn the events into an infinite lazy seq |
| 15:26 | duncanm | Chousuke: it's for cancelling the job |
| 15:26 | Chousuke | hm. |
| 15:26 | duncanm | hiredman: that reminds me of the Rx framework stuff Erik Meijer is doing for .NET |
| 15:26 | hiredman | yeah |
| 15:27 | hiredman | that is what made me do it :P |
| 15:27 | hiredman | clojurebot: hydra? |
| 15:27 | clojurebot | Pardon? |
| 15:27 | duncanm | hiredman: do you have some sketches of code for doing that? |
| 15:27 | duncanm | hiredman: i'd love to compile a list of 'best practices' for writing Swing code using Clojure |
| 15:27 | hiredman | duncanm: http://paste.lisp.org/display/87611 |
| 15:27 | Chousuke | duncanm: the toggling nature of the function just doesn't please me :P |
| 15:27 | hiredman | I dunno if it as a best practice |
| 15:27 | hiredman | I just think it's neat |
| 15:29 | duncanm | hiredman: looks interesting, i had a glance, but i need to look into it more deeply |
| 15:29 | duncanm | i'm new to all the Concurrency APIs in Java |
| 15:30 | hiredman | hydra is like a multicast que, you stick stuff in, and it comes out multiple places |
| 15:30 | hiredman | the fancy stuff is derefing a hydra produces an end point, which is an infite sequence of stuff that is put into the hydra |
| 15:31 | hiredman | and the hydra is an IFn, so you can all it as a function, and any arguments you pass it get put in the hydra |
| 15:32 | hiredman | there is a (uneeded) delay in there, but, meh |
| 15:32 | Chousuke | can you ever stop the queue? :P |
| 15:33 | hiredman | not as currently implemented |
| 15:36 | hiredman | so you just do filters, maps, and doseqs over the infinite sequence of events |
| 15:37 | duncanm | sigh, i feel like i'm such a naughty boy for writing all this code with SET!s |
| 15:38 | Chousuke | heh. |
| 15:38 | Chousuke | you'll get over it. |
| 15:38 | Chousuke | hopefully :P |
| 15:38 | duncanm | hiredman: i have this script that has a handful of globals, and I wrote an INITIALIZE! function, but now it says I can't use SET! to alter root bindings |
| 15:38 | hiredman | correct |
| 15:38 | hiredman | you can't use set! |
| 15:38 | hiredman | ever |
| 15:38 | duncanm | Chousuke: no, i know, i mean, i wrote Scheme before, but in Scheme, i don't get yelled at when I use SET! - i feel a bit dirty, but no yelling ;-P |
| 15:39 | hiredman | (except to set fields) |
| 15:39 | chouser | and thread-bound vars |
| 15:39 | duncanm | so i have to change them all to refs, and add deref to all the places that use the value |
| 15:39 | hiredman | chouser: :( |
| 15:39 | hiredman | duncanm: just don't mutate stuff |
| 15:40 | duncanm | hiredman: well, i want some state that's closed over a bunch of functions |
| 15:40 | hiredman | :( |
| 15:40 | Chousuke | heh. |
| 15:40 | duncanm | either i write all of them as internal defines, or i have to do this, right? |
| 15:40 | hiredman | state is bad |
| 15:41 | duncanm | hiredman: state is useful, it just needs to be managed properly (which i'm not doing) ;-P |
| 15:41 | Chousuke | with Clojure, the mutable stuff is (almost) all java. And who learns Clojure to write Java? :) |
| 15:41 | duncanm | Chousuke: i do ;-) i use clojure to write portable shell scripts ;-) |
| 15:41 | ambient | well, writing java with clojure is still better than writing java with java imho |
| 15:41 | hiredman | duncanm: no, managing state can help mitigate it, but it is still bad |
| 15:42 | Chousuke | it's also necessary :) |
| 15:42 | Chousuke | though people tend to use it even when it's not :/ |
| 15:43 | rhickey | aargh - contrib defines case! |
| 15:43 | chouser | rhickey: do you want deftype and defclass objects to print the same? |
| 15:43 | Chousuke | rhickey: :/ |
| 15:43 | duncanm | rhickey: stuartsierra's fcase.clj? |
| 15:43 | hiredman | contrib has a lot of stuff in it |
| 15:44 | rhickey | chouser: for now, sure, anything is better than stack overflow :) |
| 15:44 | Chousuke | Wonder if it'd help to segment the core namespace a bit? it's getting quite large :( |
| 15:44 | rhickey | duncanm: yep |
| 15:45 | chouser | rhickey: is there a way to opt out of IObj and ILookup? I'm not seeing it. |
| 15:45 | Chousuke | if you split it up, by default you could still import all the subnamespaces to keep compatibility... hm. |
| 15:45 | rhickey | chouser: there are no opts yet in or out |
| 15:45 | rhickey | but you can't rely on them |
| 15:45 | rhickey | since one out is just for user to define same interfaces |
| 15:45 | chouser | right, I think I'm relying on both and wanted to opt out to see the failure. |
| 15:46 | chouser | I'll hack it. thanks. |
| 15:47 | rhickey | you should have full access to the fields, and you will have access to the class by name while in those macros |
| 15:47 | rhickey | lots of the generated code does that |
| 15:47 | AWizzArd | is there a way to get a seq of all fields of a deftype? |
| 15:47 | rhickey | so it's not really anonymous for you. also can rely on __meta and __extmap |
| 15:48 | hiredman | AWizzArd: implement ISeq :P |
| 15:49 | rhickey | (deftype Foo [a b c]) |
| 15:49 | rhickey | (seq (Foo 1 2 3)) |
| 15:49 | rhickey | ([:a 1] [:b 2] [:c 3]) |
| 15:49 | chouser | that's exactly what I'm relying on now, and shouldn't. |
| 15:49 | rhickey | right |
| 15:50 | rhickey | there is also IDynamicType but you shouldn't need it |
| 15:50 | chouser | yep |
| 15:52 | chouser | __meta and __extmap may not exist, right? what do you mean I can rely on them? |
| 15:55 | rhickey | chouser: they will exist |
| 15:55 | chouser | even on defclass? |
| 15:55 | rhickey | they may not be used, but will be null |
| 15:55 | rhickey | chouser: yes, defclass no different in terms of expando and meta |
| 15:56 | chouser | ok, thanks. |
| 15:58 | chouser | but those fields are only accessible via reflection |
| 15:58 | wagjo | hi there, I'm trying to make a lazy seq, which returns characters from file. I open a file with (with-open [r (reader file)] .... ) but I don't know how to transform it into lazy seq, any hints? |
| 15:58 | wagjo | something like line-seq but returning individual characters instead of lines |
| 15:59 | chouser | wagjo: maybe something like (repeatedly #(.read r)) |
| 16:01 | hiredman | ((fn me [rdr] (lazy-seq (cons (.read rdr) (me rdr)))) r) |
| 16:02 | wagjo | thank you, gonna try |
| 16:02 | chouser | pretty much the same, aren't they? Neither quits at eof. |
| 16:03 | hiredman | yes |
| 16:04 | chouser | (take-while #(> % -1) (repeatedly #(.read r))) |
| 16:04 | chouser | (map char (take-while #(> % -1) (repeatedly #(.read r)))) |
| 16:04 | rhickey | chouser: which only by reflection? |
| 16:04 | chouser | (->> #(.read r) repeatedly (take-while #(> % -1)) (map char)) |
| 16:05 | chouser | rhickey: .__meta and .__extmap only by reflection |
| 16:05 | chouser | oh |
| 16:05 | chouser | no, you said I have the classname. |
| 16:05 | chouser | so I can hint to that. sorry. |
| 16:07 | rhickey | right |
| 16:08 | rhickey | although by doing so you'll have the same brittleness on re-eval |
| 16:09 | chouser | hm.. the old instances will have the old type, and so will use the old print-method. |
| 16:09 | rhickey | so better to rely on IMeta and IDynamicType/getExtensionMap for deftypes |
| 16:09 | rhickey | chouser: you should be binding the print method to type, not class, for deftypes |
| 16:09 | rhickey | i.e. the tag |
| 16:10 | chouser | oh. indeed I am. sheesh. You can see I barely have my head around this if at all. |
| 16:10 | rhickey | the type function ties into deftype types already |
| 16:10 | chouser | so: brittleness. |
| 16:10 | rhickey | will be gone if you use IMeta and IDynamicType/getExtensionMap for deftypes |
| 16:11 | chouser | so deftype and defclass instances can look the same (for now anyway) but should be generated differently |
| 16:11 | rhickey | you'll need IDynamicType/getDynamicField as well |
| 16:12 | chouser | defclass using direct hinted field access, deftype using IMeta (IObj?) and getExtensionMap |
| 16:12 | rhickey | chouser: yes |
| 16:12 | rhickey | getDynamicField will get you out of ILookup |
| 16:12 | rhickey | metadata will not be opt-outable I think |
| 16:13 | chouser | I can assume extmap has no keys that match a field? |
| 16:14 | rhickey | chouser: won't matter will it, for printing? |
| 16:14 | rhickey | you can just seq that onto the end |
| 16:15 | chouser | yep, np. |
| 16:16 | chouser | :-) |
| 16:19 | chouser | it's ok to assume deftypes implement IObj? |
| 16:19 | rhickey | IMeta |
| 16:20 | rhickey | should be enough |
| 16:20 | chouser | oh. sorry, had those swapped in my head |
| 16:20 | duncanm | chouser: i'm looking over your gist to me earlier, where's the test in the IF-LET form? |
| 16:20 | rhickey | yes, IMeta |
| 16:20 | duncanm | chouser: http://gist.github.com/221716 |
| 16:20 | chouser | duncanm: not me. Maybe Chousuke? |
| 16:21 | duncanm | oh sorry |
| 16:21 | duncanm | chouser: misfired ;-P |
| 16:21 | duncanm | Chousuke: ping |
| 16:21 | chouser | lowercase is insufficient apparently. ;-) |
| 16:21 | duncanm | i wonder when the videos from this year's JVM summit will be out |
| 16:23 | hiredman | duncanm: (seq @*workers*) is the test |
| 16:23 | hiredman | if let does something, and binds the result to a name, and then (if that-name something something-else) |
| 16:25 | duncanm | hiredman: is there a shorter form for writing this? http://gist.github.com/221780 |
| 16:25 | ordnungswidrig | how can I filter a map on the values? |
| 16:25 | duncanm | ordnungswidrig: use filter |
| 16:26 | duncanm | oh |
| 16:26 | duncanm | ,(vals {:a :b :c :d}) |
| 16:26 | clojurebot | (:b :d) |
| 16:26 | duncanm | like that |
| 16:26 | ordnungswidrig | duncanm: but I need a map |
| 16:27 | duncanm | you want to get {:b :d} back? |
| 16:27 | hiredman | if you call seq on the output of .listFiles you don't need to call empty? |
| 16:27 | kotarak | ,(into {} (filter (fn [[_ v]] (even? v)) {:a 1 :b 2 :c 4 :d 3})) |
| 16:27 | clojurebot | {:b 2, :c 4} |
| 16:27 | ordnungswidrig | kotarak: yes, like that |
| 16:27 | kotarak | ordnungswidrig: there you go. |
| 16:28 | duncanm | hiredman: why is that? |
| 16:28 | robewald | hi, what version of clojure does the API on the web refer to? |
| 16:28 | hiredman | ,(seq []) |
| 16:28 | duncanm | hiredman: oh well, it's okay, i'm fine with that function, i was hoping i can learn some new clojure idioms |
| 16:28 | clojurebot | nil |
| 16:29 | duncanm | hiredman: but i still have the method call .getAbsolutePath |
| 16:29 | hiredman | you could use juxt (my new favorite function) to get a pair of :width and :height instead of a map |
| 16:29 | hiredman | duncanm: correct |
| 16:30 | hiredman | ,(if (seq []) :foo :bar) |
| 16:30 | clojurebot | :bar |
| 16:30 | hiredman | ,(if (seq [1]) :foo :bar) |
| 16:30 | clojurebot | :foo |
| 16:30 | ordnungswidrig | kotarak: thanks |
| 16:30 | duncanm | how does juxt work? it's not in the api page |
| 16:30 | hiredman | ,(doc juxt) |
| 16:30 | clojurebot | "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]" |
| 16:31 | kotarak | ,((juxt inc dec) 2) |
| 16:31 | hiredman | dunno if that is an actual improvement |
| 16:31 | clojurebot | [3 1] |
| 16:31 | somnium | is there any obvious reason why this won't compile <- http://paste.lisp.org/display/89523 ? |
| 16:31 | robewald | or more specifically which git branch. SVN seems to be deprecated. |
| 16:31 | somnium | it compiles in slime, but when I do (compile ...) I get cannot create ISeq from Symbol ... |
| 16:31 | kotarak | hiredman: well, it generates 3 more functions: the one by juxt and #(.getWidth %) and #(.getHeight %).... |
| 16:32 | hiredman | kotarak: *shrug* |
| 16:32 | hiredman | rhickey: I have to ask, is there a reason there is no 'flip' in core? |
| 16:34 | rhickey | hiredman: have you needed it? |
| 16:34 | rhickey | I haven't |
| 16:34 | hiredman | hmmm |
| 16:34 | kotarak | What does flip do? |
| 16:34 | somnium | hiredman: I think there's one in contrib |
| 16:35 | hiredman | I wrote one, but yes, I don't think I really used it for anything |
| 16:35 | hiredman | kotarak: reverse the order of arguments |
| 16:35 | kotarak | ah ok. |
| 16:35 | hiredman | ,((flip /) 3 8) |
| 16:35 | clojurebot | 8/3 |
| 16:38 | hiredman | ,(pl (⌽/ 3 8)) |
| 16:38 | clojurebot | Invalid token: ⌽/ |
| 16:38 | hiredman | :( |
| 16:38 | hiredman | ,(pl (⌽vector 3 8)) |
| 16:38 | clojurebot | #<sandbox$uncurry__4597$uc__4599 sandbox$uncurry__4597$uc__4599@c64bc2> |
| 16:38 | hiredman | huh |
| 16:39 | hiredman | oh, right, wrong symbol |
| 16:39 | hiredman | ,(pl (↕vector 3 8)) |
| 16:39 | clojurebot | [8 3] |
| 16:39 | hiredman | and you wonder why all the symbols never caught on |
| 16:40 | ordnungswidrig | huh, there's unicode in my irc |
| 16:40 | kotarak | Es geschehen noch Zeichen und Wunder.. ;) |
| 16:40 | ordnungswidrig | ,(doc pl) |
| 16:40 | clojurebot | "([& forms]); replaces a $ b with (a b) walking right to left replaces a · b with (comp a b) left to right ⌽a with (uncurry a) left to right ↕a with (flip a) left to right" |
| 16:41 | hiredman | ~translate from de: Es geschehen noch Zeichen und Wunder |
| 16:41 | clojurebot | It happened before signs and wonders |
| 16:41 | ordnungswidrig | hiredman: that's translated a little too literally |
| 16:42 | kotarak | hehe |
| 16:42 | hiredman | ~translate to de: ok |
| 16:42 | clojurebot | OK |
| 16:43 | spuz | I'm looking at some clojure contrib code and I see a lot of ::state ::result etc. what does :: mean? |
| 16:43 | ordnungswidrig | hiredman: leo.org suggests "Well, Miracles do happen!" |
| 16:43 | hiredman | ,::state |
| 16:43 | clojurebot | :sandbox/state |
| 16:43 | hiredman | ,:state |
| 16:43 | clojurebot | :state |
| 16:43 | kotarak | hiredman: "There are still miracels and wonders..." maybe more useful translation. An exclamation if something improbable happens. |
| 16:44 | kotarak | ,`cons |
| 16:44 | clojurebot | clojure.core/cons |
| 16:44 | kotarak | ,'cons |
| 16:44 | clojurebot | cons |
| 16:44 | hiredman | :: namespace qualifies a keyword with the currect namespace |
| 16:44 | hiredman | it also lets you use alias |
| 16:45 | ordnungswidrig | kotarak: not necessarily improbable but sth. you don't expect to happen anymore. Like a decision of a municipal authority. |
| 16:45 | hiredman | if you foo.bar alias as bar in your current namespace, ::bar/foo will be :foo.bar/foo |
| 16:48 | somnium | does every function in a gen-class have to take a 'this argument or only methods? |
| 16:49 | kotarak | somnium: gen-class is independent of the namespace. Only methods take this. |
| 16:49 | somnium | kotarak: thank you. |
| 16:51 | somnium | I keep getting unable to resolve symbol this when I take them out of the non methods... |
| 16:52 | hiredman | well, uh, stop trying to use names you haven't bound to a value |
| 16:52 | kotarak | somnium: well, you use it there, you have to pass it as an argument. |
| 16:52 | somnium | ok, that's how it was, and it could load the namespace, but I got an error on (compile my-namespace) |
| 16:53 | lisppaste8 | Chouser pasted "deftype redef-and-print anomoly" at http://paste.lisp.org/display/89526 |
| 16:53 | kotarak | somnium: what might "an error" be? |
| 16:53 | hiredman | chouser: arraymap strikes again? |
| 16:53 | somnium | cannot create ISeq from Symbol, or vice versa |
| 16:54 | chouser | rhickey: is that good or would it be better to merge the extmap with the dynamicfields? |
| 16:54 | hiredman | well, stop trying to make an iseq from a symbol |
| 16:54 | kotarak | somnium: you quoted something, which you should not. probably somewhere in the ns clause |
| 16:54 | somnium | ah, I hope so :) |
| 16:55 | chouser | hiredman: nope, overlap between extmap and fields -- can't get there without chanding a deftype on the fly and then poking around at old objects. |
| 16:57 | hiredman | Oh |
| 16:58 | rhickey | chouser: I think it tells the user something important |
| 16:58 | chouser | ok. it's not entirely accurate -- I mean the value isn't actually stored twice. |
| 16:58 | somnium | kotarak: I'm sorry, I'm out of my depth. It compiles in slime but not with (compile). perhaps my mistake will be clear here? http://paste.lisp.org/display/89523 |
| 16:58 | chouser | Anyway, that works, including metadata, for deftype. |
| 16:58 | rhickey | looks nice, maybe we should elide the namespace/package for this non-readable print? |
| 16:59 | chouser | defclass isn't there yet. |
| 16:59 | chouser | ok. |
| 17:00 | chouser | I gotta go blow leaves around -- you want that patch as-is, or wait for defclass? |
| 17:01 | scottj | What higher level good alternatives are there to SQL? (in general, no specific application atm) |
| 17:02 | ordnungswidrig | what would be the easiest way to make a date string according to rfc1123 (used in SMTP/Mail and HTTP): Sun, 06 Nov 1994 08:49:37 GMT |
| 17:03 | ordnungswidrig | is there a lib or must I go via java? |
| 17:03 | hiredman | there is some java class |
| 17:03 | hiredman | simpl date formater? |
| 17:04 | hiredman | http://java.sun.com/javase/6/docs/api/java/text/SimpleDateFormat.html |
| 17:04 | ordnungswidrig | hiredman: I know the java :-) |
| 17:04 | hiredman | well, there you go |
| 17:05 | ordnungswidrig | hiredman: but I avoid it because I managed to go without calling java until now. But now is the time to learn how to do it. |
| 17:05 | somnium | scottj: there is contrib.sql and also higher level clojureql |
| 17:05 | hiredman | are you kidding me? |
| 17:05 | hiredman | calling java is nothing |
| 17:05 | chouser | rhickey: print-deftype.diff |
| 17:05 | chouser | rhickey: on clojure assembla. bbl. |
| 17:06 | ordnungswidrig | hiredman: a little :-) |
| 17:06 | rhickey | chouser: cool - thanks! |
| 17:07 | hiredman | ,(import '(java.text SimpleDateFormat)) |
| 17:07 | clojurebot | java.text.SimpleDateFormat |
| 17:09 | hiredman | ordnungswidrig: http://github.com/hiredman/clojurebot/blob/master/hiredman/clojurebot/github.clj has some date format snippets |
| 17:12 | ordnungswidrig | hiredman: I made it :-) http://gist.github.com/221836 |
| 17:31 | qed | mmmmm, map! |
| 17:32 | hiredman | ,(bean (Date.)) |
| 17:32 | clojurebot | {:seconds 43, :date 29, :class java.util.Date, :minutes 32, :hours 14, :year 109, :timezoneOffset 420, :month 9, :day 4, :time 1256851963466} |
| 17:34 | hiredman | ,(-> (Date.) bean ((juxt :date (comp (partial + 1900) :year) :month))) |
| 17:34 | clojurebot | [29 2009 9] |
| 17:37 | hiredman | ,(into {} (map (juxt class identity) '({} [] #{}))) |
| 17:37 | clojurebot | {clojure.lang.PersistentArrayMap {}, clojure.lang.PersistentVector [], clojure.lang.PersistentHashSet #{}} |
| 17:43 | wooby | (doc juxt) |
| 17:43 | clojurebot | "([f] [f g] [f g h] [f g h & fs]); Alpha - name subject to change. Takes a set of functions and returns a fn that is the juxtaposition of those fns. The returned fn takes a variable number of args, and returns a vector containing the result of applying each fn to the args (left-to-right). ((juxt a b c) x) => [(a x) (b x) (c x)]" |
| 17:43 | wooby | awesome |
| 17:47 | wooby | ,(juxt (+ 1) (+ 2) 3) |
| 17:47 | clojurebot | #<core$juxt__4916$fn__4934 clojure.core$juxt__4916$fn__4934@9458ea> |
| 17:47 | hiredman | ,((juxt (partial + 1) (partial + 2)) 3) |
| 17:47 | clojurebot | [4 5] |
| 17:47 | wooby | aha |
| 17:48 | ordnungswidrig | it's like map but applying a list of functions to a value instead of an function to a list of values? |
| 17:51 | kotarak | ,(map #(% 3) [(partial + 1) (partial + 2)]) |
| 17:51 | clojurebot | (4 5) |
| 17:51 | qed | what are partials |
| 17:52 | kotarak | qed: partial makes a new function function which calls the given function with the provided arguments + any additional arguments: ((partial + 1) 2) <=> (+ 1 2) |
| 17:53 | qed | kotarak: ahh i see |
| 17:53 | kotarak | (partial f arg1 arg2) is equivalent to #(apply f arg1 arg2 %&) |
| 17:54 | qed | thanks for that :) |
| 18:03 | wooby | ,(-> {:one {:two "X"}} (:one) (:two)) |
| 18:03 | clojurebot | "X" |
| 18:15 | rhickey | case is alive!! http://github.com/richhickey/clojure/commit/5ebed57e1d6d7dc8230fa51e6cd34e22dc1f3a42 |
| 18:16 | AWizzArd | yay, grats |
| 18:17 | AWizzArd | btw, I find it good that there now is case.. but I am curious why you added it now. Will it be of use for implementing Clojure in Clojure? |
| 18:17 | chouser | AWizzArd: deftype will use case internally for fast lookup when you do (:myfield deftype-obj) |
| 18:17 | kotarak | What is it with emacs, that it can't add a trailing newline? |
| 18:18 | AWizzArd | chouser: good |
| 18:19 | AWizzArd | kotarak: do you try it with Strg+o ? |
| 18:19 | kotarak | AWizzArd: what? |
| 18:20 | AWizzArd | kannst Steuerung + o drücken, das fügt eine neue Zeile ein |
| 18:21 | kotarak | AWizzArd: I don't use emacs. But I noticed that often files have only an incomplete line at the end, when they come from emacs users. |
| 18:21 | drewr | kotarak: yes, you have to hit return after adding a line at the end |
| 18:22 | drewr | you're talking about text files ending with \n instead of \n\n? |
| 18:22 | drewr | or no newline at all? |
| 18:23 | chouser | :-( case groups with () |
| 18:23 | AWizzArd | Why should they end with \n\n? From a windows pov I could understand \r\n. |
| 18:23 | kotarak | drewr: no newline at all |
| 18:23 | AWizzArd | chouser: can you show a minimal example? |
| 18:23 | kotarak | But this is rather off-topic. Just some observation. |
| 18:27 | rhickey | chouser: sorry |
| 18:29 | chouser | AWizzArd: (map #(case % (1 2) :a (3) :b 4 :c (5 6 7) :d :other) (range 10)) ==> (:other :a :a :b :c :d :d :d :other :other) |
| 18:31 | duncanm | it'd be nice if range can generating a descend seq |
| 18:31 | duncanm | s/generating/generate/ |
| 18:31 | AWizzArd | duncanm: maybe you can use iterate? |
| 18:32 | AWizzArd | ,(take 10 (iterate dec 20)) |
| 18:32 | clojurebot | (20 19 18 17 16 15 14 13 12 11) |
| 18:32 | duncanm | ah |
| 18:32 | cemerick | ,(range 10 0 -1) |
| 18:32 | clojurebot | (10 9 8 7 6 5 4 3 2 1) |
| 18:32 | duncanm | oh! |
| 18:32 | cemerick | ,(range 50 0 3/5) |
| 18:32 | clojurebot | () |
| 18:33 | wooby | ,(range 1 0 -0.1) |
| 18:33 | clojurebot | (1 0.9 0.8 0.7000000000000001 0.6000000000000001 0.5000000000000001 0.40000000000000013 0.30000000000000016 0.20000000000000015 0.10000000000000014 1.3877787807814457E-16) |
| 18:36 | kefka | ,(range 0 1 0.1) |
| 18:36 | clojurebot | (0 0.1 0.2 0.30000000000000004 0.4 0.5 0.6 0.7 0.7999999999999999 0.8999999999999999 0.9999999999999999) |
| 18:36 | wooby | strange |
| 18:37 | wooby | ,(map #(/ 10 %) (range 0 10 1)) |
| 18:37 | clojurebot | java.lang.ArithmeticException: Divide by zero |
| 18:38 | wooby | ,(map irc://irc.freenode.net/#(/ 10 %) (range 1 11 1)) |
| 18:38 | clojurebot | java.lang.ClassNotFoundException: irc://irc.freenode.net |
| 18:38 | chouser | (map #(case % 1 2 (map inc[1 2]) (range 3) (range 4) (+ 1 2) (inc x) :y) '(map inc range)) |
| 18:38 | djork | hah |
| 18:39 | djork | ,(map #(/ 10 %) (range 1 10 0.1)) |
| 18:39 | clojurebot | (10 9.09090909090909 8.333333333333332 7.692307692307691 7.1428571428571415 6.666666666666664 6.249999999999998 5.882352941176468 5.555555555555554 5.26315789473684 4.999999999999998 4.76190476190476 4.545454545454543 4.34782608695652 4.166666666666664 3.999999999999998 3.846153846153844 3.7037037037037015 3.5714285714285694 3.4482758620689635 3.3333333333333313 3.2258064516129012 3.1249999999999982 3.0303030303030285 2.9 |
| 18:39 | djork | ,(map #(/ 10 %) (range 8 11 0.1)) |
| 18:39 | clojurebot | (5/4 1.234567901234568 1.2195121951219514 1.2048192771084338 1.1904761904761907 1.1764705882352944 1.162790697674419 1.1494252873563222 1.1363636363636367 1.1235955056179778 1.1111111111111116 1.0989010989010994 1.086956521739131 1.0752688172043017 1.0638297872340432 1.052631578947369 1.0416666666666672 1.030927835051547 1.0204081632653068 1.0101010101010108 1.0000000000000007 0.9900990099009909 0.9803921568627458 0.97087 |
| 18:39 | djork | err sorry, I'm just spamming onw |
| 18:39 | wooby | lol |
| 18:40 | chouser | ,(range 0 1 1/9) |
| 18:40 | clojurebot | (0 1/9 2/9 1/3 4/9 5/9 2/3 7/9 8/9) |
| 18:41 | spuz | Has anyone used clojure.contrib.http.agent? |
| 18:42 | spuz | I'm having some really strange problems with the library. Appear to be concurrency issues :o |
| 18:44 | spuz | The following just hangs on my REPL: (println (string(http-agent "http://www.google.com" :method "POST" :body "param=true"))) |
| 18:44 | spuz | ,(println (string(http-agent "http://www.google.com" :method "POST" :body "param=true"))) |
| 18:44 | clojurebot | java.lang.Exception: Unable to resolve symbol: string in this context |
| 18:45 | spuz | ,(println (clojure.contrib.http.agent/string(clojure.contrib.http.agent/http-agent "http://www.google.com" :method "POST" :body "param=true"))) |
| 18:45 | clojurebot | java.lang.ClassNotFoundException: clojure.contrib.http.agent |
| 18:45 | spuz | I guess clojurebot doesn't use the contrib libraries |
| 18:55 | wooby | hiredman: is there a way to send a message via clojurebot from vimclojure or whatever? |
| 18:56 | AWizzArd | spuz: I am using it |
| 18:57 | AWizzArd | spuz: yes, (string ...) hangs |
| 18:57 | AWizzArd | You can write your own my-string |
| 18:57 | hiredman | wooby: you could run clojurebot via vimclojure |
| 18:57 | AWizzArd | (let [a (http-agent ...)] (await-for a 2000) (string a)) |
| 18:57 | The-Kenny | wooby: I think that would result in spam... You could ask the guys from codepad.org very nicely to include clojure-support. There is a vim-plugin which handles codepad.org |
| 18:57 | hiredman | or start clojurebot via the same nailgun instance as vimclojure |
| 18:58 | hiredman | oh |
| 18:58 | wooby | hiredman: that's what i have going on |
| 18:58 | wooby | hiredman: it's really cool |
| 18:58 | wooby | hiredman: i think sendMsg is my guy, but I can't figure out what to feed it for the first arg |
| 18:59 | hiredman | from core? |
| 18:59 | wooby | looks like the pircobj is in a ref maybe? |
| 18:59 | wooby | correct |
| 18:59 | spuz | AWizzArd: I don't get it, the doc says the string function will block until the response is completed, but in this case the response never completes |
| 18:59 | spuz | request even |
| 18:59 | hiredman | wooby: yeah |
| 18:59 | hiredman | sendMsg is pretty old and low level |
| 19:00 | hiredman | it is really just a wrapper over pircbot's sendMessage method |
| 19:00 | hiredman | the first arg is a instance of Pircbot |
| 19:00 | spuz | for example, this returns fine: (println (result (http-agent "http://www.google.com" :method "POST" :body "param=true"))) |
| 19:00 | hiredman | which is the :this key in the map that is the bot |
| 19:01 | spuz | so maybe something is broken with (string ...) |
| 19:01 | AWizzArd | spuz: I also don't understand why string is broken, it looked fine at a first glimpse. |
| 19:01 | cemerick | Does pmap ever run ahead of its consumer? I'd like to ensure I'm squeezing everything I can from my cores... |
| 19:01 | wooby | (:this @*bots*) ? |
| 19:01 | hiredman | cemerick: yes |
| 19:02 | hiredman | wooby: no, when you run run-clojurebot the result is map {} which is The Bot |
| 19:02 | hiredman | this gets but into @*bots*, I guess |
| 19:02 | hiredman | but I've never really used that at all, Chousuke added it |
| 19:03 | hiredman | I gotta run |
| 19:03 | wooby | hiredman: alrighty, thakns for your help, this is a lot of fun to play around with |
| 19:09 | konr | Do you use scrum or any other methodology to write software? |
| 19:26 | wooby | what's the reason for using defonce? |
| 19:35 | cemerick | wooby: so reloading a file doesn't clobber any established bindings |
| 19:35 | wooby | thanks |
| 19:57 | cddr | any examples of using compojure to write out some POST'ed XML to a file? |
| 20:17 | sdeobald_ | Hey folks. I'm naively about to attempt to port a Ruby library (xml-to-hash) we've built at work to Clojure. Seems like the Clojure version will be much cleaner than the Ruby version. |
| 20:17 | sdeobald_ | With that in mind, it seems like it would be clean enough that someone may have written it already. |
| 20:18 | sdeobald_ | Has anyone seen a function that would turn this: {:tag :TestElement, :attrs {:name "pat", :value "ok"}, :content nil} into this? {:TestElement {:name "pat" :value "ok"}} |
| 20:20 | djork | hmm |
| 20:20 | djork | destructuring would go a long way there |
| 20:22 | wooby | {(:tag thing) (:attrs thing)} |
| 20:22 | wooby | ? |
| 20:22 | wooby | or rather |
| 20:22 | wooby | no, that's right i guess |
| 20:22 | wooby | where 'thing' is your hash there |
| 20:23 | djork | ,((defn foo [thing] {(:tag thing) (:attrs thing)}) {:tag :TestElement, :attrs {:name "pat", :value "ok"}) |
| 20:23 | clojurebot | Unmatched delimiter: ) |
| 20:23 | djork | oops |
| 20:23 | djork | ,((defn foo [thing] {(:tag thing) (:attrs thing)}) {:tag :TestElement, :attrs {:name "pat", :value "ok"}}) |
| 20:23 | clojurebot | DENIED |
| 20:23 | djork | huh |
| 20:24 | wooby | clojurebot doesn't let you defn |
| 20:24 | djork | oh |
| 20:24 | djork | right |
| 20:24 | djork | that was stupid code anyway |
| 20:24 | djork | I mean to just use fn |
| 20:25 | wooby | ,(let [thing {:tag :TestElement, :attrs {:name "pat", :value "ok"}, :content nil}] {(:tag thing) (:attrs thing)}) |
| 20:25 | clojurebot | {:TestElement {:name "pat", :value "ok"}} |
| 20:25 | djork | clojurebot: I love you. |
| 20:25 | clojurebot | It's greek to me. |
| 20:25 | wooby | lol |
| 20:25 | djork | :( our love can never be |
| 20:26 | sdeobald_ | Ah, sorry. TestElement was just an example. |
| 20:26 | sdeobald_ | I basically want to follow that same pattern for any arbitrary xml struct-map that comes out of clojure.xml/parse |
| 20:28 | wooby | sdeobald_: so you could use something like clojure.contrib.lazy-xml and lazily map nodes to the format you need |
| 20:31 | sdeobald_ | wooby: Thanks, I'll check it out. |
| 20:31 | wooby | np |
| 20:39 | chouser | that's nice, but it's not destructuring |
| 20:40 | chouser | ,(let [t {:tag :TestElement, :attrs {:name "pat", :value "ok"}, :content nil}, {:keys [tag attrs]} t] {tag attrs}) |
| 20:40 | clojurebot | {:TestElement {:name "pat", :value "ok"}} |
| 20:53 | gregoryg | (message "hello") |
| 21:00 | wooby | does anyone have a link to that clojure reading list that rich posted? i'm having trouble finding it |
| 21:02 | chouser | wooby: http://www.amazon.com/Clojure-Bookshelf/lm/R3LG3ZBZS4GCTH |
| 21:03 | wooby | thank you |
| 21:10 | wooby | i've heard good things about this PAIP book |
| 21:17 | tomoj | any clojure.http.agent user's around? |
| 21:18 | tomoj | if I call stream on an agent that uses the default handler, I can read bytes out of the response just fine |
| 21:18 | tomoj | if I use a custom handler which calls stream on the agent and returns it, it EOFs immediately |
| 21:20 | tomoj | man |
| 21:21 | tomoj | myself asking this question yesterday is in the google results today |
| 21:28 | konr | What methodology do you use to program in non-OO languages, like Clojure? |
| 21:31 | wooby | konr: bottom up and functional |
| 21:31 | konr | wooby: but how do you do things like estimate the cost of creating the software |
| 21:32 | konr | wooby: the methodology I'm using for Java uses things like the number of classes |
| 21:32 | konr | wooby: I wonder if there is anything outside that mentality |
| 21:33 | wooby | konr: well typically in languages like clojure your development iterations are faster, because you're developing interactively |
| 21:33 | wooby | konr: i'm not very experienced but that methodology seems to fit well with all the agile approaches to doing things |
| 21:35 | wooby | konr: in general you'd spend less time planning and UMLing and more time trying things out, working toward the simplest working thing possible |
| 21:35 | wooby | konr: then after that your dev becomes functionality driven, and you can do bug fix accounting and stuff to estimate progress |
| 21:46 | tomoj | I think you estimate the same way you'd estimate before |
| 21:47 | tomoj | why should OOP have anything to do with your estimation? |
| 21:47 | rhickey | deftype/class now use case |
| 21:47 | rhickey | no more need for Foo:blah accessors, will be removing |
| 21:47 | rhickey | (:field x) is faster |
| 21:48 | chouser | hah. nice. |
| 21:49 | chouser | is case doing "perfect hashes"? I can't tell by looking. |
| 21:49 | rhickey | chouser: yes, the min-hash code here: http://github.com/richhickey/clojure/commit/5ebed57e1d6d7dc8230fa51e6cd34e22dc1f3a42 |
| 21:50 | chouser | it's short |
| 21:50 | rhickey | figures out the smallest masked/shifted set of bits that is unique amongst the key set |
| 21:50 | cemerick | that's stellar |
| 21:50 | rhickey | then inside the compiler it builds a tableswitch instruction, filling in any blanks with the default |
| 21:51 | cemerick | rhickey: you said this would be applicable to isa?, etc as well? |
| 21:51 | rhickey | well, case is there for all purposes now |
| 21:51 | rhickey | its quite neat, works with everything thanks to the pervasive immutability and plentiful literals |
| 21:52 | rhickey | cemerick: but this isn't the DIY perfect hash dispatch that will be needed for protocols |
| 21:52 | rhickey | I'm not sure if I can get that to map to tableswitch or not |
| 21:53 | cemerick | I see how it'd work for exact matches, but I don't see the connection to a-la-carté hierarchies. |
| 21:53 | rhickey | but my last patch generally tweaked keyword lookup as well, so all of Clojure should be a tad faster |
| 21:53 | cemerick | rhickey: were you surprised by AWizzArd's 40% figure, or no? |
| 21:54 | rhickey | cemerick: you just figure out the answer once, then rebuild the perfect hash, i.e. you cache the results of lookup |
| 21:54 | rhickey | cemerick: no, I saw that here first |
| 21:54 | cemerick | oooh, I get it now |
| 21:54 | rhickey | defstruct was never about perf, it was about reducing the waste given lots of instances with the same key set |
| 21:55 | cemerick | rhickey: right, I was wondering if 40% is a differential you'd expect, compared to structs / maps |
| 21:55 | rhickey | more surprising was just now where (:field x) is faster than (Foo:field x) |
| 21:56 | rhickey | cemerick: its easy to get speed by leveraging specificity - after all tese are now classes generated per use, vs one-class-fits-all |
| 21:56 | rhickey | these are |
| 21:57 | rhickey | I haven't done any comparisons to defclass (.field x), I imagine HotSpot can do more with that, but very happy with the all-dynamic perf |
| 21:59 | rhickey | cemerick: I didn't know what to expect, in absolute terms, other than faster |
| 22:09 | churib | why returns (take (/ 10 3) '(1 2 3 4) --> (1 2 3 4) four elements? |
| 22:10 | tomoj | ~def take |
| 22:11 | tomoj | it keeps subtracting 1 until the number is zero or negative |
| 22:11 | tomoj | and (/ 10 3) is not 3 |
| 22:11 | clojurebot | is is |
| 22:13 | churib | ah, thanks! |
| 22:13 | digash | ,(take 5 (iterate dec (/ 10 3))) |
| 22:13 | clojurebot | (10/3 7/3 4/3 1/3 -2/3) |
| 23:52 | gerry_ | (time (dotimes [i 50000] |
| 23:52 | gerry_ | (let [b (struct Person1 (str "ok" i) i)] |
| 23:52 | gerry_ | (println (:name b))))) |
| 23:53 | gerry_ | =>2833 mmsecs |
| 23:53 | gerry_ | (time (dotimes [i 50000] |
| 23:53 | gerry_ | (let [b (Person (str "ok" i) i)] |
| 23:53 | gerry_ | (println (:name b))))) |
| 23:54 | gerry_ | =>2790 msecs |
| 23:54 | gerry_ | not much perf improvement?? |
| 23:55 | gerry_ | (deftype Person [#^String name #^int age]) |
| 23:55 | tomoj | maybe most of your time is spent printlning? |
| 23:55 | gerry_ | (defstruct Person1 :name :age) |
| 23:58 | gerry_ | time of printing should be same |
| 23:59 | gerry_ | but this little benchmark isnot useful anyways |
| 23:59 | Knekk | gerry_: if println is the bulk of your time you might still have made significant gains, but println is obscuring them |