#clojure logs

2008-06-23

04:08jmbrhi
04:09jgranthi
07:24spacebat_I think I'm missing something basic about clojure
07:24spacebat_(def x 1) says I've bound #'user/x
07:24spacebat_I can evaluate it with x
07:24spacebat_and get 1
07:24drewrspacebat_: You're in the user namespace by default.
07:25spacebat_yup
07:25spacebat_like common lisp
07:25spacebat_but there is no setf
07:25drewr:-)
07:25spacebat_(set! x 2) doesn't work
07:25spacebat_(set! user/x 2) doesn't work
07:26drewrClojure doesn't let you set a value that easily.
07:26drewrIt's a feature.
07:26spacebat_nor (set #'user/x 2) nor (var-set x 2)
07:26drewrx is a Var, which are immutable.
07:26spacebat_but in a few places they say that Vars are mutable (thread locally)
07:27spacebat_"While Vars ensure safe use of mutable mutable storage locations via thread isolation..." (http://clojure.org/refs)
07:28drewrYou have to wrap it in a BINDING form, which is thread-local.
07:28spacebat_each time I update it?
07:28spacebat_but when I leave the binding that change is gone
07:29drewrWhat problem are you tring solve?
07:29drewrtrying
07:29spacebat_I have a recursive function
07:29spacebat_I thought I could close over a variable to count the number of invokations
07:30spacebat_like I can in common lisp
07:30drewrThere's an idiom for that in Clojure. Likely you'll want LOOP..RECUR.
07:31drewrSomething like (loop [ct 0] ... (recur (inc ct))).
07:31spacebat_pjb3 mentioned that this morning, but I'm not getting far with the docs I'm afraid
07:31spacebat_it seems on the one hand I don't know enough lisp to understand some things
07:32spacebat_but I know enough common lisp to go about things the wrong way :)
07:32drewrYou probably write imperative CL, which won't help.
07:32drewrYou need to think more functionally (which Clojure forces you into).
07:33spacebat_yes I'm not used to being forced
07:33spacebat_so loop..recur operats on refs
07:34drewrThey operate on whatever arguments you give them.
07:34drewrNot Ref-specific.
07:34spacebat_and can go anywhere - its not like a loop construct is like a foor or while in imperative languages
07:34spacebat_ok
07:34drewrLook through boot.clj to get some examples.
07:34spacebat_thanks drewr I will
07:35spacebat_looking at clojure I thought, I should learn some CL in order to 'get' it
07:35spacebat_but it seems clojure is different enough that I should just focus on it
07:37drewrI agree.
08:10cgrandspacebat_, can you paste your code? http://paste.lisp.org/new/clojure
08:13lisppaste8spacebat_ pasted "trivial recursive function" at http://paste.lisp.org/display/62714
08:15spacebat_the paste is of the function before I tried loop...recur
08:15spacebat_because I have no idea how to use it in a recursive context
08:16cgrandwell 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:18spacebat_is there a way to count how many times fib is called?
08:19cgrandas said before, with binding and set!, let me annotate your paste
08:20spacebat_right, I couldn't see how to keep the value of the binding after I'd left the scope
08:20spacebat_or can the binding wrap the function...
08:23lisppaste8cgrand annotated #62714 with "counting fibs invocations" at http://paste.lisp.org/display/62714#1
08:25spacebat_right, so (def fib-count) is 'unbound' because there is no initial value, it looks up and finds the binding
08:26cgrandyou can provide a default (root) value but you are unable to alter it with set!
08:26spacebat_I tried using def and set! but when I threw in binding as well, put it in the wrong place
08:26spacebat_ok
08:26spacebat_but binding allows it
08:27spacebat_so this is imperative style, but binding limits the scope
08:28cgrandand 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:29spacebat_thanks a lot, that brings some pieces together
08:30cgrandyw
08:30spacebat_now to find out how to get command line args
08:30spacebat_someone posted a patch to the group but I assume its been integrated by now
08:31cgranddon't forget to put -- before your args
10:27cgrandrhickey: 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:28rhickeyok
10:29cgrandthanks!
10:32rhickeyAlthough I heard <=> referred to as the "spaceship operator" at a Java One talk and instantly developed an aversion to it...
10:35cgrandit reminds me of text-mode breakout games but it was the only one (with cmp) to come to my mind.
10:36cgrandsignum ?
10:37rhickeyah
10:37rhickeybut that is a unary op
10:38cgrandyou're right :-(
10:38rhickeyone I want to add
10:45cgrandor AFn.compare could be changed to not use intValue
10:57rhickeycgrand: what would that solve?
10:58rhickeycompare is defined to return int in Comparator
11:11StartsWithKwhy there is no (char-array) and #^chars hint?
11:12rhickeyStartsWithK: haven't gotten to it - first pass was for numerics
11:13cgrandrhickey: 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:13cgrands/firs/fits/
11:14rhickeyseems like double work
11:37rhickeyok - I've added compare, and based sorts on compare:
11:37rhickeyuser=> (sort [19 3M 9.0 2 7 nil 4])
11:37rhickey(nil 2 3M 4 7 9.0 19)
11:40cgrandthanks!
13:00StartsWithKhow do i create array of bytes (not java.lang.Byte)?
13:01rhickey(make-array Byte/TYPE 100)
13:02rhickeyor (make-array (. Byte TYPE) 100) if you are not on SVN
13:03rhickeythe names of the classes corresponding to the primitives are static members of their respective boxed types, all called TYPE
13:04StartsWithKrhickey, this works perfectly, thanks
13:33Lau_of_DKrhickey: 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:49abrooksChouser: What was the last version of Clojure SVN you had working with Enclojure?
14:49rhickeyLau_of_DK: you can find some info by googling bagwell hash tries
14:50abrooksLau_of_DK: This wikipedia page has two good links: http://en.wikipedia.org/wiki/Hash_array_mapped_trie
14:55Lau_of_DKThanks to both of you
16:25arbschtdoes clojure have trouble handling class names containing .? I can't access java.awt.geom.Point2D.Double for example (ClassNotFoundException)
16:26rhickeythe real name of that nested class is: java.awt.geom.Point2D$Double
16:26arbschtI see
16:27arbschtthanks
16:27rhickeysure
16:37jgranthey everyone, i have a question about var scope
16:38jgrantI've defined a global var *x* in a specific package 'mypackage
16:38jgrantnow after calling the load-file function I'd like to access this variable and update it
16:39jgrantit seems the loaded file has it's own scope if i do a (def *x*) it seems to be a copy ?
16:40rhickeyare you still in the same package?
16:40rhickeynamespace
16:40jgrantyes
16:41rhickeywhat makes it feel like a copy?
16:44jgrantit doesn't have the value assigned in the parent file
16:45jgrantthanks for bearing with me i'm still figuring my way around clojure's idioms
16:45rhickeyif in the defining file you say (def *x* 42), then after loading *x* should be 42, no?
16:45jgrantyea i agree it should i must be doing something wrong
16:46rhickeyare you def'ing it again somewhere?
16:48jgrantyes in the loaded file
16:48rhickey2x in the same file?
16:48jgrantonce
16:49jgrantonce in the parent and once in the loaded file
16:49rhickeyI don't understand what you mean by parent then
16:50rhickeyfoo.clj defs x and loads bar.clj that defs x?
16:50jgrantclojure loads file1 (which defs var *x*) which loads file2 (which also defs var *x*)
16:50jgrantyes
16:50rhickeyboth in same ns?
16:50jgrantyes
16:51rhickeythey both have in-ns explicitly?
16:51jgrantbar.clj has same (in-ns ...) as foo.clj
16:51jgrantyes it's explicit
16:51rhickeylast def should win
16:52jgrantshould foo.clj see the update made to *x* by bar ?
16:53rhickeyexprs happen in order, latter see former
16:54jgrantok it's working now , not sure what i fixed
16:54jgrantanother related question
16:54jgrantbar.clj will be updating *x* in a thread
16:54rhickeyoh
16:54jgrantwould (dosync (def *serve-count* (inc *serve-count*))) be valid ?
16:55rhickeyupdating by def?
16:55jgrantyea
16:55rhickeythen *x* should be a ref and you shouldn't be re-def-ing it
16:55rhickey(def *cnt* (ref 0))
16:56rhickey(dosync (commute *cnt* inc))
16:56jgrantah i see !
17:00jgrantI'm getting 'Unable to resolve symbol: *x*' when i try that ?
17:02rhickeyare you launching your threads in bar prior to the def in foo?
17:02jgrantnot at all
17:02jgrant(def *cnt* (ref 0))
17:02jgrantis one of the first lines in foo.clj
17:03jgrantuggh, you are right
17:03jgranti was not !
17:06jgrantthx rich
17:06rhickeysure
17:21jgrantmmmm, (println *x*) doesn't seem to report the right value
17:21rhickey@*x*
17:22jgrantum yea that's what i mean
17:22rhickeyyou want the value in the ref, not the ref itself
17:22jgrantit seems to do with how many threads are trying to update *x*
17:22jgrantif i run a few at a time i see the value inc
17:22jgrantif i run a lot it seems to stay at 0
17:26jgrantaha
17:29jgrantcalling (dosync (commute *cnt* inc))
17:29jgranthas to be in the enclosing function used by the thread
17:29jgrantif it's in another function called by the thread then it does not work
17:38jgrant(or maybe it requires the dosync to be in foo.clj)
17:39jgranthaving it in bar.clj doesn't seem to work
17:52jgrantThe dosync doesn't work if it's in a function that exists also in foo.clj
17:52jgrantseems like it needs to be in the same function
17:52jgrantthat is used as the thread
18:00jgrantrich : nevermind another one of my own bugs, it works exactly as you described
23:33jgrantwhy does not work in clojure ?
23:34jgrant(map (fn [fname]
23:34jgrant (load-file (str (. (File. ".") getCanonicalPath) "/src/" fname))) '("file1.clj" "file2.clj" "file3.clj"))