#clojure logs

2010-12-05

00:09slyrusis there a way to tell leiningen that my project has a dependency without specifying the particular version? e.g. clojure-1.2-or-later or swank-clojure-1.3.0 or later?
00:19technomancyslyrus: you can, but it's almost always a bad idea since you don't know what the future will hold. most projects that work with clojure 1.2 won't work with 1.3.
00:20technomancyanyway, it's in the tutorial.
00:20slyrushrm... grumble grumble... OK, thanks!
00:22slyrusI didn't realize that the clojure 1.3 was going to be backwards-incompatible
00:23slyrusthe old stable vs. evolving language double-edged sword thing...
00:23brehautslyrus: just enough to hurt ;)
00:23technomancyin the case of swank-clojure it's probably safe
00:23technomancysince it won't break anything in production
00:26slyrustechnomancy: I'm confused by your last two comments. What's probably safe? and what is "production"?
00:27slyrusare you saying that 1.2 and 1.3 are de facto incompatible or that some code for 1.2 will need some changes to work with 1.3 but that said code will then continue to work under 1.2?
00:27slyrushrmm... I probably didn't want to use de facto there. but you get the idea.
00:28slyrusit would be nice if folks libraries could continue to be used for both 1.2 and 1.3, right?
00:28technomancydepending on a version of swank-clojure that doesn't exist yet is will probably not cause issues with projects that are in production (live, customer-facing, etc) because swank-clojure is a development tool
00:29slyruswhat, you don't give customers access to the debugger? :)
00:29technomancybut I've seen changes in even bugfix point releases in ruby code that has caused actual data loss in production scenarios because our project pulled in the latest version, assuming it would be safe without much testing
00:29technomancyheh
00:31technomancymany projects that work with Clojure 1.2 will not work with 1.3, but most projects that work in 1.3 will work in 1.2 as long as they don't depend upon primitive support or cross-thread dynamic binding
00:32slyrusyes, this touches a nerve that bothers me about leiningen. You, rightly and justifiably, I'm sure, see it as a way of saying "you need these particular versions of these particular libraries" and providing the infrastructure to go and find those versions. I see it more as "hey, you're going to want some version of these libraries and surely you've already got your own versions of them lying...
00:32slyrus...around your system somewhere, so I'll let you figure out how to tell me where I should find them".
00:34technomancynon-repeatable builds are fine for experimentation but totally incompatible with responsible deployment
00:37pdk`is 1.3 in RC phase
00:41technomancywhat you describe might be nice to have in some circumstances, but repeatable builds are a necessity, so naturally that's where most people are focusing
00:41slyrustechnomancy: in my mind, not having the source for all of the relevant pieces -- and the ability to build thos pieces myself -- is incompatible with responsible development
00:41technomancyare there any Clojure projects that deploy to clojars without source in their jars?
00:42technomancyI'm not aware of any
00:42slyrusI'd rather have my sources in a local git tree than a random jar from some jar repo
00:42slyrusbut, I suppose that's a good point
00:43technomancyas long as slime can M-. to it, it's good enough for me
00:43slyrushrm... not so great for tracking any local changes one might make to it -- not to mention rebuilding a world that contains those changes!
00:44technomancysure; making local changes is what checkout dependencies are for
00:44technomancybut that's an opt-in special case
00:44slyrusI see that as the base case, I guess
00:45slyrusperhaps I should have been at the conj where y'all could have disabused my of silly holdover common-lispisms over a beer or two
00:46technomancyI actually wrote a precursor to Leiningen that would support git checkouts
00:46brehauttechnomancy: any reason it didnt carry over?
00:46technomancyhttps://github.com/technomancy/corkscrew/blob/master/src/cork/screw/deps/git.clj
00:46technomancybrehaut: I guess the main thing is you just couldn't make any assumptions about how the dependent project was structured
00:47slyrustechnomancy: but checking things out with git isn't the problem. it's developing one's libraries/programs in that environment that seems to be more difficult than it should be.
00:47brehauttechnomancy: makes sense
00:47technomancybrehaut: does the presence of build.xml imply "ant" is enough to get a working jar? if so, what is the jar named?, etc
00:48brehauttechnomancy: sounds like a winding garden path of suffering
00:48technomancybrehaut: and you have to support mvn repos anyway, since some java projects are going to be a pain to track down source for, not perform tagging correctly, not be mirrored well, etc.
00:49technomancywho wants to have CVS installed locally just so they can use javamail?
00:49slyrustechnomancy: here's another disconnect between you and me. You see the end result of the build process as a jar (that can be repeatably built). I see it as a running clojure instance with the good bits in it.
00:49slyrustechnomancy: I have no interest in those crappy java projects
00:50technomancyjavamail is actually a really solid library
00:50technomancyI wouldn't have a job using Clojure if it weren't for it
00:50slyrusok, fine, but the point is I want the version control and the dependency management to be separated
00:51technomancyslyrus: you can do a lot to customize the classpath with leiningen plugins
00:51technomancyif you've got some ideas to experiment with, I think it should be doable
00:51technomancyactually most jars on clojars have git-related metadata in them
00:52technomancyso it wouldn't be hard to write a task that says "for all my dependencies that provide repository metadata, check them out and put them on the classpath"
00:52technomancyhttps://github.com/technomancy/leiningen/blob/master/pom.xml#L13
00:53technomancywell I am going to head off
00:54technomancyif you have questions about how such a thing would work, hit up the lein mailing list
00:54slyrusok, thanks for your thoughts
00:54technomancycheers
00:55slyrusindeed. first beer's on me next conj.
02:11rata_I know this is a weird question, but what is the cheapest sequence constructor?
02:11rata_I need to (compare ...) two sequences, but (keys ...) returns a seq that's not Comparable
02:12rata_should I vec it? or list* it?
03:20mister_robotowhen you're running some clojure app "in production", like a compojure web app or something, is it usual practice to leave a REPL running?
05:58fliebelmorning
06:01fliebelI figured there are at least 2 couchdb projects for Clojure. Which one do you recommend? clojure-couchdb appears on top at google, but clutch seems to have a Clojure view server.
06:22fliebelOkay Clutch wins. Though I wonder how it works. Especially how it handles the revision when updating.
06:26DubFishAnyone willing & able to help troubleshoot a Mac 10.5 MacPorts setup?
06:32DubFishHere's what I get:
06:32DubFish% sudo port -R -u -c install clojure clojure-contrib leiningen
06:33DubFish5% lein help install 101205Su111826
06:33DubFishThat's not a task. Use "lein help" to list all tasks.
06:33DubFishException in thread "main" java.lang.IllegalArgumentException: No implementation of method: :make-reader of protocol: #'clojure.java.io/IOFactory found for class: nil (jar.clj:17)
06:33DubFish at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2911)
06:33DubFishI'm hoping this is a well-known issue...
06:34DubFishMac OS X 10.5.8 on a 2006 MacBook Pro (dual-core Intel)
06:34DubFishJava 1.6.0_22
06:35DubFishMacPorts Clojure 1.2
06:41DubFish% lein self-install 101205Su113513
06:41DubFishThat's not a task. Use "lein help" to list all tasks.
06:41DubFish(please ignore right-hand prompt date strings)
06:49ismarcso, from your errors, it looks like lein is installed
07:29fliebelDubFish: lein is on macports?
07:51fliebelHey, isn't there a nice interface I can implement for atom? atom is "final public class Atom extends ARef" so the final means I can't even subclass it, right?
07:58fliebelHrm, so I can't subclass it, and I can't implement the interface, because there is none. But I have a case I think fits the atom model perfectly, but isn't a data structure.
08:00raekfliebel: you can make your own type that behaves exactly as an atom by implementing ARef
08:01raekhrm, swap! and friends are limited to clojure.lang.Atom....
08:02fliebelright
08:02raekfliebel: I'm curious... what are you working on?
08:02fliebelraek: Nothing, but looking at couchdb, it seems to be a prefect fit.
08:03fliebelraek: Normally updating a document involves a revision, which works exactly like compare-and-set!, if the _rev doesn't match, it fails.
08:04raekinteresting
08:04fliebelSo I think it would be easier to get deref to return the value and swap! and compare-and-set! to do the usual spin loop on updating the document.
08:06fliebelraek: Interesting, but impossible with the current implementation of atom.
08:07fliebelI'd have to bring my own swap! IDeref exist though, so @ would work.
08:07raekmaybe you should mention this to rhicket
08:07raek*rhickey
08:08fliebelraek: Do you think atom and friends could get a shiny new interface if I asked him?
08:08raekafter all, there is a very strong semantic match
08:08nickiksombody know ruby? whats not= in ruby?
08:09raekI don't know. but it could be interesting to hear why there isn't interfaces for these things
08:09fliebelnickik: !=?
08:09fliebelraek: Atom is marked final, so maybe he doesn;t want people to toy with it?
08:09raekwell, all the concrete classes in clojure is final
08:10raekbut wherever there is a concrete class, there is usually an interface as well
08:10raeke.g. IPersistentVector and PersistentVector
08:10fliebelraek: Why is that? (and what is the best way to reach rhickey?)
08:10fliebel(the final part)
08:11nickik@fliebel: thanks
08:11aligolehi guys
08:12raekI think there are some issues with subclassing (maybe thread safety?), as clojure as stayed away from it when deftype, defrecord and defprotocol was introduced
08:12raekbut I don't remeber the details
08:12fliebelokay
08:14raekI guess you could post to the mail list (or even the dev mail list, if you have signed the CA), or just hang around and hask him here
08:14fliebelNo CA, but I'll wait for him to make his appearance here.
08:15raekhaving interfaces for the other reference types might be another story
08:15fliebelWhy?
08:15clojurebothttp://clojure.org/rationale
08:15raeksince they have much more intricate semantics
08:16raekit might be hard to find something that has exactly the same semantics as a ref, for instance
08:17fliebelraek: So it's because they're hard to get right?
08:17raekthat is my guess
08:17raekthis is just speculations
08:18fliebelBut say there is a perfect use case for ref just around the corner, it wouldn't hurt to be able to implement it, right?
08:18aligoleCan anyone point me to some sample code or tutorials for some one with Python/C# background?
08:21raekfliebel: refs are entangled with the STM, so there might not be a clear cut interface in that case (this is my guess)
08:22fliebelraek: That would make sense… I think… I'll look at the ref impl
08:22raekatoms are more simple, as they only involve the atom object itself
08:24malky42do you guys know how to defstruct with default values. For example, if I do (defstruct test :arg1 :arg2) how I get arg1 to have a default value of 1?
08:25fliebelmalky42: My guess is using a :or keyword, but I am surely wrong.
08:26raekfliebel: defstruct not destruct... :-)
08:26fliebelraek: Yea, that's why I'm wrong :( Nyway, I think he ought to use records, tight?
08:27raekmalky42: you can store a "default struct" in a var and merge that with a map that the user supplies
08:27malky42raek: okay, I think I play with that.
08:27malky42raek: one thing, do records now supersede structs?
08:28raek(defn make-thing [t] (merge default-thing t))
08:28raekmalky42: records do what structs did, but with even less space
08:29raekbut yes, redords makes them a bit obsolete
08:29mduerksenraek, malky42: you actually have to do a merge-with, otherwise it won't work
08:30raek,(doc merge)
08:30fliebelraek: Can you do destructering in a record?
08:30clojurebot"([& maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping from the latter (left-to-right) will be the mapping in the r...
08:30mduerksenas a struct always has an entry for every key, which can be nil
08:30malky42raek: I haven't really looked at records. I think I'll have to read that chapter before playing with the merge/merge-with. That's a good idea to include defaults -- i hadn't thought of that.
08:30raekfliebel: records are maps.
08:30fliebelraek: yes, yes… wait… hrm...
08:32raekmduerksen: why would one have to use merge-with rather than merge?
08:32mduerksenraek, malky42: the problem with merge is that is is a difference if the key is not present or if the value for the key is nil, which is the case in structs
08:32mduerksen,(merge {:a 1} {:a nil})
08:32clojurebot{:a nil}
08:33mduerksen,(merge-with #(if %2 %2 %1) {:a 1} {:a nil})
08:33clojurebot{:a 1}
08:33raekmy assumption was that the left map was a struct object with all its slots filled
08:34raekand the right map an ordinary map used to override the defaults
08:34fliebelhrm, no destructuring at all in records: #:user.blah{:& 1, :c 2}
08:34mduerksenthe problem is, that a struct always has its slots filled, but some could have nil value
08:34clojurebotnot a problem, the average bid for it on getacoder is $821.00
08:35raekfliebel: ah, you mean in the fields vector? no.
08:35fliebel(is it me, or has clojurebot learnt a lot of new interruptions?)
08:36raekmduerksen: ok, now I see what you meant. if the 't' argument in my function is a struct, then you need to use merge-with.
08:36raekfliebel: the fields become java class fields
08:37raekso you can't have a dynamic number of fields
08:37fliebelI see
08:38mduerksenraek: yes. i ran into that issue just yesterday. the merge-with solution was all i could come up with. maybe there is something more elegant?
08:43killy971Hello. I was looking for some help on "(case ...)" statement generation with macros. I have a "factorial" function and would like to generate "(case 1 1 2 2 3 6 4 24 ...)" until a given value.
08:51raek(defmacro factorial-prime [n] `(case ~@(mapcat (juxt identity factorial) (range 0 (inc n))))))
08:52raekwait
08:55killy971~@ is used to inline a list?
08:55clojurebot@ is splicing unquote
08:56raek(defmacro factorial-cases [x n] `(case ~x ~@(mapcat (juxt identity factorial) (range n)) (factorial ~x)))
08:56raek(defn factorial2 [x] (factorial-cases x 5))
08:57raek,(let [xs [1 2 3]] `(foo a ~x b))
08:57clojurebotjava.lang.Exception: Unable to resolve symbol: x in this context
08:57raek,(let [xs [1 2 3]] `(foo a ~xs b))
08:57clojurebot(sandbox/foo sandbox/a [1 2 3] sandbox/b)
08:57aligoleHey guys! if you have a something like (defrecord Brain [neuron glia]) and you have (defrecord Neuron [id x y]) when you are "instantiating" a new brain is there a way to validate the parameter being passed is a valid Neuron!
08:57raek,(let [xs [1 2 3]] `(foo a ~@xs b))
08:57clojurebot(sandbox/foo sandbox/a 1 2 3 sandbox/b)
08:57killy971ok, I see, thanks. trying the macro
08:58raekkilly971: yes, it buts the elements in the list, rather than the whole thing as one element
08:59raek,(let [x 'x, n 5] `(case ~x ~@(mapcat (juxt identity factorial) (range n)))
08:59clojurebotEOF while reading
08:59raek,(let [x 'x, n 5] `(case ~x ~@(mapcat (juxt identity factorial) (range n))))
08:59clojurebotjava.lang.Exception: Unable to resolve symbol: factorial in this context
09:00killy971,(def factorial [n] (if (zero? n) 1 (reduce * n (range 2 n))))
09:00clojurebotDENIED
09:01raek,(let [x 'x, n 5, factorial #(reduce * (range 1 (inc %)))] `(case ~x ~@(mapcat (juxt identity factorial) (range n))) (factorial ~x))
09:01clojurebotjava.lang.IllegalStateException: Var clojure.core/unquote is unbound.
09:03raekaligole: a very common solution is to not force the users to call the Neuron constructor themselves, but provide a function like (defn make-neuron [...] ...) that can do validation, etc
09:04raekwith this approach, you can change the number of fields (as well as the ordering), without having to rewrite all code that makes instances
09:05raekuser=> (let [x 'x, n 5] `(case ~x ~@(mapcat (juxt identity factorial) (range n)) (factorial ~x)))
09:05raek(clojure.core/case x 0 1 1 1 2 2 3 6 4 24 (user/factorial x))
09:05raekkilly971: ^
09:05killy971yes?
09:05killy971looks perfect!
09:06killy971thank you very much
09:08aligoleraek: thanks, I am still in non-clojure/lisp way of thinking,
09:18aligoleraek: if I don't care about concurrency, can I just ignore about all the immutability and just use everything as I used to do in other languages?!
09:19raekno :)
09:19raekthe data structures in clojure are immutable
09:20raekthey are defined that way, so you can't change it
09:21RaynesYou could always just use Java collections, but that would be kind of silly.
09:21nickik@aligole you could but it would be really ugly code because you had to use refrencetypes everywhere.
09:21Rayness/kind of/extremely/
09:21sexpbot<Raynes> You could always just use Java collections, but that would be extremely silly.
09:21aligole:) I mean, can I think like they are not! and use set! and go ahead? or let me put it like this, programming is all about changing the value og variables if I try to keep the variables constant how I could solve the problem!
09:21raekaligole: clojure is a functional programming language. that means that much (most?) of your code takes some values and calculates new new values (without changing the old ones)
09:23raekthere are of course thing that can change, but those are separated from the datastructures themselves
09:23nickikaligole, sure you could but why would you learn clojure in the first platz. If you want that common lisp or python would be a better fit.
09:23nickik*platz place
09:24nickiki used the german word :)
09:24raekI think clojure is a great language even if you don't use the concurrency bits
09:25aligoleI know that and I have very limited functional programming experience (a couple of arc functions!) but can you guys point me to some code that solves a regular problem in clojure? I am not objecting I just want to learn the new way of thinking!
09:26nickik@not using concurrency and doing everything non-FP is not the same. You can do FP without concurrency
09:27nickik@aligole, define regular problem :)
09:27Raynesnickik: You know, IRC isn't twitter. :p
09:27raekaligole: what programming languages are you accustomed to?
09:28Raynesnickik: Just prefixing a message with someone's nick name is enough to make their clients beep or taskbar icon flash or something similar. You don't need the @.
09:29aligoleLike I want to read some data from disk visualize them for the user and let the user manipulate them and save them back to disk!
09:29nickikI know that now but I only learnd that and I do it atomaticly
09:30raekthere are different kinds of side-effects. one could be file IO, updating the UI etc. the other kind is changing data structures. Clojure is only picky about the second one...
09:31aligolenickik: now that I expressed the problem it seems clear that it could be done in a functional way, but I am too used to having global variables that I need to practice to the new ways!
09:31raekaligole: Clojure as a family of "reference types" that let you have things that change over time (e.g. things that the user can modify)
09:31raekone of them is the atom
09:32nickikagree, in this case an atom would could hold the changes
09:33raekthe reference types are updated by giving them a function
09:33raekthe function takes the old value (plus any extra args) and returns the new value
09:34nickikread in the file and convert it to a clojure data (line-seq) then save that in an atom and provide a sean API to change that data and when you are finished convert the atom back to a file
09:34nickik*sean sane
09:35raekaligole: this is a gold mine of clojure videos: http://alexott.net/en/clojure/video.html
09:36raekI especially recommend http://vimeo.com/10896148 and http://vimeo.com/8672404
09:36nickik@Raynes I'm trying to get someone to learn clojure and you last blogpost almost threw him over the cliff. :)
09:37nickikdamn, did it again :)
09:37aligolethat is cool! I need to actually try it to learn it.
09:37aligolethanks guy
09:37Raynesnickik: Hehe. I'm going to assume "threw him over the cliff" is a good thing in this case. :<
09:37Raynes:>*
09:39nickikRaynes, it is if the cliff is indefinitely high
09:39Raynes:p
09:42nickikaligole, look at http://clojure.blip.tv/posts?view=archive&amp;nsfw=dc for you the Clojure for Java Programmers videos would be best. (java meaning not lisp or FP)
09:42Raynesnickik: You're talking about the build tool introductory post, right?
09:43RaynesMy last post was about sexpbot.
09:43nickikthe one about sexpbot
09:43RaynesOh. He likes sexpbot? :o
09:43nickikhe wanted to write one anyway
09:43clojurebotI don't understand.
09:46Raynessexpbot is my favorite project just because I have gotten at least three people into Clojure just by giving them sexpbot as a project to contribute to and write plugins for.
09:46nickikI showed him your post and he twitter me back that that would almost be sufficiently cool to start learning clojure
09:47RaynesIt's very low-barrier-to-entry stuff, and they get to see it in action and use their plugins in a tool they use everyday as it is.
09:48nickikIl be sure to tell him that
09:49fliebelRaynes: I can vouch for that. Though started Clojure before sexpbot even existed, I ping everyone I have the slightest reason to :)
09:49Raynesfliebel: :p
09:49Raynesfliebel: You'll be happy to know that several people in unrelated channels find that little tidbit of functionality neat as well.
09:53fliebelI seem to have a tendency to write incredibly useful stuff that takes very few lines. Only problem being that I don't dare asking €300 for this kind of things. (seriously, a friend told me about a twitter tool that's being sold for that price that would be a one liner to make)
09:53nickikWe do people need tools for twitter?
09:54nickikI mean wtf browse read write something if you want. What tooling is required?
09:54fliebelnickik: Marketeers need them. To spam people and to follow hash tags and manage things...
09:55nickikok, valid point
09:55fliebelnickik: The tool in question monitored a Dutch hash tags for questions + a subject, and mailed you the questions, so you could make a good impression to people with related problems without scanning twitter manually.
09:57p_l|homenickik: trend tracking, use of twitter as automated information transport (with bots twittering and bots receiving), things like that
10:06fliebelhttps://github.com/pepijndevos/Twemail Would be lovely to have that in Clojure. Twisted is rather painfull.
10:11jamesnvcHello
10:11edwIn SLIME, I never get local vars in the backtrace. Is there a way to get them to show up?
10:12jamesnvcQuestion: What does "Pop without matching push" mean in the context of agents & atoms?
10:13nickiknot sure but the idea in FP is that you cant have mutable data so you can not use the usal pop and push that cange the stack.
10:14BahmanHi all!
10:14jamesnvcHrm...I think it may be due to me somewhat-abusing agents
10:15nickikWe us peek (top) to look at the first thing and pop to return the rest of the stack without changing the stack
10:15nickikdon't just build a normal stack with ref-types
10:16nickiki had that same question to and im not sure how to think about stacks atm
10:17jamesnvcI don't have any explicit stacks here
10:17jamesnvcAlthough I think I might be doing something wrong
10:18jamesnvcI basically have a bunch of agents wandering around a grid, when the encounter another agent, one of them "kills" the other by sending it a "die" message
10:18jamesnvcThe "pop w/o push" happens when it receives the die message
10:19nickikmhh
10:19jamesnvc(related: In order to have the agents repeatedly get called so they wander, I put a watch on each agent, which re-sends the move message. Not sure if that's idiomatic…)
10:21nickikwhy is not every element of your grid a ref? Then you could build some functions like move.
10:22jamesnvcI actually do have that, but I want the agents to maintain their own state
10:22jamesnvc(this is a proof-of-concept for something bigger, that will require each agent to carry around it's own position, &c)
10:23nickikso you have a map or a record in the agent
10:23jamesnvcCorrect
10:24jamesnvcThis is the nub of it: https://gist.github.com/729167
10:24nickiki don't see the use of agents because you could change the state of the record everytime you do a move
10:25__name__hi
10:25jamesnvcI'm using agents because I want to ultimately have potentially hundreds of independent units moving and doing their own thing
10:26nickikhallo
10:26__name__Am I mistaken that there's no lambda in Clojure?
10:26jamesnvc__name__: lambda = fn
10:26nickikthe lambda is justed named fn because that easyer for most people
10:26__name__Ah.
10:26__name__Fair enough :)
10:28nickikjamesnvc, I not sure i can help you because my lack experience
10:29__name__Thank you a lot, jamesnvc and nickik.
10:29nickikbut i can point you to a programme that is somewhat simular
10:29nickikhttp://clojure.googlegroups.com/web/ants.clj?gda=QaGDPzoAAAC_UdR48ERSha0tJ0UgPmyf3cnWebOqkFTyQwG7RLaV5e9OU0NQiFWgQuhmPR7veGf97daDQaep90o7AOpSKHW0
10:29jamesnvcnickik: EXcellent, thanks a lot!
10:32__name__Is there anything comparable to zip? (zip '(1 2 3) '(4 5 6)) => ((1 2) (2 3) (3 4))
10:33nickik(doc zipmap)
10:33clojurebot"([keys vals]); Returns a map with the keys mapped to the corresponding vals."
10:33nickik&(zipmap [1 2 3] ["1" "2" "3"])
10:33sexpbot⟹ {3 "3", 2 "2", 1 "1"}
10:34__name__wait, that's not the same thing.
10:34nickiki see
10:34nickikthat if you want a map
10:34nickik&(partition 2 (concat [1 2 3] [4 5 6]))
10:34sexpbot⟹ ((1 2) (3 4) (5 6))
10:35nickikmaybe there is something better but im not sure
10:35nickikin cases like this maps are normaly better
10:41lyonscfhey guys. :)
10:41nickikhallo
10:41ckynickik: But, like, maps aren't order-preserving, as your example showed.
10:41ckynickik: Real zip is. :-P
10:42nickik(doc orderd-map)
10:42clojurebotPardon?
10:42ckynickik: How do you make zipmap generate one of those?
10:42nickik(doc sorted-map)
10:42clojurebot"([& keyvals]); keyval => key val Returns a new sorted map with supplied mappings."
10:42__name__&(map (fn [x y] (x y)) '(1 2 3) '(2 3 4))
10:42sexpbotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
10:43__name__&(map (fn [x y] (list x y)) '(1 2 3) '(2 3 4))
10:43sexpbot⟹ ((1 2) (2 3) (3 4))
10:43__name__Now just for an arbitrary length of arguments.
10:43cky__name__: :-D
10:43ckyYou just want SRFI 1-style zip, dontcha. :-P
10:44__name__SRFI?
10:44__name__I want Python style zip and zip_longest :)
10:44cky__name__: It's a Scheme thing. http://srfi.schemers.org/srfi-1/srfi-1.html
10:45__name__cky: I am pretty new to Lisp, so please all bear with me :)
10:45ckyAll the SRFI 1 functions that take multiple lists use the shortest list as the length to process. That way, you can pass in circular lists for all but one, for example.
10:46nickikyou have to write it yourself (its easy enougth) or use a sorted-map
10:46__name__cky: Yeah I want that and zip for the longest with padding :)
10:46ckynickik: :-P
10:46mduerksen,(doc partition-all)
10:46clojurebot"([n coll] [n step coll]); Returns a lazy sequence of lists like partition, but may include partitions with fewer than n items at the end."
10:47nickik&(apply sorted-map [[1 2 3] [4 5 6]])
10:47sexpbot⟹ {[1 2 3] [4 5 6]}
10:47nickikmmh
10:48nickik&(sorted-map [1 2 3] [4 5 6])
10:48sexpbot⟹ {[1 2 3] [4 5 6]}
10:49lyonscfHey guys, I have a question about clj-time
10:50lyonscfIt says use (now) to get a current date-time
10:50lyonscfin the docs
10:50nickik&((fn [& coll] (partition (count coll) (concat coll) )) '(1 2 3) '(4 5 6) '(7 8 9))
10:50sexpbot⟹ (((1 2 3) (4 5 6) (7 8 9)))
10:50lyonscfand that fails when I make the call
10:50lyonscffor example
10:50lyonscf(def cur-date (date-time now))
10:51lyonscfdoesn't work
10:51lyonscfany ideas what's going wrong?
10:51nickik&((fn [& coll] (partition (count coll) (apply concat coll) )) '(1 2 3) '(4 5 6) '(7 8 9))
10:51sexpbot⟹ ((1 2 3) (4 5 6) (7 8 9))
10:51nickiklyonscf, have you included it?
10:52lyonscfnickik: yea
10:52lyonscfI think i figured it out
10:52lyonscfI shouldn't be doing (date-time now)
10:52lyonscfand only (now)
10:52lyonscfand that will return the current date-time
10:53lyonscfyup, that's it
10:53lyonscfthanks anyway. :)
12:00kzarinit-clojure.el seems to enable paredit-mode for the REPL in Emacs, I don't mind but then how do you enter a new line without evaluation? (It forces parenthesis to match so every time I press Enter the REPL thinks my statement is finished)
12:07stuartsierratry C-j
12:07kzarstuartsierra: Oh sweet thanks
12:08__name__&(map (fn [& rest] rest) '(1 2 3) '(2 3 4) '(4 5 6))
12:08sexpbot⟹ ((1 2 4) (2 3 5) (3 4 6))
12:08__name__\o/
12:09raek__name__: you can use the 'list' function too
12:28rata_hi
12:28kzarhey
12:32cky&(map list '(1 2 3) '(4 5 6) '(7 8 9))
12:32sexpbot⟹ ((1 4 7) (2 5 8) (3 6 9))
12:33cky&(map list '(1 2 3) '(4 5 6) '(7 8 9 10))
12:33sexpbot⟹ ((1 4 7) (2 5 8) (3 6 9))
12:33cky&(map list '(1 2 3 42) '(4 5 6) '(7 8 9 10))
12:33sexpbot⟹ ((1 4 7) (2 5 8) (3 6 9))
13:09__name__raek: Thanks
14:20thruspaHi, may I ask a totally newbie question?
14:22raeksure... go ahead!
14:27wyrgJust a question.
14:27wyrgI type in clojure "Math/Pi" and it fails with "Unable to find static field".
14:28raekwyrg: all the letters in PI should be capital...
14:28wyrgOh, thanks.
14:28raek&Math/PI
14:28sexpbot⟹ 3.141592653589793
14:28wyrgThe problem really is with:
14:29wyrgjava.awt.GraphicsEnvironment/getLocalGraphicsEnvironment
14:29wyrgsame error.
14:29lyonscfHey guys, does anyone have any experience with webmine?
14:29wyrg&java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment
14:29sexpbotjava.lang.Exception: Unable to find static field: getLocalGraphicsEnvironment in class java.awt.GraphicsEnvironment
14:29lyonscfclj-sys/webmine that is. :)
14:30raekwyrg: do you have parens around it?
14:30wyrgI will try...
14:30raek&(java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment)
14:30sexpbot⟹ #<HeadlessGraphicsEnvironment sun.java2d.HeadlessGraphicsEnvironment@4f7dc0>
14:31raeksince it's a method, you need to call it
14:31wyrgI see.
14:31wyrgThank you very much!
14:31wyrgI'm just starting with LISP.
14:31raeknp
14:34p_l|homewyrg: please avoid using the name LISP (with all caps). It refers to language that probably was used before you were born :P
14:34RaynesHaha.
14:34RaynesI've always wondered why people still write that word in all caps.
14:35p_l|homeRaynes: bad College courses
14:35RaynesAFAIK, even McCarthy doesn't anymore.
14:35p_l|homeand FUD on the net
14:35p_l|homeRaynes: McCarthy asked everyone not to name their languages just "lisp", no matter what case :)
14:36wyrgThank you. As I said I'm new to clojure, so I think I will absorb the nuances little by little :-)
14:37RaynesBut it's so much easier to shove them down your throat and be done with it! ;p
14:38RaynesThat explains the vocalness about not using writing Lisp in all caps.
14:39p_l|homeRaynes: well, Clojure has the difference in name, Common Lisp gets all the wackos attracted to "LISP" -_-;
14:39Raynestechnomancy: ping
14:40Raynesfliebel: Make ping case insensitive and take an optional period at the end so that I can make use of it while still looking like a grammar Nazi.
14:47p_l|homeRaynes: better, make it into a command language capable of looking like english sentences
14:47p_l|home(both easier and harder than it sounds)
14:59rata_chouser: what would be a good comparator fn for counted-sorted-sets to store maps? how is the comparator fn used there?
15:11firepoetHey all.. Java interop question...
15:13firepoetI have a function: (defn -editCardWithAction [this user board-id card-id actions]
15:13firepoet (let [action-blocks (.split actions ";")]
15:13firepoet (do
15:13firepoet (.info logger (str "edit card with: " (alength action-blocks)))
15:13firepoet (map #(.info logger (str "perform card action: " %)) action-blocks))))
15:14firepoetAnd when I run it in a repl this way, I get: com.pegby.service.clj.boardUpdate=> (-editCardWithAction nil "test" "test" 123 "first: something; second: else; third: stuff")
15:14firepoet0 [main] INFO com.pegby.service.clj.boardUpdate - edit card with: 3
15:14firepoet7 [main] INFO com.pegby.service.clj.boardUpdate - perform card action: first: something
15:14firepoet7 [main] INFO com.pegby.service.clj.boardUpdate - perform card action: second: else
15:14firepoet7 [main] INFO com.pegby.service.clj.boardUpdate - perform card action: third: stuff
15:14firepoet(nil nil nil)
15:14rata_firepoet: use gist.github.com
15:15firepoetOh sorry.
15:18firepoetSo the gist is: https://gist.github.com/729428
15:18firepoet:-)
15:18raekfirepoet: also, you should use doseq (or something similar) instead of map if you only care about the side-effects of the function
15:18firepoetAh
15:18raekfirepoet: what was the question? :-)
15:18firepoetThere was a time when I cared about the result as well.
15:19firepoetAt least for testing, since some of the functions actually return stuff I care about.
15:19firepoetSo the question is why it doesn't seem to be calling the map function at all..
15:19firepoetBut only when I compile the clojure code and run it as a Java class.
15:19firepoetWorks great on the REPL.
15:20raekfliebel: that is because the repl will print, and therefore force, every element of the sequence map returns
15:21raekthe function will only be ivoked when elements are forced
15:21firepoetOhh.
15:21_atoif you care about the return value and also want to force the lazyseq: wrap the map call in (doall ...)
15:22firepoetLazy sequences to the rescue!
15:22firepoetGreat..lemme test..
15:24firepoetSo is doall supposed to throw an NPE if the result is a seq of nils?
15:25firepoet(you can tell I'm a java programmer trying to learn clojure.. hehe)
15:26LauJensenMorning all :)
15:26firepoet_ato: I tried your suggestion, and it got further, but is now throwing a NullPointerException
15:27lyonscfWhat's the best way to debug clojure? Can anyone point me in the right direction? :)
15:27lyonscfI'm using emacs and swank-clojure
15:29fliebelRaynes: Another regex change? Sure. Want a commit, or can I tell you right away how to change the regex?
15:29fliebelraek: Was that message for me?
15:30fliebelrhickey: ping
15:32rata_lyonscf: I use swank-clojure to debug
15:32rata_just write (swank.core/break) where you want to know the value of locals
15:32lyonscfah
15:32firepoetGreat.. I worked through those issues and am now on to a new one. Thanks for your help!
15:32lyonscfawesome
15:32lyonscfhave any useful links?
15:33rata_lyonscf: http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml
15:34firepoetNew question: Is there anything special I have to to do to make the resolve function find things properly when I'm compiling to a Java class? I'm finding that (resolve (symbol str)) works great in the REPL, but not when compiled.
15:35firepoet(as in, it returns nil when compiled)
15:35lyonscfrata_: thanks. :)
15:37fliebelRaynes: The regex already works for a dot at the end, or a question- or exclamation mark even. You could do [pP]ing though if you want to be able to look like a grammar nazi. I guess you don't want to support PiNg in that case.
15:41rata_is it guaranteed that (= (seq m1) (seq m2)) if (= m1 m2), where m1 and m2 are hash-maps?
15:42firepoetSo my new question: https://gist.github.com/729449
15:48rata_why sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run() takes so much time when I profile a clojure app with visualvm?
15:51__name__Is there a map that runs until the longest item is exhausted, supplying a default argument for the ones that are already exhausted?
15:51rata_so many questions I have
15:52rata___name__: you can (concat s (repeat default-argument)) your shorter seqs
15:52kevinjqhello everyone. wondering why protocol cannot be used in `derive`. e.g., (defprotocol bar (method1 [])) then (derive bar ::quux), i got error msg: java.lang.AssertionError: Assert failed: (or (class? tag) (and (instance? clojure.lang.Named tag) (namespace tag))) (NO_SOURCE_FILE:0)
15:52hiredman,(map vector (concat [:a :b] (cycle [:default])) (range 10))
15:52clojurebot([:a 0] [:b 1] [:default 2] [:default 3] [:default 4] [:default 5] [:default 6] [:default 7] [:default 8] [:default 9])
15:52__name__Then I will need to know the length of the longest.
15:53rata___name__: no, you just need to know which one is the longest
15:53hiredmankevinjq: just like the exception says, not a class of a named thing
15:53__name__Fair enough, rata_
15:54hiredman__name__: do you see my map?
15:54__name__hiredman: Yes.
15:54kevinjqhiredman, yes, i know, but i'm wondering why clojure doesn't let protocol be an acceptable arg in derive?
15:55__name__hiredman: But then I need to know the longest. Still, thanks!
15:55hiredmankevinjq: why would they be?
15:56kevinjqhiredman, protocol, as clojure doc says, is similar to java interfaces. if you return java interfaces when you call (ancestors some-type), then why shouldn't interfaces allowable in (derive ...)?
15:57hiredmankevinjq: similar is not the same, that still doesn't seem to be a compelling reason
15:58kevinjqhiredman: well, actually, protocol is implemented under the hood as a java interface... the compelling reason is, when you call (ancestor (type []), it returns all the superclasses as well as interfaces that a persistent vector implements
15:59kevinjqwhy should protocol be different?
15:59hiredmankevinjq: just because X can be optimized as Y it does not mean that X has the same semantics as Y
16:01kevinjqthat's not reasoning
16:01firepoet*sigh* guess I hit an un-solveable one.
16:01hiredmanit is
16:01hiredmanyou are saying "protocols can be optimized as interfaces for some cases, so they should behave the same as interfaces"
16:02rlbchouser: wrt managining sub-commands and pipelines, could it make sense (for now) to just require you to provide a "context" -- i.e. something like (exec context "find" "/" ...). The scope of "context" would restrict the related process(es) resource lifetime(s).
16:03raekfliebel: 21:30 < fliebel> raek: Was that message for me? <-- which one?
16:03kevinjqhiredman, the main reason i wanted to use protocol in derive, is that i want to use it for multimethods. e.g., i have protocol foobar, and i have a record (which implements Map), then i want the dispatch simply be (derive foobar ::my-type), (derive java.util.Map ::my-type) and in (defmulti mymethod class) (defmethod mymethod ::my-type [] "blah blah")
16:03rlbSo you might have something like (with-process-context context ... set-up-and-use-commands-here)
16:04hiredmankevinjq: protocols don't create is-a relationships, so using them for type dispatch is not a good idea
16:04hiredmanprotocols are not interfaces
16:04firepoetHa! Figured it out. Java object methods aren't invoked in the same namespace as the other functions declared therein. Craziness.
16:04kevinjqhiredman, what do you suggest in this case?
16:05firepoetns-resolve to the rescue
16:06raekfirepoet: do you need to construct the symbol from a string?
16:06hiredmankevinjq: *shrug*
16:06firepoetYeah.
16:06kevinjqhiredman, you keep saying protocol isn't interface, then do you mind sharing your vision of what protocol really is?
16:07firepoetraek: I figured it out. Replaced resolve with ns-resolve and all was well.
16:07firepoetraek: the function name is derived from something a user sends in an email
16:08hiredmankevinjq: there are a number of videos on the web
16:08vIkSiTlo all
16:08kevinjqlol
16:08hiredmanthere is the protocol page on clojure.org
16:08vIkSiTwhats the best method to have a function running as a background thread (for instance, a file tailer)?
16:09raekyou can use future or future-call to start off something in another thread
16:09vIkSiTah future-call.
16:09vIkSiTgreat, thanks
16:09vIkSiTlet me experiment
16:09kevinjqhiredman, i read it. the reason for protocols are to provide abstraction/contracts, which is exactly what java interfaces are for
16:10hiredmankevinjq: again, just because two thigns are aimed at solving the same problem is does not mean they are the same
16:11hiredmanyou obvisouly read up the point where you saw the word interface and said "oh, right, it's and interface" then tuned out
16:12kevinjqhiredman, i read the whole thing, thank you very much ... i keep asking what's your interpretation of clojure protocol and you keep pointing me to other resources
16:13hiredmankevinjq: because in my opinion those other resources explain it better than I can, and if you don't get it from there I don't see how you can be made to understand
16:14hiredman~google stuart halloway expression problem
16:14clojurebotFirst, out of 516 results is:
16:14clojurebotClojure 1.2 Protocols on Vimeo
16:14clojurebothttp://vimeo.com/11236603
16:15hiredmanchouser actually has a video on infoq where he discusses protocols vs. multimethods
16:17kevinjqhiredman, thanks anyway
16:17vIkSiTraek, hmm, couple of questions about futures and threads if you've got a minute
16:18vIkSiTthis is the function i'm using to tail a file: http://paste.lisp.org/display/117361
16:18vIkSiTbecause of the Thread/sleep and recur, whenever I use this function in somehting like (doseq [line (tail-seq filename)] ... )
16:19vIkSiTeven with a future-call, the REPL basically gets taken over by this function and its output
16:19vIkSiTwould i have to use an agent to perhaps run this in the background?
16:21vIkSiT(or anyone else have an idea about this issue?)
16:22__name__Does Clojure have the concept of iterators and if so, could you link me to resources about it?
16:23hiredmansequences are a functional interation cosntruct
16:24__name__So I have laziness instead of iterators?
16:24vIkSiThmm, so a different question. lets say i've got a function that generates random numbers and prints them.
16:24vIkSiTa future would only run this function once - as opposed to keep it running in the background?
16:25hiredman__name__: not all sequences are lazy
16:27jamesnvcHello
16:28jamesnvcQuestion: Is there any reason why *agent* is suddenly turning nil, ina function that is only ever called by being sent to an agent?
16:30hiredmanjamesnvc: sounds like you just switch to clojure 1.3
16:31jamesnvcYup
16:31jamesnvc1.3 has issues with that?
16:31hiredmanthe binding propagation stuff screws up *agent*, there should be a issue in jira for it
16:32stuartsierrait's fixed on master
16:32jamesnvcAlright
16:32jamesnvcUm, if I'm using leiningen, is there any easy way to get that on master?
16:32jamesnvc1.3.0-SNAPSHOT?
16:33hiredmanjamesnvc: you have to wait for a snapshot build of master +/- a day
16:33bmhIs anyone else having trouble with clojars?
16:33jamesnvchiredman: Thanks
16:34bmh(looks like the problem is on my end)
16:36RaynesIn that case, no.
16:38rata_does anybody know why sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run() takes so much time when I profile a clojure app with visualvm?
16:40raekvIkSiT: you have to do the looping manually. future and future-call only evaluate the body / calls the function once
16:40vIkSiTraek, hmm. so basically a Thread/sleep and recur within the function?
16:41raekyes
16:41vIkSiTraek, I see. so would you recommend an agent for something like this, given their watch/error handling capabilities?
16:41stuartsierraLazytest.next https://github.com/stuartsierra/lazytest/tree/next
16:42raekvIkSiT: if you have a state you want to serialize access to, I'd go for agents
16:42vIkSiTor, what are the best practices for the creation of a long running background thread?
16:42vIkSiTraek, ah
16:44raek'future' just starts a new thread and gives you a handle to it, which can be used to get the last expression of the future body / the result of the function, check if it has finished, etc
16:45chjameshelp
16:45raekvIkSiT: when you doseq over that lazy sequence, you don't return until you have processed the *whole* sequence
16:45raekbut putting the doseq call in a separate thread should not block the repl thread
16:47vIkSiTraek, aah. I understand the issue here. however, I'm not sure how to modify it in a way that will read one line and return that line then?
16:47raekvIkSiT: futures also have error handling capabilities
16:48raekderef/@ will throw the exception (wrapped) that the body threw
16:48vIkSiTah I see
16:49vIkSiT(or the return value, I take it)
16:49raekwhat is the problem you are solving?
16:49raekwhat do you want to do in a separate thread?
16:49vIkSiTraek, i've got a file i want to tail in the background
16:50vIkSiTthat i want to keep running unless i explicitly want to stop it
16:50vIkSiTfor each new line in the file, i'd like to process it in some way
16:50raekone way could be to doseq over the lines in another thread
16:51vIkSiThmm
16:51vIkSiTperhaps wrap tail-seq into another thread?
16:51raekstepping through the sequence might block, but that would be ok if it happens in a background thrad
16:51raekthen what should the thread that waits for the next thing do?
16:52vIkSiTraek, id like it to call another function with the new line as a param.. (def myfn [newline] (process-line newline) (.. do more stuff ..))
16:52raekyou could also consider using java.util.concurrent.LinkedBlockingQueue to build your app in a producer-consumer way
16:53vIkSiTraek, i'm using the lamina project's channels to do that
16:53raek(future (doseq [line (tail-seq ...)] (process-line line))) ?
16:54raeklazy sequences are "pull driven"
16:54vIkSiThmm
16:54jamesnvcStupid question, but how do I get the 1.3.0 master in leiningen? 1.3.0-master-SNAPSHOT?
16:55vIkSiTah
16:56vIkSiTraek, that seems to work! now to see how to stop that :)
16:56stuartsierrajamesnvc: it's mis-versioned now as 1.3.0-alpha3-SNAPSHOT I think
16:56jamesnvcstuartsierra: Cool, thanks
16:57vIkSiTraek, for instance, i get this : http://paste.lisp.org/display/117361#1
16:57vIkSiTin the background, things work fine. but i'm guessing i can't stop the future unless i'd wrapped the doseq in a function and called (future-cancel myfn)
17:00vIkSiTraek, hmm this is the weird part.
17:00vIkSiTif i wrap that in (defn myfn [] ...) and then (future-call (myfn filename))
17:00raekvIkSiT: you need some way of telling it to stop. future-cancel will interrupt the thread, which will abort an ongoing sleep call, causing it to throw an InterruptedException
17:00vIkSiTthe REPL thread still bocks on it.
17:00raekblocks on the future call?
17:00vIkSiTpasting..
17:01vIkSiTraek, http://paste.lisp.org/display/117361#2
17:02raekvIkSiT: replace future-call with future
17:03raekfuture-call takes a function. you try to give it the result of invoiking tailfn
17:03raek(future <body>) is just sugar for (future-call (fn [] <body>))
17:05vIkSiTinteresting. if i put a (future (..)) within the function body
17:05vIkSiTit works as expected
17:05vIkSiTperhaps there's a difference in the way future and future-call work
17:05vIkSiToh i see.
17:10rata_does anybody know why sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run() takes so much time when I profile a clojure app with visualvm?
17:21rata_is there a number for infinity in clojure?
17:22fliebel rata_: No ##(/ 1 0)
17:22sexpbotjava.lang.ArithmeticException: Divide by zero
17:22bmhrata_: Double has NEGATIVE_INFINITY and POSITIVE_INFINITY
17:22rata_thanks =)
17:23fliebelbmh: What's inside it?
17:23bmhfliebel: 0x7ff0000000000000L http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html#NEGATIVE_INFINITY
17:23bmhand 0xfff0000000000000L
17:33__name__Comments and constructive criticism appreciated: http://bpaste.net/show/12026/
18:40cky&(map (fn [op] (op Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY) `(,+ ,/))
18:40sexpbotjava.lang.Exception: EOF while reading
18:40cky&(map (fn [op] (op Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)) `(,+ ,/))
18:40sexpbot⟹ (-Infinity -Infinity)
18:41cky...I must be doing something wrong.
18:41cky&(+ Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)
18:41sexpbot⟹ NaN
18:41cky&(/ Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)
18:41sexpbot⟹ NaN
18:41ckyThere, that's better. :-D
18:41cky&`(,+ ,/)
18:41sexpbot⟹ (clojure.core/+ clojure.core//)
18:42cky&(map (fn [op] (op 2 5)) `(,+ ,/))
18:42sexpbot⟹ (5 5)
18:42tonylwhy the commas
18:42ckytonyl: They're unquotes.
18:43cky`(+ /) is the same as '(+ /): two symbols in a list.
18:43tonyloh, I thought it was only whitespace and ~ was to unquote
18:43cky`(,+ ,/) is a list with two function objects.
18:43ckyHmm, maybe you're right.
18:43cky`(~+ ~/)
18:43cky&`(~+ ~/)
18:43sexpbot⟹ (#<core$_PLUS_ clojure.core$_PLUS_@1ba24d5> #<core$_SLASH_ clojure.core$_SLASH_@b48593>)
18:43ckyAh, much better.
18:44ckytonyl: Thanks. :-)
18:44cky&(map (fn [op] (op Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)) `(~+ ~/))
18:44sexpbot⟹ (NaN NaN)
18:44cky\o/
18:44tonylnp
18:44cky(Old Lisp habits have a way of sticking around. :-P)
18:45tonylwhat does the comma mean in old lisp? I am new to lisp
18:45ckytonyl: In traditional Lisp, comma is unquote.
18:45tonyloh
18:46ckyLet's try one more thing....
18:46cky&`(1 2 ~@(map - '(1 2 3)) 3 4 5)
18:46sexpbot⟹ (1 2 -1 -2 -3 3 4 5)
18:46cky\o/
18:47ckytonyl: In traditional Lisp, ,@ is "unquote-splicing". Glad to see that ~@ works the same way here.
18:48tonylyeah, i wasn't aware of the change in lisps, did ~ meant something else in other lisps?
18:49ckyI don't think ~ has any special meaning in other Lisps. At least, not in Scheme.
18:49rata_lets inside a fn are compiled as ns$fn-name$fn_xxx?
18:49hiredmanrata_: no
18:49tonylcky: a little more info if you want http://clojure.org/reader
18:50ckyThanks! Hopefully the info will stick this time. :-)
18:51rata_*ns$fn-name$fn__xxx?
18:51rata_or are fors compiled as ns$fn-name$fn__xxx?
18:52ckytonyl: O_o Wow, apparently viewing that page on w3m (a least on Ubuntu 9.10) causes a segmentation fault.
18:54tonylwow, let me try it
18:54rata_how are lets compiled?
18:55tonylcky: it worked in my machine (ubuntu 10.10) but it took a couple of mins
18:55ckyI searched for "unquote" (which found the first instance successfully). Pressing "n" to find the next instance caused the segfault.
18:56ckyIt doesn't happen every time, but I've managed to replicate it 3 times.
18:56tonyloh weird
18:56cky...yeah. I must try upgrading to 10.10 and see where I get.
19:25DietCokeIsMyBloocan someone clarify the difference between the rem and mod operators
19:28tonylI think the only difference that mod truncates toward negative infinity
19:30DietCokeIsMyBlooi saw that, but i don't know what that means
19:32tonylmod uses rem and checks for the result and if it is zero or the multiplication of the 2 numbers passed to it is positive it would return the value
19:32tonyl$source mod
19:32sexpbotmod is http://is.gd/igoOF
19:34DietCokeIsMyBloook.
19:34DietCokeIsMyBloo i think i got it
19:34DietCokeIsMyBloodanke :)
20:18DietCokeIsMyBloogot another question
20:19DietCokeIsMyBlooit's a recursion qustion
20:19DietCokeIsMyBloowhat's happening in line 3
20:19DietCokeIsMyBloohttp://codepad.org/QQRU8Gqp
20:20DietCokeIsMyBloois that way you go from a fxn with a single variable to 2? or is there some annonymous function stuff going on?
20:46tomojDietCokeIsMyBloo: basically, it's defining a default value for the acc parameter
20:46tomojwhen you call factorial-2 with one arg, it's n
20:46tomojthen it calls itself with 1 and your n
20:47tomojso you can either call factorial-2 passing in acc and n (the two-arg version), or if you just pass n, acc will be 1
20:47DietCokeIsMyBlooi get that part.. like what's it doing.. do i need to worry about the how thogh?
20:47tomojthe how is simple, it just calls itself
20:48tomojthe function is called factorial-2
20:48tomojon line three you see just a function call to factorial-2, passing in 1 and n as args
20:48DietCokeIsMyBlooso on line 7- when it recurs, what happens?
20:48tomojthe one-arg version of the function is just calling the two-arg version of the function
20:49tomojthen, the two-arg recurs to itself
20:49tomojsay you pass in acc 1 and n 3
20:49DietCokeIsMyBlooit seems wierd though- you're defining a fxn with one param, then saying turn into 2 param.... do stuff, and recur with the 2 param
20:50DietCokeIsMyBlooat which point, it calls the fxn which takes 1 arg
20:50tomoj3 isn't equal to 1, so it recurs, calling itself with (* 3 1) = 3 and (dec 3) = 2
20:50tomojnow 2 isn't equal to 1, so it recurs again, calling itself with (* 2 3) = 6 and (dec 2) = 1
20:50tomojnow 1 is equal to 1, so it returns 6, 3!
20:51tomojthe one-arg version calls by name because you can't recur from a one-arg to a two-arg
20:51tomojif you recur, you have to use the same number of arguments as the version you're defining (the two-arg in the example)
20:52tomojDietCokeIsMyBloo: what languages do you already know?
20:52tomojjava, c++, ruby, python, anything like that?
20:53DietCokeIsMyBloojava and c
20:53DietCokeIsMyBlooi know recursion
20:53tomojok, so say you were doing this in java, how would you do it?
20:53tomojint acc = 1;
20:53tomojthen acc *= i; in a loop?
20:54DietCokeIsMyBloowell, i'd do 2 functions( defn factorial-2 [n] factorial-helper [n 1] )
20:54DietCokeIsMyBlooand then have factorial helper do the rest
20:54DietCokeIsMyBloooh sorry- you said java
20:54tomojwell, yeah, that would work too
20:54tomojthe thing is, you don't want to defn factorial-helper really
20:54tomojbecause that's not something anyone will probably call
20:54DietCokeIsMyBloowhy's that?
20:55tomojI don't think you want to define a two-arg version of factorial, either, really
20:55DietCokeIsMyBlooagreed
20:55tomojno one will use it
20:55DietCokeIsMyBlooso, one more time
20:55tomojthe fact that we're threading an accumulator through arguments is an internal detail
20:55DietCokeIsMyBloofact-2 takes 1 arg n initially
20:56DietCokeIsMyBloochanges it into a 2 arg fxn
20:56DietCokeIsMyBloodoes stuff, recurs
20:56DietCokeIsMyBloowith the new accumulator and dec'd n
20:57DietCokeIsMyBlooand then..n it goes to line 1, tries line2- fails goes to line 3, and doesn't do anything, then hops to line 4?
20:57DietCokeIsMyBlooi'm missing something there...
20:58DietCokeIsMyBloohow the fxn knows it can take 2 args...
20:58lucianDietCokeIsMyBloo: you don't need 2 args
20:59tomojwhen you call the function, you either pass in one arg or two args
21:00tomojthe appropriate version in the defn is used
21:00lucianDietCokeIsMyBloo: if you get the chance, read "The Little Schemer"
21:00DietCokeIsMyBloois that what line 4 means?
21:00lucianit's great for learning recursion
21:01tomojwhen you recur with two args, it doesn't need to try line 2 or line 3, it just calls the two arg version because you passed in two args
21:01DietCokeIsMyBloosorry- let me be more specific- does line 4 mean, that it can take 2 args?
21:01tomojyeah
21:01tomojyou can either define a single arity like this: (defn foo [x y] ...)
21:01tomojor multiple arities like this: (defn foo ([x] ..) ([x y] ..) ([x y z] ..))
21:02DietCokeIsMyBlooahh
21:02DietCokeIsMyBloothis was where the confustion was....
21:02DietCokeIsMyBlootomoj- you're a superstar!
21:02DietCokeIsMyBlooyes, that's what you are my friend!
21:02tomojanonymous fns can do it too
21:03DietCokeIsMyBloooh
21:03DietCokeIsMyBloolet me try an annon fxn instead for this
21:03DietCokeIsMyBloobrb
21:04tomoj,((fn fact ([n] (fact 1 n)) ([a n] (if (= n 1) a (recur (* n a) (dec n))))) 20)
21:04clojurebot2432902008176640000
21:04tomojbut really the two-arg version should be hidden I'd think
21:04lucianand if you're curious you can do this with one arg, but it's no longer constant space
21:05tomojmeaning it might overflow the stack?
21:05DietCokeIsMyBloogot it
21:05luciantomoj: the recur version is tail recursive
21:05tomojright
21:05tomojyour one-arg version isn't?
21:06luciannope, all call stacks exist
21:06lucian&(defn fac [n] (if (= n 1) 1 (* n (fac (- n 1)))))
21:06sexpbotjava.lang.SecurityException: You tripped the alarm! def is bad!
21:06lucianmeh
21:06tomojoh, right
21:06lucian&((fn fac [n] (if (= n 1) 1 (* n (fac (- n 1))))) 10)
21:06sexpbot⟹ 3628800
21:06tomojwonder what types fact should use
21:10tomojinteresting: (loop [acc (bigint 1) n (int n)] ...) with (* n acc) in the recur gives auto-growing results
21:10tomojinteger, long, or BigInteger, whichever is big enough for the answer
21:10tomojI would've thought that if you started with bigint it would always be a BigInteger
21:11luciansince they're immutable, stuff like this is easy
21:12lucianstuff like this = promoting/demoting ints
21:12ckylucian: Does Clojure actually have tail calls? http://clojure.org/functional_programming suggests it doesn't.
21:13luciancky: afaik it uses recur for the same results
21:14ckyAh. :-)
21:14tomojit just won't automatically recognize tail calls
21:15ckyDarn. I was gonna read up on recur, but, my browser crashed again. :-P
21:15tomojyou must use recur and you must do it in tail position
21:15ckytomoj: *nods*
21:15luciani think it's quite nice and explicit
21:15lucianeven if clojure had tail calls, i'd still use recur
21:17ckyOkay, so, this is a complete n00b question, but, is it possible to recur to the non-innermost loop/fn?
21:31DietCokeIsMyBloocan you help me with filter?
21:31DietCokeIsMyBlooif i have a list of numbers, and i want to filter out the odds what would it be?
21:32DietCokeIsMyBloo(filter (predicate) lst)
21:32DietCokeIsMyBloobut the predicate is what i don't know...
21:32DietCokeIsMyBloo(fn[x] (odd? x) true) is not right....
21:33DietCokeIsMyBlooi just need to get rid of the true
21:33DietCokeIsMyBloobut i don't get why
21:34DietCokeIsMyBlooso, the result WOULD be, (filter (fn[x] (odd? x) ) lst).... but why?
21:34headlessClownit's not just (filter odd? lst)?
21:35DietCokeIsMyBlooi didn't try that one
21:35DietCokeIsMyBloobut don't you need a true false condition for the predicate?
21:35DietCokeIsMyBlooor is that the way filter works...
21:35tonylodd? is a fn that returns true or false
21:35DietCokeIsMyBlooright
21:35headlessClownit's all baked in
21:35tonylusually fns endind in ? do that
21:35DietCokeIsMyBloook
21:36DietCokeIsMyBlooso to use filter- apply a fxn that returns true or false. that function is applied to EVERy element of the list and those elements passing the predicate are returned?
21:37cky&(odd? Double/POSITIVE_INFINITY)
21:37sexpbotjava.lang.ArithmeticException: bit operation on non integer type: class java.lang.Double
21:37tonyldiateCokeIsMyBloo: yea
21:37ckyWell, that makes it pretty obvious how odd? is implemented. :-P
21:38tonyl$source odd?
21:38sexpbotodd? is http://is.gd/igDKd
21:38ckytonyl: Does tab completion not work on your IRC client?
21:38tonylI don't know. I am pretty new to IRC, I am using XChat
21:39ckyAh, I think if you type "di<TAB>" (where <TAB> is your tab key), it should complete the rest.
21:39tonyloh snap, it does. thanks
21:39cky\o/
21:39DietCokeIsMyBloomaybe i need a break for a bit :)
21:40DietCokeIsMyBloothanks guys
21:40ckyAnd yeah, even? and odd? are implemented the way I thought it was (given the error message :-P).
21:40tonylusing bit-and
21:43ckyYep.
22:15brehautxcthulhu: fhtagn
22:15xcthulhuIndeed
22:16xcthulhuThis is hardly a #clojure question, but what are good channels for embedded system development?
22:16xcthulhuAlthough I'm holding out that clojure will harken the second coming of the lisp-machine...
22:21xcthulhuNo bites... alas...
22:24ckyMy 2 cents on the "second coming of the Lisp Machine" business: I think x64 is the dominant platform these days. There is no getting away from that. But, you can design an OS, that runs well under virtualisation, that is fully managed and based on Clojure.
22:25ckyYour OS also needs to support loading .class files, or at least some format the Java class libraries can be compiled into.
22:25trytotracehi. I have a question about tracing. anyone here has done it the lisp way on clojure?
22:25ckyThe topic of writing fully-managed Lisp-based OSs is a not-infrequent topic in #scheme.
22:25ckyxcthulhu: ^^---
22:27trytotraceis it possible to shadow a function during runtime for tracing?
22:32jweissi'm trying to write automated tests in clojure. I'd like to not have to write separate human-readable procedures. Should I made my tests more data-like, and transform it into a more readable form for humans? or should I just make my programs readable to begin with by using a lot of macro syntactic sugar?
22:33jweissso far i've been using macros, but i keep hearing the stern warnings in my head to only use them when necessary, and I'm not sure it's necessary this time
22:35ckyjweiss: My 2 cents (as a Scheme programmer, not a Clojure one): you can use macros for syntactic sugar, but, if there's a way to make a procedure for doing so that's just as clear, then that's preferable.
22:35Deranderas a ruby programmer: damn performance, pour on the sugar!
22:36ckyDerander: Hahahaha.
22:36jweissyeah I am not particularly concerned with perf either, since my app under test is completely separate. my code spends a lot of time just waiting on the app.
22:37ckyjweiss: Indeed. Really, either approach is fine. Just truck along with what you have.
22:37jweisscky: by human readable, i mean, readable by non programmers
22:37ckyjweiss: Of course.
22:38ckyjweiss: In my day job, we program in Ruby, and care a lot about making code easy to read (I think the buzzword these days is "DSL"). So I totally understand.
22:40jweisscky: yeah it not a problem that i'm sure i can solve. i just know it seems really stupid to me to write an english procedure as the official "test" and then automate it and have the two "definitions" drift apart over time
22:41jweissif there's just going to be a canonical definition of the test it should be the code
22:43Deranderjweiss: you'll care about performance after your cucumber/rspec tests take 45 seconds to run :-
22:43Derander:-)
22:43jweisshah i wish
22:43jweisswe have selenium tests that take 12 hours
22:43Deranderoh yeah, I'm just talking about two basic scenarios
22:43jweissnot a single test mind you, hundreds of them
22:44Deranderasdf. <3 ruby, but it's painfully slow sometimes.
22:44jweissi'm not a big fan of cucumber's style of testing
22:44Deranderat least it's really obvious when you have an inefficient algorithm in ruby...
22:44Deranderjweiss: I am for some things
22:44jweisstoo much dependency on regex
22:45DeranderI have some of the people at my place of employment almost trained to write them for me
22:45Deranderso the help desk people can write my specs
22:45hippiehunteris it possible to destructure into params for a function?
22:45jweisshippiehunter: i'm pretty sure that works the same way
22:45xcthulhujweiss, Does clojure have a fast regex, like google's re2?
22:46xcthulhuI seem to recall that google's re2 was linear time (rather than exp like ordinary implementations)
22:46jweissxcthulhu: i don't know
22:46jweissmy problem with cucumber's use of regex has nothing ot do with performance
22:47jweissit's just that if you change your english spec, you have to dig up your regex and fix that
22:47jweisseven if there's no real change in behavior
22:47Derandertrade-offs must be made
22:47jweissyup
22:47jweissit's good at what it does
22:47jweissit's just not a good fit for me
22:48Deranderhttps://github.com/cavalle/steak <-- this is a cucumber alternative
22:48Deranderless english but more code
22:48Deranders/but//
22:48sexpbot<Derander> less english more code
22:48hippiehunter:jweiss im having a hard time translating my knowledge of destructuring into let and named parameters into passing parameters to a function im calling. Do you know of any examples i can look at?
22:50jweisshippiehunter: hm i take that back
22:50jweissi guess you can't destructure in the param list of a fn definition
22:50jweiss,(defn [ [x y] ] (+ x y))
22:50clojurebotjava.lang.IllegalArgumentException: Parameter declaration + should be a vector
22:52hiredmanjweiss: you are missing something there
22:52jweissoh yea
22:52jweiss,(defn foo [ [x y] ] (+ x y))
22:52clojurebotDENIED
22:52jweissdoh
22:52tonyl&((fn [[x y]] (str x "." y) [4 5])
22:52sexpbotjava.lang.Exception: EOF while reading
22:52tonyl&((fn [[x y]] (str x "." y)) [4 5])
22:52sexpbot⟹ "4.5"
22:52jweissok i take it back again hippiehunter - it does work
22:53jweiss (defn foo [ [x y] ] (+ x y))
22:53jweiss(foo [1 3])
22:53jweiss4
22:53cky&((fn [(x y)] (+ x y)) '(4 5))
22:53sexpbotjava.lang.Exception: Unsupported binding form: (x y)
22:53cky&((fn [(x . y)] (+ x y)) '(4 . 5))
22:53sexpbotjava.lang.Exception: Unsupported binding form: (x . y)
22:53tonyl&((fn [[x y]] (+ x y)) [4 5])
22:53sexpbot⟹ 9
22:53hippiehunterdoes food need to be defined in terms of [[x y]] or is there a way without the nested vector?
22:53ckytonyl: I'm trying to see if one can get away from vectors.
22:53hippiehuntererr foo
22:54tonylno, i think only maps and vectors
22:54ckyOh well.
22:54ckyIt seems in Clojure vectors are much more first-class than they are in other Lisp dialects.
22:54jweisshippiehunter: it works the same way as with let
22:55jweissexcept you aren't assigning a value until you call the function
22:55ckyIn other Lisp dialects I've seen, vectors are very much second-class, to be used only for specific cases.
22:55cky(Not second-class in the sense of "first class functions", but, just, its use is not particularly encouraged, not to the same degree as lists.)
22:55hippiehunterright but the called method needs to be aware of this
22:56hippiehunteri was hoping to turn a map into the parameters for an arbitrary function
22:57Deranderyou can do it with a map
22:57hippiehunterI suppose in my case (constructor) i can just make a plain one, then assoc it in
22:58tonylyou can destructure maps
22:59Derander,(defn foo [{a :a b :b}] (+ a b))
22:59clojurebotDENIED
22:59Derander,((fn [{a :a b :b}] (+ a b)) {:a 1 :b 2} )
22:59tonyl&((fn [{x :x y :y}] (+ x y)) {:x 5 :y 9})
22:59clojurebot3
22:59sexpbot⟹ 14
22:59Deranderhaha
23:00Derandergood timing
23:00tonylhaha yeah
23:00tonyltook me a while to test it first :P
23:01tonylDerander: how do you use :keys for destructuring? I can never remember
23:01Deranderno clue
23:01tonylmm
23:02tonylfound it ##((fn [{:keys [x y]}] (+ x y)) {:x 5 :y 9})
23:02sexpbot⟹ 14
23:02Deranderah
23:03Deranderinteresting
23:03brehautthere are equivalents for strings and maybe symbols(?) too
23:04brehaut:strs and :syms
23:04tonylbrehaut: how do you use those?
23:05brehaut,(let [{:strs [a b]} {"a" 1 "b" 3 "c" 3}] (+ a b))
23:05clojurebot4
23:05brehaut,(let [{:syms [a b]} {'a 1 'b 3 'c 3}] (+ a b))
23:05clojurebot4
23:06brehautsyms is probably more useful in a macro than normal code?
23:06tonylooh great to know
23:06hippiehunterholy crap thats awsome, that makes dealing with json so much better
23:06brehauthttp://clojure.org/special_forms
23:06brehautits all in there
23:07brehautyup, destructuring + multimethods = super json powers
23:10ckybrehaut: Oh, hey, on a different topic, I notice that you're from NZ as well...do you know talios (in person, I mean)? Just trying to see how small of a world this is.
23:11brehautnot in person
23:11ckyAh, okay.
23:11brehautwe live about 2 hours drive apart
23:11cky...is that 2 hours from Auckland, or 2 hours from Napier? :-P
23:11brehauttwo hours from auckland
23:11brehautactually, its possible both :P
23:12cky(Napier is talios's hometown, IIRC, hence my question. :-P)
23:12brehautah, 3.45 hours
23:12ckyHehehehe.
23:12brehautim in hamilton
23:12brehautbustling metropolis of cows
23:12ckyNice. We (the social circle that I know talios from) have people who live in Hamilton, too.
23:13brehautoh true
23:13ckyBut, yeah, some shade of small world. :-)
23:13brehautyeah :)
23:14brehautits frighteningly likely that there might be someone incommon :P
23:14ckyThat wouldn't surprise me in the slightest.
23:14ckyHeh, I consider Hamilton to be 1.15 hours from Auckland, but that's more a sign of the speed I drive at more than anything else. :-P
23:14brehauthah
23:15brehautwherer are you from?
23:15ckyWell, I'm an Aucklander, but, I don't actually currently live in New Zealand.
23:15brehautoh right
23:15ckyIn fact, in terms of small world, I live in the same city as Relevance. :-P
23:15brehauthah
23:16cky(Not by intention---I've only heard about Relevance some time after I've lived in Durham.)
23:24ckySo, since I'm new to the channel and all, what's the difference between sexpbot and clojurebot? :-)
23:24brehautmaintainer and various additional magic mostly?
23:25ckyOkay, so, does it matter which one I pick on?
23:25brehauti dont think so?
23:25brehauthttps://github.com/raynes/sexpbot
23:25ckyOkie dokie. :-)
23:26ckyI ask because in #scheme, there are multiple bots, each running a different Scheme implementation. But, I can't really imagine there currently being more than one Clojure implementation (unless someone is running Clojure CLR in one of the bots :-P), so.
23:27pdkclojure had a .net version at least early on
23:27pdkit's probably still maintained but second fiddle to the java one
23:27ckypdk: It's still there.
23:27hiredmanI have a clojure interpreter (written in clojure) I've been thinking about switching clojurebot too for better sandboxing
23:27ckyNice.
23:27pdkscheme implementations it seems have crap cross compatibility
23:27p_l|home"crap" is a superlative
23:28p_l|homea positive one, in this case :>
23:28ckyp_l|home: ...it is?
23:28pdkoh you
23:28ckypdk: It's true, if you want to write sizeable Scheme programs, you basically have to write for a certain implementation and stick with it.
23:29ckyPorting between implementations is, well, not free of work.
23:29p_l|homethe SRFIs don't cover enough... then you have the fact that SRFI coverage differs among implementations
23:29ckyp_l|home: ...and that the syntax for loading SRFIs are not portable, either.
23:29p_l|homeespecially which ones are implemented by code shipped with them
23:29p_l|homecky: true
23:30hiredmanthat is my concern with switching clojurebot over to the interpreter, it wouldn't really be "clojure" it would be sort of kind of like clojure
23:30p_l|homeRacket avoids the whole issue by renaming itself and differentiating from Scheme family
23:30ckyIndeed, Racket is...its own language.
23:32pdkhow do clojure and abcl usually compare for speed now
23:32p_l|homepdk: hard to compare, IMHO
23:32pdkwell are there some rules of thumb
23:32p_l|homeABCL when running compiled has definitely respectable performance, and might have less GCing than Clojure
23:33p_l|homethe big slow point of ABCL got fixed few years ago, but still floats in information available on internet
23:34p_l|homerecently hashtables got fixed (switchover from ABCL own code to JVM native)
23:44pdkwhat was the achilles heel with abcl for so long that you're referring to
23:44pdkis it just the hashtable implementation or
23:46p_l|homepdk: it had some issues in CLOS speed
23:47p_l|homeit still shows up in the material on the net, but has been actually fixed for quite long time
23:47pdkdoes working with cl structs still perform well
23:48pdkcould always roll it paul graham style and go "YEAH WELL FORGET YOU CLOS I NEVER NEEDED YOU ANYWAY"
23:48p_l|homepdk: now it doesn't matter, both structs and classes work fasst
23:48pdkgotta look into that stuff again
23:48p_l|homepdk: some people claim that he never learned CLOS :P
23:48pdkso i could do something interesting with graham's lisp book besides reading it again
23:49p_l|homepdk: which book?
23:49pdkit always struck me like the guys coming from c to c++ who went back because they said structs were good enough
23:49pdkansi common lisp
23:49p_l|homeafaik people don't really recommend that book
23:50p_l|homeGraham has some style bloopers, at least compared to "lingua franca" of CL style
23:51ckyp_l|home: On CL boks, what's your take on Practical Common Lisp?
23:51p_l|homecky: wonderful :)
23:51ckyp_l|home: I'm trying to decide how high or low to put it on my reading list. :-)
23:51ckyGood, I'll bump it right to near the top.
23:51p_l|homeor, to quote Xach, “dead sexy”
23:51cky(Programming Clojure is currenty at top. I think PCL can be #2, at the mo.)
23:54p_l|homecky: PCL is good enough to give someone a fast start into CL, Gentle Introduction to Symbolic Computation is IMHO useful for all lisps, especially the early chapters (and both are available for free on the net)
23:54DietCokeIsMyBlooi have a beginner's question about using iterate
23:54pdki should go back and finish pcl
23:54DietCokeIsMyBloothe question is: write an expression using iterate to return a list of squares of numbers btw 5 and 15
23:55pdkwhere do you find the symbolic computation one
23:55ckyp_l|home: Thanks for that, I'll add that to my list too.
23:55pdkis this for some sort of assignment or can you use something instead of iterate
23:55DietCokeIsMyBlooI have it written but was wondering if there is a cleaner way
23:55DietCokeIsMyBloohttp://codepad.org/2gAKOmaO
23:55DietCokeIsMyBloogotta use iterate
23:55ckyHahahahahaha.
23:56pdkif you're going to use iterate that way looks fine to me
23:56DietCokeIsMyBloois there a "better" or cleaner way?
23:56p_l|homepdk: gentle: "Common Lisp: A Gentle Introduction to Symbolic Computation" is a smoother introduction to lisp programming. http://www.cs.cmu.edu/~dst/LispBook/
23:56pdkthough for dinky 1-argument lambdas i'd prefer to say #(* % %) instead of (fn [x] (* x x))
23:57DietCokeIsMyBloocan i do it without using map?
23:57p_l|homecky: FYI - recently released Land of Lisp, while concentrating on CL, also has a chapter on clojure afaik
23:57pdki wouldn't think to use iterate for it off the bat first thing but if you want iterate in there i think you've hit on a fairly idiomatic way to do it
23:57ckyp_l|home: Wow, that's quite the tour of Lisp languages...wonder if it covers Arc too. :-P
23:57pdkland of lisp is the games coding one right
23:57DietCokeIsMyBloook :)
23:57DietCokeIsMyBloothanks pdk!!!
23:58ckypdk: I think so, yes.
23:58p_l|homecky: it does in one chapter :P
23:58pdki was thinking of that on kindle store but i wondered if it'd be too much like those java 101 books that teach you to use swing without knowing what an if statement even is
23:58ckypdk: It came #23 in sales on the O'Reilly ebook Cyber Monday sale. :-P
23:58pdkdoes it still yknow try to teach you lisp for real
23:58Deranderit was available from o'reilly for like $10 during their 60% off ebooks
23:58ckyDerander: Jinx!
23:58pdkoh snap is the sale already over
23:58Derandercky: :-)
23:58Deranderpdk: yeah
23:58Deranderpdk: it's my understanding that it does
23:58p_l|homepdk: it's quite good, I haven't read the whole thing yet, waiting to obtain it through official channels :)
23:58DeranderI haven't started it though
23:59pdkis that code for "i pirated the kindle version"
23:59p_l|homepdk: if you know _why's poignant guide to ruby, it's done in similar wayu
23:59p_l|home*way
23:59ckyI didn't know about the book until after the sale (though I bought 11 books from O'Reilly during it), so, I guess I'll get it when the next sale comes 'round.
23:59p_l|homepdk: No, not the kindle version, Kindle sucks at formatting :P
23:59pdki've only heard of why's guide
23:59pdki bought elementary standard ml off kindle store cause for some dopey reason