#clojure log - Dec 05 2010

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

0:09 slyrus: is 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?

0:19 technomancy: slyrus: 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.

0:20 anyway, it's in the tutorial.

0:20 slyrus: hrm... grumble grumble... OK, thanks!

0:22 I didn't realize that the clojure 1.3 was going to be backwards-incompatible

0:23 the old stable vs. evolving language double-edged sword thing...

0:23 brehaut: slyrus: just enough to hurt ;)

0:23 technomancy: in the case of swank-clojure it's probably safe

0:23 since it won't break anything in production

0:26 slyrus: technomancy: I'm confused by your last two comments. What's probably safe? and what is "production"?

0:27 are 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?

0:27 hrmm... I probably didn't want to use de facto there. but you get the idea.

0:28 it would be nice if folks libraries could continue to be used for both 1.2 and 1.3, right?

0:28 technomancy: depending 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

0:29 slyrus: what, you don't give customers access to the debugger? :)

0:29 technomancy: but 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

0:29 heh

0:31 many 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

0:32 slyrus: yes, 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...

0:32 ...around your system somewhere, so I'll let you figure out how to tell me where I should find them".

0:34 technomancy: non-repeatable builds are fine for experimentation but totally incompatible with responsible deployment

0:37 pdk`: is 1.3 in RC phase

0:38 * slyrus either doesn't deploy or, clearly, does so irresponsibly

0:41 technomancy: what 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

0:41 slyrus: technomancy: 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

0:41 technomancy: are there any Clojure projects that deploy to clojars without source in their jars?

0:42 I'm not aware of any

0:42 slyrus: I'd rather have my sources in a local git tree than a random jar from some jar repo

0:42 but, I suppose that's a good point

0:43 technomancy: as long as slime can M-. to it, it's good enough for me

0:43 slyrus: hrm... not so great for tracking any local changes one might make to it -- not to mention rebuilding a world that contains those changes!

0:44 technomancy: sure; making local changes is what checkout dependencies are for

0:44 but that's an opt-in special case

0:44 slyrus: I see that as the base case, I guess

0:45 perhaps I should have been at the conj where y'all could have disabused my of silly holdover common-lispisms over a beer or two

0:46 technomancy: I actually wrote a precursor to Leiningen that would support git checkouts

0:46 brehaut: technomancy: any reason it didnt carry over?

0:46 technomancy: https://github.com/technomancy/corkscrew/blob/master/src/cork/screw/deps/git.clj

0:46 brehaut: I guess the main thing is you just couldn't make any assumptions about how the dependent project was structured

0:47 slyrus: technomancy: 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.

0:47 brehaut: technomancy: makes sense

0:47 technomancy: brehaut: does the presence of build.xml imply "ant" is enough to get a working jar? if so, what is the jar named?, etc

0:48 brehaut: technomancy: sounds like a winding garden path of suffering

0:48 technomancy: brehaut: 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.

0:49 who wants to have CVS installed locally just so they can use javamail?

0:49 slyrus: technomancy: 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.

0:49 technomancy: I have no interest in those crappy java projects

0:50 technomancy: javamail is actually a really solid library

0:50 I wouldn't have a job using Clojure if it weren't for it

0:50 slyrus: ok, fine, but the point is I want the version control and the dependency management to be separated

0:51 technomancy: slyrus: you can do a lot to customize the classpath with leiningen plugins

0:51 if you've got some ideas to experiment with, I think it should be doable

0:51 actually most jars on clojars have git-related metadata in them

0:52 so 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"

0:52 https://github.com/technomancy/leiningen/blob/master/pom.xml#L13

0:53 well I am going to head off

0:54 if you have questions about how such a thing would work, hit up the lein mailing list

0:54 slyrus: ok, thanks for your thoughts

0:54 technomancy: cheers

0:55 slyrus: indeed. first beer's on me next conj.

2:11 rata_: I know this is a weird question, but what is the cheapest sequence constructor?

2:11 I need to (compare ...) two sequences, but (keys ...) returns a seq that's not Comparable

2:12 should I vec it? or list* it?

3:20 mister_roboto: when you're running some clojure app "in production", like a compojure web app or something, is it usual practice to leave a REPL running?

5:58 fliebel: morning

6:01 I 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.

6:22 Okay Clutch wins. Though I wonder how it works. Especially how it handles the revision when updating.

6:26 DubFish: Anyone willing & able to help troubleshoot a Mac 10.5 MacPorts setup?

6:32 Here's what I get:

6:32 % sudo port -R -u -c install clojure clojure-contrib leiningen

6:33 5% lein help install 101205Su111826

6:33 That's not a task. Use "lein help" to list all tasks.

6:33 Exception 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)

6:33 at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2911)

6:33 I'm hoping this is a well-known issue...

6:34 Mac OS X 10.5.8 on a 2006 MacBook Pro (dual-core Intel)

6:34 Java 1.6.0_22

6:35 MacPorts Clojure 1.2

6:41 % lein self-install 101205Su113513

6:41 That's not a task. Use "lein help" to list all tasks.

6:41 (please ignore right-hand prompt date strings)

6:49 ismarc: so, from your errors, it looks like lein is installed

7:29 fliebel: DubFish: lein is on macports?

7:51 Hey, 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?

7:58 Hrm, 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.

8:00 raek: fliebel: you can make your own type that behaves exactly as an atom by implementing ARef

8:01 hrm, swap! and friends are limited to clojure.lang.Atom....

8:02 fliebel: right

8:02 raek: fliebel: I'm curious... what are you working on?

8:02 fliebel: raek: Nothing, but looking at couchdb, it seems to be a prefect fit.

8:03 raek: Normally updating a document involves a revision, which works exactly like compare-and-set!, if the _rev doesn't match, it fails.

8:04 raek: interesting

8:04 fliebel: So 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.

8:06 raek: Interesting, but impossible with the current implementation of atom.

8:07 I'd have to bring my own swap! IDeref exist though, so @ would work.

8:07 raek: maybe you should mention this to rhicket

8:07 *rhickey

8:08 fliebel: raek: Do you think atom and friends could get a shiny new interface if I asked him?

8:08 raek: after all, there is a very strong semantic match

8:08 nickik: sombody know ruby? whats not= in ruby?

8:09 raek: I don't know. but it could be interesting to hear why there isn't interfaces for these things

8:09 fliebel: nickik: !=?

8:09 raek: Atom is marked final, so maybe he doesn;t want people to toy with it?

8:09 raek: well, all the concrete classes in clojure is final

8:10 but wherever there is a concrete class, there is usually an interface as well

8:10 e.g. IPersistentVector and PersistentVector

8:10 fliebel: raek: Why is that? (and what is the best way to reach rhickey?)

8:10 (the final part)

8:11 nickik: @fliebel: thanks

8:11 aligole: hi guys

8:12 raek: I think there are some issues with subclassing (maybe thread safety?), as clojure as stayed away from it when deftype, defrecord and defprotocol was introduced

8:12 but I don't remeber the details

8:12 fliebel: okay

8:14 raek: I 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

8:14 fliebel: No CA, but I'll wait for him to make his appearance here.

8:15 raek: having interfaces for the other reference types might be another story

8:15 fliebel: Why?

8:15 clojurebot: http://clojure.org/rationale

8:15 raek: since they have much more intricate semantics

8:16 it might be hard to find something that has exactly the same semantics as a ref, for instance

8:17 fliebel: raek: So it's because they're hard to get right?

8:17 raek: that is my guess

8:17 this is just speculations

8:18 fliebel: But say there is a perfect use case for ref just around the corner, it wouldn't hurt to be able to implement it, right?

8:18 aligole: Can anyone point me to some sample code or tutorials for some one with Python/C# background?

8:21 raek: fliebel: refs are entangled with the STM, so there might not be a clear cut interface in that case (this is my guess)

8:22 fliebel: raek: That would make sense… I think… I'll look at the ref impl

8:22 raek: atoms are more simple, as they only involve the atom object itself

8:24 malky42: do 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?

8:25 fliebel: malky42: My guess is using a :or keyword, but I am surely wrong.

8:26 raek: fliebel: defstruct not destruct... :-)

8:26 fliebel: raek: Yea, that's why I'm wrong :( Nyway, I think he ought to use records, tight?

8:27 raek: malky42: you can store a "default struct" in a var and merge that with a map that the user supplies

8:27 malky42: raek: okay, I think I play with that.

8:27 raek: one thing, do records now supersede structs?

8:28 raek: (defn make-thing [t] (merge default-thing t))

8:28 malky42: records do what structs did, but with even less space

8:29 but yes, redords makes them a bit obsolete

8:29 mduerksen: raek, malky42: you actually have to do a merge-with, otherwise it won't work

8:30 raek: ,(doc merge)

8:30 fliebel: raek: Can you do destructering in a record?

8:30 clojurebot: "([& 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...

8:30 mduerksen: as a struct always has an entry for every key, which can be nil

8:30 malky42: raek: 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.

8:30 raek: fliebel: records are maps.

8:30 fliebel: raek: yes, yes… wait… hrm...

8:32 raek: mduerksen: why would one have to use merge-with rather than merge?

8:32 mduerksen: raek, 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

8:32 ,(merge {:a 1} {:a nil})

8:32 clojurebot: {:a nil}

8:33 mduerksen: ,(merge-with #(if %2 %2 %1) {:a 1} {:a nil})

8:33 clojurebot: {:a 1}

8:33 raek: my assumption was that the left map was a struct object with all its slots filled

8:34 and the right map an ordinary map used to override the defaults

8:34 fliebel: hrm, no destructuring at all in records: #:user.blah{:& 1, :c 2}

8:34 mduerksen: the problem is, that a struct always has its slots filled, but some could have nil value

8:34 clojurebot: not a problem, the average bid for it on getacoder is $821.00

8:35 raek: fliebel: ah, you mean in the fields vector? no.

8:35 fliebel: (is it me, or has clojurebot learnt a lot of new interruptions?)

8:36 raek: mduerksen: ok, now I see what you meant. if the 't' argument in my function is a struct, then you need to use merge-with.

8:36 fliebel: the fields become java class fields

8:37 so you can't have a dynamic number of fields

8:37 fliebel: I see

8:38 mduerksen: raek: 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?

8:43 killy971: Hello. 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.

8:51 raek: (defmacro factorial-prime [n] `(case ~@(mapcat (juxt identity factorial) (range 0 (inc n))))))

