2010-09-19
| 00:15 | coldhead | i'm looking at this line (.. '(1 2) getClass getProtectionDomain getCodeSource getLocation) |
| 00:15 | coldhead | i can't think what the equivalent Java would be |
| 00:16 | coldhead | any tips? |
| 00:18 | Raynes | That could also be written as (.getCodeSource (.getProtectionDomain (.getClass '(1 2)))) |
| 00:19 | coldhead | right, but i'm trying to think how i'd do it in java |
| 00:19 | coldhead | its apparently getClass().getProtectionDomain().getCodeSource().getLocation() |
| 00:19 | Raynes | Something like that. I don't know Java. :\ |
| 00:20 | coldhead | the order was confusing me |
| 01:53 | Raynes | http://github.com/Raynes/cake-autodoc |
| 01:57 | seancorfield | i'm reading joy of clojure and on page 229 it has (. ~(binding 0) ~'close) |
| 01:57 | seancorfield | what exactly do (. x y) do |
| 01:57 | seancorfield | (i'm sure it's just late and i'm missing something obvious) |
| 01:58 | seancorfield | i can see that ~(binding 0) is the bound local name (page in the example) |
| 01:59 | seancorfield | and that ~'close returns the symbol close |
| 01:59 | seancorfield | but i'm having a hard time figuring out what (. page close) does (especially given the comment in the book that this example works for non closable resources) |
| 02:12 | hiredman | clojurebot: special forms? |
| 02:12 | clojurebot | special forms are http://clojure.org/special_forms |
| 02:19 | seancorfield | hiredman: then all it's doing is calling page.close() - but that contradicts what the book says about non-closable resources which is why i asked |
| 02:19 | seancorfield | maybe the book just isn't clear - i'll ask fogus / chouser next time they're around (or post on the manning forum) |
| 02:34 | seancorfield | joy of clojure says "Because Clojure namespace names are tied to the directory in which they reside,"... but that's not actually true is it? |
| 02:35 | seancorfield | i seem to be able to declare any namespace in a file, regardless of its directory structure |
| 02:35 | bobo_ | seancorfield: but can you include it in another ns? |
| 03:06 | seancorfield | bobo_: ok, experimentation has now convinced me... thanx... not sure why that didn't seem to be the case before :( |
| 03:06 | bobo_ | :-) |
| 03:06 | seancorfield | maybe i'll simplify cfmljure to rely on that :) |
| 03:07 | bobo_ | whats cfml? |
| 03:08 | bobo_ | ah cold fusion |
| 03:09 | seancorfield | yeah, cfmljure is a bridge project to make it seamless to use clojure from cfml |
| 03:09 | seancorfield | cfml is a pretty good web templating language |
| 03:10 | seancorfield | and i use railo - which is a jboss community project that provides a free open source cfml engine |
| 03:10 | bobo_ | :-) |
| 04:04 | LauJensen | Good morning all |
| 04:24 | neotyk | Good morning Lau |
| 04:28 | hamza` | morning |
| 05:20 | _ulises | morning |
| 06:20 | zmyrgel | how can I split a long string after each 8th character? |
| 06:20 | zmyrgel | I need to add '/' to my string after each 8 char seq |
| 06:29 | raek | it is possible to do it like this, but there are probably more elegant ways of doing it: |
| 06:29 | raek | ,(->> "abcdefghijklmnopqrstuvwxyz" (partition 8 8 nil) (interpose [\/]) (apply concat) (apply str)) |
| 06:29 | clojurebot | "abcdefgh/ijklmnop/qrstuvwx/yz" |
| 06:31 | noidi | I don't think you need the last two arguments to partition |
| 06:32 | noidi | ,(require 'clojure.string) |
| 06:32 | clojurebot | nil |
| 06:33 | noidi | ,(clojure.string/join "/" (partition 8 "asldfkjasdlfkjjasdflkj")) |
| 06:33 | clojurebot | "clojure.lang.LazySeq@71ff9be7/clojure.lang.LazySeq@a675bbe2" |
| 06:33 | noidi | ,(apply clojure.string/join "/" (partition 8 "asldfkjasdlfkjjasdflkj")) |
| 06:33 | clojurebot | java.lang.IllegalArgumentException: Wrong number of args (3) passed to: string$join |
| 06:33 | noidi | okay, that didn't work >( |
| 06:33 | noidi | :) |
| 06:34 | LauJensen | ,(reduce #(str %1 (when (zero? (mod (count %1) 8)) \/) %2) "" "this is a long string") |
| 06:34 | clojurebot | "/this is/ a long/ string" |
| 06:35 | zmyrgel | ok, the reduce seems a good option |
| 06:35 | zmyrgel | I'll try to see if I it is clearer to add the '/' chars while building the string |
| 06:36 | raek | ,(partition 8 "abcdefghijklmnopqrstuvwxyz") ; ignores the last letters |
| 06:36 | 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)) |
| 06:37 | noidi | ah, ok |
| 06:37 | raek | ,(partition 8 8 nil "abcdefghijklmnopqrstuvwxyz") |
| 06:37 | 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)) |
| 06:37 | raek | a bit weird default behaviour... |
| 06:37 | zmyrgel | ah, never mind. Just noticed that '/' won't go after each 8 chars all the time |
| 06:38 | zmyrgel | Have to get my string builder loop to handle the insertion at proper places |
| 06:39 | LauJensen | zmyrgel: thats the nice thing about reduce, just change the predicate and it still works |
| 06:42 | zmyrgel | LauJensen: well, its harder to use reduce as the rules for / insertion aren't obvious |
| 06:58 | bonega | I am making a tetris in clojure. |
| 06:58 | bonega | My problem is: If I evalute my state in the REPL it gets very sluggish for a period of time. |
| 06:58 | bonega | This seems directly related to *print-level* - any ideas? |
| 07:04 | Vinzent | hm, what's the right way to remove an element from the vector by index? |
| 07:15 | raek | you cannot remove an element from a persistent vector in constant time (other from the end) |
| 07:16 | raek | you can create subvecs of the parts before and after the index in constant time |
| 07:16 | raek | but merging them is O(n) |
| 07:19 | raek | ,(let [v [:a :b :c :d :e]] (into (subvec v 0 2) (subvec v 3 5))) |
| 07:19 | clojurebot | [:a :b :d :e] |
| 07:31 | Vinzent | raek, yes, now i does exactly that, but anyway thanks for your irrefragable answer |
| 07:52 | LauJensen | zmyrgel: (reduce with-my-complex-rules "" string), then just write your rules in a cond/condp statement. Should be very simple |
| 09:01 | shanmuha | Hi, I am trying to use clojure.contrib.lazy-xml |
| 09:11 | Bahman | Hi all! |
| 09:15 | LauJensen | Hi |
| 09:20 | mrBliss | how should I name a test for xy->i? (question mark isn't part of the name) xy->i-test or stick with the original name? (test is in namespace project.test.core) |
| 09:22 | LauJensen | mrBliss: I think suffixing -test reads very intuitively |
| 09:23 | mrBliss | LauJensen: thanks |
| 09:28 | LauJensen | np |
| 09:45 | LauJensen | This is fascinating |
| 09:45 | LauJensen | ,((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x))))) |
| 09:45 | clojurebot | ((fn [x] (list x (list (quote quote) x))) (quote (fn [x] (list x (list (quote quote) x))))) |
| 09:45 | LauJensen | Especially thinking back on the first C quine I ever saw |
| 09:59 | ranjit_c | e |
| 10:00 | ranjit_c | hello? |
| 10:00 | clojurebot | BUENOS DING DONG DIDDLY DIOS, fRaUline ranjit_c |
| 10:02 | jjido | is anyone ready to give advice for improving my code? http://pastebin.ca/1944174 |
| 10:04 | jjido | I am new to Clojure, don't know all the idioms yet |
| 10:06 | LauJensen | jjido: Pastebin isn't loading and in any case, I prefer gists :) |
| 10:07 | jjido | LauJensen: gists URL? |
| 10:07 | LauJensen | github.com |
| 10:07 | LauJensen | But what I like about it, is I select the region of code I want to gist, then hit M-x gist-region, and if you post a gist in here, I hit M-x gist-fetch id |
| 10:08 | ranjit_c | so is this a reasonable way to initialize a 2d array in clojure; (def A (into-array (map double-array (partition L (repeat (* L L) 1))))) |
| 10:08 | ranjit_c | it seems a lot slower than the equivalent in python |
| 10:08 | jjido | http://gist.github.com/586791 |
| 10:09 | LauJensen | jjido: Right now I have all of your code loaded in a buffer next to this chat, with proper highlighting etc, and if I want I can eval your functions and test them in the repl, hows that for integration? |
| 10:09 | mrBliss | LauJensen: I didn't know about gist-fetch yet, good to know! |
| 10:10 | LauJensen | mrBliss: Find gist.el on github |
| 10:11 | mrBliss | LauJensen: I'm already using it for posting my gists, now I'll use it also to read others people's gists :) |
| 10:11 | LauJensen | ah ok |
| 10:12 | LauJensen | jjido: So it looks like you've introduced a new type SimpleList and do so via bundling its interfaces in defstructs, which I doubt was ever idiomatic, but with the coming of protocols and records definitely isnt the way to go |
| 10:14 | jjido | LauJensen: what is a good way to do a new type? |
| 10:14 | LauJensen | jjido: defrecord/deftype |
| 10:15 | Vinzent | hm, looks like I have a trouble. When I do lein test, no test runs, this is the output: http://gist.github.com/586797, but test are defined in those namespaces |
| 10:16 | Vinzent | and *load-tests* is true |
| 10:17 | jjido | it is not here http://clojure.org/data_structures still looking for info |
| 10:19 | Vinzent | I'm putting tests and code in same namespaces, but different files (that allows me to test private functions), may the problem be in that? |
| 10:20 | jjido | I can see it in the API page but no examples :-( any suggestion where to learn about defrecord and deftype? |
| 10:21 | Vinzent | jjido, http://vimeo.com/11236603 |
| 10:24 | LauJensen | jjido: http://bestinclass.dk/index.clj/2010/04/prototurtle-the-tale-of-the-bleeding-turtle.html - very simple |
| 10:25 | jjido | thx |
| 10:28 | fbru02 | so when i want to include a jar file from disk the only way is letting lein frail and add it to the ~/.m2 folder using mvn? |
| 10:33 | Vinzent | seems so |
| 10:34 | raek | didn't lein install do something like that? |
| 10:35 | Vinzent | probably lrin install installing lein projects |
| 10:37 | raek | I guess you could also place the jar in the lib/ directory |
| 10:37 | raek | if it isn't a maven artifact |
| 10:38 | fbru02 | raek: yes, the problem often they are maven artifacts , i'm tired of dealing with maven-deploy-plugin and others |
| 10:38 | mrBliss | raek: don't you lose the jar when you execute lein deps? |
| 10:39 | fbru02 | mrBliss: i think you lose the entire lib directory?? |
| 10:40 | raek | hrm, yes |
| 10:40 | raek | if you develop multiple clojure projects in parallel, you can use the checkouts feature |
| 10:43 | Vinzent | anyway i think it's a good idea to write a lein plugin that will do it |
| 10:46 | florianjunker | Will compojure 0.4.1 work with ring 0.3.0, or will I have to keep using ring 0.2.6? |
| 11:01 | jjido | Once I have an instance of (defrecord SimpleList [values]), how do I get to its values? |
| 11:03 | jjido | ,(:values (do (defrecord SimpleList [values]) (SimpleList. [])) |
| 11:03 | clojurebot | EOF while reading |
| 11:03 | jjido | ,(:values (do (defrecord SimpleList [values]) (SimpleList. []))) |
| 11:03 | clojurebot | DENIED |
| 11:03 | jjido | ,(:values (doseq (defrecord SimpleList [values]) (SimpleList. []))) |
| 11:03 | clojurebot | java.lang.IllegalArgumentException: doseq requires a vector for its binding |
| 11:04 | fliebel | ,(first (lazy-seq (println :a) (println :b))) |
| 11:04 | clojurebot | :a :b |
| 11:05 | fliebel | How do I get that to only print :a? |
| 11:05 | LauJensen | jjido: (defrecord tmprec [f1]) => (tmprec. 1) => (:f1 inst) => 1 |
| 11:06 | jjido | ok so I am right. I get a NPE :( |
| 11:06 | jjido | somewhere |
| 11:10 | LauJensen | jjido: I dont know if you're right or not, but get the values by calling the keyword with the instance, or get all keys my calling (vals instance) |
| 11:10 | jjido | (:values instance) |
| 11:10 | jjido | right? |
| 11:11 | LauJensen | (vals instance) |
| 11:14 | fliebel | ,(first (cons (println 1) (lazy-seq [(println 2)]))) |
| 11:14 | clojurebot | 1 |
| 11:15 | fliebel | that works… any better way? |
| 11:15 | LauJensen | fliebel: of doing what exactly? |
| 11:16 | fliebel | LauJensen: Defining a lazy seq of a series of expressions. |
| 11:17 | jjido | I get a NPE when I try to do a doc string for my extend-protocol function |
| 11:21 | fliebel | LauJensen: concat is lazy, but it does evaluate the expressions. |
| 11:23 | LauJensen | fliebel: Rarely do I see people chaining expresses without wrapping them in a thunk |
| 11:24 | fliebel | LauJensen: thunk? |
| 11:24 | LauJensen | (fn [] (+ 2 2)) or something similar |
| 11:26 | fliebel | LauJensen: I have a function that returns 2 parts, where both involve io, but sometimes I need only the first part, so I'm seeking a way to return both results in a lazy manner, so that only the first part is computer if the second part is not requested. |
| 11:27 | LauJensen | [5 (fn [] (println "doing io"))] |
| 11:28 | fliebel | LauJensen: But then the other side has to call the second fn to get the result? I thought I could just create a lazy seq for the results, which is what I did with the cons above, |
| 11:30 | LauJensen | Yea I guess you can. Just saying you dont see that a lot. In fact I dont think Ive seen it done that way before |
| 11:30 | raek | fliebel: this is a validator library I'm working on. the functions cons-validator-step and concat-validator-step might be inspirational |
| 11:30 | raek | fliebel: http://gist.github.com/586836 |
| 11:30 | raek | basically, create a new fn that may or may not call the fn of the next step |
| 11:30 | raek | the whole chain becomes one fn |
| 11:31 | raek | unfortunately, I don't have time to explain more today. hope you find something useful in it |
| 11:31 | fliebel | thanks |
| 11:32 | chouser | fliebel: your (cons x (lazy-seq [y])) looks fine to me. |
| 11:32 | chouser | I might use (list y) instead of [y] in this particular case, but I'm not sure it's actually any better. |
| 11:32 | LauJensen | chouser: why list? |
| 11:33 | chouser | because then you're creating a thing that actually implements Seq, which is the whole point. |
| 11:33 | chouser | [y] is a vector, which then gets wrapped in a chunked-seq |
| 11:34 | LauJensen | ah right |
| 11:34 | chouser | ,(let [ys (list 1)] (identical? (seq (lazy-seq ys)) ys)) |
| 11:34 | clojurebot | true |
| 11:34 | chouser | ,(let [ys [1]] (identical? (seq (lazy-seq ys)) ys)) |
| 11:34 | clojurebot | false |
| 11:34 | chouser | using a vector means there's an extra allocation |
| 11:35 | chouser | but like I said, I'm not sure which is actually more idiomatic. |
| 11:35 | fliebel | I like the list better, I think it makes sense. |
| 11:36 | chouser | bbl |
| 11:38 | fliebel | It works :) Sweet! |
| 12:00 | fliebel | How bad is it to leave files open? which if the effect of not consuming a complete line-seq, if I'm correct. |
| 12:14 | technomancy | fliebel: it's a resource leak; there's a hard limit to the number of files you can have open |
| 12:14 | technomancy | just means you might not be able to open files in the future if you leak too many |
| 12:35 | fliebel | technomancy: Thanks I don't think I'll open that many. |
| 12:56 | brandonz | hi all. i was wondering if anyone had any experience with jgir. i was trying to use it to bring up some java-clutter bindings but seem to be failing. |
| 13:18 | LauJensen | Gents, Im having a problem with JFreeChart, where the chart only will render in a JTabbedPane (and not either JPanel or JScrollPane), any idea whats up ? |
| 13:54 | LauJensen | Hmm, seems its another oddity of setContentPane |
| 14:03 | octagon | hi! i'm looking for a good link for getting started with clojure, slime, emacs, etc on osx. |
| 14:06 | phobbs | http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Mac_OS_X! |
| 14:06 | phobbs | http://en.wikibooks.org/wiki/Clojure_Programming/Getting_Started#Mac_OS_X |
| 14:06 | octagon | awesome thanks |
| 14:10 | fliebel | Huh… calling a fn with a signature of [[markdown static]] with a list of 2 as argument will result in having markdown and static, right? I get "Wrong number of args (2)", while I'm only passing a list. It almost seems like there is a hidden apply in there, or I got my expansion wrong. |
| 14:14 | fliebel | *adds an ampersand* |
| 14:19 | kumarshantanu | hi, I am trying to find out what is clojure.lang.Cons |
| 14:19 | fliebel | ,(doc cons) |
| 14:19 | clojurebot | "([x seq]); Returns a new seq where x is the first element and seq is the rest." |
| 14:20 | kutku | I want to solve this problem in clojure, can anyone give me a hint on where to start? |
| 14:20 | kutku | http://pastebin.com/WyP7uggz |
| 14:22 | fliebel | kutku: You'll need to get some sin and cos functions somewhere, I think Java has a Math module, also ctonains a PI constant if I'm correct. |
| 14:25 | sproust | fliebel: are you looking for a lazy version of (do)? |
| 14:27 | LauJensen | ,(Math/sin 5) |
| 14:27 | clojurebot | -0.9589242746631385 |
| 14:27 | fliebel | sproust: No |
| 14:29 | kutku | what if I calculate the X and Y coordinates and divide them by /2 and calculate the square |
| 14:34 | sthuebner | ,(and () ()) |
| 14:34 | clojurebot | () |
| 14:35 | sthuebner | ,(true? (and () ())) |
| 14:35 | clojurebot | false |
| 14:35 | sthuebner | ,(if (and () ()) :a :b) |
| 14:35 | clojurebot | :a |
| 14:35 | sthuebner | hm, that seems odd! |
| 14:37 | mrBliss | sthuebner: (true? x) is only true when x is identical to true |
| 14:37 | mrBliss | the same with false? |
| 14:37 | sthuebner | so 'if doesn't check for true? |
| 14:37 | LauJensen | sthuebner: if/when runs their (first) body if the predicate is non-nil and non-false |
| 14:37 | LauJensen | (if (seq ()) :a :b) |
| 14:37 | LauJensen | ,(if (seq ()) :a :b) |
| 14:37 | clojurebot | :b |
| 14:38 | LauJensen | nil punning is not encouraged, instead wrap your sequence in a call to seq which evals to nil if its empty |
| 14:38 | sthuebner | ah! That's the reason for all those seq calls in labrepl! |
| 14:39 | sthuebner | I was wondering about that |
| 14:41 | sthuebner | thanks, mrBliss + LauJensen |
| 14:41 | LauJensen | np |
| 14:42 | fliebel | This is insane… user=> (fcopy app) |
| 14:42 | fliebel | java.lang.IllegalArgumentException: Wrong number of args (2) |
| 14:50 | sproust | LauJensen: the seq wrapping for boolean context has to be the most inelegant part of clojure I know of. |
| 14:51 | LauJensen | sproust: Thats because you dont know enough Clojure :) |
| 14:51 | sproust | Maybe. |
| 14:52 | sproust | It's an idiomatic way of resolving boolean context that is not intuitive. I had the same questions as sthuebner the other day. |
| 14:53 | sproust | What's the benefit of treating empty collections as boolean true? |
| 14:53 | sthuebner | yeah! I agree! In Common Lisp () is false |
| 14:53 | fliebel | I'm not sure I understand, can't you just use (boolean)? |
| 14:54 | LauJensen | I think it was a trade we did, to get fully lazy sequences |
| 14:54 | LauJensen | chouser will certainly remember the details :) |
| 14:55 | sproust | Lau: you mean that otherwise you'd have had to evaluate the lazy sequence? |
| 14:55 | LauJensen | sproust: yea, or at least consume an item |
| 14:56 | sproust | Seems like a bad tradeoff to me. All those (seq) calls everywhere... |
| 14:56 | fliebel | LauJensen: Makes sense :) I think it's good |
| 14:57 | sthuebner | Has the use of 'next over 'rest the same roots? |
| 14:57 | LauJensen | sproust: Well. The problem is, Rich decided to solve a performance problem by introducing chunks. So if you consume one item, you can actually end up consuming 32 items, making an if statement potentially expensive. I dont know if this goes away when chunks go away. |
| 14:57 | LauJensen | sthuebner: yes, introduced at the exact same time |
| 14:57 | sproust | Hey wait... don't you have to evaluate an element anyway if you wrap with seq? |
| 14:59 | sproust | ,(let [lseq (map prn (range 3))] (if (seq lseq) (prn 'a) (prn 'b))) |
| 14:59 | clojurebot | 0 1 2 a |
| 14:59 | sproust | So how does wrapping with seq help in any way? |
| 15:10 | chouser | empty list was never actually false |
| 15:10 | chouser | even before the "lazier" changes |
| 15:10 | chouser | if an empty list is false, then shouldn't an empty map, set, and vector be as well? |
| 15:10 | chouser | what about empty strings? |
| 15:11 | chouser | that way lies madness. Only two things are false: nil and false |
| 15:11 | chouser | before "lazier" many things returned nil instead of an empty lazy seq. This included filter, etc. |
| 15:13 | chouser | but in order to get the lazier behavior, something had to give. You can tell there's no more in a lazy seq without asking for the next thing, which would force that step |
| 15:14 | chouser | so no map, filter, etc. always return lazy seqs which may be empty instead of nil, and empty seqs are still not false. |
| 15:14 | chouser | you have to explicitly ask for the next step if you want to find out if it's empty or not. 'seq' does that, as does 'next' (as opposed to 'rest') |
| 15:14 | chouser | bbl |
| 15:21 | Raynes | sproust: ^ In case you missed it. |
| 15:24 | fliebel | *applauds for chouser's e-lecture* |
| 15:54 | solussd | how do you unload everything added to the namespace using 'use' ? |
| 15:54 | Chousuke | you can use ns-unmap |
| 15:55 | Chousuke | but there's no automatic way |
| 15:55 | solussd | if I did, say, a (use 'clojure.contrib.repl-utils) how can I unload all the symbols that interned into my current namespace? |
| 15:55 | solussd | can ns-unmap take a wildcard? :) |
| 15:55 | Raynes | solussd: http://groups.google.com/group/clojure/browse_thread/thread/c3fae246e06ffd7e/2f52400ca5a374dc |
| 15:56 | solussd | thanks raynes |
| 16:04 | sproust | solussd: remove-ns also works well. |
| 16:11 | vishsingh | having some issues getting swank-clojure working today, would appreciate any ideas. |
| 16:11 | vishsingh | i've basically got to the point where i can do "lein swank" in a project directory, and get a swank server running. |
| 16:12 | vishsingh | and i can do Alt-X slime-connect from emacs, and it successfully connects to the swank server. the slime-repl comes up, everything seems awesome. |
| 16:13 | vishsingh | unfortunately when I type a clojure form and hit enter.. nothing happens. it's just like I hit enter in a regular buffer, my cursor moves down. |
| 16:14 | vishsingh | the enter key is bound to the right thing.. slime-repl-return or whatever it is. something is clearly wonky and I don't know what. |
| 16:19 | laurus | I'm running a simple "Hello, World!" script using cljr, and it's quite slow. Is this because it needs to "start" Clojure every time? Is there a way to have Clojure more "ready" in the background for running scripts? I'm on GNU/Linux if that matters. |
| 16:20 | Chousuke | cake can do it for you |
| 16:20 | Chousuke | it keeps a JVM instance running |
| 16:20 | laurus | Hmm, ok I'll check it out! |
| 16:21 | laurus | Oh, it's yet another build tool, heh. |
| 16:21 | laurus | Chousuke, is there a way to do it with cljr, or just plain Java? |
| 16:21 | Chousuke | laurus: well, yes, but you'd end up reimplementing cake anyway I think :P |
| 16:22 | laurus | "Clojure also suffers from the JVM's slow startup time. This pretty much rules Clojure out for one-off scripting and other stuff where startup time can be a hindrance." Is that really true? |
| 16:22 | laurus | I want to use it for scripting! Hehe |
| 16:22 | Chousuke | well, yeah |
| 16:22 | laurus | Aww, ok, I guess I'll keep these Python scripts around then. |
| 16:22 | LauJensen | laurus: try java -client |
| 16:22 | Chousuke | unless you keep a JVM instance running at all times, running fast scripts is not very feasible |
| 16:23 | Chousuke | since the startup is at best a second :P |
| 16:23 | Chousuke | sometimes longer. |
| 16:23 | laurus | Chousuke, well I don't mind leaving it running at all times, unless there's a drawback to it I'm not aware of. |
| 16:23 | laurus | LauJensen, what does that do? |
| 16:23 | Chousuke | laurus: well, other than taking up memory, not really. |
| 16:23 | laurus | Maybe cljr is the bottleneck and not the JVM startup. |
| 16:23 | LauJensen | $ time java -cp clojure-1.2.0-master-20100813.160144-94.jar -client clojure.main -e '(println "hello")' |
| 16:23 | LauJensen | hello |
| 16:23 | LauJensen | |
| 16:23 | LauJensen | real 0m1.174s |
| 16:23 | sexpbot | LauJensen: The time is now 2010-09-19T20:20:58Z |
| 16:23 | LauJensen | user 0m1.320s |
| 16:23 | LauJensen | sys 0m0.060s |
| 16:23 | LauJensen | |
| 16:24 | LauJensen | I guess you can suffer 1 second boot time |
| 16:24 | laurus | LauJensen, well it's more like 5 seconds on this computer for some reason |
| 16:24 | LauJensen | laurus: with the above line? |
| 16:25 | laurus | LauJensen, I get "real 0m0.019s" |
| 16:25 | laurus | :P |
| 16:25 | LauJensen | Thats nice :) |
| 16:25 | laurus | "time cljr run hello-world.clj" gives me "real 0m3.324s" |
| 16:26 | laurus | "time java -jar clojure.jar hello-world.clj" gives me "real 0m1.391s." |
| 16:26 | laurus | So I guess cljr is the slow one here. |
| 16:26 | laurus | It's too bad because I wanted to use cljr to run Clojure from anywhere since it already does that |
| 16:26 | LauJensen | java doesnt run anywhere? |
| 16:26 | laurus | At the same time, how important is 2 seconds really :P |
| 16:27 | laurus | LauJensen, I mean, I have to specify the path to the Clojure jar, right? |
| 16:27 | LauJensen | laurus: yea it needs to know where it is |
| 16:27 | laurus | Right, cljr takes care of that already. |
| 16:27 | Raynes | LauJensen: Try cake. |
| 16:27 | LauJensen | unless you install it in the jvms boot lib, which I think is possible but haven't tried |
| 16:27 | Raynes | Er, laurus. |
| 16:27 | LauJensen | Raynes: stop it, you're making me hungry |
| 16:28 | Raynes | Cake uses persistent JVMs, and can do the same thing, only faster. |
| 16:28 | laurus | Raynes, that's true, but then I'd have to install ruby |
| 16:28 | LauJensen | Raynes: You're pretty much repeating Chousuke's advice from above |
| 16:28 | Raynes | I didn't check the backlogs. |
| 16:28 | laurus | Raynes I appreciate it |
| 16:28 | Raynes | And why is that such a big problem? :o |
| 16:28 | LauJensen | laurus: if you're on linux, installing Ruby takes like... 20 secs in Ubuntu and 5 in Arch ? |
| 16:28 | laurus | I don't know, I hate having to install more stuff |
| 16:28 | LauJensen | I think I'd make the investment |
| 16:28 | laurus | I like how cljr is a jar itself, that seems neat to me. |
| 16:29 | LauJensen | laurus: So make your script into an uberjar |
| 16:29 | LauJensen | A self-executable jar |
| 16:29 | LauJensen | doesn't need anything from the host except the jvm |
| 16:29 | laurus | LauJensen, oh, that's a neat idea. |
| 16:29 | LauJensen | And if you're feeling really motivated, finish the gcc-gcj project and compile to native :) |
| 16:29 | laurus | Hahahahaha :) |
| 16:29 | laurus | Despite having read two Java books in the past, I didn't know about self-executable jars. |
| 16:30 | LauJensen | laurus: 'cake uberjar' turns a project into an executable jar, which only depends on itself |
| 16:30 | laurus | Oh, wow. |
| 16:30 | laurus | So why doesn't everyone use cake instead of the other two then? |
| 16:30 | Raynes | Leiningen can do the same thing. |
| 16:30 | LauJensen | It requires a gen-classed namespace with the function (defn -main [& args] (do something)) in it |
| 16:30 | Raynes | And cake is new. |
| 16:30 | Raynes | Very, very new. |
| 16:30 | Chousuke | cake is also written in ruby ;P |
| 16:30 | Raynes | Only partially. |
| 16:30 | LauJensen | laurus: well... I think a lot of us are, and more are starting all the time |
| 16:30 | Raynes | It uses Ruby for the same thing that Lein uses bash for. |
| 16:30 | laurus | I see :) |
| 16:30 | LauJensen | Chousuke: It has a small Ruby bootstrap, thats it |
| 16:31 | Raynes | Most of it is actually written in Clojure. |
| 16:31 | laurus | Well I'll check it out when I have some time then! |
| 16:31 | laurus | Thanks for all the tips. |
| 16:31 | LauJensen | Its like lein, only with more features and a cool task/dependency system to boot |
| 16:31 | LauJensen | also, it doesn't censor your names, you can call your projects whatever you want |
| 16:31 | Raynes | Man, you're still worked over about that? :P |
| 16:31 | laurus | LauJensen, good to know |
| 16:32 | LauJensen | Raynes: Well - I dont like Censjureship :) |
| 16:32 | LauJensen | So I think, if that was the only thing which set them apart, I'd still go with Cake |
| 16:32 | LauJensen | But now that I have cross-platform and that fantastic task system, its pretty much a done deal |
| 16:33 | Chousuke | lein doesn't do censorship |
| 16:33 | Chousuke | :P |
| 16:33 | Chousuke | it merely gives good advice |
| 16:33 | LauJensen | Chousuke: Not so |
| 16:34 | Chousuke | it still works with badly named projects |
| 16:34 | laurus | Actually, there's another way to do this that I should have thought of in the first place. |
| 16:34 | laurus | Just have a cljr repl open at all times! |
| 16:34 | apeda__ | how do I increment a variable by 1 ? |
| 16:34 | laurus | And use it just like one would a bash terminal. |
| 16:34 | LauJensen | apeda__: (let [my-var (atom 0)] (swap! my-var inc)) |
| 16:34 | apeda__ | thanks |
| 16:35 | laurus | LauJensen, what do you think of that idea? |
| 16:35 | LauJensen | apeda__: Since Clojures data is immutable, you need to use an agent, a ref or an atom. Or hook into Java directly. Or a promise for edge cases |
| 16:35 | LauJensen | laurus: I cant tell, it depends on your use case. |
| 16:35 | LauJensen | brb |
| 16:35 | laurus | Good point :) |
| 16:38 | Chousuke | apeda__: note, that for most algorithms you shouldn't need to increment a variable. :) |
| 16:39 | Chousuke | ie. try to avoid mutability if you can. |
| 16:40 | LauJensen | apeda__: yea, something like (iterate inc 0) or (range) will do the same by way of making an infinite sequence of numbers always incrementing by one. This is functional programming. |
| 16:46 | apeda__ | how do I define a variable that I later on can use "inc" on to increment |
| 16:48 | LauJensen | apeda__: I think you need to spend some time on the basics of Clojure, functional programming and the concurrency semantics available in Clojure. Start at clojure.org |
| 16:48 | apeda__ | ok thanks |
| 16:48 | nex | how can i pass the values from lists when making a struct-map? |
| 16:52 | Chousuke | apeda__: see http://java.ociweb.com/mark/clojure/article.html |
| 16:53 | Chousuke | or well, that kind of skips the functional programming part :P |
| 16:54 | apeda__ | how do I cast a integer to float? I tried (float var) |
| 16:56 | hiredman | why do you need to cast an integer to a float? |
| 16:56 | apeda__ | becauase when I divide it returns the ratio |
| 16:57 | apeda__ | e.g. 22/7 |
| 16:57 | hiredman | and why can't you use a ratio? |
| 16:57 | apeda__ | because I want the answer as floating point |
| 16:57 | LauJensen | ,(float (/ 22 7)) |
| 16:57 | clojurebot | 3.142857 |
| 16:57 | apeda__ | ,(float 33) |
| 16:57 | clojurebot | 33.0 |
| 16:58 | apeda__ | i got different res on my repl..but ok |
| 16:58 | apeda__ | maybe I did smth wrong |
| 17:12 | apeda__ | what am I doing wrong? I commented out the loop and it works fine, I basically want to run that piece of code 5 times. http://pastebin.com/UEz6jEnj |
| 17:13 | LauJensen | apeda__: that is just so wrong |
| 17:13 | LauJensen | You should read a little about functional programming and the virtues of immutability |
| 17:14 | Chousuke | apeda__: you're writing imperative code |
| 17:14 | Chousuke | apeda__: Clojure is not designed for that :) |
| 17:15 | Chousuke | apeda__: one rule of thumb is, that if you're writing a def anywhere else but on the top level (ie. inside a function or a loop) you're doing something wrong. def'd vars are not supposed to change. |
| 17:15 | Chousuke | apeda__: what you need to do is design your algorithm so that you can implement it in a recursive manner |
| 17:16 | Chousuke | here you have two things that "change"; 'rsquared and 'hits |
| 17:16 | Chousuke | and x and y which are random values |
| 17:16 | apeda__ | ok im a bit lost .. and I am reading upon this. |
| 17:17 | apeda__ | Chousuke: ok. |
| 17:17 | Chousuke | apeda__: don't worry. functional programming is a big paradigm shift. |
| 17:17 | apeda__ | Chousuke: I guess :) |
| 17:17 | Chousuke | but it's not impossible to learn as long as you keep at it. |
| 17:17 | apeda__ | Chousuke: so where do I start in fixing my algorithm.. whats step 1? |
| 17:18 | Chousuke | hmmh |
| 17:19 | Chousuke | well first you need to figure out what calculations you could do if you could start with a "chosen" value |
| 17:19 | apeda__ | ok, I will define x as 0.3 and y as 0.5 |
| 17:19 | Chousuke | so your rsquared is now a value. ie, immutable |
| 17:20 | apeda__ | yes |
| 17:20 | Chousuke | it would be useful to make a function for it, so you can call (r-squared x y) |
| 17:20 | apeda__ | yes |
| 17:20 | apeda__ | let me do that then, brb |
| 17:20 | Chousuke | so there you have one mutable thing done away with |
| 17:23 | apeda__ | http://pastebin.com/ZzjTK2FP |
| 17:24 | Chousuke | now you wrapped all the code in a function (and the parameters are wrong) |
| 17:24 | Chousuke | you should've done it only for the rsquared calculation |
| 17:24 | apeda__ | ok ill fix it :) |
| 17:26 | jjido | I defined a function in a protocol that does not take an instance as first parameter. Is that allowed? How to invoke it? |
| 17:26 | Chousuke | you can't do that. |
| 17:26 | jjido | Chousuke: ok :-( |
| 17:27 | Chousuke | or rather, it makes no sense to do that |
| 17:27 | Chousuke | since there's nothing to dispatch on :P |
| 17:27 | Chousuke | so it's the same has a plain defn |
| 17:27 | apeda__ | http://pastebin.com/68K9JSHF |
| 17:27 | Chousuke | you have the syntax wrong |
| 17:27 | apeda__ | where |
| 17:28 | apeda__ | oh sorry |
| 17:28 | apeda__ | def = defn |
| 17:29 | Chousuke | http://pastebin.com/Gc7yzeyF like this |
| 17:29 | Chousuke | [x y], not [x] [y] :) |
| 17:30 | apeda__ | ok thanks. |
| 17:30 | Chousuke | but then you need a loop as well, to deal with the hits |
| 17:30 | apeda__ | i have an unmatched deliminer |
| 17:30 | Chousuke | not a for loop |
| 17:30 | apeda__ | trying to find it. |
| 17:30 | Chousuke | hmm yeah, probably. :P |
| 17:30 | Chousuke | probably the last one |
| 17:30 | apeda__ | it was! |
| 17:30 | apeda__ | fixed.. |
| 17:31 | Chousuke | anyway, to deal with "hits" you need a recursive loop. ie. instead of changing hits, you have it be an immutable parameter of the loop, and you "restart" it with a *new* value at the end. |
| 17:31 | Chousuke | clojure provides "loop" for this |
| 17:31 | apeda__ | I am lsitening. |
| 17:31 | Chousuke | it works like (loop [hits 0] code-here) |
| 17:32 | Chousuke | and in the "code-here" part somewhere you can call (recur (inc hits)) |
| 17:32 | hiredman | apeda__: you should consider reading too |
| 17:32 | Chousuke | and the loop restarts as before, but with hits now having a one larger value |
| 17:32 | Chousuke | note that nowhere are we mutating hits, we're just restarting the loop |
| 17:32 | Chousuke | with a new value |
| 17:33 | Chousuke | this is very important |
| 17:33 | apeda__ | that means I can take this out right: (def hits 0.0) |
| 17:33 | Chousuke | because that's what you'll do most of the time |
| 17:33 | Chousuke | yeah. |
| 17:33 | apeda__ | ok |
| 17:34 | Chousuke | the problem with your example is that it's not possibly to make completely functional because of the random values |
| 17:34 | Chousuke | but it'll do. |
| 17:35 | Chousuke | anyway, in the loop you'll need to make two local values x and y, with rand. use (let [x (rand)...] rest-of-the-code-here) for this |
| 17:35 | Chousuke | let is another important operator. it creates local bindings. again, immutable. |
| 17:35 | apeda__ | im trying |
| 17:39 | apeda__ | I am probably a bit off here: http://pastebin.com/Unv8dxB7 |
| 17:40 | Chousuke | yeah, you forgot parentheses from let |
| 17:40 | Chousuke | apeda__: stop thinking about statements |
| 17:40 | apeda__ | ok..I added parathesis |
| 17:41 | Chousuke | apeda__: clojure has only expressions. that means code that does (do (let [x 1]) (let [y 2]) x) is completely ineffective |
| 17:41 | Chousuke | you need to do (let [x 1, y 2] x) |
| 17:41 | Chousuke | the bindings are effective only *within* the let calll |
| 17:41 | Chousuke | (that comma is optional btw) |
| 17:42 | Chousuke | also you should put the defn outside the loop |
| 17:43 | apeda__ | what does this do: (let [x 1, y 2] x) |
| 17:44 | Chousuke | returns 1 |
| 17:44 | Chousuke | ,(let [x 1] 1) |
| 17:44 | clojurebot | 1 |
| 17:44 | Chousuke | ,(do (let [x 1] 1) x); note |
| 17:44 | clojurebot | java.lang.Exception: Unable to resolve symbol: x in this context |
| 17:45 | Chousuke | that's the same as doing (do 1 x) |
| 17:45 | apeda__ | why do I need it in my algorithm? |
| 17:45 | Chousuke | because you need some place to put the random values |
| 17:45 | Chousuke | and they are local to the loop |
| 17:46 | apeda__ | so I put that code before my (let [y (rand)]) ? |
| 17:46 | Chousuke | what code? |
| 17:46 | apeda__ | this is what I have so far: http://pastebin.com/458WAVpw |
| 17:47 | Chousuke | no, see, you're still thinking that those let statements affect code further below |
| 17:47 | Chousuke | they don't |
| 17:47 | Chousuke | because they're not statements |
| 17:47 | apeda__ | I need to get out of the old way of thinking. |
| 17:47 | Chousuke | the syntax of let is (let [some-bindings here] code-where-bindings-work) |
| 17:48 | Chousuke | apeda__: start thinking of everything as an expression. |
| 17:48 | Chousuke | *everything* returns a value |
| 17:48 | Chousuke | the let expression returns a value too |
| 17:48 | Chousuke | it returns whatever the code-expression returns. |
| 17:48 | Chousuke | so |
| 17:48 | Chousuke | ,(let [x 1] (+ 5 x)) |
| 17:48 | clojurebot | 6 |
| 17:48 | Chousuke | let returns 6 |
| 17:49 | apeda__ | yes |
| 17:49 | Chousuke | similarly, the loop I showed you earlier is another expression |
| 17:49 | Chousuke | it returns a value just like let does |
| 17:49 | Chousuke | but now you have a let inside the loop, so the loop returns whatever the let does! |
| 17:49 | apeda__ | ok, whats missing in my code now |
| 17:50 | apeda__ | I need to call r-squared from the loop right? |
| 17:50 | Chousuke | yeah |
| 17:50 | Chousuke | http://pastebin.com/u8hw3NDW |
| 17:50 | Chousuke | oops |
| 17:50 | Chousuke | forgot a closing ] |
| 17:50 | Chousuke | after the y (rand) |
| 17:50 | laurus | Do any Clojure people use JNode? |
| 17:51 | Chousuke | apeda__: you must basically do your if-check within the let now |
| 17:51 | apeda__ | so right after that missing ] i will call my r-square function |
| 17:51 | Chousuke | that's where you call r-squared. |
| 17:52 | apeda__ | yes |
| 17:52 | Chousuke | and then you need the special thing to restart the loop, ie. recur |
| 17:52 | Chousuke | it works like (recur new-value-of-loop-parameter) |
| 17:52 | Chousuke | like a recursive function |
| 17:53 | Chousuke | and if you don't want to restart the loop, just return a value |
| 17:53 | Chousuke | the loop ends |
| 17:53 | Chousuke | and the value is returned |
| 17:53 | Chousuke | ie. just put the return value in the other branch of the if |
| 17:53 | apeda__ | http://pastebin.com/c36ymFnu |
| 17:54 | apeda__ | i got it.. |
| 17:54 | apeda__ | let me work on that |
| 17:54 | Chousuke | you have no if there. :) |
| 17:54 | apeda__ | I have no if? |
| 17:55 | Chousuke | in what you just pasted |
| 17:58 | apeda__ | http://pastebin.com/FV7SqrWv |
| 17:58 | Chousuke | now you have another def there |
| 17:58 | Chousuke | that's wrong |
| 17:58 | Chousuke | defs inside functions are never correct. |
| 17:58 | apeda__ | ur right sorry |
| 17:58 | apeda__ | how do I capture the return value |
| 17:59 | Chousuke | you can put it in the let |
| 17:59 | Chousuke | but you could also just use it directly in the if |
| 18:01 | apeda__ | http://pastebin.com/tBrLMAR5 |
| 18:01 | apeda__ | im not getting errors, but I think I have my parenthesis wrong somewhere. |
| 18:01 | Chousuke | the if code is not inside the lets. (and you could've used the earlier let) |
| 18:01 | Chousuke | and the defs are still wrong |
| 18:02 | Chousuke | you're looking to make the loop return pi, not define anything |
| 18:02 | clojurebot | compiling clojure is rarely necessary to do yourself. |
| 18:02 | Chousuke | clojurebot: thanks :P |
| 18:02 | clojurebot | I don't understand. |
| 18:02 | apeda__ | now the if is outside let: http://pastebin.com/k1Fb7vm6 |
| 18:03 | Chousuke | yeah, it needs to be inside /: |
| 18:03 | Chousuke | what about this is confusing you? |
| 18:03 | apeda__ | http://pastebin.com/spam.php?i=Y2LUC1AM |
| 18:04 | Chousuke | anyway, this is what it needs to look like http://pastebin.com/pyhGD6he |
| 18:04 | Chousuke | now the loop expression returns pi |
| 18:04 | Chousuke | doesn't print it though |
| 18:04 | Chousuke | but you could wrap the entire loop expression in println to get it printed :) |
| 18:05 | Chousuke | of course, that's a silly thing to do |
| 18:05 | Chousuke | better to make the loop into a function |
| 18:05 | Chousuke | fortunately, that's easy |
| 18:06 | apeda__ | ok let me try to work on that. |
| 18:06 | Chousuke | I just noticed throws is undefined |
| 18:07 | Chousuke | hm |
| 18:08 | Chousuke | damn, does the number of throws affect the algorithm? |
| 18:08 | Chousuke | because if it does, then that does something else :P |
| 18:09 | Chousuke | apeda__: spoilers http://pastebin.com/fftm2GXE |
| 18:09 | apeda__ | basically, I want to pass throws, e.g 100 throws.. and get how many hits I got |
| 18:09 | Chousuke | ah, in that case you'll need to change that a lot |
| 18:10 | Chousuke | right now it just throws until it gets > 0.25 |
| 18:10 | Chousuke | and then quits |
| 18:10 | Chousuke | there's a better way though. |
| 18:10 | Chousuke | you should make a "throw-once" function |
| 18:12 | apeda__ | so a single function that returns hit or miss? |
| 18:12 | apeda__ | and then call it 100 times and capture its return values? |
| 18:12 | Chousuke | or r-squared |
| 18:13 | Chousuke | if you have a throw function, you can make a sequence of throws easily |
| 18:13 | Chousuke | liek this |
| 18:13 | Chousuke | ,(take 10 (repeatedly rand)) |
| 18:13 | clojurebot | (0.29019485547826773 0.24552194880643585 0.9978153461256136 0.48390336312321436 0.24757279827241707 0.36504819362606034 0.7135505090005937 0.27129678042771666 0.9895945815698848 0.23363070686385035) |
| 18:14 | Chousuke | that take is necessary because otherwise clojurebot would get stuck calculating an infinite number of rand values... for ten seconds :P |
| 18:16 | Chousuke | apeda__: I have to go now. keep trying |
| 18:16 | apeda__ | thanks for all the help!! |
| 18:16 | apeda__ | I will try to solve this |
| 18:16 | Chousuke | apeda__: the best advice I can think of is to forget everyhing you know about programming :P |
| 18:16 | apeda__ | lol |
| 18:16 | apeda__ | i guess so :) |
| 18:16 | Chousuke | because, really, functional languages work nothing like C, python or java. |
| 18:16 | Chousuke | there's a really fundamental difference in approach |
| 18:17 | Chousuke | and before you can grasp the basics of that approach, you'll have a really hard time with clojure |
| 18:17 | apeda__ | im trying to make the throw-once function |
| 18:18 | Chousuke | remember: expressions, not statements |
| 18:19 | Chousuke | functions return the last expression they evaluate |
| 18:19 | Chousuke | all previous expressions are completely ignored (though if they have side-effects they might affect the latter ones. but in general you want to avoid side-effects) |
| 18:19 | apeda__ | ok thanks! |
| 18:21 | apeda__ | http://pastebin.com/SuAdiZUK |
| 18:23 | Chousuke | hm. |
| 18:24 | Chousuke | that won't actually restart the loop since there's no recur |
| 18:24 | Chousuke | also it won't return a useful value (the return value of println is nil) |
| 18:25 | Chousuke | printing things is a side-effect too btw |
| 18:25 | Chousuke | so you should avoid it until you need it |
| 18:26 | Chousuke | when calculating pi, you don't need to print anything |
| 18:26 | Chousuke | you only need to print the result :) |
| 18:27 | apeda__ | ah.. |
| 18:28 | apeda__ | ill go nutse by the time im done lol |
| 18:28 | Chousuke | maybe you should try with something even simpler |
| 18:28 | Chousuke | just to get used to the idea of working with expressions |
| 18:29 | apeda__ | but im so close |
| 18:29 | Chousuke | just try evaluating ifs and lets and other things in a repl |
| 18:29 | apeda__ | I think once I have this problem done and study it ill have a better understanding |
| 18:29 | Chousuke | what you want to do is structure the code so that the value you want is at the "tail" somewhere |
| 18:30 | Chousuke | so when you simulate the code in your mind, the expression your want to return is the last one evaluated |
| 18:30 | apeda__ | can u wrap this up so I can take a look at how u do it |
| 18:31 | apeda__ | im just not used to this way of thinking although I have a good understanding of the actual problem |
| 18:31 | tomoj | I had never really thought about simulation of code in our minds |
| 18:38 | Chousuke | apeda__: http://pastebin.com/d3ab4mr2 I think this works |
| 18:39 | Chousuke | (don't call it with <0 throws, I sacrificed robustness for legibility :P) |
| 18:40 | apeda__ | hold on... |
| 18:40 | apeda__ | I got that running |
| 18:40 | apeda__ | but what is the return value? |
| 18:40 | apeda__ | amounth of hits? |
| 18:40 | apeda__ | how can hits be a non integer val? |
| 18:40 | Chousuke | pi. |
| 18:40 | Chousuke | hits is not? |
| 18:40 | apeda__ | oh ur right |
| 18:40 | apeda__ | hold on 1 sec. |
| 18:41 | Chousuke | the cond there is a three-branch conditional |
| 18:41 | Chousuke | it works like (cond condition1 then1 condition2 then2 condition3 then3...) |
| 18:42 | Chousuke | it evaluates the conditions in order and evaluates the corresponding then expr for the first condition that is true |
| 18:42 | Chousuke | see the :else there? that's an "always-true" condition |
| 18:42 | Chousuke | it's last, so it's the else branch :) |
| 18:43 | Chousuke | so if the cond goes and sees that there are no throws left (as indicated by the loop parameter), then it returns (* 4.0 (/ t hits)) |
| 18:44 | Chousuke | otherwise, it calls recur |
| 18:44 | Chousuke | which restarts the loop, with new values |
| 18:45 | Chousuke | and t is the number of throws you want to do |
| 18:46 | Chousuke | it doesn't change at all. |
| 18:46 | florianjunker | Looks like ring sessions aren't working |
| 18:47 | apeda__ | i fixed it |
| 18:47 | apeda__ | (* 4.0 (/ hits t)); |
| 18:47 | florianjunker | They set cookies, but I can't put anything inside and get it out again. |
| 18:47 | apeda__ | t hits should be hits t |
| 18:47 | apeda__ | thanks for all the help I got it working!!! |
| 18:47 | apeda__ | im going to study this now |
| 18:47 | apeda__ | so i get a better grasp |
| 18:47 | Chousuke | apeda__: yeah, do that |
| 18:47 | Chousuke | apeda__: try going through it in your mind a few times |
| 18:47 | Chousuke | see how it works |
| 18:48 | Chousuke | but now I need to go. |
| 18:49 | apeda__ | thanks a lot man!! |
| 18:49 | apeda__ | great great help thakns! |
| 18:56 | florianjunker | damn. ring sessions don't work with ring reloading. is there a workaround? |
| 19:20 | apeda__ | http://pastebin.com/fuYnUp97 |
| 19:20 | apeda__ | whats wrong with that? |
| 19:25 | amalloy | apeda__: recur only works if it's in the "tail position" - ie it is the last thing you will do before returning |
| 19:26 | apeda__ | makes sense |
| 19:26 | pdk | if the function you're trying to make tail recursive does anything with the return value of its recursive call other than simply return it back up |
| 19:26 | pdk | then don't expect recur to work |
| 19:27 | pdk | often functions can be restructured to fit this bill though |
| 19:28 | amalloy | apeda__: i don't think that's the "reason" this doesn't work, though. it looks like you're pretending that your loop is a (cond) |
| 19:31 | apeda__ | ok |
| 19:31 | apeda__ | im just playing aroudn trying to get a better grasp, thakns for all help. |
| 19:32 | apeda__ | I didn't think the clojure community would be this big. |
| 19:33 | amalloy | apeda__: i submitted an amendment for you |
| 19:35 | apeda__ | same url? |
| 19:35 | amalloy | um, i dunno. i don't know how pastie amendments work. try http://pastebin.com/JAVdt81c |
| 19:36 | amalloy | speaking of which, consider using pastie instead of pastebin - it has clojure syntax highlighting |
| 19:39 | apeda__ | I will in the future, im off for a little break. |
| 19:39 | apeda__ | thanks for everything |
| 19:39 | pdk | itd be nice to add some more of these handy links in the topic line |
| 20:56 | amaevis | is there any way to maintain a collection of all of the instances of a class without holding a reference forever and blocking garbage collection? |
| 20:57 | amaevis | in java |
| 22:21 | laurus | Raynes, could you tell me about the editor you were building in Clojure? |
| 23:18 | amalloy | hey rich, is there a reason we have assoc(-in) and get(-in), but only update-in (ie, no update)? |
| 23:19 | @rhickey | ,(doc update-in) |
| 23:19 | clojurebot | "([m [k & ks] f & args]); 'Updates' a value in a nested associative structure, where ks is a sequence of keys and f is a function that will take the old value and any supplied args and return the new value, and returns a new nested structure. If any levels do not exist, hash-maps will be created." |
| 23:19 | @rhickey | oh, no flat update |
| 23:19 | amalloy | right |
| 23:20 | @rhickey | no good reason, it has been requested before |
| 23:46 | tomoj | is the planet clojure feed broken? |
| 23:51 | tomoj | to match assoc/assoc-in I guess you'd want (update foo bar baz bing bang) |
| 23:51 | tomoj | which doesn't seem very useful at all |
| 23:51 | cais2002 | how does multimethod work if some implementations are located in a different namespace than the one with defmulti ? |
| 23:51 | amalloy | hiredman: you could use (assoc-in foo [bar] baz) too, but we have assoc for that |
| 23:53 | hiredman | *shrug* |
| 23:54 | hiredman | I think I would actually use (update-in foo [bar baz] (constantly bloop)) before thinking to use assoc-in |
| 23:57 | amalloy | tomoj: i suppose you're right, an update with the same parameter style as assoc would be silly |
| 23:58 | amalloy | but eg (update m f & keys) would be useful, maybe? or something like it |