#clojure log - Aug 03 2009

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

1:31 mebaran151: I'd like to have a version of concat that stops concatting at nil

1:33 something like concat while

1:33 cark: someting like (apply concat (take-while ...

1:34 mebaran151: will take-while respect laziness?

1:34 hiredman: ,(doc take-while)

1:34 clojurebot: "([pred coll]); Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects."

1:34 cark: ,(apply concat (take-while identity [[1 2 3] [:a :b :c] nil]))

1:34 clojurebot: (1 2 3 :a :b :c)

1:35 mebaran151: thanks you all

1:36 that did the trick nicely

1:36 I now have lazy cursors over berkeleydb which is pretty sweet

1:36 cark: nice =)

1:38 mebaran151: is there any reason why iterate always pulls the first iterations of its series?

1:39 ,(take 2 (iterate #(prn %1) "no"))

1:39 clojurebot: ("no" nil)

1:39 mebaran151: first three iterations?

1:40 that example didn't show it, but it all seems to prefetch the first three chunks

1:40 cark: hum it used to be like that i think, but not anymore

1:41 what version of clojure are you using ?

1:43 mebaran151: the 1.0 that comes with enclojure

1:44 I think it's from may

1:44 I don't mind the behavior, because for this application, a little prefectching is actually a pretty good idea

1:45 cark: 1.0 should not show this behaviour

1:45 my guess is that your code is to blame =)

1:45 mebaran151: mine too

1:45 but it's exactly three

1:46 I'll lisp paste the relevant functions

1:46 cark: i'm using an even older version, and i can't reproduce that

1:46 mebaran151: ~lisppaste

1:46 clojurebot: Titim gan éirí ort.

1:46 cark: clojurebot: paste?

1:46 clojurebot: lisppaste8, url

1:46 lisppaste8: To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.

1:47 mebaran151 pasted "iterate likes to pull" at http://paste.lisp.org/display/84653

1:48 mebaran151: db-list always pull the first three mores, as verified by my juvenile prn statement

1:49 these statements are not recomputed, and the laziness works as before

1:50 jonase: ,(for [x (range 1 10) y (range 1 10) :while (= y 2)] [x y])

1:50 clojurebot: ()

1:50 jonase: ,(for [x (range 1 10) y (range 1 10) :while (= x 2)] [x y])

1:50 clojurebot: ([2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [2 8] [2 9])

1:50 jonase: :while confuses me.

1:53 cark: mebaran151: sorry i can't help you on this

1:53 mebaran151: no problem

1:53 so it's nothing super obvious?

1:55 cark: i think you're looking at the wrong place ...

1:55 you have these loops in fetch and more

1:55 mebaran151: (def ts (apply concat (iterate (fn [x] (prn "MOAR")) 2)))

1:55 clojurebot: x is y

1:55 mebaran151: that function displays the exact same behavior

1:56 ,(def ts (apply concat (iterate (fn [x] (prn "MOAR")) 2)))

1:56 clojurebot: DENIED

1:56 mebaran151: printed 3 times to my screen

1:57 I think it must be in the application of concat, as concat works through its 3 overloaded forms

1:58 cark: that makes sense

1:58 mebaran151: ,(apply concat (iterate (fn [x] (prn "MOAR")) 2)))

1:58 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

1:59 mebaran151: ,(apply concat (iterate (fn [x] (prn "MOAR")) 2))

1:59 clojurebot: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: Integer

1:59 mebaran151: ,(apply concat (iterate 2 (fn [x] (prn "MOAR")))

1:59 clojurebot: EOF while reading

1:59 cark: ~def concat

1:59 mebaran151: anyway to get a concat that doesn't do this

1:59 ?

2:00 ,(apply concat (iterate 2 (fn [x] (prn "MOAR"))))

2:00 clojurebot: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn

2:00 cark: use lazyseq

2:00 make a function forit

2:01 mebaran151: so I'd just recursively hit that function or something?

2:01 cark: ~doc mapcat

2:01 clojurebot: It's greek to me.

2:02 cark: ~def mapcat

2:02 mhh nope

2:03 mebaran151: it isn't that big deal: in fact it's downright useful for use in db-list (where I'd probably write some prefetching logic anyhow)

2:04 cark: i'm pretty sure you can do this with lazy-seq ...but yes if it's usefull why bother =)

2:06 mebaran151: my other option is just to pad it with nils

2:07 cark: that's ugly =/

2:08 mebaran151: then it only hits me once

2:11 yep

2:11 padding with three nils makes it all work out okay

2:13 (apply concat (concat [nil nil nil] (iterate (fn [n] (prn "MOAR") n) [2]))))

2:13 nasty looking but functional

2:17 ,(apply concat (concat [nil nil nil] (iterate (fn [n] (prn "MOAR") n) [2]))))

2:17 clojurebot: Eval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space

2:18 mebaran151: I didn't see that one coming.....

3:00 LauJensen: Top of the morning gents

6:01 cgrand: Hi LauJensen!

6:01 LauJensen: Mr. Grand! Good to see you

7:32 JimiDini: Hi

7:33 sopi: I got your question about status of data. Unfortunately I don't have access to verify the status. X-Fade does

7:41 Fossi: is the only way to get a float[] (make-array (. Float TYPE) ) and putting stuff in there? or is there a way to use into-array or such?

7:42 Chousuke: Fossi: (into-array Float/TYPE your-seq)?

7:43 (You should really avoid using . directly. it's so ugly :()

7:43 Fossi: Chousuke: i got the (. from the docs ;p

7:44 Chousuke: well, Float/TYPE does expand to (. Float TYPE)

7:44 ... hmm

7:44 Fossi: ah. great http://clojure.org/java_interop#toc27 doesn't mention the type variant

7:45 Chousuke: Actually, I wonder what Clojure does if a class had a static field identical to an instance field in Class

7:45 because then (. FooClass fieldName) would be ambiguous

7:48 hmm, looks like it will choose the static field for that form.

7:48 Fossi: ah, even better: (float-array 10)

8:24 angerman: yep, :)

8:38 rhickey: git question: we have both a tag and a branch 1.0 in the clojure repo, whenever I do anything with git with 1.0 I get a "warning: refname '1.0' is ambiguous.", but it seems to proceed. What does it use by default, the branch or tag?

8:43 Chouser: #git says: see man git-rev-parse. The tag takes precendence.

8:43 rhickey: so, git checkout 1.0 pulls the tag

8:43 how do we apply patches to 1.0?

8:44 opqdonut: checkout, git-apply, commit?

8:44 rhickey: opqdonut: the question is about disambiguating the tag from the branch

8:45 opqdonut: have you tried "git checkout branches/1.0"

8:45 err, "heads/1.0" that should be

8:46 If you happen to have both heads/master and tags/master, you can explicitly say heads/master to tell git which one you mean.

8:46 says git-rev-parse

8:47 rhickey: so anyone who says checkout 1.0 will always get the tag snapshot and everything else we need to do with the branch needs to be qualified?

8:47 opqdonut: basically, yes

8:47 rhickey: ugh

8:47 angerman: rhickey: did you ask in #git already?

8:48 rhickey: angerman: no

8:48 angerman: found them helpful the last time I asked ;)

8:48 rhickey: we need to make a policy decision as to whether we want to work that way, no patches applied to 1.0 yet afaik

8:49 this is just what we got be default from the svn import

8:49 Chouser: I think that's right. can we rename the tag to 1.0.0 ?

8:49 rhickey: by default

8:50 opqdonut: release-1.0.0 or something might be a better tag name

8:50 rhickey: Chouser: I don't think you can rename tags once people have seen them

8:50 Chouser: ugh

8:50 * angerman hurts him for knowing too little about clojure yet :)

8:53 * angerman wonders if there is a generic AbstractTableModel proxy macro for clojure.

8:54 Chouser: bleh. maybe rename the branch (or create a new one) 1.0.x

9:07 angerman: how does clojure handle the keyword arguments?

9:07 Chouser: it doesn't.

9:07 or put another way, what keyword arguements?

9:08 angerman: like in (gen-class :extends )

9:09 I'm wondering how I could rewrite my database abstraction layer to be lisp agnostic... I like clojureql's approach, but maye (query "MyKind" :where (and (= ...)) :order-by xyz)

9:09 but if clojure does not support keyworded arguments by default, I guess I'll just not use them

9:12 durka42: not by default, but you could construct something with hash-map

9:12 Chouser: you could use clojure.contrib.def/defnk

9:18 angerman: ohh dang. I need naturally sorted results. hmm.

9:20 how would I sort a vector in clojure if my vectore looks someting like [{:pos 0 :name "x"} ... {:pos 20 :name "x"}] ... obviously not sorted beforehand

9:21 * rhickey renamed 1.0 branch 1.0.x

