2008-06-23
| 04:08 | jmbr | hi |
| 04:09 | jgrant | hi |
| 07:24 | spacebat_ | I think I'm missing something basic about clojure |
| 07:24 | spacebat_ | (def x 1) says I've bound #'user/x |
| 07:24 | spacebat_ | I can evaluate it with x |
| 07:24 | spacebat_ | and get 1 |
| 07:24 | drewr | spacebat_: You're in the user namespace by default. |
| 07:25 | spacebat_ | yup |
| 07:25 | spacebat_ | like common lisp |
| 07:25 | spacebat_ | but there is no setf |
| 07:25 | drewr | :-) |
| 07:25 | spacebat_ | (set! x 2) doesn't work |
| 07:25 | spacebat_ | (set! user/x 2) doesn't work |
| 07:26 | drewr | Clojure doesn't let you set a value that easily. |
| 07:26 | drewr | It's a feature. |
| 07:26 | spacebat_ | nor (set #'user/x 2) nor (var-set x 2) |
| 07:26 | drewr | x is a Var, which are immutable. |
| 07:26 | spacebat_ | but in a few places they say that Vars are mutable (thread locally) |
| 07:27 | spacebat_ | "While Vars ensure safe use of mutable mutable storage locations via thread isolation..." (http://clojure.org/refs) |
| 07:28 | drewr | You have to wrap it in a BINDING form, which is thread-local. |
| 07:28 | spacebat_ | each time I update it? |
| 07:28 | spacebat_ | but when I leave the binding that change is gone |
| 07:29 | drewr | What problem are you tring solve? |
| 07:29 | drewr | trying |
| 07:29 | spacebat_ | I have a recursive function |
| 07:29 | spacebat_ | I thought I could close over a variable to count the number of invokations |
| 07:30 | spacebat_ | like I can in common lisp |
| 07:30 | drewr | There's an idiom for that in Clojure. Likely you'll want LOOP..RECUR. |
| 07:31 | drewr | Something like (loop [ct 0] ... (recur (inc ct))). |
| 07:31 | spacebat_ | pjb3 mentioned that this morning, but I'm not getting far with the docs I'm afraid |
| 07:31 | spacebat_ | it seems on the one hand I don't know enough lisp to understand some things |
| 07:32 | spacebat_ | but I know enough common lisp to go about things the wrong way :) |
| 07:32 | drewr | You probably write imperative CL, which won't help. |
| 07:32 | drewr | You need to think more functionally (which Clojure forces you into). |
| 07:33 | spacebat_ | yes I'm not used to being forced |
| 07:33 | spacebat_ | so loop..recur operats on refs |
| 07:34 | drewr | They operate on whatever arguments you give them. |
| 07:34 | drewr | Not Ref-specific. |
| 07:34 | spacebat_ | and can go anywhere - its not like a loop construct is like a foor or while in imperative languages |
| 07:34 | spacebat_ | ok |
| 07:34 | drewr | Look through boot.clj to get some examples. |
| 07:34 | spacebat_ | thanks drewr I will |
| 07:35 | spacebat_ | looking at clojure I thought, I should learn some CL in order to 'get' it |
| 07:35 | spacebat_ | but it seems clojure is different enough that I should just focus on it |
| 07:37 | drewr | I agree. |
| 08:10 | cgrand | spacebat_, can you paste your code? http://paste.lisp.org/new/clojure |
| 08:13 | lisppaste8 | spacebat_ pasted "trivial recursive function" at http://paste.lisp.org/display/62714 |
| 08:15 | spacebat_ | the paste is of the function before I tried loop...recur |
| 08:15 | spacebat_ | because I have no idea how to use it in a recursive context |
| 08:16 | cgrand | well loop...recur is here to work around the lack of TCO on the jvm. Since your function is not tail recursive you can't use loop...recur to write it |
| 08:18 | spacebat_ | is there a way to count how many times fib is called? |
| 08:19 | cgrand | as said before, with binding and set!, let me annotate your paste |
| 08:20 | spacebat_ | right, I couldn't see how to keep the value of the binding after I'd left the scope |
| 08:20 | spacebat_ | or can the binding wrap the function... |
| 08:23 | lisppaste8 | cgrand annotated #62714 with "counting fibs invocations" at http://paste.lisp.org/display/62714#1 |
| 08:25 | spacebat_ | right, so (def fib-count) is 'unbound' because there is no initial value, it looks up and finds the binding |
| 08:26 | cgrand | you can provide a default (root) value but you are unable to alter it with set! |
| 08:26 | spacebat_ | I tried using def and set! but when I threw in binding as well, put it in the wrong place |
| 08:26 | spacebat_ | ok |
| 08:26 | spacebat_ | but binding allows it |
| 08:27 | spacebat_ | so this is imperative style, but binding limits the scope |
| 08:28 | cgrand | and the only way to change the root value is to re-def. Yup, binding sets a value for the var and allows you to alter it |
| 08:29 | spacebat_ | thanks a lot, that brings some pieces together |
| 08:30 | cgrand | yw |
| 08:30 | spacebat_ | now to find out how to get command line args |
| 08:30 | spacebat_ | someone posted a patch to the group but I assume its been integrated by now |
| 08:31 | cgrand | don't forget to put -- before your args |
| 10:27 | cgrand | rhickey: Hello, could clojure.lang.Numbers.compare be exposed? (as <=> or whatever please you) Without it an unsuspecting user (eg me) may write comparators using substraction and get overflows on the return value of the Comprator :-( |
| 10:28 | rhickey | ok |
| 10:29 | cgrand | thanks! |
| 10:32 | rhickey | Although I heard <=> referred to as the "spaceship operator" at a Java One talk and instantly developed an aversion to it... |
| 10:35 | cgrand | it reminds me of text-mode breakout games but it was the only one (with cmp) to come to my mind. |
| 10:36 | cgrand | signum ? |
| 10:37 | rhickey | ah |
| 10:37 | rhickey | but that is a unary op |
| 10:38 | cgrand | you're right :-( |
| 10:38 | rhickey | one I want to add |
| 10:45 | cgrand | or AFn.compare could be changed to not use intValue |
| 10:57 | rhickey | cgrand: what would that solve? |
| 10:58 | rhickey | compare is defined to return int in Comparator |
| 11:11 | StartsWithK | why there is no (char-array) and #^chars hint? |
| 11:12 | rhickey | StartsWithK: haven't gotten to it - first pass was for numerics |
| 11:13 | cgrand | rhickey: By changing AFn.compare to not use Number.intValue, I mean replacing the call to Number.intValue by something signum-like. It would make use of fns as comparators more foolproof: a comparator fn would then be able to return any number without caring whether it firs into an int or not. |
| 11:13 | cgrand | s/firs/fits/ |
| 11:14 | rhickey | seems like double work |
| 11:37 | rhickey | ok - I've added compare, and based sorts on compare: |
| 11:37 | rhickey | user=> (sort [19 3M 9.0 2 7 nil 4]) |
| 11:37 | rhickey | (nil 2 3M 4 7 9.0 19) |
| 11:40 | cgrand | thanks! |
| 13:00 | StartsWithK | how do i create array of bytes (not java.lang.Byte)? |
| 13:01 | rhickey | (make-array Byte/TYPE 100) |
| 13:02 | rhickey | or (make-array (. Byte TYPE) 100) if you are not on SVN |
| 13:03 | rhickey | the names of the classes corresponding to the primitives are static members of their respective boxed types, all called TYPE |
| 13:04 | StartsWithK | rhickey, this works perfectly, thanks |
| 13:33 | Lau_of_DK | rhickey: In the concurrency talk you mentioned some theory on log(n) calc times (or O(n)) and similar things, which were important in regards to obtaining near constant time. Do you have some links for some background reading on these issues? |
| 14:49 | abrooks | Chouser: What was the last version of Clojure SVN you had working with Enclojure? |
| 14:49 | rhickey | Lau_of_DK: you can find some info by googling bagwell hash tries |
| 14:50 | abrooks | Lau_of_DK: This wikipedia page has two good links: http://en.wikipedia.org/wiki/Hash_array_mapped_trie |
| 14:55 | Lau_of_DK | Thanks to both of you |
| 16:25 | arbscht | does clojure have trouble handling class names containing .? I can't access java.awt.geom.Point2D.Double for example (ClassNotFoundException) |
| 16:26 | rhickey | the real name of that nested class is: java.awt.geom.Point2D$Double |
| 16:26 | arbscht | I see |
| 16:27 | arbscht | thanks |
| 16:27 | rhickey | sure |
| 16:37 | jgrant | hey everyone, i have a question about var scope |
| 16:38 | jgrant | I've defined a global var *x* in a specific package 'mypackage |
| 16:38 | jgrant | now after calling the load-file function I'd like to access this variable and update it |
| 16:39 | jgrant | it seems the loaded file has it's own scope if i do a (def *x*) it seems to be a copy ? |
| 16:40 | rhickey | are you still in the same package? |
| 16:40 | rhickey | namespace |
| 16:40 | jgrant | yes |
| 16:41 | rhickey | what makes it feel like a copy? |
| 16:44 | jgrant | it doesn't have the value assigned in the parent file |
| 16:45 | jgrant | thanks for bearing with me i'm still figuring my way around clojure's idioms |
| 16:45 | rhickey | if in the defining file you say (def *x* 42), then after loading *x* should be 42, no? |
| 16:45 | jgrant | yea i agree it should i must be doing something wrong |
| 16:46 | rhickey | are you def'ing it again somewhere? |
| 16:48 | jgrant | yes in the loaded file |
| 16:48 | rhickey | 2x in the same file? |
| 16:48 | jgrant | once |
| 16:49 | jgrant | once in the parent and once in the loaded file |
| 16:49 | rhickey | I don't understand what you mean by parent then |
| 16:50 | rhickey | foo.clj defs x and loads bar.clj that defs x? |
| 16:50 | jgrant | clojure loads file1 (which defs var *x*) which loads file2 (which also defs var *x*) |
| 16:50 | jgrant | yes |
| 16:50 | rhickey | both in same ns? |
| 16:50 | jgrant | yes |
| 16:51 | rhickey | they both have in-ns explicitly? |
| 16:51 | jgrant | bar.clj has same (in-ns ...) as foo.clj |
| 16:51 | jgrant | yes it's explicit |
| 16:51 | rhickey | last def should win |
| 16:52 | jgrant | should foo.clj see the update made to *x* by bar ? |
| 16:53 | rhickey | exprs happen in order, latter see former |
| 16:54 | jgrant | ok it's working now , not sure what i fixed |
| 16:54 | jgrant | another related question |
| 16:54 | jgrant | bar.clj will be updating *x* in a thread |
| 16:54 | rhickey | oh |
| 16:54 | jgrant | would (dosync (def *serve-count* (inc *serve-count*))) be valid ? |
| 16:55 | rhickey | updating by def? |
| 16:55 | jgrant | yea |
| 16:55 | rhickey | then *x* should be a ref and you shouldn't be re-def-ing it |
| 16:55 | rhickey | (def *cnt* (ref 0)) |
| 16:56 | rhickey | (dosync (commute *cnt* inc)) |
| 16:56 | jgrant | ah i see ! |
| 17:00 | jgrant | I'm getting 'Unable to resolve symbol: *x*' when i try that ? |
| 17:02 | rhickey | are you launching your threads in bar prior to the def in foo? |
| 17:02 | jgrant | not at all |
| 17:02 | jgrant | (def *cnt* (ref 0)) |
| 17:02 | jgrant | is one of the first lines in foo.clj |
| 17:03 | jgrant | uggh, you are right |
| 17:03 | jgrant | i was not ! |
| 17:06 | jgrant | thx rich |
| 17:06 | rhickey | sure |
| 17:21 | jgrant | mmmm, (println *x*) doesn't seem to report the right value |
| 17:21 | rhickey | @*x* |
| 17:22 | jgrant | um yea that's what i mean |
| 17:22 | rhickey | you want the value in the ref, not the ref itself |
| 17:22 | jgrant | it seems to do with how many threads are trying to update *x* |
| 17:22 | jgrant | if i run a few at a time i see the value inc |
| 17:22 | jgrant | if i run a lot it seems to stay at 0 |
| 17:26 | jgrant | aha |
| 17:29 | jgrant | calling (dosync (commute *cnt* inc)) |
| 17:29 | jgrant | has to be in the enclosing function used by the thread |
| 17:29 | jgrant | if it's in another function called by the thread then it does not work |
| 17:38 | jgrant | (or maybe it requires the dosync to be in foo.clj) |
| 17:39 | jgrant | having it in bar.clj doesn't seem to work |
| 17:52 | jgrant | The dosync doesn't work if it's in a function that exists also in foo.clj |
| 17:52 | jgrant | seems like it needs to be in the same function |
| 17:52 | jgrant | that is used as the thread |
| 18:00 | jgrant | rich : nevermind another one of my own bugs, it works exactly as you described |
| 23:33 | jgrant | why does not work in clojure ? |
| 23:34 | jgrant | (map (fn [fname] |
| 23:34 | jgrant | (load-file (str (. (File. ".") getCanonicalPath) "/src/" fname))) '("file1.clj" "file2.clj" "file3.clj")) |