8:52 wait

8:55 killy971: ~@ is used to inline a list?

8:55 clojurebot: @ is splicing unquote

8:56 raek: (defmacro factorial-cases [x n] `(case ~x ~@(mapcat (juxt identity factorial) (range n)) (factorial ~x)))

8:56 (defn factorial2 [x] (factorial-cases x 5))

8:57 ,(let [xs [1 2 3]] `(foo a ~x b))

8:57 clojurebot: java.lang.Exception: Unable to resolve symbol: x in this context

8:57 raek: ,(let [xs [1 2 3]] `(foo a ~xs b))

8:57 clojurebot: (sandbox/foo sandbox/a [1 2 3] sandbox/b)

8:57 aligole: Hey 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!

8:57 raek: ,(let [xs [1 2 3]] `(foo a ~@xs b))

8:57 clojurebot: (sandbox/foo sandbox/a 1 2 3 sandbox/b)

8:57 killy971: ok, I see, thanks. trying the macro

8:58 raek: killy971: yes, it buts the elements in the list, rather than the whole thing as one element

8:59 ,(let [x 'x, n 5] `(case ~x ~@(mapcat (juxt identity factorial) (range n)))

8:59 clojurebot: EOF while reading

8:59 raek: ,(let [x 'x, n 5] `(case ~x ~@(mapcat (juxt identity factorial) (range n))))

8:59 clojurebot: java.lang.Exception: Unable to resolve symbol: factorial in this context

9:00 killy971: ,(def factorial [n] (if (zero? n) 1 (reduce * n (range 2 n))))

9:00 clojurebot: DENIED

9:01 raek: ,(let [x 'x, n 5, factorial #(reduce * (range 1 (inc %)))] `(case ~x ~@(mapcat (juxt identity factorial) (range n))) (factorial ~x))

9:01 clojurebot: java.lang.IllegalStateException: Var clojure.core/unquote is unbound.

9:03 raek: aligole: 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

9:04 with this approach, you can change the number of fields (as well as the ordering), without having to rewrite all code that makes instances

9:05 user=> (let [x 'x, n 5] `(case ~x ~@(mapcat (juxt identity factorial) (range n)) (factorial ~x)))

9:05 (clojure.core/case x 0 1 1 1 2 2 3 6 4 24 (user/factorial x))

9:05 killy971: ^

9:05 killy971: yes?

9:05 looks perfect!

9:06 thank you very much

9:08 aligole: raek: thanks, I am still in non-clojure/lisp way of thinking,

9:18 raek: 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?!

9:19 raek: no :)

9:19 the data structures in clojure are immutable

9:20 they are defined that way, so you can't change it

9:21 Raynes: You could always just use Java collections, but that would be kind of silly.

9:21 nickik: @aligole you could but it would be really ugly code because you had to use refrencetypes everywhere.

9:21 Raynes: s/kind of/extremely/

9:21 sexpbot: <Raynes> You could always just use Java collections, but that would be extremely silly.

9:21 aligole: :) 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!

9:21 raek: aligole: 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)

9:23 there are of course thing that can change, but those are separated from the datastructures themselves

9:23 nickik: aligole, 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.

9:23 *platz place

9:24 i used the german word :)

9:24 raek: I think clojure is a great language even if you don't use the concurrency bits

9:25 aligole: I 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!

9:26 nickik: @not using concurrency and doing everything non-FP is not the same. You can do FP without concurrency

9:27 @aligole, define regular problem :)

9:27 Raynes: nickik: You know, IRC isn't twitter. :p

9:27 raek: aligole: what programming languages are you accustomed to?

9:28 Raynes: nickik: 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 @.

9:29 aligole: Like 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!

9:29 nickik: I know that now but I only learnd that and I do it atomaticly

9:30 raek: there 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...

9:31 aligole: nickik: 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!

9:31 raek: aligole: Clojure as a family of "reference types" that let you have things that change over time (e.g. things that the user can modify)

9:31 one of them is the atom

9:32 nickik: agree, in this case an atom would could hold the changes

9:33 raek: the reference types are updated by giving them a function

9:33 the function takes the old value (plus any extra args) and returns the new value

9:34 nickik: read 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

9:34 *sean sane

9:35 raek: aligole: this is a gold mine of clojure videos: http://alexott.net/en/clojure/video.html

9:36 I especially recommend http://vimeo.com/10896148 and http://vimeo.com/8672404

9:36 nickik: @Raynes I'm trying to get someone to learn clojure and you last blogpost almost threw him over the cliff. :)

9:37 damn, did it again :)

9:37 aligole: that is cool! I need to actually try it to learn it.

9:37 thanks guy

9:37 Raynes: nickik: Hehe. I'm going to assume "threw him over the cliff" is a good thing in this case. :<

9:37 :>*

9:39 nickik: Raynes, it is if the cliff is indefinitely high

9:39 Raynes: :p

9:42 nickik: aligole, look at http://clojure.blip.tv/posts?view=archive&nsfw=dc for you the Clojure for Java Programmers videos would be best. (java meaning not lisp or FP)

9:42 Raynes: nickik: You're talking about the build tool introductory post, right?

9:43 My last post was about sexpbot.

9:43 nickik: the one about sexpbot

9:43 Raynes: Oh. He likes sexpbot? :o

9:43 nickik: he wanted to write one anyway

9:43 clojurebot: I don't understand.

9:46 Raynes: sexpbot 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.

9:46 nickik: I showed him your post and he twitter me back that that would almost be sufficiently cool to start learning clojure

9:47 Raynes: It'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.

9:48 nickik: Il be sure to tell him that

9:49 fliebel: Raynes: I can vouch for that. Though started Clojure before sexpbot even existed, I ping everyone I have the slightest reason to :)

9:49 Raynes: fliebel: :p

9:49 fliebel: You'll be happy to know that several people in unrelated channels find that little tidbit of functionality neat as well.

9:50 * fliebel smiles

9:53 fliebel: I 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)

9:53 nickik: We do people need tools for twitter?

