#clojure logs

2010-01-20

00:09replacanew rule proposal: projects written in Clojure may not have the letter "j" in their names
00:10technomancyreplaca: yes please!
00:11technomancythat cocoa bridge had a name that just made me cringe
00:12defn`i like the ji thing
00:12defn`like djirk
00:15technomancypersonally I'm naming all my projects after literary characters from now on
00:17alexyktechnomancy: how about I sing praises for leiningen every day for 5 days if you add host to lein swank in addition to port tmrw? :)
00:17replacaI think I'll go for the dullest possible names
00:18replacastarting with "autodoc"
00:18technomancyalexyk: you could spend the time you would potentially spend singing praises to write the code. =)
00:18replacawhich would be pretty cool if it took out your appendix, but less so with the whole html generation thing
00:18alexyktechnomancy: I don't know where to begin, macros scare me
00:19alexykplus I don't know swank and where the host would need to be stuck/plucked from
00:19alexykI'd rather stick to my core competency of singing and let you add it :)
00:19technomancyheh
00:19defn`my core competency is witchcraft
00:20technomancyalexyk: the swank server binds to more than just localhost for me
00:20alexykdefn: don't you have to be a witch to practice it?
00:20technomancydid you want to limit it to *just* localhost?
00:20alexyktechnomancy: no, I don't see it binding to the external IP. Hmm.
00:20alexykI actually wanted to have a host to explicitly tell it to bind there.
00:20defn`alexyk: i havent gotten that far yet
00:21alexykdefn: I never heard of male witches either
00:21technomancyalexyk: binding to 0.0.0.0 should work for all active interfaces
00:21replacatechnomancy: is the sonian crew going to brave the tsunami and come to functional alcoholics tomorrow?
00:22alexyktechnomancy: does it try to bind to 0.0.0.0 by default?
00:22technomancyreplaca: that's the plan
00:22technomancyalexyk: seems to here
00:22alexykhmm
00:22replacatechnomancy: cool. looking forward to it.
00:23replacait'll be fantastic not to be the only clojure guy there
00:23technomancyreplaca: we should outnumber the scala guys this time. =)
00:23technomancyreplaca: how many attend total normally?
00:23replacatechnomancy: especially since we seem to be converting al3x
00:23replaca30-40
00:23technomancywow!
00:23technomancyseafunc is 5-6
00:23alexyksay I'm carrying around a tortured Java object. To mimic FP, I have defns like, (defn doGraph [graph] ... graph). Will it copy the graph, or, it being a Java object, pass references around?
00:23replacawe take our tech seriously by the bay :-)
00:24replacadoes seafunc involve beer?
00:24alexykreplaca: it used to
00:24technomancyit varies. I'm sure that affects things.
00:24replacathat seems to be what brings them out
00:24technomancyalso it only happens 4 or 5 times a year, which is lame
00:25technomancyalexyk: you've been?
00:25alexyktechnomancy: yep
00:25replacathere used to be bayfp, too, which was more serious. But I don't think they've had one in a while
00:25technomancyalexyk: you in the area?
00:25alexyka series of bearded and unbearded folks, the great FP ones, in University City or Capitol Hill... a couple years ago, alas.
00:26woobyanyone ever run across clojure jobs in the bay area?
00:26technomancyI'm thinking about having a Seattle Clojure meeting next month
00:26technomancygot 5 already interested
00:26alexykI visit when giving a talk at MSFT once in a while
00:27alexykor visiting my friends in the area
00:27alexyktechnomancy: amazing, for clojure
00:27alexykso what about accepting and returning a Java object in a defn, does it copy or hopefully not?
00:28technomancyit won't copy unless you explicitly do it
00:28alexykgood
00:28replacatechnomancy: I think I may have had the honor of hosting the biggest pure clojure meetup ever
00:28replaca(to date that is)
00:29replacawhen Rich came to SF and we had the bay area group meeting
00:30technomancyreplaca: yeah, I made it for that one
00:30technomancyvery exciting
00:31joeggtechnomancy: what you mean "explicity do it", regarding the copy?
00:32joeggAs in (.clone foo)? Or am I missing something?
00:32technomancyjoegg: that's what I meant, yeah
00:32technomancythere's no auto-immutablize
00:32replacatechnomancy: I remember - a good crowd, but too much for the space
00:32technomancystanding room only
00:32joeggtechnomancy: Thanks, just wanted to make sure I hadn't missed something big.
00:34alexykI'm running clojure under rlwrap and suddenly see rlwrap at 100% CPU all the time, and Java at 50-150% (8 cores). Is there a reason why rlwrap would hog CPU?
00:40TheBusbyis there an easy way to rebind *in* to a file for testing in slime?
01:42rikthevik_i want to write a pipeline function . it takes functions a, b, c and an initial value then calculated (c (b (a initial)))
01:42rikthevik_thoughts?
01:42rikthevik_i did it lisp-style using pop and peek, but it's not working great when the list of functions is a seq
01:46TheBusbyrikthevik I think there is already something similiar, like ->>
01:46TheBusbyor -->
01:46TheBusbyone of the arrows I believe
01:47TheBusbygood luck googling for it though...
01:50TheBusby,(doc ->>)
01:50clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
02:20konr`What's the best way to represent a file? Is it a good idea to stick with Java's IO classes, or it's fine to create some convention for my function, like a PATH starting with @ denotes a file?
02:25technomancykonr`: I generally represent it as a string until I need to call file-related functions/methods on it
02:26technomancykonr`: c.c.java-utils/file is great for that; it will turn its argument into a file whether it's a string or already a file object
03:19quizmeif you make something a ref, does that mean it's going to use another thread when possible?
03:21technomancyquizme: refs just have values; they don't represent computation
03:21technomancymaybe you're thinking of agents?
03:21quizmeconversely, if you don't use a ref, atom, etc., does that mean it's NOT going to use another thread?
03:21quizmeum
03:21quizmei dunno
03:21quizmejust general confusion i think
03:22quizmei guess i'm wondering: what is it about clojure that makes it inherently more multi-CPU friendly?
03:23defn`it's functional
03:23defn`no side effects
03:23quizmeand: are there any language constructs that let you control the threads.... (ok agents is one)
03:23quizmefunctional => all CPUs will be used?
03:23defn`agents, refs, atoms
03:24defn`quizme: no. http://en.wikipedia.org/wiki/Functional_programming
03:24quizmewhat does function programming have to do with multi-CPU friendliness?
03:24defn`functional as in, functions are first class
03:24quizmefunctional*
03:25defn`quizme: watch http://www.vimeo.com/8426709
03:25quizmei'm just trying to make the connection between the language and being able to use all the CPUs
03:25defn`quizme: you're not going to do it by making wild guesses
03:26defn`it's false in the first place to say "use all the CPUs"
03:26defn`because A.. we're talking about cores, and B.. you can use all of the CPUs in any old language
03:27defn`cores
03:27quizmeok cores
03:29defn`quizme: what other languages have you worked with?
03:30quizmescheme, c, c++, java, ruby, php, as3, javascript
03:30defn`and you don't understand how functional programming solves many of the problems of concurrency?
03:31quizmeno
03:31defn`have you written applications with locks in c?
03:31quizmeno
03:31quizmeno to both questions
03:32defn`what does functional programming mean to you?
03:33quizmefunction behavior only depends upon the arguments
03:33defn`which means...no side effects
03:34quizmeyah
03:34defn`which makes concurrency easier
03:34quizmeso what does that have to do with cores ?
03:34defn`in a non-functional style you have to be worried about what other objects any given function/method is touching
03:36quizmeok
03:37defn`quizme: do you see how that makes scaling cores easier?
03:38quizmeif two cores are processing the same data at the same time, you know that the action of one function won't affect the behavior of another function?
03:40defn`let's call them threads
03:41quizmeso
03:41defn`quizme: the software transactional memory is important here
03:41quizmeif you want to increment x
03:42quizmelike in Lau's vimeo link you gave me
03:42defn`mmhm
03:42quizmeactually
03:42quizmeit's better to use a lazy sequence instead of atoms and all that ?
03:42defn`they're for different things
03:42quizmecuz a lazy sequence is immutable
03:42defn`,(doc atom)
03:42clojurebot"([x] [x & options]); Creates and returns an Atom with an initial value of x and zero or more options (in any order): :meta metadata-map :validator validate-fn If metadata-map is supplied, it will be come the metadata on the atom. validate-fn must be nil or a side-effect-free fn of one argument, which will be passed the intended new state on any state change. If the new state is unacceptable, the validate-fn should return
03:42quizmeyes? no?
03:43defn`you need to read more before you will have a clear picture
03:43defn`atoms and lazy seqs aren't even close to related for the purposes of this discussion
03:47quizmelet's say you didn't have any mutable data
03:48quizmehow do you know if you program is going to use multiple cores or not?
03:48quizmejust because your program is functional and processing immutable doesn't mean it's parallelizable.
03:49quizmeimmutable data i mean
05:32lpetitclojurebot: seen cgrand
05:32clojurebotcgrand was last seen quiting IRC, 274 minutes ago
05:35esjclojurebot you stalker
05:39paoclojurebot: (take 1 (filter zero? (concat (take 10 (repeat 1)) [0] (repeat 1)))
05:39paohmmm
05:39paowhy does this doesn't terminate?
05:43paoclojurebot: (first (filter zero? (concat (take 10 (repeat 1) [0] (repeat 1))))
05:43esji think because of the filter
05:43paoesj: missing parens
05:44paoclojurebot: (first (filter zero? (concat (take 10 (repeat 1)) [0] (repeat 1))))
05:44esjit never gets a non-zero value
05:44paoesj: there a zero value
05:44pao*there is
05:44pao(first (filter zero? (concat (take 1000 (repeat 1)) [0] (repeat 1))))
05:44esjafter an infinite number of 1s, no ?
05:44paoclojurebot: (first (filter zero? (concat (take 1000 (repeat 1)) [0] (repeat 1))))
05:45paoesj: no, after 10 1s
05:45esjhmm....
05:45pao1000 in this case
05:45paoesj: to you know how to query clojure version?
05:45paoit was a parenthesis problem, now on my machine it runs
05:46esjwhen the REPL starts it says
05:46paoesj: I was wondering about clojurebot's clojure version
05:46esjdunno :)
05:46paoesj: no prob :-)
05:47paoclojurebot: (take 10 (repeat 1))
05:47paoclojurebot: > (+ 1 1)
05:47paoclojurebot: help
05:47clojurebothttp://www.khanacademy.org/
05:48unfo-not the khan i was expecting
05:48pao> (+ 1 1)
05:48esjyou expecting designs for a nuke ?
05:48unfo-nope
05:48pao(+ 1 1)
05:48clojurebot2
05:49pao(take 10 (repeat 1))
05:49esjhahahah, missing parens !
05:49paoI guess it doesn't print seq...
05:49pao(first (take 10 (repeat 1)))
05:49unfo-esj, http://www.khaaan.com/
05:49esj(take 1 (filter zero? (concat (take 10 (repeat 1)) [0] (repeat 1))))
05:49esj,(take 1 (filter zero? (concat (take 10 (repeat 1)) [0] (repeat 1))))
05:49clojurebot(0)
05:50paoesj: what's the comma for?
05:50esjto ask clojurebot to execute the command :)
05:50paoesj: ah ok :-)
05:50esjnp
05:50pao,(take 10 (repeat 1))
05:50clojurebot(1 1 1 1 1 1 1 1 1 1)
05:50paonice :-)
05:51esjclojurebot is very friendly, for a stalker.
05:51paoesj: LOL
06:03taliosMorning
06:04AWizzArdHi tal
06:05taliosmm been ages since I've fired up linkinus and lurked on IRC
06:07Chousuke,*clojure-version*
06:07clojurebot{:interim true, :major 1, :minor 1, :incremental 0, :qualifier "master"}
06:07Chousukehmmh.
06:25esjnow I know, thanks.
06:47vu3rddgiven a sequence, is there a way to extract the elements from the first to last-but-one and the last?
06:47vu3rddthat is, first/rest but on a reversed list?
06:47vu3rdd(doc reverse)
06:47clojurebot"([coll]); Returns a seq of the items in coll in reverse order. Not lazy."
06:48cypher23(doc butlast)
06:49clojurebot"([coll]); Return a seq of all but the last item in coll, in linear time"
06:49cypher23(doc last)
06:49clojurebot"([coll]); Return the last item in coll, in linear time"
06:49cypher23vu3rdd, ^
06:49vu3rddcypher23: thakns
06:49vu3rddthanks
07:26dabdI don't see much use for the predicate empty? since (not (empty? is discouraged as it involves a double negation. So why not remove it and simply use (not (seq and (seq insted?
07:33LauJensendabd, empty? for testing true/false, seq and not-empty for nil/coll
07:56dabdwhat is the alternative for the #^ reader macro?
09:20kiumahello
09:20kiumais there a library to print html code ?
09:20chouserkiuma: hi!
09:20chouser(println "<html></html>") ;-)
09:20LauJensenkiuma: Compojure is a good bet
09:20kiuma:/
09:21LauJensen(html [:h1 "Hello Html"])
09:21chouserkiuma: I guess it depends on what you're starting with.
09:22chouserIf you have designer-created html that you want to adjust, I'd recommend enlive
09:22kiumachouser, I created CLAW that is in common lisp
09:23kiumaa claw html renderer is similar to cl-html
09:24kiumait transforms something like (div> (span> "foo")) to <div><span>foo</span></div>
09:24kiumadoes already exist something similar in clojure ?
09:25chouserkiuma: ah. yeah, compojure has a lib for doing things roughly like that. something roughly like that has be written several times in clojure
09:25cemerickouch
09:25cemerickkiuma: give enlive a try http://wiki.github.com/cgrand/enlive/
09:25kiumaok htx
09:25chouserusually the clojure ones use keywords and vectors, so something like [:div [:span "foo"]]
09:28kiumachouser, so I only should implement a parser, right ?
09:29cemerickkiuma: are you aiming to create another templating library?
09:29chouserkiuma: an html parser? there are good ones available already.
09:30kiumaId like something that is the most similar to html
09:30dabd`if the ^ read macro is deprecated in 1.1 what will substitute #^ ?
09:30chouserdabd`: eventually, yes.
09:30cemerickdabd`: I think with-meta will be required
09:31chouseroh, sorry, misunderstood. #^ has not been deprecated
09:31cemerickoh, I thought it was :-/
09:31cemerickkiuma: it's worth using existing libs unless there's something compelling to build separately.
09:31cemericksome compelling reason, I mean
09:32cgrandkiuma: enlive is so similar to html that it's html ;-)
09:32chouserthere's nothing else that will work in place of #^, though I guess ^ will eventually
09:32dabd`so only ^ will be deprecated
09:32cemerickcgrand: I've been trying to soft-pedal it ;-)
09:32sethskiuma: if you need to generate Javascript easily consider http://github.com/arohner/scriptjure/
09:32Hali_303hi! In Emacs/SLIME, when I try it the repl or do a compilation it hangs. how to find out what is the trouble?
09:33cgrandcemerick: I noticed your efforts :-)
09:33sethsHali_303: can you switch to the *inferior-lisp* buffer?
09:33Hali_303seths, yes
09:33sethsyou should hopefully see something like
09:33sethsuser=> user=> Connection opened on local port 49318
09:33seths#<ServerSocket ServerSocket[addr=0.0.0.0/0.0.0.0,port=0,localport=49318]>
09:33kiumaseths, javascript must be done in javascript
09:33Hali_303seths: yes, that is there
09:34kiumaand not in html pages
09:34dabd`sorry to repeat the question but what is the use of the empty? predicate if (not (empty? is discouraged because of the double negation? Why not remove empty? and simply use (not (seq and (seq instead?
09:34Hali_303seth: also, below that: user=> user=> WARNING: reader macro ^ is deprecated; use meta instead
09:34Hali_303WARNING: reader macro ^ is deprecated; use meta instead (
09:34kiumathis beacause it avoid compression in any other language
09:34cemerickdabd`: (not (empty?)) is discouraged?
09:35sethskiuma: sure, but Scriptjure is pretty slick: (js (alert "hello world")) => "alert(\"hello world\")"
09:35chouserdabd`: (not (seq x)) is less clear than (empty? x)
09:35cemerickcgrand: I'm *almost* to the point of knowing what I'm doing with enlive :-) It's quite pleasant.
09:35sethsHali_303: hmm, it sounds like swank is running then
09:35dabd`cemerick if you read the documentation it recommends avoiding (not (empty? and use the idiom (seq instead
09:36Hali_303seths, when I type (+ 1 2) I can see that parentheses-matching is also working, but if I press enter after that, it hangs
09:36cgrandcemerick: I'm happy to hear that!
09:36dabd`chouser: but (seq x) is also less clear than (not (empty? x)). At least for me...
09:36cemerickdabd`: I'd say either is fine -- many people (myself included) like a 'literate' style, where the semantics of empty? are helpful
09:36kiumaseths, compression -> http://www.wingstech.it/claw/dojotoolkit/dojo/dojo.js
09:36dabd`cemerick: yes. I appreciate that too
09:38sethsHali_303: hrm.
09:38chousermutliple negatives are more difficult to think about than simple positives.
09:38cemerickcgrand: the only thing I need to figure out is how to structure things properly. "normal" templating languages allow you to segment code pretty naturally based on one's layout -- that not being available means one has to figure out how to compose various transformations for each page, etc.
09:38sethsHali_303: how was swank-clojure installed?
09:38foguschouser: That is not not not not true
09:39ordnungswidrig(def full (comp not empty?))
09:39cemerickchouser: empty? is a predicate, and doesn't imply a negation.
09:39dabd`chouser: but when you use (not (empty? x)) the multiple negative is hidden in the implementation of empty? right?. For the user there is only one negation.
09:39chousercemerick: right. so say (empty? x) instead of (not (seq x))
09:40chousercemerick: but also, say (seq x) instead of (not (empty? x))
09:40Hali_303seths: checked out into a directory as described here: http://riddell.us/tutorial/slime_swank/slime_swank.html
09:41cemerickchouser: the fact that empty? is implemented using a negation is an implementation detail, IMO, and shouldn't influence coding style *shrug*
09:41ordnungswidrigcemerick: hehe
09:41chousersorry, let me amend my statement. *any* negation is harder to think about that simple positive statements
09:41cemerickconsider an alternate universe where seq returns an ISeq instead of nil for empty, and provided an .isEmpty() method.
09:42cemerickeven more to the point, what about if/when empty? becomes a protocol, totally divorced from seqs?
09:42somnium`(when-let [s (seq arg)] ...) seems more elegant than (when-let [s (not (empty? arg))] ...)
09:42foguschouser: I !disagree
09:43cemerickheh
09:43sethsHali_303: another option is to use leiningen
09:43cemerickfogus: go away with your algolisms! :-P
09:43foguscemerick: (not :))
09:43ordnungswidrigoffline...
09:44Raynesfogus. He disagrees.
09:44sethscreate a project, add [leiningen/lein-swank "1.0.0-SNAPSHOT"] to the :dev-dependencies
09:44sethsand then run swank-clojure-project
09:44sethshas been the smoothest process for me
09:44Hali_303seths: ok, I'll look into that, thanks
09:44sethsg/l
09:50cgrandcemerick: I've been experimenting with layout as middlewares. In such a setting the :body of the response is a map whose vals are html fragments.
09:51sethsdoes anyone know if clojure-mode has been updated for deftype?
09:51sethswhen I'm defining a method inside a deftype, clojure-mode indents like I'm calling the function
09:52sethssince there is no defn or similar keyword
09:52AWizzArdat least jochu’s repositories were not updated for months
09:53cemerickcgrand: I'm afraid I can't visualize that right off the bat.
09:53cemerickcgrand: I've been toying with identifying + looking up transformations based on element id's in the template/snippet.
09:53Hali_303seths: it seems that slime was also installed as an ubuntu package and that did not like the one installed manually. working now, thanks!
09:54sethsHali_303: glad to hear it's working, not that I did anything really :-)
10:09seths,(with-meta "foo" {:bar 'baz})
10:09clojurebotjava.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IObj
10:09seths:-(
10:09sethsI'm being idealistic I suppose
10:10angermanseths: there's nothing that keeps you from adding meta support to your own string type
10:12cemerickwhere do plans stand w.r.t. require? Typing [foobar :as foobar] all over the place is getting just a little old. :-)
10:14fogus,(let [x (with-meta (lazy-seq (seq "foo")) {:bar 2})] [(class x) (meta x) (apply str x)]) ;; total hackery
10:14clojurebot[clojure.lang.LazySeq {:bar 2} "foo"]
10:15sethsfogus: woah
10:15sethswhy wrap (seq) in a lazy-seq?
10:16fogussomething to attach metadata to. But mostly just to be playful
10:18sethsI noticed that deftype says it only works for interfaces, e.g. String is rejected, but Object works fine
10:18sethswonder why the special case? maybe since Object is the top of the Java food chain?
10:19fogusseths: For a string-like deftype, I would consider CharSequence
10:19sethshmm
10:19chouserthat'll at least work with regex
10:19chouseriirc
10:26sethschouser: I think deftyping CharSequence would work with regex, but it would be painful
10:27sethshave to expose all the methods that are invoked on CharSequence by the regex code
10:30sethsanyways, just to wrap up the thought experiment with meta on a string
10:30sethsthis technically works but is really gross
10:30seths,(deftype MyStringType [a-str] CharSequence (toString [] a-str))
10:30clojurebotjava.lang.Exception: Unable to resolve symbol: deftype in this context
10:30sethsalas
10:31seths(str (with-meta (MyStringType "abc") {:foo 'bar}))
10:31Chousukeseths: I guess Object methods are overrideable because you're forced to derive from it in any case and not being able to override things would just be limiting
10:36dabda very basic question: I thought the following would not work (let [a (ArrayList.)] (.add a "1") a) because the ArrayList would be immutable. Only Clojure data structures are immutable? If you create a Java data structure it is mutable? thx
10:37Chousukedabd: the reference "a" is immutable, not the data structure itself
10:37Chousukedabd: Clojure can't make Java's mutable things suddenly immutable :)
10:38dabdbut if a was a ref to a Clojure map the map itself would be immutable (and also the ref)?
10:39Chousukeyes.
10:39dabdthx
10:44angermanI've created a pretty stupid ascii-progress chart i though I'd share: http://ideone.com/LU8RUJCD
10:47dabd(second [1 2])
10:48dabd,(second [1 2])
10:48clojurebot2
10:51sethscemerick: what's the latest on the string interpolation code?
10:51cemerickseths: sitting right over here :-) I suppose I should open a ticket for adding it, but I haven't heard much in the way of demand.
10:52sethsI'm getting a little tired of (str x y z)
10:52sethswouldn't mind using it, not sure if there is any licensing on it yet?
10:53tolstoyseths: You mean something like Groovy's "some ${nice} interpolation?"
10:53sethstolstoy: exactly
10:53sethshttp://muckandbrass.com/web/display/~cemerick/2009/12/04/String+Interpolation+in+Clojure
10:54cemerickseths: feel free to use it. Wouldn't have posted it otherwise.
10:54sethsgreat, thanks
10:54joeggIs there a single function that will build an infinite sequence from a single item, or should I just "(cycle (list 4))"? Basically, I'm looking for "constantly" except for sequences.
10:55angermanjoegg: repeatedly
10:56Chousukerepeatedly is for functions
10:56Chousukerepeat is for items
10:56tolstoyseths: I kinda with that was in contrib. ;)
10:57joeggI guess you can clean it up a bit with (cycle [4]) instead of calling list.
10:57Chousuke,(take 5 (repeat 4))
10:57clojurebot(4 4 4 4 4)
10:58joeggChousuke: That looks perfect.
10:58Chousukeit's optional :)
10:58angermanhas it always been optional?
10:58ChousukeI don't think so.
10:58angermanhmm. so maybe my memory is just too old :)
10:59Chousukethere were two functions at some point
10:59Chousukebut then someone realised that repeat is enough :P
10:59joeggOkay, so: (constantly 4) will build a function that always returns 4, (repeat 4) builds an infinite sequence of 4, and (repeatedly somefn) will build a lazysequence based on the results of calling some function. Let's not even get into iterate. :)
11:00joeggAnd if I said something wrong there, please do correct me.
11:00Chousukeyou're correct.
11:01sethstolstoy: cemerick is the author
11:01Chousukeiterate is not that difficult either. it just keeps calling the function on its return value
11:01sethsI agree with you, would be nice to have around
11:01joeggAmazing. The only thing that worries me about clojure so far is that I'm bet I'm doing a lot of stuff like (cycle [4]) because I haven't yet internalized (for instance, (repeat 4).
11:02cemerickI guess that makes four 'seconds' on the notion of adding it to contrib. I suppose I'll have to open that ticket now. :-)
11:02Chousuke,(take 5 (iterate / 9))
11:02clojurebot(9 1/9 9 1/9 9)
11:02Chousuke:P
11:03tolstoycemerick: Do you think there's room in it for adding formatter type things? Like ~0,2{num} for zero padding, or some such thing? Or would that be too much.
11:03tolstoycemerick: I'm thinking that if you need more than simple interpolation, format works, but, I don't know, would be kinda cool for that once in a long while use case.
11:04cemericktolstoy: yeah, there's lots of room for stuff like that. I haven't thought about it at all, though.
11:04Chousuketolstoy: for that you probably want to take a look at cl-format in clojure.contrib
11:04sethscemerick: whatever you do, don't make it as painful as formatting std::cout is in c++
11:04cemerickI suppose I would like to reuse what java's Format provides.
11:04tolstoycemerick: The danger is it becomes yet another embedded DSL. (like cl-format.... )
11:05cemerickyeah, I definitely would stay away from anything approaching CL's FORMAT.
11:05cemerickjava.text.Format is just fine. Beyond that, go write a function, please.
11:05tolstoyYes, String.format works for me.
11:06tolstoyBut, I'd find it useful for logging. (log/info (<< "some ~{value} and another ~{thing}"))
11:06tolstoyBut then I'm a "printf" debugger type. ;)
11:06sethstolstoy: there's a FaceBook fan page for that
11:06sethsprintf debugging
11:06cemerickI use << for logging all the time :-)
11:08tolstoyseths: debuggering? I'm not even going to try and picture that.
11:09sethslol
11:09cemerickoh, yeah, -?>> would be helpful
11:09tolstoycemerick: maybe (log/info<< "the ~{a}'s have it")
11:09sethsyou could have special macros for logging
11:10sethslike this for really bad errors (>_< "inconceivable!")
11:10tolstoythe smilification of logging, eh?
11:10tolstoy(; "it worked!")
11:11sethstolstoy: I see what you did there
11:11tolstoy(-( "error!"))
11:17woobyseths: LOL
11:17wooby(8-o "oh no!")
11:20chouser,'(T_T "Oh dear")
11:20clojurebot(T_T "Oh dear")
11:20chouser,'(x_x "failed completely")
11:20clojurebot(x_x "failed completely")
11:20somnium`http://www.lrde.epita.fr/~didier/software/smilisp.php << maybe there's something to this
11:21the-kennyImplementing smilisp is a bit hard because it isn't possible to define your own reader-macros in cloure code
11:21tolstoyAnd now we know why.
11:26tolstoyCan you use deftype/reify to, say, create a custom exception class in clojure? Dynamically?
11:27Chousukehmm.
11:27Chousukearen't they limited to interfaces?
11:27tolstoyThat's what I was thinking (from what I read).
11:27AWizzArdWell, then there is still (proxy ...)
11:28tolstoyBut that's not named, is it? You can't (catch CustomException ...), right?
11:28stuartsierraproxy won't create a named class that you can use in a try/catch
11:28chouserbut you can't really rely on the name of the class ... right, whatever everyone is saying.
11:29stuartsierraIf you want named classes, you must compile ahead-of-time.
11:30tolstoyI sometimes have a use case (web requests which in turn call other remote services), where I'd like to create an exception that has several attributes. I can throw it, and at the top I can just catch the exception, formulate an error response, and return.
11:30chouserdefprotocol now creates named interfaces without AOT
11:30chousertolstoy: look at clojure.contrib.condition
11:31tolstoychouser: Ah, hm. I bet that's exactly what I need.
11:34LauJensenIs there something nice in contrib for downloading binary files?
11:34tolstoyDownloading from the web? http-agent works.
11:34the-kennyclojure-http-client should support this
11:35LauJensenk thx
11:36angermanDoes anyone know how to figure out the iowait statistics on os x?
11:39CalJunior,(defstruct foo :bar)
11:39clojurebotDENIED
11:39CalJunior(defstruct foo :bar)
11:39CalJunior(def map1 (struct foo nil)
11:40CalJunior(assoc map1 :bar 1)
11:40CalJuniorreturns {:bar 1}
11:40CalJuniorhowever if I call map1
11:40CalJuniorit returns {:bar nil}
11:41the-kennyCalJunior: Clojure is a functional language with immutable data structures
11:41CalJuniorYes I know it's immutability.
11:41fliebelThe assoc did not actually change anything...
11:41fliebelIt only returned the changed struct
11:41CalJuniorHow do I get it to return {:bar 1}
11:41CalJunior?
11:42ohpauleezuse an atom or a ref
11:42the-kennyCalJunior: try a ref or atom
11:42fliebelWhy would you need that?
11:42ohpauleezfliebel's answer is the one to go with
11:42ohpauleezyou really should ONLY do that if you have to
11:42CalJuniorI only need to do it once at program start-up.
11:43chouserthen why not (def map1 (struct foo 1)) ?
11:43ohpauleezmaybe you just need to define one (def ...) that you need.
11:43the-kennyalter-var-root is propably what you want.. or (def) it with the right value
11:43CalJuniorI need to map 'identities' to their place in a vector.
11:44CalJuniorrather their index in vector.
11:45the-kenny,(hash-map (zipmap [:foo :bar :baz] (iterate inc 0))
11:45clojurebotEOF while reading
11:45the-kenny,(hash-map (zipmap [:foo :bar :baz] (iterate inc 0)))
11:45clojurebotjava.lang.IllegalArgumentException: No value supplied for key: {:baz 2, :bar 1, :foo 0}
11:46the-kenny(zipmap [:foo :bar :baz] (iterate inc 0))
11:46the-kenny,(zipmap [:foo :bar :baz] (iterate inc 0))
11:46clojurebot{:baz 2, :bar 1, :foo 0}
11:48the-kennyuhh switch the arguments of zipmap
11:49CalJuniorthanks the-kenny, but I'll try the atom idea first.
11:49the-kennyCalJunior: An atom slow compared to a simple "def"
11:50the-kennytoo much overhead
11:50CalJuniorspeed is not a issue in this case
11:50the-kennyIt also isn't the "Clojure Way" ;)
11:50CalJuniorI thought atoms were quite zippy though.
11:51chouserusing an atom except to coordinate multiple threads is best avoided.
11:51hiredmanthe-kenny: what would you know about it?
11:51hiredmanalter-var-root is certainly not to be recommended
11:52the-kennyhiredman: I think that isn't a good problem for an atom. It looks like he doesn't really need mutable state here, as he only wants to do something while initializing the program
11:52CalJuniorI timed the atom on a vector at 0.025 ms.
11:52chouserCalJunior: if you could more completely describe your input and desired output, we can probably give better advice.
11:53the-kennyhiredman: I'm absolutely not the haskell type (wtf, please, no state anywhere), but I think it should be avoided where it doesn't needs to be
11:54CalJuniorchouser: I def a maps of values for a number of symbols.
11:54CalJuniormost of these values a fixed and don't change ever.
11:55chouserit seems unlikely to me that any reference type needs to be updated.
11:55CalJuniorhowever, one of them is set at the start-up of the program (daily).
11:55chouserCalJunior: "maps of values" still doesn't tell me much. Perhaps an example?
11:55the-kennyCalJunior: So you want to update a value later in the program?
11:55CalJunioryes.
11:55the-kennyOh sorry
11:56the-kennyI misunderstand you.. an atom is the best way for this, of course.
11:56the-kennyMaybe a ref, if there needs to be some coordination etc. while setting from different threads
11:56hiredmanCalJunior: is there a reason you can't just do (def map’ {:a 1 :b 2 :c (init-stuff-here)})
11:58CalJuniorI think the atom is the obvious solution. So I'll let it rest.
11:59CalJuniorchouser: love the book. as you can tell: I need it.
11:59jcromartieWould it make sense to use an agent with a nil value to handle saving data to disk?
11:59jcromartieI
11:59DeusExPikachuwhat is a fixnum and what is its purpose?
12:00jcromartieOr should the agent represent the data being saved?
12:00Chousukejcromartie: I think it's okay to have a "serializing agent"
12:00chouserjcromartie: nil is probably fine. I've sometimes put the filehandle in there, but you have to be careful to always return it from your action functions
12:00Chousukeso that you can just do (send someagent write-to-disk whatever)
12:01chouserCalJunior: glad you like it.
12:01chouserCalJunior: thanks from fogus as well. :-)
12:02chouserDeusExPikachu: I think that usually refers to an efficient way to store numbers that know their own type, that's not supported by the JVM yet.
12:02CalJuniorfogus: love your book too :-)
12:03hiredmanif have the agent hold the data to be saved you can use a watch to write
12:03jcromartiehiredman: that's a good idea
12:03Chousukehiredman: hmm, what if the data changes while the watcher is writing it?
12:03jcromartieso I send things like conj or assoc or dissoc
12:03jcromartiebut the writes have to be in order
12:04hiredman,(doc add-watch)
12:04clojurebot"([reference key fn]); Experimental. Adds a watch function to an agent/atom/var/ref reference. The watch fn must be a fn of 4 args: a key, the reference, its old-state, its new-state. Whenever the reference's state might have been changed, any registered watches will have their functions called. The watch fn will be called synchronously, on the agent's thread if an agent, before any pending sends if agent or ref. Note tha
12:04chouser"The watch fn will be called synchronously"
12:04jcromartieok
12:04jcromartiegreat!
12:05jcromartienow... is this so "experimental" that I shouldn't use it for production code?
12:05jcromartieotherwise I can just use a serializing agent
12:05jcromartieand call it a day
12:05jcromartiesend-off would do the trick
12:05chouserjcromartie: that usually has more to do with the chances of the api changing than the code breaking.
12:06jcromartieI see
12:07DeusExPikachuchouser, thanks, now the jvm talk makes sense
12:09chouserDeusExPikachu: sure. the details are interesting too, if you're into that kind of thing.
12:10DeusExPikachuchouser, I'm watching "Fast Bytecodes for Funny Languages" and Cliff is talking about why clojure is close speed to java, and what it needs to do to close the gap
12:10chouserah, yep. fixnums would be great for clojure.
12:10chousermeanwhile, rhickey's doing what he can to work around the problem. :-)
12:19DeusExPikachuchouser, I dont' know if you've watched the talk, but do you know if Escape Analysis is typically performed at the JIT level, or the clojure compiler level?
12:20chouserThe Clojure compiler doesn't do much optimization at all. Post-1.1 it's now doing some fine-grained locals clearing, but any escape analysis is being done by the JVM.
12:21chouserHm, I guess Clojure's also now doing some clever things with method caching at call sites, and some explicit (macro-style) inlining.
12:22hiredmanthat would be for deftype and protocols?
12:23chouserhiredman: yes, where (:foo bar) can be as fast as a direct field lookup, like a type-hinted (.foo bar)
12:23chouserI think that's the only place the call-site caching is done, but I may have forgotten something.
12:24hiredmando protocol fn call sites do some caching?
12:24chouserhm, perhaps that too. I haven't tried to read the implementation for any of that yet.
12:27sethscemerick: hey, email me if you are unhappy with http://bitbucket.org/seths/pokerepl/src/39b5efb4e905/src/com/muckandbrass/interpolate.clj
12:33tayssirHi! I'm trying to search for the reasoning why add-classpath's deprecated... any pointers? (To get add-classpath's dynamicity, am I supposed to unzip the .jar into my classpath or something?)
12:37hiredmanadd-classpath was only ever supposed to be used in a very limited set of circumstances, since the visibility (scope) of classes loaded that way cannot be guaranteed
12:38tmountainis there a way to write this with the arrow operator? (get (get x "foo") "bar")
12:38tmountainor some better way to write it?
12:38hiredmanit's deprecated generally because people were unable to keep themselves from using it only for experimental repl sessions
12:38hiredman(-> x (get "foo") (get "bar"))
12:39tmountainthanks hiredman
12:39hiredmanthe real solution appears to be a custom classloader as the system classloader durring developement
12:40hiredmanbut this has yet to be codified
12:40hiredman(honestly it's a fairly simple bit of code, so it should be)
12:40Chousukeisn't there a get-in as well?
12:41hiredman(doc get-in)
12:41clojurebot"([m ks]); returns the value in a nested associative structure, where ks is a sequence of keys"
12:41hiredmanYes
12:41tmountainahh, that's what I was looking for
12:41tmountainI was browsing clojure categorized... I see it's under structs rather than maps on there
12:42tayssirhiredman: Ah, cool, thanks.
12:45lypanovgen-in is cute
12:46Chousukeupdate-in and assoc-in are also neat :)
12:46Norrithi, I am looking for some kind of "flat" operation, is there something available?
12:46ChousukeNorrit: flatten? clojure.contrib.seq-utils
12:46Norritah .. thx :-)
12:47Chousukecontrib contains a lot of stuff
12:47konr`is it safe to assume that a randomly generated string does not occur in a file?
12:48the-kenny,(doc gen-in)
12:48clojurebotIt's greek to me.
12:48the-kennyOh, get-in?
12:48Chousukekonr`: depends how good your PRNG is :P
12:49Chousukealso on the length of the string :)
12:49hiredmankonr`: no
12:49hiredmana file is random collection of strings
12:49Chousukemmh
12:49Chousukemost often not random
12:50Chousukebut still, nothing would prevent anyone from looking up one of your randomly generated strings and putting it in a file.
12:50lypanovthe-kenny: aye, sorry. fingers are tired :D
12:50hiredmanChousuke: unless you know the contents of the file, it is random
12:50the-kennylypanov: I was just asking because I never heard of gen-in
12:51lypanovmaybe i should invent it
12:51Chousukekonr`: What are you you trying to accomplish?
12:51hiredmanbut unless you have actually checked to see if a random string exists in a file, it is not safe to assume it isn't in the file
12:51lypanovman this parleys thing uses a ton of cpu.. wonder where the vids are
12:51Chousukehiredman: the contents of the system files on my hard disk are definitely not random, though I don't know it :)
12:52ChousukeI guess the issue here is about probability
12:52ChousukeI mean, it's not safe to assume that a hash does not collide with anything in the future
12:53Chousukeby your logic.
12:53konr`Chousuke: I want to generate a Boundary string to a multipart POST request, and I'm a little confused. In Drakma's source code, the string is random, but here: http://www.ietf.org/rfc/rfc2388.txt it says that the string should not appear on the content
12:53konr`Chousuke: drakma, the CL equivalent
12:53Chousukekonr`: generate a UUID or something
12:53Chousukekonr`: those are designed not to collide with each other :P
12:54Chousukeor you could hash the content that you're separating
12:54Chousukethen use /hash/
12:54Chousukeor whatever
12:56ChousukeIt's rather unlikely that any good hash function would generate output A from content that contains A :P
13:05ohpauleezkonr`: you want to use HtmlUnit and interop + enlive
13:05ohpauleezthat's what I've been doing
13:09konr`ohpauleez: "GUI-Less browser for Java programs" - hmmm, I didn't knew about this one
13:09konr`I'm going to try it out, thanks guys!
13:10ohpauleeztotally welcome, I've been working on ripping parts of htmlunit out, and wrapping it a more functional way
13:11hiredmanhtmlunit is pretty nice
13:11ohpauleezagreed
13:12the-kennyhttp://kvardek-du.kerno.org/2010/01/how-common-lisp-programmer-views-users.html Clojure is Picard as a Borg :/
13:14wiligtechnomancy: did you have a chance to look at clojure/repl? I tried the simple approach but didn't get far.
13:15vu3rddI am trying to write an insertion sort routine.
13:15vu3rddas a first step, I created an insert routine, which takes an integer and a sorted sequence as parameters.
13:16vu3rddit works except when the number to be inserted in greater than all the elements in the list.
13:16vu3rddThe code is here: can someone help find the problem?
13:16vu3rddhttp://paste.lisp.org/+2099
13:17cemerickGood for a laugh, if folks haven't seen it yet: http://kvardek-du.kerno.org/2010/01/how-common-lisp-programmer-views-users.html
13:17hiredmanvu3rdd: first (seq key) is most likely not what you want
13:18hiredmanfor the empty case
13:18hiredman(seq [key]) or (list key)
13:19hiredmaninfact
13:19vu3rddok
13:19hiredmanthat might be the actually problem, since it is the base case
13:19hiredmanso do that and try again
13:20vu3rddhiredman: thanks. yes indeed.
13:20vu3rddI was struggling with it for a long time today! :-(
13:21hiredmanseq is not like list or vector
13:21hiredmanseq returns a seq on a collection, it doesn't create a collection
13:22vu3rddok.
13:22vu3rddso, any collection can be converted to sequences and can be thought of as a logical representation of any collection? is that a fair statement?
13:25tmountainanyone know any existing libs for downloading binary data using something like InputStream and OutputStream?
13:26Chousukevu3rdd: seqs are logical views to a collection, yes.
13:27vu3rddChousuke: thanks
13:28Chousukevu3rdd: seqs are also persistent, ie. once you have realised (accessed) a part of a seq, that part is immutable. this means weird things can happen if you make a seq on a mutable array and then modify the array afterwards
13:30vu3rddChousuke: thanks. But aren't vectors, maps and lists also persistent? I guess by Arrays, you mean the Java Arrays?
13:30Chousukeyes
13:31Chousuke,(let [a (into-array [1 2 3 4 5]) s (seq a)] (println (first s) ".") (aset a 0 42) (println (first s) ".") (println (aget a 0) "."))))
13:31clojurebot1 . 42 . 42 .
13:31Chousukehmm.
13:32ChousukeI guess not cached in that case :/
13:32chouserI think lazy seqs cache, not all seqs.
13:32vu3rddok
13:32Chousukechouser: might be.
13:33Chousuke,(let [a (into-array [1 2 3 4 5]) s (doall (seq a))] (println (first s) ".") (aset a 0 42) (println (first s) ".") (println (aget a 0) "."))))
13:33clojurebot1 . 42 . 42 .
13:45hiredman
13:46jkdufairAnyone played with Alice? I see it's Java. Might be fun to bolt clojure on top of it somehow.
13:46LauJensenGuys - I had a thought earlier. Previously when there's been a challenge like prime-finding, Lucas-Lehmann, Hamming numbers etc, I've joyfully used lazy-seqs to get the data I want. Now with chunked-seqs do I still dare? I imagine that with Mersenne Primes for instance the computations run for 8+ hours once you get beyond the 10.th number or so, so wont a seq representation effecually be impossible because the CPU will burn out trying to get the
13:47chouserLauJensen: you may need to be careful, yes. But many seqs are still not chunked.
13:47LauJensenmany?
13:47chousermany
13:47hiredmananything using range is chunked
13:48LauJensenhehe
13:48chouseranything you build manually using lazy-seq and cons is not chunked
13:48LauJensenAah ok
13:48LauJensenThats good news
13:48chouseranything using iterate is not chunked.
13:48LauJensenPreferably it would just be made explicit somehow if you want chunks or lazy seeing they're 2 different things
13:49chouserany of the seq library functions that consumes a non-chunked seq, produces a non-chunked seq.
13:49Chousukeit is kind of explicit right now.
13:49Chousukethere's just no function to convert from a chunked seq to a non-chunked one
13:49chouserwe could use a seq1 fn. Not sure why we don't have one yet.
13:49LauJensenYou dont me literally seq1 ?
13:50Chousukeseq1 is not a bad name. :)
13:50chouseryes, a seq1 that accepts a collection (or chunked seq) and returns a guaranteed non-chunked seq
13:50rhickeyhttp://paste.lisp.org/display/90536
13:50ChousukeI wonder if you can guarantee that for nested chunked seqs though? :/
13:50rhickeyjust a rough draft
13:51chouseriterate, for example, could potentially be faster producing a chunked seq, but if there were code written relying on it being non-chunked, that could be considered a breaking change. :-/
13:52chouserif we had an idiomatic seq1, then seq-returning things in generally could be considered potentially chunked, and code that *needed* non-chunked would explicitly use seq1
13:53hiredmanbleh
13:54chouserconsidering how little complaints we've heard about chunked seqs, I would imagine use of seq1 would be pretty rare.
13:54ChousukeI think it would serve as documentation too
13:54chouseryes
13:55hiredmanbleh
13:55Chousukehiredman: do you have a better solution?
13:55chouserhiredman: do you have an alternative you'd like to propose? :-)
13:55chouserheh
13:55Chousukeor should we call seq1 "bleh"?
13:56hiredmanI like it when map, filter, etc were lazy
13:56hiredmanliked
13:56chouseryou would prefer to not have chunked seqs at all?
13:56technomancywilig: not yet unfortunately
13:57hiredmanI have to run catch a bus, but I would prefere explicit chunking to explicit seq-1
13:57Chousukethe non-chunkedness will propagate though won't it?
13:57technomancywilig: I ordered a nexus one and have been distracted by the android emulator. =)
13:59Chousukeso if you have (map ... (filter ... (map expensive-op (generate-chunked-seq)))) then you should be able to make the whole thing non-chunked by just wrapping the map operation in seq1
13:59chouserthe inner map, yes
14:00chouserwell
14:00chouserno
14:00chouser(seq1 (generate-chunked-seq))
14:00chouser,(first (map prn (range 10)))
14:00clojurebot0 1 2 3 4 5 6 7 8 9
14:01Chousukehiredman: I think having seq1 as the non-default op makes sense, because otherwise you'd need a lot of ceremony just to get the performance benefits.
14:02Chousukehiredman: and in the vast majority of cases it makes no difference whether a seq is chunked or not
14:02Chousukeexcept that the chunked seq is faster, of course
14:04Chousukebut I guess if chunked seqs ever turn out to have been a *really* bad idea, the whole mechanism can just be removed :/
14:08hiredmanwell, the bus drove away while I was running along side it yelling and pounding on the side of the bus trying to get the driver's attention
14:08chouser:-(
14:08chouserwait -- is that a metaphore for chunked seqs?
14:08hiredmancould be
14:09Chousukeheh
14:09Chousukeyou just need to make a convincing enough case against chunked seqs
14:10hiredmanI like lazy seqs
14:10Chousukeyes, and chunked seqs are still lazy.
14:10Chousukeonly less lazy than before.
14:10wiligtechnomancy: excellent. enjoy. I'm tempted to finally succumb to the smart phone itch. It's not the price of the phone that gets me, it's the recurring costs.
14:10hiredmanyes, and less is less
14:10Chousukeand if (when) seq1 is introduced, you have an explicit way of getting back to the old semantics
14:11Chousukeso what is there not to like?
14:11Chousukethat you might need to wrap some seqs in seq1 sometimes? :/
14:13hiredmanchunked sequences basically go back on http://groups.google.com/group/clojure/browse_thread/thread/88d9fdb5bcad36a , so nil punning is gone for nothing
14:14lisppaste8fogus pasted "seq1 -- for my version of clojure" at http://paste.lisp.org/display/93650
14:15Chousukehiredman: except seq1 rectifies that too
14:16LauJensenI prefer the speed that the chunks come with, so thats a good default, but it does change the way you can think about seqs a little bit
14:16Chousukehiredman: and lazy sequences are still there. chunked sequences are just another, less lazy type of seq :P
14:16rhickeyhiredman: no, they don't, as a chunked seq does nothing until something is asked for. When asked, it does more. And given some seq1-style source for seqs, it will be exactly as before
14:17rhickeyhiredman: but you haven't proposed an alternative. Explicit chunks, linke chunk-map, chunk-filter etc? 2 versions of everything?
14:18rhickeyonce a seq is single, existing fns will process one-at-a-time
14:19rhickeyor a (chunked-seq x) to start the chunked chain?
14:19technomancywilig: yeah, with Google voice being able to fall back to wifi for calls means 95% of my voice usage will be free
14:20rhickeyjust saying bleh doesn't move the dialogue forward, and people want the perf benefits. As is now obvious, people aren't suffering much from the theoretical problem
14:21slavait just occurred to me that inserting usage of transients is something the compiler could do, at least in simple cases
14:22Chousukeslava: possibly, but that would be complicated
14:22slavaalso, what happened to 'persistent data structures are fast enough for everything' :-)
14:22Chousukeslava: even for simple cases :)
14:22stuartsierraslava: the core functions, like "into", already do.
14:22Chousukeslava: was that ever claimed?
14:23technomancy"everything" is a tricky term. =)
14:24ChousukeClojure is developed kind of incrementally.
14:25Chousuketransients are just one new tool in the box :P
14:25technomancyslava: nobody wants to work on the compiler right now since it's going away with self-hosting around the corner. but it's certainly an interesting idea.
14:25angermantechnomancy: is that look and feel issue going into lein soon?
14:25technomancyangerman: are you getting it on the latest version? or is it just a problem with the release?
14:26angermantechnomancy: using the latest release, lein pulles on self-install (from yesterday)
14:26technomancyangerman: oh, I thought that had been fixed
14:26technomancyangerman: unfortunately it only manifests on OS X, so all I can do is accept patches
14:27slavatransients are an interesting optimization. its not safe if you have multi-shot continuations
14:27angermanyes, I had it hand compiled for me. but then lein from the checkout was screweing with the classpath too much, so i cleared all of lein I had and pulled the version from the net.
14:28ChousukeI somehow doubt that Clojure will ever gain features that break transients (might deprecate some usage patterns) but amusingly enough it should be easy to remove them, too.
14:29Chousukejust make persistent! and transient no-ops and maps the ! ops to regular assoc etc. :P
14:32angermantechnomancy: lein swank still crashes. Let's see if i find the patch that fixed it for me the last time
14:32patrkrishey... i'm looking for a quote that says something along the lines of "object-oriented design patterns were made to solve the deficiencies of OOP"
14:32patrkrisfor some reason, I think it might have been rhickey who said it
14:33patrkrisor maybe he was quoting someone else
14:40angermantechnomancy: I'm sure it was this patch: http://github.com/swannodette/leiningen/commit/9d79d631a9faa870a9347992f50a4312170fdf97
14:41woobyangerman: is the OS X bug mentioned in the commit msg the OS X java runtime stuff not being on classpath?
14:42angermanwooby: that might be the case. It only happens with lein swank though
14:42technomancyangerman: right, that slows every execution down for everyone
14:42technomancyeveryone else shouldn't have to be affected by a workaround for an OS X bug
14:42angermantechnomancy: hmm ok, didn't know it caused slow down
14:45Rayneshttp://www.reddit.com/r/programming/comments/artiq/clojure_11_12_and_beyond_what_is_clojure_in/c0j3c8e :>
14:46woobymaybe lein swank could just sniff if OS X and include JavaRuntime.jar in -extra-classpath if necessary
14:46woobyi'll take a stab at it
14:51angermanwooby: (defn osx? [] (= (System/getProperty "os.name") "Mac OS X"))
14:51angermanwooby: if that helps :D
14:51woobyangerman: there 'tis :)
14:52Raynes,(System/getProperty "os.name")
14:52clojurebotjava.security.AccessControlException: access denied (java.util.PropertyPermission os.name read)
14:52Raynes:<
14:52jasapp_I was about to try the samething
15:07ts00000so, is technomancy's clojure-http-client the canonical way to do REST-type stuff these days?
15:08ts00000e.g. http post.
15:10the-kennyOkay.. how do I merge two (or more) lists: (f [1 3] [2 4]) -> [1 2 3 4]
15:10somnium`concat
15:10chouserthose are vectors
15:10chouseryou want to keep them in order?
15:10chousersorted order, I mean?
15:11the-kennychouser: Yes
15:11chouserand you promise the input seqs are already in order?
15:12the-kennyI get one from a [& foo
15:12the-kenny] function argument
15:12chouserif they're not already sorted, I don't think you can do better than (sort (concat c1 c2))
15:13woobyinterleave would work, at least in that case
15:14the-kennyI think I'll stick to (seq (zipmap ...)), the order of the interleaved pairs isn't very important, just that they're pairs
15:15chouserI don't see how that's at all similar, but if you've got something that works, then great.
15:17the-kennychouser: (fun ['foo 'bar] [:foo :bar]) should return either [foo :foo bar :bar] or [bar :bar foo :foo
15:17the-kenny+]
15:23ohpauleezthe-kenny: that's different from the orginal goal, in that case, zipping is what you want to do
15:27chouser,(interleave ['foo 'bar] [:foo :bar]) ; ?
15:27clojurebot(foo :foo bar :bar)
15:28chouserzipmap returns a map collection, not a vector or sequence.
15:28ohpauleezright
15:29ohpauleezand I suppose if you really wanted a vector, just toss a into [] in front of the interleave
15:29chouseryes, or 'vec' :-)
15:29ohpauleezthat would work too :)
15:38CalJuniorI have: (def foo { :bar ( atom { } ) } )
15:38CalJuniorhow do I swap the atom?
15:39CalJuniorfor example to 1
15:39chouser(update-in foo [:bar] swap! assoc :a 1)
15:39chouserhm.
15:39chouserno
15:40CalJuniorreturns {:a 1}
15:40CalJuniorI would like it to return 1
15:40chouser(swap! (:bar foo) assoc :a 1)
15:44CalJuniorchouser: thanks
15:45CalJuniorI guess I have to change the atom from a map to a vector to just get 1
15:45chouseran atom can hold a single number instead of a collection if you'd like
15:46CalJuniorthat's what I would like
15:46chouser,(let [a (atom nil)] (reset! a 1) a)
15:46clojurebot#<Atom@192caa9: 1>
15:48chouserI continue to doubt that an atom is the best solution for you
15:49CalJuniorI know what you mean.
15:49CalJunior(atom nil) was the key for me here.
15:49CalJuniorworks
15:50CalJuniorI'll try to find a different solution later.
15:53wiligtechnomancy: New version of swank-clojure pushed to github. This one proxies LineNumberingPushbackReader. It's a small step on the path toward clojure.main/repl
16:07ts00000there is no deliberate slowdown
16:08ts00000wrong chan
16:13ts00000doesn't swank-clojure-project autoload everything in ~/project/lib?
16:13ts00000in terms of classpath?
16:23stuartsierraHey Maven fans (& not). I'm working on a Maven-based build for contrib.
16:25lpetitcool
16:26stuartsierraIt's SO much simpler than the Ant build.
16:27chouserwhy's that?
16:28stuartsierraNo test script needed, far fewer exclusions needed when compiling, no need to manually define how to find/compile .clj sources, ...
16:30stuartsierraBasically, all the complexity of the Ant script is moved to the Maven plugin.
16:30chouserah
16:31stuartsierraAnd the plugin is published in the central repository, so we don't need to distribute it.
16:34stuartsierraCheck it out: http://github.com/richhickey/clojure-contrib/tree/maven
16:37stuartsierraNo need to specify where to find clojure.jar on the command line...
16:38zakwilsonI just set up a new machine with a new install of swank-clojure and an old .emacs file. It's saying java.lang.NoClassDefFoundError: clojure/main
16:39zakwilsonand swank-clojure-jar-path is set to a real working clojure.jar
16:39lpetitstuart, are you a new convert, or did you know/use maven for a long time ?
16:40stuartsierralpetit: I've been advocating Maven for Clojure projects for a while now. I wrote several blog articles on the subject.
16:40lpetitok, was just wondering :-)
16:41stuartsierrahttp://stuartsierra.com/tag/maven
16:41lpetit I'm currently starting a project with GWT. Was wondering whether I would use ant or maven for it, just today :-). But I would really have loved being able to work with clojure full stack with GWT :-(
16:42chouserI think Clojure is less compatible with GWT than it is with C++ libs
16:43jcromartieouch
16:43stuartsierraGWT is a Java source compiler, not much to be done about that.
16:43chouser*and* GWT can't compile Clojure's java sources
16:43chouseror couldn't last I tried, anyway.
16:43lpetitguessed so :'(
16:44chouserthe only hope would be after cinc to write a java-source backend specifically designed to stay compatible with GWT requirements.
16:46lpetityes. Some guys also reused the java->js compilation mechanism to extend it to their own classes. Depends on the size of the stuff to do, as always (e.g. a guy created QWT, qooxdoo widget toolkit, based on the google's compiler, AFAIK)
16:51ts00000this is really bizarre
16:51ts00000swank-clojure-project isn't adding my ~/project/lib to classpath
17:06heowJust fired up the latest NetBeans and Enclojure, getting an NPE when creating a new project. is this a known problem?
17:11heowAnybody use the [theoricicly user-friendly] NetBeans?
17:13lpetitI've just read interesting things about zippers, and will tend to become a zipper fan very quickly. So ... before I over abuse the tool, what are the limitations of zippers I don't see right now ? Where should they be avoided, for instance ? If not theoretically, at least given the current implementation in clojure.zip ...
17:14technomancyts00000: it should add all the jars in $PROJECT_ROOT/lib to the classpath
17:14dabdhow the see the value of classpath from a project REPL in netbeans 6.8?
17:14chouserzippers are pretty amazing, but they're not amazingly fast, and the way I used them in zip-filter turned out to be unexpectedly limiting.
17:14stuartsierraSimplifying contrib build with Maven: http://groups.google.com/group/clojure-dev/browse_thread/thread/cd807a1e5d7ce77d
17:17lpetitI thing I'll use them with the parsetree of the code of paredit.clj, to go to the node corresponding to the caret, and then from it find the parent, the previous siblings, etc. A limited number of operations, mostly navigational
17:17heowdabd: Oh hey, yeah the REPL's sig changed in 1.1. Bet that's it, thanks!
17:19lpetitBut I'm currently "reinventing the wheel" in the parser code. I browse the code from first to last char, creating events as I go: entering a () , entering spaces, quitting spaces, entering an atom, quitting an atom, etc. So I keep a stack of the parents, and when I quit node, I "close" the node with the info I've gathered on it so far, peek the parent from the stack, update it with the...
17:19lpetit..."closed" node by adding it as last child, and replace the parent on the stack.
17:20dabdheow: I'm still running clojure 1.0 with netbeans (because I cannot get 1.1 to work with the latest enclojure). I'm puzzled by this. It thought starting a proj REPL would take care of setting the classpath correctly
17:20lpetitSo, basically, I guess I've reinvented a specialized version of a zipper with a limited subset of operations on it, and without the need to maintain an "after focus point context", just a "before focus point" context
17:21lpetitBut I'm pretty sure my solution is efficient since I can see no superfluous (no non-essential) task in it.
17:22jasapp_say I've got my.ns.foo, and my.ns.bar, which have similar functions, but are different internally
17:22lpetitBut the question remains : will I also use zippers for the construction phase, or will I suffer a penalty I can't afford ?
17:22jasapp_and I want my other code to be able to switch back and forth between them, interface-like
17:22jasapp_what's the best way to do that?
17:22ts00000technomancy: if it's not, where should I start to debug?
17:22lpetitchouser: what do you thing about it ? (and please don't tell me it will be in chapter xX of joc :-) )
17:23chouserlpetit: hehe
17:23ts00000technomancy: if it's in ~/.swank-clojure it's fine, if it's in the lib directory it doesn't work
17:23chouserlpetit: I'm afraid I don't grasp your whole context sufficiently to say. You're talking about parsing a stream of bytes into some kind of tree?
17:23ts00000chouser: is there a way I can play with require without redeclaring my entire ns? I tried (require 'clojure.contrib.zip-filter) which works, but I can't seem to access any of the xml-> things
17:24technomancyts00000: check the elisp value of swank-clojure-classpath with C-h v
17:24ts00000technomancy: I did that, it's not there
17:24ts00000technomancy: but it's definitely in my lib directory
17:25stuartsierrats00000: require does not 'refer' symbols into the current namespace
17:25ts00000stuartsierra: but shouldn't I be able to do (clojure.contrib.zip-filter/func ...) ?
17:25technomancyts00000: I've never heard of that failing on a project that's laid out according to the directions in the swank-clojure-readme
17:25stuartsierrats000000: yes, you should
17:25stuartsierraIn that case the problem is somewhere else.
17:26ts00000technomancy: http://pastie.org/787307
17:26lpetitchouser: I'm the 100tiest guy to rewrite a clojure source code parser manually. For my purpose I'm just interested in a parsetree of the clojure code, and for the moment not interested in anything else than structural nodes (parens, square brackets, round brackets, strings, regexps, comments) and just 3 kinds of atoms: literal chars, spaces and the rest
17:26ts00000technomancy: did I miss something?
17:27lpetitchouser: this should give you ideas of the size and depth of my tree. clojure/core.clj is used for tests, since I see it representing an upper limit :-)
17:27technomancyts00000: when you do M-x swank-clojure-project, you input the directory containing lib/ ?
17:27ts00000technomancy: yessir
17:27chouserlpetit: I think zippers will only be useful to you if you produce a tree of some kind from the parsing, and then keep it in memory while using the zipper api to navigate it.
17:28lpetitchouser: so too heavy for massive edit operations ?
17:28chouserlpetit: if I understood your description correctly, you're currently not holding the whole thing in memory, just keeping a stack representing your nested context?
17:28ts00000technomancy: SLIME 20091016, emacs 23.1.91.1, osx
17:29technomancyts00000: is that slime from elpa?
17:29ts00000technomancy: yes
17:29chouserlpetit: you'll have to determine that yourself, I'm just saying it has to be in memory, at least ... well ... hm.
17:30lpetitchouser: well, the core function is just interested in navigating the code beginning-to-end, keeping a stack of the parents of the current node, and call hof arguments that do whatever they want in the process (they are called for each character, and given the current stack, offset, line, column context)
17:30chouserlpetit: this is for paredit-like functionality?
17:30lpetiti'm currently implementing a version of the hof arg which will write the complete parsetree
17:31lpetitfor other simpler cases, i'll implement less heavy hof args to just peek what I want on the fly
17:31lpetitchouser: did I forget to mention that i also reinvented SAX in the process ? :-)
17:31chouserhm...
17:31ts00000technomancy: also, I seem to have to declare the (require 'clojure.http.resourcefully :as resourcefully) inside a namespace - is that normal, I assume so
17:31technomancyts00000: what do you get evaling this elisp? http://p.hagelb.org/classpath.html
17:31lpetitchouser: yes, it's my "paredit.clj" project
17:31chouserlpetit: you didn't use that word, but I guessed so.
17:31chouserlpetit: SAX, I mean.
17:32technomancyts00000: that's fine for resourcefully, though it's better to keep it inside the ns form with (:require [clojure.http.resourcefully :as resourcefully])
17:32chouserlpetit: so do you know where the cursor is and what kind of operation the user's trying to do?
17:33ts00000technomancy: i'm saying I can't seem to declare it outside the ns, e.g. in a repl. also, evaling your lisp gave the right classpath results, but for some reason it's like your function doesn't get called when I do swank-clojure-project
17:33ts00000if I just call it directly that doesn't show up in the classpath var
17:33lpetitchouser: sure. it's easy to go to the right node from the offset of the cursor by elimination, given that I currently store the offset and length of each node. I have no doubt concerning the navigational part : I'll user zippers. It's the creational part where I was pondering the overhead of using zippers.
17:34technomancyts00000: you could (setq swank-clojure-classpath [the code I pasted]) for now and use M-x slime instead of swank-clojure-project
17:34chouserlpetit: oh, once you've built a whole tree, making a zipper of it is very fast
17:34ts00000technomancy: yeah, I can edit the classpath manually so i'm not too concerned, just surprised it didn't work is all
17:34jcromartiea little bit off-topic, but what color-theme are you using in Emacs?
17:34technomancybut I can't reproduce your problem, so not much else I can do
17:35technomancyjcromartie: that would be zenburn
17:35technomancyit's not a built-in theme
17:35ts00000technomancy: is there a way to trace what's being done when I swank-clojure-project?
17:35technomancyts00000: you could add calls to message in the function
17:36technomancythe output goes to the *Messages* buffer
17:36technomancygiven the correct project root, the classpath seems to be calculated correctly
17:36lpetitchouser: FYI, I'm writing paredit.clj in an IDE agnostic way, purely clojure of course (and as idiomatic as I'm capable of, given that I've just sacrificed modularity over premature optimization in the main loop), and not just a port of paredit, but will be tailored for clojure (will know literal sets so that when selecting them you also have the leading sharp in the selection, etc.)
17:36jcromartieI have tried light-on-dark themes and it doesn't work well with OS X's LCD font smoothing. Light-on-dark ends up making the text heavier.
17:38ts00000technomancy: using trace-function, the path seems to be set correctly, but even when I fully qualify the path, the classpath only shows what's in ~/.swank-clojure
17:38chouserlpetit: I wonder if it would be faster and more robust in the face of incomplete code files to start at the cursor and word backwards/forwards just as much as needed to complete the user's operation
17:38ts00000technomancy: in fact, if ~/.swank-clojure is empty, nothing on the classpath at all.
17:38ts00000weird.
17:38technomancyts00000: oh, I realized it's done a little differently now. the swank-clojure-classpath elisp var is only modified inside a let binding
17:39technomancyso once the repl session is launched, it goes back to its root binding
17:39technomancyso try messaging it right before the call to (slime) at the end
17:40joeggIs there any plan to make the various clojure launcher scripts a part of clojure generally, or is it up to individuals and package maintainers to keep rewriting them? (I ask because I just found what I think is a bug in the macports clj script.)
17:40technomancyjoegg: sooner the better, but I don't know of any concrete efforts to do so unfortunately =\
17:41ts00000technomancy: what, just (message "%s" swank-clojure-classpath) or something?
17:41lpetitchouser: I've considered this possibility, and rejected it, for two reasons : I wanted to please myself by writing a parser manually, which I had never made before, and I hope that Christophe will quickly release a workable version of parsley, which, with its incremental parsing feature, will be unbeatable
17:42technomancysure
17:42chouserlpetit: ok. so building a tree that can be used by a zipper should cost essentially no more than building a tree.
17:42chouserlpetit: or are you asking about using the zipper api to build the tree itself?
17:43lpetitchouser: yes, asking about the added overhead of using the zipper api for building the tree (edit and al) too
17:46chouserlpetit: I think building using insert-left, insert-child, replace, etc. will only be a small constant factor slower than building a plain persistent tree
17:47ts00000technomancy: I have something interesting to report. inside your function, everything is declared normally
17:47ts00000technomancy: it's almost as if the classpath gets reset after slime
17:47chouserlpetit: so, not an unreasonable thing to try, I think.
17:47ts00000technomancy: path is correctly specified, and your code is correctly expanded
17:47lpetitchouser: ok, so worth considering a zipper as my state, will avoid me some boiler plate code. Will try this , thanks!
17:48chouserlpetit: sure, good luck.
17:48chouserhm. (seq-zip (read foo))
17:49technomancyts00000: yes, since the classpath is set inside a let form, the changes are localized to that function call
17:49technomancybut since elisp doesn't have lexical scope but dynamic only, the call to slime sees the new value.
17:50joeggtechnomancy: What would a standardized clj script require? Pretty much just writing one and asking someone to pull from a branch? Or, if you know, what has prevented this from already being done? This seems like something I could roll up my sleeves and do.
17:50joeggUnless there's massive problems that I'm just too ignorant to see. :)
17:50ts00000technomancy: ok, I see what you're saying, so how do I fix it so the command is useful again :-)
17:51ts00000technomancy: let me rephrase that
17:51technomancyjoegg: I think rich just hasn't made it a priority because he assumes everyone's going to get set up with Emacs or Netbeans or whatever.
17:51ts00000technomancy: I know how to fix it on my side, but how can I fix it so that rather than setting this manually on a per-project basis, it's dynamically set within swank-clojure-project and passed correctly
17:52technomancyts00000: well because of the way dynamic binding works, it *does* get passed correctly from swank-clojure-project's let binding into the call to slime
17:53ts00000oh, I see what you're saying
17:53ts00000you're saying slime does see the right classpath
17:53ts00000but it's cleared after i've entered slime
17:53ts00000so that when I look at the variable it's wrong
17:53technomancyyes, when you inspect it, you're outside of the let
17:54technomancywhich is a different scope from what slime was seeing
17:54ts00000ah, I got it
17:54ts00000well, this is the problem though
17:54ts00000the reason I investigated this in the first place was because I couldn't load clojure.http.client
17:54technomancyts00000: did you add the jar after launching the session?
17:54ts00000no
17:54ts00000:)
17:54ts00000but let me see if it works now
17:55ts00000wow, how fantastically convenient
17:55ts00000it's there
17:55ts00000:-)
17:56ts00000technomancy: now, you were saying that I should be able to require resourcefully inside a repl, with the :as but without the namespace, although of course the namespacing is the preferred way to do it, right?
17:57ts00000but the syntax for that doesn't seem to be (require 'clojure.http.resourcefully :as resourcefully) - what is the right syntax?
17:57technomancytry wrapping everything after "require" in []
17:58ts00000well, if I do it with the ', it says unable to resolve symbol resourcefully in this context, if I do it without the ', it can't find the class
17:59technomancyts00000: should be: (ns eveloci.core (:require [clojure.http.resourcefully :as resourcefully]))
17:59technomancyns is a macro, so you don't need to quote anything
18:00ts00000if I want to do it without changing the namespace, can that be done?
18:00ts00000like I just want to mess around with it in the repl.
18:00technomancyright, if you want to do it in the repl, you'll also need to quote the final resourcefully
18:00ts00000ah, ok
18:00ts00000that's what I was missing
18:00technomancyotherwise it treats it as a variable and tries to look up the value
18:00ts00000thanks so much :)
18:00technomancybut you want the symbol itself
18:00technomancynp
18:00hiredmanuh
18:00jcromartiewhat is this all about? http://gist.github.com/282385
18:00jcromartie[B ?
18:00hiredmanyou were missing the whole vector
18:01hiredman,(class (make-array Byte/TYPE 1))
18:01clojurebot[B
18:01lpetitchouser: yes, but has no story to handle incorrect input, and no story to handle comments, literal metadata, etc.
18:01hiredmanjcromartie: you need to call .getBytes on the string
18:01jcromartiehmm
18:02jcromartiepublic static byte[] decodeBase64(String base64String)
18:02jcromartieso what's the problem, the return value?
18:02hiredmanjcromartie: no idea
18:02jcromartie.getBytes works, by the way... I'm just confused as to why the String method doesn't
18:02hiredmanthe string method wasn't being called
18:03jcromartieyeah
18:03hiredmanpossibly you have an old version of the library without it
18:03hiredmanwhat library is that?
18:03jcromartieApache Commons Codec
18:03ts00000ah: and so when I try to access (clojure.contrib.zip-filter), I also have to use the symbol to get at the functions
18:03ts00000('clojure.contrib.zip-filter/xml-)
18:03ts00000right?
18:04hiredman,(import 'org.apache.commons.codec.binary.Base64
18:04clojurebotEOF while reading
18:05hiredman,(import 'org.apache.commons.codec.binary.Base64)
18:05clojurebotjava.lang.ClassNotFoundException: org.apache.commons.codec.binary.Base64
18:05hiredmanbah
18:05hiredman,(doc show)
18:05clojurebot"clojure.contrib.repl-utils/show;[[x] [x selector]]; With one arg prints all static and instance members of x or (class x). Each member is listed with a number which can be given as 'selector' to return the member object -- the REPL will print more details for that member. The selector also may be a string or regex, in which case only members whose names match 'selector' as a case-insensitive regex will be printed. Finall
18:08jcromartieooh
18:08jcromartiethat's awesome
18:12technomancyjcromartie: that's nothing... in slime use C-c S-i to pull up the inspector
18:12technomancyit's hyperlinked
18:12alexykhow do I access a static field of a class?
18:13alexykJava's
18:15ts00000is there any way to get at private documentation from the repl?
18:18joeggalexyk: (BigDecimal/ZERO)
18:19joeggIs that what you mean?
18:19alexykjoegg: yeah... for some reason I get an error, Unable to find static field, on a class which must have it
18:20alexykhow can I use reflection to see what's inside a class in repl?
18:20alexykit's a public static final int BLAH = 8
18:29joegg,(sequence (.getFields (class "")))
18:29clojurebot(#<Field public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER>)
18:29joeggalexky: That might help, I guess.
18:29joeggOops, sorry for typoing your handle.
18:30joeggYou can also just use the name of the class:
18:30joegg,(sequence (.getFields BigInteger))
18:30clojurebot(#<Field public static final java.math.BigInteger java.math.BigInteger.ZERO> #<Field public static final java.math.BigInteger java.math.BigInteger.ONE> #<Field public static final java.math.BigInteger java.math.BigInteger.TEN>)
18:30joeggIs that helping?
18:31joeggAlso, if someone knows a better way, please correct me, as I'm just a beginner.
18:32alexykwill try, thx!
18:35dabdI'm trying to pass java HashMap to a clojure function and I get the following error: java.lang.ClassCastException: java.util.HashMap cannot be cast to clojure.lang.IPersistentCollection
18:36dabdwhat type of Map should I pass to the Clojure function?
18:36arohnerdabd: try a PersistentMap
18:36dabdarohner: thx
18:36arohnerhrm, that might have been bad advice
18:37arohnercan you paste what you're trying to do?
18:39dabdarohner I'm trying this invoke(PersistentHashMap.create(map));
18:39dabdand map is a Java HashMap
18:39arohnerinvoke? are you calling from java?
18:39dabdthe invoked Clojure function excepts a Clojure Map
18:39dabdyes I am calling from Java
18:40dabdI am implementing a Web Service that uses Java API for RESTful WS and unfortunately since it relies on Java annotations I have to write some Java code, so I need to invoke Clojure from Java
18:41arohnerI know (into {} (seq map)) will work. Looking for a better way now
18:42jcromartiedabd: invoke takes a function, PersistentHashMap.create(map) returns a new PersistentHashMap
18:42jcromartieinvoke takes IFn
18:42jcromartieso your map is being cast to an IFn and called
18:43jcromartiethe equivalent clojure would be ((map m))
18:43hiredmanjcromartie: un
18:43hiredmaninvoke is a method on a fn
18:43jcromartiedur
18:43hiredmanit may or may not take a function
18:43jcromartiesorry
18:44arohnerdabd: I think the java equivalent of (into {} (seq your-map)) is your best bet
18:45dabdarohner: I think that Java equivalent might be PersistentHashMap.create(map) where map is a Java HashMap
18:45arohneroh yeah, I missed that
18:45arohneryeah, that looks better
18:47arohnercan you paste the whole of your invoke() line?
18:47dabdinvoke seems to accept a number of Java Objects which are the arguments to pass to the Clojure function
18:47hiredmancorrect
18:47dabdarohner: Object result = groupbytf.invoke(PersistentHashMap.create(map));
18:47dabdwhere groupbytf is a clojure.lang.Var
18:47hiredman~def c.l.PersistentHashMap
18:48hiredmanand you still get the exception?
18:49dabdno I'm past that. Now I have to debug the next error :-) thx
18:55raz__Does anyone know if the clojure compiler can be used to generate the AST or some other representation of clojure source code? I know there are classes like DefExpr or AssignmentExpr and so on but it looks like the compiler just keeps those to itself and does not expose the AST. I'd like to build a toy refactoring tool and a model of the source code would be very useful
19:00lypanovchouser: (and the other author) man joy of f'n rules.
19:01ctdeanYou could use a tool like jad to decompile the .class file that clojure generates
19:02lypanovctdean: i've heard that thats not a great way of trying to use gwt to go from clojure to js
19:02lypanovvarious complications mean it sounds like its easiest to take the ast and translate directly
19:03ctdeanlypanov: sounds like you know more about this than me already :)
19:04ctdeanI used jad when I was working on one of the Scheme to jvm compilers. It was a useful debugging tool, but that's all I ever used it for
19:06fiatmoney(println "hello clojurebot")
19:06raz__try with a comma before it
19:06raz__,(println "like this?")
19:07clojurebotlike this?
19:07fiatmoney,(println "hello clojurebot")
19:07clojurebothello clojurebot
19:07fiatmoneyah, cool, thanks
19:07raz__guess it pays of to read #clojure logs instead of learning for exams
19:07raz__off*
19:07lypanovhehe
19:21raz__lypanov: there seems to be a parser in the 'La Clojure' Intellij plugin. Check the parser namespace. It uses the apache 2 license. The repository is here: git://git.jetbrains.org/idea/clojure-plugin.git
20:05arohnerRaz_: why do you need a separate AST than (read)'ing source?
20:06chouserRaynes: you can indeed get at the analysis tree, which has richer semantic information than just what 'read' returns
20:07chousersorry, that was for Raz_
20:07chouseroh. actually, raz__, but he's gone
20:07Rayneschouser: It's okay. I understand. You love my name so much, you can't help but say it every chance you get. <3
20:17ts00000chouser: do you have any idea what 'Unable to resolve symbol: text in this context' might mean while using zip-filter?
20:17ts00000I have some xml with an attr of name, could it be getting hung up on that?
20:32chouserts00000: it probably means you're using the symbol 'text' someplace where it isn't defined
20:32chouserzip-filter.xml defines a fn named text I believe. are you :use'ing it?
20:38ts00000chouser: i figured out where I went wrong by directly qualifying it; but now if I have some random xml def'd that has a foo attr with a value of bar, and I try to xml-> thexmlvar :foo, the repl tells me a string can't be cast to an iobj
21:08ts00000 i'm really close to figuring this out. I have a function that returns a map (it comes from http.client). i'm trying to parse it but I think xml/parse isn't accepting the map because an illegalargumentexception is thrown. how do I get it into something parseable?
21:09hiredman
21:09hiredmanhave you read the docstring on xml/parse?
21:09hiredmandoes it say anything that would lead you to believe it takes a map?
21:11ts00000obviously not, but when I try to feed it a string, it does something I don't expect.
21:11ts00000like (xml/parse (str (:body-seq testfunc)))
21:11hiredman,(doc clojure.xml/parse)
21:11clojurebot"([s] [s startparse]); Parses and loads the source s, which can be a File, InputStream or String naming a URI. Returns a tree of the xml/element struct-map, which has the keys :tag, :attrs, and :content. and accessor fns tag, attrs, and content. Other parsers can be supplied by passing startparse, a fn taking a source and a ContentHandler and returning a parser"
21:11hiredman"or String naming a URI"
21:12ts00000ok, so can I somehow smash my already-retrieved stuff into an inputstream?
21:12hiredman.getBytes and java.io.ByteArrayInputstream
21:14ctdean,(doc with-in-str)
21:14clojurebot"([s & body]); Evaluates body in a context in which *in* is bound to a fresh StringReader initialized with the string s."
21:17Raynests00000: (ByteArrayInputStream. (.getBytes stuff "UTF-8"))
21:20hiredman#/. is like window 11, so escape+number key doesn't find it
21:20hiredmanerp, mischan
21:24ts00000i've got to be making this out to be far more complex than it should be :/
21:27ts00000in my map, the body of the returned xml is a sequence
21:31dabdis anyone able to inspect/watch values when debugging Clojure code with netbeans?
21:41alexykhow do you translate this into clojure: collection.find( query ).skip( 1000 ).limit( 100 ).toArray()
21:41alexykis it what .. are for?
21:42chousersure. or ->
21:42hiredman(-> collection filter drop take)
21:42chouser(-> collection (.find query) (.skip 1000) (.limit 100) .toArray)
21:43alexykand what .. would look like?
21:43chouser(.. collection (find query) (skip 1000) (limit 100) toArray)
21:43alexykhard to tell what's nicer
21:43chouserthat is, it suddenly becomes less clear if find is a method or a fn, and samke with skip and limit
21:44chouserand you can no longer include regular clojure fns in the pipeline.
21:45alexykoh, I need further trickery: if skip or limit parameters are nil, the whole skip or limit call must be avoided. How can I account for it?
21:45chouseryou want to just return nil then instead of doing the rest of the chain?
21:46alexykno -- find is always done; skip or limit should be simply skpped over if their arg is nil
21:46cemerickdabd: inspect, yes -- you can't set clojure watches though, AFAIK
21:46alexykteh final toArray is also always done
21:47chouserif their arg is nil instead of 1000?
21:47alexykyep
21:48alexykis it a use case for a macro?
21:50chouser(-> c (.find q) (#(if n (.skip % n) %)) ...)
21:50chouserick
21:50dabdcemerick: say u have a breakpoint on a Clojure line. How do you inspect a value?
21:50alexykyackety-yack
21:50alexykor yuckety-yuck
21:51cemerickdabd: open the 'variables' tab and dig around
21:52alexyknever wrote a macro; but perhaps one can be used for (#(if n (~method % n) %)) ?
21:52dabdcemerick: thx
21:53cemerickdabd: np -- FYI, make sure you have a tostring column in your variables table -- that should print out nicely-formatted representations of standard data structures, etc.
21:55dabdcemerick: thx for the tip!
21:55alexykchouser: makes sense? what would the macro look like?
21:56chouserhm.. yes, a macro might work there.
22:02alexykI'd appreciate a sample macro as an example
22:03alexykwould be a starting point!
22:04chouserwell, the recipe is: first write the output by hand
22:07alexykok
22:07ts00000any ideas where i'm going wrong? http://pastie.org/787642
22:08alexykchouser: to that's essentially (method coll n) or nil
22:09ts00000testfunc returns something like {:body-seq ("<?xml version='1.0' encoding='UTF-8'?>" "<name>xxx</name>")}
22:09ts00000but I can't seem to get at the text of <name>
22:10chouseralexyk: (let [a nil] (-> 5 ((fn [x] (if a (+ x a) x)))))
22:10alexykchouser: something like this? (defmacro methornil [coll method n] `(#(if ~n (~method ~coll ~n) ~coll)))
22:10alexykI
22:10alexyk'
22:10alexykve made it up
22:11alexykso it doesn't work yet :)
22:12chouserI don't think you can use #() in a macro expansion
22:13somnium`maybe smthing like (defmacro ?#&! [arg pred f] `(if ~pred (~f ~arg) ~arg))
22:13somnium`every time I use clojure.walk I seem to write something similar
22:14chouserwe're skipping a step. The next step is an example usage.
22:14somnium`my bad :)
22:14chouser:-)
22:14chouser(let [a nil] (-.
22:15chouser(let [a nil] (-> 5 (foo + a))) perhaps?
22:17chouserso, (defmacro foo [fnname & args] ...) right?
22:17alexykyep
22:18alexykwhich will then expand to the icky (#(if...)) thing
22:20chouserhm.. actually, looking at that example usage, I don't think it needs to be a macro at all
22:22alexykI want this form: (-> [1 2 3] (methornil take 2))
22:22alexykif 2 is not nil, take is applied to [1 2 3], otherwise the original is returned
22:22alexykmethornil is "method or nil"
22:22alexyka patented medication against macrophobia
22:23chouser(defn foo [x f a] (if a (f x a) x))
22:24alexykso no need for macros at all
22:24chouser:-)
22:24chousersorry
22:24alexykpity
22:24alexykmethornil expired
22:24chouser(let [a nil] (-> 5 (foo + a)) ;=> 5
22:24chouser(let [a 9] (-> 5 (foo + a))) ;=> 14
22:25alexykindeed
22:25alexykI'll call it methornil anyways :)
22:25chousersure
22:26alexykI stylistically prefer ->> to ->, is there any logic here to pick ->?
22:26alexykI can reorder methornil's arg order
22:26chouserheh. yep.
22:26chouseroops. I'm not writing.
22:27alexyk?
22:27chouserthe book
22:27alexykah
22:28somnium`alexyk: how about <-??->
22:28alexykwhat's that?
22:28somnium`(its shorter than methornil)
22:28alexykbut it's not medicinal-sounding
22:28alexyksomnium`: I've tried to pick up mongo-specifics in the separate chat, so you see that?
22:32ts00000wow, how counterintuitive, finally got it to work
22:33ts00000what a pain in the royal ass :/
22:37ts00000chouser: now I have one that should be very easy to answer: why doesn't the root tag need to be declared when you're accessing an attribute with zip-filter.xml? I can't even get at the root tag
22:37defnAsk your Dr. of Computer Science if Methoril is right for you.
22:38chouserthere's always one root, so you can just skip it
22:38ts00000what if there are attrs on the root I want to get at?
22:38ts00000e.g. <s3-api version="2"> ....body.... </s3-api>
22:38chouseroooh! hmph!
22:38ts00000this is one of the things that has been confusing me all night and just had the eureka moment
22:39ts00000by removing the root element all of a sudden all my blanks actually had data
22:39ts00000:)
22:44ts00000Error Message %ADJ-5-PARENT: Midchain parent maintenance for [chars] - [chars]
22:44ts00000Explanation A midchain adjacency failed to stack onto an output chain because a loop was detected. Traffic through the adjacency will be dropped until the adjacency is restacked. This condition is typically transient and is resolved by the control plane that drives the stacking. For example, if an IP tunnel destination resolves through the tunnel transiently this message will appear. The situation would be resolved either by learning the tunnel destination t
22:44ts00000sorry :/
22:44chouserts00000: oh, you can still pull attrs from the root element
22:44ts00000ts00000: how?
22:44chouserwhen you put a tag like :foo, it descends a level an looks for a tag there.
22:46ts00000chouser: in my case, i'm trying (xml-> blah :s3-api (attr :version)) - wrong way?
22:46ts00000s3-api is the root of the tree
22:47chouserjust drop the :s3-api
22:47chouseryou're already at the root of the tree
22:47ts00000ah!
22:48ts00000I got it now
22:48ts00000perfect
22:49ts00000thanks so much for being patient
22:49ts00000i think it does rescan and walk it after the timers are done
22:49alexyk,(letfn [(methornil [x f a] (if a (f x a) x))] (methornil [1 2 3] take 2))
22:49clojurebotjava.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number
22:50chousersure. I actually find zip-filter fragile to use as well. I'm not sure how to fix it though. :-/
22:50alexykwhy error?
22:50ts00000i don't think it needs to be fixed
22:50ts00000it's just the most rapid way to prototype what I want to do, when what I should be doing is going deeper with just parsing out the tree itself
22:51ts00000if I were to offer only one suggestion as a complete newbie coming to clojure, i'd say that in the absence of more error messages, there needs to be a more obvious way to trace and figure out why things are going wrong. the repl is great but it is unforgiving.
22:51chouseryeah, zip-filter just give you nils, and you're left flailing around
22:51ts00000let me rephrase that; slime+repl is great but unforgiving
22:51alexykts00000: I saved a defn into a file, load-file it, boom -- printStackStrace prints the actual file:line, not no-source-file:0 :)
22:51ts00000yes, there is a lot of flailing around in clojure I have noticed, it lets you do things that are not otherwise correct
22:52hiredmantree-map + filter works pretty well
22:52ts00000alexyk: the no-source-file:0 is actually helpful to me when determining what's going on int he repl versus the file
22:52alexykts00000: unless you pasted 25 lines
22:52chouseralexyk: your args to 'take' are backwards
22:52ts00000alexyk: but look at it this way, as a newcomer, your choices of IDEs are limited, and none of them are particularly helpful, and a great many newcomers are left choosing emacs, which is even more of an issue
22:52ts00000alexyk: good point
22:52alexykchouser: doh
22:53alexykts00000: newbies should stay away from IDEs
22:53alexykwasting time on Emacs unless you know it or some GUIs is silly... raw text editor and repl and forge ahead!
22:53ts00000yes, but developing without one, especially for someone new, is difficult :-)
22:53alexykmy take at least
22:53hiredmanhttp://github.com/hiredman/clojurebot/blob/master/src/hiredman/clojurebot/clojars.clj <-- clojurebot scraping for the recently on clojars notices
22:55alexykhiredman: how about capturing outcries "clojars search is broken" and forwarding it to the clojars-ers? :)
22:56hiredman*shrug*
22:57alexykchouser: is there a "flip" adatper on things like take?
22:57alexykadapter
22:58alexykso I'd have only one methornil and call it with (flip take) or something
22:58chouser#(foo %2 %1))
22:59alexykah
23:00chouser,(-> [a 5] (let a))
23:00clojurebot5
23:01arohnerchouser: that's a little crazy
23:03alexykwhat's (let a) ?
23:03arohneralexyk: (let a) doesn't work, but the macro turns that into (let [a 5] a)
23:05alexykdon't show it to the scala people :)
23:06arohneryeah
23:06arohner,(macroexpand '(-> [a 5] (let a))
23:06clojurebotEOF while reading
23:07arohner(macroexpand '(-> [a 5] (let a)))
23:07arohner,(macroexpand '(-> [a 5] (let a)))
23:07clojurebot(let* [a 5] a)
23:07chouser,((->> (+ a b) (fn [a b])) 4 5)
23:07clojurebot9
23:08arohnerok now you're scaring me
23:08arohner,(macroexpand '((->> (+ a b) (fn [a b])) 4 5))
23:08clojurebot((->> (+ a b) (fn [a b])) 4 5)
23:08chouser,(->> (inc a) (let [a 5]))
23:08clojurebot6
23:09chouseractually, it would be better to show this to nobody at all.
23:09chouser,(->> a (+ 5) (let [a 5]))
23:09clojurebot10
23:10joegg,(->> "Ooh, me too!" (println))
23:10clojurebotOoh, me too!
23:10joeggYAY!
23:10chouserif there's only one thing, you don't even need parens
23:11joeggAh, because of the "makes it a list" part...
23:11joeggSweet.
23:12arohnerI need a random arrow. Takes your form and stick the first argument in a random place in the list...
23:13arohnerwraps it in try catches, and tries again, until you make a form that doesn't throw an exception
23:13alexykarohner: or even into a random orifice of the programmer
23:14alexyk"an arrow of doom"
23:14ts00000where is the ->> better explained/documented?
23:14ts00000i've looked at the doc string and in programming clojure but that doesn't cover that very well
23:15chouserdo not look at the examples I was just giving.
23:15alexykchouser: too late
23:15chouserthey're a horrible abuse
23:15ts00000<- eyes covered
23:15chouserI apologize for even mentioning them
23:15ts00000i'm just curious, want to learn more
23:15chouserand then tweeting
23:15chouser,(->> (range 30) (filter even?) (drop 10))
23:16clojurebot(20 22 24 26 28)
23:16chouserthat's a better example
23:16chousereach form is inserted as the final argument of the next form
23:16chouserso the above is the same as (->> (filter even? (range 30)) (drop 10))
23:16alexykevery time a crooked ->> is used, a frog dies in the Amazon
23:16chouserwhich is the same as (drop 10 (filter even? (range 30)))
23:17ts00000why would you want to use that as opposed to the (drop 10 ...) ?
23:17chouserthis will be explored in detail in chapter 7
23:17chouser:-)
23:17ts00000of your new book?
23:18ts00000joy of closure meap?
23:18chouserts00000: it allows you to read it left-to-right, instead of inside-out. Can also help reduce nesting levels. Mostly a matter of taste.
23:18chouserts00000: yep. http://joyofclojure.com/
23:18ts00000it's on the list for this weekend actually :)
23:19chouserexcept the TOC there will be revised next time the MEAP is updated
23:19chouserthe version that's available now is undergoing major surgery by fogus's deft hand
23:20alexyksince clojure is lisp-2, function literals mean themselves, right? so I could call (methornil coll take 2). Now what if instead of take it's (methornil obj .method n) -- can I still invoke with literal method name .method?
23:20arohnerclojure is not a lisp-2
23:20alexyklisp-1 I meant
23:20alexykmy understanding of the first part of my own utterance is infirm
23:20alexykthat's the gist I gathered from the past here :)
23:21arohnerlisp-1 means that variables and functions live in the same namespace
23:21arohnerin lisp-2s, you can have a variable foo, and a function foo, and they don't step on each other
23:21alexykright; does it affect the fact that you can supply a function as a parameter by just writing its name?
23:21arohneryes
23:22alexykok, that's solved. Now about .method?
23:22chouser.foo is not a function
23:22chouserunfortunately
23:22alexykarrgh
23:22chouserit's a special form
23:22alexykmethornil's just become obsolete
23:22chouserbut this is actually a good thing!
23:22chouserbecause now you have an excuse to write methornil as a macro
23:23arohneryou're wanting to pass a java method around to clojure functions?
23:23alexykyep
23:23alexykchouser: yay! let's do it
23:23alexykback to the macros
23:24alexykso I need to write a macro methornil, equivalent to the defn: (defn methornil [x f a] (if a (f x a) x)), which takes java methods as f
23:25chouser(defmacro methornil [x f a] `(if ~a (~f ~x ~a) ~x))
23:25chouserexcept that expands a and x twice each, which could potentially cause problems
23:26alexykchouser: is there like a macro val which stores the single expansion for reuse?
23:26arohneralexyk: your friend 'let' will do that
23:26chouseryou just have your macro expand to something like (let [x-val x] ...)
23:27arohner(defmacro methodornil [x f a] `(let [a# ~a x# ~x] (if a# (~f x# a#) x#))
23:27alexykright
23:27alexykwhat's a# and x#?
23:28alexykah, just single expansions
23:28alexykchouser: so how would you summarize why exactly we need macro for both methods and functions? :)
23:28alexykbefore you go...
23:28arohnernobody's ever told me I'm capable at clojure before
23:29arohneralexyk: you need a macro before java methods are not first class functions
23:29alexykarohner: using # is a sign of maturity, also thwarts perl and ruby and python people into stupefaction :)
23:29arohner(.foo obj) is a special form; you use the macro to produce those
23:30alexykright
23:30alexyksomnium`: perl people turn off like androids upon seeing #
23:30alexykand skip to the next line
23:32alexykok, finally a case for macros. somnium`, consider this: I switched to clojure 'cause congomongo is better at mongo than scala for data; now it has lead me to learn macros. What else is in store?
23:33alexykthe next application of congomongo is general relativity probably
23:34somnium`alexyk: once you get comfortable with macros, you may find any non-lisp to feel unpleasantly lacking in expressiveness
23:35somnium`that, or general relativity I guess
23:36joeggalexky: one of the main things that macros allow you to do is to create new first class syntax, which I think you're already picking up on.
23:36joeggDarn, again, typo'd your name.
23:36alexyknp)
23:36joeggAnyway, (if...) is a macro that just calls (cond...), more or less.
23:37joegg(Also, I'm a beginner, so if I end up saying something wrong, anyone can feel free to correct me please.)
23:37somnium`,(macroexpand '(cond true :foo))
23:37clojurebot(if true :foo (clojure.core/cond))
23:37alexykhow can you check what's a macro?
23:37joeggNow, one thing that I've always wanted in javascript/java/etc is a while/else.
23:37arohneralexyk: the metadata of the var
23:37arohner,(meta (var cond))
23:37clojurebot{:macro true, :ns #<Namespace clojure.core>, :name cond, :file "clojure/core.clj", :line 400, :arglists ([& clauses]), :doc "Takes a set of test/expr pairs. It evaluates each test one at a\n time. If a test returns logical true, cond evaluates and returns\n the value of the corresponding expr and doesn't evaluate any of the\n other tests or exprs. (cond) returns nil."}
23:37tomojit tells you in (doc cond) too
23:38joeggwhile(foo) { } else { }, where the else is executed only if the while was never executed.
23:38arohneroh, right
23:38joeggIn javascript, I couldn't have that, unless I wanted to write my own implementation.
23:38tomojmacro? would have to be a macro, eh?
23:38joeggOr, fake it, horribly, using functions.
23:38joeggIn clojure, *I can create while/else using macros.*
23:39joeggAnd it has the same (total lack of) syntax as everything else, it's not some second class thing.
23:39defnhi all
23:40defnls
23:40joeggalexyk: Does that make sense? (also, just found out I can tab-complete nicks.)
23:42alexykyeah
23:43alexykdefn: we just decided macro is a better nick
23:50joeggOoh, while-else, implemented (crappily):
23:50joegg(defmacro while-else [test body else] `(if ~test (while ~test ~body) ~else)))
23:51joeggCan anyone tell me if I've done something wrong on that?
23:51joeggIt appears to work fine here, but I would love to know if there's something I could do differently or better.