9:24 Neronus: angerman (sort-by #(% :pos) vector) ?

9:25 angerman: Neronus: thanks, will try.

9:26 rhickey: so I'm pretty happy with the thread safety now for mutable vectors, as well as the API

9:26 basically mutable vectors enforce use in a single thread

9:26 all mutating ops have ! appended

9:27 but count/get/nth/invoke all work with normal API, yet check thread also

9:27 no use after immutable! call

9:27 so, no fast and safe

9:27 now fast and safe

9:29 I'm amazed, but thread check was practically free perf-wise. Apparently HotSpot caches Thread/currentThread in a register or something

9:30 Chouser: what does "no use after immutable! call" mean?

9:30 rhickey: Chouser: throws an exception

9:31 Chouser: a mutating ! op after an immutable! call throws?

9:31 rhickey: Chouser: all calls throw after immutable!

9:32 Chouser: oh! on the old mutable thing. immutable! returns what you want to use.

9:34 rhickey: the idea is to support single flow usage, just like functional style but with no persistence, trying to avoid bash-in-place use

9:34 so you can take normal (but non-persistent, non-aliasing) functional use and add mutable at front, some !'s and immutable! at end for a batch editing session

9:34 new is the protection against use in other Threads

9:34 angerman: whee, sorting works. it's dead stupid but it does work. Hmm.

9:34 rhickey: throws if used in thread other than the one that called mutable

9:35 Chouser: exactly

9:36 originally I had supported calling immutable! then continuing editing, but there's no perf advantage over calling mutable again, and it is much clearer

9:37 Chouser: sounds really good.

9:37 rhickey: pv -> (mutable pv) -> mv -> edits! -> (immutable! mv) -> pv

9:37 Chouser: with structural sharing throughout

9:38 rhickey: the thread protection takes it to a whole new level, as such use, even with multiple collections is truly safe and a lot more flexible than either all-methods-synchronized (like j.u.Vector) or, shudder, locking

9:39 the fact that this works, as does parallel vector map, with the exact same data structure set is incredibly powerful

9:43 * rhickey wonders if anyone is trying these branches

9:45 Chousuke: angerman, Neronus: (sort-by :pos vector) is enough :)

9:51 rhickey: Maybe you just need to merge them to master to get people to test :P

9:51 rhickey: Chousuke: yup

9:51 Chousuke: I wonder if undoing a merge is as easy as reverting the merge commit, though.

9:53 AWizzArd: As clojure.lang.RT.conj() returns an IPersistentCollection it means I have to cast every time (in Java) when I want to conj something on my vector, right?

9:54 Chouser: casting doesn't have runtime cost, afaik

9:56 AWizzArd: No, that's not a problem. I was just curious if there is a trick to go around that need for casting :-)

9:56 cemerick: Jomyoot: perst is the most likely candidate, IMO. I've enjoyed working with it so far.

9:57 angerman: ohh no. clojures json seems to choke on utf-8 :/

9:57 Chouser: AWizzArd: you could call PersistentVector.cons() instead.

9:57 danlarkin: angerman: clojure-json? what input

9:58 cemerick: writing something like that in clojure would make the API a whole lot cleaner, but reinventing proper transactionality, etc., is not something I'm qualified to do (or interested in tackling)

9:58 angerman: danlarkin: using clojures contrib json module

9:58 but it seems to encode it correctly

9:58 now I need to find out where the issue resided

9:59 cemerick: AWizzArd: What Chouser said. Polymorphism is nifty :-)

10:00 rhickey: cemerick: covariant returns re nifty, were missing in C#

10:00 angerman: hmm jtable ... hmmm

10:01 cemerick: rhickey: When I left the shores of scala, I promised myself I'd forget everything I knew about covariance, contravariance, etc etc :-)

10:07 AWizzArd: Chouser and cemerick: yeah, good trick, that saves a few keystrokes, good.

10:12 angerman: anyone any idea how to tackle unicode from jtable -(json)-> server -(json)-> jtable?

10:17 danlarkin: angerman: what's the step that fails?

10:36 Neronus: Is there an intelligent way to check if (map fn o) can be used with object o (other than the exception way)?

10:46 LauJensen: Neronus: Generally if (seq? o) is true, then map should work

10:47 Neronus: yeah, but map works for arrays too, and (seq? (int-array 10)) == false

10:47 stuartsierra: No, seq? tests if o is already a sequence.

10:48 Chouser: there's a 'seqable?' in clojure.contrib.core, but I'd wonder if it's thr right solution.

10:49 rhickey: Neronus: in what situation would you be calling map speculatively?

10:49 Chouser: Neronus: you really want *anything* that map can work on? And how will you handle the failure?

10:54 rhickey: mutable vectors and latest ensure code now in master

10:55 Chouser: exciting!!

10:55 * Chouser pulls

10:55 stuartsierra: What's the purpose of mutable vectors in this case?

10:55 cemerick: very good news :-)

10:55 next week (hopefully!) we're going to set up our build system to always build against clojure's head automatically

10:56 * cemerick is tired of "upgrading"

10:56 Chouser: stuartsierra: chest-crushing, wind-whipping speed.

10:56 stuartsierra: oh my

10:56 Chouser: :-)

10:56 stuartsierra: In a single-threaded context?

10:56 Chousuke: stuartsierra: it's supposed to be a way to do a "batch update" I guess.

10:57 a good example is into, I guess.

10:57 ... I guess too many things.

10:57 :P

10:57 Neronus: Chouser, rhickey: I want to do something to all the keys of all maps contained in a collection, recursively. i.e. if a map is found in a collection which is contained in another map, I want to do that for the keys of the innermost map, too. Anything that is not mappable is just left as it is

10:57 rhickey: stuartsierra: if you have a pure function returning a vector, but building that vector takes a lot of steps, you can get a thread safe mutable version of a vector in O(1), make changes to it in a functional style, just using assoc!, conj! etc, then get an immutable persistent vector to return in O(1)

10:58 stuartsierra: got it

10:58 smart

10:58 Chouser: Neronus: you probably just want 'coll?' then. Remember that Java arrays, Strings, etc. are mappable

10:58 cemerick: rhickey: the same thing is coming for all data structures, right?

10:59 Neronus: Chouser: Again, not true for e.g. arrays

11:00 Chouser: Neronus: what's not true for arrays?

11:00 Chousuke: ,(coll? (float-array 1))

11:00 clojurebot: false

11:00 rhickey: cemerick: sure, patches welcome :)

11:00 cemerick: ah, I thought you had already started work on maps :-)

11:01 rhickey: cemerick: I haven't, but I think same the mechanism will apply

11:01 cemerick: I must have transformed a similar comment of yours in my head into ("...and I'm going to apply it to them forthwith!" :-P )

11:02 lisppaste8: rhickey pasted "hest-crushing, wind-whipping speed" at http://paste.lisp.org/display/84670

11:02 stuartsierra: woah!

11:02 rhickey: note how you don't even change the structure of your functional code

11:03 cemerick: *drool*

11:04 Neronus: Chousuke: Chousuke demonstrated what I mean

11:05 Chousuke: :P

11:06 stuartsierra: That actually answers a question someone brought up on the group -- what if the compiler could substitute mutable structures for immutable when it's safe to do so. It's not automatic, but that's what you've done here.

11:07 Neronus: grr

11:07 Chouser: Neronus: you're okay with all such things becoming lazy seqs?

11:07 cemerick: sometime last week, someone was talking about decorating fns with metadata indicating that they're pure, so that the compiler could do just that.

11:08 Neronus: Chouser: Yupp

11:08 Chouser: well, maybe contrib core sequable? is what you want

11:10 lisppaste8: rhickey pasted "safe at every speed" at http://paste.lisp.org/display/84672

11:10 stuartsierra: Ah, but careful, (seqable? "string") is true.

11:10 danlarkin: *cough* bad pun

11:13 LauJensen: Is it just me, or this idea of a mutable vector a little icky and scary?

11:13 clojurebot: this is not a bug

11:13 * rhickey still wants to see a legitimate use case for seqable?

11:14 rhickey: LauJensen: don't use them

11:14 LauJensen: rhickey: dont pout, I just meant generally, in a language which so fully defaults to immutable datatypes, isnt there a better way to handle this?

11:14 stuartsierra: rhickey: I think it's the scripting folks who want to write APIs that take either a single object or a collection.

11:15 rhickey: what happens when we define seq on non-collection objects to enumerate their JavaBean properties?

11:15 stuartsierra: i.e., a Thing and a collection of Things should be "the same." I don't agree, but I get it.

11:15 Right, seq is more general than just collections.

11:16 cemerick: LauJensen: it's perfectly proper when used in conjunction with pure fns

11:16 rhickey: LauJensen: better way to handle what?

11:16 stuartsierra: I think a universal "aggregate?" predicate might be useful.

11:16 LauJensen: rhickey: The fact that you want a mutable object

11:16 rhickey: stuartsierra: I guess I see seqable? as perpetually ready to break

11:16 LauJensen: cemerick: How so ?

11:17 rhickey: LauJensen: I don't want a mutable object, I want the fastest speed in a known, linear, isolated context

11:17 stuartsierra: rhickey: I agree. What people really want is a single predicate that asks "is this a single thing or a collection of things?"

11:17 cemerick: LauJensen: because you really don't care what happens to intermediate representations within a pure fn, you only care about the result value

11:17 resulting*

11:17 rhickey: stuartsierra: exactly, and they will need to option to include strings or not in that logic

11:18 LauJensen: Ok

11:18 stuartsierra: I think most people don't think of strings as collections, unless they grew up on C. :)

11:19 LauJensen: cemerick: I follow that logic actually :) I just had the notion that all things mutable are evil.

11:19 jdz: world is not black and white

11:19 rhickey: LauJensen: the beautiful thing is, you write your app as always and only when you have a bottleneck need you tap into this capability, without restructuring your code. Also some library things will do this by default, like "into"

11:19 stuartsierra: LauJensen: I think *shared* mutable things are evil.

11:20 rhickey: stuartsierra: right and these things are unshareable

11:20 LauJensen: rhickey: Sounds good. So only when I have a vector operation which is taking too long will I use this. Got it

11:20 stuartsierra: Agreed

11:21 rhickey: They also don't support the persistent modification interface, so assoc/conj etc fail, so you can't accidentally leak them into code expecting persistent data structures

11:21 LauJensen: Perfect!

11:22 That type of thinking really makes me love clojure - It protects me against me :)

11:22 stuartsierra: Without preventing you from doing what you want to do when you know what you're doing. :)

