2010-01-22
| 00:11 | defn[_] | ' |
| 00:11 | defn[_] | 'lo |
| 00:43 | defn[_] | autodoc++ |
| 04:27 | neotyk | Hi * |
| 04:27 | neotyk | Clojure-on-Clojure is it possible to get AST already? |
| 05:30 | KarlsFriend | Hi. I have a question. This is a chatroom about the prog. language clojure right? |
| 05:31 | leafw | KarlsFriend: yes. |
| 05:32 | KarlsFriend | leafw: I've been here for 10 minutes now. 5 people joined. But nobody talks. How come? |
| 05:32 | leafw | USA is sleeping |
| 05:32 | KarlsFriend | are they pming? |
| 05:32 | leafw | most folk are over there. |
| 05:32 | KarlsFriend | ok. but if i need help with clojure this is still the right place to ask? |
| 05:33 | neotyk | yep, also mailing list is good to ask |
| 05:33 | leafw | KarlsFriend: mailing list is better. More asynch and in-depth. |
| 05:34 | KarlsFriend | i am at the very begining and wondering why my code crahes. can you take a look at it? |
| 05:34 | leafw | I can't :) to busy |
| 05:34 | LauJensen | ~paste |
| 05:34 | clojurebot | lisppaste8, url |
| 05:34 | lisppaste8 | To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste. |
| 05:34 | LauJensen | KarlsFriend: Try pasting it |
| 05:34 | KarlsFriend | ok, thx |
| 05:36 | lisppaste8 | karlsfriend pasted "Working with canvas" at http://paste.lisp.org/display/93728 |
| 05:36 | Chousuke | KarlsFriend: indent less :) |
| 05:36 | KarlsFriend | ok the problem is that i expect "gamestate" to be a ref to an int. |
| 05:36 | Chousuke | KarlsFriend: two spaces is the lisp convention |
| 05:37 | KarlsFriend | do you have alink where i can look that up? |
| 05:37 | KarlsFriend | Chosuke: the whole convention thing. i never used lip |
| 05:38 | KarlsFriend | *lisp |
| 05:38 | Chousuke | well, there is a scheme style guide |
| 05:38 | Chousuke | it applies pretty well to clojure |
| 05:38 | Chousuke | with a few exceptions |
| 05:38 | Chousuke | http://mumble.net/~campbell/scheme/style.txt |
| 05:38 | KarlsFriend | ok thx. i will lokk over it |
| 05:38 | Chousuke | it tells you not to use [] etc. but that obviously doesn't apply to Clojure :) |
| 05:45 | spariev_ | KarlsFriend: it looks like you're using function with side effects (drawF) in dosync, maybe that's why it crashes |
| 05:46 | Chousuke | KarlsFriend: one common thing to do is to have the game state be a global ref |
| 05:47 | KarlsFriend | spariev: i am goin gto try that. |
| 05:47 | KarlsFriend | Chosuke: 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:48 | KarlsFriend | *two games |
| 05:49 | cgrand | KarlsFriend: (ref-set gamestate (gameF (deref gamestate) t canvas)) is better written (alter gamestate gameF t canvas) |
| 05:50 | KarlsFriend | cgrand: thx i was looking for that function |
| 05:52 | cgrand | (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:53 | lisppaste8 | karlsfriend annotated #93728 "untitled" at http://paste.lisp.org/display/93728#1 |
| 05:54 | cgrand | KarlsFriend: 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:56 | lisppaste8 | Chousuke annotated #93728 "cleaned up a bit" at http://paste.lisp.org/display/93728#2 |
| 05:57 | KarlsFriendGotDi | I got disconnected somehow. Anyone posted a solution to my problem? ;-) |
| 05:57 | cgrand | have a you a stack trace to show us? |
| 05:58 | Chousuke | http://paste.lisp.org/display/93728#2 |
| 05:58 | lisppaste8 | karlsfriend annotated #93728 "stacktrace" at http://paste.lisp.org/display/93728#3 |
| 05:58 | Chousuke | your problem was that you forgot to deref game-state |
| 05:58 | Chousuke | you passed the ref to drawF |
| 05:58 | Chousuke | and then passed that to .drawRect |
| 05:58 | Chousuke | and of course it blew up |
| 05:58 | cgrand | Chousuke: nice catch |
| 06:00 | Chousuke | KarlsFriend: but yeah, having a global state ref will prevent you from running two games concurrently, that's true |
| 06:00 | KarlsFriend3 | ok sorry. i closed mirc again :-/ |
| 06:00 | Chousuke | :/ |
| 06:00 | KarlsFriend3 | (ref-set gamestate (gameF (deref gamestate) t canvas)) |
| 06:01 | KarlsFriend3 | that did not deref it? |
| 06:01 | Chousuke | it did, but then you passed gamestate to drawF |
| 06:01 | Chousuke | ,(let [a (ref 1)] [a (deref a) a]) |
| 06:01 | clojurebot | [#<Ref@1f49e84: 1> 1 #<Ref@1f49e84: 1>] |
| 06:01 | Chousuke | see |
| 06:01 | KarlsFriend3 | ah now i see it! |
| 06:01 | KarlsFriend3 | thanks Cousuke |
| 06:02 | Chousuke | see my annotation as well. looks a bit better with less indentation (and no camelcase), doesn't it? :) |
| 06:03 | Chousuke | and you're correct about having global state limiting you to one game at a time |
| 06:04 | Chousuke | creating the needed ref in a let is a valid solution as well, but it'll complicate debugging a bit |
| 06:05 | KarlsF | I just switched to Win 7. I know most of you use linux. But does anyone have an idea why mirc somehow closes itself? |
| 06:05 | Chousuke | it's not crashing, is it? |
| 06:06 | KarlsF | no i now see i have it open 3 times |
| 06:06 | Chousuke | so maybe it's just minimised? :/ |
| 06:06 | Chousuke | in the system tray or something |
| 06:08 | Chousuke | http://clojure-log.n01se.net/ you can follow #clojure logs here to see things you might've missed |
| 06:09 | Chousuke | it's not real-time though. |
| 06:14 | AWizzArd | Chousuke: if you want real-time come here :-) |
| 06:14 | Chousuke | well, doesn't help if you have a connection like KarlsF :P |
| 06:49 | tcrayford | Any idea why the second to last test in this fails? http://gist.github.com/283706 |
| 06:50 | tcrayford | am using (is (thrown? exceptionclass body)) to check if an exception is thrown |
| 06:51 | tcrayford | and clojure-test-mode is showing an error message with IllegalArgumentException displayed |
| 06:51 | tcrayford | just not a passing test |
| 06:52 | tcrayford | lein test is showing up with an error as well, with my IllegalArgumentException as the error |
| 07:17 | LauJensen | tcrayford: Where is thrown? defined? |
| 07:45 | jcromartie | what am I failing to comprehend here: |
| 07:45 | jcromartie | ,(re-matches #"x" "xyz") |
| 07:45 | clojurebot | nil |
| 07:46 | jcromartie | does it have to match the entire string? |
| 07:49 | jcromartie | for example, in JavaScript or Ruby a simple regex of "x" matches the "x" in "xyz" |
| 07:55 | jcromartie | I guess it's just a Java regex |
| 08:38 | chouser | jcromartie: re-find |
| 08:38 | jcromartie | ,(re-find #"x" "xyz") |
| 08:38 | clojurebot | "x" |
| 08:38 | jcromartie | hmm |
| 08:39 | chouser | some 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:39 | jcromartie | the matches/find distinction seems strange but I guess it's the underlying Java library |
| 08:39 | LauJensen | ~regex |
| 08:39 | clojurebot | Sometimes people have a problem, and decide to solve it with regular expressions. Now they have two problems. |
| 08:40 | jcromartie | right |
| 08:40 | jcromartie | :) |
| 08:41 | LauJensen | re-seq is also handy |
| 09:02 | chouser | fogus: you got on lambda the ultimate! |
| 09:03 | fogus | I'm amazed at the traction of those slides... |
| 09:04 | fogus | I just stuck them up on my site so that the CAP CLUG folks could see them ... weird |
| 09:05 | chouser | :-) |
| 09:08 | cemerick | I had forgotten about the fine-grained locals clearing. That's in master at this point, right? |
| 09:09 | chouser | cemerick: I think so, yeah |
| 09:09 | rhickey | fogus: what were you trying to demonstrate on the transients slide in the bad things section? |
| 09:09 | chouser | cemerick: sorry, that was weak. Yes, that's in master. |
| 09:10 | cemerick | chouser: I'm a big boy, I could have looked it up myself if I weren't so lazy. But thanks. :-D |
| 09:12 | fogus | rhickey: 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:13 | rhickey | fogus: but it is ok to write a chain of functions that build up a transient. |
| 09:15 | rhickey | nothing 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:15 | fogus | rhickey: understood, and I think I mentioned that, but the word "always" is terribly misleading. |
| 09:16 | rhickey | the 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:17 | rhickey | never subject to race conditions or corruption though |
| 09:18 | rhickey | I have been working on a model that puts transient use into a new reference type |
| 09:19 | chouser | rhickey: any thoughts about nested transients? |
| 09:19 | cgrand | rhickey: you mean like transients being owned by an agent (sort of an asynchronous accumulator) instead of a thread? |
| 09:19 | fogus | rhickey: Better? http://www.fogus.me/static/preso/clj1.1+/content/transients.txt |
| 09:19 | rhickey | chouser: putting them in a reference type makes that easy |
| 09:20 | rhickey | cgrand: two flavors, one with single thread semantics, the other with internal locks |
| 09:20 | rhickey | I'd be happy to describe them as long as everyone understand these are not fully baked |
| 09:22 | rhickey | let me start here, so you all can ask questions |
| 09:23 | rhickey | the basic idea, recognized by transients, is that the birth of a new value might be a composite operation |
| 09:23 | rhickey | If you look at the are we there yet slides, you see the epochal time model |
| 09:23 | rhickey | the transition from state to state is described as an atomic function |
| 09:24 | rhickey | and it is atomic, from the standpoint of states - no such thing as an in-between state |
| 09:24 | rhickey | but if you crack open F, you might see something like transients inside, which is fine |
| 09:25 | rhickey | the 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:26 | rhickey | a state must exist in order to be observed |
| 09:26 | rhickey | between observations, process can occur, such process might have an extent, but exists between two moments in time |
| 09:27 | rhickey | so, 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:28 | rhickey | so, 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:29 | rhickey | but you can then keep going, unlike current transients which terminate |
| 09:29 | chouser | ah, neat. |
| 09:29 | rhickey | anyone whose observed has a perfectly fine value in hand |
| 09:29 | rhickey | who has |
| 09:29 | cgrand | can you send function afterwards? (calling trasnient again on the persisted/observed state) |
| 09:29 | rhickey | cgrand: right |
| 09:30 | rhickey | so, this fits right in with Whitehead, where a composite set of thing might influence the next moment |
| 09:30 | chouser | would there need to be a way to send non-transient update fns? |
| 09:30 | rhickey | chouser: hang on to that |
| 09:30 | chouser | ok |
| 09:31 | rhickey | it has a neat kind of quantum truth to it |
| 09:32 | rhickey | so then, there are two models for composite forces creating the next state. One is sequential - multiple action from same vector |
| 09:32 | rhickey | that is the same thread model of transients currently |
| 09:32 | rhickey | the other model is parallel forces |
| 09:33 | rhickey | this is a multithreaded model |
| 09:33 | rhickey | it would be implemented via locking inside, basically enforcing the notion of place |
| 09:34 | rhickey | then multiple threads could send actions into a cell (I've been calling these cells, with no connection to CL Cells) |
| 09:34 | rhickey | the results of those actions would accrete |
| 09:35 | rhickey | any observation would make concrete |
| 09:35 | rhickey | a la Schrödinger's cat |
| 09:35 | cgrand | :-) |
| 09:36 | rhickey | so, 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:36 | rhickey | there is possibility for defining what transient meant, even for POJO's |
| 09:37 | rhickey | i.e. could be clone |
| 09:37 | rhickey | so this is a way to bring some of that unsafe existing OO into the safe fold |
| 09:38 | rhickey | obviously, being based on locks, we don't want to inherit the problems of locks |
| 09:38 | cgrand | so StringBuilder could be used as a transient String |
| 09:38 | rhickey | the main one being the inherent danger of nesting |
| 09:38 | rhickey | cgrand: yes, right |
| 09:38 | rhickey | so, cells wouldn't support nesting |
| 09:39 | rhickey | but they could safely support declarative parallel influencing of several cells at once |
| 09:39 | rhickey | this is a different model than transactions, which support arbitrary, discover as you go, subsets |
| 09:40 | rhickey | with cells you could do (inside [cell-a cell-c cell-b] ...) |
| 09:40 | rhickey | multiple insides could always be made safe, as I can sort for lock acquisition order |
| 09:41 | rhickey | i.e. if someone else simultaneously did (inside [cell-a cell-b cell-c] ...) |
| 09:42 | rhickey | so, it inherits a limitation of locks, no arbitrary composition, but no danger |
| 09:42 | rhickey | that's the basic idea |
| 09:45 | rhickey | chouser: there is definitely work in determining what functions/methods work inside a cell |
| 09:46 | rhickey | since many OO mutators return nothing |
| 09:46 | rhickey | but transients would be a start, and clean |
| 09:47 | chouser | the cell itself would be doing the transient/persistent! calls, right? |
| 09:47 | rhickey | yes |
| 09:47 | cgrand | so 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:47 | chouser | so that would have to be some kind of configuration option of the cell. |
| 09:47 | rhickey | and they would be a protocol |
| 09:47 | chouser | ok |
| 09:47 | cgrand | ok |
| 09:47 | rhickey | or could be property of cell if supplied explicitly |
| 09:48 | rhickey | then single-threadednes would be cell property, not in the data structure |
| 09:48 | rhickey | not sure if there should be 2 different cell types or not |
| 09:49 | rhickey | the POJO part is least baked, but promising I think |
| 09:50 | cgrand | with the sequential type replacing the current model? (or the current model being reimplemented on top of the sequential type) |
| 09:50 | rhickey | but I like putting transients inside something much more than what we have now |
| 09:50 | rhickey | so, yes, replacing current model of transient in hand |
| 09:51 | rhickey | I still value the 'keep the same shape' concept |
| 09:52 | rhickey | but once transients are out of view, then they can support regular conj/assoc in a transient way |
| 09:52 | rhickey | thus making the change to exiting code even less |
| 09:52 | chouser | for 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:52 | rhickey | but, we need a new send/alter operator, and, unfortunately, a different arg order would be better |
| 09:53 | rhickey | chouser: not if it is just a polymorphic fn |
| 09:53 | cgrand | why a different arg order? |
| 09:53 | rhickey | conj on transient vector does transient conj (wht conj! did) |
| 09:53 | rhickey | cgrand: so switching preserves most shape |
| 09:54 | cgrand | of course |
| 09:54 | rhickey | (let [a (cell []] (=> conj a 42) @a) |
| 09:55 | rhickey | currently refs would use (=> a conj 42) |
| 09:55 | rhickey | the recipe would be, wrap in cell, prefix calls with =>, deref on return |
| 09:56 | rhickey | you would also need to send 'reads' of cell in, like so (<= count a) |
| 09:57 | rhickey | in order to avoid realization |
| 09:57 | rhickey | as (count @a) would require |
| 09:59 | jcromartie | Are there any guidelines for using (:foo bar) over (bar :foo) where 'bar' is a map? |
| 09:59 | rhickey | of course, you could use this to introduce less functional style code, but that's true of atom too |
| 09:59 | lpetit | a danger not to be underestimated |
| 10:00 | rhickey | lpetit: 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:01 | dnolen | rhickey: 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:01 | rhickey | one whole aspect of Clojure is recognizing the need for this and making it safe and sound |
| 10:01 | stuartsierra | jcromartie: no, but (:foo bar) seems to be more common |
| 10:01 | jcromartie | it seems more lispy |
| 10:01 | jcromartie | treating the :keyword as a getter function |
| 10:01 | stuartsierra | right |
| 10:02 | rhickey | dnolen: I'd have to think about that |
| 10:02 | chouser | jcromartie: if the key is a literal keyword like that, it's probably best to put it first. |
| 10:02 | stuartsierra | jcromartie: But sometimes you want to treat the map as a "lookup function", in which case (bar :foo) may makes sense. |
| 10:03 | rhickey | jcromartie: 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:03 | jcromartie | hmm, good guideline |
| 10:03 | chouser | jcromartie: then it will survive the map being nil, and in some cases will get you significantly better performance. |
| 10:03 | jcromartie | ah, yes, the map being nil is the tricky part |
| 10:03 | dnolen | rhickey: perhaps most useful at the REPL when playing around with promise/deliver/future since trying to print them always blocks. Just a thought. |
| 10:04 | rhickey | dnolen: what would it return if not ready? |
| 10:05 | lpetit | rhickey: 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:05 | chouser | dnolen: futures print :pending instead of blocking |
| 10:05 | chouser | perhaps promise should too |
| 10:05 | dnolen | rhickey: chouser: that would be nice I think. |
| 10:05 | lpetit | I couldn't follow you guys, too much shared implicit assumptions, to much shared implicit knowledge for me :) |
| 10:07 | rhickey | the 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:07 | rhickey | lpetit: questions welcome |
| 10:08 | lpetit | First, 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:08 | rhickey | lpetit: think jail cell |
| 10:09 | rhickey | only one visitor allowed at a time |
| 10:09 | lpetit | the following visitors may or may not wait (block) ? |
| 10:10 | rhickey | wait |
| 10:10 | lpetit | by visitor, you mean readers as well as writers |
| 10:11 | rhickey | there are two separate notions, obtaining the value (state), happens via dereferencing and does not block |
| 10:12 | rhickey | asking the prisoner a question requires a visit, using the (<= count a) function |
| 10:12 | rhickey | that blocks, and is pretty special purpose, just for composite operations |
| 10:13 | rhickey | a dereference during a process (change in another thread) see the last-produced state/value, the next one doesn't exist yet |
| 10:13 | chouser | does it block on its own, or is it required to be in a (cell ...) form that will do the blocking? |
| 10:13 | lpetit | ok, so while somebody is in the jail, every other reader continue to read the future old state's value |
| 10:14 | rhickey | chouser: cell just creates the reference, do you mean (inside ...) ? |
| 10:14 | rhickey | lpetit: yes |
| 10:15 | chouser | rhickey: Ok, I guess I do. |
| 10:15 | lpetit | could jail or jail-cell be a replacement term for cell ? (carries more meaning at least to me) |
| 10:15 | rhickey | basically its a Kafkaesque jail - people can bail you out (via dereference) but they only get a clone, you stay in jail |
| 10:16 | lpetit | and has the good property of being less overloaded than cell |
| 10:16 | rhickey | chouser: I'm hoping not, that => will do the right thing, but there are some efficiency issues with nesting-testing |
| 10:18 | rhickey | chouser: it might be that => works alone for single-thread cells, but needs to be inside (inside) for MT cells |
| 10:19 | rhickey | note that transients and persistent data structures are still critical for this system |
| 10:19 | lpetit | rhickey: 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:19 | lpetit | "my two (<=) calls I meant" |
| 10:21 | rhickey | lpetit: 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:21 | rhickey | but you still don't want to realize a state yet |
| 10:21 | chouser | ah. a deref inside and 'inside' may actually be heavier than a <= |
| 10:22 | rhickey | yes, a deref always creates a state if the current state isn't, er, current |
| 10:22 | chouser | while outside, deref (when it does what you want) will likely be lighter, at least when the prisoner is a transient. |
| 10:23 | rhickey | that in and of itself is cheap, with transients, but it means you are starting from scratch on subsequent processing |
| 10:23 | chouser | yes |
| 10:23 | rhickey | a deref in a processing loop kills the perf benefit |
| 10:24 | rhickey | i.e. it just degrades to persistent |
| 10:24 | rhickey | but with OO cells, could be devastating as most transitions will be full copies/clones |
| 10:25 | rhickey | er, POJO cells |
| 10:25 | chouser | right |
| 10:25 | rhickey | still, putting POJOs in cells is much better than current "you're on your own with that" |
| 10:25 | lpetit | what's the precise semantics of (inside), again ? |
| 10:26 | rhickey | lpetit: inside essentially lets you get the keys to multiple cells, and visit those prisoners back and forth, without anyone else intervening |
| 10:26 | chouser | taking locks on multiple cells in a sorted (therefore deadlock-proof) order |
| 10:27 | rhickey | i.e. it is a safe composite lock |
| 10:27 | rhickey | chouser: right |
| 10:27 | rhickey | and with nesting prevention |
| 10:27 | rhickey | no insides inside inside |
| 10:28 | chouser | no 'inside's inside 'inside' |
| 10:28 | chouser | hm. maybe that didn't help. |
| 10:29 | rhickey | insides don't nest |
| 10:29 | lpetit | np I understood : no nested inside : |
| 10:29 | fogus | Time flies like an arrow |
| 10:29 | lpetit | no nesting of insides :) |
| 10:29 | lpetit | where with transactions it's possible to nest |
| 10:29 | rhickey | exactly |
| 10:30 | lpetit | and concerning the multi thread scenario |
| 10:30 | lpetit | ? |
| 10:30 | rhickey | lpetit: what's the question? |
| 10:31 | lpetit | all the primitives are there ? |
| 10:31 | rhickey | ? |
| 10:31 | lpetit | never mind |
| 10:31 | rhickey | no please, I'm sorry which primitives? |
| 10:32 | lpetit | no, *I'm* sorry, I need to clarify my mind on other topics first |
| 10:32 | rhickey | it works with ordinary threads, as do all of Clojure's constructs |
| 10:33 | rhickey | if multiple simultaneous insides overlap on one or more cells, some will wait, but no deadlock possible |
| 10:33 | lpetit | If 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:34 | rhickey | => is the 'send/alter' function of cells |
| 10:35 | rhickey | <= is the trickier - asking the current process for some visibility on the value being created, must interleave with that process |
| 10:36 | lpetit | but 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:37 | rhickey | but the functions you are using aren't functions of cells, they are functions of their values |
| 10:37 | rhickey | you need to send them into the cell |
| 10:37 | rhickey | same model as all of Clojure state |
| 10:38 | rhickey | calling deref is an observation, causing the realization of a new state and production of its value |
| 10:38 | lpetit | indeed, 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:39 | rhickey | deref calls persistent on the value-in-progress |
| 10:40 | rhickey | so every time you do that, the process starts anew, and no efficiencies of transience cross persistent calls |
| 10:40 | lpetit | I understand |
| 10:41 | lpetit | so 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:42 | lpetit | or maybe not, if => and <= return the cell, humm... |
| 10:42 | rhickey | lpetit: you don't have to adopt an imperative style - it will be even nicer than current transients in supporting the same shape |
| 10:43 | rhickey | <= can't return the cell |
| 10:43 | lpetit | oh really ? |
| 10:43 | rhickey | just like count doesn't return the collection |
| 10:43 | rhickey | but => will |
| 10:44 | lpetit | why can't <= return the cell ? |
| 10:44 | lpetit | oh, <= will return the persistent value |
| 10:45 | rhickey | because it's job is to return some information about the value in progress: (<= count acell) |
| 10:45 | rhickey | returns a number |
| 10:45 | lpetit | <= 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:45 | rhickey | deref/@ returns the state/value |
| 10:46 | rhickey | lpetit: more likely from inside. Just consider, you want to add things until you have 100. How to you test for that? |
| 10:47 | rhickey | if you say (= 100 (count @acell)), you've lost efficiency |
| 10:47 | rhickey | instead (= 100 (<= count acell)) |
| 10:47 | rhickey | all of this useful inside a process |
| 10:47 | rhickey | peeking with <= much less useful, and may block |
| 10:47 | lpetit | oh yes, and I can not really count before entering the (inside) call, or I will be facing potential race conditions ... |
| 10:48 | rhickey | lpetit: exactly, this looking with <= is logically part of this 'process' |
| 10:49 | lpetit | I 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:49 | lpetit | s/realized/realize/ |
| 10:49 | rhickey | of course, I've been using => and <=, but names are welcome |
| 10:49 | jcromartie | rhickey: 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:49 | rhickey | especially since <= is taken |
| 10:50 | rhickey | jcromartie: some, yes |
| 10:52 | jcromartie | nobody knows I'm *not* using Rails yet :P |
| 10:53 | lpetit | => 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:53 | lpetit | yes, with great care :-) |
| 10:54 | the-kenny | _schulte_: The map isn't working, right? |
| 10:54 | jcromartie | _schulte_: map produces a lazy seq, you need to force it's evaluation |
| 10:54 | the-kenny | _schulte_: For things like this, you would use "dolist" |
| 10:55 | jcromartie | s/it's/its |
| 10:55 | _schulte_ | jcromartie: AH!, and here I thought it was something complicated with variable reference |
| 10:55 | lpetit | doseq |
| 10:55 | jcromartie | the-kenny: I think you mean doseq/dorun |
| 10:56 | fogus | http://www.lambdassociates.org/blog/klambda.htm -- Interesting from a cinc perspective |
| 10:56 | the-kenny | ,(doc dolist) |
| 10:56 | clojurebot | Pardon? |
| 10:56 | _schulte_ | thanks for the help, it's working with that simple wrapper |
| 10:56 | the-kenny | ,(doc doseq) |
| 10:56 | clojurebot | "([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:56 | jcromartie | dorun being a function, doseq being a macro |
| 10:56 | the-kenny | Of course, doseq :) |
| 10:56 | the-kenny | Sorry, I'm reading some things in the CL Hyperspec at the moment |
| 10:56 | jcromartie | heh |
| 10:58 | lpetit | _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:59 | lpetit | _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:59 | chouser | jcromartie: any time I spend on clojure-the-language is "spare time" for me. At work I use mostly C++ and Clojure. |
| 11:00 | lpetit | _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:00 | jcromartie | I think loop/recur is a little less elegant for iterating over a seq |
| 11:01 | jcromartie | there are so many constructs just to do that |
| 11:01 | clojurebot | _ato is a rockstar |
| 11:01 | AWizzArd | chouser: when you can get rid of the C++ stuff then your language mix will be perfect |
| 11:02 | chouser | AWizzArd: exactly |
| 11:02 | jcromartie | _schulte_: (let [lst (InstructionList.)] (doseq [x asm] (.append lst x)) lst) |
| 11:02 | lpetit | _schulte_: oh sorry, if the seq is already there, of course doseq is ideal |
| 11:03 | jcromartie | (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:03 | lpetit | héhé |
| 11:03 | _schulte_ | jcromartie: don't worry, it's not homework |
| 11:03 | jcromartie | Figuratively speaking :) |
| 11:04 | lpetit | more like grownwork :) |
| 11:04 | jcromartie | heh |
| 11:04 | _schulte_ | jcromartie: acutal real life, but yes, this is much appreciated :) |
| 11:05 | lpetit | _schulte_: even worse, you now owe him a penny :) |
| 11:06 | _schulte_ | I'll cite you in my working notes :) |
| 11:16 | rober2 | hi |
| 11:16 | rober2 | after i converted a bean to a map with (bean obj), how can i convert it back to a bean? |
| 11:19 | stuartsierra | rober2: I think you have to write that yourself. |
| 11:20 | jcromartie | keep the original object... |
| 11:20 | jcromartie | it doesn't seem like a good idea to pass around the result of (bean x) |
| 11:21 | jcromartie | at least if x is some mutable Java object |
| 11:21 | cgrand | and going back and forth between POJOs and maps with bean/unbean (yet to be written) isn't efficient (lot of reflection going on) |
| 11:21 | jcromartie | yeah unbean would have to involve proxy, wouldn't it? |
| 11:22 | jcromartie | or, no |
| 11:22 | cgrand | not if you pass it a target object |
| 11:22 | jcromartie | since the bean spec requires a zero-arg constructor and set* for every get* |
| 11:23 | cgrand | (defn unbean [obj map] (doseq [[k v] map] (Reflector/setInstanceField obj (name k) v))) |
| 11:23 | jcromartie | ,(bean "") |
| 11:23 | clojurebot | {:empty true, :class java.lang.String, :bytes #<byte[] [B@ee419f>} |
| 11:23 | jcromartie | the :class key should be used to instantiate the object |
| 11:24 | jcromartie | ,(new (:class (bean ""))) |
| 11:24 | clojurebot | java.lang.IllegalArgumentException: Unable to resolve classname: (:class (bean "")) |
| 11:24 | jcromartie | oops... |
| 11:24 | Chousuke | (.newInstance (:class (bean ""))) |
| 11:24 | Chousuke | ,(.newInstance (:class (bean ""))) |
| 11:24 | clojurebot | "" |
| 11:24 | jcromartie | there we go... unbean is almost ready for prime time :) |
| 11:26 | jcromartie | (defn unbean [m] (let [obj (.newInstance (:class m))] (doseq [[k v] (dissoc m :class)] (clojure.lang.Reflector/setInstanceField obj (name k) v)) obj)) |
| 11:27 | jcromartie | hmm, needs to check for getters first |
| 11:27 | rober2 | thx a lot :) |
| 11:29 | jcromartie | I think bean is a little overzealous about what is a bean property |
| 11:30 | crios | hi all |
| 11:31 | jcromartie | hi |
| 11:31 | jcromartie | are there any good classes to test as beans? |
| 11:33 | jcromartie | http://gist.github.com/283890 |
| 11:34 | jcromartie | it works for the simplest cases |
| 11:38 | esj | ,(has-bean? 'imperative-programming) |
| 11:38 | clojurebot | java.lang.Exception: Unable to resolve symbol: has-bean? in this context |
| 11:46 | cgrand | jcromartie: http://gist.github.com/283896 |
| 11:47 | jcromartie | very nice |
| 11:47 | cgrand | forgot to return obj :-) |
| 11:58 | Raynes | http://www.infoq.com/presentations/Value-I...ate-Rich-Hickey <-- That's the most hilarious place I've ever seen an ellipsis. |
| 11:58 | Raynes | "I...ate-Rich-Hickey" |
| 11:59 | Chousuke | :P |
| 12:02 | Chousuke | hmm, my new patched emacs has a curious bug. |
| 12:02 | Chousuke | I can't type R |
| 12:02 | Chousuke | if I enable clojure-mode |
| 12:02 | esj | ! |
| 12:03 | Raynes | They 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:03 | Chousuke | Raynes: complex, as in most featureful or the most contrived? :D |
| 12:04 | Raynes | Featureful. I wrote a http://reddit.com/r/clojure bot. |
| 12:04 | arohner | rhickey: 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:04 | Raynes | When means I parsed HTML, used the bit.ly API to shorten links, and posted results to twitter after processing them. |
| 12:04 | Raynes | Most people just write a little GUI to update twitter. |
| 12:05 | arohner | and 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:05 | cemerick | arohner: just aliases though, right? |
| 12:05 | arohner | cemerick: right. |
| 12:05 | Raynes | But arrows are prettier. |
| 12:05 | Raynes | :( |
| 12:06 | arohner | Raynes: just wait until the day where you have to explain the difference between ->>, -?>, -@>, -!> |
| 12:06 | Raynes | I would do it with honor. |
| 12:06 | Raynes | :> |
| 12:06 | lpetit | arohner: you missed :>> |
| 12:07 | esj | zakly, Agincourt was not pretty. |
| 12:07 | lpetit | :) |
| 12:07 | lpetit | I will defend -?> forever, though ! :-p |
| 12:07 | Raynes | I'm slowly converting the people on dreamincode.net to FP. Riches talks combined with sweet sweet envy. |
| 12:07 | jcromartie | -?!?!-> |
| 12:08 | jcromartie | My 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:08 | esj | jcromartie: that's a kebab |
| 12:08 | arohner | esj: you need some @'s in there for a kebab |
| 12:08 | arohner | :-) |
| 12:12 | lpetit | Ranyes: the site you're mentioning has really horrible colors :-( |
| 12:13 | Raynes | lpetit: It has really horrible users too, but yeah. |
| 12:22 | Raynes | (def mytree (Tree (Tree nil nil) (Tree (Tree nil nil) nil))) ; MY EYES! THEY BURN!! |
| 12:23 | esj | Is 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:23 | esj | if its not suicidal I'll probably do it, but don't want to produce something obviously daft. |
| 12:24 | chouser | I'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:25 | esj | chouser: thanks. |
| 12:26 | jcromartie | esj: I think you should measure it |
| 12:26 | jcromartie | I have a feeling that a ref containing the whole map is going to be better than many refs |
| 12:27 | esj | jcromartie: testing sounds far too sensible :) |
| 12:27 | Raynes | I'll put 10 dollars on jcromartie. |
| 12:27 | jcromartie | my understanding is that deriving new instances of the persistent types is efficient and shares memory |
| 12:28 | chouser | multiple threads? each transaction fiddling with a subset of the values? the subsets over time may overlap rather than being cleanly partitionable? |
| 12:28 | jcromartie | i.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:28 | chouser | "no" to more than one or two of those would suggest a smaller number of refs. |
| 12:28 | jcromartie | my rule is refs for the largest chunk possible |
| 12:28 | esj | now 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:29 | esj | now it could be that this flag should be separated from the main map |
| 12:31 | esj | multiple threads: yes. Transaction subset: yes, but not overlapping. |
| 12:32 | chouser | so you might consider on ref per non-overlapping subset. |
| 12:32 | chouser | then again, if that requires more complex code, start with a simpler solution and see if it is fast "enough" |
| 12:32 | esj | chouser: nice idea ! |
| 12:33 | esj | But we all agree that the fewer refs you can get away the better ? |
| 12:33 | Raynes | defn: http://stackoverflow.com/questions/2115021/learning-a-lisp-variant-suggestions :( |
| 12:33 | esj | barring heroic coding |
| 12:35 | esj | thanks guys. |
| 12:45 | esj | partitioning is the answer. |
| 12:48 | jcromartie | are my assumptions about the space efficiency of persistent vectors/maps/sets etc. correct? |
| 12:49 | Chousuke | yes |
| 12:49 | jcromartie | that's good |
| 12:49 | jcromartie | I'd be interested in testing the tradeoffs |
| 12:50 | Chousuke | there are a few blog posts about the data structures around |
| 12:50 | jcromartie | too bad Java doesn't like being memory profiled :) |
| 12:51 | Chousuke | the persistent structures aren't particularly memory efficient if you're storing lots of small objects :/ |
| 12:52 | Chousuke | ie. primitives. :P |
| 12:53 | Chousuke | but I think Rich is planning to introduce specialised variants for longs and doubles at least. |
| 12:54 | Chousuke | jcromartie: http://blog.higher-order.net/2009/02/01/understanding-clojures-persistentvector-implementation/ |
| 12:54 | jcromartie | awesome stuff |
| 12:55 | jcromartie | a little bedtime reading |
| 12:55 | Chousuke | there's also an article for persistenthashmap |
| 14:11 | devinus | can anybody link me to an article on how to get started with clojure/clojure-contrib/slime/swank/clojure-mode/emacs on OS X ? |
| 14:13 | the-kenny | devinus: wait.. there's a good blog post |
| 14:17 | jkdufair | devinus: apparently ELPA has a clojure slime/swank package that will grab the latest clojure itself too |
| 14:17 | jkdufair | haven't done it yet but it was discussed here yesterday |
| 14:18 | the-kenny | Yeah, just use elpa to install slime and swank-clojure |
| 14:18 | the-kenny | And one of my recommendations after that would be leiningen |
| 14:18 | the-kenny | so you can just M-x swank-clojure-project RET dir RET to start a repl with matching classpath etc. for the project |
| 14:21 | joegg | I 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:21 | joegg | I'm still trying to learn the basics. |
| 14:22 | Chousuke | I think the (comparator #(> ...)) thing can be shortened to just > :) |
| 14:23 | joegg | SO COOL! |
| 14:23 | joegg | Of course! |
| 14:23 | hiredman | http://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:24 | Chousuke | joegg: also the one-branch ifs could be replaced with when to express your intent better |
| 14:25 | joegg | Ah, if's without else's --> when. |
| 14:26 | Chousuke | other than that, I can't see anything really wrong with it. |
| 14:27 | Chousuke | though since you're using let to create a "private" lookup table, you could move the private defn to it too |
| 14:27 | chouser | joegg: since you're using a sorted seq, could do: (defn match [num] (first (subseq numbers >= num))) |
| 14:27 | joegg | Chousuke: Thanks for looking! Glad to have a more knowledgable pair of eyes. |
| 14:27 | Chousuke | eg (let [numbers ..., match (fn [num] ...)] (defn speak-num ...)) |
| 14:29 | joegg | Chousuke: 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:29 | joegg | The defn- doesn't make it local to the binding, but rather local to the (non-existent) namespace, right? |
| 14:29 | Chousuke | well, it's just marked as private |
| 14:30 | Chousuke | but there are ways to get to it from the outside |
| 14:30 | joegg | Good to know, thanks! |
| 14:30 | chouser | joegg: I'd actually recommend going the other direction. put numbers in a var, like (def numbers ...) instead of a let |
| 14:30 | Chousuke | anyway, I don't have a clear preference for either method. They're both okay |
| 14:30 | chouser | that makes it easier to redefine individual pieces as you're working on it. |
| 14:32 | joegg | chouser: How so? Just because the let syntax is out of the way better? |
| 14:35 | chouser | if 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:35 | chouser | if 'numbers' were a var instead of a local, you could just redefine 'match' and try it |
| 14:36 | chouser | that said, there are certainly times where it makes sense to put everything in a let, helper functions too. |
| 14:36 | joegg | Okay. That makes sense. I'm very much used the edit/compile/run approach, and not the repl, so that explanation was very enlightening. |
| 14:37 | joegg | Would 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:37 | joegg | Like, 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:38 | chouser | not necessarily. it's fine to have top-level def and defn's that rely on each other |
| 14:38 | hiredman | I would recomend defs for anything that is not a local sort of scratch value |
| 14:39 | joegg | chouser: Because the an (ns ...) would prevent this from just clobbering the global namespace. |
| 14:39 | hiredman | vars are rebindable and just make you code more amendable to various work arounds |
| 14:39 | chouser | joegg: there is no "global" namespace |
| 14:39 | hiredman | your |
| 14:39 | joegg | I'm approaching this from something of a javascript background, and so I keep thinking "gotta put my code in a closure". |
| 14:40 | joegg | Right. But in my mind, I'm still stuck in javascript. |
| 14:40 | joegg | Where this is. |
| 14:40 | chouser | joegg: ah, yeah, don't worry about that. put your code in a namespace. :-) |
| 14:40 | Chousuke | in javascript, namespaces are closures, aren't they? :P |
| 14:40 | joegg | Yes. |
| 14:41 | chouser | Before "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:41 | Chousuke | of course you shouldn't declare needlessly public vars |
| 14:42 | Chousuke | you could make numbers a private var with (def #^{:private true} numbers ...) |
| 14:42 | chouser | yes, though if people aren't being promiscuous with :use, it shouldn't matter too much |
| 14:43 | hiredman | even if they are, you get an exception |
| 14:47 | joegg | Okay, awesome. I'm going to make the changes that everyone suggested and I'll repaste it. Thank you all for your help! |
| 14:49 | rhickey | I'm back from lunch meeting - any lingering questions on transient cells? |
| 14:51 | chouser | can we do ccinc first? :-D |
| 14:51 | Chousuke | :P |
| 14:51 | Chousuke | related: is it possible to implement cells purely in Clojure? |
| 14:51 | rhickey | chouser: no deps either way |
| 14:53 | rhickey | I don't want to go another release without transients squared away |
| 14:53 | rhickey | i.e. change sooner rather than later |
| 14:53 | rhickey | chouser: is that bad? |
| 14:53 | chouser | heh. no. |
| 14:54 | Chousuke | the naming is a bit unfortunate again. :/ |
| 14:54 | rhickey | names are completely up for grabs right now |
| 14:55 | chouser | most 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:55 | chouser | so more work, but no not ultimately bad at all. |
| 14:55 | rhickey | one nice thing is that cells and ccinc will be good proving grounds for deftype and protocols |
| 14:56 | fogus | chouser: Well, we have a place-holder for it already. ;-) |
| 14:56 | rhickey | presuming I don't need volatile for cells |
| 14:56 | chouser | fogus: cells!? |
| 14:57 | fogus | chouser: Yes. That was incredible foresight no? |
| 14:57 | fogus | ;0 |
| 14:57 | fogus | ;) |
| 14:57 | saml | hey, @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:57 | chouser | hm. "cells" in the concurrency section isn't ... quite ... um... |
| 14:58 | fogus | chouser: I just kidding. That section was for Tilton (like) Cells |
| 14:58 | saml | in java, I 'd have to do SomeClass.class.getField("x").getAnnotation(Foo.class).a() |
| 14:58 | chouser | fogus: yeah :-) I know. |
| 14:58 | hiredman | saml: then that should work in clojure |
| 14:58 | fogus | But Kafkaesque cells could take that space instead. |
| 14:58 | saml | hiredman: thanks |
| 14:58 | hiredman | (-> SomeClass (.getField "x") (.getAnnotation Foo) .a) |
| 15:01 | rhickey | so 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:01 | rhickey | http://blog.fogus.me/2010/01/22/de-chunkifying-sequences-in-clojure/ |
| 15:02 | Chousuke | I vote for explicit de-chunking |
| 15:02 | angerman | Hmm. my rfe code for libsvm works. |
| 15:02 | fogus | rhickey: I like chunked by default. I tend not to calculate explosive sequences. |
| 15:03 | drewr | rhickey: I haven't had any problems, but I'm sympathetic to the least-surprise argument |
| 15:03 | stuartsierra | I vote chunked by default with explicit de-chunking. |
| 15:03 | angerman | Ohh, 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:03 | the-kenny | Without being much into the topic, I'd vote for explicit chunking (for example map vs. map-chunked |
| 15:03 | chouser | I'm with stuartsierra |
| 15:03 | angerman | In the end it will boil down to what is anchored as default in my brain. |
| 15:03 | chouser | and Chousuke |
| 15:04 | angerman | How do other languages handle this? The default is non-chunked, right? |
| 15:04 | scgilardi | would explicit dechunking the head of a chain of lazy seqs make the whole chain one-at-a-time lazy? |
| 15:05 | rhickey | note also that many seqs will never be chunked |
| 15:05 | Chousuke | angerman: few languages even have an analogy. :/ |
| 15:05 | chouser | scgilardi: generally, yes |
| 15:05 | scgilardi | then I'm with chouser and stuartsierra |
| 15:05 | angerman | Chousuke: Nah, I mean with lazy-sequences. |
| 15:05 | rhickey | scgilardi: you'd need to dechunk the source of a chain, then everything would be one at a time |
| 15:05 | rhickey | not the head |
| 15:05 | chouser | I've heard even less call for a collect-chunks step |
| 15:06 | scgilardi | I see. That seems sufficient based on what we've seen. |
| 15:06 | angerman | can we have a configureable chunk size too? |
| 15:06 | chouser | angerman: why? |
| 15:06 | angerman | (e.g. I know I can read 10 itms at a time (memory), but 32 would blow it |
| 15:06 | Chousuke | angerman: the point is that the chunk size is optimised for the underlying representation. |
| 15:06 | rhickey | angerman: no, because choosing a chunk size not aligned with the data makes things worse, not better |
| 15:07 | chouser | angerman: probably not much value in chunking that at all then -- just read the first 10 individually |
| 15:07 | angerman | ok, maybe 10 was a bad choice |
| 15:07 | angerman | are ther other "favorable" sized? |
| 15:07 | rhickey | it might make sense when the data is generated, i.e. not sourced from a data structure |
| 15:07 | angerman | *sizes? |
| 15:08 | Chousuke | angerman: if you make your own chunked seq you're free to use whatever buffer size is optimal, though. |
| 15:08 | rhickey | some research shows a sharp dropoff in benefit as you move too far from 32-512 |
| 15:08 | chouser | it seems likely that the value of adjusting the chunk size coming from e.g. 'range' would rarely pay for the extra complexity |
| 15:08 | rhickey | 32 being a sweet spot for chunking and the persistent data structures |
| 15:08 | rhickey | chouser: true |
| 15:09 | angerman | Chousuke: that's right. Scratch what I said. I've looking at the problem from the wrong direction |
| 15:09 | chouser | though maybe a separate collect-chunk step in the pipeline would work for those rare occasions |
| 15:10 | rhickey | chouser: what does that do, chunkify? |
| 15:11 | chouser | right, would takes individual items and stuffs them into a chunk-buffer. I assume would require unusal performance profile downstream to be worth while. |
| 15:11 | angerman | so basically the generator has to decide what's the optimal chunk size, right? |
| 15:12 | chouser | angerman: yes |
| 15:12 | rhickey | angerman: everything about this discussion of different chunk sizes seems like premature optimization to me |
| 15:12 | rhickey | 32 |
| 15:12 | rhickey | there |
| 15:12 | chouser | :-) |
| 15:12 | angerman | rhickey: to me it looks more like a datastructure problem. |
| 15:14 | rhickey | if the data structure has specific requirements, that should dominate |
| 15:14 | rhickey | chunk size follows |
| 15:15 | chouser | I 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:16 | rhickey | chouser: yes, the whole issue is - is seq1 a wrapper or a request for a non-chunked seq directly supported by all chunked seqs? |
| 15:16 | chouser | ah |
| 15:16 | Chousuke | I don't think a wrapper will be problematic. |
| 15:17 | chouser | less work for each collection. I assume there's a worry over performance? |
| 15:17 | angerman | Hm. how about a seq-wrapper generator? |
| 15:17 | Chousuke | since if you want to avoid generating more than once item at once, it must not be a very quick operations. |
| 15:17 | Chousuke | -s |
| 15:17 | angerman | (def seq1 (chunked-seq 1))? |
| 15:17 | Chousuke | and the overhead of a seq wrapper would be inconsequential |
| 15:18 | chouser | angerman: chunks of size 1 are not exactly the same as unchunked. seq1 would probably just go unchunked. |
| 15:18 | angerman | chouser: ok, so basically like a flag? |
| 15:19 | angerman | isn't that what "meta" is supposed to give? |
| 15:19 | rhickey | as 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:19 | rhickey | i.e. if iterate was chunked |
| 15:20 | Chousuke | when would you need that much control? :/ |
| 15:20 | angerman | rhickey: right. so it's all about the producer, right? |
| 15:21 | rhickey | angerman: iff things like iterate became chunked, it would be |
| 15:21 | angerman | Thus we would need at "consumer" level a way flag message the producer, wether or not it should emit chunks? |
| 15:21 | rhickey | data that's already in memory or ephemeral and cheap like range, adapting works fine |
| 15:21 | chouser | that would be the kind of context where explicitly asking for chunks makes more sense to me. chunked-repeatedly in particular |
| 15:22 | angerman | rhickey: ok. We had "no chunking" before. And that worked consistnely accross the board? |
| 15:22 | rhickey | angerman: yes, and adapting the things that are currently chunked would work fine too |
| 15:23 | rhickey | making something like iterate or repeatedly always chunk would be a mistake |
| 15:23 | rhickey | so they don't chunk now |
| 15:23 | rhickey | and may never |
| 15:23 | chouser | right, but it seems like overkill to make vectors know about seq1 just so repeatedly would have that option. |
| 15:24 | rhickey | chouser: yes |
| 15:25 | chouser | so, seq1 as a wrapper with the possibility of chunked-iterate or chunked-repeatedly later? |
| 15:25 | Chousuke | if chunked seqs were "degradable", wouldn't that complicate creating them? :/ |
| 15:25 | rhickey | chouser: I need to think more about it, that's why seq1 wasn't in 1.1 |
| 15:26 | chouser | ok |
| 15:26 | rhickey | need recognized, though |
| 15:26 | angerman | Chousuke: that's the point why we do not have (send-1) and (send-chunk) on producers, right? |
| 15:26 | rhickey | so, what does everyone think about this clojureconf idea in the fall? |
| 15:27 | angerman | where_ |
| 15:27 | rhickey | bay area I think |
| 15:27 | fogus | :-( |
| 15:27 | angerman | hmm. that's east? west? |
| 15:27 | hiredman | california |
| 15:27 | angerman | It's at least over the pond, that I know |
| 15:27 | rhickey | san francisco |
| 15:27 | angerman | ohh the earth-quake area |
| 15:27 | hiredman | no doubt about it |
| 15:27 | angerman | ok |
| 15:27 | rhickey | san jose? |
| 15:27 | fogus | I love the idea -- hate the location. |
| 15:28 | chouser | It's nice and cheap to fly into Indianapolis. |
| 15:28 | chouser | Chicago's a great town |
| 15:28 | chouser | no, me! |
| 15:28 | angerman | fogus: Munich? |
| 15:28 | fogus | angerman: Is that anywhere near Washington DC? ;) |
| 15:29 | angerman | fogus: i think it's close to the airport |
| 15:29 | angerman | :D |
| 15:29 | rhickey | well, chime in for locations here: http://groups.google.com/group/clojure/browse_frm/thread/7723d2afca4245c5 |
| 15:29 | chouser | but seriously, I'd love to go and/or present present, but I'm not likely to pay my own way there. |
| 15:29 | the-kenny | Munich would be ok for me :) (At least it's in germany :D) |
| 15:29 | chouser | er "present something" |
| 15:29 | angerman | chouser: meta presenting is ok too ;) |
| 15:30 | fogus | angerman: I'll be in Tyrol next fall, so Munich is not too far from there |
| 15:30 | chouser | heh. those are called "introductions" or sometimes "keynotes" |
| 15:30 | angerman | fogus: that's right. |
| 15:30 | dysinger | I hate it |
| 15:30 | danlarkin | conj!!! |
| 15:30 | dysinger | conj! |
| 15:31 | angerman | though as Munich is most likely the unlikeliest location anyway. |
| 15:31 | the-kenny | Leiningen would be a cool location too. But I think it's a bit far away from any internation airport |
| 15:31 | technomancy | definitely needs to be called ClojureConj. |
| 15:31 | danlarkin | clojure conj 2010!!! choo choo!! |
| 15:31 | hiredman | (conj clojure you) |
| 15:33 | rhickey | dysinger: hate what? |
| 15:33 | dysinger | ClojureConf |
| 15:33 | Chousuke | the name? :P |
| 15:33 | dysinger | y |
| 15:33 | Chousuke | yeah, it's a bit plain |
| 15:33 | dysinger | I wanted it to be called Clojure Conj |
| 15:34 | danlarkin | we want conj! |
| 15:34 | rhickey | oh, my bad, I didn't mean to imply that was the real name |
| 15:34 | jimduey | conj |
| 15:34 | dysinger | It's a play on "Cons" like BSD Con |
| 15:34 | rhickey | sure Clojure Conj |
| 15:34 | dysinger | and it's a function that's about bringing things together |
| 15:34 | dysinger | which is fun |
| 15:34 | chouser | fn |
| 15:34 | chouser | "ClojureConj 2010 -- It's more fn!" |
| 15:34 | dysinger | I am just explaining my justification - You probably know what conj is rhickey :) |
| 15:36 | Chousuke | I think it might be better to not write it together, but instead as Clojure Conj :/ |
| 15:36 | rhickey | dysinger: what about location? I'm most concerned we enable the greatest attendance |
| 15:36 | lypanov | amsterdam! |
| 15:36 | danlarkin | sf bay area |
| 15:36 | lypanov | (so i can come :P) |
| 15:36 | the-kenny | Amsterdam is nice for me too :) |
| 15:37 | the-kenny | (Almost everything in countries next to Germany is ok :D) |
| 15:37 | jasapp_ | Oklahoma is a very central location |
| 15:37 | jasapp_ | halfway between SF and Europe |
| 15:37 | chouser | heh |
| 15:37 | rhickey | NY! |
| 15:37 | jimduey | Kansas City |
| 15:37 | jimduey | Great ribs |
| 15:37 | lypanov | iceland! |
| 15:37 | Chousuke | unless it's held in Finland I'm very unlikely to be able to attend, but... |
| 15:38 | cemerick | Northampton, halfway between NYC and boston ;-) |
| 15:38 | hiredman | Seattle! |
| 15:38 | jasapp_ | jimduey: the bbq in kc leaves a little to be desired ;) |
| 15:38 | technomancy | currently the largest gathering of Clojurists ever has been in SF |
| 15:38 | the-kenny | We should go swimming in the Atlantic |
| 15:38 | rhickey | cemerick: dream on |
| 15:38 | jimduey | jasapp_:not |
| 15:38 | dysinger | I would rather have SF since Amit and I are organizing |
| 15:38 | dysinger | and it has the biggest clojure group in the US |
| 15:38 | angerman | Chousuke, the-kenny: let's buy a boat :D |
| 15:38 | technomancy | you have to have an organizer in the city where the conference is held |
| 15:39 | AndiXng | hi |
| 15:39 | technomancy | so if you're arguing for your home city, it should be taken as implicitly volunteering to help run it. =) |
| 15:39 | angerman | yea, 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:39 | tbatchelli2 | at 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:40 | tbatchelli2 | 23% California, 10% Ohio, 7% Massachusetts and NY |
| 15:41 | angerman | chouser: you are diqualified for cheating. |
| 15:41 | cemerick | chouser: I think we're pretty much hosed :-/ |
| 15:41 | chouser | d'oh |
| 15:41 | rhickey | clojure site has been consistently 45% US |
| 15:41 | jasapp_ | isn't that what curl is fore? |
| 15:41 | jasapp_ | for |
| 15:41 | angerman | rhickey: ok, so not US |
| 15:41 | chouser | cemerick: not the least because we aren't even pulling for the same town :-) |
| 15:41 | fogus | For what it's worth my blog is CA, NY, TX |
| 15:42 | dysinger | Texas!!! |
| 15:42 | dysinger | :) |
| 15:42 | scgilardi | clojure map: http://bit.ly/4CKYzO |
| 15:42 | dysinger | j/x |
| 15:42 | angerman | dysinger: I'm not gonna set a foot into that part of the world |
| 15:42 | tbatchelli2 | Americas 51%, Europe 40%, Asia 5.5% |
| 15:42 | dysinger | angerman: but they have Whataburger! |
| 15:43 | AndiXng | can 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:43 | rhickey | Do they let NYers into Texas? |
| 15:43 | dysinger | Hawaii represent! |
| 15:43 | fogus | Although NY, NY is the #1 reader for my site |
| 15:43 | cemerick | chouser: I'll come to ohio just to represent the hinterland locales generally. |
| 15:43 | chouser | cemerick: ok! I'd drive to ohio |
| 15:43 | technomancy | the east coast has a lot of people, but pretty spread out |
| 15:43 | cemerick | chouser: aren't you in ohio? or crap, was it IN? |
| 15:43 | chouser | people in chicago could drive there too |
| 15:43 | technomancy | the density of clojurists around the SF Bay is pretty serious |
| 15:44 | chouser | cemerick: heh. yeah, IN. I know, pretty much interchangable to you coastal folk. :-P |
| 15:44 | technomancy | also: the map is probably not updated much, so take a grain of salt w/ that |
| 15:44 | tbatchelli2 | I get 3 times as many visits from SF than from NYC |
| 15:45 | hiredman | hayward would be nice |
| 15:45 | rhickey | http://www.google.com/trends?q=clojure&ctab=0&geo=all&date=ytd&sort=0 |
| 15:45 | technomancy | hiredman: kevins still outnumber non-kevins in Seattle |
| 15:45 | cemerick | chouser: people talk about coming to w. mass. like it's the same as scaling K2, so I feel you. |
| 15:45 | hiredman | boo yeah |
| 15:45 | chouser | cemerick: :-) |
| 15:45 | chouser | cemerick: I've actually been to w. mass. There's six flags out there, right? |
| 15:46 | cemerick | rhickey: yeah, that's what makes you the man. :-D |
| 15:46 | cemerick | chouser: 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:46 | chouser | ah. went there once when I lived in NH |
| 15:48 | angerman | How about Vietnam? |
| 15:48 | angerman | Can Tho is pretty nice. |
| 15:48 | angerman | Cheap, warm, sunny :D |
| 15:49 | angerman | And it's likely equally far away from each of us :] |
| 15:52 | dysinger | Vietnam ??? |
| 15:53 | angerman | yea, good, cheap food. |
| 15:53 | angerman | cell coverage is no issue |
| 15:53 | angerman | wifi usually not |
| 15:53 | dysinger | I think I would have a hard time paying for my team flying to vietnam |
| 15:53 | fogus | I would be all for Tokyo. Clojure is getting big in Japan |
| 15:53 | angerman | fogus: Tokyo is so expensive |
| 15:54 | hiredman | Seoul! |
| 15:54 | angerman | hiredman: ok, haven't been there. |
| 15:54 | patrkris | LauJensen: Hey. Will the changes to the front-end be available in ClojureQL 1.0 or will it come in a later version? |
| 15:54 | dysinger | We could have some interesting conversations while wifi-ing at some amsterdam coffee shops if it where there (thinking) |
| 15:54 | lypanov | yeah! |
| 15:54 | lypanov | and anyone that wishes can sleep at my place in den haag |
| 15:55 | lypanov | (well, limit 4 people) |
| 15:55 | hiredman | if it was in seoul I most likely could get my parents to pay for my flight |
| 15:55 | dysinger | hehehehe |
| 15:55 | technomancy | I was going to say... how big is your place? =) |
| 15:55 | dysinger | lypanov: I hope there is at least 100 that come |
| 15:55 | danlarkin | ok hiredman we'll plan the conference around your budget |
| 15:55 | hiredman | :P |
| 15:55 | hiredman | danlarkin: I would appreciate it |
| 15:55 | danlarkin | s/your/your parents/ |
| 15:55 | lypanov | my budget is negative |
| 15:55 | lypanov | does that mean we get paid to come? :D |
| 15:56 | dabd | anyone from here is coming for the european lisp conference in Lisbon (May 2010)? |
| 15:56 | angerman | Hmmm if I can get my Prof into thinking that Clojure is important, maybe I can get the money from the university. |
| 15:56 | danlarkin | so we're all agreed, SF, Chicago or NY. Probably SF |
| 15:56 | danlarkin | book it |
| 15:56 | hiredman | in the fall right? |
| 15:56 | danlarkin | yeah |
| 15:57 | chouser | I guess I knew what I was doing when I decided to not live in CA. |
| 15:57 | lypanov | dabd: oo, thats very doable for me in comparison to anything states side. |
| 15:57 | hiredman | gah |
| 15:57 | technomancy | if it's not near an airport with lots of non-stop flights it complicates things a lot |
| 15:57 | technomancy | hiredman: you can fly from SEA to SFO for like $69 |
| 15:57 | lypanov | amsterdam!! ... |
| 15:58 | hiredman | technomancy: really? |
| 15:58 | technomancy | well, one-way at least |
| 15:58 | lypanov | i suppose a few can fit in my basement! as long as its summer! |
| 15:58 | hiredman | I was just looking at priceline and it looked like $250 for a roundtrip in september |
| 15:59 | technomancy | hiredman: I came down for the Clojure meetup around JavaOne for only a bit over a hundred |
| 16:00 | lypanov | (man, as much as i love .nl. jobs blow :) ) |
| 16:00 | Apage43 | *going |
| 16:01 | lypanov | probably enough for my morning toast :D |
| 16:02 | dabd | lypanov: it would be interesting to see some Clojure people in Lisbon http://www.european-lisp-symposium.org/ |
| 16:03 | angerman | dabd: hmm. let's hold the clojure conj _inside_ the els |
| 16:03 | dysinger | I think you'll find that the universe pretty much covers everything.. |
| 16:10 | lypanov | dysinger: mars! its equally far from us all! |
| 16:10 | hiredman | NSA was giving away shuttle engines |
| 16:11 | angerman | NSA? |
| 16:11 | tbatchelli2 | lypanov: it depends on the time of the day, doesn't it? |
| 16:11 | hiredman | pardon |
| 16:11 | hiredman | NASA |
| 16:11 | hiredman | they tried to sell them but no one would buy them |
| 16:11 | angerman | clojureconj on mars would definitely cause some media attention |
| 16:13 | angerman | well. bye. |
| 16:13 | lypanov | lol |
| 16:13 | lypanov | ah, dabd is in pt. explains. hehe |
| 16:14 | lypanov | bit far for me, but far more doable than the states. |
| 16:14 | lypanov | and i'd just love to come :( |
| 16:17 | joshua-choi | ,(list* ()) |
| 16:17 | clojurebot | nil |
| 16:17 | joshua-choi | Is there a particular reason why list* called on an empty sequence returns nil instead of the empty list? |
| 16:20 | hiredman | ,(doc list*) |
| 16:20 | clojurebot | "([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:20 | hiredman | I think "as a sequence" is they key point |
| 16:23 | slashus2 | Hello everyone. |
| 16:25 | cemerick | It's seems like fns such as atoi should be in core... |
| 16:27 | DeusExPikachu | is there something like this clojure (from python) somevector[1:-1] |
| 16:27 | headius | FYI: http://gist.github.com/284140 |
| 16:27 | headius | I know some of you dig JRuby |
| 16:31 | rhickey | headius: so all fields of Clojure::Object derivees are refs? |
| 16:31 | cemerick | talios: welcome :-) |
| 16:32 | talios | cemerick: howdy :) I need to fire up my IRC client more often and lurk more. |
| 16:33 | DeusExPikachu | nm, subvec |
| 16:33 | cemerick | talios: you could pimp clojure-maven-plugin, anyway ;-) |
| 16:33 | talios | true - and maven-polyglot-clojure - which I need to do some work on as well. |
| 16:34 | cemerick | that's a new one on me. |
| 16:34 | cemerick | talios: does clojure still have issues under osgi? |
| 16:35 | talios | mmm, 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:36 | talios | I 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:37 | cemerick | talios: I *think* that's no longer a problem. |
| 16:37 | cemerick | at least, such issues don't occur in NetBeans Platform apps anymore (which use an osgi-esque classloader structure) |
| 16:37 | talios | cemerick: oh cool, I'll have to dig out my OSGi clojure test code and give it a bash |
| 16:38 | rhickey | I'd like to improve the story there, if I knew what was needed |
| 16:38 | talios | cemerick: http://polyglot.sonatype.org/clojure.html <- polyglot maven - write your POMs in clojure (pom.clj) |
| 16:38 | talios | Write, and -script- your POMs that is |
| 16:38 | cemerick | oh, sonatype-hosted, even, nice |
| 16:39 | cemerick | talios: so the objective is to have complete parity with xml-based poms? |
| 16:39 | talios | cemerick: yep,so far theres clojure, scala, yaml, and ruby DSLs |
| 16:39 | talios | cemerick: yep, theres a transformer as well: ./bin/transform pom.xml pom.clj - converts the XML to a clojure version and vice versa |
| 16:39 | cemerick | how well baked is it, relative to clojure-maven-plugin? |
| 16:40 | talios | cemerick: 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:41 | talios | the polyglot side of it is solely the maven POM, not clojure compiling etc |
| 16:41 | talios | its'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:42 | cemerick | well, the release plugin is broken for me anyway :-P |
| 16:42 | talios | heh |
| 16:43 | cemerick | no, seriously, it doesn't work right with git + hudson |
| 16:43 | dysinger | headius: when is the jvm language summit each year and where ? |
| 16:44 | talios | Hrm. I use the release plugin with git without problem, how does hudson play into that? |
| 16:44 | cemerick | talios: see the comments near the bottom of http://wiki.hudson-ci.org/display/HUDSON/Git+Plugin |
| 16:44 | rhickey | dysinger: http://openjdk.java.net/projects/mlvm/jvmlangsummit/ |
| 16:45 | cemerick | you 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:45 | dysinger | rhickey: headius maybe we could do the clojure conj 2010 around the same time. |
| 16:46 | dysinger | it's in santa clara nearby |
| 16:47 | rhickey | dysinger: would be useful for me, but don't expect much overlap in attendees otherwise - language summit is for implementors |
| 16:48 | dysinger | yeah I am only thinking of usefulness |
| 16:48 | talios | cemerick: 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:48 | rhickey | dysinger: I wonder if there will be a Java One, nevermind JVM lang summit |
| 16:48 | dysinger | Are we going to have to get a Pledgie button to get chouser out here ? |
| 16:49 | talios | cemerick: 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:49 | dysinger | rhickey: true |
| 16:49 | talios | rhickey: Javaone's now mentioned on the moscone website |
| 16:49 | cemerick | talios: 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:49 | dysinger | I'll go to the airport with my coffee cup and guitar to raise money to get chouser out here :) |
| 16:50 | rhickey | talios: 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:50 | talios | rhickey: http://www.moscone.com/site/do/event/view?nav.type=0&nav.filter=1005&nav.base=1001&id=440 |
| 16:50 | talios | 06/22/10 - 06/25/10 |
| 16:51 | rhickey | chouser has to come to clojure conj! |
| 16:51 | talios | rhickey: 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:53 | rhickey | talios: great! |
| 16:57 | dysinger | Do we have any good contacts for a cheap (but good designer) for clojure conference website? |
| 16:57 | rhickey | thickey: |
| 16:57 | the-kenny | rhickey's Brother? |
| 16:58 | rhickey | yes |
| 16:58 | Raynes | rhicky and thicky. What a pair. What a pair I say, what a pair. |
| 17:00 | headius | rhickey: yes, all refs |
| 17:00 | headius | stepped away for a bit |
| 17:00 | headius | @foo and @foo = are just deref and set |
| 17:01 | rhickey | headius: 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:02 | headius | I presume that would be the same problem if you are dealing with a set of refs |
| 17:02 | headius | this is just a shortcut for passing around a set of refs as though it were an object |
| 17:03 | rhickey | if 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:03 | rhickey | headius: yes, but sets of refs are not that great |
| 17:03 | headius | mmm interesting |
| 17:03 | rhickey | have the snapshot implement the read interface of the original |
| 17:04 | headius | so instead of a set of refs, you have a ref to a set |
| 17:04 | headius | and replace it en masse |
| 17:04 | rhickey | that is in keeping with the ideas behind refs and Clojure state |
| 17:04 | rhickey | right, ref to a map |
| 17:05 | headius | wouldn't be hard to modify this to work that way |
| 17:05 | headius | jruby fields aren't kept in a map, they're just in an indexed structure (an array normally) |
| 17:05 | headius | so it would just be a ref to a vector of values |
| 17:05 | rhickey | I ecommend it - independent refs do not an object make |
| 17:06 | rhickey | whatever the structure, it needs to be immutable |
| 17:10 | the-kenny | Whoa.. macoexpansion at compile time got me again. |
| 17:11 | twbray | rhickey: It's not obvious that you need transaction semantics across all the fields in an object. Hmmm |
| 17:12 | dnolen | from ML, nice: http://lisperati.com/vijual/ |
| 17:13 | the-kenny | dnolen: whoa |
| 17:13 | headius | twbray: 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:13 | headius | in which case whether they're separate refs or a single ref, they're all part of the transaction, no? |
| 17:20 | rhickey | headius: 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:21 | rhickey | separate refs means you must read in a transaciton |
| 17:22 | headius | makes sense |
| 17:24 | headius | if you had any sort of javadocs at all, this would be easier :) |
| 17:26 | rhickey | http://clojure.org/state |
| 17:29 | headius | hmm |
| 17:29 | headius | RT doesn't appear to like being loaded from bootclasspath |
| 17:30 | headius | rhickey: you know .class.getClassLoader returns null when loaded from bootclasspath, yes? |
| 17:31 | headius | RT.baseLoader doesn't check for that |
| 17:35 | headius | I'll work around it for now |
| 17:50 | nathanmarz | technomancy: can leiningen be used as the build system for a regular java project? |
| 18:12 | jkkramer | ping |
| 18:12 | jkkramer | i just made an ns cheatsheet for myself that others might find handy: http://gist.github.com/284230 |
| 18:53 | mabes | anyone 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:57 | danlarkin | technomancy: ping |
| 18:59 | alexyk | did you guys have to register your nicks today? |
| 18:59 | alexyk | I'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:00 | technomancy | alexyk: yeah, I couldn't speak in this channel without registering. |
| 19:01 | technomancy | alexyk: I could speak fine in other channels, but #clojure must be configured differently |
| 19:01 | alexyk | I wonder what's up with that. No more ___ and ` and |away |
| 19:01 | jkkramer | mabes: defroutes accepts route variables, so you can do something like: (defroutes all-routes foo-routes bar-routes), then (servlet all-routes) |
| 19:01 | alexyk | perhaps the clojurebot decided it's HAL? |
| 19:01 | mabes | jkkramer: perfect. Thanks! |
| 19:02 | alexyk | clojurebot: did you get drunk and fight nickserv again? |
| 19:02 | alexyk | ah! clojurebot has to register too |
| 19:05 | alexyk | it's like mute hordes show up, bang on the doors, and leave silently |
| 19:06 | hiredman | clojurebot is registered |
| 19:07 | hiredman | must be netsplitted |
| 19:07 | hiredman | clojurebot: ping? |
| 19:07 | clojurebot | PONG! |
| 19:11 | ubii | clojurebot: Open the pod bay doors, HAL. |
| 19:11 | clojurebot | the nest sentence is true |
| 19:11 | ubii | damn, I was hoping he would respond by saying "I'm sorry, Dave. I'm afraid I can't do that." |
| 19:12 | ubii | guess he really isn't HAL |
| 19:16 | hiredman | clojurebot: Open the pod bay doors, HAL is <reply>I'm sorry, Dave. I'm afraid I can't do that. |
| 19:16 | clojurebot | In Ordnung |
| 19:16 | hiredman | clojurebot: Open the pod bay doors, HAL. |
| 19:16 | clojurebot | I'm sorry, Dave. I'm afraid I can't do that. |
| 19:17 | ubii | nice :) |
| 19:17 | hiredman | clojurebot: Open the pod bay doors, HAL is <reply>I'm sorry, #who. I'm afraid I can't do that. |
| 19:17 | clojurebot | 'Sea, mhuise. |
| 19:17 | hiredman | clojurebot: Open the pod bay doors, HAL. |
| 19:17 | clojurebot | I'm sorry, hiredman. I'm afraid I can't do that. |
| 19:17 | hiredman | :P |
| 19:18 | ubii | even better |
| 19:52 | alexyk | how do I convert a seq of pairs ([1 2][3 4]) into a map most efficiently? |
| 20:03 | KirinDave | So |
| 20:03 | KirinDave | Can someone explain to me why this macro freaks out Clojure? |
| 20:03 | KirinDave | https://gist.github.com/198e96fbdf697b98d3d3 |
| 20:03 | KirinDave | It works on the repl. |
| 20:03 | KirinDave | But if I try to use it in code, it dies. |
| 20:03 | KirinDave | With no error from the compiler. |
| 20:05 | alexyk | still -- how do I convert a seq of pairs ([1 2][3 4]) into a map most efficiently? |
| 20:07 | the-kenny | alexyk: (hash-map (apply concat seq))? |
| 20:08 | the-kenny | ,(hash-map (apply concat '([1 2] [3 4 |
| 20:08 | clojurebot | EOF while reading |
| 20:08 | the-kenny | ,(hash-map (apply concat '([1 2] [3 4]))) |
| 20:08 | clojurebot | java.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@e93c3 |
| 20:08 | the-kenny | ,(hash-map (apply concat [[1 2] [3 4]])) |
| 20:08 | clojurebot | java.lang.IllegalArgumentException: No value supplied for key: clojure.lang.LazySeq@e93c3 |
| 20:08 | the-kenny | ,(apply hash-map (apply concat [[1 2] [3 4]])) |
| 20:08 | clojurebot | {1 2, 3 4} |
| 20:08 | the-kenny | ha! |
| 20:08 | alexyk | yay! |
| 20:10 | alexyk | or (flatten theseq) |
| 20:11 | alexyk | so what's with into? I thought hiredman had a way to (into {} ...) |
| 20:12 | alexyk | but can't remember how |
| 20:12 | clojurebot | with style and grace |
| 20:13 | KirinDave | So, uh, no one? |
| 20:13 | KirinDave | Why that macro fails? |
| 20:14 | KirinDave | https://gist.github.com/198e96fbdf697b98d3d3 |
| 20:14 | KirinDave | Cuz it works in macroexpand. |
| 20:15 | tolstoy | If you have, say, a connection pool (DB), and you want to initiate it on first use, is a "ref" the way to go? |
| 20:15 | alexyk | I'm working a huge transient map of transient vectors. Then I need to persistent!-ize it back. Here's the result of toil: |
| 20:15 | alexyk | ,(->> (transient {:a (transient [1])}) (persistent!) (map (fn [[k v]] [k (persistent! v)])) (apply concat) (apply hash-map)) |
| 20:15 | clojurebot | {:a [1]} |
| 20:15 | alexyk | is this reasonable? |
| 20:16 | alexyk | using the new Deutsch import from the-kenny in the end |
| 20:18 | the-kenny | alexyk: huh? Deutsch import? |
| 20:18 | alexyk | the-kenny: like a shiny BMW |
| 20:19 | alexyk | I'm doing your trick of precise engineering in the end of that ->> :) |
| 20:19 | alexyk | the question is, ios it the efficient way -- to persist! the map first, then the leaves |
| 20:20 | the-kenny | alexyk: Ah :) got it |
| 20:22 | alexyk | headius: did you have to register too? |
| 20:23 | headius | hi |
| 20:23 | headius | what's up? |
| 20:24 | alexyk | headius: do you know who inflicted this Guantanamo-style registration on us? |
| 20:24 | alexyk | it was weird here all day |
| 20:24 | headius | Freenode probably |
| 20:24 | headius | there was a big spam attack this weekend and they set channels +R |
| 20:25 | headius | operator can turn it off though...I did in JRuby |
| 20:25 | headius | #jruby |
| 20:25 | alexyk | ah ok |
| 20:43 | chouser | alexyk: into |
| 20:43 | chouser | alexyk: into |
| 20:43 | chouser | ,(into {} [[1 2] [3 4]]) |
| 20:43 | clojurebot | {1 2, 3 4} |
| 20:54 | alexyk | chouser: I've tried with |
| 20:54 | alexyk | ,(into {} ([1 2][3 4])) |
| 20:54 | clojurebot | java.lang.IllegalArgumentException: Key must be integer |
| 20:54 | alexyk | and it failed |
| 20:55 | alexyk | why does (vec..) fix it? |
| 20:56 | chouser | that's just the literal list getting evaluated |
| 20:56 | chouser | ,(into [] (list [1 2] [3 4])) |
| 20:56 | clojurebot | [[1 2] [3 4]] |
| 20:56 | chouser | ,(into {} (list [1 2] [3 4])) |
| 20:56 | clojurebot | {1 2, 3 4} |
| 20:57 | alexyk | ah nice |
| 20:58 | alexyk | vec's almost obliterate 'quoting |
| 20:58 | chouser | yep |
| 20:59 | chouser | and (list ...) |
| 21:04 | alexyk | chouser: cgrand : is this a good way tp persist a transient map of transient vectors: |
| 21:04 | alexyk | ,(->> (transient {:a (transient [1])}) (persistent!) (map (fn [[k v]] [k (persistent! v)])) (into {})) |
| 21:04 | clojurebot | {:a [1]} |
| 21:05 | alexyk | i.e. least reallocation? |
| 21:08 | limux | what's the meaning of "fn*" |
| 21:11 | limux | would I walk around the google to find the anwser or have to read the source of clojure? |
| 21:15 | alexyk | limux: where did you see fn* ? |
| 21:15 | mattrepl | probably read clojure/core.clj. it has to do with not having a destructuring fn while bootstrapping.. in fact the comments say as much =) |
| 21:16 | limux | sorry, i forget it |
| 21:18 | limux | but you can use fn* to def a func which can work well |
| 21:19 | mattrepl | hmm, I think my answer is only partially correct |
| 21:20 | limux | in REPL, (fn a [] ()) => #<user$eval__3567$a__3569 user$eval__3567$a__3569@f4c0275> |
| 21:20 | limux | but, (fn* a [] ()) => #<user$eval__3567$a__3569 user$eval__3567$a__3569@f4c0275> |
| 21:20 | mattrepl | but it has something to do with bootstrapping and special forms |
| 21:20 | limux | all is ok |
| 21:21 | limux | i remeber i saw someone use fn* in his app on github |
| 21:22 | limux | but i forget his proj |
| 21:25 | mattrepl | fn is a macro, so expand it and you'll see how fn* is used underneath |
| 21:27 | limux | i read only part of the sources of clojure |
| 21:28 | limux | fn* a [] ()) => #<user$eval__3575$a__3577 user$eval__3575$a__3577@22cb4138> |
| 21:29 | limux | a bit diffence to fn |
| 21:29 | mattrepl | ,(macroexpand (fn [x] (inc x))) |
| 21:29 | clojurebot | #<sandbox$eval__5090$fn__5092 sandbox$eval__5090$fn__5092@1d39053> |
| 21:29 | mattrepl | ,(macroexpand '(fn [x] (inc x))) |
| 21:29 | clojurebot | (fn* ([x] (inc x))) |
| 21:33 | limux | any more clealy explain? |
| 21:34 | limux | ,(macroexpand (fn* [x] (inc x))) |
| 21:34 | clojurebot | #<sandbox$eval__5099$fn__5101 sandbox$eval__5099$fn__5101@beaff3> |
| 21:34 | limux | #<user$eval__3628$fn__3630 user$eval__3628$fn__3630@1a71d29a> |
| 21:35 | limux | ,(macroexpand (fn [x] (inc x))) |
| 21:35 | clojurebot | #<sandbox$eval__5105$fn__5107 sandbox$eval__5105$fn__5107@1d998e8> |
| 21:35 | limux | #<user$eval__3637$fn__3639 user$eval__3637$fn__3639@7991ba7> |
| 21:35 | mattrepl | you need to quote macroexpand's argument |
| 21:35 | limux | ok |
| 21:35 | mattrepl | ,(macroexpand '(fn [x] (inc x))) |
| 21:35 | clojurebot | (fn* ([x] (inc x))) |
| 21:37 | limux | ,(macroexpand '(fn [x] (inc x))) |
| 21:37 | clojurebot | (fn* ([x] (inc x))) |
| 21:38 | limux | ,(macroexpand '(fn [x] (inc x))) => (fn* ([x] (inc x))) |
| 21:38 | clojurebot | (fn* ([x] (inc x))) |
| 21:38 | limux | ,(macroexpand '(fn* [x] (inc x))) => (fn* [x] (inc x)) |
| 21:38 | clojurebot | (fn* [x] (inc x)) |
| 21:39 | limux | fn is macro |
| 21:40 | limux | (def |
| 21:40 | limux | #^{:macro true} |
| 21:40 | limux | fn (fn* fn [& decl] (cons 'fn* decl))) |
| 21:43 | limux | let, loop do the same as fn |
| 21:43 | limux | let* loop* |
| 21:47 | chouser | sorry, what was the question? |
| 21:48 | mattrepl | chouser: the purpose of fn* |
| 21:53 | limux | in compliler.java, static final Symbol FN = Symbol.create("fn*) |
| 22:17 | hiredman | fn is a macro that emits calls to the special form fn* |
| 22:25 | jlb | my "...more fn" t-shirt arrived today! http://img113.yfrog.com/i/kzml.jpg/ |
| 22:33 | chouser | jlb: cool! quality of the shirt and printing ok? |
| 22:35 | jlb | chouser: yeah... I customized w/ an American Apparel shirt, but it looks great |
| 22:41 | chouser | great. |