2010-02-17
| 00:16 | technomancy | who's ready for a leiningen release tonight? |
| 00:16 | danlarkin | Choo CHoooooooooo |
| 00:18 | Raynes | Aw man! |
| 00:18 | Raynes | More shit to download, excuse my french. ;) |
| 00:18 | technomancy | well, this will be the last time |
| 00:18 | technomancy | somebody contributed an upgrade task |
| 00:19 | Raynes | technomancy: Has the "lein new project.clj is all a single line" bug been fixed? |
| 00:19 | Raynes | Oh goody! |
| 00:19 | technomancy | Raynes: yup |
| 00:19 | Raynes | Yay! I'm all excited now. |
| 00:19 | Raynes | Get to releasing, Doctor Phil! |
| 00:19 | technomancy | it's done with format now instead of pprint, which is lame but not as lame as a one-line project.clj |
| 00:20 | danlarkin | upgrade task? sounds non-friendly to packages |
| 00:20 | Raynes | danlarkin: Screw you and your packages. >:| |
| 00:21 | technomancy | danlarkin: yeah, you'll want to delete that for homebrew |
| 00:22 | technomancy | but it does check to make sure the bin script is writable before it replaces it. |
| 00:22 | tomoj | what's this "packages"/"homebrew" thing |
| 00:22 | danlarkin | I'm gonna let that stew for a few days |
| 00:24 | technomancy | oh nice; github has a flash-less upload system now |
| 00:24 | technomancy | so I can use that instead of my dreamhost |
| 00:24 | Raynes | I think somebody needs to relay the whole "git doesn't store binaries well" discussion to Ola Bini. Ioke's git repo is unbelievably huge. |
| 00:25 | technomancy | Raynes: pet peeve! |
| 00:26 | technomancy | I will do it if I see him. |
| 00:26 | technomancy | I got Charlie to agree to rewriting Duby's history in order to remove jars. |
| 00:26 | Raynes | I don't contribute to Ioke simply because downloading the repository on this dial up connection is either impossible, or just not worth the time it would take. |
| 00:27 | Raynes | I might tether up my phone and pull it down over a day or two on a different computer over my phone's 4kb (I live in the middle of nowhere) connection. |
| 00:27 | technomancy | I tried to submit a patch to remove jars from the Katta project, but the patch was so big that Jira refused it. |
| 00:28 | underdev | hi! i'm trying to use clojure-test-mode, but i'm having a problem. If i run code directly in slime-repl, the testing works fine. If i try to C-c C-, from a buffer with the same code, i get an error: Unmatched delimiter: ) |
| 00:28 | Raynes | I'm not really sure what makes Ioke's repo so big, but I know that some 300mb is too big for a year old language. |
| 00:28 | Raynes | I mean, even Factor's repo is just 50mb. |
| 00:29 | underdev | anyone else encounter this problem? |
| 00:29 | technomancy | yeah, the problem is that even just removing a jar adds the size of the jar to the repo over again. |
| 00:30 | technomancy | so a series of upgrades is going to be a disaster |
| 00:30 | technomancy | underdev: no, sounds like the file has a typo |
| 00:31 | Raynes | I wish github showed repository and file sizes. |
| 00:31 | Raynes | I'd like to know just how large this beast is. |
| 00:31 | underdev | backtrace 0: clojure.lang.LispReader.read(LispReader.java:180) |
| 00:31 | underdev | technomancy: which file? |
| 00:32 | Raynes | I know that whatever made the repo so big isn't there anymore, because the actual source without the history is only like 4mb... |
| 00:32 | Raynes | http://github.com/olabini/ioke/tree/master/lib/build/ Or maybe I spoke too soon. Appears he is still keeping jars in there. |
| 00:33 | underdev | i had a little trouble installing clojure-test-mode from elpa, maybe its fubared |
| 00:33 | technomancy | underdev: no, it's probably the file containing the tests |
| 00:33 | scottj | I saw a screencast where clojure-test-mode highlighted the minibuffer (not just lines) in green/red when tests passed/failed and printed in minibuffer what was expected from test instead of just number of failures. anyone know what version of clojure test mode has those features? |
| 00:34 | technomancy | scottj: that'd be tcrayford's. it had a few issues I asked him to resolve before I merged |
| 00:34 | Raynes | And this: http://github.com/olabini/ioke/tree/master/bin/ |
| 00:35 | underdev | technomancy: no, its balanced. its tiny |
| 00:35 | underdev | paredit confirms :) |
| 00:35 | technomancy | underdev: maybe it's a namespace that it requires then? |
| 00:35 | underdev | (use 'clojure.test) |
| 00:36 | underdev | that's it |
| 00:36 | underdev | (deftest testing-tests (is (= 2 2))) |
| 00:36 | scottj | technomancy: cool, those features will be nice |
| 00:36 | Drakeson | can I use leiningen to build/install/do-something-to a project that still only has a pom.xml? |
| 00:37 | technomancy | Drakeson: not currently |
| 00:38 | Drakeson | I see |
| 00:39 | scottj | does leiningen (or one of it's plugins) have anything for deployment? |
| 00:40 | technomancy | you guys are full of great ideas |
| 00:40 | technomancy | but they are not in leiningen yet |
| 00:40 | technomancy | think of it as an opportunity to contribute |
| 00:41 | Raynes | And be greatful that technomancy knows how to manage a github repo, and the size is quite small. |
| 00:41 | Raynes | s/github/git/ |
| 00:43 | scottj | I did spend like two hours trying to figure out why recent (since jochu's) swank-clojure M-. doesn't work correctly on Windows but failed miserably. |
| 00:44 | technomancy | windows is ... lightly supported. to put it generously. |
| 00:45 | technomancy | heck, swank-clojure is lightly-supported when it comes down to it. |
| 00:47 | scottj | Other than M-. it worked pretty well I think. I think it's just got / hard coded instead of using File/separator maybe |
| 00:48 | technomancy | what are the specifics on badditude of single-segment namespaces? |
| 00:49 | technomancy | is it just an AOT-time problem, or is it more general? |
| 00:50 | hiredman | I think current;ly it is mostly an aot issue, but because we wnat something like unified semantics, it is everyone's problem |
| 00:50 | technomancy | I'll buy that. |
| 00:51 | technomancy | fewer awkward questions down the road |
| 00:51 | technomancy | so lein new will spit out a foo.core ns instead of foo |
| 00:56 | technomancy | hiredman: did you have a use-/bin/sh fix? |
| 00:56 | hiredman | the website updates via fork/pull request is a neat idea |
| 00:56 | hiredman | technomancy: no :( |
| 00:56 | technomancy | hiredman: I stole that from the Seattle Ruby group |
| 00:56 | technomancy | hiredman: probably a little late in the release cycle to change something like that anyway |
| 00:59 | underdev | having backtracked, when i try to install clojure-test-mode from ELPA, it complaims that swank-clojure.el already exists |
| 01:00 | underdev | anyone see that before? |
| 01:00 | technomancy | underdev: yeah... it's a known bug. |
| 01:00 | technomancy | I've fixed it, but the package.el maintainer hasn't applied my patch yet. =\ |
| 01:00 | underdev | how would i get your copy? |
| 01:00 | technomancy | underdev: http://github.com/technomancy/package.el |
| 01:00 | technomancy | lots of other neat features there too. =) |
| 01:01 | underdev | technomancy: ty |
| 01:01 | underdev | !!! |
| 01:01 | technomancy | eh? |
| 01:02 | underdev | thank you |
| 01:02 | technomancy | oh, I thought the !!! was an expression of surprise or alarm. |
| 01:02 | underdev | appreciation |
| 01:02 | slyphon | "Ooooh!" |
| 01:02 | slyphon | "no, 'Arrrgh!'" |
| 01:03 | technomancy | "no, it's more in the back of the throat..." |
| 01:03 | slyphon | :D |
| 01:06 | Knekk | hmm, what's the simplest way to convert a char[] to a list of chars? |
| 01:06 | technomancy | Knekk: call seq on it |
| 01:06 | Knekk | ah, that's simple enough, thanks. |
| 01:06 | slyphon | seq and ye shall find |
| 01:07 | Knekk | brilliant, thanks |
| 01:09 | underdev | technomancy: w00t! thank you! |
| 01:10 | underdev | rock on |
| 01:11 | technomancy | should future versions of leiningen have code names? |
| 01:11 | danlarkin | yes! |
| 01:12 | underdev | DARN IT! |
| 01:13 | underdev | installed but still getting that stupid error |
| 01:13 | technomancy | look out for Leiningen "Amazing Horse" 1.2.0, coming to a git hub near you. |
| 01:13 | danlarkin | Heyooooooooooooooooo |
| 01:14 | technomancy | danlarkin: next time I call you I'm going to be thinking about the fact that "hey, pressing this button is going to cause the amazing horse song to be played. neat." |
| 01:14 | danlarkin | Hahah |
| 01:15 | technomancy | dun dun DUN: http://github.com/technomancy/leiningen/blob/1.1.0/NEWS#L3 |
| 01:15 | danlarkin | well my phone's on silent most of the time, but it's the thought that counts |
| 01:15 | underdev | technomancy: do you think i would be better off using the esk? does that have clojure-test-mode integrated into it? |
| 01:16 | technomancy | underdev: it installs clojure-test-mode via elpa too. |
| 01:16 | technomancy | can you try M-x toggle-debug-on-error? |
| 01:16 | technomancy | maybe that could get you a stacktrace you could paste |
| 01:18 | slyphon | god *dammit* |
| 01:19 | technomancy | slyphon: you could try wall-hack |
| 01:19 | technomancy | in contrib |
| 01:19 | technomancy | but I don't know much about it apart from it's an awesome name that sounds like it could be relevant to the problem at hand |
| 01:19 | slyphon | hah |
| 01:20 | hiredman | it got renamed |
| 01:20 | hiredman | in master it is called reflection something or other |
| 01:20 | hiredman | excellent |
| 01:21 | slyphon | it seems like gen-class provides a way to do this, i just can't figure out the correct combination of :exposes-methods and :methods or something |
| 01:23 | hiredman | slyphon: what does :methods have to do with it? |
| 01:24 | slyphon | so, my superclass has a protected setName method, when i (defn -setName ...) and try to do (.setName inst "blah") i get No matching method found: setName |
| 01:25 | slyphon | basically, i'm throwing stuff at the wall and seeing what sticks at this point |
| 01:26 | hiredman | :exposes {setName private-setName} |
| 01:26 | hiredman | or something |
| 01:26 | slyphon | yeah :exposes-methods { setName setNameSuper } |
| 01:26 | slyphon | is what i have |
| 01:26 | hiredman | actually, hypens are not a good idea |
| 01:27 | hiredman | is this for pircbot? |
| 01:27 | slyphon | yeah |
| 01:27 | slyphon | https://gist.github.com/8e989bdceba5fb2b5778 |
| 01:27 | slyphon | it's my first project with any language i'm trying to learn |
| 01:27 | hiredman | I think I wrote wall-hack-method for this purpose |
| 01:28 | slyphon | shouldn't :exposes-methods take care of this? |
| 01:28 | hiredman | I bet, but gen-class'ing sucks |
| 01:28 | slyphon | hahahaha |
| 01:28 | slyphon | indeed |
| 01:29 | slyphon | how about proxy? |
| 01:29 | hiredman | proxy? |
| 01:29 | clojurebot | proxy is <Chouser> proxy teases with its ease of use, then suddenly betrays. |
| 01:29 | slyphon | hah |
| 01:29 | hiredman | clojurebot uses proxy and wall-hacks setName |
| 01:29 | slyphon | ok |
| 01:29 | slyphon | i'll look at that then |
| 01:30 | hiredman | the main issue I had with proxy is updating the methods can be a pain |
| 01:30 | technomancy | unless you've got a fair amount of java experience, you might want to avoid these kind of tricky interop things for a first project |
| 01:30 | Raynes | I think an IRC client will be my next adventure after I finally realize that I can't design an email client and give up. |
| 01:30 | slyphon | technomancy: well, true |
| 01:31 | technomancy | they're not nearly as fun and quick as a more functional project would be |
| 01:31 | Raynes | Oh joy. Ted Bundy is coming on. I like me some serial killer. |
| 01:31 | slyphon | i wrote a scalabot using PircBot, so i had something of a structure worked out |
| 01:31 | technomancy | but if you've got something that would be useful then that's a plus too |
| 01:31 | slyphon | yeah |
| 01:32 | slyphon | this is always the hard thing, trying to figure out what's easy enough to mess with, the middle ground between a toy and something really substantive |
| 01:32 | hiredman | clojurebot: scala 1+1 |
| 01:32 | technomancy | yup |
| 01:32 | technomancy | slyphon: I had a lot of fun with mire: http://github.com/technomancy/mire |
| 01:32 | clojurebot | Int = 2 |
| 01:33 | slyphon | hah |
| 01:33 | slyphon | i'm afraid i'm not much of a MUD guy, but yeah |
| 01:34 | technomancy | oh yeah, I didn't actually *play* it. but it was fun to write. =) |
| 01:34 | slyphon | hahaha |
| 01:34 | hiredman | the java guys always cry if someone mentions pircbot |
| 01:34 | slyphon | oh yeah? |
| 01:34 | hiredman | they all like jerklib |
| 01:34 | slyphon | hah |
| 01:34 | hiredman | I think that is what it is called |
| 01:34 | slyphon | pircbot is really not that awesome, it's just...i dunno, straightforward in a way |
| 01:35 | slyphon | yeah, jerklib |
| 01:35 | slyphon | http://jerklib.sourceforge.net/ |
| 01:35 | slyphon | hey, they have The Big Lebowski on their homepage, this *must* be awesome! |
| 01:36 | hiredman | :P |
| 01:37 | slyphon | ah, yeah, this is event based, which is what i always wind up having to shoehorn onto pircbot |
| 01:39 | hiredman | all of the proxy'ied methods in clojurebot end up calling a function that calls a multimethod trampolined in a future |
| 01:39 | slyphon | you had me at "trampoline" |
| 01:41 | slyphon | yeah, i was basically gonna convert the onFooBar method's arguments into a struct, then figure out some way of calling a bunch of listeners with that struct in a separate thread |
| 01:42 | slyphon | future-cancelled? sounds rather...fatal |
| 01:43 | hiredman | (future (trampoline some-function arg1 arg2)) |
| 01:43 | slyphon | why do you need trampoline there? |
| 01:44 | hiredman | some times some-function returns a thunk that calls some-function again with altered args |
| 01:45 | hiredman | and some-function is a multimethod and recur only works with-in fns |
| 01:45 | slyphon | "a thunk" is a curried function? |
| 01:45 | hiredman | a thunk is a no arg function |
| 01:45 | slyphon | ah |
| 01:45 | hiredman | #(some-function arg4 arg5) |
| 01:45 | slyphon | gotcha |
| 01:45 | slyphon | and trampoline ensures you don't consume stack |
| 01:47 | hiredman | right |
| 01:47 | slyphon | that's pretty damn cool |
| 01:50 | hiredman | the trampolining is neat |
| 01:50 | slyphon | it's very disconcerting |
| 01:50 | slyphon | at first |
| 01:50 | hiredman | ~seen hiredman |
| 01:50 | clojurebot | hiredman was last seen in #clojure, 0 minutes ago saying: ~seen hiredman |
| 01:50 | slyphon | hah |
| 01:51 | hiredman | everything goes to that "plugin" and once it updates the tracking stuff it just adds an ignore me flag to the metadata and trampolines |
| 01:52 | slyphon | you're dispatching based on the metadata? |
| 01:52 | slyphon | or that's something trampoline does? |
| 01:52 | slyphon | (the ignore-me bit) |
| 01:52 | slyphon | clojurebot: code? |
| 01:52 | clojurebot | I don't understand. |
| 01:53 | hiredman | each plugin defines a function that the multimethod uses to determine who gets a message |
| 01:53 | hiredman | clojurebot: source |
| 01:53 | clojurebot | source is http://github.com/hiredman/clojurebot/tree/master |
| 01:54 | slyphon | oooh |
| 01:54 | slyphon | xmpp |
| 01:54 | slyphon | *FANCY* |
| 01:54 | slyphon | :) |
| 01:54 | hiredman | http://github.com/hiredman/clojurebot/blob/master/src/hiredman/clojurebot/seenx.clj |
| 01:55 | hiredman | I wish there was a pircbot for xmpp |
| 01:55 | slyphon | yeah, all the jabber libs are as confusing as the jabber protocol |
| 01:58 | underdev | no one is using clojure-test-mode |
| 01:58 | underdev | i know this to be true |
| 01:59 | underdev | because on both ubuntu and windows, it throws the same error, but after dismissing the error the test results are shown in slime |
| 02:00 | underdev | if others were using it, this behavior would be know |
| 02:00 | underdev | n |
| 02:12 | underdev | i'm going to try fresh with the ESK |
| 02:29 | Raynes | Is there a standard way of shuffling the contents of a sequence? |
| 02:29 | Raynes | Maybe something in contrib? |
| 02:30 | somnium | ,(doc shuffle) |
| 02:30 | clojurebot | "([coll]); Return a random permutation of coll" |
| 02:30 | Raynes | What do you know. |
| 02:30 | Raynes | :| |
| 02:30 | somnium | c.c.seq-utils for 1.1 |
| 02:31 | Raynes | Thaks. |
| 02:31 | Raynes | Thanks* |
| 02:31 | somnium | Welome |
| 02:40 | Knekk | I am brain-dead... what's the easiest way to return a list with only the first instance of an element removed? |
| 02:40 | Knekk | or any one instance of a particular element removed. |
| 02:40 | Knekk | i.e. remove a \a from (\a \a \a \b \b \b) returns (\a \a \b \b \b) |
| 02:41 | Knekk | maybe I should sleep on it |
| 02:41 | TheBusby | rest? |
| 02:41 | clojurebot | rest never returns a unicorn |
| 02:42 | TheBusby | ,(rest [1 2 3]) |
| 02:42 | clojurebot | (2 3) |
| 02:42 | Knekk | rest only works if the element is at the first position, which is not always true |
| 02:42 | Knekk | I could want to remove \b so that I have (\a \a \a \b \b) as the result |
| 02:42 | TheBusby | ahh, so for example (magic 2 [1 1 2 3 3]) would return [1 1 3 3] |
| 02:43 | Knekk | right |
| 02:43 | Knekk | remove at most one instance from the list |
| 02:43 | TheBusby | er, take-while? |
| 02:43 | Knekk | ,(doc take-while) |
| 02:43 | clojurebot | "([pred coll]); Returns a lazy sequence of successive items from coll while (pred item) returns true. pred must be free of side-effects." |
| 02:43 | TheBusby | in this case, take-while not equal |
| 02:43 | Knekk | it would remove all instances, not just one |
| 02:43 | Chousuke | you might want to make a custom lazy seq for that. |
| 02:44 | _mst | maybe: (defn magic [elt coll] (let [[xs ys] (split-with #(not= elt %) coll)] (concat xs (rest ys)))) |
| 02:44 | TheBusby | when-first? |
| 02:44 | _mst | (mostly untested ;) |
| 02:44 | Knekk | let me try that. |
| 02:45 | TheBusby | I heartily recommend the "clojure cheat sheet" for running these types of questions down. Not that I know the answer though :) |
| 02:45 | Knekk | _mst: very nice |
| 02:46 | _mst | hooray :D |
| 02:49 | Knekk | thanks all |
| 02:49 | Knekk | fun with ProjectEuler problems, but time for bed. |
| 02:51 | vy | Considering (apply str (line-seq rdr)) expression, does str work eagerly in here? |
| 02:52 | Chousuke | yes. |
| 02:52 | Chousuke | strings are java Strings, so it has to :) |
| 02:55 | tomoj | is it evil to have a deftype with a field that points to an atom? |
| 02:55 | tomoj | my use case: I need to implement a java interface with a single message that is called when a message comes in via xmpp |
| 02:56 | tomoj | the deftype will implement that interface, and the method will push (swap!) the incoming method onto the queue |
| 02:56 | tomoj | when I want to process incoming messages I can then pop (swap!) messages off |
| 02:56 | tomoj | seems strange and weird, but maybe beautiful |
| 02:57 | somnium | :volatile-mutable and :unsychronized-mutable just got added as options to deftype fields in master |
| 02:58 | hamza | is reduce lazy? |
| 02:58 | tomoj | both of those sound scary |
| 02:58 | tomoj | but I will take a look |
| 02:58 | tomoj | hmm, I don't think they are for me |
| 02:58 | tomoj | I want STM |
| 02:59 | somnium | putting an atom in a struct-map doesnt sound terribly evil |
| 03:00 | tomoj | great :) |
| 03:01 | somnium | is there any docs/discussion on how the &form &env implicit macro args work? |
| 03:19 | tomoj | is there a function version of @ ? |
| 03:19 | somnium | deref? |
| 03:19 | tomoj | ah, of course |
| 03:19 | tomoj | thanks |
| 03:34 | hiredman | ,(macroexpand '@a) |
| 03:34 | clojurebot | (clojure.core/deref a) |
| 03:34 | hiredman | ,(read-string "@a") |
| 03:34 | clojurebot | (clojure.core/deref a) |
| 03:46 | bosie | how much slower is clojure compared to java? i googled but you find numbers from twice as slow to ten times as slow |
| 03:46 | Chousuke | it depends on what you're doing |
| 03:47 | hiredman | and how you do it, and how often you do it |
| 03:47 | bosie | algorithmic nature, data crunching |
| 03:47 | slyphon | hiredman: that's what she said? |
| 03:47 | hiredman | clojurebot: do something |
| 03:47 | clojurebot | what should I do today, it is the weekend and all |
| 03:47 | hiredman | clojurebot: what timezone is that? |
| 03:47 | clojurebot | It's greek to me. |
| 03:48 | hiredman | right, europe, the worker's paradise |
| 03:48 | slyphon | hah |
| 03:48 | bosie | so the 10x is possible when you have a lot of data and have to calculate on it? |
| 03:48 | slyphon | bosie: "how much slower is it" has got to be one of the least-answerable questions in the abstract |
| 03:48 | Chousuke | I think you usually get 10x if you write straightforward, functional code with type hints. |
| 03:49 | bosie | ok |
| 03:49 | Chousuke | but you can get significantly better performance through optimisation. |
| 03:49 | bosie | slyphon: i know i know |
| 03:50 | hiredman | Chousuke: really? |
| 03:50 | hiredman | (about the 10x) |
| 03:50 | slyphon | benchmark it! |
| 03:50 | Chousuke | hiredman: well, that's just my pessimistic estimate |
| 03:51 | Chousuke | hiredman: I haven't actually benchmarked it :) |
| 03:52 | Chousuke | only for now, straightforward code (using many lazy seqs, no transients or primitives, etc) is a fair bit slower |
| 03:53 | hiredman | rhickey's gvec in clojure is supposed to be the same speed as the java |
| 03:53 | Chousuke | I suppose. but I wasn't considering 1.2 yet :P |
| 03:54 | Chousuke | also it's not really number-crunching |
| 03:55 | Chousuke | bosie: so in short, I think you probably won't be able to get to 1:1 with java, but close enough for most purposes. |
| 03:56 | bosie | Chousuke: considering that a single process of the java version took 15 hours to process the data.... ;) |
| 03:56 | Chousuke | bosie: was it multithreaded, though? |
| 03:56 | bosie | Chousuke: single process, single thread |
| 03:57 | bosie | Chousuke: no |
| 03:57 | hiredman | pmap |
| 03:57 | Chousuke | right. |
| 03:57 | bosie | Chousuke: but if its 15 hours for java, multithreading doesn't help much for clojure either |
| 03:58 | Chousuke | well, assuming you can get clojure to even 2x java speed, then running it with 4 cores should help :P |
| 03:58 | bosie | i have 80 cores |
| 03:58 | hiredman | :D |
| 03:58 | bosie | but i will run the java code on those 80 cores too ;) |
| 03:59 | hiredman | have you seen the clojure widefinder write up? |
| 03:59 | somnium | bosie: have fun synchronizing the java :p |
| 03:59 | Chousuke | bosie: you might want to give Clojure a try though. |
| 03:59 | bosie | hiredman: this one? (http://clj-me.cgrand.net/index.php?s=WideFinder%202%20in%20Clojure%20(naive%20port%20from%20Ruby)) |
| 03:59 | bosie | somnium: yea, no fun using threads in java |
| 03:59 | hiredman | http://meshy.org/2009/12/13/widefinder-2-with-clojure.html |
| 03:59 | hiredman | ^- that one |
| 04:00 | hiredman | the not naive one |
| 04:00 | bosie | Chousuke: i would like to, that's why i am reading the book |
| 04:05 | AWizzArd | Moin |
| 04:10 | bosie | thanks guys |
| 04:24 | cgrand | AWizzArd: hallo! |
| 04:25 | esj | morning all |
| 05:32 | powr-toc | What's the idiomatic way of taking everything except the last element from a sequence? |
| 05:32 | Raynes | Autodoc has a bucket load of deps. |
| 05:32 | the-kenny | powr-toc: butlast? |
| 05:33 | the-kenny | ,(doc butlast) |
| 05:33 | clojurebot | "([coll]); Return a seq of all but the last item in coll, in linear time" |
| 05:33 | powr-toc | the-kenny: cheers |
| 05:33 | powr-toc | I knew I'd seen something like that somewhere :-) |
| 05:36 | metaperl | ,(def x 5) |
| 05:36 | clojurebot | DENIED |
| 05:36 | metaperl | is it feasible to use the :test keyword of def() to set the allowable range of a variable? |
| 05:36 | bosie | the-kenny: what's your ',' doing? |
| 05:37 | metaperl | the kenny? |
| 05:37 | metaperl | you mean me? |
| 05:37 | the-kenny | bosie: , is the prefix-command for clojurebot to evaluate clojure-code |
| 05:37 | metaperl | I was trying to use the bot... Im a novice |
| 05:37 | the-kenny | ,(+ 1 2 3) |
| 05:37 | clojurebot | 6 |
| 05:37 | bosie | ah right |
| 05:37 | the-kenny | It doesn't let you evaluate things |
| 05:37 | the-kenny | s/evaluate/def/ |
| 05:37 | triyo | anyone have experience with clojure and mongodb? |
| 05:38 | Raynes | My first experience with a DB will be with FleetDB in my email client. |
| 05:38 | the-kenny | triyo: Someone here uses mongodb with clojure alot |
| 05:40 | triyo | the-kenny: thanks, I'm new to NoSQL and am trying to see how to query embedded docs. A bit of a mind shift. |
| 05:40 | triyo | using congomong clojure lib that is. |
| 05:41 | triyo | somnium: first off, congomongo is cool :) |
| 05:41 | triyo | second, I need some help |
| 05:42 | triyo | I have following simple case. Events collection with embedded Guests. |
| 05:43 | triyo | How do I query guest socs within the event doc? |
| 05:43 | triyo | by query I mean also inserts and updates. |
| 05:43 | triyo | do I use clojure conj, merge, etc? |
| 05:44 | somnium | probably update-in/assoc-in for embedded docs |
| 05:44 | triyo | * socs = docs |
| 05:44 | tomoj | it's likely I will be using congomongo at work soon :) |
| 05:44 | somnium | I am so far behind on patches its embarassing :/ |
| 05:45 | triyo | I see, this is the route I chose. |
| 05:45 | triyo | Here is even a better q. For a give guest doc, how do I determine the event it is embedded in? :) |
| 05:46 | bosie | test |
| 05:46 | bosie | ,(+ 1 2 3) |
| 05:46 | clojurebot | 6 |
| 05:46 | somnium | triyo: to search for an imbedded, (find :events :where {:guest.name "..."}) |
| 05:47 | triyo | thx |
| 05:47 | somnium | triyo: Im not sure I understad, how can you get your hands on an imbedded doc without knowing what it was imbedded in? |
| 05:48 | somnium | ok, maybe ^^ was the answer |
| 05:49 | triyo | somnium: via a browser, a http request was issued with the guest id. So I use guest id to lookup event. So your above where cond will do. |
| 05:49 | triyo | somnium: have you got a change log of patches, whats going in? |
| 05:50 | somnium | gridfs support is the main addition |
| 05:51 | triyo | are you looking to support group and sort? |
| 05:51 | somnium | experimental stripping out of the .java too, but maybe hold-off on that |
| 05:52 | somnium | triyo: sure, why not, patch? |
| 05:56 | somnium | tomoj: really, your workplace uses mongodb? |
| 05:57 | tomoj | not yet, but probably soon |
| 05:57 | tomoj | I've gotten to use clojure on some prototype stuff, and expect to be using it in production soon :) |
| 05:58 | triyo | somnium: you asking for a patch, if so I'd be happy to have a look at that. |
| 06:05 | somnium | triyo: sure, atm Im unlikely to add anything to it that I dont suddenly need, but Im happy to merge in useful things. (though Ive been terribly slow about it this month) |
| 06:09 | triyo | no worries. If I produce something useful, you can look at it and maybe commit it if you wish at your own suitable time. |
| 07:02 | rrc7cz | how might you make a sorted-map by val instead of key |
| 07:10 | AWizzArd | rrc7cz: (def s (apply sorted-set-by #(compare (:username %1) (:username %2)) [1000-users])) |
| 07:11 | AWizzArd | A a User is something like a (deftype User [username password age city ...]) |
| 07:12 | rrc7cz | AWizzArd: I was something along those lines: (sorted-map-by #(compare (m %1) (m %2)) m) but it's treating m as a single key |
| 07:12 | AWizzArd | Maybe because (m of-your-obj) does not return a unique value of all your objects. |
| 07:12 | rrc7cz | AWizzArd: Then I tried various combinations of apply, like (apply (fn [& keyvals] (sorted-map-by #(compare (m %1) (m %2)) keyvals)) m) |
| 07:12 | rrc7cz | hmm |
| 07:12 | AWizzArd | When each User has a unique :username then a sorted set is fine. |
| 07:13 | rrc7cz | okay |
| 07:13 | AWizzArd | But if 5 people live in the :city Paris it won't work. |
| 07:13 | AWizzArd | Because a set treats two things as equal when they are the same over their comparator. |
| 07:13 | rrc7cz | My map is simple string : int, key val pairs, so it should be okay |
| 07:13 | tomoj | hmm, that seems kinda crummy |
| 07:14 | AWizzArd | tomoj: even when the two User instances are not the same under identical? it doesn't matter. |
| 07:14 | tomoj | does no one ever want to have a set, with equality on the actual items, but sorting by some function of the items? |
| 07:14 | AWizzArd | Yes. |
| 07:14 | tomoj | and, if I understand you, sorted-sets can't do that? |
| 07:14 | AWizzArd | You will have to emulate SortedMultisets or SortedMultimaps. |
| 07:14 | tomoj | ah |
| 07:14 | AWizzArd | tomoj: per se it is true, they can not do that. |
| 07:15 | AWizzArd | But: you can have for example a SortedMap and as the key you use the :age of a person. And the value will be a set. |
| 07:15 | AWizzArd | All people of age 85 go into the same set. |
| 07:15 | tomoj | ah, yeah, I can see that |
| 07:16 | tomoj | and then to iterate in sorted order, just iterate over each set in order |
| 07:16 | AWizzArd | Yes. From a SortedMap you can ask for all Users of ages 30 to 40. |
| 07:16 | AWizzArd | And then you will get 10 sets. |
| 07:16 | AWizzArd | Instead of sets it can even be SortedSets, sorted by a unique key of the User deftype. |
| 07:17 | AWizzArd | Then you can have all 20 year old people, sorted by :username. |
| 07:22 | rrc7cz | (apply sorted-map-by #(compare (val %1) (val %2)) m) seems like it should work, but after two comparisons it throws an exception, with m = {:f 1, :j 6, :n 3, :w 2, :m 9} |
| 07:23 | rrc7cz | IllegalArgumentException: No value supplied for key: [:m 9]. It does call compare twice on [:n 3] and [:f 1] which seems odd |
| 07:24 | AWizzArd | m is a vector of maps? |
| 07:24 | rrc7cz | straight map |
| 07:25 | AWizzArd | I am not sure if map breaks m up into (map identity m) |
| 07:29 | rrc7cz | something else I don't understand is why "(sorted-map-by #(compare %1 %2) :f 1 :j 6 :n 3 :w 2 :m 9)" works (sorted by key), but "(apply sorted-map-by #(compare %1 %2) m)" throws an exception |
| 07:30 | AWizzArd | oh, I misread that you want a sorted-MAP and not a sorted-SET |
| 07:30 | AWizzArd | ,(apply sorted-set-by #(compare (val %1) (val %2)) {:a 1, :b 5, :c 3}) |
| 07:30 | clojurebot | #{[:a 1] [:c 3] [:b 5]} |
| 07:30 | AWizzArd | So, for sortedSETs this approach works. |
| 07:31 | AWizzArd | For a map however your comparator gets a different input |
| 07:31 | AWizzArd | you put MapEntries as input |
| 07:32 | AWizzArd | so, for the key [:f 1] you input the value [:j 6] |
| 07:32 | AWizzArd | while in reality you wanted to input :f 1 :j 6 |
| 07:32 | rrc7cz | but I thought I was doing that: #(compare (val %1) (val %2)) |
| 07:33 | rrc7cz | I call val on the MapEntry |
| 07:34 | AWizzArd | Yes. But later you compare only with keywords, such as :f |
| 07:35 | AWizzArd | let's try it with into maybe |
| 07:35 | AWizzArd | ,(into (sorted-map-by compare) {f 1 :j 6 :n 3 :w 2 :m 9}) |
| 07:35 | clojurebot | java.lang.Exception: Unable to resolve symbol: f in this context |
| 07:36 | AWizzArd | ,(into (sorted-map-by compare) {:f 1 :j 6 :n 3 :w 2 :m 9}) |
| 07:36 | clojurebot | {:f 1, :j 6, :m 9, :n 3, :w 2} |
| 07:36 | AWizzArd | rrc7cz: even when you read out the val of your MapEntry, the MapEntry will be the key in the resulting map |
| 07:37 | rrc7cz | AWizzArd: I didn't know that. That's probably what's screwing me up |
| 07:37 | AWizzArd | yes, sorted maps and sets need a very different comparator |
| 07:38 | rrc7cz | now the exception makes sense: No value supplied for key: [:m 9] |
| 07:39 | AWizzArd | yes |
| 07:39 | AWizzArd | apply splitted it into MapEntries, while you wanted "the brackets removed" |
| 07:41 | rrc7cz | then I have no idea how I can implement this, except using some hack using sorted-set-by, then building a map from the resulting MapEntries |
| 07:41 | AWizzArd | What again do you want to implement? |
| 07:41 | rrc7cz | a map sorted by its val |
| 07:41 | rrc7cz | instead of key |
| 07:42 | AWizzArd | Can you make the values the key? |
| 07:42 | AWizzArd | And btw, a sorted set could be also fine I guess. |
| 07:43 | AWizzArd | Only the requests will look a bit ugly |
| 07:43 | rrc7cz | I can't make the values a key because they are int counts. So I have many 1, 2, etc |
| 07:43 | triyo | Is there a way, using update-in or similar, to update a specific nested map in a vector thats in a map itself? {:x 1 :y [{:id 1 :name "Bob"} {:id 2 :name "Alice"}]} -> I wish to update where :id is 2 |
| 07:43 | rrc7cz | yeah |
| 07:43 | AWizzArd | rrc7cz: you could emulate a sorted Multimap |
| 07:43 | triyo | By "way" I mean a most idiomatic way. Here is my hackish attempt: http://gist.github.com/306565 |
| 07:44 | AWizzArd | rrc7cz: it won't help to first build a sorted-set and then make an ordinary map out of it, as this would destroy the order again |
| 07:45 | rrc7cz | AWizzArd: I'm just finding that out now... |
| 07:45 | rrc7cz | hmm |
| 07:45 | AWizzArd | But maybe you can have the current values (the int counts) as keys. |
| 07:45 | AWizzArd | And the value will be a set of keywords |
| 07:46 | AWizzArd | {1 #{:a :f}, 2 #{:b}, 3 #{:x :y :z}, ...} |
| 07:49 | rrc7cz | AWizzArd: that's an interesting idea |
| 07:49 | rrc7cz | they could even be a sorted set of keywords, to default to alphabetical when the counts are the same |
| 07:52 | AWizzArd | Yes A SortedMultimapSortedSet ;) |
| 07:52 | rrc7cz | I think my head just exploded |
| 07:52 | AWizzArd | Yeah, I was fighting with this in the past days for my DB project. |
| 07:52 | AWizzArd | That's why I am currently fluent in that |
| 07:52 | rrc7cz | which db proj? |
| 07:53 | rrc7cz | I'm constantly on the lookout for a couchdb replacement for my project |
| 07:54 | AWizzArd | Well, I will tell more about it in some weeks, when I publish it. An object DB for Clojure. |
| 07:54 | rrc7cz | okay. I'll keep an eye out on the mailing list |
| 07:58 | djpowell | using mutator methods that return void with cells might be a bit annoying |
| 07:59 | djpowell | are there any plans for a cell for thread safe things? |
| 08:00 | somnium | triyo: update-in works on vectors and maps, so |
| 08:00 | somnium | ,(update-in {:x [{:y 1}]} [:x 0 :y] inc) |
| 08:00 | clojurebot | {:x [{:y 2}]} |
| 08:01 | tomoj | but he needs to pick by value, not by vector index, I think |
| 08:01 | triyo | somnium: oh I see how you have index in key attr section |
| 08:01 | tomoj | (not that I have a better idea) |
| 08:01 | triyo | tomoj is right though |
| 08:01 | djpowell | cells seem pretty interesting. in clojure, it is impossible to accidentally forget synchronization; in java it is impossible to tell when you have |
| 08:02 | triyo | here is what I'm looking to prettify: http://gist.github.com/306565 |
| 08:03 | triyo | its hackish I'd say since it uses filter to drop the item first then conj to add it again |
| 08:06 | Kjellski | Hi there, anyone with a latex listings definition for clojure code? |
| 08:06 | Kjellski | ~latex |
| 08:06 | clojurebot | It's greek to me. |
| 08:07 | somnium | seems like a higher-order 'make-updater fn should be possible, but nothing elegant springs to mind (or a macro that spits out a bunch of fetch-x-by-y-when-z fns possibly) |
| 08:07 | Kjellski | ~And you don´t speak greek? |
| 08:07 | clojurebot | Titim gan éirí ort. |
| 08:08 | triyo | somnium: thx, was thinking along similar line. |
| 08:46 | rhickey | Seajure - awesome! http://seajure.technomancy.us/ |
| 08:55 | ohpauleez | haha, finally, someone did it |
| 08:56 | ohpauleez | technomancy is awesome, he deserves some sort of community award haha |
| 08:57 | ohpauleez | whoa, for sure |
| 09:03 | underdev | eerrgghh! |
| 09:03 | underdev | i am desperately trying to use clojure-test-mode |
| 09:04 | underdev | i have installed in windows, ubuntu, and ubuntu |
| 09:04 | underdev | with emacs starter kit |
| 09:04 | underdev | in all cases, i am getting this error |
| 09:04 | underdev | http://gist.github.com/306633 |
| 09:05 | underdev | i have one line, 1 set of parenthesis |
| 09:05 | underdev | I SWEAR TO GOD THEY AREN'T UNMATCHED!!!!! |
| 09:07 | ohpauleez | underdev: so frustrating |
| 09:07 | underdev | you know it |
| 09:07 | underdev | how can it possibly be that in 3 different installations, i |
| 09:08 | underdev | im getting the same error |
| 09:08 | underdev | yet it doesn't seem to be a problem anyone else is having??@? |
| 09:09 | ohpauleez | I would fire up a debugger and/or type it in piece by piece on the repl |
| 09:09 | ohpauleez | I'm not a clojure-emacs user, so I can't provide much help beyond that |
| 09:10 | underdev | yeah, im not sure how to break |
| 09:10 | underdev | (use 'clojure.test) |
| 09:10 | underdev | down any further |
| 09:10 | ohpauleez | gah! |
| 09:10 | esj | i have'd had the same error for ages |
| 09:11 | underdev | okay, thank you thank you |
| 09:11 | underdev | for just acknowledging that |
| 09:11 | underdev | it runs the tests!, and displays output after the error |
| 09:11 | esj | i've never had the stomach to figure out what is going wrong |
| 09:12 | underdev | this is a broken window i'm having a very difficult time ignoring |
| 09:13 | underdev | if it didn't slam the buffer with "you're an idiot", i guess i could tolerate it better |
| 09:14 | tomoj | underdev: elpa? |
| 09:14 | underdev | this is elpa |
| 09:14 | ohpauleez | cemerick: seriously haha, this channel is 1/3 new features 1/3 emacs and 1/3 (map vector [1 2 3] [1 2 3]) |
| 09:15 | ohpauleez | :) |
| 09:15 | cemerick | well, I've no problem with the first and last thirds |
| 09:15 | ohpauleez | me either |
| 09:15 | underdev | installed by site in 2 oses, and once cloned from technomancy's "Emacs Starter Kit" |
| 09:15 | cemerick | I don't have a problem with emacs stuff either, but it seems like having a separate channel for clojure/emacs issues would be more productive for everyone |
| 09:15 | tomoj | hmm, I don't see the error :( |
| 09:15 | ohpauleez | I don't even mind the emacs chat all that much, I just feel bad it happens so much |
| 09:16 | cemerick | ...and maybe cut down on opportunities for people to start pointless editor discussions ;-/ |
| 09:16 | jcromartie | Can we get a "project.clj not found" instead of a massive screen-filling stack trace? |
| 09:16 | cemerick | that was supposed to be ;-) |
| 09:16 | jcromartie | :) |
| 09:16 | underdev | tomoj, elpa? |
| 09:16 | tomoj | yeah |
| 09:16 | ohpauleez | now now now, who would do that :) |
| 09:16 | ohpauleez | do we have to talk about window managers again? |
| 09:16 | cemerick | oy |
| 09:16 | ohpauleez | ;) |
| 09:16 | ohpauleez | haha |
| 09:17 | cemerick | yah :-) |
| 09:17 | underdev | so this channel should be about clojure in the abstract and not clojure development in the concrete? |
| 09:17 | underdev | sorry to annoy |
| 09:17 | tomoj | underdev: what's the filename? |
| 09:17 | ohpauleez | underdev: you're totally fine, dig in. There are certainly people here that can help out |
| 09:17 | underdev | http://gist.github.com/306633 |
| 09:18 | underdev | tomoj ^^^ |
| 09:18 | tomoj | but, what's the filename |
| 09:18 | underdev | which filename (sorry) |
| 09:18 | tomoj | the file you wrote "(use 'clojure.test)" in |
| 09:19 | eevar2 | tomoj: probably the repl? |
| 09:19 | underdev | tdd.clj |
| 09:19 | tomoj | seems doubtful |
| 09:19 | jcromartie | underdev: I just got testing working for myself |
| 09:19 | tomoj | ok, tdd.clj should be fine |
| 09:19 | tomoj | you don't have any quotes or anything weird on the path? |
| 09:19 | tomoj | (the path to the file, I mean) |
| 09:19 | underdev | clojure-test-mode-1.3 from elpa is working?!? |
| 09:20 | jcromartie | underdev: oh, no I'm not using clojure-test-mode |
| 09:20 | tomoj | underdev: yeah |
| 09:20 | jcromartie | it would seem that whatever it loading up that REPL is not using the most recent clojure version |
| 09:20 | jcromartie | if it's clojure-test-mode then I would guess they are using an old clojure 1.0 or something |
| 09:20 | tomoj | wait, no |
| 09:20 | tomoj | I get the same error as you, now |
| 09:21 | jcromartie | hmm |
| 09:21 | tomoj | strange, must be some weird bug |
| 09:21 | underdev | lololol |
| 09:21 | underdev | i think so |
| 09:21 | tomoj | underdev: (ns foo.tdd (:use clojure.test)) |
| 09:21 | underdev | is that my problem |
| 09:22 | tomoj | hmm |
| 09:22 | tomoj | it seems to only happen when you don't have an ns declaration |
| 09:22 | jcromartie | underdev: I may have missed something, but are you just trying to eval (use 'clojure.test) from slime? |
| 09:23 | tomoj | strange bug |
| 09:23 | underdev | from a buffer, yes |
| 09:23 | esj | no, I have it with an ns too |
| 09:23 | tomoj | but anyway, you should have an ns declaration anyway |
| 09:23 | tomoj | hmm, when I add an ns declaration it goes away |
| 09:26 | jcromartie | seems like a bug with clojure-mode? |
| 09:26 | jcromartie | perhaps '-related |
| 09:27 | tomoj | I get the same error without ' |
| 09:27 | tomoj | just a missing ns causes it for me |
| 09:27 | tomoj | I think the bug is in swank-clojure |
| 09:28 | jcromartie | hmm |
| 09:29 | tomoj | anyway, it doesn't bother me that much :/ |
| 09:29 | tomoj | ns is a good thing |
| 09:29 | jcromartie | I can C-x C-e a (use 'clojure.test) expression |
| 09:29 | jcromartie | is that what you guys are doing? |
| 09:29 | tomoj | no, clojure-test-mode |
| 09:29 | jcromartie | oh |
| 09:29 | tomoj | C-c C-, |
| 09:29 | jcromartie | underdev said he wasn't using that |
| 09:30 | tomoj | hmm |
| 09:30 | tomoj | I only see you saying you weren't using it |
| 09:30 | tomoj | :) |
| 09:30 | underdev | YEAH! |
| 09:30 | jcromartie | oh wow, I totally read that wrong |
| 09:30 | jcromartie | :D |
| 09:30 | underdev | thank you so much |
| 09:31 | underdev | i was trying to work from d: |
| 09:31 | underdev | Linux tcltk 2.6.18-164.2.1.el5.028stab066.10 #1 SMP Sat Dec 12 18:52:53 MSK 2009 i686 |
| 09:31 | underdev | To access official Ubuntu documentation, please visit: |
| 09:31 | underdev | http://help.ubuntu.com/ |
| 09:31 | underdev | System information as of Wed Feb 17 07:03:36 EST 2010 |
| 09:31 | jcromartie | NOOOOOOOOO |
| 09:31 | underdev | System load: 0.0 Memory usage: 0% Processes: 13 |
| 09:31 | underdev | Usage of /: 3.4% of 20.00GB Swap usage: 0% Users logged in: 0 |
| 09:31 | underdev | Graph this data and manage this system at https://landscape.canonical.com/ |
| 09:31 | underdev | 11 packages can be updated. |
| 09:31 | underdev | 11 updates are security updates. |
| 09:31 | underdev | Last login: Wed Feb 17 00:26:05 2010 from cpe-98-27-227-21.neo.res.rr.com |
| 09:31 | cemerick | oh gawd |
| 09:31 | underdev | To run a command as administrator (user "root"), use "sudo <command>". |
| 09:31 | underdev | See "man sudo_root" for details. |
| 09:31 | underdev | sorry |
| 09:32 | chouser_ | shouldn't the IRC clients have this fixed by now? |
| 09:32 | underdev | i'm just so sorry |
| 09:33 | underdev | there is a tutorial on kakkaya.com that uses examples without namespaces |
| 09:33 | tomoj | maybe the bug didn't exist then, I dunno |
| 09:34 | tomoj | anything real needs to have a namespace anyway |
| 09:34 | underdev | rt |
| 09:34 | tomoj | though I guess it might be convenient to be able to C-c C-, on a temporary file |
| 09:34 | tomoj | just to screw around |
| 09:34 | underdev | rt |
| 09:34 | underdev | at least o |
| 09:34 | underdev | i'll know how to advice the next guy |
| 09:36 | underdev | or cemerick can handle it |
| 09:36 | underdev | :) |
| 09:41 | wthidden | any issues with metadata on functions in 1.2.0-master-SNAPSHOT? |
| 09:51 | underdev | as penance, i have posted a comment in his blog warning others of this problem |
| 09:52 | chouser | Huh. Blog comments in general make a lot more sense now ... I didn't realize they were penance. |
| 09:53 | underdev | in my case it is |
| 09:54 | chouser | that must be why each blog as its own incompatible and slightly broken comment markup syntax |
| 09:55 | underdev | rt, his comment system crashed firefox twice, chrome handled it though |
| 09:55 | rhickey | anyone try cells yet? |
| 09:55 | AWizzArd | They are already available?? In what branch? |
| 09:56 | AWizzArd | Some days ago chouser and I were discussing and it sounded as a feature for the distant future.. |
| 09:56 | rhickey | just a gist right now: http://gist.github.com/306174 |
| 09:56 | chouser | not yet. my use cases are all in code using 1.1 |
| 09:57 | AWizzArd | Okay, I must study them. Chris mentioned they may be usable in my DB. |
| 09:57 | stuartsierra | Someone remind me again what cells are for? |
| 09:57 | AWizzArd | Oho, they are implemented in Clojure :) |
| 09:57 | AWizzArd | Where is the Java code? ^^ |
| 09:58 | chouser | stuartsierra: new reference type |
| 09:59 | AWizzArd | Okay, do I need a specific branch to run this? When I compile I get: error: java.lang.RuntimeException: java.lang.IllegalArgumentException: Cannot assign to non-volatile: val (cells.clj:26) |
| 09:59 | rhickey | a cell is a new reference type that arbitrates the possibly multi-step/multi-threaded process of producing a new value |
| 09:59 | rhickey | encapsulates the use of transients |
| 09:59 | stuartsierra | ok, how is that different from transients? |
| 10:00 | rhickey | can bring POJOs into the sane concurrency story |
| 10:00 | chouser | transients aren't a reference type at all |
| 10:00 | stuartsierra | yes |
| 10:00 | stuartsierra | So a cell isolates an object on a single thread? |
| 10:01 | rhickey | note in the examples in the gist, String/StringBuilder are used as Value/Transient duals |
| 10:01 | rhickey | stuartsierra: there are both single thread guaranteed and multi-thread capable cells |
| 10:02 | rhickey | imagine a future (into "" some-source-of-chars) |
| 10:02 | AWizzArd | Is it okay to use the clojure.jar from build.clojure.org? |
| 10:02 | AWizzArd | To try cells? |
| 10:03 | stuartsierra | AWizzArd: I think not |
| 10:03 | chouser | hm, hadn't realized pass/fetch would be macros and support object methods. |
| 10:03 | rhickey | AWizzArd: yes, the latest build there has all you need |
| 10:03 | AWizzArd | ok, I will then try this |
| 10:04 | rhickey | chouser: I'm still playing with that. I think it's critical if we want people to put their POJOs in cells that the perf be the same. Right now it can be. But the option for .method ==> fn is still open |
| 10:05 | stuartsierra | So a cell is a mutable value locked in a thread-safe container? |
| 10:06 | rhickey | stuartsierra: the internal transient isn't a critical part of the story. They are still unique reference types in being coordinated and in serializing activity, not just data succession |
| 10:07 | rhickey | so, using a cell instead of an atom would differ in that your function would never retry |
| 10:07 | stuartsierra | Ah, so it's a means of serializing operations without the overhead of transactions? |
| 10:07 | AWizzArd | Hmm hmm, this could be interesting on a lot of levels... |
| 10:08 | rhickey | they (cells/refs) are at different points in a multidimensional space. Transactions can have arbitrary, discovered footprints, in that nested calls can enlarge the set of affected refs, whereas multithreaded cells have a fixed up-front footprint and don't support nesting |
| 10:10 | rhickey | from a completely different perspective, cells might solve the 'stream' problem (and obviate chunks). I'm working on this now |
| 10:10 | chouser | I somehow thought that the ops for converting to/from the mutable version of the value would properties of the cell itself. |
| 10:11 | rhickey | chouser: that's a to-come option. If not provided would be based on protocol |
| 10:12 | rhickey | I just haven't decided where to stick them (val/transient fns) and how to make their use fast |
| 10:12 | chouser | a protocol that would for example be extended to String? |
| 10:12 | rhickey | that protocol is in the gist right now, including extension to string |
| 10:12 | chouser | ah, I see it |
| 10:13 | cemerick | stuartsierra: same here. :-/ |
| 10:13 | stuartsierra | Is there a paper somewhere with the theory behind this? |
| 10:13 | cemerick | I was just going to suggest a assembla wiki writeup or something. |
| 10:13 | rhickey | stuartsierra, cemerick: well, I'd like to help you all understand, as I think this is very important, the missing piece of a complete model for state |
| 10:14 | stuartsierra | ok, so why would I create a cell, and what would I do with it? |
| 10:14 | chouser | have you guys looked at the previous IRC discussions? |
| 10:14 | stuartsierra | chouser: no |
| 10:14 | rhickey | stuartsierra: have you ever used a StringBuilder or transient? |
| 10:15 | metaperl | rhickey: would like write access to the wiki --- I'm bringing up a lot of points about the reference docs that need fixing and am willing to make what contribution I can |
| 10:15 | cemerick | chouser: I think I caught the first one (a few weeks ago?), but it didn't stick either. |
| 10:15 | stuartsierra | rhickey: yes |
| 10:15 | chouser | it makes the most sense to may as applied to transients ... I'm still trying to think through to understand these other possible uses. |
| 10:15 | stuartsierra | both |
| 10:15 | rhickey | stuartsierra: then you need cells |
| 10:15 | stuartsierra | ok |
| 10:15 | rhickey | cells make transients better, and potentially multithreaded. Cells make mutable things like StringBuilders safe and sane |
| 10:16 | stuartsierra | as in, safe to pass around to different functions? |
| 10:16 | rhickey | basically transients had their polict built in - cells splits it out. Once split out, the policy can be applied bot hto the transient data structures and those less, ... well less |
| 10:16 | chouser | yes! just like all reference type objects |
| 10:16 | rhickey | stuartsierra: yup |
| 10:16 | rhickey | policy |
| 10:17 | cemerick | stuartsierra: that's what I said at first |
| 10:17 | rhickey | but cells preserve a very important part of Clojure's state model, that observing an identity yields a value |
| 10:18 | rhickey | monads embed serialization in a call sequence, but in doing so thwart parallelization |
| 10:18 | rhickey | monads are essentially non-cooperative - this monad is mine, mine, all mine |
| 10:18 | stuartsierra | :) |
| 10:19 | cemerick | rhickey: but you can't have multiple threads whacking away at a cell either -- put a StringBuilder or a transient vector in one, and you'll still get garbled results, no? |
| 10:19 | stuartsierra | cemerick: That was my next question |
| 10:19 | rhickey | cells stick with the identity/state/value model. They just acknowledge, as transients did, that sometimes creating the next state is a multi-step, and now possibly multi-participant, process |
| 10:20 | rhickey | cemerick: no! multi-threads whacking works!! |
| 10:20 | rhickey | a thread cell will prevent it, and a locked-cell will make it correct |
| 10:20 | cemerick | well, works in that there's no breakage, or works in that the order of entrance into the cell is defined? |
| 10:20 | Chousuke | so, for creating a new mutable vector you could perhaps have one thread change one branch and another work on the other? |
| 10:20 | Chousuke | could that be coordinated with cells? :/ |
| 10:20 | chouser | would still be serialized in a locked-cell |
| 10:20 | stuartsierra | rhickey: So you're telling me I can make a StringBuilder, put it in a cell, append to it from multiple threads, and get a reasonable result? |
| 10:21 | rhickey | cemerick: what does it mean to define the order of independent activities? then they're not independent |
| 10:21 | cemerick | ah...so only non-sequential data structures make sense in cells? |
| 10:21 | rhickey | stuartsierra: as cemerick just said, the sequentiality of Strings might not be useful |
| 10:22 | chouser | or sequential data structures where the order doesn't matter to you. |
| 10:22 | rhickey | but it really depends on what you are doing |
| 10:22 | Chousuke | cemerick: I think the idea is that only non-sequential things make sense in a multithreaded context in the first place :) |
| 10:22 | rhickey | chouser: right |
| 10:22 | stuartsierra | ok |
| 10:22 | cemerick | ok, so we should not talk about any stringy stuff at all |
| 10:22 | rhickey | go process these web sites in parallel and ad your results to a vector - you might not care about the order in the vector |
| 10:22 | cemerick | maps, structs, sets, etc. |
| 10:23 | rhickey | cemerick: if your granularity was lines, still might work for strings |
| 10:23 | chouser | it's important to do all your << inside the >> form, if you using that to build up the value? |
| 10:23 | cemerick | yeah |
| 10:23 | cemerick | ...wonky java objects. |
| 10:23 | rhickey | chouser: inside which form? |
| 10:24 | cemerick | rhickey: so, say I'm keeping a reference to an embedded database in an agent right now, and using send-off to serialize access to it. Would putting that reference in a cell help me at all? |
| 10:24 | rhickey | cemerick: it's not just about Java objects - Clojure persistent/transient is made efficient, safe and multi-thread capable |
| 10:25 | chouser | I'm looking at the s4 example in the gist. if (<< .length ...) was done before >> and then its value used inside the >>, it would no longer be correct, right? |
| 10:25 | rhickey | cemerick: yes, it would likely be faster and the embedded DB could be a transient, only creating new values when read |
| 10:26 | rhickey | chouser: no, because you are wither single threaded or in-cells |
| 10:26 | cemerick | rhickey: why faster? Less/no thread mgmt? |
| 10:26 | stuartsierra | Going back to the identity/state/value model: the 'value' is a mutable object, the 'identity' is the cell object, yes? |
| 10:27 | rhickey | so, that's the other part of cells, multiple actions can affect the transient, even across calls, across threads, acrross multiple in-cells blocks, before a value is produced |
| 10:27 | Chousuke | cemerick: that's still open |
| 10:27 | rhickey | stuartsierra: no - values go in, and values come out. The transient is locked in the cell, an implementation detail of the birth of a new value |
| 10:27 | Chousuke | pass/fetch is the other suggested naming scheme |
| 10:27 | cemerick | hrm |
| 10:28 | rhickey | cemerick: pass/fetch are there - I encourage people to try both and give feedback from use |
| 10:28 | rhickey | cemerick: right, no thread dispatch, no message queues |
| 10:28 | cemerick | rhickey: I'm probably biased because of my string interpolation lib, but it is odd that cells get << and >>, but all other reference types have descriptive names for their "actions". |
| 10:29 | stuartsierra | So a cell is kind of a magician's box: immutable data goes in, becomes something mutable, gets bashed around, then new immutable data comes out. |
| 10:29 | rhickey | cemerick: plus, cells can be coordinated where agents can't |
| 10:29 | AWizzArd | ,(doc >>) |
| 10:29 | clojurebot | Gabh mo leithscéal? |
| 10:29 | rhickey | stuartsierra: that magician's box thing happens every time you assoc to a Clojure persistent map. |
| 10:29 | chouser | I think it's not uncommon for people to use agents and then await on the results. In such circumstances, cells should definitely be considered instead. |
| 10:29 | AWizzArd | rhickey: how to cooperate? |
| 10:30 | cemerick | oh, I totally get it now. Yeah, cells, baby! :-D |
| 10:30 | rhickey | AWizzArd: (in-cells [a b c] ...) |
| 10:30 | wthidden | so this implementation of cells is getting "similar" to Kenny Titton's cells, yes? |
| 10:30 | AWizzArd | no |
| 10:30 | AWizzArd | very different from, uhm, Tilton |
| 10:30 | chouser | rhickey: ah! ok, glossed over the in-cells. good. |
| 10:30 | cemerick | If we can get transient sorted maps and sets, then this would make me *very* happy. |
| 10:31 | AWizzArd | cemerick: yes :) |
| 10:31 | Chousuke | wthidden: http://gist.github.com/306174 this is apparently the entirety of the implementation for now :P |
| 10:31 | AWizzArd | I would be willing to "insert" in the exact correct order, if it only were faster, going around the comparator check |
| 10:31 | rhickey | wthidden: nothing to do with those kind of cells |
| 10:31 | cemerick | rhickey: yes, what sort of coordination are you referring to? |
| 10:32 | AWizzArd | cemerick: reads out of multiple cells |
| 10:32 | rhickey | AWizzArd: also modifications of multiple cells |
| 10:32 | rhickey | as part of a single unit of work |
| 10:34 | rhickey | stuartsierra: does the rationale for transients work for you? http://clojure.org/transients |
| 10:34 | AWizzArd | yes okay, now I just need to see the major difference from refs. |
| 10:34 | stuartsierra | rhickey: yes, and I've used transients successfully |
| 10:35 | AWizzArd | Like refs, but for state which is still in the process of being built? |
| 10:35 | rhickey | stuartsierra: ok, so, cells are a way to take the policy out of the transient data structure and put it in a reusable place, the cell, coupling it with work I had been doing on a lock-based reference type |
| 10:35 | Chousuke | AWizzArd: refs can't work with mutable data. |
| 10:35 | Chousuke | or rather, non-persistent data. |
| 10:35 | chouser | or other side effects. |
| 10:35 | ohpauleez | does anyone have the "Are we there yet?" video link on hand, I can't seem to google it correctly |
| 10:35 | ohpauleez | the one that shows video and slides |
| 10:35 | stuartsierra | OK. Cells are a generalization of transients. Check. |
| 10:36 | Chousuke | ohpauleez: add infoq |
| 10:36 | AWizzArd | So, Cells are closest to refs? |
| 10:36 | rhickey | stuartsierra: but they go further in adding a second policy to single-threaded - lock-based multi-threaded |
| 10:36 | chouser | AWizzArd: I wouldn't say that. They have some properties like several reference types |
| 10:36 | stuartsierra | rhickey: Ah! |
| 10:37 | rhickey | stuartsierra: they also abstract out what it means to be a value/transient dual, and, right now, expose that as a protocol |
| 10:37 | stuartsierra | So a cell does the work of wrapping access to some piece of mutable state in a lock. |
| 10:37 | rhickey | which means you can extend it to String/StringBuilder |
| 10:37 | chouser | AWizzArd: as I said, you might use a cell instead of an agent with a lot of awaits |
| 10:38 | AWizzArd | With the cell fn being executed in the calling thread |
| 10:38 | chouser | AWizzArd: right. |
| 10:38 | stuartsierra | Where in C, I would write spin_lock(x), modify(x), spin_unlock(x); in Clojure I can write (let [c (cell x)] (>> modify c)) |
| 10:38 | rhickey | stuartsierra: as much as it is a feature of cells, the support for mutability inside isn't essential. In fact, I'd thought of making the default for transient/persistent be identity, so you can use with all Clojure value types |
| 10:38 | chouser | AWizzArd: and I've been doing ugly things with atoms (doing side effects in the update fn) that would be cleaner with cells |
| 10:39 | AWizzArd | chouser: well yeah, I am currently doing something similar. I will see how and where I can apply this now. |
| 10:39 | rhickey | stuartsierra: and as chouser is highlighting, the serialization of activity is a new feature vs refs and atoms |
| 10:39 | AWizzArd | But a deeper understanding won't hurt :-) |
| 10:40 | chouser | AWizzArd: and yes, multiple cells can be coordinated like refs |
| 10:40 | stuartsierra | But the basic idea is still a value protected by a lock, right? |
| 10:40 | chouser | rhickey: Is the mutation semantic really a property of the identity? |
| 10:40 | rhickey | agents serialize activity, for a single reference. Like I said, it really is multidimensional. |
| 10:41 | rhickey | stuartsierra: there are still single-thread cells that throw on access from another thread too |
| 10:41 | chouser | stuartsierra: protected by a Sentry, which may be lock or something else |
| 10:42 | rhickey | stuartsierra: and as chouser says, the sentry abstraction is also broken out |
| 10:42 | stuartsierra | What other sorts of Sentries might there be? |
| 10:43 | chouser | hm. would there be any value in a Sentry that uses a real queue instead of just a lock? |
| 10:43 | rhickey | stuartsierra: dunno yet. Lock fairness is exposed tight now already |
| 10:43 | rhickey | right |
| 10:43 | rhickey | also, sentry usage can be hierarchical. Given a cell, you can adopt it as a parent by making a new cell with the same sentry |
| 10:44 | rhickey | thus supporting coarser-granularity locking |
| 10:45 | Chousuke | hmm |
| 10:45 | chouser | rhickey: will there never be a situation where I want a single identity to sometimes participate in-cells and other times in a dosync? Or whatever... |
| 10:45 | rhickey | I'm still amazed at how tiny this was with deftype and protocols - 4 protocols, 2 deftypes, 4 extensions, bunch of macros and factories, 150 lines |
| 10:46 | stuartsierra | Ok, some of the code makes more sense now. |
| 10:46 | rhickey | chouser: I think that would be extremely hard |
| 10:46 | rhickey | stuartsierra: yeah, obviously some docs strings are in order :) |
| 10:46 | chouser | Yeah, I'm talking more about high-level semantics and design than implementation challenges. |
| 10:46 | stuartsierra | There are 2 kinds of cells right now: ThreadCell is isolated to a single thread; LockCell uses a Java lock and supports access from multiple threads. |
| 10:46 | ohpauleez | Chousuke: thanks a ton |
| 10:46 | Chousuke | wonder if you could build a "dependency" system out of cells so that for one cell to yield a value, its parent cell must also be able to yield one. (otherwise it would block or something) |
| 10:47 | rhickey | Chousuke: that's a different notion of cells |
| 10:47 | bosie | is there a way to adjust the number of cores which arer used by agents? |
| 10:49 | chouser | heh. locks sorted by hash. :-) |
| 10:50 | rhickey | chouser: that may change |
| 10:50 | chouser | why? |
| 10:50 | clojurebot | why not? |
| 10:50 | raek | I think I'm starting to comprehend what cells are about... |
| 10:51 | raek | how is << used? |
| 10:51 | rhickey | I've never really stressed identity hash uniqueness, but a failure will be caught |
| 10:51 | bosie | i have 8 cores + 8 hyperthreaded chores. i have to use 16 agents to use my 8 physical cores which is obviously sub optimal |
| 10:51 | raek | it produces an immutable value, right? |
| 10:52 | rhickey | so, if you look at the slides here: http://wiki.jvmlangsummit.com/images/a/ab/HickeyJVMSummit2009.pdf |
| 10:52 | rhickey | slide 31 shows the epochal time model |
| 10:53 | chouser | raek: it ends up calling value-of on the "Transient" held in the cell, so yes that ought to return an immutable value. |
| 10:53 | stuartsierra | ok |
| 10:53 | rhickey | what cells do is allow the Fs (pure functions), to become Ps (processes) that have some extent. This is only possible and correct if observers not involved in the process can only obtain state values (Vs) |
| 10:53 | rhickey | cells ensure that |
| 10:54 | rhickey | and so, follow the model |
| 10:54 | rhickey | but instead of saying - pure functions but correct use of transients is ok, makes a reusable construct for processes |
| 10:55 | stuartsierra | Hmm. So a process can be bashing away at a value, and an outside observer can still see a consistent state at any time. |
| 10:55 | rhickey | so, while functional people look at that diagram and see a monad, I never did. I always imagined multiple participants/parallelism |
| 10:56 | rhickey | stuartsierra: there's no such thing as bashing at a value |
| 10:56 | rhickey | values are immutable |
| 10:56 | stuartsierra | arghhh. |
| 10:56 | stuartsierra | right |
| 10:56 | rhickey | they bash at transients, which are *unobservable* outside of the process |
| 10:57 | stuartsierra | right |
| 10:57 | rhickey | that's key, just like a transient inside the scope of a single function F would be |
| 10:57 | AWizzArd | While the fn is running all derefs in other threads will yield the value of the cell before fn started, yes? |
| 10:57 | rhickey | only now, F becomes P and can have some extent, while preserving the unobservability, and transitions of the identity from state to state |
| 10:58 | stuartsierra | So the cell expands the scope of a transient to multiple processes, ok. |
| 10:58 | Chousuke | AWizzArd: wouldn't that be decided by the sentry? |
| 10:58 | rhickey | stuartsierra: right, or across calls |
| 10:59 | Chousuke | AWizzArd: I suppose sometimes you might want a deref to block instead of returning an old value |
| 10:59 | rhickey | across calls being equally critical and useful, especially when multiple cells are involved |
| 10:59 | stuartsierra | Nuts, have to go to a meeting, back in a bit. |
| 10:59 | raek | so cells do transient-like stuff, but not limited to single functions, single threads or clojure transients? |
| 10:59 | chouser | AWizzArd: I think that depends on the type of sentry and the scope of in-cells (if that's being used) |
| 10:59 | rhickey | raek: right |
| 11:01 | chouser | rhickey: any particular reason you don't import java.util.concurrent.locks.ReentrantLock in that gist? |
| 11:01 | rhickey | AWizzArd: so, still in flux is value production. I've baked in one policy but there are several. Single thread cells produce a value on any deref. LockedCells create a value on any deref in-cells |
| 11:01 | rhickey | chouser: no |
| 11:01 | rhickey | but there could be other policies - never auto-generate values, only on request for render |
| 11:02 | rhickey | or, for locked cells, try to generate on deref but don't wait if busy |
| 11:02 | rhickey | or, always enter the process to see if there is a new value on deref |
| 11:03 | rhickey | I'm not sure if I will expose all of these. There are other composite ones like yields new value every N edits |
| 11:03 | AWizzArd | Maybe in some complex way they can be exposed, so if people really need such fine granularity it would be there. |
| 11:04 | AWizzArd | And some typical use cases for very easy use. |
| 11:04 | rhickey | some knobs will be useful, as you have very distinct scenarios - heavy writing, any interim value is good, block writing, no interim value is good |
| 11:04 | rhickey | sporadic writing |
| 11:04 | rhickey | what is true in all cases is that the last value is remembered and constitutes the observable state |
| 11:05 | rhickey | like the other refs |
| 11:05 | chouser | but when the shole cell protocol is described in 12 lines of code, I wonder how many knobs are worth including before you just tell advanced users to write their own cell. |
| 11:05 | rhickey | references |
| 11:05 | rhickey | chouser: could be, but want to avoid multiple implementations of common needs |
| 11:06 | rhickey | elevensies (tea) |
| 11:10 | raek | >> and << are just synonyms for pass and fetch now, right? |
| 11:10 | chouser | raek: yes |
| 11:16 | raek | an observation: the order of the arguments of >> is not consitent with that of alter, swap!, send etc... |
| 11:17 | raek | i.e. f - ref - args instead of ref - f - args |
| 11:18 | BrandonW | is it wrong that i actually like the enforcement of loop/recur when creating a tail recursive function? |
| 11:18 | the-kenny | BrandonW: No, I like it too |
| 11:19 | BrandonW | good |
| 11:19 | BrandonW | it just makes it seem more readable to me |
| 11:19 | BrandonW | was wondering if i was missing something... |
| 11:22 | chouser | raek: that's intentional, to keep conversion of existing persistent code to the use of cells as straight-forward as possible. |
| 11:23 | chouser | hm, I wonder if it would make sense for >> and << to keep the arg order they have now, and make pass and fetch match the other reference fn arg order. |
| 11:27 | raek | chouser: I was thinking about that too... |
| 11:29 | rhickey | chouser: yes, I'm definitely not sold on the different arg order |
| 11:34 | AWizzArd | so far Strings and StringBuilder and some Clojure collections can be edited in Cells, yes? If I want to modify different objects I have to extend on a Protocol? |
| 11:34 | chouser | that they're macros is another important difference. |
| 11:35 | rhickey | chouser: that could go away with .method fn literals |
| 11:36 | chouser | oh right, you mentioned that. That's mostly blocking on a decision about how they would support hinting? |
| 11:37 | rhickey | I think I ended up with the generated fn having a type switch for overloads |
| 11:38 | chouser | I don't know what a type switch is |
| 11:38 | rhickey | if it's a This do this, else if it's a That do that ... |
| 11:39 | rhickey | but essentially, given .AClass/aMethod, generate a single fn that could deal with any arirty or same-arirty type overloads |
| 11:40 | AWizzArd | are pass/fetch supposed to be used in user code? Or will it be << and >>? |
| 11:40 | rhickey | AWizzArd: right now, use whichever you prefer and report back |
| 11:41 | chouser | rhickey: oh, I see. I forgot about having the class in the symbol. so then a couple runtime tests would remove the need for any arg hints |
| 11:42 | rhickey | right |
| 11:42 | chouser | but I guess that might not produce a consistent return hint |
| 11:42 | rhickey | also right, but when used as a higher order fn, that's not really in play |
| 11:43 | AWizzArd | rhickey: do you think the pure Clojure implementation of Cells performs practically equally well, compared to a Java implementation? |
| 11:43 | rhickey | AWizzArd: yes |
| 11:46 | Draggor | Hey hey, so, is Programming Clojure the main book to get? |
| 11:46 | chouser | Draggor: it's the only complete book so far. |
| 11:46 | AWizzArd | Rumours say another book is currently written.. |
| 11:46 | chouser | Draggor: but some lovely options are on the way |
| 11:47 | Draggor | I've got a brithday coming up, and my programming book library is rather thin, so it's time to beef it up! |
| 11:47 | chouser | Draggor: There's one book from APress and two from Manning that have some chapters available online already. |
| 11:49 | Draggor | Oh Apress, knew that was familiar, got PCL from there |
| 11:50 | rhickey | so, today's wake-me-up-at-4am idea is - the transient dual of a seq is an iterator/stream-like thing. So, given appropriate plumbing, putting a seq in a cell will give you an allocation-free yet safe stream, convertible back to a value at any time |
| 11:51 | LauJensen | wow ... at 4am? :) |
| 11:51 | mattrepl | hmm, I thought the variants ending with * (e.g., bound-fn*) were just function variants of macros. but what of list and list*? |
| 11:51 | rhickey | LauJensen: unfortunately, that's frequently the case - I wake up working |
| 11:52 | LauJensen | Sounds a little stressful - Long walks help. Anyway, the idea sounds incredible interesting |
| 11:52 | Chousuke | mattrepl: the convention is not limited like that :) |
| 11:52 | Chousuke | mattrepl: the * just means "variant" |
| 11:53 | chouser | like x and x' ("x prime") in math. related in some unspecified way, yet different. |
| 11:54 | StartsWithK | what are << and >>? |
| 11:55 | chouser | StartsWithK: operators on cells, a new kind of reference object: http://gist.github.com/306174 |
| 12:01 | eyeris | In the definition of dotimes (or just about any other std macro), why is body deref'd but bindings is not? |
| 12:02 | chouser | that's not a deref ~@ splices a list into the output, where ~ just inserts an item |
| 12:03 | chouser | ,`(1 2 ~[:a :list] 4 5) |
| 12:03 | clojurebot | (1 2 [:a :list] 4 5) |
| 12:03 | chouser | ,`(1 2 ~@[:a :list] 4 5) |
| 12:03 | clojurebot | (1 2 :a :list 4 5) |
| 12:03 | eyeris | Oh. I see. |
| 12:04 | eyeris | ,`(1 2 ~@[:a [:x :y] :b] 4 5) |
| 12:04 | clojurebot | (1 2 :a [:x :y] :b 4 5) |
| 12:04 | eyeris | Thanks |
| 12:04 | dnolen | rhickey: so another silly mental model thing. are cells about perf at all the way transients are? using a cell to modify a string (via StringBuilder) will that be faster than modifying a string using Clojure primitives? |
| 12:06 | rhickey | dnolen: no, not about perf, but good perf. Strings can't be modified. Some string transforms could be done with stringbuilders, many not |
| 12:12 | rhickey | imamgining transient seqs: http://paste.lisp.org/display/95115 |
| 12:12 | rhickey | imagining |
| 12:13 | rhickey | so, lazy-seqx takes a recipe for a lazy seq and a recipe for a transient seq |
| 12:13 | rhickey | all seqs on data structures support transient versions |
| 12:14 | mattrepl | this is looking like great stuff for agent-based models |
| 12:15 | rhickey | then things like reduce and into can simply hoist a stream out of a lazy seq chain |
| 12:15 | rhickey | without giving up the ability to get a value at any time. And unlike the stream design, this is restartable/continuable |
| 12:17 | chouser | you're too far away to hear the sound of my head exploding |
| 12:17 | dnolen | rhickey: for some reason I had gotten the notion that << is expensive, I guess not true? |
| 12:17 | rhickey | chouser: do you see where I am going? |
| 12:17 | rhickey | dnolen: not true |
| 12:17 | dnolen | rhickey: also what you're saying ^ seems to imply that into would be cheap (unlike how it is now) |
| 12:18 | chouser | I think so. still working on "restartable" |
| 12:19 | rhickey | chouser: the only things that wouldn't be restartable, and for which you couldn't use lazy-seqx. are seqs sourced from IO |
| 12:19 | rhickey | but restartable/continuable means you could grab a val from a transient seq and then call move! on it - no problem |
| 12:19 | djpowell | rhickey: in JCIP he uses a tie-breaking lock of the identity-hashcodes are the same for two objects, and locks that, followed by the two locks in an arbitrary order. would that work for locked-cells - as a fallback |
| 12:20 | chouser | if you have a lazy-seqx obj, you can get either a seq or an Iter+Transient out of it |
| 12:20 | rhickey | chouser: right |
| 12:20 | rhickey | lazy-seqx would implement Editable in terms of a call to the latter |
| 12:21 | chouser | if you take the Iter, you can mutate it safely and at any point capture a lazy-seqx of the remainder |
| 12:21 | rhickey | so (cell a-lazy-seq) works |
| 12:21 | rhickey | the Iters are always in cells |
| 12:22 | rhickey | you can't directly touch them |
| 12:22 | rhickey | This solves the long-standing problems of iterators - you can't safely share them, and can't get values out of them |
| 12:23 | chouser | the second expr in that lazy-seqx example is returning an Iter+Transient, but you're saying when I can't get that directly -- the lazy-seqx object would give me a cell of it instead (not collc but another cell)? |
| 12:23 | chouser | s/when/that/ |
| 12:24 | rhickey | when you said (cell lazy-seqx), that calls transient-of on it, which is implemented by it in terms of a call to the second expr |
| 12:24 | rhickey | leaving you with that iter in the cell |
| 12:25 | chouser | ok. then I can fetch the Iter and move! it? |
| 12:25 | rhickey | calling transient-of directly is a no no |
| 12:25 | rhickey | chouser: use the iter through the cell |
| 12:25 | chouser | pass not fetch |
| 12:25 | rhickey | you can't get it out of the cell |
| 12:26 | jlilly | (-> world (nth x) (nth y)) ~= ((nth (nth world))) ? |
| 12:26 | rhickey | pass move!, fetch current |
| 12:26 | jlilly | err. with the right number of parens, that is. |
| 12:26 | chouser | jlilly: (nth (nth world x) y) |
| 12:27 | jlilly | chouser: ahh. that makes much more sense. and is apparent now that I reread the docs. thx. |
| 12:28 | chouser | rhickey: and @(cell lazy-seqx) gets me a regular sequence |
| 12:28 | rhickey | right |
| 12:29 | rhickey | even after having move!d it a few times, and ok to move! it afterwards |
| 12:30 | chouser | right! and the cost of inserting a deref into that process is just a couple allocs. |
| 12:30 | rhickey | right |
| 12:30 | rhickey | but it means a chain of map filter blah blah turns into a single value-producing factory |
| 12:30 | chouser | though walking the seq and the seqx would each compute each new value |
| 12:31 | rhickey | while in the cell |
| 12:31 | rhickey | chouser: yes, but no [lazy]-seq nodes |
| 12:31 | rhickey | i.e. the fns produce values, but have to |
| 12:31 | chouser | lazy-seq nodes for the seq, but not for the seqx |
| 12:32 | djpowell | you can use .method in your fetch/pass call, but usually in Java mutators return void - would calling mutators want any special support? |
| 12:32 | somnium | very ot, but is there a convention for 'partial-ear-muffs', like choosing *foo vs. foo*? |
| 12:32 | rhickey | once you've put the lazy-seqx in a cell, there is no allocation other than that done be the work itself (e.g. map call (f x)) |
| 12:33 | rhickey | djpowell: possibly. The first use case - StringBuilder, happened to return the object |
| 12:33 | chouser | ok, but that's an unusual case anyway. perfectly safe and hardly any more expensive than pre-chunk seqs. Most of the time a seq chain is used once. |
| 12:33 | rhickey | chouser: much less overhead than pre or post chunk seqs |
| 12:34 | tomoj | somnium: the only time I've seen that is for foo* as a helper to foo |
| 12:34 | chouser | I meant walking the same lazy-seqx from two different places, one as a seqx the other as a seq. Rare but still safe. |
| 12:35 | rhickey | chouser: oh, yes, the realized/lazy seq has same overhead as always |
| 12:35 | chouser | that is, rare and each value gets computed twice (once for the seq and once for the seqx), but not terrible perf and a reasonable cost for the safety |
| 12:36 | rhickey | but the critical thing here is that you can start with a bunch of normal lazy-looking calls in a chain, only to have the end consumer know they will slurp in in one go - they put it in a cell and bam - the seq is completely virtual |
| 12:36 | rhickey | or reduce or int do that for them |
| 12:36 | rhickey | into |
| 12:37 | chouser | right. and a chain that includes links that *don't* use lazy-seqx will still use the cell for the spans of the chain that support it, right? |
| 12:37 | rhickey | so, this dimension of cells is also quite important, IMO |
| 12:38 | chouser | hm, just the final span I guess. |
| 12:38 | rhickey | chouser: well, lazy-seqx is for computed seqs, but all of the concrete seqs will support editable. If a chain has non-Iter nodes then move! will fail |
| 12:39 | rhickey | it's a good question |
| 12:39 | chouser | (->> big-vector (map f) (filter g) (partition 2) (map h) (filter i)) |
| 12:40 | rhickey | yes, put that in a cell and the whole calculation is virtual, no cons cells |
| 12:40 | chouser | Right. But in instead we assume map and filter support lazy-seqx, but partition does not ... |
| 12:40 | chouser | s/in/if/ |
| 12:41 | rhickey | I understand |
| 12:41 | rhickey | IO seqs the most likely problems |
| 12:42 | chouser | bah, screwed it up |
| 12:42 | chouser | (->> big-vector (map f) (filter g) (partition 2) (map h) (filter i) (into [])) |
| 12:42 | chouser | there. so if into also supports lazy-seqx... |
| 12:42 | rhickey | for ordinary seqs, move! == next |
| 12:43 | chouser | does the whole chain go lazy-seq, or can into drive a cell for map h and filter i, while pulling lazy-seqs from map f, filter g, and partition? |
| 12:43 | rhickey | there is nothing about cells that demands the implementation be mutating |
| 12:43 | rhickey | so, ordinary lazy-seq implements Iter where current == irst and move! == next |
| 12:43 | rhickey | first |
| 12:44 | rhickey | value-of == this |
| 12:44 | rhickey | done |
| 12:45 | chouser | but filter i will returh a lazy-seqx, right? and into would use the cell version of that? |
| 12:45 | rhickey | oops, transient-of == seq. Now done |
| 12:46 | rhickey | (cell an-ordinary-lazy-seq) will work if ordinary lazy seqs, in the absence of a high-performing mutating impl, have a simple impl of Editable/Transient/Iter as above |
| 12:47 | rhickey | current/first, move!/next, transient-of/seq, value-of/this |
| 12:48 | rhickey | because cells capture return values, they work fine with values |
| 12:48 | chouser | ok, I'm not getting this detail, but I see how normal usages will always be compatible and sometimes be alloc-free. very cool. |
| 12:48 | rhickey | and pure fns |
| 12:49 | chouser | much easier to support than chunks as well, for individual seq library fns. |
| 12:50 | rhickey | right. I'd still like to make that second expr more succinct |
| 12:50 | rhickey | but with the above recipe for compatibility, people could add more efficient transient support as needed |
| 12:51 | rhickey | i.e. lazy-seq looks exactly as it does now and support Iter/Editable as I've described, with no client help |
| 12:51 | ordnungswidrig | aloha |
| 12:51 | rhickey | swithc to lazy-seqx (or whatever it is called), provide an Iter impl, and you're off to the races |
| 12:53 | rhickey | lazy-seq-iter? |
| 12:54 | chouser | heh. better than lazy-seqx. :-) |
| 12:55 | jlilly | http://pastie.org/private/hp1lhudpqpfjozqjlb7cq -- any chance someone can walk me through line 7 of this? Having a hard time with all the alters and assocs. |
| 12:56 | jlilly | or perhaps there's a better explanation of assoc / alter than (doc) ? |
| 12:57 | arkrost | Hi! Tell me please what difference between let and let*. |
| 12:57 | Chousuke | jlilly: it takes the value of p, and alters it by associng a value to the key :ant |
| 12:57 | chouser | arkrost: let* is an implementation detail. ignore it. |
| 12:58 | Chousuke | arkrost: if you're looking at a macroexpansion, just treat let* as let |
| 12:58 | chouser | arkrost: if you're looking at macroexpand output, try macroexpand-1 instead -- might be clearer. |
| 12:58 | Chousuke | except that it doesn't support destructuring |
| 12:58 | jlilly | assoc :ant p is basically an equivalent of mymap['p'] = new_p ? (for other languages) |
| 12:59 | Chousuke | jlilly: assoc takes the map first. |
| 12:59 | Chousuke | jlilly: but in this case, because it's used with alter, it's *alter* that passes it the map, behind the scenes |
| 13:00 | Chousuke | eg: (assoc {:a 1} :b 2) -> {:a 1 :b 2} |
| 13:01 | Chousuke | but (def p (ref {:a 1})), (dosync (alter p assoc :b 2)), @p -> {:a 1 :b 2} |
| 13:03 | jlilly | so just to get all of my noob questions answered.. |
| 13:03 | Chousuke | jlilly: in most languages there's no direct equivalent for this |
| 13:03 | Chousuke | jlilly: since they don't separate values from identities |
| 13:03 | jlilly | @p is really saying "Get me the value of the ref (ref being an indirect pointer to some data) p" right? |
| 13:03 | Chousuke | yes. |
| 13:04 | jlilly | and because that was in a dosync, and we altered p, p's new value should be {:a 1 :b 2} when we finish. right? |
| 13:04 | Chousuke | yes |
| 13:04 | jlilly | or, assuming someone else updates the datastructure out from under us, we'll at least know that p has :b 2 in it, b/c that's what our operation does. right? |
| 13:05 | jlilly | my interpretation of what happens is that it tries to alter the structure, fails, is told to retry, then it runs again on the updated datastructure? |
| 13:05 | Chousuke | at commit, yes. of course, someone might independently update it after the transaction has finished and right before you read it |
| 13:06 | Chousuke | something like that happens, but it's just the implementation. the semantics are more important than what it actually does :) |
| 13:06 | jlilly | I'm basing nearly all of my knowledge here on ants.clj and the "clojure for java programmers" talk, despite not being a java programmer. |
| 13:06 | jlilly | :-P |
| 13:07 | Chousuke | heh |
| 13:07 | jlilly | I'm assuming that ants.clj is a solid reference for this stuff? |
| 13:07 | jlilly | or at least well written enough to based style and practices from? |
| 13:07 | stuartsierra | ants.clj is old |
| 13:07 | Chousuke | I think it should be okay, but it's a bit dated in style. |
| 13:08 | jlilly | is there better example code? |
| 13:08 | Chousuke | for refs and such it's still valid. they haven't changed. |
| 13:15 | bosie | Chousuke: but for the agents? |
| 13:16 | Chousuke | probably :P |
| 13:17 | bosie | i am a bit confused with most of the concurrent programming articles in clojure. isn't refs nothing more than a mutable object? |
| 13:17 | bosie | to run it on multiple cores i always need agents, no? |
| 13:17 | Chousuke | no |
| 13:18 | Chousuke | you can use threads to run functions on multiple threads :P |
| 13:18 | bosie | you mean the java class Thread? |
| 13:18 | Chousuke | yeah. |
| 13:19 | Chousuke | ,(do (.start (Thread. #(do (sleep 1) (println 'foo)))) (println "bar")) |
| 13:19 | clojurebot | java.lang.Exception: Unable to resolve symbol: sleep in this context |
| 13:19 | Chousuke | eh |
| 13:19 | Chousuke | ,(do (.start (Thread. #(do (Thread/Sleep 1000) (println 'foo)))) (println "bar")) |
| 13:19 | clojurebot | java.lang.IllegalArgumentException: No matching method: Sleep |
| 13:19 | Chousuke | :( |
| 13:20 | Chousuke | oh well, something like that anyway |
| 13:20 | stuartsierra | ,(do (.start (Thread. #(do (Thread/sleep 1000) (println 'foo)))) (println "bar")) |
| 13:20 | clojurebot | bar |
| 13:20 | bosie | Thread/sleep |
| 13:20 | bosie | ye |
| 13:20 | Chousuke | hm, I guess the thing in the other thread got printed somewhere else :D |
| 13:20 | stuartsierra | yep |
| 13:21 | Chousuke | anyway, the thing is that refs are mutable boxes with well-defined concurrency semantics |
| 13:23 | Chousuke | whereas concurrently reading/writing regular mutable variables in a common language usually results in undefined behaviour |
| 13:23 | Chousuke | which is why you need locks |
| 13:27 | rhickey | live notes around cells, not docs! http://www.assembla.com/wiki/show/clojure/Cells |
| 13:27 | ben_m | Greetings! :) |
| 13:29 | ben_m | In Clojure, what would be the best way to concurrently run some functions and then, after they're all done, return a list with the results? |
| 13:29 | Licenser | is there a document about this cell stuff aka what it is suposed to do in the future? |
| 13:30 | rhickey | ben_m: pmap or pvalues |
| 13:31 | ben_m | Thanks! :) |
| 13:31 | _fogus_ | Licenser: Chapter 8 of "The Joy of Clojure" ;-) |
| 13:31 | Licenser | Now I may sound stupid but what is "The Joy of Clojure?" |
| 13:33 | Licenser | ah cells seem to be a way to encapsulate mutable objects in a imutable hull when I get the notes from rhickey right |
| 13:41 | BrandonW | is there some information posted somewhere on this talk of cells lately? |
| 13:41 | BrandonW | it sounds very interesting |
| 13:41 | rhickey | BrandonW: logs here: http://clojure-log.n01se.net/ |
| 13:42 | BrandonW | thanks |
| 13:42 | ordnungswidrig | was there an agreement on the naming around cells? I left the conversation early the other day |
| 13:48 | BrandonW | wow that does sound useful |
| 13:49 | rhickey | ordnungswidrig: current best names in use now, all subject to change |
| 13:49 | BrandonW | i was just thinking today what the best way to wrap something like the java commons http client |
| 13:50 | BrandonW | if you could put that in a cell and operate on it (and any cookie containers and others objects that would get potentially altered by each use of the client) in a thread-agnostic way |
| 13:50 | BrandonW | jakarta* |
| 13:51 | BrandonW | although that might be better served with an existing threading mechanism |
| 13:51 | ben_m | I hate ELPA, it makes my .emacs messy :( |
| 14:03 | ordnungswidrig | oh, nice. |
| 14:04 | ben_m | Anyone using clojure with slime without using ELPA? If yes, could I see your .emacs? |
| 14:04 | technomancy | ben_m: if your .emacs is messier with Emacs than without, you're probably confused about how to set it up. |
| 14:05 | ben_m | Might be true |
| 14:05 | technomancy | because it should be one or two lines |
| 14:06 | ben_m | When I last tried it I had to do a lot of config in my .emacs to get stuff to work after I started using ELPA |
| 14:06 | ben_m | So I got rid of it |
| 14:08 | maxhodak | hey -- i need some help debugging this: http://github.com/franzinc/agraph-java-client/blob/agraph32/clojure/src/com/franz/util.clj |
| 14:09 | maxhodak | basically what they're doing is using (declare) and then referencing a variable (*with-open-stack*) before it gets bound, leading to fail |
| 14:09 | maxhodak | and i can't figure out the right way to solve it |
| 14:10 | maxhodak | L29 and L49 are the most interesting |
| 14:11 | maxhodak | i've already changed contrib.stacktrace to clojure.stacktrace |
| 14:11 | rhickey | maxhodak: they document you're not supposed to use those outside the scope of with-open |
| 14:12 | rhickey | maxhodak: with-open2 binds *with-open-stack* |
| 14:14 | maxhodak | rhickey: hmm, let me find where this is called; it's deep enough inside their logic i'd be surprised if the with-open was needed all the way up |
| 14:15 | maxhodak | http://github.com/franzinc/agraph-java-client/blob/agraph32/clojure/src/com/franz/agraph.clj#L28 |
| 14:15 | maxhodak | so i call agraph-repoconn on L37 |
| 14:16 | maxhodak | do i need with-open outside of my invocation of that? |
| 14:19 | Chousuke | maxhodak: seems like anything that calls open needs to be within a with-open2 context |
| 14:21 | Chousuke | maxhodak: and that means dynamic scope, so anything that might call open in any way to be wrapped in with-open2 :P |
| 14:21 | Chousuke | +needs |
| 14:22 | maxhodak | Chousuke: ok, thanks, i'll try that |
| 14:22 | maxhodak | rhickey: thanks for pointing out "read the obvious doc" too |
| 14:22 | Chousuke | maxhodak: looks like you can use the scope* functions too |
| 14:23 | Chousuke | or macros :P |
| 14:25 | lancepantz | clojure-yaml/clojure-build.xml:86: Could not find clojure.lang.Compile. Make sure you have it in your classpath <----- looking for clojure.jar in my classpath, right? |
| 14:27 | lancepantz | because clojure.jar is indeed in my classpath |
| 14:27 | lancepantz | i have no clue what is throwing that error |
| 14:33 | chouser | Huh. From twitter: "Moving from #clojure to #scala, watching as the entire software community passes me going in the opposite direction." |
| 14:34 | Chousuke | heh |
| 14:34 | rhickey | chouser: I saw that - funny |
| 14:34 | ben_m | Scala is interesting |
| 14:35 | ben_m | But it's not a Lisp :D |
| 14:35 | chouser | lancepantz: I've not seen a stack trace pointing at a line in an xml file before. Is that maven or ant or something? |
| 14:35 | lancepantz | ant |
| 14:35 | lancepantz | which i'm new and unfamiliar with /idiot disclaimer |
| 14:37 | rhickey | names again - Iter interface: has-item, item, move! ? |
| 14:38 | rhickey | I don't like has-item |
| 14:39 | chouser | has-item is the complement of empty? |
| 14:39 | rhickey | kinda |
| 14:39 | lancepantz | so no one can make sense of that ant error? because otherwise i'm going to have to use jyaml :/ |
| 14:39 | lancepantz | and i really don't like java :) |
| 14:40 | Chousuke | lancepantz: maybe you need to pass ant some parameter that tells it where clojure.jar is :/ |
| 14:40 | Chousuke | for contrib it used to be ant -Dclojure.jar=/some/path |
| 14:40 | lancepantz | cool, let me try it |
| 14:41 | Chousuke | lancepantz: take a look at the build file and see if it has something like ${clojure.jar} or whatever |
| 14:41 | rhickey | chouser: the protocol is (when (<< has-item cc) (use-it (<< item cc)) (>> move! cc)) |
| 14:42 | jlilly | sanity check, is #(..) shorthand for defining a macro on the fly? |
| 14:42 | rhickey | one benefit of has-item is it keys you into the fact that you (must) call it before item |
| 14:43 | Chousuke | jlilly: no, a function |
| 14:43 | jlilly | got it. thx. |
| 14:43 | chouser | so has-item/item/move! are used very roughly where one would ahve used seq/first/next |
| 14:44 | rhickey | right, except the return of has-item isn't useful except in a conditional |
| 14:44 | jlilly | Chousuke, and % represents the the args to the function? |
| 14:44 | Chousuke | jlilly: the first arg |
| 14:44 | Chousuke | jlilly: %n represents the nth arg |
| 14:44 | chouser | sure |
| 14:44 | Chousuke | % is short for %1 :) |
| 14:48 | Chousuke | (when (fetch permit cc) (f (fetch item cc)) (pass move! cc)) :P |
| 14:50 | jlilly | Chousuke, so I don't have to keep bothering you, is there a place that lists all of these # syntax things? I think I've come across #( #' and now #^ |
| 14:50 | Chousuke | clojure.org/reader does I think |
| 14:50 | jlilly | rokk |
| 14:57 | ben_m | When editing Clojure code with paredit and I'm typing a closing ], it jumps to the end of the expression. Can I disable that somehow? |
| 14:57 | Chousuke | isn't that what it's supposed to do? :/ |
| 14:58 | ben_m | (defn foo [n]), after pressing ] it jumps to the ), so I have to move the point back a character before I can write the rest of the defn |
| 14:58 | ben_m | point being at n |
| 14:59 | Chousuke | I think I should fix my paredit. it doesn't work properly in slime. |
| 14:59 | Chousuke | ben_m: works for me. :/ |
| 14:59 | ben_m | :/ |
| 15:00 | ben_m | Maybe my paredit version is old |
| 15:00 | morphling | ben_m: you can move out of [] by typing ), regarding your question: you can find out what ) is bound to and bind ] to the same |
| 15:00 | ben_m | ] and ) do the same thing for me |
| 15:00 | ben_m | But they're bound to different functions |
| 15:01 | chouser | if a sequence isn't made up of items, perhaps it's made up of steps? |
| 15:02 | chouser | step, do-step!, steps-done? :-/ |
| 15:02 | morphling | ben_m: ah, ok, then I have no idea |
| 15:03 | Chousuke | chouser: I think it would have to be steps-left? |
| 15:03 | chouser | ah, better. |
| 15:04 | Chousuke | but "step" is a common local name already ;/ |
| 15:05 | chouser | step isn't right anyway. There is an action involved, and make next-step would work, but item is supposed to return the result of the pervious step, not the action itself. |
| 15:05 | rhickey | chouser: it has to be really clear which order to call. Both Java and .Net collapse these into 2-method protocols in order to avoid mistakes, and still added foreach. But we can't combine like hasNext/next of Iterator since next needs to return the item and move, but we need to capture the moved iter |
| 15:06 | chouser | Java's .next() freaks me out. |
| 15:06 | rhickey | the first cut I showed had move! potentially returning nil when done, but was eager, and longer than the 3-method impl |
| 15:07 | Chousuke | how about the "permit" name I suggested? :P |
| 15:07 | chouser | the counter arithmetic in gvec's ListIterator implementation seems almost completely arbitrary to me. |
| 15:07 | rhickey | chouser: it has one benefit which is you can only call it once. current usually means having to cache. I don't intend to, so multiple calls to current/item mean multiple calls to work |
| 15:07 | chouser | hm, so it is like redoing the current step |
| 15:08 | rhickey | Chousuke: permit doesn't work for me |
| 15:08 | rhickey | chouser: yeah, although I'm not keen on step. These will operate over plain data also |
| 15:09 | chouser | sure, but are still logical sequences. |
| 15:09 | chouser | I don't like 'step' either, just trying to get ideas flowing. |
| 15:09 | rhickey | yes, but step implies 'job/work' to me |
| 15:09 | chouser | item is so generic |
| 15:10 | rhickey | yes, item is, but it is just data. first still works, sort of |
| 15:15 | technomancy | oh nice, metadata on fns landed. |
| 15:15 | technomancy | this pleases me. =) |
| 15:43 | stuartsierra | Am I correct in thinking that any class that will be stored in a cell must extend Editable and Transient? |
| 15:44 | rhickey | stuartsierra: there might be per-cell options to specify to-transient and to-value functions, otherwise yes |
| 15:45 | stuartsierra | ok |
| 15:49 | stuartsierra | So: one reasonable use case: I create a date/time datatype, extending transient-of to return a java.util.Calendar. Then extend value-of on Calendar to return my date/type type. Then I can put a Calendar in a cell and roll it, but get a reasonable value back out. |
| 15:51 | rhickey | stuartsierra: you would put the value in, and the cell would call transient-of/value-of as needed. But yes, values in and out |
| 15:53 | stuartsierra | right |
| 15:54 | stuartsierra | In that case, what benefit does the cell give me? |
| 15:54 | cemerick | rhickey: caught up on logs, I'd say I grok the important bits. Stellar stuff. |
| 15:56 | chouser | seems like it may be reasonable to put a mutable thing in a cell in an agent, when you might now just put the mutable thing in the agent and try to remember to never mutate directly. |
| 15:56 | rhickey | stuartsierra: well, a cell gives you identity (as do all ref types), so if that data was a 'due date' or something that might be associated with different values over time, the same benefits would apply. Processing a date functionally is pretty cheap so no real benefit to the transience. But changes to the date could be coordinated (like refs), and activity serialized |
| 15:56 | rhickey | also if you pass it around you will get thread safety checks |
| 15:57 | rhickey | unlike a raw Calendar |
| 15:57 | stuartsierra | Right, so I'm protected from mutating it from multiple threads. |
| 15:57 | rhickey | yes, if you want to be. or coordinated across threads if desired |
| 15:58 | stuartsierra | So a cell is most useful in the case when realizing a persistent value could be expensive. |
| 15:58 | rhickey | i.e. if any logged in user's thread could change the due date |
| 15:58 | ben_m | How do I specify a -D argument when starting clojure in Emacs? |
| 15:59 | stuartsierra | ben_m: use a shell script |
| 15:59 | rhickey | stuartsierra: I'm not going to let cells be pigeonholed like that. There are a number of use cases related to the serialization of activity that still apply even if the contents are pure values (which will be possible) |
| 15:59 | chouser | (send agt #(>> set! (.field %) val)) |
| 15:59 | rhickey | also see recent conversation about transient seqs based on cells |
| 16:00 | stuartsierra | yeah, those left me even more confused. |
| 16:00 | rhickey | hrm |
| 16:00 | stuartsierra | So: cell guarantees transition going in (transient-of) and transition coming out (value-of) |
| 16:01 | rhickey | yes, but you could use with Clojure data values by supplying identity for both. It's not just about transience |
| 16:01 | stuartsierra | ok |
| 16:02 | rhickey | people sometimes need once-and-once only activity coordinated with data change |
| 16:02 | stuartsierra | More importantly, it guarantees that all operations on the thing inside the cell will be mediated by >> |
| 16:02 | chouser | set! was a bad example -- I was thinking something that took some work thus useful to do in another thread. |
| 16:02 | Chousuke | Was the idea that you could specify two ways of generating a seq: a persistent and a transient one; then a function which knows it's going to consume the entire seq will request the transient version? |
| 16:02 | rhickey | chouser: not sure of the benefits over (future (>> foo! acell)) |
| 16:03 | chouser | oh, good point. |
| 16:03 | rhickey | given the cell must be lock-based for any thread pool access to work |
| 16:04 | rhickey | I wonder if a shorthand for (in-cells [c] (>> foo! c)) is in order |
| 16:04 | chouser | yeah, I hadn't thought of using future there. cell instead of agent+await. future+cell instead of agent |
| 16:05 | rhickey | the diff with latter being a defined order on sends from same threads |
| 16:06 | rhickey | agent+await should die |
| 16:06 | rhickey | almost always a bad design that's avoiding latches or queues |
| 16:07 | rhickey | (pass-in foo! c) ? |
| 16:11 | chouser | (in>> foo! c) ? :-P |
| 16:18 | powr-toc | Just watching Rich's awesome lecture on clojure's philosophy for time management (again)... And I'm wondering where these ideas on the seperation of identity, state, values and time come from... Are there any other languages that share these notions, or is clojure unique? |
| 16:18 | powr-toc | if so are there any references (beyond whitehead etc...) to this? |
| 16:21 | chouser | man, it *so* frustrating to get stack traces that include a line inside a try-block that was somehow never caught |
| 16:21 | Chousuke | there is at least one language where time is a fundamental type. Processing only occurs if you advance time. |
| 16:22 | powr-toc | Chousuke: do you have a reference/ |
| 16:22 | powr-toc | ? |
| 16:22 | chouser | I've seen this before, and it hurts every time. Sometimes it's a wrapped exception thing, but right now I have (catch Throwable e ...) and it's still not catching |
| 16:22 | Chousuke | powr-toc: I think it was this one http://chuck.cs.princeton.edu/doc/language/ |
| 16:23 | hiredman | chouser: maybe a lazy thing, or a delay of some kind |
| 16:24 | hiredman | macro re-arranging something? |
| 16:24 | hiredman | line numbers could be lies |
| 16:24 | powr-toc | Chousuke: cheers... what about Rich's critique of OO's confused mix of identity, state and time? Are there any papers or other work mentioning this? |
| 16:25 | Chousuke | I'm not aware of any |
| 16:25 | chouser | hiredman: those are all good thoughts, but I don't think any of them apply here. |
| 16:27 | hiredman | println time |
| 16:27 | technomancy | debug-repl! |
| 16:27 | chouser | I'm catching it successfully at an outer level, where it claims to be a java.lang.IllegalArgumentException |
| 16:27 | hiredman | println at the top of the try and at the bottom |
| 16:27 | Chousuke | your catch form has illegal arguments! :P |
| 16:27 | chouser | Chousuke: :-P no it doesn't |
| 16:28 | Chousuke | (or the try form) |
| 16:28 | Chousuke | I wonder what happens if you do (try foo (catch ...) blah) |
| 16:28 | underdev | powr-toc: the notions of time/state/identity seem to me more along the lines of kant vs hume than identity |
| 16:29 | underdev | whiteheads notion of identity, state, and time would be very different |
| 16:29 | chouser | oh, no I'm successfully catching in an *inner* scope.. dang it. my tests have been faulty |
| 16:29 | chouser | Chousuke: compile error I think |
| 16:30 | chouser | ,#(try 0 (finally 1) 2) |
| 16:30 | clojurebot | chouser: I don't understand. |
| 16:30 | chouser | , #(try 0 (finally 1) 2) |
| 16:30 | clojurebot | chouser: It's greek to me. |
| 16:30 | underdev | ie higher order actual occasions would have intrinsic identity, with state changing due to prehensions, with time created to accomodate the change in state |
| 16:30 | chouser | ,(fn [] (try 0 (finally 1) 2)) |
| 16:30 | clojurebot | chouser: It's greek to me. |
| 16:30 | powr-toc | underdev: Thanks I might well check that out :-)... but I'm wondering if there is an argument similar to Rich's in cs literature anywhere. |
| 16:30 | hiredman | clojurebot ignores try's |
| 16:31 | chouser | hmph |
| 16:32 | chouser | might proxy eat an exception? |
| 16:33 | hiredman | pircbot tends to eat exceptions |
| 16:33 | hiredman | chouser: what do you mean? |
| 16:33 | hiredman | methods on a proxy object, inside methods? |
| 16:34 | chouser | wait... |
| 16:36 | chouser | ok, there are a few extra layers of proxy and macro involved here than I was thinking. |
| 16:36 | chouser | why do I create such complicated things!? |
| 16:37 | hiredman | you are driven by a faustian bargain with management |
| 16:39 | chouser | I can't blame management -- they leave me alone here, to create my own hell... |
| 16:40 | somnium | yay freedom |
| 16:40 | Chousuke | at least it's a hell written in clojure |
| 16:40 | chouser | Chousuke: yes! |
| 16:41 | chouser | But that means I can't blame management *or* the language. Which leaves ... |
| 16:41 | chouser | ... google protobuf! *whew* that was close. |
| 16:43 | jasapp | chouser: how did you convince management to let you write in clojure? |
| 16:44 | chouser | they are enlightened :-) |
| 16:44 | hiredman | depending which faust you read that could work |
| 16:44 | jasapp | nice, I'm jealous |
| 16:44 | chouser | it's mostly meant as "prototype" code. We'll see if it stays that way. :-) |
| 16:45 | chouser | we're hiring! |
| 16:45 | jasapp | working from home ok? |
| 16:46 | ben_m | I'd relocate for a Clojure job |
| 16:46 | ben_m | heh |
| 16:46 | chouser | http://www.sentryds.com/company/employment/ |
| 16:47 | jasapp | I would, but my wife wouldn't |
| 16:47 | jasapp | guess she'd just have to deal with it |
| 16:47 | ben_m | tell her it's clojure |
| 16:47 | ben_m | She'll understand |
| 16:47 | eyeris | Is the complexity of expanding -> linear or better? |
| 16:47 | chouser | Many of us work from home. Some of us write in Clojure. |
| 16:47 | chouser | eyeris: -> is all at compile time -- no runtime cost |
| 16:48 | powr-toc | chouser: looks like an interesting company |
| 16:48 | eyeris | chouser: Right. I have a program that could be written as one huge -> macro with 1000+ forms. |
| 16:48 | hiredman | :( |
| 16:48 | eyeris | Would it take forever and a day to compile? |
| 16:48 | chouser | ha! I have no idea |
| 16:48 | ben_m | "4 year undergrad degree or higher" |
| 16:48 | ben_m | Meh :( |
| 16:48 | Chousuke | eyeris: I think you wouldn't even notice the difference :/ |
| 16:48 | hiredman | the compiler expands macros recursively (not iteratively) |
| 16:50 | stuartsierra | got to get my resume together |
| 16:50 | hamza | gents, is there a way to check if calling deref on a future object will block or not? |
| 16:50 | Chousuke | future-done? I think |
| 16:51 | hamza | ,(doc future-done? |
| 16:51 | clojurebot | EOF while reading |
| 16:51 | hamza | ,(doc future-done?) |
| 16:51 | clojurebot | "([f]); Returns true if future f is done" |
| 16:52 | hiredman | man, github fails horribly at displaying Compiler.java |
| 16:52 | hamza | Chousuke: thanks a lot, hate it when functions have obvious names :) |
| 16:52 | hiredman | I guess it could be firefox fails at displaying github displaying Compiler.java |
| 16:54 | Apage43 | i'd tell you how IE6 handles it but I don't think it'd be worthwhile to know |
| 16:54 | stuartsierra | So I was thinking about rewriting clojure.test yesterday. |
| 16:54 | stuartsierra | But I don't know if it's worth the trouble. |
| 16:56 | chouser | stuartsierra: what would you do to it? |
| 16:56 | stuartsierra | Redesign around first-class objects. |
| 16:56 | stuartsierra | I.e., a Test is a collection of Assertions. |
| 16:57 | eyeris | Indeed, hiredman, a ->> macro with 1000+ forms results in a stack overflow :( |
| 16:57 | eyeris | Darn |
| 16:57 | stuartsierra | a Test runs in one or more Contexts |
| 16:57 | stuartsierra | Contexts are nested hierarchically.. |
| 16:58 | stuartsierra | Running a set of tests produces a sequence of TestResults |
| 16:59 | technomancy | I like the idea of more separation between assertions and the setup they require. the intermixing of these is probably the greatest hindrance to test readability in my experience. |
| 16:59 | stuartsierra | yes, that was the big idea |
| 17:00 | stuartsierra | Writing tests as fns is easy, but mixes assertions with setup/teardown. |
| 17:00 | stuartsierra | That's one thing that object-oriented test frameworks actually do better. |
| 17:00 | powr-toc | Is there an explanation of what Cells are yet... I saw the discussion on this channel about them, but would like to understand more about them |
| 17:01 | chouser | powr-toc: your most complete and accurate info will be IRC for a while. They're too much in flux to warrant real docs yet. |
| 17:01 | chouser | powr-toc: there is the implementation and "notes" links -- you saw those? |
| 17:02 | powr-toc | chouser: no, I don't think I did... Are they on assembla? |
| 17:02 | chouser | powr-toc: src/java/com/sentryds/qdc/rpc/clojure.clj |
| 17:02 | chouser | er |
| 17:02 | chouser | not that |
| 17:02 | hiredman | it is amazing how fast stuff goes from rhickey saying "I am playing around with idea X" to everyone demanding docs for X |
| 17:02 | chouser | powr-toc: http://gist.github.com/306174 and http://www.assembla.com/wiki/show/clojure/Cells |
| 17:02 | powr-toc | hiredman: lol |
| 17:02 | Chousuke | hiredman: heh |
| 17:02 | stuartsierra | hiredman: Because no one understand's rhickey's code. |
| 17:02 | rhickey | ouch |
| 17:03 | Chousuke | stuartsierra: I think that only applies to java |
| 17:03 | stuartsierra | rhickey: No offense meant, it's beautiful code. |
| 17:03 | powr-toc | Chousuke: yeah I saw that gist... somehow missed those notes though |
| 17:03 | stuartsierra | It's just so abstract that it's rarely obvious what it's for. |
| 17:05 | hiredman | rhickey is fluent in the language he is writing while the rest of use running around with dictionaries |
| 17:06 | stuartsierra | hiredman: good analogy |
| 17:06 | stuartsierra | Re testing again, the problem I'm stuck on is how to share values between assertions and setup/teardown. |
| 17:06 | stuartsierra | clojure.test fixtures do it via dynamic bindings, but the syntax is awkward. |
| 17:06 | powr-toc | Chousuke: I've found that the java code I've looked at has mostly been very clean and readable... Just very un-idiomatic... I've only skimmed it though |
| 17:07 | stuartsierra | And if you're not defining setup and assertions in the same fn body, you can't use let-bindings. |
| 17:08 | Chousuke | powr-toc: I suppose the un-idiomatic feel comes from the functional data structures used and the style in general. at least the reader was like that. |
| 17:08 | hiredman | stuartsierra: unless you use eval |
| 17:08 | hiredman | er |
| 17:08 | stuartsierra | But eval doesn't capture lexical scope, right? |
| 17:08 | hiredman | forget I said that |
| 17:08 | hiredman | :/ |
| 17:09 | stuartsierra | ,(let [x 42] (eval 'x)) |
| 17:09 | clojurebot | DENIED |
| 17:09 | stuartsierra | Anyway, it throws "x not defined" |
| 17:11 | chouser | you could put the tests inside the setup/teardown via macros. |
| 17:11 | stuartsierra | I thought about that. |
| 17:11 | chouser | do you setup/teardown per test? |
| 17:11 | stuartsierra | I want to support both options: once per test and once per test suite. |
| 17:12 | stuartsierra | But if the assertions are inserted into the setup/teardown code, then there could be a clash of locals. |
| 17:12 | hiredman | you can have the assertion creation macro analyze forms for free symbols and generate a function taking a map that does keyword destructuring |
| 17:12 | stuartsierra | And setup/teardown contexts are no longer reusable. |
| 17:12 | chouser | don't you *want* to capture the locals? |
| 17:12 | stuartsierra | no |
| 17:12 | chouser | then what are you setting up? |
| 17:13 | stuartsierra | Or, I want something that *looks* like local capture, but in a safe manner. |
| 17:13 | stuartsierra | hiredman: That's where I might be headed. |
| 17:13 | stuartsierra | But it seems so complicated. |
| 17:14 | stuartsierra | I want something that looks more like fn pre/post conditions. |
| 17:14 | chouser | (defwrap foo (let [a ... b ...] (.open b) :insert-tests-here (.close b))) (with-wrap foo (.write a "blah")) |
| 17:14 | hiredman | tree-seq is your friend |
| 17:14 | technomancy | stuartsierra: per-test-suite really means per-ns, right? |
| 17:14 | stuartsierra | technomancy: In the current definition of a suite-as-namespace, yes. But |
| 17:15 | stuartsierra | Ideally, I'd want to support nested suites. |
| 17:15 | hiredman | why? |
| 17:15 | clojurebot | why not? |
| 17:15 | hiredman | clojurebot: thanks! |
| 17:15 | clojurebot | Excuse me? |
| 17:15 | technomancy | if you support nested contexts wouldn't that amount to the same thing? |
| 17:15 | hiredman | nesting :( |
| 17:15 | stuartsierra | Not quite. |
| 17:16 | stuartsierra | I tried to make it possible to run a single test at the REPL by calling a function. |
| 17:16 | stuartsierra | With fixtures, that doesn't work, because the test function doesn't know which fixtures it needs. |
| 17:16 | stuartsierra | But if the test retains a reference to the contexts it needs, it can be run by itself. |
| 17:17 | stuartsierra | Or in the context of a test suite, without running fixtures more times than necessary. |
| 17:18 | ordnungswidrig | stuartsierra: oh running single tests would be very nice |
| 17:19 | stuartsierra | clojure.test already supports that, just not with fixtures |
| 17:19 | technomancy | ordnungswidrig: clojure-test-mode makes that pretty easy in Emacs |
| 17:19 | StartsWithK | stuartsierra, i used http://paste.pocoo.org/show/179465/ a syntax similar to let form in my tests, is this what you would like to do? |
| 17:20 | ordnungswidrig | technomancy: really? I always run all tests using C-, |
| 17:20 | Raynes | technomancy: Ola Bini apparently heard my cries. He's strongly considering moving Ioke to a new repo with no history. :D |
| 17:20 | StartsWithK | for once/every i was planing to use memoize over the setup function, but don't need that for now |
| 17:21 | stuartsierra | StartsWithK: That's pretty close to what I had in mind. |
| 17:21 | technomancy | Raynes: high-five |
| 17:22 | technomancy | ordnungswidrig: C-c M-, |
| 17:22 | ordnungswidrig | technomancy: nice, I'll try |
| 17:27 | dakrone | triyo: neat, is it opensource? |
| 17:28 | cemerick | stuartsierra: did you leave out basic auth in http.connection intentionally? |
| 17:28 | triyo | dakrone: well not as of yet. I'm gonna clean up the code a bit over the weekend, hopefully, and put it up on github. |
| 17:28 | stuartsierra | cemerick: no, just an omission |
| 17:28 | dakrone | triyo: cool, look forward to it :) |
| 17:29 | stuartsierra | cemerick: http.connection is another child of mine that needs to die |
| 17:29 | stuartsierra | Not to sound nihilistic or anything. |
| 17:29 | cemerick | replaced by? |
| 17:29 | stuartsierra | Something involving the Apache HTTP client. |
| 17:29 | cemerick | heh |
| 17:30 | cemerick | I suggested that many moons ago, but people didn't like the notion of 3rd party deps. |
| 17:30 | cemerick | ;-) |
| 17:30 | stuartsierra | Another reason why contrib itself needs to die. |
| 17:30 | stuartsierra | Basically, everything sucks. ;) |
| 17:30 | cemerick | That's funny, since you're probably the leading contributor :-D |
| 17:30 | stuartsierra | I know. |
| 17:30 | cemerick | but yes, I absolutely agree |
| 17:31 | stuartsierra | If rhickey could stop revolutionizing computer science long enough to care about menial details like packaging... |
| 17:31 | stuartsierra | Or if Maven 3 really IS a unicorn... |
| 17:32 | stuartsierra | triyo: immigration doesn't work |
| 17:32 | hiredman | yeah, compojure is hardly a beacon of light for the masses |
| 17:33 | jasapp | hiredman: why do you say that? |
| 17:33 | hiredman | the use of immigration for one |
| 17:33 | triyo | hiredman: once you dive beyond a hello world web apps, it stings. |
| 17:33 | cemerick | stuartsierra: at a certain point, I'm going to have to start caring about what rhickey is doing only once every 3 months or something ;-) |
| 17:33 | hiredman | the single segment namespace, but that should be fixed next release |
| 17:34 | hiredman | I mean it works, and is fine, but it is not a paragon of style |
| 17:34 | cemerick | anyway, binding start-http-connection is a perfectly decent way of adding basic auth to contrib.http :-) |
| 17:34 | stuartsierra | cemerick: Ah, good. Glad to be of service. :) |
| 17:35 | hiredman | cemerick: until direct binding bites! |
| 17:35 | technomancy | I thought base64 was added to contrib specifically to support auth in contrib.http |
| 17:35 | jasapp | I'm trying to think of web frameworks that are paragons of style |
| 17:35 | technomancy | or was that something other than basic auth |
| 17:35 | cemerick | hiredman: direct binding? |
| 17:35 | stuartsierra | technomancy: I started base64 but quit before I finished. |
| 17:35 | hiredman | jasapp: ok, but immagration and single segment namespaces are *grossly* bad style |
| 17:35 | technomancy | heh |
| 17:35 | hiredman | cemerick: no rebinding |
| 17:36 | jasapp | agreed. |
| 17:36 | Chousuke | single-segment namespaces aren't just bad style, they break things :P |
| 17:36 | cemerick | hiredman: totally not following you (not the firs time, tho ;-) ) |
| 17:36 | hiredman | immigration |
| 17:37 | hiredman | cemerick: as mentioned single segment namespaces break stuff |
| 17:37 | jasapp | can you explain? I have no idea what immigration is |
| 17:37 | hiredman | and immigration is just icky |
| 17:37 | triyo | agreed |
| 17:37 | triyo | to much magic :) |
| 17:37 | somnium | the immigration was a failed experiment, but the goal was noble |
| 17:37 | hiredman | it re-defs stuff in a new namespace basically |
| 17:37 | jasapp | ahh, ok |
| 17:38 | hiredman | somnium: road to hell... etc |
| 17:39 | Raynes | I read that as 'rot in hell'. |
| 17:39 | Raynes | :o |
| 17:39 | somnium | hiredman: noble goals are the road to hell? |
| 17:39 | _mst | good intentions :) |
| 17:40 | hiredman | http://idioms.thefreedictionary.com/road+to+hell+is+paved+with+good+intentions |
| 17:48 | kylesmith | Is anyone here good at writing parsers? |
| 17:50 | shrughes | it depends how you want to write them |
| 17:50 | hiredman | if I was any good writing parsers why would I use lisp? |
| 17:50 | triyo | hehehe |
| 17:50 | hiredman | I kid, I kid, I love the parens |
| 17:51 | kylesmith | I need a parser for CIF files, but some of the files do not follow the format exactly. |
| 17:52 | triyo | * patching=matching |
| 17:53 | hiredman | fnparse is the only clojure parser library I have used at all, it is ok |
| 17:53 | kylesmith | FYI, the files are in this zip file http://www.crystallography.net/cod.zip (BEWARE, 314 MB) |
| 17:54 | hiredman | constantly under developement and changing though |
| 17:54 | hiredman | which can be a drag |
| 17:55 | kylesmith | I don't mind using a library, but due to the irregular nature of these files, I need to be able to first try the correct way to parse the file, then try another way, etc. |
| 17:55 | hiredman | sure |
| 17:56 | hiredman | fnparse just creates functions that have a certain input and output |
| 17:57 | triyo | night all |
| 19:11 | powr-toc | Does anyone else find it annoying that the API docs at http://richhickey.github.com/clojure/ don't link back to clojure.org? It's hard to browse to the docs for special forms etc... |
| 19:14 | technomancy | powr-toc: I think the real problem is that so many special forms lack docstrings |
| 19:14 | technomancy | or they just say "see clojure.org for details" |
| 19:14 | powr-toc | technomancy: yeah, that's really annoying too |
| 19:15 | powr-toc | technomancy: what's the procedure for submitting documentation patches/suggestions? |
| 19:15 | powr-toc | can I just github fork? |
| 19:15 | powr-toc | presumably I'll need to sign a contributor agreement |
| 19:15 | technomancy | powr-toc: yeah, but don't use pull requests. http://clojure.org/contributing |
| 19:15 | technomancy | that too |
| 19:17 | powr-toc | I also find the docs for reduce a little cryptic... Especially how it doesn't document the form of the function you pass it very well. |
| 19:23 | technomancy | reduce is really hard to explain well without some sort of visual aid |
| 19:24 | powr-toc | technomancy: true... but my problem isn't in understanding reduce, more remembering the order of arguments for the supplied function... I always get the accumulator and current item mixed up |
| 19:24 | powr-toc | and the docs dont even mention the order of arguments there |
| 19:28 | dnolen | ,(:arglists ^#'reduce) |
| 19:28 | clojurebot | ([f coll] [f val coll]) |
| 19:30 | powr-toc | dnolen: yes, but reduce requires f to take two arguments. The order of those arguments are not mentioned. |
| 19:32 | dnolen | powr-toc: yeah I see what you mean. I suppose that's what clojure.contrib.repl-utils source is good for. In Emacs I'm always jumping into the core definitions to see how things work. refreshing actually coming from other langs. |
| 19:34 | powr-toc | dnolen: ahhh a handy package, thanks for the pointer... yeah having clojures source code to hand is seriously handy and far more accessible than in most languages |
| 19:39 | dnolen | powr-toc: only thing cooler |
| 19:39 | dnolen | will be when Clojure is written in Clojure. will be almost Smalltalkish then |
| 19:41 | powr-toc | dnolen: yeah that'll be sweet! But I do worry that the whole bootstrapping/meta-circularity thing might make things a little less accessible |
| 19:41 | hamza | guys, I have a func called start defined in leiningen.start namespace but lein is not picking it up. lein help start says it can't find the file but it is there this in a fresh lein project. |
| 19:42 | dnolen | powr-toc: in what way do you mean? |
| 19:42 | dnolen | hamza: and is your source organized src/leiningen/start.clj ? |
| 19:43 | hamza | dnolen: yeap its the only file there.. |
| 19:45 | powr-toc | dnolen: I think clojure in clojure will totally rock, and absoloutely is the way to go... I just think a big part of my learning clojure was digging through the clj and java source code and seeing things grounded in a language I knew (Java)... If it's turtles all the way down, that learning process is harder |
| 19:46 | powr-toc | dnolen: Plus you'll need a build of a clojure to build clojure, which makes the build process more convoluted |
| 19:46 | dnolen | hamza: hmm I'm assuming you're writing a plugin, I note that lein-swank itself can't work that way. |
| 19:46 | powr-toc | dnolen: But everything else is pure upside! |
| 19:48 | hamza | yeap its a plugin, are you saying i can't test it until i build a jar and add as a dev-dep? |
| 19:48 | dnolen | hamza: I just wrote my first lein plugin for dealing with native deps today, and I know it works if you build a jar and add as a dev-dep. |
| 19:49 | dnolen | hamza: and put in your lib directory |
| 19:50 | hamza | dnolen: kk so during testing just mock something for the arguments to the function? |
| 19:50 | dnolen | powr-toc: heh, not knowing Java well, I haven't had the experience you have. It also seems Clojure attracts a lot of people with only passing familiarity with Java. Being written in Clojure widens the number of people interested in contributing core code. |
| 19:51 | dnolen | hamza: heh, I didn't bother writing any tests for my plugin too simple for that really. but that sounds like a good approach. |
| 19:51 | hamza | dnolen: kk thanks alot. |
| 19:53 | slyphon | argh, i hate log4j |
| 19:53 | powr-toc | dnolen: I don't disagree... I just think it's a sign of clojure growing up... I'm happy for it to become an adult, but I'll miss its childhood. |
| 19:55 | nuggien | if i have a java class Foo with a constructor like Foo(Bar b) where Bar is an interface and Baz is a class implementing Bar, and in clojure I do (let [x (Foo. (Baz.))] ...) why does it keep telling me Baz cannot be cast to Bar? |
| 19:56 | chouser | What you describe should work. Are you very very sure you're creating a Baz, that Baz implements Bar, and that Foo's ctor takes a Bar? |
| 19:57 | nuggien | yes, does it matter if both Foo and Baz are declared as final? |
| 19:59 | chouser | I don't think so. |
| 19:59 | chouser | try (instance? Bar (Baz.)) |
| 20:00 | nuggien | yes that returns true |
| 20:00 | powr-toc | nuggien: No, I can't imagine how... final classes prevent java inheritence |
| 20:01 | powr-toc | nuggien: Have you cleaned and recompiled your java code? You might have stale class files |
| 20:01 | nuggien | powr-toc: this is just using classes in the unit testing jars that come with google app engine |
| 20:02 | powr-toc | nuggien: is the constructor public? |
| 20:02 | nuggien | basically the line: private final LocalServiceTestHelper helper = new LocalServiceTestHelper(new LocalDatastoreServiceTestConfig()); from |
| 20:02 | nuggien | http://code.google.com/appengine/docs/java/tools/localunittesting.html |
| 20:02 | nuggien | LocalDatastoreServiceTestConfig is a final class implementing the LocalServiceTestConfig interface |
| 20:04 | nuggien | i can do (cast LocalServiceTestConfig (LocalDatastoreTestConfig.)) just fine in the repl |
| 20:05 | chouser | what about the ctor. can you use repl-utils 'show' to confirm the ctor you want is there? |
| 20:05 | nuggien | but as soon as i pass that to LocalServiceTestHelper, it bails out saying it can't cast LocalDatastoreServiceTestConfig to LocalServiceTestConfig |
| 20:05 | nuggien | chouser: let me try that |
| 20:06 | nuggien | i guess this line is the constructor? [ 2] (class [Lcom.google.appengine.tools.development.testing.LocalServiceTestConfig;) |
| 20:07 | chouser | looks like it wants an array |
| 20:07 | chouser | varargs in java is an array for objects in Clojure |
| 20:07 | nuggien | the [L is array? |
| 20:07 | powr-toc | yes |
| 20:09 | hiredman | [ is an array |
| 20:10 | nuggien | what is the L for? |
| 20:10 | hiredman | the L and the ; at the end are just part of reference type names |
| 20:11 | nuggien | thank you all, it seems to work now |
| 20:11 | hiredman | the jvm has two or three different ways of giving type names, and Ljava.lang.Object; is one of them |
| 20:11 | hiredman | also java/lang/Object |
| 20:24 | slyphon | hiredman: did you know another lisp before clojure? |
| 20:51 | hiredman | slyphon: I'd poked at scheme a little, but just sort of hello worldish stuff |
| 20:52 | slyphon | i read through the "programming clojure" prag-prog book, i'm wondering what else is out there that's good |
| 20:52 | technomancy | Qi is spoken highly of by rich |
| 20:52 | slyphon | Qi? |
| 20:53 | technomancy | Qi! |
| 20:54 | technomancy | http://www.lambdassociates.org/ |
| 20:54 | scgilardi | http://en.wikipedia.org/wiki/Qi_%28programming_language%29 |
| 20:56 | slyphon | man, you know, i just had to pull the ex-nasa-physicist-pretending-to-be-a-CS-professor |
| 20:57 | slyphon | who argued with me that OO was useless because "it's just another way of referring to a pointer" |
| 20:57 | slyphon | and wondered why everyone didn't just write MASM |
| 21:01 | slyphon | not that i'm bitter or anything |
| 21:05 | lithpr | wow, that |
| 21:05 | lithpr | Qi book looks very interesting |
| 21:23 | ag90 | A question about GUI programming: Assuming that I'm using Swing, is there a more functional or lisp-y way to write the GUI instead of the standard Java imperative way? If not, what about other toolkits (like SWT)? |
| 21:25 | Modius | Is there a macrolet/environments in Clojure? Just need a name to look up if there is. |
| 21:26 | ag90 | Modius: Do you mean this? http://richhickey.github.com/clojure-contrib/macro-utils-api.html#clojure.contrib.macro-utils/macrolet |
| 21:26 | Modius | ag90: Is the expansion environment available? |
| 21:28 | ag90 | Modius: I don't know. I was just guessing. |
| 21:28 | TheBusby | contextual macros? the idea is interesting, but sounds a little dangerous |
| 21:33 | lancepantz | how do you use the class? function? |
| 21:33 | lancepantz | it only takes one argument, but i would expect it to take an instance and a class name |
| 21:33 | lancepantz | and return true if that instance is in that class |
| 21:34 | arohner | ag90: stuart sierra had a few blog posts on the topic... |
| 21:35 | arohner | ag90: http://stuartsierra.com/tag/swing |
| 21:35 | arohner | lancepantz: it returns true if the object you pass it is a class |
| 21:35 | arohner | as opposed to say, a number |
| 21:35 | arohner | lancepantz: maybe you want instance? |
| 21:36 | lancepantz | ah |
| 21:36 | lancepantz | yes, thank you :) |
| 21:37 | lancepantz | and i can pass the expected class as a string, correct? |
| 21:38 | lancepantz | looks like i cant |
| 21:38 | arohner | the actual class object |
| 21:39 | arohner | ,(instance? String "hello world") |
| 21:39 | clojurebot | true |
| 21:39 | arohner | ,(instance? String 42) |
| 21:39 | clojurebot | false |
| 21:39 | lancepantz | got it |
| 21:39 | lancepantz | thanks |
| 21:39 | arohner | np |
| 22:17 | TheBusby | Hmm, how would this work? (magic even? [1 2 4 6 5 5 5 7 8 8 10 11]) => [2 6 8 10] |
| 22:18 | chouser | who no 4? |
| 22:19 | TheBusby | looking for the bounds of valid ranges |
| 22:19 | TheBusby | "why no 4" right? |
| 22:20 | chouser | I thought you wanted distinct even values, but that would ahve included 4 in the output. |
| 22:21 | TheBusby | yeah, filter and distinct would have been a good option then |
| 22:21 | TheBusby | but finding the boundary values... |
| 22:22 | TheBusby | was hoping that maybe there was a split function where I could get (magic-split even? [1 2 4 6 5 5 5 7 8 8 10 11]) => [ [2 4 6] [8 8 10] ] |
| 22:26 | arohner | TheBusby: so you're looking for seqs of consecutive values that pass the predicate? |
| 22:26 | TheBusby | arohner: yes |
| 22:26 | arohner | I think you'll have to write that |
| 22:27 | TheBusby | k, just wanted to make sure there wasn't something hiding in contrib or somewhere that I wasn't aware of |
| 22:27 | TheBusby | I know re-seq kind of does what I want for strings, so I thought a more general function might be hiding somewhere |
| 22:28 | lancepantz | anyone mind helping me get this recursive function correct? http://www.pastie.org/830208 |
| 22:28 | lancepantz | it returns nil, but i'm expecting it to return a nested map |
| 22:30 | chouser | ,(use '[clojure.contrib.seq :as seq]) |
| 22:30 | clojurebot | java.io.FileNotFoundException: Could not locate clojure/contrib/seq__init.class or clojure/contrib/seq.clj on classpath: |
| 22:30 | chouser | ,(use '[clojure.contrib.seq-utils :as seq]) |
| 22:30 | clojurebot | nil |
| 22:30 | chouser | ,(->> [1 2 4 6 5 5 5 7 8 8 10 11] (seq/partition-by even?) (filter (comp even? first))) |
| 22:30 | clojurebot | ((2 4 6) (8 8 10)) |
| 22:30 | TheBusby | ah, partition-by! |
| 22:31 | TheBusby | chouser: much thanks! |
| 22:31 | chouser | ,(->> [1 2 4 6 5 5 5 7 8 8 10 11] (seq/partition-by even?) (filter (comp even? first)) (map (juxt first last))) |
| 22:31 | clojurebot | ([2 6] [8 10]) |
| 22:32 | arohner | lancepantz: doseq returns nil |
| 22:35 | dannycoates | can anyone here help a noob compile clojure-clr? I've got 3 build errors |
| 22:36 | lancepantz | arohner: is there a different function i should use instead, or is my approach flawed? |
| 22:37 | lancepantz | maybe loop/recur? |
| 22:37 | arohner | lancepantz: I'm not entirely sure what you're trying to accomplish |
| 22:37 | lancepantz | hahah |
| 22:38 | lancepantz | i've got a nested yaml string, and snakeyaml returns a nested java.util.LinkedHashMap, i'm trying to recursively turn that into clojure maps |
| 22:38 | lancepantz | *turn that into a clojure map of clojure maps |
| 22:44 | arohner | lancepantz: try using reduce and assoc |
| 22:45 | lancepantz | k, ty! |
| 23:15 | TheBusby | data |
| 23:16 | chouser | code |
| 23:16 | TheBusby | whoops, sorry wrong window :) |
| 23:56 | lancepantz | alright, got it |
| 23:57 | lancepantz | arohner: this is what i was trying to do:: (defn to-seq [data] (into {} (for [[k v] (into {} data)] [k (if (instance? java.util.LinkedHashMap v) (to-seq v) v)]))) |
| 23:58 | arohner | cool |