11:23 LauJensen: I think this calls for a T-Shirt

11:23 rhickey: stuartsierra: well, they do in some sense, since for example you might be able to share mutable things between threads if you knew what you were doing, these prevent it

11:24 I think thread-local assurance is a huge deal, another safe model other than locks

11:24 Chouser: most languages attempt to protect you from yourself in some cases and to some extent, while letting you do "dangerous" things in other cases.

11:24 stuartsierra: Ok, fair enough, but you can always create Java collections if you want to be really sneaky.

11:25 LauJensen: hehe

11:25 rhickey: with a lot of power since it supports both composite work on one data structure and work involving multiple data structures

11:25 Chouser: the question is how well does a particular language fit with your own experience of what is dangerous vs. what is necessary

11:25 rhickey: stuartsierra: true, I'm trying to make it so you'd never be tempted by that

11:25 Chouser: this drives some people to enjoy coding in C, because they're unwilling to give up direct pointer manipulation.

11:26 cemerick: the answer to that question is probably directly corollated with the quality/type of programmers you have around you

11:26 stuartsierra: Code us not into temptation, but dissociate us from mutability.

11:27 rhickey: :)

11:28 LauJensen: rhickey: Could you define what you mean when you say 'thread-local assurance' ?

11:29 rhickey: LauJensen: rhickey pasted "safe at every speed" at http://paste.lisp.org/display/84672

11:29 If you try to use one of these mutable things from other than the thread on which they were created it will throw an exception

11:30 LauJensen: Thats awesome!

11:31 rhickey: It when coupled with O(1) to/from immutable+persistent, this is, IMO, game-changing

11:32 * rhickey needs to write it up somewhere

11:32 stuartsierra: yes, yes

11:33 LauJensen: rhickey: You should get a blog going and sell subscriptions :) I dont want to be the one to tell you to charge, but I think you could :)

11:34 stuartsierra: Actually, sounds like a good topic for one of the functional programming conferences.

11:34 IFL 2009 is coming up.

11:34 Right across the Hudson. :)

11:34 Chouser: maybe it'd be easier to sell a writeup as an article to a magazine that already has a compensation model.

11:36 cemerick: do authors get paid for magazine articles anymore? (outside of the mainstream press?)

11:37 stuartsierra: a little, not much

11:43 angerman: so with all this parrallelism of clojure can we have some math libs that serioulsy use the parrellism and show that clojure is fast?

11:45 stuartsierra: Go for it. :)

11:46 rhickey: angerman: there's a third leg to to this Clojure perf work - parallelism, safe mutability, and finally primitives in Clojure's vectors and fns, the latter is still to come, and will be 'limited' to longs and doubles

11:46 * hiredman doesn't know how math works

11:46 stuartsierra: why longs & doubles?

11:55 LauJensen: stuartsierra: ints are too small, doubles have similar speed to floats? :)

11:56 cemerick: LauJensen: I've been advised by people who would know that doubles *should* be faster than floats in general.

11:57 LauJensen: Cool - I wasnt quite sure so I took the safe route: theyre similar :)

11:58 cemerick: I've yet to benchmark the difference in our case, but the rationale I heard made sense to me at the time. :-)

11:58 stuartsierra: ok, just curious

11:59 Neronus: Chouser: yeah, thanks, sequable? works for me

11:59 clojurebot: Why are you asking *him*

11:59 cemerick: parallelizable primitive arrays! I never thought I'd see the day :-P

12:02 hiredman: ~botsnack

12:02 clojurebot: thanks; that was delicious. (nom nom nom)

12:02 rhickey: stuartsierra: because longs and doubles can accommodate the smaller primitives without loss

12:03 stuartsierra: Ok, but what if you had a huge array of 'short's?

12:03 rhickey: float->double byte->short->char->int->long

12:03 cemerick: stuartsierra: RAM is cheap?

12:03 * cemerick ducks

12:03 stuartsierra: And they wouldn't fit in memory as an array of longs?

12:04 I'm thinking search engines, where you might have a billion-element array.

12:04 rhickey: stuartsierra: oh well, memory is getting cheaper and bigger

12:04 cemerick: you can always start packing bits

12:05 (if you care that much)

12:06 stuartsierra: Ok, I guess. Won't affect me personally. But I know people who never have enough RAM.

12:06 rhickey: but each supported type is a multiplier, i.e. supporting n arg types means n^num-args variations, I'm thinking 3 (Object/long/double) with support for up to 4 args

12:06 stuartsierra: I understand the problem.

12:07 Code generation!

12:08 rhickey: there may be some flex in the data structures vs fn calling, I'm mostly fixed on long/double for fns, it might be possible to have vectors of shorts going in/out as longs

12:09 stuartsierra: it's not a code generation problem (FWIW, I generated the original IFn overloads in CL), it's a vtable size thing, I'm concerned about that getting out of hand

12:09 oh, yes, fourth leg of perf tuning is new new, in progress

12:10 stuartsierra: ah, ok

12:11 hiredman: ,(import 'clojure.lang.AFn)

12:11 clojurebot: clojure.lang.AFn

12:12 rhickey: one thing's for sure, drawing conclusions about Clojure perf now is very premature, when all of these are in place it will be stunning

12:12 hiredman: ,((new [AFn] (invoke [] "foo")))

12:12 clojurebot: "foo"

12:14 rhickey: has anyone tried new new's signature inference? (other than that ^^) :)

12:14 new new is now the only branch not merged into master

12:15 Chouser: rhickey: I started going through contrib again, but haven't had the time to finish

12:15 ...little time though it should take.

12:16 rhickey: I swapped out future and promise, where else do we have proxy? xml I guess

12:16 cemerick: rhickey: I'll probably start beating on it next week.

12:17 rhickey: new new docs in progress: https://www.assembla.com/wiki/show/clojure/New_new

12:17 volatile now works

12:17 only missing non-reflective self calls

12:17 Chousuke: hmm

12:17 rhickey: and stable names during AOT

12:18 Chousuke: parallel, inspector and xml have proxy calls.

12:18 and core_proxy of course :P

12:18 cemerick: rhickey: how are captured locals stored? It'd be great if they were actual fields, with nice (identical, when possible?) names...

12:18 rhickey: parallel is going to be deprecated

12:19 Chousuke: heh

12:19 * cemerick is thinking about libs that dig around via reflection

12:19 Chousuke: well, that's where most of the proxy calls are

12:19 rhickey: cemerick: they are but I am loathe to promise that. The semantics of this are simpler than classes with fields etc

12:20 cemerick: rhickey: for goodness' sake, think of the tools...! ;-)

12:20 Jomyoot: what is the best editor for clojure these days?

12:20 still Emacs?

12:21 technomancy: some things never change. =)

12:21 rhickey: cemerick: what I am trying to do is some up with a story I could explain without reference to Java/C# etc. Then and only then, there could be a description of the intended (non-portable) mapping to host constructs

12:21 cemerick: think of Chouser, writing ClojureScript!

12:22 cemerick: heh

12:22 rhickey: cemerick: targeting Javascript is a big deal, and only going to become bigger IMO

12:23 cemerick: clojurescript is pretty crazily wonderful -- but still crazy :-)

12:23 rhickey: cemerick: Is GWT crazy, IYO?

12:24 JS engines *are* the VMs of the browsers

12:24 Chouser: GWT is crazier. Given the choice between writing in Java and Javascript, I choose Java.

12:24 cemerick: rhickey: in concept, no -- and neither is clojurescript. But I'm guessing the latter will always have a footprint issue.

12:24 stuartsierra: And these days they do JIT compilation, just like the JVM.

12:24 hiredman: huh, assembla turns ascii smilies into images

12:24 Jomyoot: Does ECB work well with clojrue?

12:24 Chouser: gah!

12:25 Javascript! I choose Javascript!

12:25 sheesh

12:25 technomancy: Jomyoot: ECB is kind of pointless for Clojure IIRC

12:25 cemerick: but then, it's all in what you're doing, too. For the web stuff I care to bother with, I'd much rather have a very thin remoting layer so I can touch clojure fns running on the server super-easy.

12:25 technomancy: it's for Complicated Languages

12:25 Jomyoot: how come?

12:25 technomancy: what if i need project browser like in textmate?

12:26 showing folder trees

12:26 technomancy: Jomyoot: (a) you probably don't; you just think you do and (b) you can use speedbar by itself without ECB. =)

12:26 cemerick: I really dislike web development, which explains a lot of my preferences :-)

12:27 rhickey: cemerick: me too, ClojureScript is my best hope :)

12:31 stuartsierra: I always worry about *-to-JavaScript translators because you have to think about three layers at once -- the source language, the translator, and JavaScript. All three have quirks.

12:33 alrex021: How do I, if possible, use :gen-class and run compile in REPL? I am following the http://clojure.org/compilation hello example and get the following exception in my REPL: "Could not locate clojure/examples/hello__init.class or clojure/examples/hello.clj on classpath"

12:33 Jomyoot: how good is vimclojure?

12:34 kotarak: Jomyoot: good (shameless advertisement)

12:34 Jomyoot: but has its quirks

12:34 Jomyoot: kotarak: you made it?

12:34 what are the quirks?

12:34 kotarak: yes

12:34 Jomyoot: http://kotka.de/projects/clojure/vimclojure.html it looks very good for formating though

12:34 lining up the columns

12:34 cemerick: stuartsierra: js is the new bytecode? *shudder*

12:35 Chouser: cemerick: so clearly it needs a way to embed source filename and linenumbers

12:35 :-)

12:35 stuartsierra: cemerick: it's true though, look at Chrome, Gmail, iPhones, Palm's Web OS...

