#clojure logs

2009-08-10

00:17rlbDoes clojure have an rfc-822 date parser?
00:19arbschtdoesn't java have a class for that?
00:19LauJensenyep
00:20arbschtjava.text.SimpleDateFormat, I suppose
00:25rlbSure, though it looked like that might require multiple patterns. I had just wondered if clojure already had something simpler. Anyway, thanks.
00:26LauJensenIt might - Just not something that I know of. Check clojure.org under libraries maybe
00:27rlbI saw the email lib -- perhaps it provides access to the date parser.
00:28rlbnevermind, that's just for sending
00:34Anniepooclojurebot: paste
00:34clojurebotlisppaste8, url
00:34lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
00:49lisppaste8Anniepoo pasted "with-foo" at http://paste.lisp.org/display/85108
00:51hiredmanbinding
00:51Anniepooprobably a very simple question, but I nee dto know what the buzzword is for this
00:51AnniepooThanks!
00:51hiredman,(doc binding)_
00:51clojurebot"([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before."
00:51Anniepooah, sweet
00:51Anniepoook, thanks
00:51Anniepoothat's what I wanted
00:51hiredmananyway, binding is for dynamic binding
00:51Anniepooyah, what about concurrancy?
00:52hiredmanthreadlocal
00:52Anniepoook, cool
00:52Anniepoo8cD Clojure continues to amaze and delight
00:53LauJensen(and it'll keep doing it for a while)
01:23d2dchatHow can I make a function repeat 2 or any number of times I specify?
01:23d2dchattwice*
01:23d2dchatlike the equivalent of times.do in ruby
01:23d2dchatI tried (repeat 2 (my-recursive-function))
01:23LauJensen~(take 10 (repeat 2))
01:23clojurebotGabh mo leithscéal?
01:23d2dchatbut that didn't work
01:24d2dchathmm what does take do?
01:24LauJensenWhen you say repeat, do you mean execute in sequence?
01:24d2dchatit doesn't matter the order, as long as it repeats the function twice
01:25d2dchatexecutes twice
01:25LauJensen(dotimes [i 2] (my-func))
01:26d2dchatLauJensen: ah! That worked beautifully
01:26d2dchathow come repeat doesn't work?
01:26LauJensenI have no idea, it works locally
01:26LauJensen~(repeat 2)
01:26clojurebotIt's greek to me.
01:26LauJensen~(doc repeat)
01:26clojurebotExcuse me?
01:26Fossid2dchat: repeatedly
01:26Fossirepeat repeats a value
01:27Fossi,(doc repeat)
01:27clojurebot"([x] [n x]); Returns a lazy (infinite!, or length n if supplied) sequence of xs."
01:27d2dchatwell for whatever reason repeat didn't execute the function twice
01:27d2dchatand dotimes did
01:27d2dchatnot sure why
01:27LauJensenBut repeat is not what you want
01:27LauJensenI thought you wanted a data sequence
01:27LauJensenBut may I ask why you're executing something twice?
01:27Fossirepeat repeats a value
01:27d2dchatwell it could be variable.. depends on arity
01:28Fossiit does not call a function
01:28d2dchatFossi: gotcha
01:28d2dchatLauJensen: my function generates functions randomly based on arity :)
01:28hiredman,(doc repeatedly)
01:28clojurebot"([f]); Takes a function of no args, presumably with side effects, and returns an infinite lazy sequence of calls to it"
01:29d2dchathmm, my function has args
01:29hiredmand2dchat: wrap it in a thunk
01:30Fossithunkamajunk
01:30hiredman,(take 2 (repeatedly #(+ 1 2)))
01:30d2dchatthunk? :)
01:30clojurebot(3 3)
01:30hiredman~google thunk
01:30clojurebotFirst, out of 1370000 results is:
01:30clojurebotThunk - Wikipedia, the free encyclopedia
01:30clojurebothttp://en.wikipedia.org/wiki/Thunk
01:30LauJensend2dchat: Sounds awesome
01:31d2dchathopefully it will be.. Genetic Programming is fun :)
01:31LauJensenIf you can program a hamster which brews coffee, please let me know
01:31d2dchatLauJensen: I'm on it!
01:31d2dchat;)
01:32d2dchatWill call is Javaster
01:32LauJensenClamster
01:32d2dchatBeanster
01:33d2dchatnow I have to learn how to preserve state across functions.. do I just pass a parameter around?
01:34d2dchatwell
01:34d2dchatit's the same function
01:34d2dchatI will experiment :)
01:34LauJensenTo be truely functional you have to pass everything around
01:34Anniepoolook at 'let'
01:34d2dchatIs it better to pass it around?
01:35LauJensenhttp://en.wikipedia.org/wiki/Functional_programming
01:35LauJensenSkim that
01:35d2dchatRight, I know some erlang
01:35d2dchatjust wanted to know clojure conventions because it's a hybrid
01:35d2dchatbut I guess opt for immutability !
01:56d2dchatHow come this isn't allowed?
01:56d2dchatuser=> (defn blah [something] (something))
01:56d2dchat#'user/blah
01:56d2dchatuser=> (blah ())
01:57d2dchatI'm assuming there is a better way to push an empty list to a function :)
01:57d2dchatuser=> (defn blah [something] (something))
01:57d2dchat#'user/blah
01:57d2dchatuser=> (blah ())
01:57d2dchatjava.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
01:57Fossiyou call something
01:58hiredmanyou are trying to call the empty list as a function
01:58hiredmanit isn't
01:58hiredmanso surprisingly you get an exception
01:58d2dchatSure, makes sense, is there a way to test that?
01:58hiredmanlists == function application
01:59LauJensenThe empty list is '() not ()
01:59hiredman,(list? ())
01:59clojurebottrue
01:59hiredmanLauJensen: the empty lists doesn't need quoting
01:59hiredman,()
01:59clojurebot()
01:59LauJensenoh
01:59LauJensenOld habit then
02:00hiredman,((fn [something] (something)) 1)
02:00clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
02:00d2dchathmm I think what I want is to create an expression on the fly
02:01d2dchatwithout it evaluating quite yet
02:01hiredmanthat function will give you an exception if you call it with anything that does not implement IFn
02:01d2dchatright, make ssense
02:01LauJensen,(def f (fn [x] 5))
02:01clojurebotDENIED
02:01d2dchat:)
02:02d2dchatis it possible to execute [+ 5 6] ?
02:02hiredmand2dchat: you seem not to have read any docs, I think it would help if you read some, tried out a few euler problems
02:02hiredmanetc
02:02hiredmanwhat the blip.tv videos
02:02hiredmanwatch
02:13osaundersI'm confused. Is Clojure object-oriented? How do I create an object?
02:14hiredmanno
02:14hiredmanclojurebot: rationale
02:14clojurebotrationale is http://clojure.org/rationale
02:16osaundersStill confused. There are multimethods but it's not object-oriented?
02:16hiredmanosaunders: multimethods can dispatch on any function
02:17hiredman~bliptv
02:17clojurebotHuh?
02:17hiredman~blipt.v
02:17clojurebotIt's greek to me.
02:17hiredmanbah
02:17hiredman~blip tv
02:17clojurebotI don't understand.
02:17hiredman~blip.tv
02:17clojurebotblip.tv is http://clojure.blip.tv/
02:17hiredmanhorrible
02:17hiredmananyway watch the videos, read the rationale
02:18osaundersI watched the ones for Java Programmers.
02:18osaundersGuess I should move on to the ones for LISP ones.
02:20osaunders"Systems that utilize runtime polymorphism are easier to change and extend. Clojure supports polymorphism at 3 levels. First, almost all of the core infrastructure data structures in the Clojure runtime are defined by Java interfaces."
02:20hiredmanosaunders: did you see anything with objects and calling methods on objects in the video?
02:21osaundersNo
02:21osaundersShould I?
02:21hiredmanwould you expect to see such in a video about an oop language?
02:22hiredmanhave you looked at the rationale page?
02:23hiredmanthere is a whole website beyond the page on multimethods
02:23osaundersWow, you're almost berating me here.
02:23hiredman*shrug*
02:25osaundersDoes Rich thing Smalltalk is a spaghetti code language?
02:25osaunders*think
02:26Fossiosaunders: dunno, maybe ask him? ;D
02:26osaundersFossi: hiredman is having me look at the rationale as if that's going to explain the characteristics of the language.
02:27Fossiwell, it kinda does
02:27Fossiat least it has some major points on there
02:28osaundersHang on, let me read this fully http://clojure.org/runtime_polymorphism
02:28Fossithat being said i'd argue that clojure is mainly functional, but as a lisp, it can't keep you from coding in a OO style if you must
02:28clojurebotthat is not what I wanted
02:29hiredmanhttp://clojure.org/state is also good
02:29Fossionly that it would be awkward and prolly slow as well :)
02:30Fossibbl
02:49d2dchatIs there a way to concatinate lists without evaluating them?
02:49d2dchatI have a loop that gives me (+) (5) and (6)
02:49d2dchatbut I want to make it (+ 5 6)
02:50hiredmanhttp://clojure.org/sequences
02:52mikehincheyconcat
02:53d2dchatmikehinchey: isn't that just for vectors?
02:54mikehincheyno, most functions like that work on any seq
02:54d2dchatuser=> (concat (5) (5) (5))
02:54d2dchatjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
02:55hiredmand2dchat: lists are function application
02:55mikehincheyif you quote each (5), it will work '(5)
02:55d2dchatahh OK
02:55d2dchatmakes sense
02:55hiredman(5) tries to call 5 as a function
02:56d2dchatyup
02:56d2dchatuser=> (concat '(5) '(5) '(5))
02:56d2dchat(5 5 5)
02:56d2dchatgrr
02:56d2dchatstupid mistake :(
02:56hiredmanplease read the url I pasted
02:56hiredmansequences and sequence functions are very import in clojure
02:57d2dchatreading through it
04:16mikehincheyWhat does #= do? I thought it was a reader macro for evaluation, but #=(if true 1 2) fails.
04:17hiredmanread the exception
04:17mikehinchey"can't resolve if"
04:17hiredmanthe evaluation at readtime is very limited
04:18hiredman#=() is typically just used to call contructors
04:18hiredman,#=(java.util.ArrayList. (1 2 3))
04:18clojurebot#<ArrayList [1, 2, 3]>
04:19hiredmanso you can have the reader read an ArrayList
04:19hiredmanconstructors
04:19mikehincheyok, that's fine, it's not what I wanted then
04:20hiredman,#=(System/exit 1)
04:20clojurebotSystem
04:20hiredmanbah
04:22mikehincheythanks
05:42alrex021Is there any online paste that has clojure syntax highlight?
05:43Chousukegist.github.com
05:45alrex021thx Chousuke
05:46alrex021I am trying to get my head around conditional flow in clojure. I have a following code snippet: http://gist.github.com/165113
05:47alrex021chat-view is meant to check if session has :login key, if not it must add it. After that it must continue on to return the html fragments
05:47Chousukehm
05:47Chousukethen your problem there is that (layout... is the else branch
05:48alrex021yup, exactly...
05:48alrex021how do I setup a control flow so that (layout ... is always ran
05:49Chousukeyou need (if-not pred then-branch nil)
05:49Chousukeor alternatively, (when-not pred then-branch=
05:49Chousuke)*
05:49Chousukewhich is just a shortcut for the above :)
05:50alrex021hmm, I am not following 100% :) .. what is wrong wih my if-not?
05:50alrex021well...hmm layout falls in else part?
05:50Chousukeif-not requires both the then-form and else-form
05:50Chousukeand your layout is in the place where it expects the else-form
05:52alrex021but my (layout ... part should be ran regardless of the if-not outcome...
05:52Chousukebtw, it looks like your session-assoc is a function containing a dosync... I think it's better style to not have dosyncs hidden in the actual "alter" functions
05:53alrex021hmmm, its compojure's session-assoc which they advise to use
05:53Chousukeah, hmm. in that case, I guess there's no helpong it :/
05:53alrex021and yes, it internally does an alter on the session ref
05:54ChousukeI just think one should keep most of the logic in pure functions. .)
05:55Chousukeeg. instead of a side-effecting function, I think it'd be better to have a pure function like (alter-session assoc :login whatever) designed to be wrapped in a dosync
05:55arbschtyou could probably refactor that with the mutation in some kind of chat-login-controller function around chat-view
05:55Chousukebut I guess if it's the framework that's providing it to you, you should use it.
05:55arbschta -view altering the session should ring bells, even in compojure
05:56alrex021interesting
05:57ChousukeAnyway, you want to do (when-not guest (session-assoc ...)) (layout ...)
06:01alrex021hhmm still doesn't seem right http://gist.github.com/165113
06:02alrex021prob is when (session-assoc ..) runs it doesn't bind it to guest in local block
06:02alrex021that my guess
06:03arbschtoh, you want to use the updated session in chat-view
06:04arbschtthat would need a new request
06:05alrex021hmm, interesting... so I would need to exit the function and come back in?
06:05alrex021would'n if-let help with this to maybe rebind guest to new value for new session :login
06:06alrex021am I just making this look so difficult or is it really this difficult?
06:06arbschtyou're conflating clojure flow with compojure+http flow :)
06:08arbschthm, compojure docs are offline? :/
06:08alrex021what docs? :)
06:08arbschtoh, there was a secret site at preview.compojure.org
06:08Chousukearbscht: ah, right.
06:09Chousukearbscht: try (let [guest (or (session :login) (session-assoc :login (guest-account)))]
06:10alrex021ok this worked....http://gist.github.com/165113
06:11alrex021for some reason I still think thats not really the cleanest way
06:11alrex021So if-not guest, then add :login to session and then redirect back into the view via http call
06:12arbschtyes, that login check and redirect should go in a non-view function
06:12Chousukeyeah
06:12alrex021I see, that makes sense....the mutable bit so then view would have no side-effects....does that sound right?
06:13arbschtright
06:13Chousukeand in general, doing non-view stuff in the view, mutable or not.
06:14alrex021but would the view call this func that has side-effects...?
06:14Chousukethe other way around I think
06:14arbschtthe router would dispatch to the -controller (or whatever), which would call the appropriate view after determining login etc
06:14Chousukeyou write the function that checks the login, alters the session if needed, and then calls the view function.
06:15alrex021oh I see...that makes very much sense...thx I'll give that a try quick
06:43alrex021Ok I have a new working version that separates the pure function from one that alters the mutable data... http://gist.github.com/165113
06:44alrex021only question I have is....is it ok for the chat-view to still have a check on guest and then if required to redirect to login-controller to perform login then redirect to chat
06:45arbschtthat's hard to make sense of without seeing the routes
06:46alrex021sorry about that, I just added the routes.... http://gist.github.com/165113
06:47alrex021doesn't seem clean that my chat-view actually deals with login check
06:48arbschtright
06:48arbschtI'd suggest associating "/chat" with a controller, rather than a view, since it may affect the session state
06:49alrex021so just anotherer level of indirection?
06:49arbschtessentially, yes
06:50alrex021chat-controller ....checks login and takes you to chat-view
06:50alrex021this way chat-view has no side-effects
07:00alrex021arbscht: I have made the changes now and it looks much better. The chat-controller now holds the control logic and then delegates to chat-view pure function .. http://gist.github.com/165113
07:04arbschtvery good :)
07:05arbschthaving the login-controller only redirect to "/chat" seems too specific. you could probably generalize it further somehow
07:06alrex021yup, pass in :next param maybe
07:06arbschtthat certainly cleaned up the view nicely, though
07:07alrex021thx
07:07arbschtif session-assoc fails for some reason (say, disabled cookies), could you get caught in a redirect cycle?
07:16alrex021_I added next-url param to login-controller so now its more generic...
07:16alrex021_other controllers could redirect to it with next-url param that indicates where to go after login
07:17alrex021_"f session-assoc fails for some reason (say, disabled cookies), could you get caught in a redirect cycle?" -> very good question....that is a big prob
07:19alrex021_I'd hope that then an exception is raised or something to break the flow and then I could redirect to error page
07:20alrex021_Again, this is just Simple Chat prog I;m building to learn more about clojure, conurracy api, ..etc
07:22Chousukehm
07:23Chousukewell, it should be rather easy to check if session-assoc failed or not.
07:23Chousukejust try and see if the value you put there is present.
07:24Chousukeif not, redirect to an error page from the controller.
07:24alrex021_yup, that makes sense..
07:25alrex021_so check (session :login) after assoc call
07:25alrex021_if not there, well then cookies prob not enabled...so show error page
07:39arbschtsorry, what I mean is if the client rejects the session data in the response, it would be like a new visitor after the redirect
08:43weissjis there a way to define functions, etc in something other than the current namespace? seems strange to keep switching ns, doing a defn, switching again, etc
08:46carki usually recompile the whole file, which has the ns form on top
08:47weissjcark: not sure i understand
08:47carkare you using emacs ?
08:47weissjno
08:47carkhow are you developing ?
08:47weissjclojure-dev (eclipse)
08:47carkoh i see
08:47carki can't help then =(
08:48weissjthis question isn't an environment question, it's a clojure lang question
08:48carkwell it's a about your developement process
08:48weissjmy file has the ns form at the top, but i want to defn something in that file that goes in a different ns
08:48carkoh
08:48carkthat seems strange
08:49weissjcark: yeah, it's using clj-record, which is like ruby on rails' ActiveRecord
08:49weissjit creates namespaces for each table and creates functions for them
08:49weissjusing macros
08:49smoonenweissj -- does (intern) do what you want?
08:50weissj,(doc intern)
08:50clojurebotDENIED
08:50weissjsmoonen: yeah i think that's it, thanks!
08:51weissjsmoonen: wait, maybe not. it creates vars, what about functions?
08:53smoonenweissj -- seems to work if I pass it a lambda
08:53smoonen(intern 'user 'f (fn [x] (inc x)))
08:54weissjsmoonen: huh, ok, not quite how i imagined it would work, but i think that'll do it
08:54weissji was expecting something more like "let"
08:55weissjsorta like (let-ns ns (block))
08:56weissjin-ns switches ns, but does it permanently, it doesn't wrap anything
08:56carkyou may use the binding form
08:57cark(binding [*ns* ..]
09:00weissjcark: ok let me give that a shot
09:06carkdoesn't work =/
09:06carkbecause it's a read-time thing instead of compile-time
09:35slaneyis clojurebot a opensouce project that I can use myself?
09:36arbschtslaney: http://github.com/hiredman/clojurebot/tree/master
09:36slaneyah, great thanks
09:48ericthorsenWhat is the equivalent to memfn for static methods in a java class?
09:50Chousuke(doc memfn)
09:50clojurebot"([name & args]); Expands into code that creates a fn that expects to be passed an object and any args and calls the named instance method on the object passing the args. Use when you want to treat a Java method as a first-class fn."
09:50Chousukehm.
09:50ericthorsen...if I want to treat a static method as a first-class fn
09:50ChousukeI'd just use #(Foo/static %1 %2 %3...)
09:52ericthorsenChouser: yes...that would work...too simple. I guess I was hoping Foo/static would just return something I could use.
10:32weissjis there something like "let" for namespaces (ie, execute this block in this namespace)
10:33weissjseems like the only option is to use in-ns which changes ns permanently (until you change it back)
10:33ChouserI've wondered the same thing.
10:33smoonencouldn't find anything. you could definitely write your own via macro.
10:34weissjso the macro would just save the value of *ns* and switch it back after the block runs?
10:34ChouserThe most obvious interface to me would be just (defn other.ns/foo ...) but that appears to be explicitly unsupported
10:34weissjChouser: yeah i tried that :)
10:35weissji would have thought in-ns would have a different form for that
10:43Anniepoowondering what constitutes real metadata
10:44AnniepooI've got a bunch of code that shoves around vectors that represent 3D boxes
10:46Anniepoothe boxes have to actually come from a list with other info
10:47Anniepooin a structmap. Eventually I'll want to get back to the structmap. Is it kosher to shove it into metadata?
10:49Chouserdoes it seem to anyone else that the questions in here keep getting harder?
10:49AnniepooLOL
10:50Anniepoowe're learning!
10:50ChouserAnniepoo: I would imagine that's ok.
10:50Anniepoook, cool
10:50ChouserUsing metadata like that is probably ok, I mean. Learning is unacceptible.
10:50AnniepooI know from bitter experience with XML attributes that mixing metadata and data willy nilly is a bad thing
10:51AnniepooI'm actually solving the knapsack problem at the moment.
10:52AnniepooChouser, can you solve the knapsack problem for me? ;c)
10:58Chouser0-1 ? one constraint?
10:59AnniepooI've got what actually isn't the knapsack problem (or I wouldn't be solving it), I need to exactly pack an AABB with
10:59AnniepooAABB's drawn from a list. I also have available, fortunately, any sized AABB up to a certain maximum dimension on each side
11:00Anniepoo(AABB = axis aligned bounding box, a non rotated rectangular prism)
11:01Chouser3D?
11:01Anniepooyes
11:02Anniepoothe key is the variable sized one. I pack the thing with the biggest piece that will still fit, over and over, until the remaining chunks are under the limit of the rubber cube
11:16lisppaste8cgrand pasted "microbenchmark: PersistenthashMap2$TransientMap" at http://paste.lisp.org/display/85126
11:21Chousercgrand: wow. care to summerize the difference, or should I just keep trying to read the code?
11:26cgrandChouser: ideas from rhickey: no leave nodes and inner nodes aren't packed as soon as they are half full
11:28Chousercgrand: version 3 will use new new? :-)
11:30cgrandmaybe
11:35cemerickChouser: welcome back :-)
11:35cemerick(if you had actually gone somewhere, that is)
11:36Chousercemerick: thanks! family "vacation".
11:37Chousercgrand: so ArrayNode instead of LeafNode?
11:41cgrandChouser: ArrayNode instead of FullNode and BitmapIndexedNode now contains an interleaved array of keys and values (if the key is null then the value is an INode))
11:51duploIs there a webpage that explains "if-let" more than the clojure page?
11:52drewrduplo: not sure; what are you confused about?
11:58duplodrewr: The explanation just seems a little terse to me.
11:59duplodrewr: But maybe I need to read up a bit on macros for it to make more sence.
12:04arohnerduplo: ,(source if-let)
12:04drewrduplo: it's a substitution for a common idiom (let [x true-or-false] (if x :foo :bar))
12:07duck1123I use it more often to test if the let contains something, or is nil
12:09duck1123I just wish if-let would allow me to have multiple let statements. (perhaps with AND semantics for each statement)
12:09Chousukethat shouldn't be too difficult to implement.
12:10Chousuke would be a backwards-compatible change too
12:11Chouserare you sure 'and' is what you'd want?
12:11duck1123not sure. that, or just like a normal let, with the if only applying to the last one
12:14duck1123the latter is closer to how I've tried to use it, before I got the error
12:15duck1123but in those cases, each statement in the original let was true anyway
12:17ChousukeI suppose it would be possible to have (if-let :any [x foo y bar] ...)
12:18Chousuke(and :all too)
12:23duck1123Chousuke: would :last be the default then?
12:23Chousukeduck1123: maybe.
12:25ChousukeI'm still wondering whether it really makes sense, though.
12:25Chousuketo extend if-let like that I mean.
12:25cemerickI think not, if only because I'd expect :all to be the default. :-/
12:25cemerick...and others would expect :first
12:26cemerickand then someone would suggest a way to specify alternate schemes, like :alternating
12:26cemerickyeah, that was snark ;-)
12:27duck1123I think :last is the best one truthfully. That's the one that fit's my use case when I ran into this yesterday
12:28Chouserthis is all to avoid one more nesting of 'let'?
12:28duck1123(let [a foo] (if-let [b bar] ... )) becomes (if-let [a foo b bar] ... ) but I can see how people might want :all as well
12:50unlinkWhere can I find a list of all the new transient methods?
12:50Chousukehmm
12:51Chousukefind-doc transient will probably find you them all
12:52unlinkThanks.
12:53unlinkSo assoc! is how I mutate arrays?
12:54Chousukevectors, and yes
12:54unlinkright...transient vectors
12:55tomojis this sane? (map #(vec [:foo %]) coll)
12:55Chousukemaking a vector out of a vector is a bit weird :P
12:55tomojthat's what I thought
12:55tomojbut not sure how to do it without "vec" there
12:56tomojsince otherwise the map will try to call the vector as a function
12:56Chousukeyou probably want to use a real lambda (map (fn [x] [:foo x]) coll)
12:56tomojaha
12:56tomojthanks
12:57unlinkDo transients scream 'leaky abstraction' to anyone else? Persistent data structures enforce immutability, but transients come with a caveat -- don't bash in place -- which is not technically enforced and easy to get wrong
12:57Chousuke#(foo) is short for (fn [] (foo)), which trips people up sometimes.
12:57tomojah, I see
12:57tomojthere is no shortcut for (fn [] foo) I guess?
12:57Chousukeno
12:57Chousukethough you can do #(do foo)
12:58tomojrather use a real lambda I think
12:58Chousukeunlink: I think it's possible it might become enforced at some point
12:59Chousukethough I suppose enforcing it would have to cost something
13:00Chousukebut I don't think it's a problem. Transients are supposed to be used carefully to begin with.
13:00unlinkThe second you start designing your programming language with warnings that a construct needs to be "used carefully", you have already failed.
13:01Chousukewell, I mostly meant that you should first design the algorithm with persistents, and then swap in transients if performance is a problem.
13:02unlinkI agree that they should not be the go-to idiom for designing clojure programs, but the "incidental" mutability of transient values is a very real part of the API of clojure.
13:02unlinkAnd no amount of warning will take that away.
13:02unlink(Unless technically enforced)
13:03Chousukeit'd help if the old values were invalidated, but I think that would cost too much in terms of performance.
13:04Chousukeyou'd need a flag for every interim value to indicate whether it's been used or not.
13:04tomojhmm.. I thought clojure was big on always enforcing immutability except through a few very specific APIs
13:05tomojwell, and all of Java
13:05unlinkWhich could kill cache locality. You're right -- it would negate part of the benefit of transients. As they stand, transients expose an enormous correctness abstraction leak.
13:05unlinkhowever.
13:06unlinkWhat makes this dangerous is that transients support the same read API as persistents.
13:06Chousukehmm
13:06ChousukeI don't think that
13:06Chousuke... will be a problem
13:08unlinkPerhaps this correctness issue could be culturally enforced. I know however I would be more comfortable if there was a safety net that ensured that I could never be handed a transient value that could change under my feet and still read like a persistent without warning.
13:09Chousukewell, transients can't be used outside the thread they were created in.
13:10Chousukeso even if you happen to get a transient as input to a read-only function, it's not going to change between two reads unless you also write to it through the transient api.
13:13unlinkRight, that is an essential safety measure.
13:13Chousukehmm, I wonder if transients could cache the most recent value of "this" and check it upon edits.
13:14Chousukewait, that makes no sense.
13:20cemerickwould it really be bad if a flag were set on every transient instance that had been used as the basis of a mutation operation (assoc!, conj!, etc)?
13:20cemerickyeah, I guess it would.
13:21Chousukesome indirection could work :P
13:22cemerickbut defeat the point, at least somewhat
13:22Chousukeyeah
13:23cemerickI'm happy enough to let the pitfalls be documented, and be done with it.
13:23cemerickyou can't blame the rope when you hang yourself
13:24cemericke.g. (let [a ..some transient..] (assoc! a :foo 5) (assoc! a :bar 6)) reflects some incredibly misguided thinking in general, so protecting against that is a tough order
13:28cemerick(I was called a 'lisp weenie' over the weekend. Maybe this is the kind of attitude that prompted that. :-P )
13:29ChousukeI'm always wary of function bodies that contain more than one expression :P
13:30d2dchatHow do you do the equivalent of && in a boolean expression?
13:31Chousukeuse (and ...)
13:32d2dchatChousuke: thx! I wonder why I couldn't find that in the API
13:33Chousukewell, and is not the easiest word to search for :P
13:33Chousukerather, it's a bit too easy to find :)
14:06kotarakHow can I parse xml files containing UTF-8 characters with clojure.xml/parse? The characters always turn to '?'.
14:09gcvwhat's the right way to determine the type of a Clojure value? I'm looking for an equivalent to (class x) which would return, e.g., :vector instead of clojure.lang.LazilyPersistentVector.
14:11hiredmangcv: why would anything return :vector
14:12kotarakgcv: quick hack http://paste.pocoo.org/show/133501
14:12tomoj(count (filter ...)) is not good with laziness, is it?
14:12kotarakbut why do you need it?
14:12kotaraktomoj: no
14:12hiredmantomoj: how could count be lazy?
14:13tomojwell, I mean, does it need to load the whole seq into memory at once, or not?
14:13kotarakobviously
14:14tomojguess I need to write filter-count then
14:14clojurebotfilter doesn't stop
14:14gcvkotarak: yeah, I was hoping to get a quick lookup... I'm working on writing Clojure values to Berkeley DB, and I need type tags, so I don't want to worry about the various vector types
14:15kotarakgcv: use multimethods with IPersistentMap etc, as dispatch values
14:15hiredman,(ancestors [])
14:15clojurebotnil
14:15hiredmaner
14:15hiredman,(ancestors (class []))
14:15clojurebot#{java.lang.Iterable java.lang.Runnable clojure.lang.Obj clojure.lang.IPersistentVector java.util.Collection clojure.lang.IFn clojure.lang.Seqable clojure.lang.Indexed java.util.List clojure.lang.AFn clojure.lang.Streamable java.lang.Object java.util.concurrent.Callable clojure.lang.IMeta java.util.RandomAccess clojure.lang.IObj clojure.lang.Sequential clojure.lang.IPersistentStack java.io.Serializable clojure.lang.Revers
14:16gcvancestors!
14:16gcvhiredman: thank you, that's the function I needed
14:16hiredmanclojure.lang.IPersistentVector msot likely what you want
14:16gcvhiredman: judging by the implementation of vector?, yes it is
14:17d2dchatcan someone help me figure out why expression is not evaluating properly?
14:17d2dchathttp://pastie.org/private/kax4t0yrhw2caujppupa
14:18hiredmand2dchat: what do you mean "not evaluating properly"
14:18d2dchatI'm getting an exception at the very end
14:18d2dchatException in thread "main" java.lang.ClassCastException: clojure.lang.LazySeq cannot be cast to clojure.lang.IFn (darwin.clj:0)
14:19hiredmanso somewhere you are trying to call a lazy-seq as a function
14:19d2dchatdo (/ 5 6) expressions turn into lazy sequences if you are concat'ing them?
14:20hiredmansure
14:20hiredmanbut (/ 5 6) is also not a function
14:20hiredmanso you cannot call it
14:20d2dchatbut you can eval it ?
14:20hiredmansure
14:21hiredmand2dchat: I would really suggest you spend more time getting to know the language instead of just jumping and trying to write genetic algorithms
14:21d2dchathehe
14:21d2dchatI learned a lot from this exercise, but I agree ;)
14:21d2dchatI think I got far though!
14:24d2dchathiredman: can you explain to me why when I (println expression) on line 39, I get my desired output
14:24d2dchatbut when I try to println outside of that context on line 48 it throws an exception?
14:25d2dchatisn't it just passing that around?
14:25Chousukebtw, rather than quoting each of the inner lists, you can just quote the vector :P
14:26hiredmand2dchat: in the paste there are only 25 lines
14:26d2dchatI didn't think I was using any vectors... don't vectors use [] notation?
14:26d2dchathiredman: whoops haha I have comments in my code
14:27hiredmanare you for real?
14:27hiredmando you see all the [] in your code?
14:27d2dchathiredman: Yes, but I'm using them for parameters?
14:27d2dchathiredman: line 16 = line 39
14:27d2dchatline 25 = line 48
14:28d2dchatsry for the confusion
14:28d2dchatOOOHH
14:28d2dchatI see what you're saying
14:28d2dchatlol
14:28d2dchatChousuke: thx :)
14:29hiredmand2dchat: somewhere you are trying to call a sequence like it is a function
14:29d2dchatChousuke: made my API much nicer :)
14:30d2dchatChousuke: hmm I get an exception now running with this: '[+ - / *]
14:30hiredmansince you are building lists (I guess, I really don't want to step through this line by line) I imagine expression is a list/sequence
14:30d2dchatException in thread "main" java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn (darwin.clj:0)
14:30ChousukeI think it's in the rand-item
14:30hiredmanon line 16 you try and call expression as a function
14:31hiredmanis it?
14:31d2dchathiredman: right, then I try to quote line 16 and it just returns (expression)
14:31d2dchatand when I try evaling that
14:31d2dchatit is like what??
14:31hiredman
14:31hiredmanplease learn clojure first
14:31hiredmanplease
14:32d2dchatlol, I didn't realize this room was reserved for complex questions.. sry.. I will do more research on my own :(
14:33d2dchatI understand that it can be annoying to answer the same questions all the time, but just thought I could get some quick reference
14:37cemerickd2dchat: simple questions are very welcome here, but trying to debug blobs of application code through irc isn't particularly easy
14:38d2dchatcemerick: agreed. I'm very appreciative of the help I received :)
15:26weissjdoes anyone know a way to add command history to the repl?
15:27ChouserI like rlwrap
15:27smoonenweissj -- I use http://utopia.knoware.nl/~hlub/uck/rlwrap/
15:27kotarakthere is jline (for completeness sake)
15:27gcvweissj: SLIME :)
15:28weissjhm ideally i could use it in eclipse, but i doubt that clojure-dev supports any of these
15:28kotarakAnd VimClojure Repl also does history
16:43replacatomoj, kotarak: (count (filter #(...) ...)) isn't lazy, but it doesn't hold head either. So you can run it without blowing memory.
16:44replacafor example, (time (count (filter #(zero? (rem % 2)) (range 1000000000)))) runs without any problem, with java staying at about 210MB on the billion item list.
16:44kotarakreplaca: depends on the second ...
16:45tomojreplaca: huh, and it's actually faster than the custom filter-count I wrote
16:45tomoj:)
16:46kotaraktomoj, replaca: (let [r (range 1000000000000)] (count (filter #(zero? (rem % 2)) r)))
16:47tomojisn't that holding the head?
16:48kotaraktomoj: bingo. If you aren't charge of the seq you get, you cannot guarantee that (count (filter...)) does not blow up.
16:48replaca kotarak: that's cause you're holding head with the let
16:49tomojluckily I'm in charge :)
16:49replacathat's just always a problem with lazy seqs!
16:50kotaraktomoj: and you buy that with computing time. If you want to use the actual seq again without count, you have to recompute it again.
16:51tomojI don't :)
17:28Anniepooclojurebot: paste
17:28clojurebotlisppaste8, url
17:28lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
17:35lisppaste8Anniepoo pasted "optional element in list" at http://paste.lisp.org/display/85162
17:35Anniepoosilly style question
17:36Chousukehm
17:37Chousukemaybe syntax-quote could help you?
17:38Chousuke,`(1 2 ~@(do nil) 4)
17:38clojurebot(1 2 4)
17:38Chousuke,`(1 2 ~@(do '(3)) 4)
17:38clojurebot(1 2 3 4)
17:38hiredmandepends what you mean by "build a list"
17:39hiredmanyou mean just have a list literal that conditionaly includes some element?
17:39Anniepoowell, I'm calling a bunch of functions in order and surrounding them with list
17:39hiredman:(
17:39hiredmansounds horrid
17:40Anniepoowell, I'm interacting with an imperative system I can only talk to over http in 2K chunks\
17:40Anniepooand can't use more than 64K memory
17:40hiredman,(for [x [#(inc 1) #(inc 3) #(inc 4)]] (x))
17:40clojurebot(2 4 5)
17:42hiredmanso you know which element you want to conditionally include?
17:42Anniepoo,(list "foo" (if (< 3 7) "maybe") "bar")
17:42clojurebot("foo" "maybe" "bar")
17:42Chousuke,(for [x [inc dec not identity] :let [z (x 1)] :when z] z)
17:42clojurebot(2 0 1)
17:43Anniepoobut that's broken for
17:43Anniepoo ,(list "foo" (if (< 8 7) "maybe") "bar")
17:43Anniepoo,(list "foo" (if (< 8 7) "maybe") "bar")
17:43clojurebot("foo" nil "bar")
17:44Anniepooexpecting ("foo" "bar")
17:44kotarak_,(concat (list 1 2) (when false (list 3)) (list 4))
17:44clojurebot(1 2 4)
17:44hiredman:(
17:44hiredmanconcat
17:44Anniepooyah, that looks more right
17:45Anniepoomake a sublist for each piece and concat them
17:45hiredmanwhat is the issue with filter?
17:45Anniepoonot one
17:45hiredman,(remove nil? (list "foo" (if (< 8 7) "maybe") "bar"))
17:45clojurebot("foo" "bar")
17:46Anniepoothis just felt 'horrid' and un-clojure-like
17:46Anniepooah, cool
17:46hiredmanwell, it isn't
17:47Anniepoothis one seems closest to expressing the idea of the code
17:47Anniepoo ,`(1 2 ~@(do nil) 4)
17:47Anniepoo,`(1 2 ~@(do nil) 4)
17:47clojurebot(1 2 4)
17:48hiredmansure, but are you using a literal or not, and willyou always be using a literal?
17:49hiredmanif the list of strings is built, it is possible to put the logic in the function that builds the list
17:49Anniepoono, I'm not using literals, I'm calling a different function for each element
17:49hiredmanthe other thing to keep in mind is:
17:49hiredman,(str nil)
17:49clojurebot""
17:49kotarak_For strings when should be sufficient
17:49kotarak_,(str "a" (when false "b") "c")
17:49clojurebot"ac"
17:50hiredman,(apply str (list "foo" (if (< 8 7) "maybe") "bar"))
17:50clojurebot"foobar"
17:50Anniepoowanted ("foo" "bar")
17:50hiredmanAnniepoo: but the list, not the elements of the list, is the list a literal or constructed
17:50Anniepoohmm... maybe I'm not understanding that question
17:51AnniepooI'm calling list
17:51hiredman(list (foo 1) (bar 2)) or (somefunction-that-produces-a-list some-input-data)
17:52hiredmando you think you will always produce the list that way? is it possibly you might switch to some other list producing function in the future (pull the list from a database, or over the network, or whatever)
17:52Anniepoothe first
17:53Anniepoono
17:53hiredmanfilter/remove will work for both cases (list …) and a list produced via some other method
17:53Anniepoothe list represents a series of commands to the external system
17:53AnniepooI'm writing a compiler for that system
17:55Anniepoothis is the convert-sane-representation-to-sequence-of-cmds-that-instantiates-it-on-what-amounts-to-hardware
17:57hiredmanI think anything you do will reimplement filter
17:57Anniepoook, cool
17:57hiredmanyou want to conditionally remove items from a list
17:58Anniepoojust wondered if there was an idiomatic way
17:58Anniepoorich hickey said at one point to try to stay close to expressing the idea of the code
17:59hiredmansomething like (remove nil? (list "foo" (if (< 8 7) "maybe") "bar"))
17:59Anniepooand the idea here in English is 'if 3 < 7 then add the third item'
17:59hiredmanusing when instead of if
17:59Anniepooyah, looks like it
17:59Anniepoothanks
17:59Anniepoohi Mike!
17:59mikehincheyhi Annie
18:00hiredmanif you make whatever recieves the list tolerant of nils in someway (silently ignore them?) then you don't need the remove
18:00Anniepootrue
18:01Anniepooif I do that, what I should do is some 'flatten' operation
18:01hiredman,(doc flatten)
18:01clojurebot"([x]); Takes any nested combination of sequential things (lists, vectors, etc.) and returns their contents as a single, flat sequence. (flatten nil) returns nil."
18:01tomojanyone heard anything about continuation-based web dev in clojure? reading an old thread from december, but it died
18:02Anniepooyah, oddly, that's the solution here
18:04Anniepoo,(flatten ("foo" '() "bar"))
18:04clojurebotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn
18:04tomoj,(flatten '("foo" () "bar"))
18:04clojurebot("foo" "bar")
18:04Anniepoo,(flatten '("foo" () "bar"))
18:04clojurebot("foo" "bar")
18:04Anniepoothanks tom
18:04Anniepoowhoo hoo, that's right
18:04Anniepooglad I asked
18:05Anniepoothanks all
18:46prospero_what allows *print-length* to be changed via set!
18:46prospero_if I try to change a def of my own, I get a "can't change root binding with set" error
18:47hiredmanprospero_: the repl is executed inside a binding
18:48prospero_yes, but if I call "set! *print-length* 10" outside the repl, it doesn't throw an exception
18:49prospero_it doesn't do anything either, I know, but I'm just wondering why it doesn't throw an exception
18:50hiredmanit's possible that the binding is created by the compiler
18:50hiredman*shrug*
18:50hiredmanI never use set!
18:51prospero_well, maybe you can suggest a decent way to handle this:
18:51prospero_I'm trying to handle memory management on the gpu
18:51hiredmanOh
18:51prospero_and I want to be able to define a threshold, above which it collects unused textures
18:52prospero_this should be a global setting, not necessarily within a binding
18:52prospero_so set! seems like a decent candidate
18:52hiredmanuh
18:52prospero_but maybe not?
18:52hiredmanhave you read the docs on set! ?
18:53prospero_maybe not as carefully as I should have
18:53hiredmanset! only works on threadlocaly bound vars, which are generally setup via binding
18:53prospero_I was more going on how it's used with *print-length*
18:53Anniepooprospero, it might make sense to make it an atom. You're trying to make something mutable
18:53hiredmanprospero_: http://clojure.org/vars#toc1
18:53prospero_anniepoo: that makes sense, it just seemed cleaner if it weren't wrapped in an atom or ref
18:54Anniepoo(def texture-mem-threshold (atom 7500000))
18:54osaundersHow do I split a string into characters?
18:54_mstwould alter-var-root be an option maybe?
18:54Chousukeosaunders: calling seq on it will return a seq of characters
18:54_mstI've never seen it used much in the wild so I'm unsure...
18:54prospero_hiredman: making it thread-local would be fine, actually
18:54Chousuke,(seq "foo")
18:54clojurebot(\f \o \o)
18:54prospero_I'll take a second look at the docs
18:54hiredmanprospero_: so then use binding
18:54osaundersChousuke: Thanks :)
18:55Anniepoosomebody explained to me, when I asked similar question, that the @mem-threshold had a salutary effect of warning that it's mutable
18:55Anniepoobecause of the @
18:55Chousukeif you use binding, it's not really mutable.
18:55prospero_hiredman: fair enough
18:55Chousukeit can just vary depending on the dynamic environment.
18:55hiredmanChousuke: tell that to set!
18:56Chousukehiredman: set! is evil and shall be ignored.
18:56hiredman:D
18:56hiredmanthat's what I like to hear
18:57AnniepooChousuke has a set of tights and a cape with a no-@ symbol and calls himself immutable man 8cD
18:57prospero_ok, so I guess I'll leave set! to *print-length*
18:57clojurebotcount
18:57Chousukebut really, set! is for setting stuff at the repl, and for java fields :)
18:58hiredman,(macroexpand '@x)
18:58clojurebot(clojure.core/deref x)
18:58hiredmanno @ needed
18:58hiredmanderef should yeild immutable values anyway
18:59Chousukethough my syntax-quote macro uses a thread-locally bound var as a "mutable".
18:59Chousukebut it's not shared between syntax-quote calls so it's fine.
18:59hiredman:(
19:00Chousukein fact, an atom wouldn't work since I'd have to take care of resetting it, and then you couldn't use the syntax-quote macro in two threads at the same time :/
19:02ChousukeI'm not using set! though.
19:02Chousukeit kept throwing exceptions and after a while I got alter-var-root to do what I needed.
19:05Chousukeactually, I wonder
19:05Chousukenow that I tested it, it's not doing what I want :(
19:12Chousukeand now it seems to work just right, when I changed it back to using set! ...
19:14hiredmanwonder if it would make sense to have an ur-clojure reader and compiler that work with ArrayList and HashMap for bootstrapping cinc
19:15Chousuke...
19:15ChousukeI think I will just stop trying to be clever with vars and pass down the autogensym map as a parameter...
19:15hiredmanif all the Persistent collections are written in clojure
19:16Chousukewell, the old clojure reader will probably work?
19:19hiredmanI guess
19:20hiredmanI guess LispReader.java isn't that bad
19:24Chousukegahh
19:24Chousukeit was laziness that was causing the trouble.
19:25hiredmanclojurebot: laziness?
19:25clojurebotPardon?
19:25hiredmanclojurebot: laziness is what will save us all
19:25clojurebotAlles klar
19:26Chousukenow it all works beautifully
19:26Chousukeclojure.core> (syntax-quote (foo# ~@(list 1 2 3) foo#))
19:26Chousuke(foo__auto__7666 1 2 3 foo__auto__7666)
19:26hiredmannice
19:26ChousukeI just have to get my reader into somewhat usable state too.
19:27Chousukecurrently, it can read itself!
19:27hiredmanthat is syntax-quote as a macro?
19:27Chousukeyes
19:27Chousuke(producing, unfortunately, not quite correct output ;()
19:27Chousuke(the reader, that is)
19:28Chousukesyntax-quote seems to be working
19:28hiredmanwhat does the macroexpand to?
19:28Chousuke(clojure.core/first (clojure.core/list (clojure.core/concat (clojure.core/list (quote foo__auto__7676)) (do (list 1 2 3)) (clojure.core/list (quote foo__auto__7676)))))
19:29hiredman:(
19:29Chousukethat's what syntax-quote does anyway :)
19:29Chousukejust read-time, so you never see it.
19:29hiredmanyeah
19:30Chousukethe (first (list ..)) at the start could probably be done away with, but it simplifies the implementation.
19:30hiredmanI think it is a good idea to keep computation in the same place it was before
19:30hiredmanread → compile → run
19:31hiredmanI guess it doesn't make a huge difference
19:34Chousukehttp://github.com/Chousuke/clojure/tree/clojure-reader here's what I have now (probably easiest to look at the commits page)
19:34Chousukeit's not usable yet at all, and I may destroy the branch at any time, but it's there if you're curious :P
19:36jwhitlarkIs there anyway to create an interface other than gen-interface? I need to dynamically create and pass an interface (not a class) to a function.
19:39ChousukeI'm not aware of any dynamic way of creating interfaces :/
19:39Chousukewould the function use reflection or something to figure it out, then?
19:40jwhitlarkkinda. It's for the java lib for dbus. You need to pass in an interface that tells what the remote object implements.
19:40jwhitlarkOf course, dbus provides that information, but I've not found a way for the java lib to use that to create the object.
19:40jwhitlarkyet.
19:41jwhitlarkperhaps a better approach would be to cast the resulting object against a proxy which implements the interface, but I'm not sure it that would work.
19:42jwhitlark(can't test it at the moment, I'm on the wrong machine)
19:42Chousukehm :/
19:43ChousukeI have no idea. And I'm off to get some sleep. Good night :)
19:43jwhitlarkThanks for trying, anyway. Good night.
21:00ataggartis there a way to make the following work properly? (defmacro foo [] `(defn bar [s] (println s)))
21:01ataggartright now when I call (foo), I get "java.lang.Exception: Can't use qualified name as parameter: user/s"
21:02arbscht(defmacro foo [] `(defn bar [s#] (println s#)))
21:03ataggarthmm, though I tried that
21:03ataggart*thought
21:04ataggartthanks
21:59rabidsnailWhy does clojure.zip/children not return a seq of nodes, but instead a seq of the data at the nodes?
22:00hiredmana seq of nodes would be pretty useless
22:00hiredmanwell
22:00rabidsnail(clojure.zip/branch? (first (clojure.zip/children (clojure.zip/vector-zip [1 [2 [3 [4 5]]]])))) --> java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn (NO_SOURCE_FILE:0)
22:01hiredman,(-> [1 [2 [3 [4 5]]]] zip/vector-zip)
22:01clojurebot[[1 [2 [3 [4 5]]]] nil]
22:01hiredman,(-> [1 [2 [3 [4 5]]]] zip/vector-zip zip/children)
22:01clojurebot(1 [2 [3 [4 5]]])
22:01hiredman,(-> [1 [2 [3 [4 5]]]] zip/vector-zip zip/children first)
22:01clojurebot1
22:01hiredman,(-> [1 [2 [3 [4 5]]]] zip/vector-zip zip/children first zip/branch?)
22:01clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
22:01hiredman~def clojure.zip/vector-zip
22:02gjahad /join #sa-website
22:02hiredmanweird
22:03rabidsnailCould it be a bug?
22:03hiredmanoh
22:03hiredmanit is not a bug
22:03tomojwhat exactly does the fact that watches are "Experimental" mean?
22:04tomojthey might not work right? or they might change/disappear in the future?
22:04hiredmanno, I think just the exact interface has not solidified yet
22:04tomojah, ok
22:05hiredmanrabidsnail: you are call branch? on something that is not a zipper structure
22:05hiredmanjust the exception is not very helpful because of the coding style used in branch?
22:06rabidsnailWhy doesn't children return zipper structures? next, up, down, etc. do, right?
22:07hiredmanrabidsnail: because the zipper is immutable, children would have to return new zipper structures for each child
22:08rabidsnailIsn't that what up down left and right do?
22:08rabidsnailWhy shouldn't children do that?
22:09hiredmanrabidsnail: yes, but neither returns more then one zipper structure
22:10hiredmanrabidsnail: why do you want children to return zipper structures?
22:10rabidsnailSo that I can recurse by mapping through them
22:10hiredmanhaha
22:11hiredmanyou can use something like (iterate zip/left zipper)
22:14hiredmanor, for that matter, you can just call vector-zip on each child
22:14hiredman(via map)
22:15rabidsnailthat's true
22:15alphaeusHow would you do (for [a1 (range 2) a2 (range 2) ... a40 (range 2)] [a1 a2 ... a40]) without writing all the a variables?
22:15hiredmanI can only imagine you must be doing this for side effects
22:16hiredmanalphaeus: I wouldn't
22:16hiredman,(doc nth)
22:16clojurebot"([coll index] [coll index not-found]); Returns the value at the index. get returns nil if index out of bounds, nth throws an exception unless not-found is supplied. nth also works for strings, Java arrays, regex Matchers and Lists, and, in O(n) time, for sequences."
22:16hiredmanactually
22:16hiredmanmap vector
22:16hiredman,(map vector (range 10) (range 10 20) (range 20 30))
22:16clojurebot([0 10 20] [1 11 21] [2 12 22] [3 13 23] [4 14 24] [5 15 25] [6 16 26] [7 17 27] [8 18 28] [9 19 29])
22:18Anniepooclojurebot: paste
22:18clojurebotlisppaste8, url
22:18lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
22:24alphaeushiredman: I don't understand how that code is a substitute for using for
22:25alphaeus,(count (for [i (range 10) j (range 10 20) k (range 20 30)] [i j k]))
22:25clojurebot1000
22:25hiredmanoh, right
22:25hiredman*that*
22:27hiredman*shrug* write a macro to generate the for expression for you
22:30lisppaste8Anniepoo pasted "multimethods oopsie" at http://paste.lisp.org/display/85172
22:30Anniepoothis is my first multimethod - I'm clearly having some noobie problem, but I can't see it
22:31Anniepoo(scroll to bottom before doing painful code reading)
22:34arbschtalphaeus: see clojure.contrib.combinatorics/cartesian-product
22:35hiredmanAnniepoo: something is trying to call a method on nil
22:35tomojaw man
22:35hiredmanso look for nils
22:35arbscht(count (apply cartesian-product [(range 10) (range 10 20) (range 20 30)])) => 1000
22:36Anniepoonils are my life
22:36tomojalphaeus: https://gist.github.com/1df4bbae8b2685b02826
22:36tomojmy first macro in clojure :)
22:37tomojbut use contrib
22:39tomojare you really going to use 40??
22:39tomoj..really big seq
22:44alphaeusarbscht: thanks
22:44alphaeustomoj: I wish I could but I don't think I have enough cpu or patience for it to evaluate
22:44tomojI did (count (n-bits 40)) and then I thought about what I just typed a bit...
22:52arbschtAnniepoo: I don't follow what's going on in lsl-type. is "^x" a typo? is meta-type a function?
22:53Anniepooit's the metadata for x
22:54AnniepooI need to ensure that things get uploaded as the proper type in the external system
22:54Anniepooso I tag my data with it's type in the external system
22:55hiredmanAnniepoo: start add println's and look for the source of the nil
22:55Anniepooit's that line
22:55Anniepoothat is, it's the multimethod call
22:56Anniepooit's not getting to any of the multimethod cases that I can see
22:56Anniepoothough I can trip a breakpoint in lsl-type
22:56hiredmanAnniepoo: that means it is the dispatch function
22:56arbschtcan you explain what meta-type is?
22:56hiredmanso something in the dispatch function is calling a method on nil
22:57hiredmanpossibly x is nil
22:57hiredman,^nil
22:57clojurebotnil
22:57hiredmanbah
22:57hiredman,(let [x nil] ^x)
22:57clojurebotnil
22:57Anniepoothis system is a GUI that lets the user draw stuff onscreen, then sends it by an arcane system to the Second Life virtual world
22:57Anniepoometa-type is the type the data will have in Second Life
22:58hiredmanoh
22:58arbschtin cond, you're invoking it as a function
22:58Anniepoolsl-type extracts the type
22:58hiredmanyeah
22:58Anniepoothe metadata is authoritative
22:58hiredman,(nil)
22:58clojurebotjava.lang.IllegalArgumentException: Can't call nil
22:58Anniepoobut it's often obvious from the clojure type
22:58Anniepooaaargh!
22:58hiredmanAnniepoo: you are call meta-type as a function
22:58Anniepooyou're right
22:58Anniepoothanks
22:59AnniepooI meant to just check if it was nil
22:59hiredmanwell it was
22:59AnniepooLOL
22:59Anniepooodd, wonder why it's nil
23:01rabidsnailIs there a reverse operation for seq-zip?
23:02hiredmanuh
23:03hiredmanwhat?
23:03rabidsnail(reverse-operation (seq-zip thing)) == thing
23:03hiredman,(doc zip/root)
23:03clojurebot"([loc]); zips all the way up and returns the root node, reflecting any changes."
23:04rabidsnailwhen I do that I get a bunch of stuff added.
23:04hiredmanhttp://clojure.org/other_libraries#toc5
23:04rabidsnailvectors and maps and such
23:05hiredmanthat means you are changing the zipper
23:05hiredmanif you want to keep the original, you should hang on to it before you start editing
23:06rabidsnailI don't want the original, I wan a clean chaned version that doesn't have maps with :pnodes and :ppath and such
23:06rabidsnailchanged
23:06rabidsnailrather
23:07hiredmanuh
23:07hiredmanyou are doing something wrong
23:08hiredmanthe :pnodes stuff is part of the editing, once you call root it should be there, if it is, that means you messed up a call somewhere and broke the zipper
23:08hiredman,(-> [1 2 3 4] zip/vector-zip zip/next)
23:08clojurebot[1 {:l [], :pnodes [[1 2 3 4]], :ppath nil, :r (2 3 4)}]
23:08hiredman,(-> [1 2 3 4] zip/vector-zip zip/next zip/root)
23:08clojurebot[1 2 3 4]
23:08rabidsnailoh
23:22Anniepooin this example are the commas significant?
23:22Anniepoo(let [{a :a, b :b, c :c, :as m :or {a 2 b 3}} {:a 5 :c 6}]
23:22durka42no
23:23durka42commas are always whitespace
23:23Anniepoothanks