#clojure logs

2010-09-12

04:20LauJensenMorning all
04:55kjeldahlAnybody using slime-connect in emacs who can comment on how or why delimiter matching isn't working in the repl environment?
05:19tomojkjeldahl: what do you mean by "delimeter matching"?
05:19tomojparedit?
05:19clojurebotparedit screencast is http://p.hagelb.org/paredit-screencast.html
05:46kjeldahltomoj: When I write things like (let [[a b][1 2]][a b]) I need help matching the ] and )s. Differently from most other places in emacs (including clojure-mode), the slime REPL buffer in emacs doesn't seem to help.
05:46LauJensenkjeldahl: SLIME doesn't run Clojure-mode
05:47kjeldahlLauJensen: Yes, I get that. I still need help though. Which is why I asked.
05:47LauJensentry M-x clojure-mode
05:47tomojthat screws it up, doesn't it?
05:48tomojkjeldahl: what kind of help are you looking for, though?
05:48tomojparen highlighting?
05:48kjeldahlYes, seems like that screws it up.
05:48LauJensenI tried it here a while back because I needed that highlighting for something, and it worked, and there yes I think there was some kind of bug but I forgot which
05:48kjeldahltomoj: Yes, inside the repl in emacs.
05:48tomojkjeldahl: M-x show-paren-mode
05:48tomojI don't know how to get paredit to play nice with the repl
05:49tomojif I M-x clojure-mode my repl, it's totally borked
05:49tomojit's now just an R
05:49tomojhell it doesn't even R, it's just totally gone
05:49kjeldahlThanks, I know the basics outside of slime-connect repl mode. repl inside emacs matches (, but not [ and probably not {.
05:58LauJensenGuess it wouldn't be too hard to rip the font-locking stuff out of cloure-mode and make clojure-repl-mode
06:05mrBlissI use clojure-mode in my repl without problems. Here's how: http://github.com/mrBliss/dotfiles/blob/master/.emacs.d/clojure.el#L50
06:06LauJensencool
06:07tomojmrBliss: thanks!
06:07tomojalso paredit, wow
06:07tomojyou are a savior
06:07mrBlissI'm not using paredit at the moment, but it is there for when I intend to learn it
06:10tomojaw, it makes you lose the colored repl prompt
06:10mrBlisslook at slime-repl-prompt-face on line 24
06:11mrBlissit's not perfect
06:11tomojah, I skipped the syntax tweak
06:11tomojparedit seems busted somehow too
06:11LauJensentrue
06:11tomoje.g. if you type (()), then point at ((|)), DEL DEL leaves you with ))
06:12mrBlisssorry I'm not using it the moment, so I can't help
06:12tomojthe binding to paredit-backward-delete is gone for some reason.. hmm
06:12tomojno problem
06:12tomojit looks like the binding for DEL is coming from slime-repl-map-mode
06:13mrBlissadd the bindings again in (eval-after-load "slime-repl" ...
06:17tomojI think that's the only binding that gets clobberd
06:18kjeldahlmrBliss: Excellent, thank you.
06:20tomojdamn, I can't get that binding for some reason
06:20tomojoh well, I'll look at it again later
06:20mrBlisswhich binding exactly?
06:22tomojparedit-backward-delete
06:22tomojto DEL
06:22mrBlissI'll see what I can do
06:22tomojtried putting it where the bindings for paredit-open-curly and the other are, no luck. maybe the hook isn't being reloaded or something. don't worry about it though, I'm sure I'll figure it out eventually
06:24mrBlissalright
06:59nlogax(:lol {:foo "bar", :lol "bbq"}) i was surprised that worked, can someone explain why/how to a noob? :)
07:00nlogaxnevermind, i just found it in the docs
07:00LauJensennlogax: maps are functions of their keys
07:01nlogaxLauJensen: i had seen that one before, but not "callable" keywords
07:01jjidoI tried converting my program to trampoline but I quickly get a stack overflow. How do I prevent stack from growing? http://pastebin.ca/1938762
07:03jjidoNote: my solution with (loop [next start] (recur (next))) works fine
07:03tomojI think you have far too many trampolines
07:04tomojI don't understand your code, but my guess would be to try only having the one trampoline in start, and get rid of all the rest
07:08jjidotomoj: I think I don't understand trampoline, hence my code
07:09jjidoI want to throw away the current function stack then call a function
07:09jjidocan trampoline do that?
07:10tomojyes, just return the function
07:10Chousukejjido: you return a thunk from the function and the trampoline calls it
07:12LauJensen,(letfn [(dec-even [x] (if (zero? x) x (dec-odd (dec x))))
07:12LauJensen (dec-odd [x] (if (zero? x) x (dec-even (dec x))))]
07:12LauJensen (trampoline dec-even 6))
07:12clojurebotEOF while reading
07:12LauJensenwell, that would return zero, think its the simplest example of a trampoline I can think of anyway
07:12ChousukeLauJensen: that's not right.
07:12ChousukeLauJensen: you need to return a function from dec even, not call dec-odd directly
07:13Chousukesomething like. (letfn [(x [] (print "x") #(y)) (y [] (print "y") #(x))] (trampoline x))
07:14LauJensen,(letfn [(dec-even [x] (if (zero? x) "even" #(dec-odd (dec x)))) (dec-odd [x] (if (zero? x) "odd" #(dec-even (dec x))))] (trampoline dec-even 5))
07:14clojurebot"odd"
07:14LauJensen,(letfn [(dec-even [x] (if (zero? x) "even" #(dec-odd (dec x)))) (dec-odd [x] (if (zero? x) "odd" #(dec-even (dec x))))] (trampoline dec-even 6))
07:14clojurebot"even"
07:20jjidotomoj: Chousuke: ok I just replace my loop with trampoline, that works
07:25jjidoUpdated program here (WARNING prints 700000 lines) http://pastebin.ca/1938773
07:30Chousukejjido: you should use two spaces as the standard indent, it makes the code look less nested.
07:30jjidook
07:30Chousukethe underscore names are curious too but other than that the code looks fine to me.
07:32jjidojust to avoid clobbering throw (don't know if there is a return in Clojure)
07:33Chousukethere isn't.
07:34Chousukeand it's acceptable to shadow names in functions, as long as the function is short enough :)
07:34jjidoI will use "return" and "error" instead
07:35Chousukemy first thought when I saw _return was that it's just a named unused parameter
07:35Chousukeas _ is the idiomatic "unused parameter" name
07:38jjidohow about "loop"? I don't want to clobber that at the top level
07:38Chousukeyeah, you shouldn't.
07:38jjidowould f-loop look more lispy?
07:38Chousukewhat does the f mean?
07:38jjidofunction
07:39Chousukehmm.
07:40Chousukeboth names are pretty uninformative in my opinion
07:41jjidocould be, I did have a "loop" function in my original program (in a different language)
07:41Chousukeeven if you called it "loop" it raises the question "what loop?"
07:41jjidoit is a loop that prints "Hello World!" seven times
07:42Chousukeso maybe you can call it print-loop or something?
07:42jjidois that better style: http://pastebin.ca/1938786
07:44Chousukeyeah, looks better. You can use more spaces to align parameters though if that makes the code look better.
07:45Chousukefn_loop should be fn-loop though. (or print-loop as I suggested :P)
07:46tomojChousuke: yes, I also had to go test whether those would be named but unused
07:46tomojand I was thinking, wow, someone wrote all this code without ever testing it?
07:46tomojnow I'm trying to remember where I've seen named unused parameters before
07:47Chousukejjido: Maybe you should come up with a naming convention for the continuations to differentiate them from the other parameters
07:49Chousukelike yes-c or returnc. I think it would make the code easier to understand. (though more typing for you)
07:49jjidoChousuke: the code will be generated
07:49Chousukeah, okay
07:50tomojnaming stuff is hard
07:51Chousukeyeah, it is.
07:52LauJensenwas easier in CL
08:03cwbI'm reading Programming Clojure and don't understand the difference between next and rest: if rest always returns a sequence then why do we need next equivalent to (seq (rest aseq))?
08:04LauJensen,(next [])
08:04clojurebotnil
08:04LauJensen,(rest [])
08:04clojurebot()
08:04cwbAha -- thanks!
08:04LauJensennp
08:42BahmanHi all!
10:04alpheusWhat's good style for formal function parameter names that clash with well-known functions? Something scheme-like, spelling list as lst?
10:14AWizzArdalpheus: often people want to name parameters like the datatype they are holding. Another way is to type-hint them: (defn foo [^clojure.lang.PersistentList l] ...)
10:19scottjHow do you disable congomongo's auto converting of strings to keywords? When I insert {"foo bar" 1} it will then always return it printing as {:foo bar 1} even though looking "foo bar" up in it still works
10:20RaynesThere is an argument you can pass somewhere.
10:21RaynesHrm, maybe not.
11:28boredomistIs there a better way of doing (str (char 65)) to change 65 to "A"?
11:28boredomist(for example)
11:38AWizzArdboredomist: that's fine.
11:57LauJensenIf its not paypal, do you guys have some really good experiences with other cart/payment providers?
11:59kotarakCan someone explain me, how equiv works?
11:59kotarakObviously I'm too stupid to implement it.
12:02LauJensenkotarak: http://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/APersistentMap.java#L72
12:02LauJensenThat what we're talking about?
12:02kotarakYeah. Roughly. More for list.
12:03kotarakA translated things into Clojure, but it doesn't like me.
12:03kotarakArgh.
12:03LauJensenLooks simple, if its not the same type return false, if its not the same size return false, otherwise, check all element
12:03LauJensens
12:03kotarakLauJensen: Never mind. I'm stupid.
12:03LauJensenOk - Now back to my Payment provider question, any recommendations?
12:16chouserLauJensen: I've used google checkout a bit. No particular recommendation one way or the other.
12:17LauJensenk
12:36maravillasfrom a buyer's or seller's perspective, LauJensen?
12:36maravillasI've bought through google checkout as well, and it's been straightforward enough
12:38chouserI guess google checkout provides a bit more management of the sales "workflow", with the payment authorization showing up in a list before the buyer has actually been charged.
12:38chouser...so that you can prepare and ship your item, then click the "ship" button to actually charge the buyer.
12:39chouserbut neither google nor paypal strike me as being very good about customer service. I would be nervous if 100% of my income depended on either of them paying out promptly.
12:39LauJensenmaravillas: seller
14:04BahmanMy project.clj is (http://pastebin.ca/1938963)
14:05iveyIdiomatic clojure question: I'm building a library that wraps a remote API. Is it more appropriat to set *username* and *password* vars and use those everywhere, or create a client data structure and pass that around?
14:06BahmanWhen I run 'lein deps' Leiningen looks for clojure-1.1.0-alpha-SNAPSHOT and fails. Any ideas?
14:10pomykBahman: maybe incanter or org.clojars.ato/compojure tries to bring it in?
14:10LauJensenivey: Passing arguments around is definitely more function and thus idiomatic. However some libraries take the approach that you save your credentials in a struct, then make all calls (with-credentials struct ....)
14:10Raynesivey: You'll find fans of both styles. Personally, I prefer the latter style in this specific case. I do something similar in my clj-github library. I believe I have an *authentication* var that contains a map with credentials.
14:11RaynesI've seen some similar libraries do similar things. When you have doubts about whether doing stuff like that is a good idea, it's better go err towards passing arguments around.
14:13iveyTaking a look at clj-github now.
14:13Bahmanpomyk: Checking...
14:14RaynesCalls are like (with-auth {:user "Username" :pass "password"} ...calls to various API stuff)
14:15iveyRaynes: but if you were doing a lot of calls, you'd do a (def *authentication* {...})
14:15ivey?
14:15RaynesI've never done that.
14:15RaynesBut, I imagine yes, you could.
14:16iveyInteresting.
14:21pomykivey: why not make a "class" to hold the username/pass and provide api methods?
14:22iveyso you get an object that knows how to auth, and has all the calls on it?
14:23Raynesivey: If you're thinking about what I think you're thinking about, that wouldn't work. You'd have to use binding.
14:24RaynesDoing (def *authentication* ..) from a client library shouldn't override the var in the library itself.
14:24iveyright
14:24iveyI have a conceptual map of this territory that's a mashup of Ruby and elisp.
14:25iveyI think I'll try it with a (with-creds) macro and see how that feels
14:32BahmanIs there a simple way to use REPL when working Compojure and Lein?
14:33KirinDave?
14:33KirinDaveBahman: What problem are you running into?
14:35BahmanKirinDave: Nothing. I just don't have any idea how/where to start. New to clojure.
14:35KirinDaveBahman: The answer is "yes, you just do."
14:35KirinDaveLein repl works.
14:35RaynesYou can start a repl with 'lein repl'
14:36BahmanNice. Any chance to use Emacs instead of command line repl?
14:36KirinDaveyes
14:36KirinDaveWorks fine.
14:36KirinDaveBut!
14:37BahmanJust please give me a pointer and I figure it out.
14:37RaynesIf you have SLIME set up, you can run a swank server with 'lein swank' and connect to it with M-x slime-connect
14:37KirinDavePlease note that the launch directory for your java instance will be set to the file location of the curent buffer wehn you call slime.
14:37LauJensenKirinDave: Congrats on the book :)
14:37RaynesWhat he said.
14:38KirinDaveLauJensen: Thanks!
14:38Bahman"lein swank
14:38BahmanThat's not a task. Use "lein help" to list all tasks." I guess I'm missing something.
14:38KirinDaveBahman: Newer version required.
14:39KirinDaveBahman: I start swank-clojure-project from a dired buffer on the top of the file
14:39KirinDaveBahman: So that $ROOT/resources/templates will resolve
14:39BahmanKirinDave: Using 1.3.1 ... should I upgrade to 1.4?
14:40KirinDaveEnlive's template generator, when I last tried it, was less than helpful on errors, especially FileNotFound.
14:40BahmanThat's too advanced for me now :-) .but will keep it in mind.
14:40RaynesBahman: Add swank-clojure "1.2.1" to your dev-dependencies in project.clj
14:40RaynesI forgot to mention that.
14:40KirinDaveI don't actually know how to use lein with slime-connect
14:41Raynesswank-clojure has the lein plugin in it now.
14:41RaynesSo, that'll do the trick.
14:42KirinDaveWhich version has that, is it in the packages, Raynes?
14:42danlarkinyes, put swank-clojure as a dev-dependency in your project descriptor and then lein deps, and then you can lein swank
14:42RaynesKirinDave: The jar, I mean.
14:42Raynesswank-clojure is on clojars. You just have to add it as a dev dependency.
14:42KirinDaveAh
14:43RaynesYou don't need any Emacs-side swank stuff anymore. Just slime.
14:44KirinDaveAh
14:44KirinDaveDeath to swank-clojure-project then
14:44KirinDavebane of my existence.
14:44anonymouse89I'm confused by: "No matching ctor found for foo"
14:44KirinDaveanonymouse89: So are we, without context. :)
14:44danlarkinthere's a lein-swank elsip function floating around out there, maybe technomancy can point you to its canonical location
14:45anonymouse89where foo is a fn passed as an arg to another function
14:46anonymouse89I guess my question would be, is there any documentation that I'm missing that would help with this error? Or for those who have seen this is it more on the specific or general side of things?
14:46KirinDaveanonymouse89: Could you make a gist of the context, please?
14:46KirinDaveanonymouse89: gist.github.com has a clojure highlighting mode that is good. :)
14:47anonymouse89it's a little obscure, but sure
14:48KirinDaveLauJensen: I'm looking forward to getting to writing, I just hope I've got the chops to write a whole book.
14:48LauJensenKirinDave: Im sure you do, but if not you're in good company I see :)
14:49KirinDaveLauJensen: The other tough sell is that we want to talk to rubyists and pythonistas.
14:49KirinDaveLauJensen: And maybe even JS people, in addition to the straightlaced java developer.
14:49LauJensenYea I cant really help you with that, they've never liked my blogposts :)
14:52BahmanKirinDave and Raynes: Thanks for the assisst.
14:52KirinDaveLauJensen: One thing we're not doing
14:52LauJensenWhats that?
14:52KirinDaveLauJensen: is doing a chapter on macros. No macro chapter.
14:52LauJensenhehe - Why not?
14:52RaynesAnytime.
14:52KirinDaveWe're only going to mention them in context.
14:53LauJensenGood call
14:53RaynesClever.
14:53KirinDaveLauJensen: Well, because it's one of those things that most people won't understand. Syntax-oriented programming is a very alien concept.
14:53anonymouse89KirinDave: here's a pared down version: http://gist.github.com/576320 ... I completely understand if this is too involved of a problem (AKA my ignorance is too great :))
14:53LauJensenOne guy at Conj Labs Brussels was horribly disappointed with macros and especially their frailty and uglyness, so I told him, that Macros were mostly important in discussions with other languages. Like if you're talking to some Scala guy you can always say "Have you got macros? because if not.." :)
14:54LauJensen(it was a joke, and funny at the time)
14:54KirinDaveanonymouse89: Um, so
14:54KirinDaveanonymouse89: Where is the error occuring?
14:55anonymouse89from what I can tell, it occurs when map-qubit-combinations is nested with itself
14:55KirinDaveLauJensen: I'm researching to try and write an MBE lib. I think most complaints about macros are addressed by plt scheme's macro system
14:55KirinDaveWhich isn't always enough, but for most syntax it's WAY faster and less error prone to use MBE and a syntax transformer that has real eror handling, etc.
14:56anonymouse89basically, map-qu-combos applies a function a bunch of times, but if that function also calls map-qu-op then there is the ctor problem
14:56LauJensenKirinDave: Sounds incredibly interesting, got a mock of it somewhere?
14:56KirinDaveanonymouse89: Can you reproduce your problem with fewer than 138 lines of code?
14:56KirinDaveLauJensen: You can look at the racket documentation if you wanna see how it looks
14:57KirinDaveI haven't started coding yet. It's a pretty involved project.
14:57KirinDaveLauJensen: Racket's guide is an excellent intro: http://docs.racket-lang.org/guide/pattern-macros.html
14:58LauJensenGreat, thanks
14:58KirinDaveLauJensen: The classic example of a "rotate" macro: http://gist.github.com/raw/576326/b85a4eaa1b47e4f7459eb05dc2fc13df8444f83d/ex.plt
14:58KirinDaveLauJensen: But the ... expansions can get pretty tricky.
14:59LauJensenhehe
15:00KirinDaveI am trying to go to the conj
15:00KirinDavebut fuck flying to NC is a pain in the ass.
15:00KirinDaveExpensive and painful.
15:01LauJensenyea, fly to Frankfurt instead
15:01RaynesChas is making my airline reservations. :>
15:01KirinDaveAt least that'd be _easy_.
15:01KirinDaveLol
15:01RaynesNo complication for me. :D
15:01KirinDaveI should ask him to do that for me.
15:01KirinDaveBecause Delta is refusing my credit card. :\
15:01KirinDaveAnd I am not the kind of guy with multiple cards to try.
15:09KirinDaveanonymouse89: Here is a hint, btw
15:09KirinDaveanonymouse89: You do not need eval. You *never* need eval. If you think you need eval, it's a sure sign that you don't.
15:10LauJensenYea, thats the give-away sign :)
15:11anonymouse89KirinDave: do you see what I'm trying to do in those lines?
15:11anonymouse89KirinDave: I'd like something like (-> foo (fn-a 0) (fn-b) (fn-a 1) (fn-b) ...)
15:11KirinDaveYes, you're trying to make -> statements.
15:13KirinDaveI'd recommend NOT doing it that way
15:13KirinDaveWhat I'd do is use reduce.
15:14KirinDaveanonymouse89: -> is just a fancy syntax for reduce. You don't need to use that error-prone eval method if you use reduce. Build a list of the functions you need, in order, then use reduce to perform your transform.
15:14KirinDaveanonymouse89: -> is for syntactic convenience, only.
15:15KirinDaveIt will make debugging easier, too
15:16anonymouse89KirinDave: ok, that makes sense.
15:23KirinDaveTwinql?
15:25LauJensen(find-twins :named "Jack")
15:25LauJensenreturns all twins on facebook as a sql statement
15:25KirinDavedang
15:26LauJensenyea, powerful technology
15:26LauJensenNaah Im just kidding, dont know what that is :)
15:34_ulisesevening
16:05anonymouse89((a) (b) (c)) into (a) (b) (c) ?
16:06LauJensenanonymouse89: one form which expands into 3 forms?
16:07anonymouse89LauJensen: yes, I guess more precisely, using (for [i (range 3)] i) gives (1 2 3) where I would like 1 2 3
16:08anonymouse89*0 1 2
16:08LauJensenAll Clojure forms return the result of evaluating the final element. I don't know of anyway of returning multiple values that are all atoms
16:09wwmorgananonymouse89: are you doing this in a macro? If so, you can use macro unsplice ~@
16:10anonymouse89wwmorgan: no. but thanks for the hint
16:10LauJensenwwmorgan: still, it cant be a return, only the argument to something else
16:10LauJensen(within the macro)
16:10anonymouse89LauJensen: right, that's my situation
16:10anonymouse89I think I might just use a macro
16:11LauJenseneither a macro, or apply. Prefer apply
16:11wwmorgananonymouse89: What is your use case? I can't think of one
16:12anonymouse89I want to assoc specific indices of a vector with 1 or 0 depending on a condition
16:13LauJensen,(map #(if (even? %) 1 0) [1 2 3 4 5 6])
16:13clojurebot(0 1 0 1 0 1)
16:13anonymouse89like (assoc index myvector (if (cond index) 1 0)) for indices in (1 3 7 9)
16:13LauJensenYou could probably work that seq in a more functional style, like the map above
16:14anonymouse89LauJensen: that seems like exactly what I should be doing
16:15LauJensenanonymouse89: great. If you're coming from an imperative language. I suggest trying to ask your questions more broadly, because odds are you can pick up a few hints about functional design
16:16anonymouse89LauJensen: how did you guess? :p I'll try. Also, I think I need to do a lot more general reading on writing functionally
16:17LauJensenEither that, or attend conj-labs.eu :)
16:19anonymouse89LauJensen: sounds great but ... I'm a student :(
16:19LauJensenWell students are welcome as well. I wonder if we should make a special student discount.
16:20morphlinghi guys, is there a common interface that all integer classes share?
16:20morphlinglike Number, but ratios also implement/extend that
16:22morphlingby "all integer classes" I mean Integer, Long and BigInteger
16:24wwmorgan,(->> (ancestors (class 1)) (clojure.set/union (ancestors (class (bigint 1)))) (clojure.set/difference (ancestors (class (/ 5 2)))))
16:24clojurebot#{}
16:24Bahmanmorphling: java.lang.Number
16:25LauJensenwwmorgan: that was cool :)
16:25wwmorganmorphling: it looks like there are not. You could compute the information by doing (zero? (mod n 1)), I think
16:26morphlingwwmorgan: thanks :)
16:27morphlingI want to dispatch on type with multi methods, and I essentially have the same code for Integer, Long and BigInt
16:28LauJensenmorphling: use meta data?
16:28morphlingI'll probably just put the actual code in an external function and call that three times, or do everything in the bigint case
16:28tomoj,(map integer? [(int 1) (long 1) (bigint 1)])
16:28clojurebot(true true true)
16:29KirinDaveanonymouse89: Sorry man, but sadly clojure doesn't support multiple return values like common lisp's.
16:29KirinDaveanonymouse89: The best way to do it is to assume 0->inf number of elements on all return values OR an error.
16:29KirinDaveanonymouse89: error-kit should help you handle the error case more rigorously.
16:29morphlingLauJensen: how can i use meta data for that?
16:29LauJensenmorphling: multi-methods can dispatch on anything
16:30LauJensenSo as long as your data supports its. If you want the pure numbers being passed, then you cant
16:30KirinDaveLauJensen: The burden of history. :)
16:30LauJensen?
16:31KirinDaveLauJensen: No meta on numbers.
16:31KirinDaveAn implementation detail :(
16:31LauJensenyea well... :)
16:31wwmorganmorphling: do you need to dispatch on type? If not, then you would just change your dispatch method from type to integer?, or something like that
16:31morphlingLauJensen: I thought about using a more complicated dispatch function and dispatch on keywords, like :integer for those three, but I don't think it's worth it
16:32morphlingwwmorgan: see above :)
16:32morphlingthanks guys!
16:34anonymouse89LauJensen, KirinDave: ah, i think the big thing I was missing was map can take multiple collections, thanks again for your help and patience
16:34KirinDaveanonymouse89: Don't worry, it's complex for everyone
16:34LauJensenthats what we're here for :)
16:55Bahmanwwmorgan: What does ->> do in the statement above?
16:58wwmorganbahman: ->> is thread-last. (->> a (b c) (d e)) becomes (d e (b c a)). Along with -> (thread-second), it's useful for showing the flow of data and avoiding deep nesting of s expressions
16:59LauJensen,(-> 5 (/ 10))
16:59clojurebot1/2
16:59LauJensen,(->> 5 (/ 10))
16:59clojurebot2
17:00BahmanThanks wwmorgan and LauJensen.
17:01LauJensennp
17:01wwmorganLauJensen: that's a great comparison
17:01BahmanBy "deep nesting" you mean using "let" forms?
17:01LauJensenwwmorgan: yea I think its a lot easier to follow than a b c d examples
17:01LauJensen(no offense whatsoever)
17:02wwmorgannone taken :-p
17:03BahmanRight...now the above mystical statement is clear to me :-)
17:03BahmanI was wondering if it was sort of Assembley language :-)
17:04BahmanOne last question: What is an "s" expression?
17:04LauJensentechnically, everything in (println "hi" "there") is an s-exps which contains 3 s-exps, unless I misunderstood completely :)
17:06BahmanLauJensen: So every form in Clojure is an S expression?
17:06LauJensenyea
17:06LauJensenS expressions could be labeled, intelligent XML I guess
17:07BahmanGot that. Thanks.
17:11LauJensenIm off now - Those looking to secure a seat at Conj Labs Frankfurt with the EB discount, book tomorrow morning :) http://conj-labs.eu
17:14iveyIf I have an XML doc in a string, how can I turn it into a structmap? xml/parse wants a file.
17:17iveynevermind, I got it.
17:45anonymouse89is there any way to have a binding without already having that var root-bound?
17:46wwmorgan,(doc with-local-vars) ; <- anonymouse89
17:46clojurebot"([name-vals-vec & body]); varbinding=> symbol init-expr Executes the exprs in a context in which the symbols are bound to vars with per-thread bindings to the init-exprs. The symbols refer to the var objects themselves, and must be accessed with var-get and var-set"
17:47anonymouse89wwmorgan: thanks
17:47wwmorgananonymouse89: actually, it doesn't appear to do what you want
17:47wwmorgan,(with-local-vars [a 1] (binding [a 3] @a))
17:47clojurebotjava.lang.Exception: Unable to resolve var: a in this context
17:48anonymouse89I've never seen this before:
17:48anonymouse89,(with-local-vars [a 1] (println a))
17:48clojurebot#<Var: --unnamed-->
17:49dakrone,(with-local-vars [a 1] (println (var-get a)))
17:49clojurebot1
17:49anonymouse89dakrone: is that any different than deref-ing?
17:50wwmorgan,(with-local-vars [a 1] (println @a)) ; This works too. @ is a reader macro for getting the content of a reference type
17:50clojurebot1
17:50dakroneanonymouse89: using @ is better
17:50anonymouse89dakrone: right, I meant var-get vs. @
17:52wwmorgananonymouse89: looking at the macroexpansion of binding suggests that, if you want to use binding, the vars need to root-bound
17:53anonymouse89hmm, it seems like I can't set! vars bound with with-local-vars
17:54wwmorgananonymouse89: set! is for java interop. You want var-set
17:56anonymouse89i'm really failing today :( .. but now I know, thanks
18:23amalloyi used destructuring to peel apart a complex nested-map structure that one of my functions is receiving, and now it looks way harder for me to read than the naive (fn [obj] (let [thing1 (:child obj)...])) form
18:24amalloyis this usual, or something i'll get used to like all the parens, or a way i should be formatting it more legibly?
18:25rhudsonWhat does your destructuring look like?
18:25amalloy(defn minimax
18:25amalloy [{{{{p :to-play} :state} :posn
18:25amalloy :as posn} :posn
18:25amalloy :as consq}]
18:26rhudsonSeems like it would be better to unnest it
18:26amalloyby which you mean...?
18:28rhudsonSomething like your suggestion above. Like have one level of destructuring in your arg list, then 'let bindings to destructure successive levels.
18:28rhudsonDestructuring is in the lang (I think) partly to make the code more readable, not less
18:29rhudsonGenerally if you have trouble reading your own code, that's a bad smell
18:29amalloy*chuckle*
19:18BahmanCouldn't sleep. NetBeans+Enclojure is really nice...maven-based build and nice repl.
19:18BahmanOnly if I could make its auto-completion work for project libs. Currently only works for Clojure and Clojure contrib.
19:22rps_If I have a vector of articles, how would I print the :title of each article?
19:27cinim0drps_: Hint: map, :title, articles
19:28rps_cinim0d: thanks
20:28sproustLeiningen question: when I start my VM with "lein swank", I can then connect with slime-connect, but the "lein swank" target does not eval the code of my project. Is there a way to tell leiningen to evaluate some module and then start a swank server, so I don't have to do that every time I reconnect?
20:40amalloyi notice that (memoize fib) is no faster than (fib) the first time you call it, because fib does all its recursion internally where memoize can't intercept it. is there a macro somewhere like defmemo that rewrites the function definition to recur through the cache?
20:43wtetznerthe problem is that (defn fib [n] ...) expands to something like (def fib (fn fib [n] ...))
20:44wtetznerso the recursive call doesn't reference the var
20:44amalloywtetzner: sure, i understand why it doesn't work
20:44wtetznerthere is defn-memo in contrib, but it doesn't solve the problem
20:45wtetzneryou have to do (def fib (memoize (fn [n] ...)))
20:46amalloyyou sure defn-memo doesn't solve the problem? it looks like it might, from the source
20:46BahmanDoes (defn -main [&args] ...) mean that I have to pass some args to -main?
20:47BahmanI thought & means args is optional.
20:47dakroneBahman: args is optional
20:47Bahmandakrone: #<CompilerException java.lang.IllegalArgumentException: Wrong number of args (0) passed to: core$-main (NO_SOURCE_FILE:3)>
20:48BahmanThat's what I get when I call it like (guestbook.core/-main)
20:48_atoBahman: you need a space between & and args
20:48wtetzneramalloy: defn-memo just calls defn and then alters the root var
20:48dakroneyea, should be [& args]
20:48BahmanDoh!
20:48wtetzneramalloy: so you still have the (fn fib [] ...) problem
20:48BahmanThanks.
20:49amalloyhm. okay, i think i see
20:49wtetznerdefn-memo really should have been implemented to expand to (def fib (fn [] ...)) without the name in the call to fn
20:50_mstif you want to force the recursive call back through the memoized version, you might want to do the recursive call with: (#'fib ...)
20:51_atoor just forget the macro and write your function using (def fib (memoize (fn [n] ...))) :-)
20:51Raynes_ato!
20:51RaynesI haven't seen you in forever.
20:52amalloyit can't be that hard to write a macro that walks the tree and converts (recur) and (fib) calls and converts them back into calls to the memoized version
20:52_atoyep, or do that :)
20:53wtetznertree-walking macros like that are always a bit tricky
20:53wtetznerit's easy to forget some case where the replacements you're doing won't work
20:54wtetznerfor example, what if recur is referencing loop instead of the enclosing function?
20:54wtetzneryou can account for it, but things like that are easy to forget
20:54amalloybah! who uses loops? :)
20:55wtetzneralso, if someone is using recur, chances are it's because they want tail recursion
21:04BahmanIs it possible to deploy Compojure apps in an ordinary application server (not embedded)?
21:08chouserBahman: pretty sure, yeah.
21:10Bahmanchouser: So I should use jetty adapter only for development right?
21:13scottjWhat's the easiest logging solution to use w/ c.c.logging, and how to run in debug mode? The default sucks bc all messages look like "Sep 12, 2010 8:59:01 PM clojure.contrib.logging$eval7120$impl_write_BANG___7123 invoke INFO: message"
21:13chouserwell, that's up to you I guess
21:13chouserBahman: if it'll do, I'd use it until it won't do anymore. :-)
21:13Bahmanchouser: Got your point...thanks.
21:16amalloyscottj: passing it through perl or awk or something sounds easier than reconfiguring c.c.logging. perl -p -e 's/^.*invoke/;' < my_log_file
21:16scottjamalloy: well c.c.logging supports several logging backends, I'm just wondering which is easiest
21:17scottjthere are like a million tutorials on monads for clojure but none on setting up another backend for logging :)
21:23dakronehow do I type something like "^M" in Emacs?
21:23Raynesdakrone: C-q-C-character
21:23dakroneRaynes: thanks
21:24Raynesdakrone: I discovered that by accident about three hours ago.
21:25scottjC-q is very common in emacs, you'll use it in paredit too if you ever get unmatched parens
21:25Raynesscottj: That's how I discovered it.
21:26scottjRaynes: you were right, there's somnium.congomongo.coerce/*keywordize* but it kinda stinks
21:26RaynesI knew there was *something*. I couldn't find it though.
21:26RaynesI was looking in the wrong namespace.
21:27scottjit stops string keys from becoming keywords, but it also means you can't use keywords for keys
21:49sproustWouldn't it make sense to throw an error when a struct-map is accessed with an invalid key?
21:49sproustQuite often the default behaviour of returning nil for a key not found hides errors in accessing the s/m's "members".
21:50sproustMakes typo errors harder to find.
21:50sproustI suppose I could just create my own failing-getter, but isn't that a really common use case?
21:52RaynesIt'd be inconsistent, at the very least. Maps return nil if a key isn't found in them. The general idea is that, if you need something other than nil to mean "key not found" you can use get.
21:54scottjyou don't even need get on either, (:foo {} (Exception. "key not found")) or ({} :foo ...)
21:57sproustscottj: that's nice, but it doesn't raise the exception.
21:57sproustAdding (raise) won't help either, it evals the not-found form before it checks, it seems.
21:57chouserpeople have written safe-get and I think even a safe-map
21:58sproust,(:foo {:foo 42} (throw (Exception. "Not found.")))
21:58clojurebotjava.lang.Exception: Not found.
21:58sproustchouser: Funny I was going to call it just that. Should be core IMHO, so common.
21:59sproustOh wait, it's in map-utils
21:59sproustNever mind, thx.
21:59RaynesOrly
21:59Raynes-> (:foo {} "not found"}
21:59sexpbotjava.lang.Exception: Unmatched delimiter: }
21:59Raynes-> (:foo {} "not found")
21:59sexpbot=> "not found"
21:59RaynesWhen did that happen!!!
22:00sproustRaynes: not good enough for my use case; it just returns the value, that'll sweep th eproblem under the rug too many times.
22:00sproustHmmm, also surprising we don't have PG's aif in core.
22:00chousersproust: rhicky doesn't like anaphora
22:01chouserhas called them "evil", I believe
22:01sproustOh. He'd really hate Hoyte's entire book then.
22:01RaynesYou could always write a safe-get like chouser alluded to.
22:01sproustRaynes: there's one in map-utils.
22:02sproustchouser: clojure.contrib.anaphoric?
22:02Raynesclojure.contrib.evil >:)
22:03sproustHahaha
22:03chouserI don't like that they introduce new bindings without calling out their names
22:03sproustWith great power comes great responsibility :-)
22:04RaynesI've been guilty of such acts before reading Joy.
22:04chouserintroduce or change the value of.
22:05chousersproust: we do have if-let and when-let
22:07sproustHaa, nice. That's cute. I didn't know if-let.
22:07sproustLovely.
22:07sproustClojure is full of surprises, really a wonderful language.
22:10sproustHow do you switch between "edit expression" and "eval"? I have a bookmark and move my cursor to my "main" expression, then C-M-x, and then back to edit-modify-eval, and then repeat, but it's getting a bit annoying. I'm starting to think I should automate this a bit.
22:24scottjif anyone else was wondering how to use log4j w/ c.c.logging and set log level http://groups.google.com/group/clojure/msg/30738d8efc179ea3
22:31laurusDoes anyone else find the Incanter graphics library horribly ugly?
22:31chouserthe library or the graphics it produces?
22:31lauruschouser, sorry, the graphics it produces :)
22:32scottjI think the graphs look decent, definitely better than old excel or old incanter :)
22:32laurusI have a lot more experience in Python than Lisp, and I was considering using Clojure to try to do some data analysis, but those plots are a real turn-off for me, unfortunately...
22:32laurusIs there a way to swap graphics libraries or something?
22:32scottjyou're definitely not the first to complain
22:33scottjyou can use the dark theme
22:33chouserare there not config settings to improve the look? I'm afraid I haven't used Incater at all.
22:34lauruschouser, there are themes, but they still look kind of unprofessional, to me at least
22:34laurusI can't understand why they picked that library, other than sheer convenience
22:38rhudsonThere's quite a bit you can do with the underlying JFreeChart to change appearance
22:40laurusrhudson, really, okay!
22:41laurusThat's good to know...
22:41laurusPerhaps I just need to poke around?
22:44scottjwonder why there's no ChartTheme repo for jfreechart
22:45laurusI'm new to Clojure, the only Lisp I've really used much is XLisp, where I could run (^ 2 3) and get 8. How do I do exponents in Clojure?
22:46scottj,(Math/pow 2 3)
22:46clojurebot8.0
22:46scottjlame, I know
22:46laurusscottj, haha, honestly that is kind of lame, but whatever :)
22:46ZhivagoSo, define a function name that you prefer ...
22:47laurusZhivago, will do :P
22:47laurusOr I'll just get used to it, probably the better way.
22:53laurusIs _Practical Clojure_ a good introduction to the language?
22:53scottjZhivago: then you have differnt names for a basic function in different people's code or stupid import statements for a basic function that should have been in core.
22:55chouserhm. what import statement?
22:56scottjsay you didn't want to define pow all the time, (:use 'basic-math)
22:56scottj(sorry if import instead of use was the confusing part)
22:57scottjs/basic-math/clojure.contrib.math
22:59chouseroh, I see. yep.
22:59laurusscottj, I wonder why it's not in the core
22:59chouserlaurus: I don't know, but here's a guess... clojure is pretty minimal and doesn't include much that doesn't add real value.
23:00laurusHeh
23:00chouserthe other math functions are included because they work seamlessly across number types in a way that java interop methods don't.
23:00lauruschouser, that's interesting.
23:02rhudsonAs it is, core defines over 500 symbols -- not everything that everyone wants can go into core
23:03laurusrhudson, it's cool
23:03chouserI suppose one could make an exponent function that returned whole nubmers for whole inputs. But would people actually use it? I dunno...
23:03rhudsonI use string join or split a hundred times for every time I need an exponent
23:03laurusI think I better read some more about Clojure before messing around any more
23:03rhudsonApparently that's what clojure.contrib.math/expt does
23:03laurusI just wanted to try entering a couple XLisp functions to see what happened :P
23:04scottjrhudson: but how many times have you defined a function named expt that wasn't an exponent function? :)
23:04rhudsonI've never named a function 'expt :)
23:04chouserheh, yeah, clojuse is not scheme. there are a lot of differences considering they're both lists.
23:06laurusI find it somewhat hilarious that I've seen mentioned on at least three blogs how Clojure is supposedly difficult to get working. It took me about 3 minutes to find the download, download it, unzip the jar, and run it.
23:06laurusOne blogger bragged about how it only took him 20 minutes to get the thing started as I recall, and others claimed to have given up in frustration.
23:07rhudsonlaurus, I think "Programming Clojure" is a great introduction to Clojure, despite it describing 1.0. Some folks here have said that "Practical Clojure" is a good intro, and describes 1.2. "Joy of Clojure" is an outstanding second book on Clojure
23:08laurusrhudson, thanks for your opinion. I'll go for one of those two then.
23:08laurus:)
23:08rhudsonLaurus, it seems a lot of folks coming from the Lisp side of things find the Java world arcane
23:08rhudson(and vice versa)
23:08laurusAhh... I've actually programmed more Java than Lisp
23:09scottjI really like programming clojure. and I think joy is good in theory, but I'd highly reccommend waiting till it's been edited
23:10rhudsonThat's soon now, right chouser?
23:10rhudsonThe most recent MEAP is really quite good -- a few typos here and there
23:11phobbs when is it scheduled to be printed?
23:11phobbsI find it so much harder to read ebooks
23:11rhudsonThat's why I want to get an iPad!
23:12laurusphobbs, I prefer paper books too...
23:12scottjrhudson: w/ "retina display"!
23:13rhudsonScottj: amen! I just got a 4G iPod touch, and the display just blows me away
23:13rhudsonMy MacBook looks grainy after that
23:13sproustlaurus: if you're just running the main clojure jar and typing commands at the repl it's pretty straightforward. Slightly more complicated (but not much) issues come about when you need external jars if you're not familiar with Java, and it used to be a bit broken for a little while when clojure's swank support was in flux. That's probably why some people bitched about setup.
23:14chouserthe MEAP update for "joy" that came out a couple weeks ago has tons of typo/spelling/grammar corrections from the original chapter MEAPs
23:14laurussproust, right, that makes sense... jars are a pain.
23:14laurusWithout ant, or something
23:14rhudsonlaurus, phobbs -- I go for paper too when there's a choice -- but there's too much early access stuff I can't wait to get my hands on
23:15chouserI don't think there will be another update until it's ready to be printed, but I haven't heard anything about the schedule of that. All I know is Amazon says December for shipping paper copies.
23:15rhudsonThe Manning site says November (est.)
23:15sproustMy limited experience with Java Jars is fairly positive; once you provide your list of jars to the vm it pretty much always works. Problem is, startup time is just... very... slow.
23:15chouserthat's good. Amazon used to and changed it. I hope it's Nov not Dec.
23:16scottjthe last meap update sounded like there wouldn't be any more till release
23:16rhudsonme too. You guys did an amazing job with that book
23:16laurussproust, right, I guess it depends how one loads the app. My experience in Java was with web applications on Tomcat, and ant helped a lot there.
23:17chouserrhudson: thank you very much. fogus deserves the bulk of the credit, really. it was his project from the beginning and I was pleased to be included.
23:18chouserI glad it's done
23:18chouserturns out I prefer writing code to prose. shocker.
23:18rhudson:)
23:19laurusSo what's with this whole Clojure on Clojure thing?
23:20laurusEr, sorry, Clojure *in* Clojure.
23:20scottjlaurus: a goal, unless rhickey has been coding on it in private, there's nothing there but features have been added to clojure to make it easier to accomplish
23:20laurusscottj, but what is the purpose of that goal? To make it more independent of the JVM or the Java language?
23:21rhudsonlaurus, a lot of the Clojure runtime, including the persistent collections, are currently in Java.
23:21rhudsonlaurus, I think partly Rich Hickey wants to be writing in Clojure not Java :)
23:22scottjI always thought it was funny how fogus and chouser would tweet back and forth about each other and their book. fogus: @chouser's book is brilliant!. chouser: mark twain's got nothing on @fogus!
23:22laurusBut it would still run on the JVM?
23:22scottjoh, I forgot the discount coupon links
23:22chouserthere are places that the JVM (as it is and will be in the foreseeable future) doesn't fit well. I want to be able to use Clojure in those places anyway.
23:23scottjlaurus: yeah, it makes porting clojure to .net and javascript etc much easier because clojure datastructures etc are written in clojure
23:23chousersuch as: iOS, javascript, unix command-line, etc.
23:23laurusscottj, oh, got it. So it doesn't affect the end users that much, it's more for the developers of the core language.
23:23laurusAnd for portability.
23:23chouserlaurus: right.
23:23laurusSounds great! :)
23:23laurusI think it would be great to not have to run it on the JVM, actually
23:23chouserUsers of Clojure on JVM should see either no difference, or boosts in features and performance.
23:23laurusDon't ask me why I think that, it's just a feeling
23:36laurusIs there a way to log a Clojure REPL session to a file?
23:48sproustlaurus: do you mean to dump the image, or just the text?
23:49sprouste.g. like (sb-ext:save-lisp-and-die)
23:49sproustActually I've wondered about this too: is there a way to dump the runtime and somehow restart it later, like you would with some CL's?
23:50KirinDavesproust: The JVM isn't image based
23:52sproust,(boolean (list))
23:53clojurebottrue
23:53sproustI get bitten by this all the time.
23:53sproustKirinDave: I was wondering if the runtime LISP structures couldn't be dumped and then have a new process pick them up later.
23:54wwmorgan,(boolean (seq (list)))
23:54clojurebotfalse
23:54sproustI find the dual role of that seq function inelegant. On the one hand it returns a seq on the collection, on the other hand it's needed to check if the collection is empty.
23:54sproustwwmorgan: thx
23:55sproustI don't know how many times I've tripped up over this; a lot. I'm just too used to cons cells.
23:56sproustI should just get used to using empty?
23:56sproust,empty?
23:56clojurebot#<core$empty_QMARK_ clojure.core$empty_QMARK_@15c7277>
23:56sproust,(doc empty?)
23:56clojurebot"([coll]); Returns true if coll has no items - same as (not (seq coll)). Please use the idiom (seq x) rather than (not (empty? x))"
23:56sproustHmmm, it says I shouldnt...
23:57wwmorgansproust: the only reason that it works is that nil is logical false
23:57wwmorgan,(if nil 1 2)
23:57clojurebot2
23:57sproustSo (seq x) is the recommended idiom. But it doesn't look like a predicate.
23:57sproustwwmorgan: _that's_ the only bit that makes sense to me.
23:58wwmorgan,(if (filter even? [1 3]) 0 1) ; sproust: don't let this trip you up either
23:58clojurebot0
23:58sproust,(filter even? [1, 3])
23:58clojurebot()
23:59sproustRight, empty list is true.
23:59wwmorgansproust: not the behavior I was trying to highlight, actually. Not my best example