12:36 kotarak: Jomyoot: it uses the introspection of clojure to provide dynamic things. That means, that it tries to load the file you are editing. => it executes code, must not contain syntax errors... hiredman doesn't like that, for such cases you can turn off dynamic features and just use the static things vim provides.

12:36 Jomyoot: I used to this style and it works perfectly for me.

12:37 Jomyoot: the static things like formatting, syntax highlighting, static completion, are on par with emacs, enclojure, ... you name it.

12:38 Jomyoot: so typically does emacs or vim wins?

12:38 stuartsierra: That's been going on for decades.

12:38 kotarak: Jomyoot: neither, a matter taste I guess

12:38 rhickey: cinc->js ftw!

12:39 Jomyoot: can emacs line up columns like in vimclojure?

12:39 http://kotka.de/projects/clojure/vimclojure.html

12:39 technomancy: sure; M-x align-regexp

12:39 kotarak: It would be surprised if not...

12:39 s/It/I/

12:42 cemerick: stuartsierra: all that heat just makes me want to dive under the bed until the market makes some real decisions. I don't want to go platform-hopping every 6 months because Google, Apple, Palm, and 500 spinning VC-backed pre-revenue "companies" collectively sneeze.

12:43 Chouser: I would guess the safe-mutable collections will be an even bigger win for JS VMs than it is for JVM.

12:43 cemerick: yeah, I'd presume the VMs' GCs are relatively primitive.

12:43 stuartsierra: cemerick: In general, though, everyone's coalescing around HTML + CSS + JS as a user interface standard, for better or for worse.

12:45 cemerick: stuartsierra: oh, don't get me wrong, I think it's for the better! What I really dislike is getting led around by the nose by platform vendors, which is inevitable in any immature tech market.

12:45 Chouser: cemerick: so quit whining and just use sliverlight already.

12:45 rhickey: ouch!

12:45 stuartsierra: Sure, the mobile world is going to be hairy for the next couple of years. But hey, three years ago we couldn't even write mobile apps.

12:46 cemerick: Chouser: better throw out that wink really fast! :-P

12:46 rhickey: I don't think js in browsers is going away

12:46 Chouser: ;-)

12:46 cemerick: :-D

12:50 Jomyoot: Is Rich Hickey still using Aquamac?

12:54 technomancy: Jomyoot: yeah, but he doesn't use slime

12:55 presumably because he knows what the code will do before it executes. =)

12:55 Jomyoot: why aquamacs and not carbon or cocoa emacs?

12:55 u know?

12:55 LauJensen: And he doesnt use a keyboard either.. he just stays at the compiler until it obeys

12:55 stares...

12:56 technomancy: Jomyoot: I don't know. I have heard of a number of weird edge-casey bugs with aquamacs so I don't recommend it myself.

12:56 also since it's not portable it's hard for people to test on it.

12:56 stuartsierra: I use it, no problem.

12:56 clojurebot: "There is no problem in computer programming which cannot be solved by an added level of indirection." -- Dr Maurice Wilkes

13:02 rhickey: so, I need a term for these single-threaded mutable collections that can share structure with the persistent collections. "Mutable" doesn't seem to do them justice, and has bad implications

13:02 stuartsierra: "fast"

13:02 rhickey: heh

13:02 editable views?

13:03 batch structures?

13:03 stuartsierra: that implies some separate, concrete backing object

13:03 batch structures is ok

13:03 rhickey: stuartsierra: yeah, view is scary, since the source is inviolate

13:04 stuartsierra: "protean"

13:04 "mercurial"

13:04 * stuartsierra has fun with thesauri

13:05 stuartsierra: "builder structures"

13:06 "growth structure"

13:07 "fillable container"

13:08 Chousuke: fillable container sounds redundant :P

13:08 stuartsierra: "agglomerator"

13:08 rhickey: breeder/composer/producer

13:09 stuartsierra: "accumulator"

13:09 rhickey: interesting

13:10 cached

13:10 very overloaded I know

13:10 stuartsierra: yeah, "cached" makes me think memoization

13:10 "collector"

13:11 rhickey: assembler, maker

13:11 ooh, collector

13:12 kotarak: drain

13:12 rhickey: put your data in the drain? :)

13:12 hrm

13:12 durka42: can you flush the drain?

13:13 stuartsierra: collector/accumulator because they're like accumulator functions in Common Lisp loops.

13:13 Chousuke: hoard :P

13:14 stuartsierra: That's actually not bad, you're hoarding a collection. :)

13:14 rhickey: stuartsierra: hmm, that analogy isn;t helping me. but I like collector. Whatever name wins could replace (mutable coll) and needs a counterpart for yielding the immutable result

13:14 stuartsierra: "finalize"

13:15 rhickey: urk

13:15 kotarak: (flush (drain coll)) :P ;)

13:15 stuartsierra: :)

13:15 "realize"

13:15 "conclude"

13:15 rottcodd: thaw/freeze

13:15 Chousuke: "seal"

13:15 rhickey: also, one of the things you can do with these is only remove things, in which case you aren't collecting items, but changes

13:15 Chousuke: and unseal

13:16 rhickey: If it could incorporate some sense of the linearity/single-threadedness that would be good too

13:17 stuartsierra: isolate / share

13:17 rhickey: except (isolate x) doesn't

13:17 stuartsierra: ok

13:17 tap / untap

13:18 crack / seal

13:19 immediate / persistent

13:20 Chousuke: tether/unleash

13:20 rhickey: (foo immutable-thing) -> threaded-mutable-thing -> (bar threaded-mutable-thing) -> immutable-thing, none of which affects or hinders immutable-thing

13:21 stuartsierra: threadify / unthreadify :P

13:21 danlarkin: I like mutable/persistent, not sure why you don't like mutable though

13:21 Chouser: it's cute that immutable! has a ! but mutable does not.

13:22 stuartsierra: transient / persistent

13:22 rhickey: danlarkin: well, and ArrayList is mutable too, but much less powerful

13:22 an ArrayList

13:22 and less safe

13:23 so there are two notions in my view, one is the data structure, and the other is the 'editing session'

13:23 Chouser: persistent! is nice, then you just need a noun for the safe-mutable thing itself which can also be used as the "factory" fn name.

13:23 kotarak: editor / save

13:24 * stuartsierra goes out to lunch

13:25 rhickey: transient, ephemeral?

13:25 Chousuke: thread-bound?

13:25 hmm

13:26 rhickey: transient/persistent!

13:27 Chouser: chameleon

13:28 rhickey: I like transient, any objections?

13:30 Chouser: "bum" is shorter and less PC

13:30 * Chouser ducks

13:30 rhickey: hah

13:30 opqdonut: how about apple/orange

13:30 Chouser: I guess their transience is no less defining than their other features.

13:31 danlarkin: it's too bad there's no word that means exactly "locally mutable"

13:31 hiredman: locutable

13:31 cgrand: in-flux/solid

13:32 rhickey: I think the term is kind of open when applied to data structures, so this method can define it. It is a great counterpart to persistent

13:33 Chouser: inconstans propinquus

13:35 rhickey: transient data structures "move" through various states, in a single-threaded manner

13:35 they are not memory holes subject to poking from multiple threads

13:35 and calling persistent! stops them

13:36 danlarkin: get-a-job!

13:36 rhickey: Chouser: is that a kind of bird or something?

13:37 very funny that transient makes you guys think of drifters

13:38 Chouser: rhickey: that's a lame attempt at a latin phrase for locally mutable

13:38 I just find it interesting that when other sciences need to name things, they string together latin words until it's unique and then apparently truncate to one or two syllables

13:39 rhickey: I like the sense of motion and the implied short-livedness in transient

13:39 Chouser: :)

13:39 Chousuke: rhickey: plus it sounds cool and mysterious

13:39 which is good for catching people's attention

13:39 rhickey: Chousuke: there you go!

13:40 Chouser: while comp. sci. hunts around for related english thing and then overloads it to death, "tree" being the classic example.

13:40 rhickey: at least they'll have to consider what it means, with mutable they'll presume they know

13:41 ok, well the bum objection notwithstanding, any other objections to transient?

13:43 Chouser: conclusive silence.

13:44 rhickey: ok, seems no one else likes it, but no one objects - transient it is - thanks for the help!

13:44 Chouser: ha!

13:44 rhickey: will be (transient pv) -> tv -> edit! tv -> (persistent! tv) -> pv

13:45 Chouser: and we can call the thing transients

13:45 the things

13:45 rhickey: or bums

13:45 Chousuke: :P

13:46 Chouser: transient vectors -- that's indeed better than mutable vectors

13:46 Chousuke: also implies that you're not supposed to keep them around for long.

13:46 rhickey: it's a great fit - sparked by your call for (persistent! x)

13:47 Chouser: "persistent" was stuartsierra

13:48 rhickey: ok, creds/blame to him when he gets back from lunch

13:52 and a persistent collection capable of producing a transient version? not all will be

13:53 currently "editable"

13:55 Chouser: transable

13:57 overpaid

13:57 rhickey: oh boy

13:58 Chouser: The state prior to becoming a bum might be "lazy", but I guess that won't work.

13:58 Fossi: ;D

14:01 rhickey: transient == bum completely doesn't click with me, didn't even consider it

14:02 Chousuke: transient is apparently a PC way of saying it :P

14:02 Chouser: I didn't think of it 'til very late. Wasn't a particularly natuarl association.

14:03 I think it was the plural form "transients" that made it click.

14:04 rhickey: it's a Java keyword, wonder if that will be a problem

14:05 Sun's JVM seem pretty tolerant of names, but IBM's isn't

14:05 jwhitlark: What's the best way to suggest a minor update to the docs?

14:06 Chouser: ha! even in Java transient means not persistent.

