#clojure logs

2010-01-22

00:11defn[_]'
00:11defn[_]'lo
00:43defn[_]autodoc++
04:27neotykHi *
04:27neotykClojure-on-Clojure is it possible to get AST already?
05:30KarlsFriendHi. I have a question. This is a chatroom about the prog. language clojure right?
05:31leafwKarlsFriend: yes.
05:32KarlsFriendleafw: I've been here for 10 minutes now. 5 people joined. But nobody talks. How come?
05:32leafwUSA is sleeping
05:32KarlsFriendare they pming?
05:32leafwmost folk are over there.
05:32KarlsFriendok. but if i need help with clojure this is still the right place to ask?
05:33neotykyep, also mailing list is good to ask
05:33leafwKarlsFriend: mailing list is better. More asynch and in-depth.
05:34KarlsFriendi am at the very begining and wondering why my code crahes. can you take a look at it?
05:34leafwI can't :) to busy
05:34LauJensen~paste
05:34clojurebotlisppaste8, url
05:34lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
05:34LauJensenKarlsFriend: Try pasting it
05:34KarlsFriendok, thx
05:36lisppaste8karlsfriend pasted "Working with canvas" at http://paste.lisp.org/display/93728
05:36ChousukeKarlsFriend: indent less :)
05:36KarlsFriendok the problem is that i expect "gamestate" to be a ref to an int.
05:36ChousukeKarlsFriend: two spaces is the lisp convention
05:37KarlsFrienddo you have alink where i can look that up?
05:37KarlsFriendChosuke: the whole convention thing. i never used lip
05:38KarlsFriend*lisp
05:38Chousukewell, there is a scheme style guide
05:38Chousukeit applies pretty well to clojure
05:38Chousukewith a few exceptions
05:38Chousukehttp://mumble.net/~campbell/scheme/style.txt
05:38KarlsFriendok thx. i will lokk over it
05:38Chousukeit tells you not to use [] etc. but that obviously doesn't apply to Clojure :)
05:45spariev_KarlsFriend: it looks like you're using function with side effects (drawF) in dosync, maybe that's why it crashes
05:46ChousukeKarlsFriend: one common thing to do is to have the game state be a global ref
05:47KarlsFriendspariev: i am goin gto try that.
05:47KarlsFriendChosuke: I thought about that, but that would prevent me from having to games at the same time. Not that i would want that. But there must be another way
05:48KarlsFriend*two games
05:49cgrandKarlsFriend: (ref-set gamestate (gameF (deref gamestate) t canvas)) is better written (alter gamestate gameF t canvas)
05:50KarlsFriendcgrand: thx i was looking for that function
05:52cgrand(let [new-gamestate (dosync (alter gamestate gameF t canvas))] (drawF gfx new-gamestate canvas)) to get the side-effecting fn out of the dosync
05:53lisppaste8karlsfriend annotated #93728 "untitled" at http://paste.lisp.org/display/93728#1
05:54cgrandKarlsFriend: in your last version you aren't sure that the gamestate value when you call drawF is still the same as when you updated it in the dosync above. Does that bother you?
05:56lisppaste8Chousuke annotated #93728 "cleaned up a bit" at http://paste.lisp.org/display/93728#2
05:57KarlsFriendGotDiI got disconnected somehow. Anyone posted a solution to my problem? ;-)
05:57cgrandhave a you a stack trace to show us?
05:58Chousukehttp://paste.lisp.org/display/93728#2
05:58lisppaste8karlsfriend annotated #93728 "stacktrace" at http://paste.lisp.org/display/93728#3
05:58Chousukeyour problem was that you forgot to deref game-state
05:58Chousukeyou passed the ref to drawF
05:58Chousukeand then passed that to .drawRect
05:58Chousukeand of course it blew up
05:58cgrandChousuke: nice catch
06:00ChousukeKarlsFriend: but yeah, having a global state ref will prevent you from running two games concurrently, that's true
06:00KarlsFriend3ok sorry. i closed mirc again :-/
06:00Chousuke:/
06:00KarlsFriend3(ref-set gamestate (gameF (deref gamestate) t canvas))
06:01KarlsFriend3that did not deref it?
06:01Chousukeit did, but then you passed gamestate to drawF
06:01Chousuke,(let [a (ref 1)] [a (deref a) a])
06:01clojurebot[#<Ref@1f49e84: 1> 1 #<Ref@1f49e84: 1>]
06:01Chousukesee
06:01KarlsFriend3ah now i see it!
06:01KarlsFriend3thanks Cousuke
06:02Chousukesee my annotation as well. looks a bit better with less indentation (and no camelcase), doesn't it? :)
06:03Chousukeand you're correct about having global state limiting you to one game at a time
06:04Chousukecreating the needed ref in a let is a valid solution as well, but it'll complicate debugging a bit
06:05KarlsFI just switched to Win 7. I know most of you use linux. But does anyone have an idea why mirc somehow closes itself?
06:05Chousukeit's not crashing, is it?
06:06KarlsFno i now see i have it open 3 times
06:06Chousukeso maybe it's just minimised? :/
06:06Chousukein the system tray or something
06:08Chousukehttp://clojure-log.n01se.net/ you can follow #clojure logs here to see things you might've missed
06:09Chousukeit's not real-time though.
06:14AWizzArdChousuke: if you want real-time come here :-)
06:14Chousukewell, doesn't help if you have a connection like KarlsF :P
06:49tcrayfordAny idea why the second to last test in this fails? http://gist.github.com/283706
06:50tcrayfordam using (is (thrown? exceptionclass body)) to check if an exception is thrown
06:51tcrayfordand clojure-test-mode is showing an error message with IllegalArgumentException displayed
06:51tcrayfordjust not a passing test
06:52tcrayfordlein test is showing up with an error as well, with my IllegalArgumentException as the error
07:17LauJensentcrayford: Where is thrown? defined?
07:45jcromartiewhat am I failing to comprehend here:
07:45jcromartie,(re-matches #"x" "xyz")
07:45clojurebotnil
07:46jcromartiedoes it have to match the entire string?
07:49jcromartiefor example, in JavaScript or Ruby a simple regex of "x" matches the "x" in "xyz"
07:55jcromartieI guess it's just a Java regex
08:38chouserjcromartie: re-find
08:38jcromartie,(re-find #"x" "xyz")
08:38clojurebot"x"
08:38jcromartiehmm
08:39chousersome regex engines, like java's and python's have two different entrypoints. One function for matching the whole string, and a different one for searching for a match within a string.
08:39jcromartiethe matches/find distinction seems strange but I guess it's the underlying Java library
08:39LauJensen~regex
08:39clojurebotSometimes people have a problem, and decide to solve it with regular expressions. Now they have two problems.
08:40jcromartieright
08:40jcromartie:)
08:41LauJensenre-seq is also handy
09:02chouserfogus: you got on lambda the ultimate!
09:03fogusI'm amazed at the traction of those slides...
09:04fogusI just stuck them up on my site so that the CAP CLUG folks could see them ... weird
09:05chouser:-)
09:08cemerickI had forgotten about the fine-grained locals clearing. That's in master at this point, right?
09:09chousercemerick: I think so, yeah
09:09rhickeyfogus: what were you trying to demonstrate on the transients slide in the bad things section?
09:09chousercemerick: sorry, that was weak. Yes, that's in master.
09:10cemerickchouser: I'm a big boy, I could have looked it up myself if I weren't so lazy. But thanks. :-D
09:12fogusrhickey: My only point was that if it's at all possible to localize the transient to a function or block then do so. In my actual talk I noted that they were isolated to single threads and an attempt to mod in another would except. That dialogue is of course not reflected in the slide
09:13rhickeyfogus: but it is ok to write a chain of functions that build up a transient.
09:15rhickeynothing bad can happen, and I wouldn't want people to write unusually large functions in an effort to confine a transient to a block
09:15fogusrhickey: understood, and I think I mentioned that, but the word "always" is terribly misleading.
09:16rhickeythe one thing that can leak is a transient to the same thread. If you kept the transient around and continued to interact with it, reads of that transient could produce different values at different times
09:17rhickeynever subject to race conditions or corruption though
09:18rhickeyI have been working on a model that puts transient use into a new reference type
09:19chouserrhickey: any thoughts about nested transients?
09:19cgrandrhickey: you mean like transients being owned by an agent (sort of an asynchronous accumulator) instead of a thread?
09:19fogusrhickey: Better? http://www.fogus.me/static/preso/clj1.1+/content/transients.txt
09:19rhickeychouser: putting them in a reference type makes that easy
09:20rhickeycgrand: two flavors, one with single thread semantics, the other with internal locks
09:20rhickeyI'd be happy to describe them as long as everyone understand these are not fully baked
09:22rhickeylet me start here, so you all can ask questions
09:23rhickeythe basic idea, recognized by transients, is that the birth of a new value might be a composite operation
09:23rhickeyIf you look at the are we there yet slides, you see the epochal time model
09:23rhickeythe transition from state to state is described as an atomic function
09:24rhickeyand it is atomic, from the standpoint of states - no such thing as an in-between state
09:24rhickeybut if you crack open F, you might see something like transients inside, which is fine
09:25rhickeythe reason it is fine, and the key to reconciling this whole notion of immutable states with the mutable memory everyone knows is there, has to do with visibility
09:26rhickeya state must exist in order to be observed
09:26rhickeybetween observations, process can occur, such process might have an extent, but exists between two moments in time
09:27rhickeyso, we have a reference type that can accumulate the effects of process, and manages time as always by providing states, the key being that a state won't be produced until observed
09:28rhickeyso, it looks like a reference type, except it can call transient on the thing placed in it. You send it functions, and it will process them transiently, you deref, it call persistent
09:29rhickeybut you can then keep going, unlike current transients which terminate
09:29chouserah, neat.
09:29rhickeyanyone whose observed has a perfectly fine value in hand
09:29rhickeywho has
09:29cgrandcan you send function afterwards? (calling trasnient again on the persisted/observed state)
09:29rhickeycgrand: right
09:30rhickeyso, this fits right in with Whitehead, where a composite set of thing might influence the next moment
09:30chouserwould there need to be a way to send non-transient update fns?
09:30rhickeychouser: hang on to that
09:30chouserok
09:31rhickeyit has a neat kind of quantum truth to it
09:32rhickeyso then, there are two models for composite forces creating the next state. One is sequential - multiple action from same vector
09:32rhickeythat is the same thread model of transients currently
09:32rhickeythe other model is parallel forces
09:33rhickeythis is a multithreaded model
09:33rhickeyit would be implemented via locking inside, basically enforcing the notion of place
09:34rhickeythen multiple threads could send actions into a cell (I've been calling these cells, with no connection to CL Cells)
09:34rhickeythe results of those actions would accrete
09:35rhickeyany observation would make concrete
09:35rhickeya la Schrödinger's cat
09:35cgrand:-)
09:36rhickeyso, to chouser's question, there's no reason the thing inside a cell would have to be transient-able. Regular fns would work too
09:36rhickeythere is possibility for defining what transient meant, even for POJO's
09:37rhickeyi.e. could be clone
09:37rhickeyso this is a way to bring some of that unsafe existing OO into the safe fold
09:38rhickeyobviously, being based on locks, we don't want to inherit the problems of locks
09:38cgrandso StringBuilder could be used as a transient String
09:38rhickeythe main one being the inherent danger of nesting
09:38rhickeycgrand: yes, right
09:38rhickeyso, cells wouldn't support nesting
09:39rhickeybut they could safely support declarative parallel influencing of several cells at once
09:39rhickeythis is a different model than transactions, which support arbitrary, discover as you go, subsets
09:40rhickeywith cells you could do (inside [cell-a cell-c cell-b] ...)
09:40rhickeymultiple insides could always be made safe, as I can sort for lock acquisition order
09:41rhickeyi.e. if someone else simultaneously did (inside [cell-a cell-b cell-c] ...)
09:42rhickeyso, it inherits a limitation of locks, no arbitrary composition, but no danger
09:42rhickeythat's the basic idea
09:45rhickeychouser: there is definitely work in determining what functions/methods work inside a cell
09:46rhickeysince many OO mutators return nothing
09:46rhickeybut transients would be a start, and clean
09:47chouserthe cell itself would be doing the transient/persistent! calls, right?
09:47rhickeyyes
09:47cgrandso a cell would take an init value, a transient function and a persistent! function (and/or transient and persistent! would be redefined as a protocol)
09:47chouserso that would have to be some kind of configuration option of the cell.
09:47rhickeyand they would be a protocol
09:47chouserok
09:47cgrandok
09:47rhickeyor could be property of cell if supplied explicitly
09:48rhickeythen single-threadednes would be cell property, not in the data structure
09:48rhickeynot sure if there should be 2 different cell types or not
09:49rhickeythe POJO part is least baked, but promising I think
09:50cgrandwith the sequential type replacing the current model? (or the current model being reimplemented on top of the sequential type)
09:50rhickeybut I like putting transients inside something much more than what we have now
09:50rhickeyso, yes, replacing current model of transient in hand
09:51rhickeyI still value the 'keep the same shape' concept
09:52rhickeybut once transients are out of view, then they can support regular conj/assoc in a transient way
09:52rhickeythus making the change to exiting code even less
09:52chouserfor a single cell to support both transient and non-transient actions, the mutation-causer fn (update, alter, whatever) would need at least a flag
09:52rhickeybut, we need a new send/alter operator, and, unfortunately, a different arg order would be better
09:53rhickeychouser: not if it is just a polymorphic fn
09:53cgrandwhy a different arg order?
09:53rhickeyconj on transient vector does transient conj (wht conj! did)
09:53rhickeycgrand: so switching preserves most shape
09:54cgrandof course
09:54rhickey(let [a (cell []] (=> conj a 42) @a)
09:55rhickeycurrently refs would use (=> a conj 42)
09:55rhickeythe recipe would be, wrap in cell, prefix calls with =>, deref on return
09:56rhickeyyou would also need to send 'reads' of cell in, like so (<= count a)
09:57rhickeyin order to avoid realization
09:57rhickeyas (count @a) would require
09:59jcromartieAre there any guidelines for using (:foo bar) over (bar :foo) where 'bar' is a map?
09:59rhickeyof course, you could use this to introduce less functional style code, but that's true of atom too
09:59lpetita danger not to be underestimated
10:00rhickeylpetit: true, but the alternative is - people don't use functional langs because they are too slow, people switch from persistent data structures to ArrayLists
10:01dnolenrhickey: I accidentally read <= as a left point arrow. Would it be useful to have a function say <- to safely read blocking reference types (promises and futures for examples)?
10:01rhickeyone whole aspect of Clojure is recognizing the need for this and making it safe and sound
10:01stuartsierrajcromartie: no, but (:foo bar) seems to be more common
10:01jcromartieit seems more lispy
10:01jcromartietreating the :keyword as a getter function
10:01stuartsierraright
10:02rhickeydnolen: I'd have to think about that
10:02chouserjcromartie: if the key is a literal keyword like that, it's probably best to put it first.
10:02stuartsierrajcromartie: But sometimes you want to treat the map as a "lookup function", in which case (bar :foo) may makes sense.
10:03rhickeyjcromartie: one rule of thumb is, if :foo feels to you like an attribute, put it first, if it feels like an element in a collection, put the collection first
10:03jcromartiehmm, good guideline
10:03chouserjcromartie: then it will survive the map being nil, and in some cases will get you significantly better performance.
10:03jcromartieah, yes, the map being nil is the tricky part
10:03dnolenrhickey: perhaps most useful at the REPL when playing around with promise/deliver/future since trying to print them always blocks. Just a thought.
10:04rhickeydnolen: what would it return if not ready?
10:05lpetitrhickey: sure. Was just reminding me some abuses of atoms that can come up on the ml from time to time (not so many, though)
10:05chouserdnolen: futures print :pending instead of blocking
10:05chouserperhaps promise should too
10:05dnolenrhickey: chouser: that would be nice I think.
10:05lpetitI couldn't follow you guys, too much shared implicit assumptions, to much shared implicit knowledge for me :)
10:07rhickeythe other thing about cells is that they could provide a safe model for 'mutable' primitive locals/members, turning into nothing if non-escaping - still on the fence about that
10:07rhickeylpetit: questions welcome
10:08lpetitFirst, the word cell is really connoted (want it or not), and I'm tempted to link old (partial) knowledge to new (understood) bits of knowledge
10:08rhickeylpetit: think jail cell
10:09rhickeyonly one visitor allowed at a time
10:09lpetitthe following visitors may or may not wait (block) ?
10:10rhickeywait
10:10lpetitby visitor, you mean readers as well as writers
10:11rhickeythere are two separate notions, obtaining the value (state), happens via dereferencing and does not block
10:12rhickeyasking the prisoner a question requires a visit, using the (<= count a) function
10:12rhickeythat blocks, and is pretty special purpose, just for composite operations
10:13rhickeya dereference during a process (change in another thread) see the last-produced state/value, the next one doesn't exist yet
10:13chouserdoes it block on its own, or is it required to be in a (cell ...) form that will do the blocking?
10:13lpetitok, so while somebody is in the jail, every other reader continue to read the future old state's value
10:14rhickeychouser: cell just creates the reference, do you mean (inside ...) ?
10:14rhickeylpetit: yes
10:15chouserrhickey: Ok, I guess I do.
10:15lpetitcould jail or jail-cell be a replacement term for cell ? (carries more meaning at least to me)
10:15rhickeybasically its a Kafkaesque jail - people can bail you out (via dereference) but they only get a clone, you stay in jail
10:16lpetitand has the good property of being less overloaded than cell
10:16rhickeychouser: I'm hoping not, that => will do the right thing, but there are some efficiency issues with nesting-testing
10:18rhickeychouser: it might be that => works alone for single-thread cells, but needs to be inside (inside) for MT cells
10:19rhickeynote that transients and persistent data structures are still critical for this system
10:19lpetitrhickey: how could the (<= count a) question be interesting, if the next time I open the jail, I'm not faced with the same value again (if someone else hit the prisoner in the face during my two (=>) calls ?
10:19lpetit"my two (<=) calls I meant"
10:21rhickeylpetit: it makes more sense in the single-threaded scenario, or when inside several cells in the MT scenario, then there will be no intervention
10:21rhickeybut you still don't want to realize a state yet
10:21chouserah. a deref inside and 'inside' may actually be heavier than a <=
10:22rhickeyyes, a deref always creates a state if the current state isn't, er, current
10:22chouserwhile outside, deref (when it does what you want) will likely be lighter, at least when the prisoner is a transient.
10:23rhickeythat in and of itself is cheap, with transients, but it means you are starting from scratch on subsequent processing
10:23chouseryes
10:23rhickeya deref in a processing loop kills the perf benefit
10:24rhickeyi.e. it just degrades to persistent
10:24rhickeybut with OO cells, could be devastating as most transitions will be full copies/clones
10:25rhickeyer, POJO cells
10:25chouserright
10:25rhickeystill, putting POJOs in cells is much better than current "you're on your own with that"
10:25lpetitwhat's the precise semantics of (inside), again ?
10:26rhickeylpetit: inside essentially lets you get the keys to multiple cells, and visit those prisoners back and forth, without anyone else intervening
10:26chousertaking locks on multiple cells in a sorted (therefore deadlock-proof) order
10:27rhickeyi.e. it is a safe composite lock
10:27rhickeychouser: right
10:27rhickeyand with nesting prevention
10:27rhickeyno insides inside inside
10:28chouserno 'inside's inside 'inside'
10:28chouserhm. maybe that didn't help.
10:29rhickeyinsides don't nest
10:29lpetitnp I understood : no nested inside :
10:29fogusTime flies like an arrow
10:29lpetitno nesting of insides :)
10:29lpetitwhere with transactions it's possible to nest
10:29rhickeyexactly
10:30lpetitand concerning the multi thread scenario
10:30lpetit?
10:30rhickeylpetit: what's the question?
10:31lpetitall the primitives are there ?
10:31rhickey?
10:31lpetitnever mind
10:31rhickeyno please, I'm sorry which primitives?
10:32lpetitno, *I'm* sorry, I need to clarify my mind on other topics first
10:32rhickeyit works with ordinary threads, as do all of Clojure's constructs
10:33rhickeyif multiple simultaneous insides overlap on one or more cells, some will wait, but no deadlock possible
10:33lpetitIf one has 'inside, and a deref "publishes" a new value of the currently "edited" state to the external world, then I don't understand what <= and => are used for ?
10:34rhickey=> is the 'send/alter' function of cells
10:35rhickey<= is the trickier - asking the current process for some visibility on the value being created, must interleave with that process
10:36lpetitbut if all operations on editable cells occur inside an 'inside, one couldn't consider they are all opened by inside and closed at the end, and if one wants to emit an intermediate value as a new state value, one calls deref inside inside ?
10:37rhickeybut the functions you are using aren't functions of cells, they are functions of their values
10:37rhickeyyou need to send them into the cell
10:37rhickeysame model as all of Clojure state
10:38rhickeycalling deref is an observation, causing the realization of a new state and production of its value
10:38lpetitindeed, even inside (dosync) one calls deref & al . It's just the fact that one has to specify the cells he wants to place the lock on, that made me think about that
10:39rhickeyderef calls persistent on the value-in-progress
10:40rhickeyso every time you do that, the process starts anew, and no efficiencies of transience cross persistent calls
10:40lpetitI understand
10:41lpetitso for this composite value creation, one will not have to use a functional style such the one one had to use while manipulating transients, one has to adopt an imperative style
10:42lpetitor maybe not, if => and <= return the cell, humm...
10:42rhickeylpetit: you don't have to adopt an imperative style - it will be even nicer than current transients in supporting the same shape
10:43rhickey<= can't return the cell
10:43lpetitoh really ?
10:43rhickeyjust like count doesn't return the collection
10:43rhickeybut => will
10:44lpetitwhy can't <= return the cell ?
10:44lpetitoh, <= will return the persistent value
10:45rhickeybecause it's job is to return some information about the value in progress: (<= count acell)
10:45rhickeyreturns a number
10:45lpetit<= is intended to be called from outside the (inside), e.g. another thread willing to see what the construction process has been able to produce so far ?
10:45rhickeyderef/@ returns the state/value
10:46rhickeylpetit: more likely from inside. Just consider, you want to add things until you have 100. How to you test for that?
10:47rhickeyif you say (= 100 (count @acell)), you've lost efficiency
10:47rhickeyinstead (= 100 (<= count acell))
10:47rhickeyall of this useful inside a process
10:47rhickeypeeking with <= much less useful, and may block
10:47lpetitoh yes, and I can not really count before entering the (inside) call, or I will be facing potential race conditions ...
10:48rhickeylpetit: exactly, this looking with <= is logically part of this 'process'
10:49lpetitI first thought of <= was meant to do inter-process communication of "progression", but I now realized it's not the primary intent of the primitive
10:49lpetits/realized/realize/
10:49rhickeyof course, I've been using => and <=, but names are welcome
10:49jcromartierhickey: Slightly orthogonal to Clojure-the-language, but I have to ask: Are you able to use Clojure professionally, or is the language development taking up all of your time? And same goes for anybody else contributing heavily.
10:49rhickeyespecially since <= is taken
10:50rhickeyjcromartie: some, yes
10:52jcromartienobody knows I'm *not* using Rails yet :P
10:53lpetit=> and =< for a start :)
10:53_schulte_any recommendations on how to use an imperative Java library which works through side effects from inside of a clojure function?
10:53_schulte_I've tried a number of variations on the following http://gist.github.com/283864 with no success
10:53lpetityes, with great care :-)
10:54the-kenny_schulte_: The map isn't working, right?
10:54jcromartie_schulte_: map produces a lazy seq, you need to force it's evaluation
10:54the-kenny_schulte_: For things like this, you would use "dolist"
10:55jcromarties/it's/its
10:55_schulte_jcromartie: AH!, and here I thought it was something complicated with variable reference
10:55lpetitdoseq
10:55jcromartiethe-kenny: I think you mean doseq/dorun
10:56fogushttp://www.lambdassociates.org/blog/klambda.htm -- Interesting from a cinc perspective
10:56the-kenny,(doc dolist)
10:56clojurebotPardon?
10:56_schulte_thanks for the help, it's working with that simple wrapper
10:56the-kenny,(doc doseq)
10:56clojurebot"([seq-exprs & body]); Repeatedly executes body (presumably for side-effects) with bindings and filtering as provided by \"for\". Does not retain the head of the sequence. Returns nil."
10:56jcromartiedorun being a function, doseq being a macro
10:56the-kennyOf course, doseq :)
10:56the-kennySorry, I'm reading some things in the CL Hyperspec at the moment
10:56jcromartieheh
10:58lpetit_schulte_: using local vars is just a way to convince yourself you're doing it right, but really doesn't buy you anything. It's the instructionList internals which is mutable, and placing a var over the instrunctionList instance will neither prevent that, neither help
10:58_schulte_lpetit: so I could just as easily us a let w/o all the var-get calls?
10:59lpetit_schulte_: and using map as a way to loop over asm, if you're not interested in any value produced by map, is just space overhead by creating all those needless seq values
10:59chouserjcromartie: any time I spend on clojure-the-language is "spare time" for me. At work I use mostly C++ and Clojure.
11:00lpetit_schulte_: I would just go with plain loop
11:00_schulte_lpetit: ah, thanks, so should I use loop and recur?
11:00_schulte_lpetit: alright, I'll give that a try
11:00jcromartieI think loop/recur is a little less elegant for iterating over a seq
11:01jcromartiethere are so many constructs just to do that
11:01clojurebot_ato is a rockstar
11:01AWizzArdchouser: when you can get rid of the C++ stuff then your language mix will be perfect
11:02chouserAWizzArd: exactly
11:02jcromartie_schulte_: (let [lst (InstructionList.)] (doseq [x asm] (.append lst x)) lst)
11:02lpetit_schulte_: oh sorry, if the seq is already there, of course doseq is ideal
11:03jcromartie(I don't mean to be doing peoples' homework)
11:03_schulte_jcromartie: ah, thanks, I was just about to complain about the lack of a map which discards output, but looks like doseq fits that bill
11:03lpetithéhé
11:03_schulte_jcromartie: don't worry, it's not homework
11:03jcromartieFiguratively speaking :)
11:04lpetitmore like grownwork :)
11:04jcromartieheh
11:04_schulte_jcromartie: acutal real life, but yes, this is much appreciated :)
11:05lpetit_schulte_: even worse, you now owe him a penny :)
11:06_schulte_I'll cite you in my working notes :)
11:16rober2hi
11:16rober2after i converted a bean to a map with (bean obj), how can i convert it back to a bean?
11:19stuartsierrarober2: I think you have to write that yourself.
11:20jcromartiekeep the original object...
11:20jcromartieit doesn't seem like a good idea to pass around the result of (bean x)
11:21jcromartieat least if x is some mutable Java object
11:21cgrandand going back and forth between POJOs and maps with bean/unbean (yet to be written) isn't efficient (lot of reflection going on)
11:21jcromartieyeah unbean would have to involve proxy, wouldn't it?
11:22jcromartieor, no
11:22cgrandnot if you pass it a target object
11:22jcromartiesince the bean spec requires a zero-arg constructor and set* for every get*
11:23cgrand(defn unbean [obj map] (doseq [[k v] map] (Reflector/setInstanceField obj (name k) v)))
11:23jcromartie,(bean "")
11:23clojurebot{:empty true, :class java.lang.String, :bytes #<byte[] [B@ee419f>}
11:23jcromartiethe :class key should be used to instantiate the object
11:24jcromartie,(new (:class (bean "")))
11:24clojurebotjava.lang.IllegalArgumentException: Unable to resolve classname: (:class (bean ""))
11:24jcromartieoops...
11:24Chousuke(.newInstance (:class (bean "")))
11:24Chousuke,(.newInstance (:class (bean "")))
11:24clojurebot""
11:24jcromartiethere we go... unbean is almost ready for prime time :)
11:26jcromartie(defn unbean [m] (let [obj (.newInstance (:class m))] (doseq [[k v] (dissoc m :class)] (clojure.lang.Reflector/setInstanceField obj (name k) v)) obj))
11:27jcromartiehmm, needs to check for getters first
11:27rober2thx a lot :)
11:29jcromartieI think bean is a little overzealous about what is a bean property
11:30crioshi all
11:31jcromartiehi
11:31jcromartieare there any good classes to test as beans?
11:33jcromartiehttp://gist.github.com/283890
11:34jcromartieit works for the simplest cases
11:38esj,(has-bean? 'imperative-programming)
11:38clojurebotjava.lang.Exception: Unable to resolve symbol: has-bean? in this context
11:46cgrandjcromartie: http://gist.github.com/283896
11:47jcromartievery nice
11:47cgrandforgot to return obj :-)
11:58Rayneshttp://www.infoq.com/presentations/Value-I...ate-Rich-Hickey <-- That's the most hilarious place I've ever seen an ellipsis.
11:58Raynes"I...ate-Rich-Hickey"
11:59Chousuke:P
12:02Chousukehmm, my new patched emacs has a curious bug.
12:02ChousukeI can't type R
12:02Chousukeif I enable clojure-mode
12:02esj!
12:03RaynesThey are having this 52 weeks of code challenge thing on dreamincode.net, where every week they have a simple challenge to expose users to new technologies and such. This week was a Twitter challenge. I wrote my submission in Clojure, and so far, I think it's the most complex yet. :D
12:03ChousukeRaynes: complex, as in most featureful or the most contrived? :D
12:04RaynesFeatureful. I wrote a http://reddit.com/r/clojure bot.
12:04arohnerrhickey: cells sound really interesting. My only request is that there be "real" names (i.e. words) for => and <=. I grow weary of the explosion of ->, ->>, -?>, etc
12:04RaynesWhen means I parsed HTML, used the bit.ly API to shorten links, and posted results to twitter after processing them.
12:04RaynesMost people just write a little GUI to update twitter.
12:05arohnerand it would be great if -> and ->> had real names as well, so we could refer to them as "thread-first", "thread-last". It would reduce the incentive to come up with crazy function names like -@>
12:05cemerickarohner: just aliases though, right?
12:05arohnercemerick: right.
12:05RaynesBut arrows are prettier.
12:05Raynes:(
12:06arohnerRaynes: just wait until the day where you have to explain the difference between ->>, -?>, -@>, -!>
12:06RaynesI would do it with honor.
12:06Raynes:>
12:06lpetitarohner: you missed :>>
12:07esjzakly, Agincourt was not pretty.
12:07lpetit:)
12:07lpetitI will defend -?> forever, though ! :-p
12:07RaynesI'm slowly converting the people on dreamincode.net to FP. Riches talks combined with sweet sweet envy.
12:07jcromartie-?!?!->
12:08jcromartieMy friend told me yesterday: "next I'll say I'm making cheeseburgers and you'll say Why don't you come over for some Clojureburgers"
12:08esjjcromartie: that's a kebab
12:08arohneresj: you need some @'s in there for a kebab
12:08arohner:-)
12:12lpetitRanyes: the site you're mentioning has really horrible colors :-(
12:13Rayneslpetit: It has really horrible users too, but yeah.
12:22Raynes(def mytree (Tree (Tree nil nil) (Tree (Tree nil nil) nil))) ; MY EYES! THEY BURN!!
12:23esjIs there a big memory / execution penalty to fine grained refs ? Specifically I'm creating a very big map of small objects which are mutated individually. I'd prefer the fine granularity of being able to have each element in the map as a ref, rather than make the entir e map a ref, but am concerned about the implications ? Thoughts ?
12:23esjif its not suicidal I'll probably do it, but don't want to produce something obviously daft.
12:24chouserI'd like to hear rhickey's reaction to that, but if you think it seems to fit your problem, I'd go for it.
12:25esjchouser: thanks.
12:26jcromartieesj: I think you should measure it
12:26jcromartieI have a feeling that a ref containing the whole map is going to be better than many refs
12:27esjjcromartie: testing sounds far too sensible :)
12:27RaynesI'll put 10 dollars on jcromartie.
12:27jcromartiemy understanding is that deriving new instances of the persistent types is efficient and shares memory
12:28chousermultiple threads? each transaction fiddling with a subset of the values? the subsets over time may overlap rather than being cleanly partitionable?
12:28jcromartiei.e. if you had a vector of 1000 items, and you created 1000 new vectors with the first item changed each time, it would not take 1000 x 1000 the space
12:28chouser"no" to more than one or two of those would suggest a smaller number of refs.
12:28jcromartiemy rule is refs for the largest chunk possible
12:28esjnow usually I'd agree. Thing is one reason I'm mutating as that each element in the map has a keyword :endured, which I'm using to flag whether it has gone to the database. I'm worried that if I ref the whole map I'm going to find the I/O to the database will take its own sweet time, and retries on the ref commit will kill me.
12:29esjnow it could be that this flag should be separated from the main map
12:31esjmultiple threads: yes. Transaction subset: yes, but not overlapping.
12:32chouserso you might consider on ref per non-overlapping subset.
12:32chouserthen again, if that requires more complex code, start with a simpler solution and see if it is fast "enough"
12:32esjchouser: nice idea !
12:33esjBut we all agree that the fewer refs you can get away the better ?
12:33Raynesdefn: http://stackoverflow.com/questions/2115021/learning-a-lisp-variant-suggestions :(
12:33esjbarring heroic coding
12:35esjthanks guys.
12:45esjpartitioning is the answer.
12:48jcromartieare my assumptions about the space efficiency of persistent vectors/maps/sets etc. correct?
12:49Chousukeyes
12:49jcromartiethat's good
12:49jcromartieI'd be interested in testing the tradeoffs
12:50Chousukethere are a few blog posts about the data structures around
12:50jcromartietoo bad Java doesn't like being memory profiled :)
12:51Chousukethe persistent structures aren't particularly memory efficient if you're storing lots of small objects :/
12:52Chousukeie. primitives. :P
12:53Chousukebut I think Rich is planning to introduce specialised variants for longs and doubles at least.
12:54Chousukejcromartie: http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/
12:54jcromartieawesome stuff
12:55jcromartiea little bedtime reading
12:55Chousukethere's also an article for persistenthashmap
14:11devinuscan anybody link me to an article on how to get started with clojure/clojure-contrib/slime/swank/clojure-mode/emacs on OS X ?
14:13the-kennydevinus: wait.. there's a good blog post
14:17jkdufairdevinus: apparently ELPA has a clojure slime/swank package that will grab the latest clojure itself too
14:17jkdufairhaven't done it yet but it was discussed here yesterday
14:18the-kennyYeah, just use elpa to install slime and swank-clojure
14:18the-kennyAnd one of my recommendations after that would be leiningen
14:18the-kennyso you can just M-x swank-clojure-project RET dir RET to start a repl with matching classpath etc. for the project
14:21joeggI would like to make this shorter and sweeter: http://paste.lisp.org/display/93750 Can anyone offer some advice? I don't want to play clojure-golf, but if there's something I could do that's better, I would love to know.
14:21joeggI'm still trying to learn the basics.
14:22ChousukeI think the (comparator #(> ...)) thing can be shortened to just > :)
14:23joeggSO COOL!
14:23joeggOf course!
14:23hiredmanhttp://www.reddit.com/r/programming/comments/asm7h/scala_a_postfunctional_language/ <-- it's interesting how little immutable values come up in debates over the definition of functional languages
14:24Chousukejoegg: also the one-branch ifs could be replaced with when to express your intent better
14:25joeggAh, if's without else's --> when.
14:26Chousukeother than that, I can't see anything really wrong with it.
14:27Chousukethough since you're using let to create a "private" lookup table, you could move the private defn to it too
14:27chouserjoegg: since you're using a sorted seq, could do: (defn match [num] (first (subseq numbers >= num)))
14:27joeggChousuke: Thanks for looking! Glad to have a more knowledgable pair of eyes.
14:27Chousukeeg (let [numbers ..., match (fn [num] ...)] (defn speak-num ...))
14:29joeggChousuke: That was going to be one of my questions, is it better style do to an internal utility function as a binding in a let, or not? It appears that the answer is yes. :)
14:29joeggThe defn- doesn't make it local to the binding, but rather local to the (non-existent) namespace, right?
14:29Chousukewell, it's just marked as private
14:30Chousukebut there are ways to get to it from the outside
14:30joeggGood to know, thanks!
14:30chouserjoegg: I'd actually recommend going the other direction. put numbers in a var, like (def numbers ...) instead of a let
14:30Chousukeanyway, I don't have a clear preference for either method. They're both okay
14:30chouserthat makes it easier to redefine individual pieces as you're working on it.
14:32joeggchouser: How so? Just because the let syntax is out of the way better?
14:35chouserif you start with what you wrote in the repl and want to try out a new definition of 'match', you have to reload the whole 'let' block.
14:35chouserif 'numbers' were a var instead of a local, you could just redefine 'match' and try it
14:36chouserthat said, there are certainly times where it makes sense to put everything in a let, helper functions too.
14:36joeggOkay. That makes sense. I'm very much used the edit/compile/run approach, and not the repl, so that explanation was very enlightening.
14:37joeggWould it be normal to start by just approaching everything as defs when you are first working the in the repl, but then move more toward a let/def approach when it is in a finalized and sharable form?
14:37joeggLike, say I wanted this in clojure-contrib (which, of course, I don't), then would the let/def approach make more sense than just multiple defs?
14:38chousernot necessarily. it's fine to have top-level def and defn's that rely on each other
14:38hiredmanI would recomend defs for anything that is not a local sort of scratch value
14:39joeggchouser: Because the an (ns ...) would prevent this from just clobbering the global namespace.
14:39hiredmanvars are rebindable and just make you code more amendable to various work arounds
14:39chouserjoegg: there is no "global" namespace
14:39hiredmanyour
14:39joeggI'm approaching this from something of a javascript background, and so I keep thinking "gotta put my code in a closure".
14:40joeggRight. But in my mind, I'm still stuck in javascript.
14:40joeggWhere this is.
14:40chouserjoegg: ah, yeah, don't worry about that. put your code in a namespace. :-)
14:40Chousukein javascript, namespaces are closures, aren't they? :P
14:40joeggYes.
14:41chouserBefore "releasing" your code, you would want to make sure you've got your own ns declared at the top of the file, but that's all you need.
14:41Chousukeof course you shouldn't declare needlessly public vars
14:42Chousukeyou could make numbers a private var with (def #^{:private true} numbers ...)
14:42chouseryes, though if people aren't being promiscuous with :use, it shouldn't matter too much
14:43hiredmaneven if they are, you get an exception
14:47joeggOkay, awesome. I'm going to make the changes that everyone suggested and I'll repaste it. Thank you all for your help!
14:49rhickeyI'm back from lunch meeting - any lingering questions on transient cells?
14:51chousercan we do ccinc first? :-D
14:51Chousuke:P
14:51Chousukerelated: is it possible to implement cells purely in Clojure?
14:51rhickeychouser: no deps either way
14:53rhickeyI don't want to go another release without transients squared away
14:53rhickeyi.e. change sooner rather than later
14:53rhickeychouser: is that bad?
14:53chouserheh. no.
14:54Chousukethe naming is a bit unfortunate again. :/
14:54rhickeynames are completely up for grabs right now
14:55chousermost of the book is stuff I already know -- little or no new "research" needed. protocols and deftype I need to know better though, and cells would definitely be in that category of course.
14:55chouserso more work, but no not ultimately bad at all.
14:55rhickeyone nice thing is that cells and ccinc will be good proving grounds for deftype and protocols
14:56foguschouser: Well, we have a place-holder for it already. ;-)
14:56rhickeypresuming I don't need volatile for cells
14:56chouserfogus: cells!?
14:57foguschouser: Yes. That was incredible foresight no?
14:57fogus;0
14:57fogus;)
14:57samlhey, @Foo(a=32) private Something x; this is from Java code, is there a short way to get the value 32 from clojure? should i use Java interop?
14:57chouserhm. "cells" in the concurrency section isn't ... quite ... um...
14:58foguschouser: I just kidding. That section was for Tilton (like) Cells
14:58samlin java, I 'd have to do SomeClass.class.getField("x").getAnnotation(Foo.class).a()
14:58chouserfogus: yeah :-) I know.
14:58hiredmansaml: then that should work in clojure
14:58fogusBut Kafkaesque cells could take that space instead.
14:58samlhiredman: thanks
14:58hiredman(-> SomeClass (.getField "x") (.getAnnotation Foo) .a)
15:01rhickeyso we've heard from some who'd prefer chunked seqs not be the default, but I've had no reports from the field on chunked seqs, they've been in master for months. What does everyone else think - do you want to have to ask for chunks explicitly?
15:01rhickeyhttp://blog.fogus.me/2010/01/22/de-chunkifying-sequences-in-clojure/
15:02ChousukeI vote for explicit de-chunking
15:02angermanHmm. my rfe code for libsvm works.
15:02fogusrhickey: I like chunked by default. I tend not to calculate explosive sequences.
15:03drewrrhickey: I haven't had any problems, but I'm sympathetic to the least-surprise argument
15:03stuartsierraI vote chunked by default with explicit de-chunking.
15:03angermanOhh, de-chunking? ... me too. But I'd like to make it explicift if I want it or not. I don't care what's the default, but I want to have an explicit way to do the non-chunked/chunked way
15:03the-kennyWithout being much into the topic, I'd vote for explicit chunking (for example map vs. map-chunked
15:03chouserI'm with stuartsierra
15:03angermanIn the end it will boil down to what is anchored as default in my brain.
15:03chouserand Chousuke
15:04angermanHow do other languages handle this? The default is non-chunked, right?
15:04scgilardiwould explicit dechunking the head of a chain of lazy seqs make the whole chain one-at-a-time lazy?
15:05rhickeynote also that many seqs will never be chunked
15:05Chousukeangerman: few languages even have an analogy. :/
15:05chouserscgilardi: generally, yes
15:05scgilardithen I'm with chouser and stuartsierra
15:05angermanChousuke: Nah, I mean with lazy-sequences.
15:05rhickeyscgilardi: you'd need to dechunk the source of a chain, then everything would be one at a time
15:05rhickeynot the head
15:05chouserI've heard even less call for a collect-chunks step
15:06scgilardiI see. That seems sufficient based on what we've seen.
15:06angermancan we have a configureable chunk size too?
15:06chouserangerman: why?
15:06angerman(e.g. I know I can read 10 itms at a time (memory), but 32 would blow it
15:06Chousukeangerman: the point is that the chunk size is optimised for the underlying representation.
15:06rhickeyangerman: no, because choosing a chunk size not aligned with the data makes things worse, not better
15:07chouserangerman: probably not much value in chunking that at all then -- just read the first 10 individually
15:07angermanok, maybe 10 was a bad choice
15:07angermanare ther other "favorable" sized?
15:07rhickeyit might make sense when the data is generated, i.e. not sourced from a data structure
15:07angerman*sizes?
15:08Chousukeangerman: if you make your own chunked seq you're free to use whatever buffer size is optimal, though.
15:08rhickeysome research shows a sharp dropoff in benefit as you move too far from 32-512
15:08chouserit seems likely that the value of adjusting the chunk size coming from e.g. 'range' would rarely pay for the extra complexity
15:08rhickey32 being a sweet spot for chunking and the persistent data structures
15:08rhickeychouser: true
15:09angermanChousuke: that's right. Scratch what I said. I've looking at the problem from the wrong direction
15:09chouserthough maybe a separate collect-chunk step in the pipeline would work for those rare occasions
15:10rhickeychouser: what does that do, chunkify?
15:11chouserright, would takes individual items and stuffs them into a chunk-buffer. I assume would require unusal performance profile downstream to be worth while.
15:11angermanso basically the generator has to decide what's the optimal chunk size, right?
15:12chouserangerman: yes
15:12rhickeyangerman: everything about this discussion of different chunk sizes seems like premature optimization to me
15:12rhickey32
15:12rhickeythere
15:12chouser:-)
15:12angermanrhickey: to me it looks more like a datastructure problem.
15:14rhickeyif the data structure has specific requirements, that should dominate
15:14rhickeychunk size follows
15:15chouserI do think it would be good to have something like seq1, so that it can be used in pipelines where you know you want one-at-a-time, even if your source is not currently chunked.
15:16rhickeychouser: yes, the whole issue is - is seq1 a wrapper or a request for a non-chunked seq directly supported by all chunked seqs?
15:16chouserah
15:16ChousukeI don't think a wrapper will be problematic.
15:17chouserless work for each collection. I assume there's a worry over performance?
15:17angermanHm. how about a seq-wrapper generator?
15:17Chousukesince if you want to avoid generating more than once item at once, it must not be a very quick operations.
15:17Chousuke-s
15:17angerman(def seq1 (chunked-seq 1))?
15:17Chousukeand the overhead of a seq wrapper would be inconsequential
15:18chouserangerman: chunks of size 1 are not exactly the same as unchunked. seq1 would probably just go unchunked.
15:18angermanchouser: ok, so basically like a flag?
15:19angermanisn't that what "meta" is supposed to give?
15:19rhickeyas it stands, a wrapper can only throttle down post a chunked seq, so is working for range and the current data-based chunked seqs, but they actually are producing chunks. If you had a chunked source and didn't want chunks at any point, an adapter can't do that for you
15:19rhickeyi.e. if iterate was chunked
15:20Chousukewhen would you need that much control? :/
15:20angermanrhickey: right. so it's all about the producer, right?
15:21rhickeyangerman: iff things like iterate became chunked, it would be
15:21angermanThus we would need at "consumer" level a way flag message the producer, wether or not it should emit chunks?
15:21rhickeydata that's already in memory or ephemeral and cheap like range, adapting works fine
15:21chouserthat would be the kind of context where explicitly asking for chunks makes more sense to me. chunked-repeatedly in particular
15:22angermanrhickey: ok. We had "no chunking" before. And that worked consistnely accross the board?
15:22rhickeyangerman: yes, and adapting the things that are currently chunked would work fine too
15:23rhickeymaking something like iterate or repeatedly always chunk would be a mistake
15:23rhickeyso they don't chunk now
15:23rhickeyand may never
15:23chouserright, but it seems like overkill to make vectors know about seq1 just so repeatedly would have that option.
15:24rhickeychouser: yes
15:25chouserso, seq1 as a wrapper with the possibility of chunked-iterate or chunked-repeatedly later?
15:25Chousukeif chunked seqs were "degradable", wouldn't that complicate creating them? :/
15:25rhickeychouser: I need to think more about it, that's why seq1 wasn't in 1.1
15:26chouserok
15:26rhickeyneed recognized, though
15:26angermanChousuke: that's the point why we do not have (send-1) and (send-chunk) on producers, right?
15:26rhickeyso, what does everyone think about this clojureconf idea in the fall?
15:27angermanwhere_
15:27rhickeybay area I think
15:27fogus:-(
15:27angermanhmm. that's east? west?
15:27hiredmancalifornia
15:27angermanIt's at least over the pond, that I know
15:27rhickeysan francisco
15:27angermanohh the earth-quake area
15:27hiredmanno doubt about it
15:27angermanok
15:27rhickeysan jose?
15:27fogusI love the idea -- hate the location.
15:28chouserIt's nice and cheap to fly into Indianapolis.
15:28chouserChicago's a great town
15:28chouserno, me!
15:28angermanfogus: Munich?
15:28fogusangerman: Is that anywhere near Washington DC? ;)
15:29angermanfogus: i think it's close to the airport
15:29angerman:D
15:29rhickeywell, chime in for locations here: http://groups.google.com/group/clojure/browse_frm/thread/7723d2afca4245c5
15:29chouserbut seriously, I'd love to go and/or present present, but I'm not likely to pay my own way there.
15:29the-kennyMunich would be ok for me :) (At least it's in germany :D)
15:29chouserer "present something"
15:29angermanchouser: meta presenting is ok too ;)
15:30fogusangerman: I'll be in Tyrol next fall, so Munich is not too far from there
15:30chouserheh. those are called "introductions" or sometimes "keynotes"
15:30angermanfogus: that's right.
15:30dysingerI hate it
15:30danlarkinconj!!!
15:30dysingerconj!
15:31angermanthough as Munich is most likely the unlikeliest location anyway.
15:31the-kennyLeiningen would be a cool location too. But I think it's a bit far away from any internation airport
15:31technomancydefinitely needs to be called ClojureConj.
15:31danlarkinclojure conj 2010!!! choo choo!!
15:31hiredman(conj clojure you)
15:33rhickeydysinger: hate what?
15:33dysingerClojureConf
15:33Chousukethe name? :P
15:33dysingery
15:33Chousukeyeah, it's a bit plain
15:33dysingerI wanted it to be called Clojure Conj
15:34danlarkinwe want conj!
15:34rhickeyoh, my bad, I didn't mean to imply that was the real name
15:34jimdueyconj
15:34dysingerIt's a play on "Cons" like BSD Con
15:34rhickeysure Clojure Conj
15:34dysingerand it's a function that's about bringing things together
15:34dysingerwhich is fun
15:34chouserfn
15:34chouser"ClojureConj 2010 -- It's more fn!"
15:34dysingerI am just explaining my justification - You probably know what conj is rhickey :)
15:36ChousukeI think it might be better to not write it together, but instead as Clojure Conj :/
15:36rhickeydysinger: what about location? I'm most concerned we enable the greatest attendance
15:36lypanovamsterdam!
15:36danlarkinsf bay area
15:36lypanov(so i can come :P)
15:36the-kennyAmsterdam is nice for me too :)
15:37the-kenny(Almost everything in countries next to Germany is ok :D)
15:37jasapp_Oklahoma is a very central location
15:37jasapp_halfway between SF and Europe
15:37chouserheh
15:37rhickeyNY!
15:37jimdueyKansas City
15:37jimdueyGreat ribs
15:37lypanoviceland!
15:37Chousukeunless it's held in Finland I'm very unlikely to be able to attend, but...
15:38cemerickNorthampton, halfway between NYC and boston ;-)
15:38hiredmanSeattle!
15:38jasapp_jimduey: the bbq in kc leaves a little to be desired ;)
15:38technomancycurrently the largest gathering of Clojurists ever has been in SF
15:38the-kennyWe should go swimming in the Atlantic
15:38rhickeycemerick: dream on
15:38jimdueyjasapp_:not
15:38dysingerI would rather have SF since Amit and I are organizing
15:38dysingerand it has the biggest clojure group in the US
15:38angermanChousuke, the-kenny: let's buy a boat :D
15:38technomancyyou have to have an organizer in the city where the conference is held
15:39AndiXnghi
15:39technomancyso if you're arguing for your home city, it should be taken as implicitly volunteering to help run it. =)
15:39angermanyea, the clojure community is quite weak in munich. I'd say it's part of the lisp user group but even those don't get to have regular meetings. :D
15:39tbatchelli2at disclojure.org, most of the readership is from the US, and of those, most of them located in CA... I don't know how representative this data is though
15:40tbatchelli223% California, 10% Ohio, 7% Massachusetts and NY
15:41angermanchouser: you are diqualified for cheating.
15:41cemerickchouser: I think we're pretty much hosed :-/
15:41chouserd'oh
15:41rhickeyclojure site has been consistently 45% US
15:41jasapp_isn't that what curl is fore?
15:41jasapp_for
15:41angermanrhickey: ok, so not US
15:41chousercemerick: not the least because we aren't even pulling for the same town :-)
15:41fogusFor what it's worth my blog is CA, NY, TX
15:42dysingerTexas!!!
15:42dysinger:)
15:42scgilardiclojure map: http://bit.ly/4CKYzO
15:42dysingerj/x
15:42angermandysinger: I'm not gonna set a foot into that part of the world
15:42tbatchelli2Americas 51%, Europe 40%, Asia 5.5%
15:42dysingerangerman: but they have Whataburger!
15:43AndiXngcan anybody help me with the following question about deftype: the doc says that fields "can have type hints", but this seems to work only for primitive types, not classes. how is this useful for direct Java interop anyway, because I have to cast each time before using a field?
15:43rhickeyDo they let NYers into Texas?
15:43dysingerHawaii represent!
15:43fogusAlthough NY, NY is the #1 reader for my site
15:43cemerickchouser: I'll come to ohio just to represent the hinterland locales generally.
15:43chousercemerick: ok! I'd drive to ohio
15:43technomancythe east coast has a lot of people, but pretty spread out
15:43cemerickchouser: aren't you in ohio? or crap, was it IN?
15:43chouserpeople in chicago could drive there too
15:43technomancythe density of clojurists around the SF Bay is pretty serious
15:44chousercemerick: heh. yeah, IN. I know, pretty much interchangable to you coastal folk. :-P
15:44technomancyalso: the map is probably not updated much, so take a grain of salt w/ that
15:44tbatchelli2I get 3 times as many visits from SF than from NYC
15:45hiredmanhayward would be nice
15:45rhickeyhttp://www.google.com/trends?q=clojure&amp;ctab=0&amp;geo=all&amp;date=ytd&amp;sort=0
15:45technomancyhiredman: kevins still outnumber non-kevins in Seattle
15:45cemerickchouser: people talk about coming to w. mass. like it's the same as scaling K2, so I feel you.
15:45hiredmanboo yeah
15:45chousercemerick: :-)
15:45chousercemerick: I've actually been to w. mass. There's six flags out there, right?
15:46cemerickrhickey: yeah, that's what makes you the man. :-D
15:46cemerickchouser: yeah, haven't been to it in a *long* time though. People here still call it Riverside (which was the independent park that Six Flags took over and basically ruined).
15:46chouserah. went there once when I lived in NH
15:48angermanHow about Vietnam?
15:48angermanCan Tho is pretty nice.
15:48angermanCheap, warm, sunny :D
15:49angermanAnd it's likely equally far away from each of us :]
15:52dysingerVietnam ???
15:53angermanyea, good, cheap food.
15:53angermancell coverage is no issue
15:53angermanwifi usually not
15:53dysingerI think I would have a hard time paying for my team flying to vietnam
15:53fogusI would be all for Tokyo. Clojure is getting big in Japan
15:53angermanfogus: Tokyo is so expensive
15:54hiredmanSeoul!
15:54angermanhiredman: ok, haven't been there.
15:54patrkrisLauJensen: Hey. Will the changes to the front-end be available in ClojureQL 1.0 or will it come in a later version?
15:54dysingerWe could have some interesting conversations while wifi-ing at some amsterdam coffee shops if it where there (thinking)
15:54lypanovyeah!
15:54lypanovand anyone that wishes can sleep at my place in den haag
15:55lypanov(well, limit 4 people)
15:55hiredmanif it was in seoul I most likely could get my parents to pay for my flight
15:55dysingerhehehehe
15:55technomancyI was going to say... how big is your place? =)
15:55dysingerlypanov: I hope there is at least 100 that come
15:55danlarkinok hiredman we'll plan the conference around your budget
15:55hiredman:P
15:55hiredmandanlarkin: I would appreciate it
15:55danlarkins/your/your parents/
15:55lypanovmy budget is negative
15:55lypanovdoes that mean we get paid to come? :D
15:56dabdanyone from here is coming for the european lisp conference in Lisbon (May 2010)?
15:56angermanHmmm if I can get my Prof into thinking that Clojure is important, maybe I can get the money from the university.
15:56danlarkinso we're all agreed, SF, Chicago or NY. Probably SF
15:56danlarkinbook it
15:56hiredmanin the fall right?
15:56danlarkinyeah
15:57chouserI guess I knew what I was doing when I decided to not live in CA.
15:57lypanovdabd: oo, thats very doable for me in comparison to anything states side.
15:57hiredmangah
15:57technomancyif it's not near an airport with lots of non-stop flights it complicates things a lot
15:57technomancyhiredman: you can fly from SEA to SFO for like $69
15:57lypanovamsterdam!! ...
15:58hiredmantechnomancy: really?
15:58technomancywell, one-way at least
15:58lypanovi suppose a few can fit in my basement! as long as its summer!
15:58hiredmanI was just looking at priceline and it looked like $250 for a roundtrip in september
15:59technomancyhiredman: I came down for the Clojure meetup around JavaOne for only a bit over a hundred
16:00lypanov(man, as much as i love .nl. jobs blow :) )
16:00Apage43*going
16:01lypanovprobably enough for my morning toast :D
16:02dabdlypanov: it would be interesting to see some Clojure people in Lisbon http://www.european-lisp-symposium.org/
16:03angermandabd: hmm. let's hold the clojure conj _inside_ the els
16:03dysingerI think you'll find that the universe pretty much covers everything..
16:10lypanovdysinger: mars! its equally far from us all!
16:10hiredmanNSA was giving away shuttle engines
16:11angermanNSA?
16:11tbatchelli2lypanov: it depends on the time of the day, doesn't it?
16:11hiredmanpardon
16:11hiredmanNASA
16:11hiredmanthey tried to sell them but no one would buy them
16:11angermanclojureconj on mars would definitely cause some media attention
16:13angermanwell. bye.
16:13lypanovlol
16:13lypanovah, dabd is in pt. explains. hehe
16:14lypanovbit far for me, but far more doable than the states.
16:14lypanovand i'd just love to come :(
16:17joshua-choi,(list* ())
16:17clojurebotnil
16:17joshua-choiIs there a particular reason why list* called on an empty sequence returns nil instead of the empty list?
16:20hiredman,(doc list*)
16:20clojurebot"([args] [a args] [a b args] [a b c args] [a b c d & more]); Creates a new list containing the items prepended to the rest, the last of which will be treated as a sequence."
16:20hiredmanI think "as a sequence" is they key point
16:23slashus2Hello everyone.
16:25cemerickIt's seems like fns such as atoi should be in core...
16:27DeusExPikachuis there something like this clojure (from python) somevector[1:-1]
16:27headiusFYI: http://gist.github.com/284140
16:27headiusI know some of you dig JRuby
16:31rhickeyheadius: so all fields of Clojure::Object derivees are refs?
16:31cemericktalios: welcome :-)
16:32talioscemerick: howdy :) I need to fire up my IRC client more often and lurk more.
16:33DeusExPikachunm, subvec
16:33cemericktalios: you could pimp clojure-maven-plugin, anyway ;-)
16:33taliostrue - and maven-polyglot-clojure - which I need to do some work on as well.
16:34cemerickthat's a new one on me.
16:34cemericktalios: does clojure still have issues under osgi?
16:35taliosmmm, to be honest I've not tried under 1.1.0 - but the last time I tried it every namespace/function got defined under the classloader for RT, but unloading the bundle leaves those classes around
16:36taliosI was meaning to look into trying a bundle-deactivator which calls an 'unload namespace' to remove it from clojure's RT, but havn't had a chance to try it
16:37cemericktalios: I *think* that's no longer a problem.
16:37cemerickat least, such issues don't occur in NetBeans Platform apps anymore (which use an osgi-esque classloader structure)
16:37talioscemerick: oh cool, I'll have to dig out my OSGi clojure test code and give it a bash
16:38rhickeyI'd like to improve the story there, if I knew what was needed
16:38talioscemerick: http://polyglot.sonatype.org/clojure.html <- polyglot maven - write your POMs in clojure (pom.clj)
16:38taliosWrite, and -script- your POMs that is
16:38cemerickoh, sonatype-hosted, even, nice
16:39cemericktalios: so the objective is to have complete parity with xml-based poms?
16:39talioscemerick: yep,so far theres clojure, scala, yaml, and ruby DSLs
16:39talioscemerick: yep, theres a transformer as well: ./bin/transform pom.xml pom.clj - converts the XML to a clojure version and vice versa
16:39cemerickhow well baked is it, relative to clojure-maven-plugin?
16:40talioscemerick: its independant of clojure-maven-plugin, however - the compiler plugin is "automatically added" to the POM model, so it compiles clojure out of the box
16:41taliosthe polyglot side of it is solely the maven POM, not clojure compiling etc
16:41taliosits's experimental :) Currently I know the release plugin will break, as theres no easy way to update version numbers if/when the pom is a scripted magic foo
16:42cemerickwell, the release plugin is broken for me anyway :-P
16:42taliosheh
16:43cemerickno, seriously, it doesn't work right with git + hudson
16:43dysingerheadius: when is the jvm language summit each year and where ?
16:44taliosHrm. I use the release plugin with git without problem, how does hudson play into that?
16:44cemericktalios: see the comments near the bottom of http://wiki.hudson-ci.org/display/HUDSON/Git+Plugin
16:44rhickeydysinger: http://openjdk.java.net/projects/mlvm/jvmlangsummit/
16:45cemerickyou really want to have your CI environment do the release, but hudson's git plugin doesn't check out refs, so there's no way to push back.
16:45dysingerrhickey: headius maybe we could do the clojure conj 2010 around the same time.
16:46dysingerit's in santa clara nearby
16:47rhickeydysinger: would be useful for me, but don't expect much overlap in attendees otherwise - language summit is for implementors
16:48dysingeryeah I am only thinking of usefulness
16:48talioscemerick: mmm, personally I'd rather do the release locally, so that I know no random commits are leaking in - unless the CI server pulled out a specific release branch.
16:48rhickeydysinger: I wonder if there will be a Java One, nevermind JVM lang summit
16:48dysingerAre we going to have to get a Pledgie button to get chouser out here ?
16:49talioscemerick: A while ago I was thinking I'd love a release plugin "hack" that did the tag/branch etc., but then created a new "Release Build" profile in TeamCity (which we use) so that does that build.
16:49dysingerrhickey: true
16:49taliosrhickey: Javaone's now mentioned on the moscone website
16:49cemericktalios: that's what Brad is talking about there -- even if you tell hudson to build a particular branch, it won't use that branch's ref for checking out, so no pushing. You should be able to build, release, push on a release branch, if that's your bag.
16:49dysingerI'll go to the airport with my coffee cup and guitar to raise money to get chouser out here :)
16:50rhickeytalios: they would have to seriously alter their process, no call for papers yet even - last year they were vetting accepted presentation at this point
16:50taliosrhickey: http://www.moscone.com/site/do/event/view?nav.type=0&amp;nav.filter=1005&amp;nav.base=1001&amp;id=440
16:50talios06/22/10 - 06/25/10
16:51rhickeychouser has to come to clojure conj!
16:51taliosrhickey: true. Whats interesting is that the moscone details went up the day the EU agreed to let Oracle buy Sun, and the Mosone webpage shows a photo of Larry
16:53rhickeytalios: great!
16:57dysingerDo we have any good contacts for a cheap (but good designer) for clojure conference website?
16:57rhickeythickey:
16:57the-kennyrhickey's Brother?
16:58rhickeyyes
16:58Raynesrhicky and thicky. What a pair. What a pair I say, what a pair.
17:00headiusrhickey: yes, all refs
17:00headiusstepped away for a bit
17:00headius@foo and @foo = are just deref and set
17:01rhickeyheadius: one of the issues with making each field its own ref, is you can't see (i.e. read) a consistent object unless you are in a transaction
17:02headiusI presume that would be the same problem if you are dealing with a set of refs
17:02headiusthis is just a shortcut for passing around a set of refs as though it were an object
17:03rhickeyif you put the entire (immutable) state of the object in a ref, then you could have a deref method that returned a snapshot of the object, out of a transaction
17:03rhickeyheadius: yes, but sets of refs are not that great
17:03headiusmmm interesting
17:03rhickeyhave the snapshot implement the read interface of the original
17:04headiusso instead of a set of refs, you have a ref to a set
17:04headiusand replace it en masse
17:04rhickeythat is in keeping with the ideas behind refs and Clojure state
17:04rhickeyright, ref to a map
17:05headiuswouldn't be hard to modify this to work that way
17:05headiusjruby fields aren't kept in a map, they're just in an indexed structure (an array normally)
17:05headiusso it would just be a ref to a vector of values
17:05rhickeyI ecommend it - independent refs do not an object make
17:06rhickeywhatever the structure, it needs to be immutable
17:10the-kennyWhoa.. macoexpansion at compile time got me again.
17:11twbrayrhickey: It's not obvious that you need transaction semantics across all the fields in an object. Hmmm
17:12dnolenfrom ML, nice: http://lisperati.com/vijual/
17:13the-kennydnolen: whoa
17:13headiustwbray: I guess I'm still confused why you wouldn't need that in either case...if you're going to work with multiple of them, you'll want that work to be done in dosync
17:13headiusin which case whether they're separate refs or a single ref, they're all part of the transaction, no?
17:20rhickeyheadius: a key point of the Clojure system is that reads generally fall outside of the coordination system - get your composite value and be on your way
17:21rhickeyseparate refs means you must read in a transaciton
17:22headiusmakes sense
17:24headiusif you had any sort of javadocs at all, this would be easier :)
17:26rhickeyhttp://clojure.org/state
17:29headiushmm
17:29headiusRT doesn't appear to like being loaded from bootclasspath
17:30headiusrhickey: you know .class.getClassLoader returns null when loaded from bootclasspath, yes?
17:31headiusRT.baseLoader doesn't check for that
17:35headiusI'll work around it for now
17:50nathanmarztechnomancy: can leiningen be used as the build system for a regular java project?
18:12jkkramerping
18:12jkkrameri just made an ns cheatsheet for myself that others might find handy: http://gist.github.com/284230
18:53mabesanyone know if, in compojure, you can combine multiple routes when passing it the the servlet? Meaning, I have used the defroutes macro twice and I want to pass both resulting vars to the servlet function
18:57danlarkintechnomancy: ping
18:59alexykdid you guys have to register your nicks today?
18:59alexykI'm inserting pairs like ["a" 0.1] into a vector. I'd like them to be inserted in a sorted order by the number. Is there a core data structure to do that?
19:00technomancyalexyk: yeah, I couldn't speak in this channel without registering.
19:01technomancyalexyk: I could speak fine in other channels, but #clojure must be configured differently
19:01alexykI wonder what's up with that. No more ___ and ` and |away
19:01jkkramermabes: defroutes accepts route variables, so you can do something like: (defroutes all-routes foo-routes bar-routes), then (servlet all-routes)
19:01alexykperhaps the clojurebot decided it's HAL?
19:01mabesjkkramer: perfect. Thanks!
19:02alexykclojurebot: did you get drunk and fight nickserv again?
19:02alexykah! clojurebot has to register too
19:05alexykit's like mute hordes show up, bang on the doors, and leave silently
19:06hiredmanclojurebot is registered
19:07hiredmanmust be netsplitted
19:07hiredmanclojurebot: ping?
19:07clojurebotPONG!
19:11ubiiclojurebot: Open the pod bay doors, HAL.
19:11clojurebotthe nest sentence is true
19:11ubiidamn, I was hoping he would respond by saying "I'm sorry, Dave. I'm afraid I can't do that."
19:12ubiiguess he really isn't HAL
19:16hiredmanclojurebot: Open the pod bay doors, HAL is <reply>I'm sorry, Dave. I'm afraid I can't do that.
19:16clojurebotIn Ordnung
19:16hiredmanclojurebot: Open the pod bay doors, HAL.
19:16clojurebotI'm sorry, Dave. I'm afraid I can't do that.
19:17ubiinice :)
19:17hiredmanclojurebot: Open the pod bay doors, HAL is <reply>I'm sorry, #who. I'm afraid I can't do that.
19:17clojurebot'Sea, mhuise.
19:17hiredmanclojurebot: Open the pod bay doors, HAL.
19:17clojurebotI'm sorry, hiredman. I'm afraid I can't do that.
19:17hiredman:P
19:18ubiieven better
19:52alexykhow do I convert a seq of pairs ([1 2][3 4]) into a map most efficiently?
20:03KirinDaveSo
20:03KirinDaveCan someone explain to me why this macro freaks out Clojure?
20:03KirinDavehttps://gist.github.com/198e96fbdf697b98d3d3
20:03KirinDaveIt works on the repl.
20:03KirinDaveBut if I try to use it in code, it dies.
20:03KirinDaveWith no error from the compiler.
20:05alexykstill -- how do I convert a seq of pairs ([1 2][3 4]) into a map most efficiently?
20:07the-kennyalexyk: (hash-map (apply concat seq))?
20:08the-kenny,(hash-map (apply concat '([1 2] [3 4
20:08clojurebotEOF while reading
20:08the-kenny,(hash-map (apply concat '([1 2] [3 4])))
20:08clojurebotjava.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@e93c3
20:08the-kenny,(hash-map (apply concat [[1 2] [3 4]]))
20:08clojurebotjava.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@e93c3
20:08the-kenny,(apply hash-map (apply concat [[1 2] [3 4]]))
20:08clojurebot{1 2, 3 4}
20:08the-kennyha!
20:08alexykyay!
20:10alexykor (flatten theseq)
20:11alexykso what's with into? I thought hiredman had a way to (into {} ...)
20:12alexykbut can't remember how
20:12clojurebotwith style and grace
20:13KirinDaveSo, uh, no one?
20:13KirinDaveWhy that macro fails?
20:14KirinDavehttps://gist.github.com/198e96fbdf697b98d3d3
20:14KirinDaveCuz it works in macroexpand.
20:15tolstoyIf you have, say, a connection pool (DB), and you want to initiate it on first use, is a "ref" the way to go?
20:15alexykI'm working a huge transient map of transient vectors. Then I need to persistent!-ize it back. Here's the result of toil:
20:15alexyk,(->> (transient {:a (transient [1])}) (persistent!) (map (fn [[k v]] [k (persistent! v)])) (apply concat) (apply hash-map))
20:15clojurebot{:a [1]}
20:15alexykis this reasonable?
20:16alexykusing the new Deutsch import from the-kenny in the end
20:18the-kennyalexyk: huh? Deutsch import?
20:18alexykthe-kenny: like a shiny BMW
20:19alexykI'm doing your trick of precise engineering in the end of that ->> :)
20:19alexykthe question is, ios it the efficient way -- to persist! the map first, then the leaves
20:20the-kennyalexyk: Ah :) got it
20:22alexykheadius: did you have to register too?
20:23headiushi
20:23headiuswhat's up?
20:24alexykheadius: do you know who inflicted this Guantanamo-style registration on us?
20:24alexykit was weird here all day
20:24headiusFreenode probably
20:24headiusthere was a big spam attack this weekend and they set channels +R
20:25headiusoperator can turn it off though...I did in JRuby
20:25headius#jruby
20:25alexykah ok
20:43chouseralexyk: into
20:43chouseralexyk: into
20:43chouser,(into {} [[1 2] [3 4]])
20:43clojurebot{1 2, 3 4}
20:54alexykchouser: I've tried with
20:54alexyk,(into {} ([1 2][3 4]))
20:54clojurebotjava.lang.IllegalArgumentException: Key must be integer
20:54alexykand it failed
20:55alexykwhy does (vec..) fix it?
20:56chouserthat's just the literal list getting evaluated
20:56chouser,(into [] (list [1 2] [3 4]))
20:56clojurebot[[1 2] [3 4]]
20:56chouser,(into {} (list [1 2] [3 4]))
20:56clojurebot{1 2, 3 4}
20:57alexykah nice
20:58alexykvec's almost obliterate 'quoting
20:58chouseryep
20:59chouserand (list ...)
21:04alexykchouser: cgrand : is this a good way tp persist a transient map of transient vectors:
21:04alexyk,(->> (transient {:a (transient [1])}) (persistent!) (map (fn [[k v]] [k (persistent! v)])) (into {}))
21:04clojurebot{:a [1]}
21:05alexyki.e. least reallocation?
21:08limuxwhat's the meaning of "fn*"
21:11limuxwould I walk around the google to find the anwser or have to read the source of clojure?
21:15alexyklimux: where did you see fn* ?
21:15mattreplprobably read clojure/core.clj. it has to do with not having a destructuring fn while bootstrapping.. in fact the comments say as much =)
21:16limuxsorry, i forget it
21:18limuxbut you can use fn* to def a func which can work well
21:19mattreplhmm, I think my answer is only partially correct
21:20limuxin REPL, (fn a [] ()) => #<user$eval__3567$a__3569 user$eval__3567$a__3569@f4c0275>
21:20limuxbut, (fn* a [] ()) => #<user$eval__3567$a__3569 user$eval__3567$a__3569@f4c0275>
21:20mattreplbut it has something to do with bootstrapping and special forms
21:20limuxall is ok
21:21limuxi remeber i saw someone use fn* in his app on github
21:22limuxbut i forget his proj
21:25mattreplfn is a macro, so expand it and you'll see how fn* is used underneath
21:27limuxi read only part of the sources of clojure
21:28limuxfn* a [] ()) => #<user$eval__3575$a__3577 user$eval__3575$a__3577@22cb4138>
21:29limuxa bit diffence to fn
21:29mattrepl,(macroexpand (fn [x] (inc x)))
21:29clojurebot#<sandbox$eval__5090$fn__5092 sandbox$eval__5090$fn__5092@1d39053>
21:29mattrepl,(macroexpand '(fn [x] (inc x)))
21:29clojurebot(fn* ([x] (inc x)))
21:33limuxany more clealy explain?
21:34limux,(macroexpand (fn* [x] (inc x)))
21:34clojurebot#<sandbox$eval__5099$fn__5101 sandbox$eval__5099$fn__5101@beaff3>
21:34limux#<user$eval__3628$fn__3630 user$eval__3628$fn__3630@1a71d29a>
21:35limux,(macroexpand (fn [x] (inc x)))
21:35clojurebot#<sandbox$eval__5105$fn__5107 sandbox$eval__5105$fn__5107@1d998e8>
21:35limux#<user$eval__3637$fn__3639 user$eval__3637$fn__3639@7991ba7>
21:35mattreplyou need to quote macroexpand's argument
21:35limuxok
21:35mattrepl,(macroexpand '(fn [x] (inc x)))
21:35clojurebot(fn* ([x] (inc x)))
21:37limux,(macroexpand '(fn [x] (inc x)))
21:37clojurebot(fn* ([x] (inc x)))
21:38limux,(macroexpand '(fn [x] (inc x))) => (fn* ([x] (inc x)))
21:38clojurebot(fn* ([x] (inc x)))
21:38limux,(macroexpand '(fn* [x] (inc x))) => (fn* [x] (inc x))
21:38clojurebot(fn* [x] (inc x))
21:39limuxfn is macro
21:40limux(def
21:40limux #^{:macro true}
21:40limux fn (fn* fn [& decl] (cons 'fn* decl)))
21:43limuxlet, loop do the same as fn
21:43limuxlet* loop*
21:47chousersorry, what was the question?
21:48mattreplchouser: the purpose of fn*
21:53limuxin compliler.java, static final Symbol FN = Symbol.create("fn*)
22:17hiredmanfn is a macro that emits calls to the special form fn*
22:25jlbmy "...more fn" t-shirt arrived today! http://img113.yfrog.com/i/kzml.jpg/
22:33chouserjlb: cool! quality of the shirt and printing ok?
22:35jlbchouser: yeah... I customized w/ an American Apparel shirt, but it looks great
22:41chousergreat.