9:54 I mean wtf browse read write something if you want. What tooling is required?

9:54 fliebel: nickik: Marketeers need them. To spam people and to follow hash tags and manage things...

9:55 nickik: ok, valid point

9:55 fliebel: nickik: 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.

9:57 p_l|home: nickik: trend tracking, use of twitter as automated information transport (with bots twittering and bots receiving), things like that

10:06 fliebel: https://github.com/pepijndevos/Twemail Would be lovely to have that in Clojure. Twisted is rather painfull.

10:11 jamesnvc: Hello

10:11 edw: In SLIME, I never get local vars in the backtrace. Is there a way to get them to show up?

10:12 jamesnvc: Question: What does "Pop without matching push" mean in the context of agents & atoms?

10:13 nickik: not 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:14 Bahman: Hi all!

10:14 jamesnvc: Hrm...I think it may be due to me somewhat-abusing agents

10:15 nickik: We us peek (top) to look at the first thing and pop to return the rest of the stack without changing the stack

10:15 don't just build a normal stack with ref-types

10:16 i had that same question to and im not sure how to think about stacks atm

10:17 jamesnvc: I don't have any explicit stacks here

10:17 Although I think I might be doing something wrong

10:18 I 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:18 The "pop w/o push" happens when it receives the die message

10:19 nickik: mhh

10:19 jamesnvc: (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:21 nickik: why is not every element of your grid a ref? Then you could build some functions like move.

10:22 jamesnvc: I actually do have that, but I want the agents to maintain their own state

10:22 (this is a proof-of-concept for something bigger, that will require each agent to carry around it's own position, &c)

10:23 nickik: so you have a map or a record in the agent

10:23 jamesnvc: Correct

10:24 This is the nub of it: https://gist.github.com/729167

10:24 nickik: i 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:25 jamesnvc: I'm using agents because I want to ultimately have potentially hundreds of independent units moving and doing their own thing

10:26 nickik: hallo

10:26 __name__: Am I mistaken that there's no lambda in Clojure?

10:26 jamesnvc: __name__: lambda = fn

10:26 nickik: the lambda is justed named fn because that easyer for most people

10:26 __name__: Ah.

10:26 Fair enough :)

10:28 nickik: jamesnvc, I not sure i can help you because my lack experience

10:29 __name__: Thank you a lot, jamesnvc and nickik.

10:29 nickik: but i can point you to a programme that is somewhat simular

10:29 http://clojure.googlegroups.com/web/ants.clj?gda=QaGDPzoAAAC_UdR48ERSha0tJ0UgPmyf3cnWebOqkFTyQwG7RLaV5e9OU0NQiFWgQuhmPR7veGf97daDQaep90o7AOpSKHW0

10:29 jamesnvc: nickik: 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:33 nickik: (doc zipmap)

10:33 clojurebot: "([keys vals]); Returns a map with the keys mapped to the corresponding vals."

10:33 nickik: &(zipmap [1 2 3] ["1" "2" "3"])

10:33 sexpbot: ⟹ {3 "3", 2 "2", 1 "1"}

10:34 __name__: wait, that's not the same thing.

10:34 nickik: i see

10:34 that if you want a map

10:34 &(partition 2 (concat [1 2 3] [4 5 6]))

10:34 sexpbot: ⟹ ((1 2) (3 4) (5 6))

10:35 nickik: maybe there is something better but im not sure

10:35 in cases like this maps are normaly better

10:41 lyonscf: hey guys. :)

10:41 nickik: hallo

10:41 cky: nickik: But, like, maps aren't order-preserving, as your example showed.

10:41 nickik: Real zip is. :-P

10:42 nickik: (doc orderd-map)

10:42 clojurebot: Pardon?

10:42 cky: nickik: How do you make zipmap generate one of those?

10:42 nickik: (doc sorted-map)

10:42 clojurebot: "([& 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:42 sexpbot: java.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:43 sexpbot: ⟹ ((1 2) (2 3) (3 4))

10:43 __name__: Now just for an arbitrary length of arguments.

10:43 cky: __name__: :-D

10:43 You just want SRFI 1-style zip, dontcha. :-P

10:44 __name__: SRFI?

10:44 I want Python style zip and zip_longest :)

10:44 cky: __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:45 cky: All 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:46 nickik: you 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:46 cky: nickik: :-P

10:46 mduerksen: ,(doc partition-all)

10:46 clojurebot: "([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:47 nickik: &(apply sorted-map [[1 2 3] [4 5 6]])

10:47 sexpbot: ⟹ {[1 2 3] [4 5 6]}

10:47 nickik: mmh

10:48 &(sorted-map [1 2 3] [4 5 6])

10:48 sexpbot: ⟹ {[1 2 3] [4 5 6]}

10:49 lyonscf: Hey guys, I have a question about clj-time

10:50 It says use (now) to get a current date-time

10:50 in the docs

