2010-02-06
| 00:00 | BrandonW | i have another question :) i don't understand the difference between commute and alter. what is the difference between restarting a transaction, and re-running your function with the newest value of the ref you are changing? |
| 00:01 | BrandonW | and if commute doesn't care about in order processing, but alter does: don't they both work such that whichever operation on the ref finishes first is the first one that succeeds in changing the ref? how is commute different from alter in terms of ordering? |
| 00:03 | alexyk | liebke: ping? |
| 00:15 | liebke | alexyk: hey |
| 00:16 | alexyk | liebke: is there a paper I could cite for Incanter? Otherwise I did this: http://paste.pocoo.org/show/174472/ |
| 00:17 | liebke | alexyk: that looks fine, I'm looking forward to reading the paper. |
| 00:17 | alexyk | liebke: cool |
| 00:23 | JayM | hmm..possible to get out of an infinite loop in slime? |
| 00:25 | somnium | JayM: C-c C-c |
| 00:27 | JayM | somnium: aha, thanks |
| 00:33 | slyrus | evening |
| 00:34 | slyrus | so... I see that clojure-contrib has switched over to maven. how do I use maven to build a clojure-contrib jar without downloading all sorts of crazy jars from god-knows-where? |
| 00:45 | alexyk | liebke: I have two lists, xs and ys, I feed to scatter-plot. How do I save them to disk to get them back readily to reproduce scatter-plot? |
| 00:45 | alexyk | need to reload with your pdf option |
| 00:46 | liebke | alexyk: create a dataset from the two vectors and save it with the save function |
| 00:47 | liebke | (save (conj-cols xs ys) filename) |
| 00:48 | alexyk | ok |
| 01:06 | alexyk | liebke: and how do I load it back and feed to scatter-plot again? |
| 01:09 | liebke | alexyk: (scatter-plot :col-0 :col-1 :data (incanter.io/read-dataset filename :header true)) |
| 01:10 | alexyk | liebke: for some reason conj-cols wasn't available, I did (matrix [x y]) -- how do I read *that* back? |
| 01:10 | alexyk | x and y are vectors of x's and y's |
| 01:11 | liebke | alexyk: you might have an old version. incanter.io/read-dataset works with saved matrices too |
| 01:12 | alexyk | in the same way? are x and y columns then? |
| 01:12 | liebke | alexyk: check the saved file though, x and y are probably rows the way you created the matrix |
| 01:12 | liebke | use trans to flip them |
| 01:12 | liebke | i recommend updating incanter too |
| 01:13 | alexyk | tmrw :) |
| 01:13 | alexyk | (after the 3 am deadline) |
| 01:13 | alexyk | is there a :row-0 etc selector? |
| 01:13 | liebke | what time is it where you are? |
| 01:14 | alexyk | 1:14 am |
| 01:14 | liebke | (sel :rows 0) |
| 01:14 | alexyk | ok |
| 01:14 | liebke | (sel mat :rows 0) |
| 01:15 | liebke | alexyk: ah, you're in my timezone, where are you? |
| 01:15 | alexyk | liebke: Dartmouth |
| 01:15 | liebke | ah |
| 01:15 | alexyk | think Moose |
| 01:16 | fatrow | hi. Is there a way to get a subsequence like a slice of python? |
| 01:20 | qed | exec("/bin/kill $blah_pid[0] 2>&1",$a,$b); |
| 01:20 | qed | ^^what is happening here? |
| 01:20 | qed | what is the 2>&1 is that just sh script? |
| 01:20 | qed | im trying to understand that line |
| 01:21 | krumholt | fatrow, something like split-at? |
| 01:21 | krumholt | ,(first (split-at 2 [1 2 3 4])) |
| 01:21 | clojurebot | (1 2) |
| 01:21 | krumholt | ,(second (split-at 2 [1 2 3 4])) |
| 01:21 | clojurebot | (3 4) |
| 01:24 | fatrow | krumholt: thank you. |
| 01:29 | krumholt | fatrow, or if you need more arbitrary splits you can use a combination of drop and drop-last |
| 01:30 | krumholt | ,((fn [coll x y] (drop (dec x) (drop-last (- (count coll) y) coll))) [1 2 3 4 5 6 7 8] 3 5) |
| 01:30 | clojurebot | (3 4 5) |
| 01:31 | fatrow | krumholt: thanks. I want to get a subsequence like (xxx [1 2 3 4] 1 3) => [2 3] |
| 01:32 | krumholt | yes my last post will do exactly that |
| 01:32 | fatrow | krumholt: thank you. |
| 01:33 | krumholt | ok not exactly that it starts at index 1 not 0 |
| 01:37 | fatrow | I guess subseq is this, but it is different. |
| 01:39 | krumholt | ,(subvec [1 2 3 4 5 6] 2 4) |
| 01:39 | clojurebot | [3 4] |
| 01:42 | fatrow | krumholt: oh, subvec is this. Is there a subvec for general sequence version ? |
| 01:43 | krumholt | fatrow, i am not sure. but it is not subseq :) |
| 01:43 | krumholt | ,(subs '(1 2 3 4) 2 3) |
| 01:43 | clojurebot | java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to java.lang.String |
| 01:44 | krumholt | ,(subs "blub" 2 3) |
| 01:44 | clojurebot | "u" |
| 02:28 | fatrow | krumholt: I have solved it. thanks. |
| 02:28 | fatrow | (defn slice [coll start & end] (let [len (count coll), start (max start 0),end (if (nil? end) len (min end len))] (take (- end start) (drop start coll)))) |
| 02:30 | zab | Is it worth attempting to shoehorn an installation of Clojure on App Engine? |
| 02:31 | hiredman | you don't need to shoehorn |
| 02:31 | hiredman | it's fairly painless |
| 02:31 | zab | what about loss of language features like concurrency? |
| 02:32 | hiredman | *shrug* |
| 02:32 | zab | hmm ok |
| 02:33 | zab | im fairly new to the whole JVM thing, but will give it a shot. any good resources out there particularly suited to GAE? |
| 02:33 | hiredman | http://github.com/zitterbewegung/blank-appengine-clj |
| 02:33 | hiredman | looks good but I have no experience with it |
| 02:34 | zab | nice thanks! |
| 02:34 | hiredman | I have http://github.com/hiredman/appengine-helper but I am not regularly working on it, and it is slowly bitrotting |
| 02:35 | hiredman | there are some nice blog posts around |
| 02:35 | zab | yeah i've read most of them i think. they are all pretty old though. |
| 02:37 | hiredman | appengine-clj was junk last time I looked at it, which was many moons ago |
| 02:37 | hiredman | I really like google's datastore |
| 02:37 | hiredman | maps well to storing maps |
| 02:39 | hiredman | I did two apps on appengine, really small facebook apps (maybe five users tops) |
| 02:39 | hiredman | mostly just for my personal use |
| 02:40 | zab | ive built a couple of python GAE apps. i really like the model and pricing structure. |
| 02:40 | zab | and i want to pick up a new language, and clojure looks really interesting. |
| 02:40 | zab | ive never really dug into a lisp before. |
| 02:41 | hiredman | running clojure on the appengine does mean you have to monkey around with AOT compilation |
| 02:42 | hiredman | at least for the servlet file |
| 02:43 | hiredman | the gen-class stuff can be painful to work with |
| 02:43 | zab | is this in the clojure documentation, or is this JVM stuff? (like I said, new to JVM) |
| 02:44 | hiredman | it is under compilation |
| 02:45 | hiredman | the java appengine follows some java webapp spec "servlets" so you need to generate a class with a stable name that the servlet stuff can talk to |
| 03:52 | Lewisham | hi all, Clojure newbie here. I'm trying to do a simple recursive movement through a list, and it's not going well :) I keep getting an NPE thrown out, and I'm not sure what I'm doing wrong. It's very basic! http://pastie.org/812186 |
| 03:52 | Lewisham | I'm also not sure if I'm doing things the Clojure way |
| 03:52 | Lewisham | so any help would be appreciated |
| 03:53 | hiredman | you have an extra pair of parens |
| 03:53 | Lewisham | I do? I thought they all matched up :/ |
| 03:54 | hiredman | yes |
| 03:55 | hiredman | a form like (a b) is function application |
| 03:55 | hiredman | you have ((println ...) ...) |
| 03:56 | Lewisham | oh, I see |
| 03:56 | Lewisham | I didn't need to wrap the second clause in parens |
| 03:56 | Lewisham | d'oh |
| 03:57 | hiredman | if takes two forms |
| 03:58 | hiredman | http://clojure.org/special_forms#toc12 |
| 03:59 | hiredman | ,(reduce (comp inc first list) 0 '("one" "two" "three")) |
| 03:59 | clojurebot | 3 |
| 04:00 | hiredman | ,(count '("one" "two" "three")) |
| 04:00 | clojurebot | 3 |
| 04:00 | Intertricity | How close is ClojureCLR to binary? |
| 04:01 | hiredman | "close to binary" |
| 04:01 | Intertricity | and, how do you access a C# dictionary from it >.> or can you |
| 04:01 | Intertricity | well it's via compile only atm :P |
| 04:01 | hiredman | so? |
| 04:02 | hiredman | what does that have to do with binary? |
| 04:02 | Lewisham | hiredman: thanks very much :) I got it to work with (do...) |
| 04:02 | Lewisham | I need to figure out how this recur form works though |
| 04:02 | Intertricity | hiredman, I'm assuming they'll make a binary for more public use when it's mature enough |
| 04:02 | hiredman | binary is a counting system using two digits |
| 04:02 | Intertricity | ohh, no I meant compiled already |
| 04:03 | Intertricity | drop in and go |
| 04:04 | hiredman | so you meant to ask "how close is ClojureCLR to being distributed already built?" |
| 04:05 | Intertricity | yes, sorry, that would be a better way to put it |
| 04:07 | hiredman | hard to say, I don't know how much of a community it has, and community feedback tends to drive releases |
| 04:55 | Lewisham | hi, sorry, another silly question :) is there a way I can have (count-words) initialize "bins" if it's nil? I've been Googling for things like "default arguments clojure" and it's returning some scary key based stuff that I don't yet understand! http://pastie.org/812204 |
| 04:58 | lypanov | you could use the multiple function defn form |
| 04:58 | lypanov | (defn blah ([x] first fun) ([x y) second fun)) |
| 04:59 | Lewisham | oh, that's true |
| 06:20 | StartsWithK | (time (dotimes [i 100000] (keyword (str "x" i)))) -> "Elapsed time: 2495.639935 msecs", but (time (dotimes [i 100000] (clojure.lang.Keyword/intern (str "x" i)))) -> "Elapsed time: 357.043285 msecs" |
| 06:20 | StartsWithK | why such a big difference? |
| 06:21 | StartsWithK | it looks like keyword checks for Keyword instance, and it wastes time on that |
| 06:39 | Chousuke | StartsWithK: an instance check shouldn't take that long :/ |
| 06:39 | StartsWithK | http://paste.pocoo.org/show/174527/ i am trying to speed up my json lib, and by using Keyword/intern i get something like 4x speedup in reader (words was slurped from cca 330kb json file) |
| 06:40 | StartsWithK | lets see how it works on c.c.json |
| 06:46 | StartsWithK | ~2x speedup in c.c.json when using Keyword/intern vs keyword |
| 08:00 | qed | morning gents |
| 08:03 | AWizzArd | Hallo qed |
| 08:13 | qed | AWizzArd: top 'o the mornin' to ya |
| 08:13 | qed | AWizzArd: how goes clojure? |
| 08:14 | AWizzArd | Going good so far, today I will be hopefully finishing my db transactions as the underlying mechanism for manipulations. |
| 08:14 | qed | interesting -- i dont know what you're talking about :) |
| 08:15 | qed | AWizzArd: how does it work |
| 08:15 | AWizzArd | The DB system I am writing in Clojure for Clojure. |
| 08:15 | qed | are you using the STM as your DB, or something more heavy duty? |
| 08:15 | qed | AWizzArd: ahh, very cool |
| 08:15 | AWizzArd | I thought you mean this when you asked how it is going :-) |
| 08:16 | qed | ah, sorry :) |
| 08:16 | AWizzArd | Under the hood it does not use the STM, but the data structures rhickey implemented, which are amazingly powerful and useful for such work. |
| 08:17 | qed | so clojure's standard structures? vec/map/set/etc? |
| 08:17 | AWizzArd | Yes. Because they are persistent. |
| 08:17 | qed | AWizzArd: would it be reasonable to build a DB on top of the STM? |
| 08:18 | qed | or rather a layer of DBness on top of the STM? |
| 08:18 | AWizzArd | I wanted to do that first. But the current dosync does not allow the use of "plugins". If you want to synchronize DB changes to disk it must happen in a dosync block. |
| 08:18 | qed | from what i gather about STMs in general -- they behave like databases, and I wondered if one could use that with some tinkering, as a production DB |
| 08:19 | qed | AWizzArd: i see |
| 08:19 | AWizzArd | But a dosync should not contain side effects/io. Also for a DB one needs to do a guaranteed write to the disk, which will slow down each dosync and may trigger hundreds of unsatisfying retries. |
| 08:20 | qed | AWizzArd: yes my next question was about retries, but the i/o is another excellent point |
| 08:21 | qed | i am desperate to have some more time with clojure -- i have been so busy with other things lately |
| 08:22 | AWizzArd | The real usefulness is that Clojures data structures are fully persistent, as in http://en.wikipedia.org/wiki/Persistent_data_structure |
| 08:22 | qed | *nod* yes |
| 08:22 | qed | tries -- bagwell |
| 08:23 | qed | AWizzArd: i was so...amazed...when i first learned about persistence in clojure |
| 08:23 | qed | i knew nothing of persistence prior to that |
| 08:24 | qed | shared structure -- versions of a structure, it's so elegant |
| 08:39 | qed | so much stupid in PHP it's unbelievable |
| 08:39 | qed | I really love this community |
| 08:39 | qed | #php, that is |
| 10:08 | raek | how does relations work in clojure.set? |
| 10:09 | raek | can someone show an example of how clojure.set/index is used? |
| 10:25 | raek | ok, found something: http://www.mail-archive.com/clojure@googlegroups.com/msg17047.html |
| 11:12 | npoektop | hi! can anyone help me with compojure? It looks a really simple question, but i can't find the answer myself. |
| 11:12 | npoektop | hi! how do i get content of a POST request? I can do defroutes with (POST "/:name" ...) or smth and get that name with (params :name). But how do i get the whole content? |
| 11:20 | LauJensen | npoektop: check out my blog, have a few examples |
| 11:20 | LauJensen | http://www.bestinclass.dk/index.php/2010/02/reddit-clone-in-10-minutes-and-91-lines-of-clojure/ |
| 11:20 | LauJensen | This one is quite easy |
| 11:25 | npoektop | LauJensen: oh, i now i get it. (GET "/*" ...) and (params :*). Cool. Thank you. |
| 11:25 | LauJensen | np |
| 11:38 | Raynes | http://force7.de/nimrod/ Looked a little bit interesting until I found out it's written in FreePascal. What's up with that? :o |
| 11:39 | patrkris | LauJensen: Is the new front-end in a state where I can test it, or is it currently b0rken? |
| 11:40 | patrkris | LauJensen: talking about clojureql, if you were wondering :) |
| 11:40 | kotarak | patrkris: not ywt |
| 11:40 | kotarak | yet |
| 11:41 | patrkris | kotarak: Ok. I checked out the frontend-2.0 branch. I like the new stuff (also from what I can read on gitorious). I'm excited :) |
| 11:41 | kotarak | thanks :) let's see how it works out. |
| 11:42 | kotarak | There are quirks, but there are also a lot of improvements |
| 11:42 | patrkris | kotarak: I saw that somewhere in the source code it says "Monad stuff". I've never understood monads, but I think I might go try to work on my understanding of it now. |
| 11:42 | kotarak | it uses now a state monad. |
| 11:43 | patrkris | kotarak: my impression is that frontend-2.0 keeps the promise of being more clojure-like instead of SQL-like |
| 11:43 | kotarak | good for boilerplate, bad for dynamics |
| 11:43 | patrkris | kotarak: yeah... I have really no idea what it is. I've asked one of the PhD-students at my university to explain it to me, which he hopefully will soon. |
| 11:44 | kotarak | I try to get away from sql, I have working fleetdb prototype |
| 11:44 | patrkris | but i'm amazed that even some of the more senior scientists at my department aren't able to explain monads |
| 11:44 | kotarak | patrkris: it is overrated |
| 11:44 | patrkris | monads are overrated? |
| 11:44 | Chousuke | patrkris: The most simplified description of monads I can think of is that they describe how to compose operations |
| 11:45 | kotarak | yes, they are not a silver bullet |
| 11:45 | patrkris | Chousuke: yes, I've read that somewhere - but still ... :) |
| 11:45 | Chousuke | patrkris: so that two sequences of operations composed under a different monad have a different outcome. |
| 11:45 | patrkris | Chousuke: ah |
| 11:45 | AWizzArd | lypanov: because it can return the coll |
| 11:45 | AWizzArd | ,(doc not-empty) |
| 11:45 | clojurebot | "([coll]); If coll is empty, returns nil, else coll" |
| 11:46 | kotarak | patrkris: eg. i have to introduce non-sensic redirections to make the monad stuff independent from the backend |
| 11:46 | lypanov | AWizzArd: ah, k. now it makes sense. thank you! |
| 11:46 | AWizzArd | It does not return true or false. |
| 11:46 | Chousuke | patrkris: this only applies to operations that can be "lifted" to the monad though. some operations might be such that they only work within a single monad :/ |
| 11:46 | lypanov | still think its weird that "empty" is so different to "not-empty" |
| 11:47 | patrkris | Chousuke: Ok. Did you go through category theory to understand them? |
| 11:47 | kotarak | not-empty is a sister to seq |
| 11:47 | Chousuke | patrkris: nah. |
| 11:47 | Chousuke | patrkris: I've just read loads of monad tutorials. and I'm still not sure if I understand them |
| 11:47 | lypanov | (defn two-of-each [xs] (let [x (first xs)] (if (not-empty xs) [] (concat [x x] (recur (rest xs))) ))) |
| 11:47 | Chousuke | patrkris: this is just my interpretation |
| 11:48 | lypanov | anyone have a clue why this isn't accepted? what does "recur must be in tail position" mean exactly? |
| 11:48 | patrkris | Chousuke: hehe, well that's what I've tried to do too, but probably not hard enough |
| 11:48 | lypanov | i guess i need a more specific form than this, i've used it a few other times without issue. |
| 11:49 | Chousuke | patrkris: I think the principles behind monads are simple enough, but it's so abstract that it's difficult to see how to apply it to a real problem :/ |
| 11:49 | lypanov | ah... got it. |
| 11:49 | lypanov | concat is in tail position? |
| 11:49 | Chousuke | lypanov: recur is in the tail position of the concat form, not the defn form :) |
| 11:52 | kotarak | lypanov: (defn two-of-each [coll] (mapcat (juxt identity identity) coll)) |
| 11:53 | lypanov | ooo. identity is cute. |
| 11:55 | qed | Chousuke: you can have a recur without an explicit loop form |
| 11:56 | Chousuke | hm? |
| 11:56 | qed | gah i just reformatted -- it's in stuart's book |
| 11:57 | kotarak | fn also adds a "loop" point for recur |
| 11:57 | qed | kotarak: thank you |
| 11:57 | Chousuke | Did I say something that hinted otherwise? :/ |
| 11:57 | qed | i think i mis-read -- sorry Chousuke |
| 11:58 | kotarak | Chousuke: maybe it was a question? |
| 11:58 | qed | i just saw recur .... not the defn form |
| 11:58 | qed | which means! it's time for bed. night all |
| 11:59 | lypanov | heh. night qed :)) |
| 12:13 | StartsWithK | how can i test is my pom.xml file correct without maven/lain/other build tools.. |
| 12:13 | StartsWithK | is there a validator tool? |
| 12:13 | StartsWithK | and, how do i declare dependency on clojure 1.1-1.2-SNAPSHOT |
| 12:16 | kotarak | StartsWithK: [1.1,1.2-SNAPSHOT] |
| 12:16 | StartsWithK | do i declare my lib alpha/beta? |
| 12:17 | StartsWithK | if it depends on 1.2 (alpha) shouldn't then that reflect my version too? |
| 12:17 | StartsWithK | i can't be 'stabel' if i depend on something that isn't? |
| 12:32 | arkrost | hi! Can anyone explain how to use dotimes macro with several bindings? |
| 12:37 | the-kenny | arkrost: Looks like dotimes only support exactly one binding |
| 12:42 | AWizzArd | one can easily stack them, or use for |
| 13:13 | AWizzArd | rhickey: did you hear/read from Mark Tarvers (teamed up with Carl Shapiro) effort to make the important parts of Qi available in such a way, that it can be ported to Clojure without too much work? |
| 13:14 | AWizzArd | Message-ID: <37b52400-6e4f-4a15-8bd9-bb7b45ea8a40@14g2000yqp.googlegroups.com> |
| 13:58 | BrandonW | i have another question :) i don't understand the difference between commute and alter. what is the difference between restarting a transaction, and re-running your function with the newest value of the ref you are changing? |
| 13:58 | BrandonW | and if commute doesn't care about in order processing, but alter does: don't they both work such that whichever operation on the ref finishes first is the first one that succeeds in changing the ref? how is commute different from alter in terms of ordering? |
| 14:08 | LauJensen | You pretty much said it. Commute doesn't enforce strict ordering, so you need to work on operation which arent dependant on the order, for instance incrementing, alter does enforce strict ordering, so moving items from 1 datastructure to another will maintain integrity, ie. the order in which the items were listed in list #1 |
| 14:12 | BrandonW | well, for example consider a chat application where a message log is being modified from multiple sources. the most recent message would appear at the top. i would consider that to be dependent upon ordering |
| 14:13 | BrandonW | however, i don't understand the difference between commute and alter there. in either case, whichever operation finishes the transaction first is the one that successfully modifies the message log |
| 14:14 | BrandonW | i don't understand what the difference between alter's need to restart the transaction if the value the ref is pointing at changes, versus commute's ability to just rerun the function without restarting the transaction (isn't that all the transaction is, just running the function on the most current value of the ref?) |
| 14:18 | zaphyr | but the restart may cause your transaction to decide it should not continue |
| 14:19 | BrandonW | ohhhhhhhhhhh |
| 14:19 | zaphyr | whereas with commute, it cannot fail |
| 14:19 | hiredman | eh? |
| 14:20 | zaphyr | chat logging is a bad example- imagine credit/debit transactions on a bank account, or similar |
| 14:20 | BrandonW | okay that is a much better example |
| 14:20 | zaphyr | hiredman: have i misunderstood the difference between commute/alter myself? :/ |
| 14:20 | BrandonW | one transaction aims to debit $50, the other wants to debit $45, the account has $55 total |
| 14:21 | BrandonW | well |
| 14:21 | BrandonW | so you can't have validation or anyting preventing a commutative transaction from continuing? |
| 14:23 | BrandonW | ordering seems to be the main difference between alter & commute, but the order seems like it would stay the same no matter which function you use to modify the ref |
| 14:23 | hiredman | the credit/debit is better than logging because for stm examples it is best to have at least two refs |
| 14:24 | hiredman | but it is not good enough because you are still doing addition and subtraction |
| 14:24 | hiredman | which are communicative |
| 14:24 | zaphyr | hiredman: yeah. agreed :) |
| 14:24 | hiredman | LauJensen's example was pretty good but not fleshed out |
| 14:25 | hiredman | if we have two refs, A and B, A points to [1 2 3] and B points to [4 5 6] |
| 14:27 | BrandonW | okay i think i understand now |
| 14:27 | BrandonW | i was thinking in terms of operations too simple (and coincidentally commutative) |
| 14:27 | Chousuke | "alter" is always the safe choice |
| 14:27 | hiredman | alter? |
| 14:27 | clojurebot | alter is always correct |
| 14:28 | BrandonW | so it is more along the lines of if you have several actions that have to be done in a certain order, you can start the action via several alters, but as long as yuo start them in order you know they will be finished in order |
| 14:28 | Chousuke | you can use commute if you notice that you're getting unnecessary restarts :) |
| 14:28 | BrandonW | whereas if you use commute, even if you start them in order, the 3rd one might finish first, then the 5th, then the first, etc. |
| 14:29 | BrandonW | okay i definitely understand now... alter seems closer to synchronous, because if you have several actions, the quick ones might be much easier to execute, but they are at the end. so you would have to finish the first ones (which might be longer running) first |
| 14:29 | Chousuke | I'm not sure if that's quite right. |
| 14:30 | zaphyr | specifically commute works only for commutative operations- that is X op Y == Y op X |
| 14:30 | zaphyr | no matter what order you evaluate a sequence of commutative operations, the result will always be the same |
| 14:30 | BrandonW | well, consider a problem where you have several operations that have to be done in order. the first operation takes X time to complete, the 2nd takes x+1, the third takes x+2 |
| 14:30 | hiredman | BrandonW: if they are running concurrently the short transactions will complete and cause the longer running ones to restart |
| 14:30 | BrandonW | so all the actions try to execute at first, but every one but the first theoretically will complete before the first, but they would all have to restart because the first one wasn't done yet |
| 14:31 | BrandonW | and then again with teh 2nd, then again with the third |
| 14:31 | hiredman | STM is not a lock |
| 14:31 | Chousuke | no, the first one would restart if the second finishes first :/ |
| 14:32 | BrandonW | okay i still don't understand the ordering concept then :( |
| 14:32 | hiredman | clojurebot: the STM is not a lock |
| 14:32 | clojurebot | In Ordnung |
| 14:32 | hiredman | clojurebot: stm? |
| 14:32 | clojurebot | No entiendo |
| 14:32 | zaphyr | xD |
| 14:32 | hiredman | :( |
| 14:32 | hiredman | clojurebot: the stm |
| 14:32 | clojurebot | the STM is not a lock |
| 14:32 | Chousuke | transactions are not ordered, but the operations within one transaction are |
| 14:32 | BrandonW | oh ok |
| 14:32 | Chousuke | unless you use commute, in which case it eases up the requirements a bit |
| 14:33 | BrandonW | but the operations inside a commute transaction aren't ordered |
| 14:33 | BrandonW | or aren't *necessarily* ordered |
| 14:34 | BrandonW | but then if the only thing that changes is the potential order of expressions in a transaction, how can that improve performance in commute vs alter? |
| 14:34 | Chousuke | say transaction A modified X with alter and Y with commute, and B modifies Y with commute; both start at the same time, but B finishes first; now, A doesn't need to restart. |
| 14:34 | Chousuke | that's as far as I understand it. I hope I'm getting it right. :/ |
| 14:35 | Chousuke | of course, if A is designed so that it actually depends on the final value of Y, then it contains a bug :) |
| 14:37 | BrandonW | ohhhhhhhhhhhhhh okay |
| 14:37 | BrandonW | that just made it click |
| 14:38 | BrandonW | i'm was thinking of transactions as a single function call |
| 14:38 | BrandonW | but you can have multiple alters/commutes at once |
| 14:38 | zaphyr | ah. yeah. don't do that :) |
| 14:38 | hiredman | BrandonW: right |
| 14:38 | zaphyr | yeah, this is happening all at once, you really don't know what's coming in next |
| 14:38 | Chousuke | then there is ensure, which you need to use if you read Y and alter X based on the read value; if you just used deref, something else might use commute on Y and the altering of X would be done with an "old" value :/ |
| 14:38 | BrandonW | now i understand what the programming clojure book was saying when commute only requires the commut call to be re-executed, versus alter which needs to restart the entire transaction (which could contain a lot of other function calls) |
| 14:39 | BrandonW | ensure hmm |
| 14:40 | BrandonW | i think that is going to be one of the difficulties after i finish the programming clojure book: finding out all the new additions since the book (or things the book didn't mention) |
| 14:40 | Chousuke | heh. |
| 14:40 | Chousuke | you need to get chouser and fogus' book :P |
| 14:40 | lypanov | yeah, today. |
| 14:41 | BrandonW | is that the new one coming out soon? |
| 14:41 | lypanov | they areon 37% discount. |
| 14:41 | lypanov | um. i'm a java / ruby head. alien to this strange () filled world. |
| 14:41 | zaphyr | hmm, yeah i read that- does that include dead tree versions when they're complete? |
| 14:41 | lypanov | any one think guice is needed if you have the various alt project abstractions lisp provides? |
| 14:43 | BrandonW | which book is written by chouser and fogus? |
| 14:43 | lypanov | BrandonW: http://www.manning.com/fogus/ |
| 14:43 | BrandonW | i only see Practical Clojure by Luke Vanderhart in addition to programming clojure |
| 14:43 | hiredman | lypanov: definitely not |
| 14:43 | BrandonW | awesome, i'll bookmark that for later |
| 14:44 | lypanov | and http://www.manning.com/rathore/ (which i have mainly as it looks neat to learn style from) |
| 14:44 | lypanov | hiredman: figured as much :) |
| 14:44 | BrandonW | clojure seems like it is speeding up |
| 14:44 | lypanov | and a good book on unit testing, universally applicable? |
| 14:45 | lypanov | s/lisp/clojure/ |
| 14:45 | zaphyr | lypanov: i quite liked http://www.amazon.co.uk/Test-Driven-Acceptance-Java-Developers/dp/1932394850, ymmv |
| 14:45 | Raynes | It's obvious that Joy is going to be awesome, but it's not complete enough for one to learn off of yet. |
| 14:46 | BrandonW | 3 new books coming in the next 10 months |
| 14:46 | BrandonW | unit testing seems to lend itself to functional programming in general |
| 14:47 | BrandonW | okay i gotta go |
| 14:47 | BrandonW | thanks for all the help re: commute vs alter :) |
| 14:48 | lypanov | zaphyr: ah, koskela ... interesting: http://www.manning.com/koskela2/ |
| 14:49 | zaphyr | hmm, looks like that one seems much more language agnostic |
| 14:49 | lypanov | reading through the chapter list makes me thing "oh, not needed with lisp" tbh |
| 14:49 | lypanov | s/thing/think/ |
| 14:50 | lypanov | maybe i'll just wait on the chapters in clojure in action for the moment |
| 14:50 | lypanov | part ii has tdd stuff |
| 14:50 | zaphyr | yeah, to a degree. the nice thing about test harnesses, primarily, is that when you want to change a big huge system, you can run all the tests to make sure you didn't break something far far away |
| 14:51 | lypanov | i'm already a tdd fan, just missing some of the tricks needed for java. but by the looks of it, half of the pain isn't even seen when using clojure. |
| 14:52 | zaphyr | ahh, right, yeah. clojure makes a lot of the pain irrelevant |
| 14:52 | Chousuke | one tends to write a function and then test it immediately afterwards until it works :P |
| 14:52 | lypanov | Chousuke: *nod* |
| 14:52 | lypanov | on that topic, |
| 14:53 | lypanov | do you guys have tricks for printf debugging of complex things? |
| 14:53 | lypanov | inserting a print randomly in ruby is just trivial, but it gets quite complicated in clojure. |
| 14:53 | hiredman | doto |
| 14:53 | Chousuke | complicated? :/ |
| 14:53 | hiredman | and use prn |
| 14:53 | hiredman | not println |
| 14:54 | lypanov | doh! didn't know about prn. thx hiredman! |
| 14:54 | hiredman | ,(doto 1 prn) |
| 14:54 | clojurebot | 1 |
| 14:54 | clojurebot | 1 |
| 14:54 | lypanov | i'm still half way through core. doing the projecteuler stuffs. |
| 14:54 | Chousuke | I suppose instead of random printfs you should use a proper logging macro so that they can be easily disabled when you don't want to see debugging output |
| 14:54 | hiredman | Chousuke: pfffft |
| 14:55 | lypanov | Chousuke: its just for in repl debugging. |
| 14:55 | hiredman | what are you? some kind of professional? |
| 14:56 | lypanov | ooo. comp is neat. |
| 14:57 | hiredman | I really should figure out logging, I did some on appengine, prn doesn't work there |
| 14:59 | lypanov | hiredman: ah, doto ... prn is cute. thank you. just what i needed. |
| 15:03 | arohner | in clojure, strings are interned, so = compares by pointers, rather than strcmp, right? |
| 15:04 | arohner | I'm wondering if I'll get in trouble by using strings as keys in a map |
| 15:05 | Raynes | ,(keyword "hai") |
| 15:05 | clojurebot | :hai |
| 15:05 | arohner | ,(keyword "I am a string with spaces") |
| 15:05 | clojurebot | :I am a string with spaces |
| 15:05 | arohner | shrug. that works too |
| 15:06 | hiredman | don't do that |
| 15:06 | hiredman | just use strings |
| 15:06 | Raynes | arohner: I wasn't answering your question. |
| 15:06 | Raynes | :p |
| 15:06 | Raynes | I was just checking out the keyword function. |
| 15:06 | Raynes | Use strings. |
| 15:07 | AWizzArd | Raynes: I brought this issue up a few days ago. |
| 15:07 | AWizzArd | ,{:a 1, :a 2} |
| 15:07 | clojurebot | {:a 1, :a 2} |
| 15:07 | Raynes | AWizzArd: I know. |
| 15:07 | zaphyr | ?! how? |
| 15:08 | Raynes | zaphyr: Magic. |
| 15:08 | zaphyr | broken magic XD |
| 15:08 | Raynes | Indeed. |
| 15:08 | AWizzArd | ,(hash-map :a 1, :a 2) |
| 15:08 | clojurebot | {:a 2} |
| 15:09 | billsmithaustin | ,(class {:a 1, :a 2}) |
| 15:10 | zaphyr | :( |
| 15:10 | zaphyr | ,(keys { :a 1 :a 2 :a 3 }) |
| 15:10 | clojurebot | (:a :a :a) |
| 15:11 | zaphyr | ,(conj { :a 1 :a 2 :a 3} { :a 4 }) |
| 15:11 | clojurebot | {:a 4, :a 2, :a 3} |
| 15:11 | zaphyr | :S |
| 15:13 | zaphyr | Is it a bug in the reader? or nastier? |
| 15:14 | hiredman | arraylist doesn't check keys |
| 15:14 | hiredman | ~ticket #87 |
| 15:14 | clojurebot | {:url http://tinyurl.com/y92lmv8, :summary "GC Issue 83: PersistentArrayMap trust the reader (map literals) too much", :status :test, :priority :low, :created-on "2009-06-17T20:36:09+00:00"} |
| 15:14 | hiredman | there is a patch :P |
| 15:15 | zaphyr | aha. phew. i had a moment there. rhicky: accept this patch please :D |
| 15:18 | hiredman | actually, the patch only adds guards to the reader, I suppose it should also add guards to arraymap |
| 15:19 | zaphyr | hmm. probably. how much of a hit is it? |
| 15:19 | zaphyr | performance wise? |
| 15:19 | zaphyr | (correctness should probably be favored over performance here though, imo) |
| 15:21 | hiredman | the patch creates a hashset of the keys everytime a map literal is read |
| 15:22 | zaphyr | yeah, one time reader costs probably don't hurt much at all |
| 15:22 | hiredman | and it throws an exception if you try to read a map with duplicate keys |
| 15:23 | zaphyr | :) |
| 16:10 | Scriptor | hey everyone |
| 16:23 | npoektop | i still can't get parameters of a POST http method with compojure. Can anyone help me? http://pastebin.com/d6e4b5cd6 |
| 16:26 | hiredman | "/:*" |
| 16:26 | hiredman | if I recall |
| 16:29 | zaphyr | hmm. I have found myself wrapping awt with multimethods and macros. That isn't inherantly a bad thing is it? It makes things much more lispy :) |
| 16:30 | hiredman | why are you using awt? |
| 16:30 | zaphyr | well, the Graphics2D part of awt |
| 16:30 | zaphyr | swing for UI components, naturally |
| 16:30 | hiredman | just making sure |
| 16:31 | zaphyr | and you rightly should :) |
| 16:31 | zaphyr | things like (with-graphics g (draw-line 50 50 200 200)) |
| 16:32 | zaphyr | binding g to a private fluid var *g* |
| 16:34 | npoektop | hiredman: no, "/:*" doesn't work |
| 17:22 | lypanov | i don't get if-let... |
| 17:23 | kotarak | ,(if-let [x 5] x 6) |
| 17:23 | clojurebot | 5 |
| 17:23 | kotarak | ,(if-let [x nil] x 6) |
| 17:23 | clojurebot | 6 |
| 17:23 | kotarak | ,(if-let [x false] x 6) |
| 17:23 | clojurebot | 6 |
| 17:23 | kotarak | ,(if-let [x true] x 6) |
| 17:23 | clojurebot | true |
| 17:24 | lypanov | i keep getting the equiv of "unable to resolve x in this context" |
| 17:25 | kotarak | lypanov: code? |
| 17:25 | lypanov | i'm too ashamed to paste :P |
| 17:25 | AWizzArd | ;-) |
| 17:25 | kotarak | lypanov: you shouldn't be |
| 17:26 | lypanov | k... *shame* |
| 17:26 | lypanov | https://gist.github.com/c6791d30086488f4335c |
| 17:26 | kotarak | The binding is only in the true branch of the if. |
| 17:27 | lypanov | line 19. has an if-let form. 'm getting the error: java.lang.Exception: Unable to resolve symbol: rest2-primes in this context (NO_SOURCE_FILE:385) |
| 17:27 | lypanov | ah! doh |
| 17:27 | kotarak | After the seq call you know it's nil. |
| 17:27 | kotarak | in the else branch, that is |
| 17:27 | lypanov | good point... how on earth did this code work. |
| 17:28 | lypanov | thinking in clojure is teh hard |
| 17:28 | kotarak | *shrug* Schroedingbug |
| 17:28 | lypanov | it wasn't used anyway, so the nil just got ignored previously |
| 17:29 | kotarak | lypanov: no, it's not. Clojure is veeery consistent. cf. alter, commute, swap!, update-in, .... Know one, you know the others. |
| 17:29 | lypanov | thank you :) |
| 17:29 | lypanov | kotarak: agreed, but when you're 3 days in... and you're trying to solve problems that you'd find hard in any lang. its teh hard. :P |
| 17:29 | kotarak | ok. That's true. :) |
| 17:37 | AWizzArd | lypanov: already some hours ago i saw you talking.. were you learning all those hours Clojure? |
| 17:38 | lypanov | AWizzArd: and watching crap tv :P |
| 17:38 | lypanov | but yeah, crap tv takes around 5% in my brain-top |
| 17:39 | AWizzArd | maybe resting can be nice from time to time :) |
| 17:39 | lypanov | AWizzArd: my wife will force me to do that eventually. |
| 17:39 | lypanov | :P |
| 17:39 | AWizzArd | great |
| 17:39 | lypanov | anyway. inbetween coding i'm watching the "clojure for lisp programmers" video at double speed. |
| 17:40 | AWizzArd | yes |
| 17:40 | lypanov | okay. getting closer to not sucking: https://gist.github.com/c6791d30086488f4335c |
| 17:48 | Mec | In emacs, is there a way to get things to output to the repl instead of *inferior-lisp* or *slime-events*? |
| 17:49 | the-kenny | Mec: I think there was some variable in emacs to accomplish that |
| 17:53 | the-kenny | ha! |
| 17:53 | AWizzArd | Ja? |
| 17:53 | the-kenny | Mec: Try C-h f slime-redirect-inferior-output |
| 17:54 | arohner | I have a list, I want to map over it, but I want each call to give me two adjacent elements. Is there a function that does that? |
| 17:55 | arohner | i.e. (map* f (range 5)) would call (f 0 1) (f 1 2) (f 2 3) ... |
| 17:55 | the-kenny | arohner: destructuring and (partition) |
| 17:55 | zaphyr | ,(partition 2 1 [1 2 3 4 5 6]) |
| 17:55 | clojurebot | ((1 2) (2 3) (3 4) (4 5) (5 6)) |
| 17:55 | the-kenny | ,(doc partition) |
| 17:55 | clojurebot | "([n coll] [n step coll] [n step pad coll]); Returns a lazy sequence of lists of n items each, at offsets step apart. If step is not supplied, defaults to n, i.e. the partitions do not overlap. If a pad collection is supplied, use its elements as necessary to complete last partition upto n items. In case there are not enough padding elements, return a partition with less than n items." |
| 17:55 | arohner | thanks! |
| 17:59 | Mec | the-kenny: thanks, that's exactly what I wanted |
| 18:02 | lypanov | ok. |
| 18:02 | the-kenny | Mec: You're welcome :) |
| 18:02 | lypanov | can anyone with a few minutes go over https://gist.github.com/c6791d30086488f4335c and tell me why it sucks? |
| 18:03 | lypanov | (other than the fact that lcm can be done way way easier ;) ) |
| 18:03 | Mec | hmm that didnt redirect all, is there a way to redirect output from evaluating an expression to the repl instead of just the little line at the bottom? |
| 18:04 | kotarak | lypanov: something more general: use (next ...) instead of (seq (rest ...)) |
| 18:06 | lypanov | cute. thank you. |
| 18:08 | zaphyr | i need to dispatch on my defstructs and general classes- am i doing this right? http://paste.lisp.org/display/94500 |
| 18:10 | Mec | I think you can replace tag-or-class with just type |
| 18:10 | zaphyr | aha, thanks :) |
| 18:10 | Mec | maybe not |
| 18:11 | zaphyr | nope. PersistantStructMap :) |
| 18:13 | lypanov | is there any other way to do multi return value than destructuring in the caller? |
| 18:13 | technomancy | lypanov: how else would you? |
| 18:13 | technomancy | to return multiple values, you'd have to return a collection type |
| 18:14 | lypanov | clomagic? :P no idea. |
| 18:14 | zaphyr | tchnomancy: call-with-values (scheme) multiple-value-let (common lisp) |
| 18:14 | zaphyr | but clojure doesn't support that behaviour |
| 18:14 | technomancy | zaphyr: what does that mean? |
| 18:15 | the-kenny | lypanov: It's easy to implement with metadata, but they're bound to types which support metadata then |
| 18:15 | technomancy | I mean, if multiple values are returned, it must be a collection type, right? |
| 18:15 | zaphyr | you cease to have functions that return |
| 18:15 | the-kenny | technomancy: Common Lisp has "Optional Return Values". There's one main-value and optional, additional values which you can access with multiple-value-bind |
| 18:16 | zaphyr | ahh, multiple-value-bind, i thought that was wrong =] |
| 18:16 | lypanov | now i understand why clojure is a good lang for me to learn ;) |
| 18:16 | lypanov | last time i started cl i almost fainted. |
| 18:16 | zaphyr | technomancy, effectively (inside the compiler) a function calls another function with the arguments returned by values |
| 18:17 | technomancy | and that's considered useful? |
| 18:17 | zaphyr | the net result is you don't end up boxing up anything to get multiple returns |
| 18:17 | the-kenny | technomancy: It's useful. |
| 18:17 | the-kenny | It's possible if the value returned by let is nil or it wasn't found, without a special value for "not found" |
| 18:18 | lypanov | okay. taking AWizzArd's advice and taking a much needed sake drinking break. |
| 18:18 | technomancy | so it reduces the need for things like containts? |
| 18:18 | technomancy | *contains? |
| 18:19 | zaphyr | and partition can just return two values, rather than a list of two values |
| 18:36 | zaphyr | clojure.lang.PersistentBitVector. want! |
| 18:37 | hiredman | damn |
| 18:37 | hiredman | (+ 1 2) in the repl doesn't call Expr.parse |
| 18:37 | clojurebot | 3 |
| 18:37 | hiredman | clojurebot: byte me |
| 18:37 | clojurebot | My mother? I'll tell you about my mother |
| 18:42 | hiredman | I'm thinking #^{:primitive true} (+ (float 1) (float 2)) is nicer than (jop + (float 1) (float 2)) |
| 18:44 | zaphyr | could there not be f+ f- f* ... i+ i- i* with automatic coercions? |
| 18:45 | hiredman | easier to dispatch (and better) to dispatch on type |
| 18:45 | hiredman | easier (and better) to dispatch on type |
| 18:46 | zaphyr | hmm, yeah i suppose so. maybe just add a float reader format #^{:primitive true} (+ 1.0f 2.0f) |
| 18:47 | hiredman | zaphyr: but then what about non-literals? |
| 18:47 | zaphyr | use float still :) |
| 18:47 | zaphyr | i'm just thinking about populating a matrix full of float literals. ick. |
| 18:47 | hiredman | anyway, in my conception this is not for users |
| 18:48 | hiredman | this is at the bottom of the numbers dispatch stuff that has already determined the types of all the numbers |
| 18:48 | zaphyr | ah, right |
| 18:58 | gstratton | Hi, I can't figure out why this doesn't work: (for [i (map vector '(float int int) '(0.5 2 4))] (apply (first i) (rest i))) |
| 18:58 | gstratton | I want to apply a list of args to a list of single-valued functions |
| 18:59 | gstratton | I'm sure there are multiple shorter ways which do work, but I'm stumped finding them |
| 18:59 | hiredman | that is a pointless thing to do |
| 19:00 | hiredman | you are casting to primives, and then sticking the result into a collection that does not support primitives |
| 19:00 | hiredman | so they are boxed all over |
| 19:05 | zaphyr | gstratton: to make the code work, you might want to try [float int int] instead of '(float int int) |
| 19:06 | zaphyr | but as hiredman says, you'll be casting to integers and wrapping them back into boxed Integers, so its probably not the best thing to do |
| 19:07 | gstratton | Okay, thanks, I'm reading up on boxing now. |
| 19:08 | zaphyr | i'm not sure what the effect of calling a symbol as a function is, but that's what you were doing |
| 19:09 | gstratton | zaphyr: Oh, I see, thanks |
| 19:09 | zaphyr | ,('foobar 3) |
| 19:09 | clojurebot | nil |
| 19:09 | hiredman | ,('f {'f 1}) |
| 19:09 | clojurebot | 1 |
| 19:10 | zaphyr | ahhh, so like keywords |
| 19:10 | zaphyr | thanks :) |
| 19:10 | hiredman | yes |
| 19:46 | zaphyr | hmm, if i implement a version of drop-while which works from the end for vectors, would that still be horrible? |
| 19:47 | zaphyr | i think that removing from the end of a vector via subvec would be O(1), so it would be fine? |
| 19:59 | wilig | https://gist.github.com/2574d3bba9a9540c1bb8 My first attempt at validation. Constructive criticism would be most welcome. |
| 20:03 | hiredman | :D |
| 20:04 | wilig | heh |
| 20:04 | zaphyr | you could filter with identity instead of #(not (nil? %)) |
| 20:05 | hiredman | wilig: if you collapse each verification function into a single function, you can use a map instead of a vector of vectors |
| 20:05 | hiredman | but I guess that has downsides as well |
| 20:06 | hiredman | I have #^{:primitive true} (+ (double 1) (double 2)) compiling to a dadd :D |
| 20:06 | zaphyr | \o/ |
| 20:08 | wilig | I'm so far over my head. Haven't even made it to the macro chapter in programming clojure yet. Having lots of fun though. |
| 20:09 | wilig | zaphyr: Could you use little words and explain filter with identity? |
| 20:09 | zaphyr | ,(filter identity [1 2 nil 3 4]) |
| 20:09 | clojurebot | (1 2 3 4) |
| 20:09 | wilig | Ah! |
| 20:09 | zaphyr | ,(doc identity) |
| 20:09 | clojurebot | "([x]); Returns its argument." |
| 20:10 | wilig | Oh, thanks for showing me the light. Much better. |
| 20:10 | zaphyr | np |
| 20:12 | qed | wilig: ive been at clojure for a few months and i still feel the same way, learning so much fun stuff along the way though |
| 20:12 | qed | clojure is like a supplementary CS education |
| 20:12 | wilig | I totally agree |
| 20:13 | wilig | I've always wanted to learn a bit of lisp, and I'm having the time of my life. |
| 20:14 | wilig | Hardest part is internalizing how much can be accomplished just by combining the core functions in various ways. |
| 20:16 | hiredman | user=> (expression-info (with-meta '(bit-shift-right (byte 10) (byte 1)) {:primitive true})) |
| 20:16 | hiredman | {:class byte, :primitive? true} |
| 20:16 | zaphyr | :D |
| 20:16 | zaphyr | much win |
| 20:17 | hiredman | well, I still need to see if rich is interested in it |
| 20:18 | qed | wilig: i like to look at code ive written in other languages and adapt it to clojure -- it helps my brain a bit to see what i used to think of, and how to think of it in clojure |
| 20:19 | zaphyr | hiredman: is it generating java bytecodes, or calling static methods that do the work? |
| 20:21 | wilig | qed: actually that's a very good idea. I may have to try that. thanks. |
| 20:22 | hiredman | zaphyr: java bytecode |
| 20:22 | hiredman | right now + and similar compile down to calls of static methods from Numbers.java |
| 20:22 | zaphyr | then I totally have a use for that. can't wait to play with it :) |
| 20:23 | hiredman | but this le you generate bytecode directly, trading off flexibility |
| 20:23 | hiredman | lets |
| 20:24 | zaphyr | would be incredibly useful for DSLs I'd wager |
| 20:24 | hiredman | how do you figure? |
| 20:24 | hiredman | DSLs usually seem to want more abstractions and indirection, not less |
| 20:25 | zaphyr | yeah, but say your language works only with ints and longs |
| 20:25 | zaphyr | and needs to go faster than unboxing into bigints |
| 20:26 | zaphyr | it looks like you could create a mini compiler for said language with that, if i understand you correctly |
| 20:26 | zaphyr | (potentially without requiring a clojure runtime) |
| 20:26 | hiredman | if you want to write a compiler you can use the asm library, just like clojure does |
| 20:27 | zaphyr | hmm. good point. |
| 20:34 | zaphyr | hiredman: but it might make this less painful, right? http://paste.lisp.org/display/94503 |
| 20:37 | hiredman | I don't know |
| 20:45 | hiredman | http://gist.github.com/297122 |
| 20:46 | zaphyr | instruction 12 \o/ :) |
| 20:46 | zaphyr | i presume you only box everything back up at the very end |
| 20:47 | zaphyr | so there could be much hair in that function |
| 20:47 | hiredman | the compiler infrastructure takes care of that |
| 20:47 | hiredman | it's pretty nice, .emit vs. .emitUnboxed |
| 20:48 | zaphyr | i like it |
| 20:48 | hiredman | in this case .emit calls .emitUnboxed and then does the boxing stuff |
| 20:49 | zaphyr | yeah. literally my only gripes are lack of primitive types in arguments/return, and inability to also inline that (for extreme performance win). copy-in-place optimization would probably make my vector math library faster than the java version... |
| 20:50 | hiredman | it's neat to see the locals clearing stuff aconst_null, astore_1 |
| 20:50 | hiredman | ,(doc definline) |
| 20:50 | clojurebot | "([name & decl]); Experimental - like defmacro, except defines a named function whose body is the expansion, calls to which may be expanded inline as if it were a macro. Cannot be used with variadic (&) args." |
| 20:51 | hiredman | I now rhickey is thinking/working on a primitive argument interface to fns |
| 20:51 | zaphyr | yeah, but i want an inline metadata to stuff on standard fns |
| 20:52 | zaphyr | although, definline does do the trick for now |
| 20:52 | zaphyr | just means i have lots more #'s in my code than i'd like |
| 20:53 | hiredman | clojurebot: performance |
| 20:53 | clojurebot | http://clojure.org/java_interop#toc46 |
| 20:57 | zaphyr | yeah. actually it was unclear, do i need (int ...) around Float/floatToIntBits, given that that returns an int anyway? I'd imagine not |
| 20:58 | hiredman | I don't think so |
| 20:59 | zaphyr | figures. that and a bunch of vector math stuff was the first thing i wrote in clojure, and already it looks silly |
| 21:00 | Mec | In emacs, is there a way to redirect the output from lisp-eval-last-sexp to the repl instead of *messages*? |
| 21:16 | Lewisham | hi all, can anyone figure out how I would get this function to work? recur isn't the tail expression, but I can't seem to work out how to get it to be the last expression... http://pastie.org/812951 |
| 21:22 | somnium | Lewisham: try writing it with reduce |
| 21:22 | Mec | (reduce + (map count-words lines)) |
| 21:23 | Lewisham | ah, I thought about that, but what I actually return is a map of the words and their occurance, such as {"Me" 1, "You" 2} |
| 21:23 | Lewisham | that's why I was using merge-with |
| 21:24 | Lewisham | so it keeps merging the maps until you get one final big one |
| 21:24 | Lewisham | but it (understandably) barfs on a file of any large size |
| 21:24 | Lewisham | with a StackOverflowError |
| 21:24 | hiredman | use reduce |
| 21:25 | Mec | so count-words returns a map? |
| 21:25 | Lewisham | Mec: yes :) |
| 21:26 | Lewisham | (reduce (merge-with +) (map count-words lines)) ? |
| 21:26 | hiredman | you need to use partial |
| 21:26 | Lewisham | that NPEs in my code, but that's not to say it's because my count-words function is bad |
| 21:26 | hiredman | ,(merge-with +) |
| 21:26 | clojurebot | nil |
| 21:26 | hiredman | ^ |
| 21:27 | hiredman | ,(reduce nil '(1 2)) |
| 21:27 | clojurebot | java.lang.NullPointerException |
| 21:27 | hiredman | ^- |
| 21:27 | Lewisham | ah |
| 22:04 | technomancy | just in case anyone's not following the mailing list, there's a Seattle Clojure meeting next thursday: http://bit.ly/d1rwpe |
| 22:07 | Lewisham | hiredman: Mec: somnium: I got it working, thank you :) Just have to hope I get my RAM back at some point :) |
| 23:16 | ag90 | Hey I have a question. I'm working on this code and for the past few hours I was stuck on this small function. After many random printlns I concluded that it got stuck when it called a particular function. No errors. It just didn't work. When I tried that function in REPL, I got a simple error about trying to use a reference as a sequence. Worked perfectly after dereferencing. How can I enable such error messages outside the REPL? |
| 23:16 | ag90 | TL;DR - I want to know if there's a way for Clojure to raise errors outside the REPL when running as a script? |
| 23:16 | technomancy | ag90: the main difference between the repl and stuff inside a script is that the repl prints everything, which forces lazy sequences to be evaluated |
| 23:17 | technomancy | you can wrap a lazy sequence in "dorun" or "doall" to force it in any context |
| 23:17 | ag90 | Oh. So this problem was because of laziness? |
| 23:17 | ag90 | (the missing error messages) |
| 23:17 | technomancy | 90% sure it is |
| 23:18 | technomancy | that's by far the most common cause of "works one way in the repl; another way in a script" problems |
| 23:18 | ag90 | Oh. Great! Thanks. |
| 23:19 | technomancy | use dorun if you need return values; use doall if you just want to force the seq |
| 23:19 | technomancy | or possibly replace for/map with doseq; depends on the context |
| 23:27 | tomoj | lancepantz: did you figure out the body thing with compojure? |
| 23:27 | tomoj | I just needed to do that as well |
| 23:27 | tomoj | I found a function in compojure called slurp-body which slurps the body into a string, but it's private |
| 23:27 | tomoj | so just ended up wrapping PushbackReader and InputStreamReader to hand to c.c.json.reda |
| 23:27 | tomoj | s/reda/read/ |
| 23:28 | tomoj | did it in middleware so in a handler (:json request) is the parsed json body |
| 23:28 | hiredman | that is a nifty idea |
| 23:30 | tomoj | it gave me an "I love clojure" moment |
| 23:30 | tomoj | :) |
| 23:32 | piccolino | How would one check if a particular object is an instance of an array of bytes? I'm having trouble with isa? and instance?, neither seems to work with bytes as a parameter. |
| 23:32 | tomoj | hmm.. I feel like I also could use a macro over let which lets you bind names to values in maps in the request map, to replace (let [foo (-> request :bar :foo) bizz (-> request :baz :bizz)] ..) |
| 23:34 | tomoj | ,(instance? (Class/forName "[B") (byte-array 10))) |
| 23:34 | clojurebot | true |
| 23:34 | tomoj | wonder if there is a prettier way to get (Class/forName "[B") ... |
| 23:34 | piccolino | Ah, OK, thanks. |
| 23:34 | hiredman | tomoj: not really |
| 23:35 | hiredman | for type hinting there is ^bytes |
| 23:35 | hiredman | #^bytes |