14:06 Chousuke: I wasn

14:06 Chouser: just different meanings of both. :-)

14:06 rhickey: Chouser: for another definition of persistent

14:06 Chousuke: I wasn't even aware of transient. :/

14:06 the keyword that is.

14:08 jwhitlark: It would be helpful if the http://clojure.org/java_interop page had a quick note on the requirement to import java inner classes; it took me quite a while to find out.

14:08 finally found it here: http://bradfordcross.blogspot.com/2009/05/using-inner-classes-from-clojure.html

14:08 so it appears I'm not the only one.

14:09 Chousuke: I think it is mentioned there.

14:09 Chouser: "Note that nested classes are named EnclosingClass$NestedClass, per the JVM spec"

14:09 Chousuke: just not very noticeable. :/

14:09 rhickey: jwhitlark: it's in the second paragraph in the explanation of the Dot form

14:09 Chousuke: hm, looking through the list of java keywords, strictfp seems to be the only other keyword new to me.

14:10 Chouser: I wonder if a FAQ would be more scannable for some of these issues

14:10 jwhitlark: yea, I got the $ part of it, it was having to import it that wasn't obvious.

14:10 unless I'm still missing something.

14:11 Chouser: well, the class name itself has the $ in it.

14:11 rhickey: the transients have moved in: http://github.com/richhickey/clojure/commits/master

14:11 technomancy: jwhitlark: me too; I thought importing the outer class would let you access the nested class

14:11 jwhitlark: I'd import the parent class, and try calling it with the $ syntax. I didn't expect that I'd have to import the inner class.

14:12 Chouser: If named Foo$Bar, Foo is a class but Bar is not -- must use Foo$Bar

14:12 also the #1 example for class name aliases.

14:12 jwhitlark: technomancy: that's it. It wasn't the naming that was confusing, it was the deliberate import.

14:13 Chouser: You imported Foo and then tried to use Foo$Bar?

14:14 jwhitlark: Something along the lines of: "Inner classes must be specifically imported with the $ syntax" would have saved me a lot of puzzlement.

14:14 yea.

14:14 coming from Python, so perhaps it's a leftover from that.

14:14 Chouser: but they don't have to be imported at all, any more than other classes. :-/

14:15 Fossi: it's also non-obvious coming from java

14:15 Chouser: you can say com.company.Foo$Bar with no import

14:17 jwhitlark: true, but when you do (import '(com.company Foo)) a portion of population is going to expect Foo$bar to work.

14:17 * stuartsierra returns

14:17 jwhitlark: not saying it's right, just saying a single sentence addition would remove a stumbling block for some people.

14:18 Chouser: jwhitlark: I'm not arguing against a sentence, just not sure of the right wording.

14:19 "must be imported" seems misleading

14:20 stuartsierra: "Note that nested Java classes are named OuterClass$InnerClass and must be imported as such."

14:20 Chouser: the thing is, each unqualified class name used must be specifically named in an import

14:20 stuartsierra: you saw you won?

14:21 stuartsierra: yes. :-D

14:21 Not that it matters.

14:21 jwhitlark: not sure what the wording should be.

14:21 Chouser: so whether it's a.b.Foo or a.b.Foo$Bar, you can't get away with only mentioning a.b to get to Foo or a.b.Foo to get to Foo$Bar

14:23 jwhitlark: so what would be the best way to express that inner classes aren't a special case?

14:23 I think that's the assumption that got me into trouble. Thinking of the inner classes more as a member of field.

14:23 s/of/or/g

14:24 damn, got that wrong twice.

14:25 perhaps: Note that inner classes are not a special case, and must either be explicitly imported or fully qualified.

14:28 a little redundant with the docs that are already there, but makes a potential pitfall clear.

14:44 Chouser: what do you think? Is that closer?

14:45 Chouser: jwhitlark: yeah. any suggestion on where to put it?

14:47 jwhitlark: well, the second paragraph of the dot special form discussion seems reasonable, but where it would have really helped me is in api/import

14:48 I think either would do. I read them both several times when I was struggling with it.

14:49 Chouser: I think the import docstring is best. An example of Inner$Outer might be helpful there too.

14:49 jwhitlark: interesting aside: this is the first time I've had this type of problem with clojure. I'm *really* liking lisp and clojure in particular.

14:50 I think that would do very nicely.

14:51 Chouser: "Note that inner classes (such as Inner$Outer) are not a special case, and must be fully qualified (mypackge.myname.Outer$Inner) or explicitly imported.

14:51 "

14:51 rhickey: aren't they normally nested, not inner, classes?

14:52 Chouser: this is where my knowledge of Java breaks down.

14:53 looks like both

14:53 http://java.sun.com/docs/books/tutorial/java/javaOO/innerclasses.html

14:53 http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html

14:53 jwhitlark: hmm.. I think nested is more proper, but the one time I took a java course, the instructor called them inner.

14:53 rhickey: inner classes have a relationship to their enclosing instance, nested are more generally just lexically nested, and are the ones you're most likely to use from outside the class

14:54 jwhitlark: "Note that nested or inner classes ..."

14:54 ?

14:54 Chouser: "Note that nested or inner classes (such as Outer$Nested) are not a special case, and must be fully qualified (mypackge.myname.Outer$Nested) or explicitly imported.

14:55 jwhitlark: That would have done it for me.

14:59 rhickey: I don't normally gush, but I wanted to thank you; even as inexperienced with clojure as I am, it feels like the most clean and powerful language I've ever used.

15:00 rhickey: jwhitlark: great! thanks

15:19 cemerick: is it safe to say that clojure is "more dependent" on jit than typical javac'd java? e.g. a particular clojure operation/fn/program requires more "runs" before it's performance settles into a minima?

15:19 that's the impression I get, and I wonder if there's any basis to it.

15:21 stuartsierra: don't know, maybe the bytecode is less "efficient" on the first pass

15:39 lizp: hello, shouldn't this expression return 5 - ((first '(+ 2 3)) 2 3) ?

15:39 it returns 3