10:50 nickik: &((fn [& coll] (partition (count coll) (concat coll) )) '(1 2 3) '(4 5 6) '(7 8 9))

10:50 sexpbot: ⟹ (((1 2 3) (4 5 6) (7 8 9)))

10:50 lyonscf: and that fails when I make the call

10:50 for example

10:50 (def cur-date (date-time now))

10:51 doesn't work

10:51 any ideas what's going wrong?

10:51 nickik: &((fn [& coll] (partition (count coll) (apply concat coll) )) '(1 2 3) '(4 5 6) '(7 8 9))

10:51 sexpbot: ⟹ ((1 2 3) (4 5 6) (7 8 9))

10:51 nickik: lyonscf, have you included it?

10:52 lyonscf: nickik: yea

10:52 I think i figured it out

10:52 I shouldn't be doing (date-time now)

10:52 and only (now)

10:52 and that will return the current date-time

10:53 yup, that's it

10:53 thanks anyway. :)

12:00 kzar: init-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:07 stuartsierra: try C-j

12:07 kzar: stuartsierra: Oh sweet thanks

12:08 __name__: &(map (fn [& rest] rest) '(1 2 3) '(2 3 4) '(4 5 6))

12:08 sexpbot: ⟹ ((1 2 4) (2 3 5) (3 4 6))

12:08 __name__: \o/

12:09 raek: __name__: you can use the 'list' function too

12:28 rata_: hi

12:28 kzar: hey

12:32 cky: &(map list '(1 2 3) '(4 5 6) '(7 8 9))

12:32 sexpbot: ⟹ ((1 4 7) (2 5 8) (3 6 9))

12:33 cky: &(map list '(1 2 3) '(4 5 6) '(7 8 9 10))

12:33 sexpbot: ⟹ ((1 4 7) (2 5 8) (3 6 9))

12:33 cky: &(map list '(1 2 3 42) '(4 5 6) '(7 8 9 10))

12:33 sexpbot: ⟹ ((1 4 7) (2 5 8) (3 6 9))

13:09 __name__: raek: Thanks

14:20 thruspa: Hi, may I ask a totally newbie question?

14:22 raek: sure... go ahead!

14:27 wyrg: Just a question.

14:27 I type in clojure "Math/Pi" and it fails with "Unable to find static field".

14:28 raek: wyrg: all the letters in PI should be capital...

14:28 wyrg: Oh, thanks.

14:28 raek: &Math/PI

14:28 sexpbot: ⟹ 3.141592653589793

14:28 wyrg: The problem really is with:

14:29 java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment

14:29 same error.

14:29 lyonscf: Hey guys, does anyone have any experience with webmine?

14:29 wyrg: &java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment

14:29 sexpbot: java.lang.Exception: Unable to find static field: getLocalGraphicsEnvironment in class java.awt.GraphicsEnvironment

14:29 lyonscf: clj-sys/webmine that is. :)

14:30 raek: wyrg: do you have parens around it?

14:30 wyrg: I will try...

14:30 raek: &(java.awt.GraphicsEnvironment/getLocalGraphicsEnvironment)

14:30 sexpbot: ⟹ #<HeadlessGraphicsEnvironment sun.java2d.HeadlessGraphicsEnvironment@4f7dc0>

14:31 raek: since it's a method, you need to call it

14:31 wyrg: I see.

14:31 Thank you very much!

14:31 I'm just starting with LISP.

14:31 raek: np

14:34 p_l|home: wyrg: please avoid using the name LISP (with all caps). It refers to language that probably was used before you were born :P

14:34 Raynes: Haha.

14:34 I've always wondered why people still write that word in all caps.

14:35 p_l|home: Raynes: bad College courses

14:35 Raynes: AFAIK, even McCarthy doesn't anymore.

14:35 p_l|home: and FUD on the net

14:35 Raynes: McCarthy asked everyone not to name their languages just "lisp", no matter what case :)

14:36 wyrg: Thank you. As I said I'm new to clojure, so I think I will absorb the nuances little by little :-)

14:37 Raynes: But it's so much easier to shove them down your throat and be done with it! ;p

14:37 * p_l|home is even less than new to Clojure, has been concentrating on Common Lisp for last few years

14:38 Raynes: That explains the vocalness about not using writing Lisp in all caps.

14:39 p_l|home: Raynes: well, Clojure has the difference in name, Common Lisp gets all the wackos attracted to "LISP" -_-;

14:39 Raynes: technomancy: ping

14:40 fliebel: 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:47 p_l|home: Raynes: better, make it into a command language capable of looking like english sentences

14:47 (both easier and harder than it sounds)

14:59 rata_: chouser: what would be a good comparator fn for counted-sorted-sets to store maps? how is the comparator fn used there?

15:11 firepoet: Hey all.. Java interop question...

15:13 I have a function: (defn -editCardWithAction [this user board-id card-id actions]

15:13 (let [action-blocks (.split actions ";")]

15:13 (do

15:13 (.info logger (str "edit card with: " (alength action-blocks)))

15:13 (map #(.info logger (str "perform card action: " %)) action-blocks))))

15:14 And 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:14 0 [main] INFO com.pegby.service.clj.boardUpdate - edit card with: 3

15:14 7 [main] INFO com.pegby.service.clj.boardUpdate - perform card action: first: something

15:14 7 [main] INFO com.pegby.service.clj.boardUpdate - perform card action: second: else

15:14 7 [main] INFO com.pegby.service.clj.boardUpdate - perform card action: third: stuff

15:14 (nil nil nil)

15:14 rata_: firepoet: use gist.github.com

15:15 firepoet: Oh sorry.

15:18 So the gist is: https://gist.github.com/729428

15:18 :-)

15:18 raek: firepoet: also, you should use doseq (or something similar) instead of map if you only care about the side-effects of the function

15:18 firepoet: Ah

15:18 raek: firepoet: what was the question? :-)

15:18 firepoet: There was a time when I cared about the result as well.

15:19 At least for testing, since some of the functions actually return stuff I care about.

15:19 So the question is why it doesn't seem to be calling the map function at all..

15:19 But only when I compile the clojure code and run it as a Java class.

15:19 Works great on the REPL.

15:20 raek: fliebel: that is because the repl will print, and therefore force, every element of the sequence map returns

15:21 the function will only be ivoked when elements are forced

15:21 firepoet: Ohh.

15:21 _ato: if you care about the return value and also want to force the lazyseq: wrap the map call in (doall ...)

15:22 firepoet: Lazy sequences to the rescue!

15:22 Great..lemme test..

15:24 So is doall supposed to throw an NPE if the result is a seq of nils?

15:25 (you can tell I'm a java programmer trying to learn clojure.. hehe)

15:26 LauJensen: Morning all :)

15:26 firepoet: _ato: I tried your suggestion, and it got further, but is now throwing a NullPointerException

15:27 lyonscf: What's the best way to debug clojure? Can anyone point me in the right direction? :)

15:27 I'm using emacs and swank-clojure

15:29 fliebel: Raynes: Another regex change? Sure. Want a commit, or can I tell you right away how to change the regex?

15:29 raek: Was that message for me?

15:30 rhickey: ping

15:32 rata_: lyonscf: I use swank-clojure to debug

15:32 just write (swank.core/break) where you want to know the value of locals

15:32 lyonscf: ah

15:32 firepoet: Great.. I worked through those issues and am now on to a new one. Thanks for your help!

15:32 lyonscf: awesome

15:32 have any useful links?

15:33 rata_: lyonscf: http://hugoduncan.org/post/2010/swank_clojure_gets_a_break_with_the_local_environment.xhtml

15:34 firepoet: New 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:35 (as in, it returns nil when compiled)

15:35 lyonscf: rata_: thanks. :)

15:37 fliebel: Raynes: 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:41 rata_: is it guaranteed that (= (seq m1) (seq m2)) if (= m1 m2), where m1 and m2 are hash-maps?

15:42 firepoet: So my new question: https://gist.github.com/729449

15:48 rata_: 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:51 rata_: so many questions I have

15:52 __name__: you can (concat s (repeat default-argument)) your shorter seqs

15:52 kevinjq: hello 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:52 hiredman: ,(map vector (concat [:a :b] (cycle [:default])) (range 10))

15:52 clojurebot: ([: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:53 rata_: __name__: no, you just need to know which one is the longest

15:53 hiredman: kevinjq: just like the exception says, not a class of a named thing

15:53 __name__: Fair enough, rata_

15:54 hiredman: __name__: do you see my map?

15:54 __name__: hiredman: Yes.

15:54 kevinjq: hiredman, 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:55 hiredman: kevinjq: why would they be?

15:56 kevinjq: hiredman, 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:57 hiredman: kevinjq: similar is not the same, that still doesn't seem to be a compelling reason

15:58 kevinjq: hiredman: 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:59 why should protocol be different?

15:59 hiredman: kevinjq: just because X can be optimized as Y it does not mean that X has the same semantics as Y

16:01 kevinjq: that's not reasoning

16:01 firepoet: *sigh* guess I hit an un-solveable one.

16:01 hiredman: it is

16:01 you are saying "protocols can be optimized as interfaces for some cases, so they should behave the same as interfaces"

16:02 rlb: chouser: 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:03 raek: fliebel: 21:30 < fliebel> raek: Was that message for me? <-- which one?

16:03 kevinjq: hiredman, 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:03 rlb: So you might have something like (with-process-context context ... set-up-and-use-commands-here)

16:04 hiredman: kevinjq: protocols don't create is-a relationships, so using them for type dispatch is not a good idea

16:04 protocols are not interfaces

16:04 firepoet: Ha! Figured it out. Java object methods aren't invoked in the same namespace as the other functions declared therein. Craziness.

16:04 kevinjq: hiredman, what do you suggest in this case?

16:05 firepoet: ns-resolve to the rescue

16:06 raek: firepoet: do you need to construct the symbol from a string?

16:06 hiredman: kevinjq: *shrug*

16:06 firepoet: Yeah.

16:06 kevinjq: hiredman, you keep saying protocol isn't interface, then do you mind sharing your vision of what protocol really is?

16:07 firepoet: raek: I figured it out. Replaced resolve with ns-resolve and all was well.

16:07 raek: the function name is derived from something a user sends in an email

16:08 hiredman: kevinjq: there are a number of videos on the web

16:08 vIkSiT: lo all

16:08 kevinjq: lol

16:08 hiredman: there is the protocol page on clojure.org

16:08 vIkSiT: whats the best method to have a function running as a background thread (for instance, a file tailer)?

16:09 raek: you can use future or future-call to start off something in another thread

16:09 vIkSiT: ah future-call.

16:09 great, thanks

16:09 let me experiment

16:09 kevinjq: hiredman, i read it. the reason for protocols are to provide abstraction/contracts, which is exactly what java interfaces are for

16:10 hiredman: kevinjq: again, just because two thigns are aimed at solving the same problem is does not mean they are the same

16:11 you obvisouly read up the point where you saw the word interface and said "oh, right, it's and interface" then tuned out

16:12 kevinjq: hiredman, 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:13 hiredman: kevinjq: 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:14 ~google stuart halloway expression problem

16:14 clojurebot: First, out of 516 results is:

16:14 Clojure 1.2 Protocols on Vimeo

16:14 http://vimeo.com/11236603

16:15 hiredman: chouser actually has a video on infoq where he discusses protocols vs. multimethods

16:17 kevinjq: hiredman, thanks anyway

16:17 vIkSiT: raek, hmm, couple of questions about futures and threads if you've got a minute

16:18 this is the function i'm using to tail a file: http://paste.lisp.org/display/117361

16:18 because of the Thread/sleep and recur, whenever I use this function in somehting like (doseq [line (tail-seq filename)] ... )

16:19 even with a future-call, the REPL basically gets taken over by this function and its output

16:19 would i have to use an agent to perhaps run this in the background?

16:21 (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:23 hiredman: sequences are a functional interation cosntruct

16:24 __name__: So I have laziness instead of iterators?

16:24 vIkSiT: hmm, so a different question. lets say i've got a function that generates random numbers and prints them.

16:24 a future would only run this function once - as opposed to keep it running in the background?

16:25 hiredman: __name__: not all sequences are lazy

16:27 jamesnvc: Hello

16:28 Question: Is there any reason why *agent* is suddenly turning nil, ina function that is only ever called by being sent to an agent?

16:30 hiredman: jamesnvc: sounds like you just switch to clojure 1.3

16:31 jamesnvc: Yup

16:31 1.3 has issues with that?

16:31 hiredman: the binding propagation stuff screws up *agent*, there should be a issue in jira for it

16:32 stuartsierra: it's fixed on master

16:32 jamesnvc: Alright

16:32 Um, if I'm using leiningen, is there any easy way to get that on master?

16:32 1.3.0-SNAPSHOT?

16:33 hiredman: jamesnvc: you have to wait for a snapshot build of master +/- a day

16:33 bmh: Is anyone else having trouble with clojars?

16:33 jamesnvc: hiredman: Thanks

16:34 bmh: (looks like the problem is on my end)

16:36 Raynes: In that case, no.

16:38 rata_: does anybody know why sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run() takes so much time when I profile a clojure app with visualvm?

16:40 raek: vIkSiT: you have to do the looping manually. future and future-call only evaluate the body / calls the function once

16:40 vIkSiT: raek, hmm. so basically a Thread/sleep and recur within the function?

16:41 raek: yes

16:41 vIkSiT: raek, I see. so would you recommend an agent for something like this, given their watch/error handling capabilities?

16:41 stuartsierra: Lazytest.next https://github.com/stuartsierra/lazytest/tree/next

16:42 raek: vIkSiT: if you have a state you want to serialize access to, I'd go for agents

16:42 vIkSiT: or, what are the best practices for the creation of a long running background thread?

16:42 raek, ah

16:44 raek: '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:45 chjames: help

16:45 raek: vIkSiT: when you doseq over that lazy sequence, you don't return until you have processed the *whole* sequence

16:45 but putting the doseq call in a separate thread should not block the repl thread

16:47 vIkSiT: raek, 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:47 raek: vIkSiT: futures also have error handling capabilities

16:48 deref/@ will throw the exception (wrapped) that the body threw

16:48 vIkSiT: ah I see

16:49 (or the return value, I take it)

16:49 raek: what is the problem you are solving?

16:49 what do you want to do in a separate thread?

16:49 vIkSiT: raek, i've got a file i want to tail in the background

16:50 that i want to keep running unless i explicitly want to stop it

16:50 for each new line in the file, i'd like to process it in some way

16:50 raek: one way could be to doseq over the lines in another thread

16:51 vIkSiT: hmm

16:51 perhaps wrap tail-seq into another thread?

16:51 raek: stepping through the sequence might block, but that would be ok if it happens in a background thrad

16:51 then what should the thread that waits for the next thing do?

16:52 vIkSiT: raek, id like it to call another function with the new line as a param.. (def myfn [newline] (process-line newline) (.. do more stuff ..))

16:52 raek: you could also consider using java.util.concurrent.LinkedBlockingQueue to build your app in a producer-consumer way

16:53 vIkSiT: raek, i'm using the lamina project's channels to do that

16:53 raek: (future (doseq [line (tail-seq ...)] (process-line line))) ?

16:54 lazy sequences are "pull driven"

16:54 vIkSiT: hmm

16:54 jamesnvc: Stupid question, but how do I get the 1.3.0 master in leiningen? 1.3.0-master-SNAPSHOT?

16:55 vIkSiT: ah

16:56 raek, that seems to work! now to see how to stop that :)

16:56 stuartsierra: jamesnvc: it's mis-versioned now as 1.3.0-alpha3-SNAPSHOT I think

16:56 jamesnvc: stuartsierra: Cool, thanks

16:57 vIkSiT: raek, for instance, i get this : http://paste.lisp.org/display/117361#1

16:57 in 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:00 raek, hmm this is the weird part.

17:00 if i wrap that in (defn myfn [] ...) and then (future-call (myfn filename))

17:00 raek: vIkSiT: 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:00 vIkSiT: the REPL thread still bocks on it.

17:00 raek: blocks on the future call?

17:00 vIkSiT: pasting..

17:01 raek, http://paste.lisp.org/display/117361#2

17:02 raek: vIkSiT: replace future-call with future

17:03 future-call takes a function. you try to give it the result of invoiking tailfn

17:03 (future <body>) is just sugar for (future-call (fn [] <body>))

17:05 vIkSiT: interesting. if i put a (future (..)) within the function body

17:05 it works as expected

17:05 perhaps there's a difference in the way future and future-call work

17:05 oh i see.

17:10 rata_: does anybody know why sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run() takes so much time when I profile a clojure app with visualvm?

17:21 is there a number for infinity in clojure?

17:22 fliebel: rata_: No ##(/ 1 0)

17:22 sexpbot: java.lang.ArithmeticException: Divide by zero

17:22 bmh: rata_: Double has NEGATIVE_INFINITY and POSITIVE_INFINITY

17:22 rata_: thanks =)

17:23 fliebel: bmh: What's inside it?

17:23 bmh: fliebel: 0x7ff0000000000000L http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Double.html#NEGATIVE_INFINITY

17:23 and 0xfff0000000000000L

17:33 __name__: Comments and constructive criticism appreciated: http://bpaste.net/show/12026/

18:40 cky: &(map (fn [op] (op Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY) `(,+ ,/))

18:40 sexpbot: java.lang.Exception: EOF while reading

18:40 cky: &(map (fn [op] (op Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)) `(,+ ,/))

18:40 sexpbot: ⟹ (-Infinity -Infinity)

18:41 cky: ...I must be doing something wrong.

18:41 &(+ Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)

18:41 sexpbot: ⟹ NaN

18:41 cky: &(/ Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)

18:41 sexpbot: ⟹ NaN

18:41 cky: There, that's better. :-D

18:41 &`(,+ ,/)

18:41 sexpbot: ⟹ (clojure.core/+ clojure.core//)

18:42 cky: &(map (fn [op] (op 2 5)) `(,+ ,/))

18:42 sexpbot: ⟹ (5 5)

18:42 tonyl: why the commas

18:42 cky: tonyl: They're unquotes.

18:43 `(+ /) is the same as '(+ /): two symbols in a list.

18:43 tonyl: oh, I thought it was only whitespace and ~ was to unquote

18:43 cky: `(,+ ,/) is a list with two function objects.

18:43 Hmm, maybe you're right.

18:43 `(~+ ~/)

18:43 &`(~+ ~/)

18:43 sexpbot: ⟹ (#<core$_PLUS_ clojure.core$_PLUS_@1ba24d5> #<core$_SLASH_ clojure.core$_SLASH_@b48593>)

18:43 cky: Ah, much better.

18:44 tonyl: Thanks. :-)

18:44 &(map (fn [op] (op Double/POSITIVE_INFINITY Double/NEGATIVE_INFINITY)) `(~+ ~/))

18:44 sexpbot: ⟹ (NaN NaN)

18:44 cky: \o/

18:44 tonyl: np

18:44 cky: (Old Lisp habits have a way of sticking around. :-P)

18:45 tonyl: what does the comma mean in old lisp? I am new to lisp

18:45 cky: tonyl: In traditional Lisp, comma is unquote.

18:45 tonyl: oh

18:46 cky: Let's try one more thing....

18:46 &`(1 2 ~@(map - '(1 2 3)) 3 4 5)

18:46 sexpbot: ⟹ (1 2 -1 -2 -3 3 4 5)

18:46 cky: \o/

18:47 tonyl: In traditional Lisp, ,@ is "unquote-splicing". Glad to see that ~@ works the same way here.

18:48 tonyl: yeah, i wasn't aware of the change in lisps, did ~ meant something else in other lisps?

18:49 cky: I don't think ~ has any special meaning in other Lisps. At least, not in Scheme.

18:49 rata_: lets inside a fn are compiled as ns$fn-name$fn_xxx?

18:49 hiredman: rata_: no

18:49 tonyl: cky: a little more info if you want http://clojure.org/reader

18:50 cky: Thanks! Hopefully the info will stick this time. :-)

18:51 rata_: *ns$fn-name$fn__xxx?

18:51 or are fors compiled as ns$fn-name$fn__xxx?

18:52 cky: tonyl: O_o Wow, apparently viewing that page on w3m (a least on Ubuntu 9.10) causes a segmentation fault.

18:54 tonyl: wow, let me try it

18:54 rata_: how are lets compiled?

18:55 tonyl: cky: it worked in my machine (ubuntu 10.10) but it took a couple of mins

18:55 cky: I searched for "unquote" (which found the first instance successfully). Pressing "n" to find the next instance caused the segfault.

18:56 It doesn't happen every time, but I've managed to replicate it 3 times.

18:56 tonyl: oh weird

18:56 cky: ...yeah. I must try upgrading to 10.10 and see where I get.

19:25 DietCokeIsMyBloo: can someone clarify the difference between the rem and mod operators

19:28 tonyl: I think the only difference that mod truncates toward negative infinity

19:30 DietCokeIsMyBloo: i saw that, but i don't know what that means

19:32 tonyl: mod 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:32 $source mod

19:32 sexpbot: mod is http://is.gd/igoOF

19:34 DietCokeIsMyBloo: ok.

19:34 i think i got it

19:34 danke :)

20:18 got another question

20:19 it's a recursion qustion

20:19 what's happening in line 3

20:19 http://codepad.org/QQRU8Gqp

20:20 is that way you go from a fxn with a single variable to 2? or is there some annonymous function stuff going on?

20:46 tomoj: DietCokeIsMyBloo: basically, it's defining a default value for the acc parameter

20:46 when you call factorial-2 with one arg, it's n

20:46 then it calls itself with 1 and your n

20:47 so 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:47 DietCokeIsMyBloo: i get that part.. like what's it doing.. do i need to worry about the how thogh?

20:47 tomoj: the how is simple, it just calls itself

20:48 the function is called factorial-2

20:48 on line three you see just a function call to factorial-2, passing in 1 and n as args

20:48 DietCokeIsMyBloo: so on line 7- when it recurs, what happens?

20:48 tomoj: the one-arg version of the function is just calling the two-arg version of the function

20:49 then, the two-arg recurs to itself

20:49 say you pass in acc 1 and n 3

20:49 DietCokeIsMyBloo: it 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:50 at which point, it calls the fxn which takes 1 arg

20:50 tomoj: 3 isn't equal to 1, so it recurs, calling itself with (* 3 1) = 3 and (dec 3) = 2

20:50 now 2 isn't equal to 1, so it recurs again, calling itself with (* 2 3) = 6 and (dec 2) = 1

20:50 now 1 is equal to 1, so it returns 6, 3!

20:51 the one-arg version calls by name because you can't recur from a one-arg to a two-arg

20:51 if you recur, you have to use the same number of arguments as the version you're defining (the two-arg in the example)

20:52 DietCokeIsMyBloo: what languages do you already know?

20:52 java, c++, ruby, python, anything like that?

20:53 DietCokeIsMyBloo: java and c

20:53 i know recursion

20:53 tomoj: ok, so say you were doing this in java, how would you do it?

20:53 int acc = 1;

20:53 then acc *= i; in a loop?

20:54 DietCokeIsMyBloo: well, i'd do 2 functions( defn factorial-2 [n] factorial-helper [n 1] )

20:54 and then have factorial helper do the rest

20:54 oh sorry- you said java

20:54 tomoj: well, yeah, that would work too

20:54 the thing is, you don't want to defn factorial-helper really

20:54 because that's not something anyone will probably call

20:54 DietCokeIsMyBloo: why's that?

20:55 tomoj: I don't think you want to define a two-arg version of factorial, either, really

20:55 DietCokeIsMyBloo: agreed

20:55 tomoj: no one will use it

20:55 DietCokeIsMyBloo: so, one more time

20:55 tomoj: the fact that we're threading an accumulator through arguments is an internal detail

20:55 DietCokeIsMyBloo: fact-2 takes 1 arg n initially

20:56 changes it into a 2 arg fxn

20:56 does stuff, recurs

20:56 with the new accumulator and dec'd n

20:57 and 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:57 i'm missing something there...

20:58 how the fxn knows it can take 2 args...

20:58 lucian: DietCokeIsMyBloo: you don't need 2 args

20:59 tomoj: when you call the function, you either pass in one arg or two args

21:00 the appropriate version in the defn is used

21:00 lucian: DietCokeIsMyBloo: if you get the chance, read "The Little Schemer"

21:00 DietCokeIsMyBloo: is that what line 4 means?

21:00 lucian: it's great for learning recursion

21:01 tomoj: when 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:01 DietCokeIsMyBloo: sorry- let me be more specific- does line 4 mean, that it can take 2 args?

21:01 tomoj: yeah

21:01 you can either define a single arity like this: (defn foo [x y] ...)

21:01 or multiple arities like this: (defn foo ([x] ..) ([x y] ..) ([x y z] ..))

21:02 DietCokeIsMyBloo: ahh

21:02 this was where the confustion was....

21:02 tomoj- you're a superstar!

21:02 yes, that's what you are my friend!

21:02 tomoj: anonymous fns can do it too

21:03 DietCokeIsMyBloo: oh

21:03 let me try an annon fxn instead for this

21:03 brb

21:04 tomoj: ,((fn fact ([n] (fact 1 n)) ([a n] (if (= n 1) a (recur (* n a) (dec n))))) 20)

21:04 clojurebot: 2432902008176640000

21:04 tomoj: but really the two-arg version should be hidden I'd think

21:04 lucian: and if you're curious you can do this with one arg, but it's no longer constant space

21:05 tomoj: meaning it might overflow the stack?

21:05 DietCokeIsMyBloo: got it

21:05 lucian: tomoj: the recur version is tail recursive

21:05 tomoj: right

21:05 your one-arg version isn't?

21:06 lucian: nope, all call stacks exist

21:06 &(defn fac [n] (if (= n 1) 1 (* n (fac (- n 1)))))

21:06 sexpbot: java.lang.SecurityException: You tripped the alarm! def is bad!

21:06 lucian: meh

21:06 tomoj: oh, right

21:06 lucian: &((fn fac [n] (if (= n 1) 1 (* n (fac (- n 1))))) 10)

21:06 sexpbot: ⟹ 3628800

21:06 tomoj: wonder what types fact should use

21:10 interesting: (loop [acc (bigint 1) n (int n)] ...) with (* n acc) in the recur gives auto-growing results

21:10 integer, long, or BigInteger, whichever is big enough for the answer

21:10 I would've thought that if you started with bigint it would always be a BigInteger

21:11 lucian: since they're immutable, stuff like this is easy

21:12 stuff like this = promoting/demoting ints

21:12 cky: lucian: Does Clojure actually have tail calls? http://clojure.org/functional_programming suggests it doesn't.

21:13 lucian: cky: afaik it uses recur for the same results

21:14 cky: Ah. :-)

21:14 tomoj: it just won't automatically recognize tail calls

21:15 cky: Darn. I was gonna read up on recur, but, my browser crashed again. :-P

21:15 tomoj: you must use recur and you must do it in tail position

21:15 cky: tomoj: *nods*

21:15 lucian: i think it's quite nice and explicit

21:15 even if clojure had tail calls, i'd still use recur

21:17 cky: Okay, so, this is a complete n00b question, but, is it possible to recur to the non-innermost loop/fn?

21:31 DietCokeIsMyBloo: can you help me with filter?

21:31 if i have a list of numbers, and i want to filter out the odds what would it be?

21:32 (filter (predicate) lst)

21:32 but the predicate is what i don't know...

21:32 (fn[x] (odd? x) true) is not right....

21:33 i just need to get rid of the true

21:33 but i don't get why

21:34 so, the result WOULD be, (filter (fn[x] (odd? x) ) lst).... but why?

21:34 headlessClown: it's not just (filter odd? lst)?

21:35 DietCokeIsMyBloo: i didn't try that one

21:35 but don't you need a true false condition for the predicate?

21:35 or is that the way filter works...

21:35 tonyl: odd? is a fn that returns true or false

21:35 DietCokeIsMyBloo: right

21:35 headlessClown: it's all baked in

21:35 tonyl: usually fns endind in ? do that

21:35 DietCokeIsMyBloo: ok

21:36 so 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:37 cky: &(odd? Double/POSITIVE_INFINITY)

21:37 sexpbot: java.lang.ArithmeticException: bit operation on non integer type: class java.lang.Double

21:37 tonyl: diateCokeIsMyBloo: yea

21:37 cky: Well, that makes it pretty obvious how odd? is implemented. :-P

21:38 tonyl: $source odd?

21:38 sexpbot: odd? is http://is.gd/igDKd

21:38 cky: tonyl: Does tab completion not work on your IRC client?

21:38 tonyl: I don't know. I am pretty new to IRC, I am using XChat

21:39 cky: Ah, I think if you type "di<TAB>" (where <TAB> is your tab key), it should complete the rest.

21:39 tonyl: oh snap, it does. thanks

21:39 cky: \o/

21:39 DietCokeIsMyBloo: maybe i need a break for a bit :)

21:40 thanks guys

21:40 cky: And yeah, even? and odd? are implemented the way I thought it was (given the error message :-P).

21:40 tonyl: using bit-and

21:43 cky: Yep.

22:15 brehaut: xcthulhu: fhtagn

22:15 xcthulhu: Indeed

22:16 This is hardly a #clojure question, but what are good channels for embedded system development?

22:16 Although I'm holding out that clojure will harken the second coming of the lisp-machine...

22:21 No bites... alas...

22:24 cky: My 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:25 Your OS also needs to support loading .class files, or at least some format the Java class libraries can be compiled into.

22:25 trytotrace: hi. I have a question about tracing. anyone here has done it the lisp way on clojure?

22:25 cky: The topic of writing fully-managed Lisp-based OSs is a not-infrequent topic in #scheme.

22:25 xcthulhu: ^^---

22:27 trytotrace: is it possible to shadow a function during runtime for tracing?

22:32 jweiss: i'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:33 so 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:35 cky: jweiss: 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:35 Derander: as a ruby programmer: damn performance, pour on the sugar!

22:36 cky: Derander: Hahahaha.

22:36 jweiss: yeah 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:37 cky: jweiss: Indeed. Really, either approach is fine. Just truck along with what you have.

22:37 jweiss: cky: by human readable, i mean, readable by non programmers

22:37 cky: jweiss: Of course.

22:38 jweiss: 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:40 jweiss: cky: 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:41 if there's just going to be a canonical definition of the test it should be the code

22:43 Derander: jweiss: you'll care about performance after your cucumber/rspec tests take 45 seconds to run :-

22:43 :-)

22:43 jweiss: hah i wish

22:43 we have selenium tests that take 12 hours

22:43 Derander: oh yeah, I'm just talking about two basic scenarios

22:43 jweiss: not a single test mind you, hundreds of them

22:44 Derander: asdf. <3 ruby, but it's painfully slow sometimes.

22:44 jweiss: i'm not a big fan of cucumber's style of testing

22:44 Derander: at least it's really obvious when you have an inefficient algorithm in ruby...

22:44 jweiss: I am for some things

22:44 jweiss: too much dependency on regex

22:45 Derander: I have some of the people at my place of employment almost trained to write them for me

22:45 so the help desk people can write my specs

22:45 hippiehunter: is it possible to destructure into params for a function?

22:45 jweiss: hippiehunter: i'm pretty sure that works the same way

22:45 xcthulhu: jweiss, Does clojure have a fast regex, like google's re2?

22:46 I seem to recall that google's re2 was linear time (rather than exp like ordinary implementations)

22:46 jweiss: xcthulhu: i don't know

22:46 my problem with cucumber's use of regex has nothing ot do with performance

22:47 it's just that if you change your english spec, you have to dig up your regex and fix that

22:47 even if there's no real change in behavior

22:47 Derander: trade-offs must be made

22:47 jweiss: yup

22:47 it's good at what it does

22:47 it's just not a good fit for me

22:48 Derander: https://github.com/cavalle/steak <-- this is a cucumber alternative

22:48 less english but more code

22:48 s/but//

22:48 sexpbot: <Derander> less english more code

22:48 hippiehunter: :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:50 jweiss: hippiehunter: hm i take that back

22:50 i guess you can't destructure in the param list of a fn definition

22:50 ,(defn [ [x y] ] (+ x y))

22:50 clojurebot: java.lang.IllegalArgumentException: Parameter declaration + should be a vector

22:52 hiredman: jweiss: you are missing something there

22:52 jweiss: oh yea

22:52 ,(defn foo [ [x y] ] (+ x y))

22:52 clojurebot: DENIED

22:52 jweiss: doh

22:52 tonyl: &((fn [[x y]] (str x "." y) [4 5])

22:52 sexpbot: java.lang.Exception: EOF while reading

22:52 tonyl: &((fn [[x y]] (str x "." y)) [4 5])

22:52 sexpbot: ⟹ "4.5"

22:52 jweiss: ok i take it back again hippiehunter - it does work

22:53 (defn foo [ [x y] ] (+ x y))

22:53 (foo [1 3])

22:53 4

22:53 * jweiss should just go to bed

22:53 cky: &((fn [(x y)] (+ x y)) '(4 5))

22:53 sexpbot: java.lang.Exception: Unsupported binding form: (x y)

22:53 cky: &((fn [(x . y)] (+ x y)) '(4 . 5))

22:53 sexpbot: java.lang.Exception: Unsupported binding form: (x . y)

22:53 tonyl: &((fn [[x y]] (+ x y)) [4 5])

22:53 sexpbot: ⟹ 9

22:53 hippiehunter: does food need to be defined in terms of [[x y]] or is there a way without the nested vector?

22:53 cky: tonyl: I'm trying to see if one can get away from vectors.

22:53 hippiehunter: err foo

22:54 tonyl: no, i think only maps and vectors

22:54 cky: Oh well.

22:54 It seems in Clojure vectors are much more first-class than they are in other Lisp dialects.

22:54 jweiss: hippiehunter: it works the same way as with let

22:55 except you aren't assigning a value until you call the function

22:55 cky: In other Lisp dialects I've seen, vectors are very much second-class, to be used only for specific cases.

22:55 * jweiss is headed out

22:55 cky: (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:55 hippiehunter: right but the called method needs to be aware of this

22:56 i was hoping to turn a map into the parameters for an arbitrary function

22:57 Derander: you can do it with a map

22:57 hippiehunter: I suppose in my case (constructor) i can just make a plain one, then assoc it in

22:58 tonyl: you can destructure maps

22:59 Derander: ,(defn foo [{a :a b :b}] (+ a b))

22:59 clojurebot: DENIED

22:59 Derander: ,((fn [{a :a b :b}] (+ a b)) {:a 1 :b 2} )

22:59 tonyl: &((fn [{x :x y :y}] (+ x y)) {:x 5 :y 9})

22:59 clojurebot: 3

22:59 sexpbot: ⟹ 14

22:59 Derander: haha

23:00 good timing

23:00 tonyl: haha yeah

23:00 took me a while to test it first :P

23:01 Derander: how do you use :keys for destructuring? I can never remember

23:01 Derander: no clue

23:01 tonyl: mm

23:02 found it ##((fn [{:keys [x y]}] (+ x y)) {:x 5 :y 9})

23:02 sexpbot: ⟹ 14

23:02 Derander: ah

23:03 interesting

23:03 brehaut: there are equivalents for strings and maybe symbols(?) too

23:04 :strs and :syms

23:04 tonyl: brehaut: how do you use those?

23:05 brehaut: ,(let [{:strs [a b]} {"a" 1 "b" 3 "c" 3}] (+ a b))

23:05 clojurebot: 4

23:05 brehaut: ,(let [{:syms [a b]} {'a 1 'b 3 'c 3}] (+ a b))

23:05 clojurebot: 4

23:06 brehaut: syms is probably more useful in a macro than normal code?

23:06 tonyl: ooh great to know

23:06 hippiehunter: holy crap thats awsome, that makes dealing with json so much better

23:06 brehaut: http://clojure.org/special_forms

23:06 its all in there

23:07 yup, destructuring + multimethods = super json powers

23:10 cky: brehaut: 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:11 brehaut: not in person

23:11 cky: Ah, okay.

23:11 brehaut: we live about 2 hours drive apart

23:11 cky: ...is that 2 hours from Auckland, or 2 hours from Napier? :-P

23:11 brehaut: two hours from auckland

23:11 actually, its possible both :P

23:12 cky: (Napier is talios's hometown, IIRC, hence my question. :-P)

23:12 brehaut: ah, 3.45 hours

23:12 cky: Hehehehe.

23:12 brehaut: im in hamilton

23:12 bustling metropolis of cows

23:12 cky: Nice. We (the social circle that I know talios from) have people who live in Hamilton, too.

23:13 brehaut: oh true

23:13 cky: But, yeah, some shade of small world. :-)

23:13 brehaut: yeah :)

23:14 its frighteningly likely that there might be someone incommon :P

23:14 cky: That wouldn't surprise me in the slightest.

23:14 Heh, 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:14 brehaut: hah

23:15 wherer are you from?

23:15 cky: Well, I'm an Aucklander, but, I don't actually currently live in New Zealand.

23:15 brehaut: oh right

23:15 cky: In fact, in terms of small world, I live in the same city as Relevance. :-P

23:15 brehaut: hah

23:16 cky: (Not by intention---I've only heard about Relevance some time after I've lived in Durham.)

23:24 So, since I'm new to the channel and all, what's the difference between sexpbot and clojurebot? :-)

23:24 brehaut: maintainer and various additional magic mostly?

23:25 cky: Okay, so, does it matter which one I pick on?

23:25 brehaut: i dont think so?

23:25 https://github.com/raynes/sexpbot

23:25 cky: Okie dokie. :-)

23:26 I 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:27 pdk: clojure had a .net version at least early on

23:27 it's probably still maintained but second fiddle to the java one

23:27 cky: pdk: It's still there.

23:27 hiredman: I have a clojure interpreter (written in clojure) I've been thinking about switching clojurebot too for better sandboxing

23:27 cky: Nice.

23:27 pdk: scheme implementations it seems have crap cross compatibility

23:27 p_l|home: "crap" is a superlative

23:28 a positive one, in this case :>

23:28 cky: p_l|home: ...it is?

23:28 pdk: oh you

23:28 cky: pdk: 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:29 Porting between implementations is, well, not free of work.

23:29 p_l|home: the SRFIs don't cover enough... then you have the fact that SRFI coverage differs among implementations

23:29 cky: p_l|home: ...and that the syntax for loading SRFIs are not portable, either.

23:29 p_l|home: especially which ones are implemented by code shipped with them

23:29 cky: true

23:30 hiredman: that 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:30 p_l|home: Racket avoids the whole issue by renaming itself and differentiating from Scheme family

23:30 cky: Indeed, Racket is...its own language.

23:31 * p_l|home still sticks to CL, mostly. Though Clojure seems to mesh with JVM nicer than ABCL for some stuff

23:32 pdk: how do clojure and abcl usually compare for speed now

23:32 p_l|home: pdk: hard to compare, IMHO

23:32 pdk: well are there some rules of thumb

23:32 p_l|home: ABCL when running compiled has definitely respectable performance, and might have less GCing than Clojure

23:33 the big slow point of ABCL got fixed few years ago, but still floats in information available on internet

23:34 recently hashtables got fixed (switchover from ABCL own code to JVM native)

23:44 pdk: what was the achilles heel with abcl for so long that you're referring to

23:44 is it just the hashtable implementation or

23:46 p_l|home: pdk: it had some issues in CLOS speed

23:47 it still shows up in the material on the net, but has been actually fixed for quite long time

23:47 pdk: does working with cl structs still perform well

23:48 could always roll it paul graham style and go "YEAH WELL FORGET YOU CLOS I NEVER NEEDED YOU ANYWAY"

23:48 p_l|home: pdk: now it doesn't matter, both structs and classes work fasst

23:48 pdk: gotta look into that stuff again

23:48 p_l|home: pdk: some people claim that he never learned CLOS :P

23:48 pdk: so i could do something interesting with graham's lisp book besides reading it again

23:49 p_l|home: pdk: which book?

23:49 pdk: it always struck me like the guys coming from c to c++ who went back because they said structs were good enough

23:49 ansi common lisp

23:49 p_l|home: afaik people don't really recommend that book

23:50 Graham has some style bloopers, at least compared to "lingua franca" of CL style

23:51 cky: p_l|home: On CL boks, what's your take on Practical Common Lisp?

23:51 p_l|home: cky: wonderful :)

23:51 cky: p_l|home: I'm trying to decide how high or low to put it on my reading list. :-)

23:51 Good, I'll bump it right to near the top.

23:51 p_l|home: or, to quote Xach, “dead sexy”

23:51 cky: (Programming Clojure is currenty at top. I think PCL can be #2, at the mo.)

23:54 p_l|home: cky: 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:54 DietCokeIsMyBloo: i have a beginner's question about using iterate

23:54 pdk: i should go back and finish pcl

23:54 DietCokeIsMyBloo: the question is: write an expression using iterate to return a list of squares of numbers btw 5 and 15

23:55 pdk: where do you find the symbolic computation one

23:55 cky: p_l|home: Thanks for that, I'll add that to my list too.

23:55 pdk: is this for some sort of assignment or can you use something instead of iterate

23:55 DietCokeIsMyBloo: I have it written but was wondering if there is a cleaner way

23:55 http://codepad.org/2gAKOmaO

23:55 gotta use iterate

23:55 cky: Hahahahahaha.

23:56 pdk: if you're going to use iterate that way looks fine to me

23:56 DietCokeIsMyBloo: is there a "better" or cleaner way?

23:56 p_l|home: pdk: gentle: "Common Lisp: A Gentle Introduction to Symbolic Computation" is a smoother introduction to lisp programming. http://www.cs.cmu.edu/~dst/LispBook/

23:56 pdk: though for dinky 1-argument lambdas i'd prefer to say #(* % %) instead of (fn [x] (* x x))

23:57 DietCokeIsMyBloo: can i do it without using map?

23:57 p_l|home: cky: FYI - recently released Land of Lisp, while concentrating on CL, also has a chapter on clojure afaik

23:57 pdk: i 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:57 cky: p_l|home: Wow, that's quite the tour of Lisp languages...wonder if it covers Arc too. :-P

23:57 pdk: land of lisp is the games coding one right

23:57 DietCokeIsMyBloo: ok :)

23:57 thanks pdk!!!

23:58 cky: pdk: I think so, yes.

23:58 p_l|home: cky: it does in one chapter :P

23:58 pdk: i 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:58 cky: pdk: It came #23 in sales on the O'Reilly ebook Cyber Monday sale. :-P

23:58 pdk: does it still yknow try to teach you lisp for real

23:58 Derander: it was available from o'reilly for like $10 during their 60% off ebooks

23:58 cky: Derander: Jinx!

23:58 pdk: oh snap is the sale already over

23:58 Derander: cky: :-)

23:58 pdk: yeah

23:58 pdk: it's my understanding that it does

23:58 p_l|home: pdk: it's quite good, I haven't read the whole thing yet, waiting to obtain it through official channels :)

23:58 Derander: I haven't started it though

23:59 pdk: is that code for "i pirated the kindle version"

23:59 p_l|home: pdk: if you know _why's poignant guide to ruby, it's done in similar wayu

23:59 *way

23:59 cky: I 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:59 p_l|home: pdk: No, not the kindle version, Kindle sucks at formatting :P

23:59 pdk: i've only heard of why's guide

23:59 i bought elementary standard ml off kindle store cause for some dopey reason

Logging service provided by n01se.net