15:39 hiredman: ,(first '(+ 2 3))

15:39 clojurebot: +

15:39 hiredman: ,((first '(+ 2 3)) 2 3)

15:39 clojurebot: 3

15:39 hiredman: ,((first '(+ 2 3)) 2)

15:39 clojurebot: nil

15:40 Chousuke: lizp: that's because (first '(+ 3 2)) returns the symbol +, not the function

15:40 hiredman: oh

15:40 duh

15:40 ,((first (list + 2 3)) 2)

15:40 clojurebot: 2

15:40 Chousuke: ('+ 3 2)

15:40 ,('+ 3 2)

15:40 clojurebot: 2

15:40 hiredman: ,((first (list + 2 3)) 2 3)

15:40 clojurebot: 5

15:40 Chousuke: lizp: symbols have an interesting property: they look themselves up in things when used as functions

15:41 lizp: but 3 is not associative, so you get nil; however, if there are two arguments, the latter gets used instead of nil

15:41 ,('foo '{foo bar})

15:41 clojurebot: bar

15:41 Chousuke: ,('fooz '{foo bar} 'default)

15:41 clojurebot: default

15:42 lizp: where can i read about the semantics of symbols/functions in clojure?

15:44 Chousuke: lizp: keywords are also functions. as are maps, sets and vectors

15:44 hiredman: well

15:44 lizp: http://clojure.org/data_structures#toc10

15:45 avital: ,'(+ 1 2)

15:45 clojurebot: (+ 1 2)

15:45 avital: ,(list + 1 2)

15:45 clojurebot: (#<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622> 1 2)

15:45 hiredman: lizp: http://clojure.org/vars

15:45 etc

15:45 avital: so what is ' exactly?

15:45 isn't it the same as (list ...)?

15:45 hiredman: quote

15:46 nope

15:46 ,'a

15:46 clojurebot: a

15:46 Chousuke: avital: it's "this is an unevaluated code literal"

15:46 kotarak: ,a

15:46 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

15:46 hiredman: it keeps the quoted symbol from being evaluated

15:46 kotarak: ,(list a)

15:46 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

15:46 kotarak: ,'(a)

15:46 clojurebot: (a)

15:46 hiredman: ' is a reader macro for (quote …)

15:46 kotarak: ,(quote a)

15:46 clojurebot: a

15:47 Chousuke: avital: so while in clojure (+ 1 2) gets evaluated and produces 3, '(+ 1 2) produces the list that when evaluated as code would produce 3

15:47 hiredman: something quoted is what is read, without any evaluation

15:48 avital: ,(eval 2)

15:48 clojurebot: DENIED

15:48 avital: oh what

15:48 Chousuke: eval is not allowed :)

15:48 avital: hehe

15:48 so i see that (eval +) returns the + function and (eval 2) returns 2

15:48 Chousuke: avital: but remember that clojure code is not text. it's made of symbols, lists, vectors, keywords, maps and sets.

15:49 avital: is there another way to get the + function other than eval?

15:49 Chousuke: ,+

15:49 clojurebot: #<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622>

15:49 Chousuke: of course, that has an implicit eval

15:49 :P

15:49 hiredman: ,(find-var '+)

15:49 clojurebot: java.lang.IllegalArgumentException: Symbol must be namespace-qualified

15:49 hiredman: ,(find-var *ns* '+)

15:49 clojurebot: java.lang.IllegalArgumentException: Wrong number of args passed to: core$find-var

15:49 hiredman: bah

15:49 lizp: hehe

15:49 Chousuke: since the symbol +, when evaled, produces the + function

15:50 hiredman: ,(find-var (symbol (str *ns*) (name '+)))

15:50 clojurebot: nil

15:50 avital: but is there a more direct way?

15:50 Chousuke: direct?

15:50 what could be more direct than +?

15:50 hiredman: avital: what are you trying to do?

15:50 the symbol + evaluates to the function +

15:51 so as long as the you don't quote it (stop evaluation) you will get the function


15:52 avital_: sorry lost the last few messages, so is there a simple way to get the + function?

15:52 Chousuke: :P

15:52 ,+

15:52 clojurebot: #<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622>

15:52 Chousuke: there

15:52 the simplest possible way :9

15:53 cark: ,(type +)

15:53 clojurebot: clojure.core$_PLUS___4094

15:53 hiredman: the symbol + evaluates to the function +, so if you don't quote + (stop the evaluation) you will get the function

15:53 cark: ,(type '+)

15:53 clojurebot: clojure.lang.Symbol

15:53 cark: ,(type (find-var 'clojure.core/+))

15:53 clojurebot: clojure.lang.Var

15:53 avital_: no but wait

15:53 hiredman: ,(resolve '+)

15:53 clojurebot: #'clojure.core/+

15:54 hiredman: ,(deref (resolve '+))

15:54 clojurebot: #<core$_PLUS___4094 clojure.core$_PLUS___4094@e5d622>

15:54 avital_: so can we make the ((first '(+ 2 3)) 4 5) example work with minor modifications?

15:54 ,((first '(,+ 2 3)) 4 5)

15:54 clojurebot: 5

15:54 avital_: doesn't work

15:54 cark: ah nice hiredman =)

15:54 hiredman: ((first `(~+ 2 3)) 4 5)

15:54 ,((first `(~+ 2 3)) 4 5)

15:54 clojurebot: 9

15:54 avital_: wow ok what just happened there? :)

15:54 Fossi: what do you expect to get?

15:54 hiredman: avital_: ~ is unquote

15:55 ,((first '(~+ 2 3)) 4 5)

15:55 clojurebot: java.lang.ClassCastException: clojure.lang.PersistentList cannot be cast to clojure.lang.IFn

15:55 Chousuke: avital_: ` is a special kind of quote, and ~ unquotes :)

15:55 avital_: oh right

15:55 Chousuke: fo you get a list of a function, 2 and 3

15:55 avital_: ok great thanks"!

15:55 Chousuke: alternatively, you could just use a vector :P

15:55 hiredman: or a list

15:55 cark: avital_ : fossi's question might be worth answering

15:55 Chousuke: that IS a list

15:56 hiredman: ,((first (list + 2 3)) 4 5)

15:56 clojurebot: 9

15:56 avital_: cark

15:56 yeah sorry

15:56 Chousuke: hiredman: the syntax-quoted thing is almost teh same.

15:56 cark: this strikes me as a very strange way to do things

15:56 avital_: Fossi: I wanted to get 9, and hiredman's solution gives me 9.

15:56 I was just experimenting

15:56 Chousuke: ,((first [+ - /]) 3 4) ; no need for quoting stuff

15:56 clojurebot: 7

15:56 cark: oh ok

15:56 piggybox: this channel makes me feel like in #haskell...

15:56 cark: well that's not idiomatic at all

15:56 Chousuke: (the things in a vector are always evaluated)

15:56 Chouser: oh dear

15:56 Chousuke: unless the vector is quoted, of course :P


15:57 Fossi: omg, now i get it

15:57 Chouser: piggybox: what can we do to fix that?

15:57 hiredman: foo :: x -> a -> b

15:57 now it is just like #haskell

15:57 Chousuke: hiredman: quick, do something cryptic with pl!

15:57 hiredman: clojurebot: numbers!

15:57 clojurebot: (pl reverse $ (↕reduce range $ 10 () λxy (↕conj inc $ y x)))

15:57 Chousuke: excellent!

15:57 hiredman: actually I don't think I reloaded pl

15:57 danlarkin: cult of lambda

15:58 hiredman: ,(pl reverse $ (↕reduce range $ 10 () λxy (↕conj inc $ y x)))

15:58 clojurebot: (1 2 3 4 5 6 7 8 9 10)

15:59 piggybox: lOlrz

16:04 cemerick: hah

16:04 avital_: so why would i ever use ' and not `?

16:04 cemerick: what's pl, anyway?

16:05 hiredman: pl is a toy

16:05 Chouser: avital_: ` qualifies symbols into var names and class names

16:05 hiredman: ,~a

16:05 clojurebot: java.lang.Exception: Unable to resolve symbol: a in this context

16:05 hiredman: er

16:05 ,`a

16:05 clojurebot: sandbox/a

16:05 Chouser: ,[`foo `map `Integer 'foo 'map 'Integer]

16:05 clojurebot: [sandbox/foo clojure.core/map java.lang.Integer foo map Integer]

16:05 hiredman: ,'a

16:05 clojurebot: a

16:06 avital_: Chouser: my question was: if ` is a stronger form of ' that allow to use ~ inside, why would i ever use vanilla '?

16:06 oh

16:06 wht

16:06 hired just answered

16:06 sorry

16:06 hiredman: and what is sandbox/a... ?

16:07 hiredman: it is a namespace qualified symbol

16:07 avital_: and why is it that 'a and `a are diferent?

16:07 hiredman: symbols quoted with syntax-quote (`) are turned into full qualified symbols

16:07 mostly

16:08 ' is the traditional simpler quoting

16:08 ` and ~ and ~@ are used alot for writing macros

16:09 avital_: hiredman: what is ~@?

16:10 hiredman: unquote splice

16:10 avital_: oh right

16:10 Quiark: ,'a

16:10 clojurebot: a

16:10 hiredman: ,`(1 2 ~@(list 3 4 5))

16:10 clojurebot: (1 2 3 4 5)

16:10 Quiark: ,`a

16:10 clojurebot: sandbox/a

16:11 Quiark: ,`a#

16:11 clojurebot: a__2992__auto__

16:11 hiredman: oh, right

16:11 tomoj: autogensyming is awesome

16:11 hiredman: gensyms working in syntax quote too

16:21 lizp: thanks btw!

16:58 JAS415: ,a#

16:58 clojurebot: java.lang.Exception: Unable to resolve symbol: a# in this context

16:59 rhickey: first cut at transient docs - feedback welcome: http://clojure.org/transients

16:59 Chousuke: foo# is a special feature of syntax-quote

17:02 technomancy: rhickey: I love the notion that there shouldn't be any "we do this in clojure's internal implementation, but you shouldn't do this in your own code" moments.

17:02 very democratic

17:05 Chousuke: lisp is (or claims to be!) all about that, isn't it :)

17:05 angerman: thickey: not bad, I was able to understand it, eh >:)

17:08 * angerman really likes how clojure feels likea practicioners tool not an academic beauty thing.

17:08 Fossi: rhickey: good read

17:08 JAS415: I like using clojure as a java compiler

17:10 angerman: JAS415: isn't that what we all use clojure for? :)

17:10 * angerman so hopes he can soon use the P4 HT with 4g ram as a work horse.

17:11 stuartsierra: rhickey: good explanation of transients

17:11 JAS415: i guess i mean like pretending that java is the assembly language and then writing functions and macros that arrange the java into the right forms

17:11 like clojure is the compiler

17:11 mebaran151: what version of clojure has transients?

17:12 rhickey: mebaran151: master

17:12 mebaran151: ah so it's bleeding edge stuff

17:12 angerman: JAS415: well, that's all Suns fault. If they hand's alised java with the jvm and java bytecode ...

17:14 Chousuke: JAS415: fortunately Clojure does not compile down to Java, but JVM bytecode.

17:14 rhickey: mebaran151: yes, I added that info on the page

17:15 Chousuke: I suppose as far as Clojure is concerned, Java is "just another JVM language" (also the implementation language, but...)

17:17 jwhitlark: JAS415: That's exactly how I think of java, the new assembly language.

17:17 mebaran151: it's the new COBOL

17:17 or FORTRAN

17:17 which ever old school, excessively verbose, down to the metal language floats your fancy

17:18 JAS415: right, java is just another jvm language, except clojure has really good support for calling it

17:18 so you can write a macro that programmatically arranges java into the right clojure code to suite your puroses

17:18 Chousuke: Clojure doesn't call *java* code per se. it calls *JVM* code

17:18 JAS415: its like having a really really large amount of leverage over a language with a ton of libraries

17:19 doesn't matter really

17:19 concept is the same

17:19 Chousuke: I suppose the host interop matches best with java.

17:19 mebaran151: anyway are transients like tag types, only supposed to be used in dire emergencies?

17:19 JAS415: java just has most libraries

17:19 fastest libraries too, which counts

17:20 mebaran151: eh, C has the most fast libraries, but I've never seen an ffi in which I really would invest a lot of faith

17:20 jwhitlark: I used to be really down on java programmers, then I realized who I needed to be down on were people who *only* wrote java.

17:20 Chousuke: JAS415: Well, the libraries could be written in Scala or Groovy too

17:21 jwhitlark: or jython, I suppose.

17:21 Chousuke: mebaran151: transients look like they can be used pretty safely anywhere, but I doubt it's worth the trouble unless you have a code path that is a bottleneck

17:21 JAS415: hmm, do we have (.. macro or proxy or genclass for scala or groovy?

17:21 mebaran151: don't forget JRuby, you could have Clojure on Cleets

17:21 *Cleats

17:21 jwhitlark: Which is actually an interesting idea for me; I could use my knowledge of the python standard library form clojure. hmmmm....

17:22 Chousuke: JAS415: how do you call a Scala method from java?

17:22 JAS415: do that, then translate to clojure interop. That is your scala interop.

17:22 mebaran151: Scala builds things that look very similar to Java classes

17:22 languages like JRuby and Groovy probably require a bit more dancing

17:22 Chousuke: not to mention clojure itself.

17:22 stuartsierra: JRuby's not hard, I use it.

17:23 Chousuke: Calling clojure stuff through the java interop would probably look a bit ugly... :P

17:23 mebaran151: that's what I meant

17:23 it would be nasty to write a ruby on rails app in clojure, even though it's technically possible

17:23 jwhitlark: what we need are reverse macros ;-)

17:24 assuming that doesn't have a meaning that I'm unaware of.

17:24 stuartsierra: Well, if you use Java calling conventions as your common denominator, all the JVM languages create Java classes/methods.

17:25 headius: not necessarily

17:26 JAS415: sorry didn't mean to be rude and dissapear, had to keep dinner from burning...

17:26 mebaran151: couldn't some languages make some sort of nasty bytecode that might violate the nice neat modle of JVM classes and methods

17:26 stuartsierra: Not if they want the JVM to run it.

17:26 headius: jruby by default interprets code at first, so there's no classes or methods for "java" to call

17:26 Chousuke: ,(.invoke (clojure.lang.Var/find (clojure.lang.Symbol/intern "clojure.core" "+")) 1 2) ; calling clojure through java interop...

17:26 clojurebot: DENIED

17:26 Chousuke: damn

17:27 headius: stuartsierra: I think you're making some assumptions about what the JVM expects...it's extremely liberal

17:27 in scala, for example, you can't create a static Java method

17:27 it's simply not possible

17:28 on the other hand, a lot of scala's constructs can't easily be called directly from normal Java code because they've got mangled names or singleton abstractions or whatever

17:28 scala does some really wild and scary things with bytecode and class/method structures

17:28 stuartsierra: ah, ok

17:28 JAS415: i was thinking about stuart, so for example let and def are private/public variables, defn- and def are functional equivalent (sort of)

17:28 stuartsierra: That's scala's fault, then. :)

17:28 hiredman: ~scala

17:28 clojurebot: {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

17:28 headius: clojure does too, really... a class per function immediately makes it harder to interop because you have a million little classes to link against

17:29 jwhitlark: The transients docs look very good. I went in to it on one end having never heard of it, and came out with a good understanding of when and why I'd use it. In one pass.

17:29 stuartsierra: But in Clojure you can generate nice normal-looking Java classes.

17:29 headius: which are just a shim around a million little classes

17:29 mebaran151: jwhitlark, agreed

17:29 Chousuke: headius: but, perversely, that's a requirement for smooth interop :P

17:29 headius: but yes, it's better for java

17:29 mebaran151: Clojure has really good conceptual documentation compared to most languages

17:29 headius: jruby's various java interop options do the same thing, as does groovy's

17:29 Fossi: no wonder

17:29 Chousuke: headius: since it's the only way for every function to sanely implement Callable and Runnable

17:29 jwhitlark: mebaran151: the best I've ever seen, actually.

17:30 headius: in almost every case where a language needs to present a "normal" looking Java type, they go above and beyond their own data structures and usually produce something artificial

17:30 Chousuke: jruby does something similar, but all in memory

17:30 when you compile a .rb it produces exactly one .class file

17:30 that .class file generates method stubs on boot

17:30 Chousuke: mebaran151: Rich does a good job at explaining the concepts, but the actual API docs have much room for improvement.

17:31 mebaran151: totally agreed

17:31 there is much room for something that's more navigable

17:31 headius: so jruby doesn't have any easier time of interop...we still need to generate a synthetic Java type that is made up of our Ruby structures behind the scenes

17:32 hiredman: hmmm

17:32 mebaran151: maybe even something like the noobkit docs for ruby, that present a hierarchy for documentation

17:32 Chousuke: mebaran151: at least there are the "related functions" sections in the reference nowadays...

17:33 JAS415: it would have been cleaner if java had been implemented in clojure

17:33 technomancy: headius: I submitted a talk for RubyConf on using Clojure's STM and data structures from JRuby, so hopefully we'll see some JRuby love there. =)

17:33 headius: technomancy: neat

17:34 technomancy: I love the way JRuby procs implement Callable; made it really easy to use them with Clojure.

17:35 mebaran151: I wonder if there would be a seamless way adapt multimethods to operate on a ruby class hierarchy

17:37 the clojure api could actually use a comments section

17:37 headius: technomancy: we could improve that consistency a lot...but where we have it it's nice

17:38 jruby's got a lot of baggage still

17:39 mebaran151: and maybe even quick notes as to what is lazy and what isn't

17:39 headius: I'm obviously very interested in language interop in general

17:39 there's a lot of people who will never use clojure and prefer jruby, but getting access to clojure's structures would be great for them

17:40 and lots of people who will never want to write ruby but use clojure, and then want to be able to interop with ruby apps or libraries

17:40 JAS415: clojure on ruby on rails

17:40 headius: it's unfortunate there hasn't been more interest among other language implementers in building a common interop protocol

17:40 mebaran151: as I said, Clojure on Cleats

17:40 headius: the only people who've ever worked on one, as far as I know, are me and Attila

17:41 and mostly Attila

17:41 JAS415: the only thing i would worry about would be programs that use clojure/ruby/python/java/scala/groovy, where you have to have a huge breadth of knowledge to understand the entire codebase

17:42 headius: well, other than scala, those are all pretty easy to grasp at a glance

17:42 mebaran151: wouldn't the ffi stuff be a good conceptual starting point? it seems nasty, but I don't see any more common basis

17:42 headius: mixing scala into any codebase scares me, but I'm still of the opinion that scala is like programming gymnastics

17:42 mebaran151: I've seen ruby C++ C projects before, so it can't be THAT bad

17:42 JAS415: haha

17:43 yeah i just worry about getting the reputationi CL has for maintnence difficulty

17:43 Chousuke: headius: every example of Scala I've seen thus far has been rather off-putting :P

17:43 headius: that will always be clojure's cross to bear

17:43 Chousuke: I've seen some great examples of Scala...unfortunately I wrote all of them myself

17:44 don't get me wrong, I like scala...but I fear it at the same time

17:44 Chousuke: I don't have a real opinion of Scala

17:45 All the times I've tried to learn more about it I've been scared away by cryptic code.

17:45 headius: me too

17:45 Chousuke: something about the syntax just doesn't agree with me.

17:45 headius: alex's book (pragprog) is pretty good, though I've only seen early drafts

17:45 he teaches scala from a rubyist's perspective

17:45 mebaran151: it seems to be weird to try to combine functional techniques with OOP

17:45 OOP is all about state

17:46 JAS415: its is pretty good in CL actually

17:46 headius: yeah, it's a weird combination

17:46 mebaran151: I bought the scala book: it's a confusing hydra of a language

17:46 headius: at least it feels weird in scala

17:46 mebaran151: well you have to do it differently: you can't use Java style oop

17:46 headius: I still would rather write something like Duby for my static-typed code

17:46 piggybox: well, Scala isn't the first one to do that. OCAML comes into my mind

17:46 mebaran151: you probably want something akin to the multimethods or what not

17:46 JAS415: you use functional for certain things and oop for other things

17:46 headius: if I ever got Duby finished

17:46 Chousuke: CL OOP is actually method-oriented programming :P

17:47 mebaran151: I don't think OCaml is modula one

17:47 * Simula style oop

17:47 JAS415: i mean, i find the java oop x-treme methodology to be kind of perverse

17:47 Fossi: what's a binary or in clojure?

17:47 mebaran151: where you have fields that you set

17:47 Chousuke: Fossi: bit-or I think

17:47 JAS415: everything is an object? even abstract stuff? really?

17:47 Fossi: Chousuke: great. thanks.

17:48 Chousuke: JAS415: the thing with java is that it doesn't even adhere to the "Everything is an object" thing :P

17:49 Smalltalk does it right. Even code is objects :)

17:50 mebaran151: I remembering reading somewhere you can either represent objects as hashtables or closures conceptually

17:50 JAS415: yeah that's the idea behind scheme i think

17:50 mebaran151: the hashtable methdology with fields and such, just isn't such a good fit for functional languages, where as closures are a natural way to carry state in real functional languages

17:51 JAS415: they had factorial and actorial and it turned out to be the same thing :-)

17:51 same code*

17:52 mebaran151: I don't know much about clos, but I've heard it's filled with Dragos

17:52 *Dragons

17:52 and Cruft

17:54 JAS415: dragons?

17:55 mebaran151: as in, it's a convoluted system

17:55 with lots of ways to do the wrong thing

17:55 JAS415: lisp in general is kind of like that

17:55 enough rope to hang yourself

17:56 mebaran151: I found clojure a lot less crufty than most lisps: it enjoys a sensible design

18:00 jwhitlark: heh. I'm certainly enjoying clojure more than I did elisp. Although I think I'm getting better at the later from my exposure to the former.

18:02 JAS415: i dunno, i guess it depends on what the definition of cruft is

18:03 there are things in CL that are very very nice, but i never really touch, simply because i don't think to use them

18:05 mebaran151: it's nice to break with the past though

18:05 try reading an mp3 file in common lisp or anything like that

18:06 I can think of 10 Java libraries I can choose from with sane api's

18:06 JAS415: yeah definitely

18:06 try even installing CL without already knowing how to do it

18:06 i think it took me the better part of a week the first time i did SBCL, and I didn't even have it setup right

18:09 Chousuke: I think one huge benefit over CL that Clojure has are first-class hashmaps and vectors (and sets).

18:10 poor sets, always mentioned in parenthesis

18:10 JAS415: you can write some pretty macros with that stuff :-)

18:10 Chousuke: yes. and you don't need four sets of functions, one for each data type.

18:11 mebaran151: also found macro writing in clojure more approachable

18:12 JAS415: the helper macros being built in... helps :-P

18:12 Chousuke: helper macros?

18:12 JAS415: off the top of my head the `var# macro

18:12 Chousuke: ahh, autogensyms

18:12 yes.

18:12 JAS415: i think there are others but that is the big one

18:13 Chousuke: the namespace-qualifying property of syntax-quote is almost as big, if not bigger :)

18:13 JAS415: yeah that's true, the trick there is figuring out how to circumvent it

18:14 Chousuke: which is relatively easy.

18:14 JAS415: yeah :-)

18:14 jwhitlark: I love sets. I had an interview question, where they changed the requirements to keep a unique list of items instead of all items, took me one second to change my code. Got the job.

18:16 Chousuke: heh

18:24 mebaran151: sets are an important data structure

18:24 very useful for the current project I'm working on which essentially does a little relational calculus

18:24 it's also nice that they are lazy (I think)

18:25 technomancy: sets can't be lazy.

18:25 since you'd have to realize the whole thing to determine membership.

18:25 mebaran151: that does make sense

18:25 but luckily I can map over them lazily

18:26 technomancy: if you're producing a list, yes.

18:26 mebaran151: which is where it matters (I don't hit the db, until I need the return value)

18:26 working with laziness has turned out to be a lot of fun

18:31 Chousuke: Laziness can sometimes surprise you though.

18:31 You may not get what you think you should get :)

19:05 cemerick: rhickey: the transients document is very good

19:15 lizp: hi! lets say i want to write the following macro: (defmacro aif [x y] `(let [it ~x] (if it ~y))) and have y be an expression that uses 'it'. my problem is that upon expansion ` makes 'it' become 'user/it' and 'it' doesnt exist..

19:16 cark: use this form : ~'it

19:18 lizp: no, it is still user/it

19:19 for example: (aif (+ 2 3) (print it))

19:19 cark: mhh there is something like it though ...let me check

19:19 lizp: ok

19:19 ok

19:19 sorry

19:20 tomoj: (let [it# ~x] (if it# ~y)) ?

19:21 lizp: thank you cark, it works

19:22 this works: (defmacro aif [x y] `(let [~'it ~x] (if ~'it ~y)))

19:22 cark: oh great i was wondering how it was working here and not to your place !

19:22 tomoj: isn't that a really bad thing to do, though?

19:22 cark: no it isn't

19:22 but i beleive it was made hard to do so that you don't do it by mistake

19:22 lizp: so ~' is basically unquote then quote?

19:23 otherwayaround

19:23 cark: not the same kind of quotes

19:23 tomoj: indeed, but... why does lizp want to do it?

19:23 cark: the aif macro is pretty standard lisp stuff

19:23 avital: lizp yes why do you want to do it?

19:23 tomoj: it was made hard for a reason :)

19:23 cark: "a" stands for ...take a seat .. anamorphic

19:23 avital: anaphoric

19:24 cark: oh

19:24 lizp: why do i want to do the macro or the ~' thing?

19:24 tomoj: maybe I don't understand what the macro is supposed to do

19:24 avital: lizp the whole macro

19:24 cark: avital:indeed =/

19:25 you could (if (retreive-customer customer-id) (print it))

19:25 you could (aif (retreive-customer customer-id) (print it))

19:25 =)

19:26 lizp: yeah

19:26 :)

19:26 avital: its a quite common scenario - you want to act if something is not nil

19:26 on that thing

19:26 instead of writing a let each time

19:26 tomoj: ok, but suppose I have a variable "it" already

19:26 avital: this both saves space and makes the code more readable imho

19:26 tomoj: that macro clobbers it

19:26 cark: though the macro you wrote won't work that way

19:26 avital: tomoj: sure you have to take care

19:26 cark: and they can't be nested

19:27 avital: yes if you want to nest such things you have to think of a different scheme

19:27 cark: so we have in clojure : when-let if-let

19:27 tomoj: oh, gensyms don't work in this case, I see

19:28 cemerick: jeez, I pop into #haskell for a sec just for the hell of it, and this is the first thing I see: data G = G (G -> a -> b); f :: G -> a -> b; f (G g) a = g a; g (G f) h = f h; h = g (G f) (G f)

19:31 avital: ,(source if-let)

19:31 clojurebot: java.lang.Exception: Unable to resolve symbol: source in this context

19:31 avital: oh

19:31 cark: ~def if-let

19:32 avital: cark thanks :)

19:36 Chousuke: cemerick: what is that supposed to mean?

19:36 cemerick: absolutely no idea

19:37 I thought of popping in after hiredman got clojurebot to drop some scala :-)

19:37 tomoj: looks vaguely similar to the Y combinator to me

19:37 Chousuke: as far as I can tell it's some kind of recursively defined type and then a bunch of functions

19:37 cemerick: ~scala

19:37 clojurebot: Scala often gets in the way when trying to write neat code -- seen in #scala

19:37 cemerick: ~scala

19:37 clojurebot: {((x: Any, y: Any) => (f: Function2[Any, Any, Any]) => f(x, y))(1, 2)((x: Any, y: Any) => x)}

19:37 cemerick: there we go :-)

19:37 hiredman: evaluates to 1, btw

19:38 tomoj: there apparently is a G combinator

19:38 apparently having something to do with "anaphoric" something or other, interestingly

21:42 JAS415: swing feels inelegant, this is kind of frustrating

21:43 quidnunc: Anyone know how to specify a DNS server when using pppoe client?

21:47 quidnunc`: Sorry, wrong chan

21:50 slaney: are these sanctioned? ...like do proceeds help the dev effort? http://www.zazzle.com/clojure+tshirts

21:51 hiredman: I think Chouser created the store

21:51 slaney: ok

21:51 coolio

21:53 hiredman: 2009:Feb:16:20:48:26 Chouser : blbrown: you should. I've currently got the keys to that account, but since the ideas are mostly not my own I've already said I'll give the proceeds (if any) over to Rich.

21:54 slaney: danke

21:57 Carkh: question : is there a way to detect we're compiling during AOT compilation ?

21:58 hiredman: ,(doc *compile-files*)

21:58 clojurebot: "; Set to true when compiling files, false otherwise."

21:58 Carkh: thanks !

22:04 cemerick: Brief/helpful comparison of transients to haskell's SP monad here: http://www.reddit.com/r/programming/comments/977mq

22:04 or, actually: http://www.reddit.com/r/programming/comments/977mq/think_persistent_data_structures_and_functional/c0bo4md

22:13 hiredman: ~max users

22:13 clojurebot: Titim gan éirí ort.

22:13 hiredman: ~max people

22:13 clojurebot: max people is 149

22:44 cemerick: huh, that should be 164

22:48 durka42: does it not count often enough?

22:49 hiredman: nah

22:49 I reset it to 5 a while back to see if it was working

22:50 ~max people is 164

22:50 clojurebot: Roger.

22:50 onats1: question guys

22:50 when is clojure useful?

22:50 hiredman: always

22:51 onats1: im just curious about it.. as i've read the label..

22:51 hiredman: clojurebot: rationale

22:51 clojurebot: rationale is http://clojure.org/rationale

22:51 onats1: hiredman, can you give me a scenario? like, and end-application that was done using clojure?

22:51 hiredman: clojurebot

22:52 I have used clojure and htmlunit to do screenscraping with clojure

22:52 clojure and SuperCSV to do CSV processing

22:53 people are using clojure for hadoop jobs

22:53 some people are even using it for writing android apps

22:58 onats1: this is a fairly new concept to me

22:58 is it similar to haskell?

22:59 hiredman: ~blip.tv

22:59 clojurebot: blip.tv is http://clojure.blip.tv/

22:59 hiredman: I would check out the videos

23:00 onats1: alright

23:07 arohner: onats_: I'm making a website using it

23:07 onats_: arohner, deployed on what?

23:07 arohner: compojure & apache on AWS

23:08 oh, and jetty

23:08 compojure is a clojure web framework

23:47 tomoj: to me compojure looks more like a tool for building web frameworks

23:48 I guess I'm just used to heavily opinionated frameworks

23:51 arohner: tomoj: you're not wrong, it is low level, but that's what we have right now. it hasn't been much of a hinderance though

23:52 Carkh: did they manage to make expiring sessions yet ?

23:52 tomoj: yeah, I think that's awesome

23:52 I have been pondering writing my own framework based on compojure

23:52 need to learn clojure better first I suppose

23:53 actually I want to go learn seaside first since if I tried now it would just be a clone of rails

23:53 arohner: Carkh: I haven't heard of anything, though I haven't been following the group closely

23:53 Carkh: arohner: me neither ...

23:53 though i 'm almost done with an app

23:54 and that's one of those things i still need to look into =/

23:54 gko: What's the minimum JDK version to compile Clojure?

23:54 Carkh: 1.5

23:54 gko: Argh...

23:55 No 1.4 ?

23:55 Carkh: nope =(

23:55 gko: Too bad :(

23:55 hiredman: why dod you need 1.4?

23:55 do

23:56 gko: Old machines

23:56 DEC OSF1

23:56 hiredman: Oh

23:56 gko: Can find only 1.4.2

23:56 hiredman: ouch

23:57 gko: yeah

23:57 mebaran151: so I've got a bunch of sets and I'd like to lazily combine them

23:57 #{0} #{0 6} #{0 6} #{0 6 12} #{0 6 12 18}

23:58 essentially I'd like this to look like a lazy list that would go 0 6 12 18 etc

23:58 how can I do this?

23:58 hiredman: sets are not lazy

23:59 mebaran151: no I know

23:59 but I'd like to lazily combine them

Logging service provided by n01se.net