#clojure logs

2009-11-25

00:26technomancyKirinDave: I think I got the bootstrapping issues sorted out for leiningen; sorry about the rough spots.
00:26technomancyself-hosting is Fraught with Peril.
00:30danlarkin
00:37defntechnomancy: what do you do your blog with?
00:39technomancydefn: I use this script: http://p.hagelb.org/Rakefile.html
00:39technomancyalong with htmlize from Emacs for code snippets
00:40defncool, thanks
00:41technomancycomments are done with a short ruby CGI script, but it's not very good, so I won't share it.
00:45chouser,(last 2 (range 10))
00:45clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$last
00:45chouserhmph
00:46chouser,(take-last 2 (range 10))
00:46clojurebot(8 9)
00:46chouserah, there it is
00:47chouserkzar: in case you still care
01:02efarrarhello!
01:02chouserefarrar: ha!
01:03chouserer, hi!
01:03efarrarI'm trying to work through translating this (http://www.arduino.cc/playground/Interfacing/Java) to clojure
01:03efarrarpretty much plain old reading from an io stream
01:04efarrarand I've got it sort of reading, i can often get the \H out
01:04efarrarbut think i'm running up against a problem of blocking io in this loop: http://gist.github.com/242517
01:06efarrarhave i somewhat correctly transliterated the loop from java to clojure?
01:09KirinDave1technomancy: That's awesome news
01:10technomancyKirinDave1: and this time I've actually tried it instead of just informally reasoning about it.
01:10technomancyI realized informal reasoning doesn't work for shell scripts.
01:10KirinDave1:D
01:11KirinDave1technomancy: A nice guy on the mailing list gave me a built version.
01:11technomancyah, good old sourdough software
01:28hiredmanclojurebot: ping?
01:28clojurebotPONG!
01:32chouserefarrar: yes, that's pretty much the same, though that nested java loop is a little weird
01:33chouser...and in clojure, to have a loop like that the doesn't return a value is also a little weird, though not unheard-of in IO stuff.
01:52defnGood god -- Why do people use these site generator thingamabobs?
01:52defnWhat a f****ing headache.
01:58efarrar(if (< 0 (. istream available)) (print (char (.read istream)))) ; works
01:58efarrar(while true (if (< 0 (. istream available)) (print (char (.read istream))))) ; never prints anything
02:00hoeck1efarrar: maybe you need println or `flush' after each print to actually see the output?
02:00hiredmanif you close the stream that automatically flushes
02:01hiredmanso if you close your streams properly you never have this problem anyway
02:10efarrarwow
02:10efarrarprintln did it
02:10efarrarvs print
02:11efarrari mean its now printing each char on it's own line, but it is progress
02:11efarrarthanks guys
02:11hiredmanyeah
02:11hiredmanyou aren't closing the stream properly
02:17tomojlooks like a vector in destructuring bind ignores any unmentioned elements?
02:17tomojso [[foo bar] aseq] gets you the first two into foo and bar and doesn't care if there are more?
02:18hiredmancorrect'
02:18tomojI realized I was writing ugly literals like [[k1 v1] [k2 v2]] for some reason :(
02:27alexykis there a fold, in addition to reduce?
02:28hiredmanuh
02:28hiredmanwhat would the difference be?
02:28alexykhiredman: init value of a different type and function reducing to that
02:28hiredmanalexyk: reduce can take an init value
02:29hiredman,(doc reduce)
02:29clojurebot"([f coll] [f val coll]); f should be a function of 2 arguments. If val is not supplied, returns the result of applying f to the first 2 items in coll, then applying f to that result and the 3rd item, etc. If coll contains no items, f must accept no arguments as well, and reduce returns the result of calling f with no arguments. If coll has only 1 item, it is returned and f is not called. If val is supplied, returns the r
02:29alexykhiredman: ah, so it's a fold, too.
02:29hiredman,(reduce conj () [1 2 3 4])
02:29clojurebot(4 3 2 1)
02:31alexykcuute
02:31defnthat's interesting
02:31defnnever seen that before
02:32hiredmanit's very handle
02:32hiredmanit's very handy
02:32defnwhy is it in reverse?
02:33defnthe result I mean...
02:33hiredman,(conj () 1)
02:33clojurebot(1)
02:33defnbecause that's how conj acts on vectors?
02:33hiredman,(conj (conj () 1) 2)
02:33clojurebot(2 1)
02:33hiredmanetc
02:33defnahhhh, right
02:33defncool
02:33defnconj is actually acting like cons here, no?
02:34hiredmanwith the arg order reversed
02:34hiredman,(cons 2 (cons 1 ()))
02:34clojurebot(2 1)
02:35defnso forgive me, but a () is just a list always right? I get a little confused with the context switch between seqs and other types
02:35efarrar,(+ 1 1)
02:35clojurebot2
02:35efarrarnice
02:36defnheh
02:36hiredman() is a list
02:37defni guess ive just been confused by the quoted form and the () form, since you can't (cons 0 (1 2 3))
02:37defnwhich seems to make sense to me, instead you have to quote it
02:37defnwhy is that?
02:37hiredmansure, () is special cased
02:37hiredmanI mean, it's obviously not a function call
02:38defnbut why the need to quote in the case of (cons 0 (1 2 3)), but not when you (cons 2 (cons 1 ()))?
02:38hiredmanbecause () is special cased
02:39defnoh, i see what you're saying
02:39defnyou can only cons onto an empty list, not onto a list with values, unless you quote it
02:39hiredmanno
02:39hiredmanthat is not qhat I am saying at all
02:39defn,(cons 0 ())
02:39clojurebot(0)
02:39defn,(cons 0 (1 2))
02:39clojurebotjava.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
02:40defnI think maybe I'm not being clear
02:40hiredmanthat has nothing to do with cons
02:40hiredmanit is the expression (1 2)
02:40defnis that not a list?
02:40hiredmanlisp treats lists as function calls
02:41hiredmanwhat is the difference between the lists (+ 1 2) and the list (1 2 3)?
02:41defnthe function
02:41defn(+)
02:41hiredmanthere is no difference
02:41hiredmanthey are both lists
02:42defnhaha, yes, but one of them does contain a function, where the other does not, no?
02:42hiredmanliteral lists are all treated as function calls
02:42hiredmandefn: a function is just another value
02:42tomojeven () ?
02:42defn() is the special case
02:42hiredmantomoj: if you scroll up, you will see I am trying to explain that () is a special case
02:42tomojI see
02:43defnhiredman, i see what you're saying now, the populated list is in essence a function, it returns itself?
02:43hiredman
02:43hiredmanno
02:43defnlol damnit
02:43hiredmana function is just another value
02:43tomojif it returned itself (+ 1 2) would be '(+ 1 2), no?
02:44hiredmanso there is no difference between (+ 1 2) and (1 2 3)
02:44hiredmanso they are both treated as function calls
02:44hiredman1 is not a function, so you get an exception
02:45tomojon the other hand you have
02:45hiredmana compiler/interpreter is more or a less a giant switch statement
02:45tomoj,'([1 2] 0)
02:45clojurebot([1 2] 0)
02:45efarrar,(class ())
02:45clojurebotclojure.lang.PersistentList$EmptyList
02:45tomoj,([1 2] 0)
02:45clojurebot1
02:46hiredmantomoj: vectors are functions
02:46defnok, so... () is a special case because there is nothing for a function to act on, whereas when you have (1 2), by virtue of the fact that it is in (), the 1 is treated as a function, and so you get the exception?
02:46tomojwhich makes me quite happy :)
02:46efarrar,(class '(1))
02:46clojurebotclojure.lang.PersistentList
02:46hiredmanso that has no effect on this disucssion
02:46hiredmandefn: no!
02:46hiredman() is a special case because there is no function to call
02:47defnthat's what i was saying i suppose
02:47hiredman(foo) has nothing for the funtion to act on, but it is still a function call, just with no args
02:47defnnothing for a function to act on within the ()
02:47defnbecause there is no function in ()
02:47hiredman
02:47hiredmansure
02:48defnbut once you have (1), the first of that list will be treated as a fn
02:49hiredmanit's not "the first of the fn is treated as a function" it's a list of size greater than zero is a function call, and it just happens the function to call goes at the front of the list
02:49hiredmanbut oh, we wanted a function but got a number, better throw an exception
02:49tomojhmm.. () is nil in CL
02:49defnhehe tomoj
02:49tomojI wonder if this is the same special case, since '() is nil too
02:49defnit's different in clojure
02:50tomojor if they're doing what seems right to me, calling no function gives you no result
02:50hiredmanI mean literal a special case
02:50hiredmanI expect there is a case in a switch statement, or if statement, in the compiler
02:50defnhiredman, i think you might have just answered my question, but if I do:
02:50hiredmanthat says for () emit ()
02:50defn,(asdf 1)
02:50clojurebotjava.lang.Exception: Unable to resolve symbol: asdf in this context
02:50defn,(1 asdf 1)
02:50clojurebotjava.lang.Exception: Unable to resolve symbol: asdf in this context
02:51defnwhy doesnt it throw any error about the iFn?
02:51tomojI guess clojure evals the args before trying to call the function?
02:51hiredmanbecause symbols are resolved before functions are called
02:51defnahhh, thank you so much
02:52defnhiredman > *
02:52efarrarjust think of 1 as a symbol, but luckily it is symbol that resolves to the number 1
02:52defn1 is not a symbol
02:52efarrarso since one resolves ok, it goes on to try the next part of the expression
02:52defnwell at least not in my reasoning
02:52efarrarwhere it hurls
02:52defn1 is a primitive
02:53tomojwouldn't have surprised me if it barfed before evaling asdf because 1 isn't an IFn
02:53tomoj1 isn't a primitive :/
02:53defni think we made hiredman angry
02:53tomojI guess it can be in some places maybe?
02:53efarrarafter it's resolved all of them, it goes back and tries to call the function
02:54defnim relying on some very spotty reminder of SICP where Sussman talks about the primitives of a language, and IIRC mentions the integers 0-9
02:54defnas being primitives
02:54tomojyeah that's the strange thing to me, it shouldn't need to resolve all the args
02:54arohnerdefn: scheme isn't clojure
02:54hiredmandefn: efarrar is proposing a thought experiment
02:55tomojonce it's got 1, it could just bail out
02:55tomojdoesn't matter what the args are, you can't call 1
02:55tomojthat doesn't matter anyway I suppose
02:55defnefarrar: yeah i suppose your way of reasoning makes sense in this case
02:55hiredmanI could easiliy imagine a lisp where numbers are symbols, and the symbol resolution step just turns the number
02:56defnwhat do you mean by "turns"?
02:56efarrarit's also the way that many homo-iconic languages choose to deal with primitives, to make "1" a valid symbol, that happens to return 0x0001 or whatever
02:56hiredmanreturns
02:56defnahhh
02:56hiredmanactually, I'm kind of thinking of using numbers to represent symbols in this compiler I am toying with
02:57tomojefarrar: what's an example of one of these languages?
02:57hiredmanhmmm
02:57tomojI would be surprised if I couldn't add numbers in my macros without evaling them as symbols
02:57hiredmanclojurebot: history?
02:57clojurebotNo entiendo
02:58hiredman~google history of lisp
02:58clojurebotFirst, out of 134000 results is:
02:58clojurebotHistory of Lisp
02:58clojurebothttp://www-formal.stanford.edu/jmc/history/lisp/lisp.html
02:58defngod, i've felt like a noob before, but never as much as right now
02:58hiredmangreat paper, guy steele and some other guy whose name I always forget
02:58defnpeople have been coding lisp for 40+ years, and here I am just getting on board
02:59defnif i ever have children interested in programming I will force them to learn lisp first, the rest second
02:59hiredmanthere used to be a huge diversity of languages called lisp, before the ai winter
02:59defnai winter being post mid-1980s?
03:00hiredmanI am sure one of them, some where, treated numbers as symbols at some point
03:00hiredmandefn: sounds right, the actually timeline didn't stick as well as the catchy name
03:01defnThe worst times for AI were 1974−80 and 1987−93.
03:01defn(per the wiki article)
03:01defn1987 == Collapse of the lisp machine market
03:02defnhttp://en.wikipedia.org/wiki/Fifth-generation_computer
03:02defnthat's an interesting article
03:02hiredmanthat link from google is not the history of lisp I was looking for
03:04defnhttp://www.infoq.com/presentations/Lisp-Guy-Steele-Richard-Gabriel
03:04defnWhy is InfoQ so crappy and so great at the same time?
03:05hiredmanI found a pdf of it online
03:07hiredmanah!
03:07hiredman~google the evolution if lisp
03:07clojurebotFirst, out of 13900 results is:
03:07clojurebotLisp (programming language) - Wikipedia, the free encyclopedia
03:07clojurebothttp://en.wikipedia.org/wiki/Lisp_(programming_language)
03:07hiredman~google the evolution of lisp
03:07clojurebotFirst, out of 31200 results is:
03:07clojurebotThe Evolution of Lisp
03:07clojurebothttp://www.dreamsongs.com/NewFiles/HOPL2-Uncut.pdf
03:07hiredmanthat one
03:07hiredman++
03:07hiredmanA++
03:13defnthanks hiredman
03:15defnYuck. It's Richard "Fineman" not "Feighn-men"
03:16tomojI have a vector like [[[k1, foo], v1], [[k2, bar], v2], [k3, baz], v3]
03:16tomojis it possible to get two lazy seqs (k1, k2, k3) and (v1, v2, v3) without walking this vector twice?
03:18tomojat this point it doesn't really matter since the vector isn't lazy anyway, but I'm just curious
03:18tomojI guess the idea might not even make sense, you can't have two lazy seqs which cooperate realizing something together
03:20defnMy intuition tells me it's possible
03:20defnbut I couldn't tell you how
03:23tomojmy intuition tells me that if it is possible, it requires evilness to do it
03:24tomojif someone realizes some of the one seq, the other seq needs to somehow know this and not redo the work
03:34defntomoj: yeah that becomes very weird
03:35defnbut i suppose i can conceive of some sort of function approaching 0 which is able to capture those on its way
03:35defndoes that make sense?
03:37tomojuh
03:37tomojno :(
03:52defnPascal is for building pyramids. Imposing, breathtaking, static structures built by pushing heavy blocks into place. Lisp for building organisms.
03:55defntomoj: the perfect combination of functions selecting points "around" the point they intend to meet, for any logical structure, over the course of a handful of generations, or thousands, approaches the answer you seek
03:56tomojhmm
03:56tomojyes I really have no idea what you're talking about
03:57defnhaha, im philosophizing a bit
03:57defnbut suppose you have 3 functions which take wild stabs at the point their intended result resides
03:58defnnow suppose they split off into smaller pieces, inching closer towards their "goal"
03:58tomojare you stoned
03:58defnyes
03:59tomojah, now I understand
03:59defn100% -- not even joking
04:00defnbut no I just am saying that if we have what we describe functions, they can be part of a larger system which inches them towards our intended result
04:00defndescribe as*
04:02defnso the purely functional thing is great, but that's why Lisp > Haskell IMO, because you can create those side-effect laden state-loving function-manipulating entities in order to evolve your pure structures in ways they couldn't do on their own
04:04defntomoj: just tell me to shut up if this is ridiculous
04:06tomojI don't know if it's ridiculous or not
04:06tomojI can barely parse it
04:06defnlittle pure bits manipulated by impure bits
04:07defnerr impure "bytes"
04:08ordnungswidrighi all
04:09tomojdon't talk about your impure bits in public
04:13licoresseGood morning
04:18hoeck1ordnungswidrig, licoresse: good morning!
04:20licoresseso, been away for a while, anything new?
04:22licoressehad a peek at clojats
04:23licoresseclojars
04:23hoeck1licoresse: how long have you been away?
04:23licoresse1 month
04:27hoecklicoresse: there are now `protocols' in the new branch
04:28licoresseI'll have a look
04:28licoresseany videos of protocols?
04:28hoecklicoresse: and the next release (1.1) is not that far away, only three patches left, from what Ive heard
04:28licoressejoy!
04:29hoecklicoresse: they are documented extensively in the docstring, and there is an assembla wiki-scratchpad page
04:29licoresseok
04:29hoeckclojurebot: protocols
04:29clojurebothttp://www.assembla.com/wiki/show/clojure/Protocols http://clojure-log.n01se.net/date/2009-10-13.html#12:02
04:31hoecklicoresse: and there is deftype for buildung small structlike objects dynamically, but thats about 1 month old, maybe you've already heard of it
04:31licoresseclojurebot: deftype
04:31clojurebotdeftype is see datatype
04:32licoresseclojurebot: datatype
04:32clojurebotdatatype is see datatypes
04:32licoresseclojurebot: datatypes
04:32clojurebothttp://www.assembla.com/wiki/show/clojure/Datatypes
04:32licoresseah
05:40licoresseany clojure activity at wave.google.com?
05:42ordnungswidrighi all
05:42ordnungswidrigups
05:50liwplicoresse: search for "with:public clojure" in wave
05:51liwpseems like there are 20 public waves with clojure in them
05:51licoresseah, great, thanks
07:50BjeringI am 10 days into clojure now, and wow, I haven't had this much fun programming in 15 years!
07:52rhickeyBjering: Great! (sorry about the last 15 years)
07:53AWizzArdBjering: grats! Sounds familiar to me :)
07:53AWizzArdI should do this every day.
07:53rhickeyyw
07:53AWizzArd"Clojure - brings the fun back to programming"
07:54Raynes"Clojure - More fun than Python. Yes, I went there."
07:56Bjeringrhickey, I saw your presentation "are we there yet" on info-q that really sold it to me. I am mainly a C++ guy and whenever I've been in Java och C# the lack of value-based programming made me uncomfortable.
07:57BjeringI think that presentation was very important since it does not say "Clojure" in the subject it felt generally applicable and drew me (and I am sure other non-converts) in :)
07:58rhickeyBjering: yeah, avoiding talking about Clojure specifically was a goal of that talk
07:59rhickeyIt includes an inside joke for Clojure users - "I wish there was a programming language where these persistent data structures were the default"
07:59AWizzArdThat allowed me to forward this vid to several non (not-yet) devs.
07:59Bjering:)
07:59AWizzArduhm, non-clojure devs
08:00BjeringMy thinking during most of the talk was, I sure hope the boost guys watch this and make me a nice C++ lib.
08:02BjeringFrom my perspective the whole modern C++ community is working really hard to do things "Clojure things" with template meta-programming and a focus on value-types.
08:03rhickeyBjering: it is certainly possible in most langs, but not idiomatic in many
08:04Bjeringrhickey: I notice you usually compare against C# and/or Java, is this becuase you think C++ is long dead ;) Or because you think C++ has more things "right"?
08:05rhickeyI think the lack of GC in C++ is a huge problem
08:06Bjeringref-counting with something like boost::smart_ptr isn't enough?
08:06rhickeyno
08:07BjeringYou think its a huge problem in general, or did you mean specifically for the persistent datastructures?
08:07rhickeyin general
08:07cemerickrhickey: you should toss out a "...and get off my lawn!", just for the hell of it ;-)
08:08rhickeycemerick: I'm not trying to discourage the questions, and am happy to oblige, really, just a little been there, done that :)
08:09cemerickrhickey: oh, I know. It doesn't come through irc, but that was a *huge* wink at the end of the line.
08:10BjeringOk, well, honesly memory-management has never been a problem for me, i've had much more problems with such things in Java and C#, possibly because I was fooled into thinking "well I have gc, I dont need to care...". Now mutable state otoh, that just break things...
08:10rhickeyBjering: lack of standard GC completely changes library design
08:10BjeringBut good C++ code has alot of immutable value-classes.
08:11rhickeyBjering: I've also become very sensitive to incidental complexity, and C++ is chock full of it
08:11Bjeringagreed
08:12rhickeypower/complexity is the key ratio
08:12BjeringI am already at 3/10 of knowing Clojure I think, and after 20 years of C++ I think I am barely at 6/10 ;)
08:13cemerickrhickey: what's your take on the "JRoR in front, clojure in the back" notion? I have to say, it makes a lot of sense from where I sit, even though I'd love to say clojure is the best solution end-to-end.
08:13gerry`jdk7 will support closures, any benefit to clojure?
08:15rhickeycemerick: people should do what is most productive. I think in the end there will be Clojure-based web tools that make Clojure devs most productive, but in a mixed skills shop multiple langs might make sense
08:15rhickeypersonally I find ORM quite goofy and wrong
08:16cemerickindeed, but when you're not using an RDBMS, that issue goes away nicely :-)
08:16rhickeygerry`: hard to say
08:16esjrhickey: interesting! How do you think about DB backed apps ? (genuinely curious)
08:17rhickeycemerick: then what's rails doing for you?
08:17cemerickrhickey: I agree completely re: productivity. I just worry about the (perhaps large) population that expects a language to cover the full stack.
08:17rhickeyesj: I think databases are great and people should really learn the relational model and stop being afraid of it
08:18gerry`rhickey: much less class files due to closures?
08:18cemerickrhickey: sane templating, tons of fiddly glue libraries for making working with HTML and js easy, etc.
08:18rhickeycemerick: well, the backend of say, Flightcaster, seems to me the harder job, so if you can cover that well then reaching the front end is a matter of libs and frameworks
08:19rhickeycemerick: that's a matter of opinion, re: templating
08:19cemerickright, which is exactly why 99% of our "backend" as it were is in clojure
08:19cemerickrhickey: yeah, templating is a very personal choice -- hard to argue on merits because of the huge variety in requirements + opinions.
08:20Bjeringrhickey: How do you see best-pracitce for persistens (as in stored on disk! (what shall I call this now that you use the word in another meaning?)) working in clojure?
08:20rhickeymy concentration for Clojure has always been about making a language suitable for the back end - that's where all the hard parts live
08:20cemerickI personally think that sexpr templating is insane.
08:20rhickeycemerick: I think the bigger issue is - where is the code, how does it interleave with the doc structure, if at all?
08:21tomojcemerick: what about enlive-style?
08:21rhickeySo, functional templating a la Enlive, String Template, GXP, all appeal to me
08:21gerry`#(int i, Strings) (i + s.length()) = #(fn [x y] (+ x (count y)))
08:21BjeringI mean, do you beleive in marrying a RDBMS transaction handling, so we can get similiar behavior to the STM only fully persisten. Some "ref" type that live on disc?
08:21cemericktomoj: I like enlive a lot. I don't like the current state of the rest of the clojure web stacks.
08:21rhickeyBjering: that's impossible to answer generally
08:22rhickeycemerick: ok, but that's a maturity thing, not a language capability thing
08:22tomojI still haven't tried to do much of anything with compojure
08:22chouserIn Soviet Russia, lazy sequences hold *your* head!
08:23rhickeybut Clojure is pragmatic - being able to compose a solution with JRoR is just another feature
08:23cemerickrhickey: absolutely. I just can't spend our time on helping with web front end stuff, as it's simply not that important to us.
08:24BjeringOk, if I try to be more specific, say your making a bank-system, with clojure as language, what would be the most convenient way to work Once and Once only with the transaction logic and still have it persistent?
08:25BjeringI can see doing it with Refs in the STM, but then I'll have to duplicate it for my Database updates.
08:25rhickeyBjering: a huge issue with data and databases in general is that the business has a set of rules for the data - where should they live? probably not in apps
08:27rhickeycemerick: when I look at RoR I see an incidental-complexity fest
08:27Bjering...and for now you are happy to replace Java, not SQL :)
08:27cemerickrhickey: even leaving aside activerecord?
08:27rhickeyyes
08:28rhickeycemerick: but I can't say I've spent much time with it (RoR), just evaluated and rejected
08:29gerry`Bjering: in your case , just use database logic not use clojure STM to do that,i think
08:29rhickeycemerick: that's just my preferences though, others love it
08:29cemerickrhickey: Perhaps I'm blind to it. Web development is absurdly and unnecessarily complicated all on its own, and rails seems to shield me somewhat.
08:29rhickeycemerick: until...
08:32rhickeycemerick: exactly
08:33cemerickheh
08:33rhickeythat's how incidental complexity works
08:33AWizzArdcemerick: I find Compojure nice.
08:33cemerickwell, it sounds like you're saying that rails doesn't properly abstract from the nuttiness of the web. Are there any solutions that do?
08:33cemerickrhickey: ^^
08:35rhickeycemerick: probably not, but I'd rather have transparency and simplicity
08:35cemerickAWizzArd: as far as it goes, yes, it's OK. It needs time to cure though.
08:35rhickeyrather than opacity and apparent simplicity
08:35cemerickI suppose GWT is pointing in that direction, but that has a boatload of its own problems.
08:35BjeringOk, scrap the bank-system idea then, as it is clearly a case where data-integrity/performance tradeoff is an easy win for data-integrity and take something like an game-server instead. This also need to be able to survive a blackout, but at the same time if any time you fire a weapon is a database insert you wont get the responsiveness you need.
08:38rhickeycemerick: right, GWT is another example - is it really changing the power/complexity ratio? If more power comes with more (esp. implicit) complexity, you really aren't getting anywhere
08:40BjeringI guess what I want is a system where events both get saved forever to disk, and at the same time, following the same logic, affects the state "in RAM" following the same rules. Without me writing duplicated logic, and without the "in RAM" version reading from the DB all the time (for performance reasons).
08:40rhickeyusually we can do 90% of the job with 10% of the complexity, but the other 90% of the complexity is sitting there in the langs/frameworks and we use it because it's there
08:41cemerickI wonder if anyone is willing to pay the price associated with a web framework that actually does change the power/complexity ratio. Seaside comes to mind, but that's hardly a common choice.
08:42cemerickBjering: you're wanting a terracotta cluster, or something similar
08:42rhickeycemerick: I think people don't normally consider incidental complexity, they are infatuated with apparent simplicity
08:43cemerickrhickey: right...and what I was saying is, perhaps that's the legitimately sane choice for web front ends -- which are ditched and replaced, wholesale, every 9 months on average (or whatever)
08:44rhickeycemerick: could be
08:44rhickeybut when they are not ditched, then what?
08:45tomojdo frameworks like sinatra and compojure not change the power/complexity ratio?
08:45tomoj(compared to like django and rails)
08:45cemerickrhickey: till the soil, and see what comes up next, I suppose
08:46chouserI've been very pleased with the power/complexity ratio of ring, so far anyway.
08:46BjeringI have an arrow, hitting an ogre, the ogres state should change to "wounded" at the same time the arrows state should change to "stuck", this seems prefectly nice to do in the STM. Its also nice to do with database transactions. What if want both? The right answer is "no if you want both, you do it only in the DB and then re-read your data to the APP? :(
08:46rhickeycemerick: line with bad choices has been my experience, fewer things ditched than not, systems lasting well beyond when they ought to
08:46rhickeylive with
08:47rhickeyBjering: it might be possible in the future to tie STM in with a transaction coordinator, but not yet
08:48cemerickBjering: from what I understand, most MMORPGs run entirely in-memory, with only selected bits (inventory, XP, etc) being persisted to disk
08:49_atoI would consider GWT and Seaside to be two very good examples of opacity and apparant -- but not real -- simplicity. What happens with GWT when you reach the 10% that GWT can't do for you, or worse you encounter a bug? With something small and transparent like Sinatra/Compojure you can go read the code, tweak it etc. With GWT it's just overwhelmingly complex.
08:49cemerickBjering: but what you're describing is exactly what terracotta and similar clustering frameworks aim for
08:50Bjeringcemerick: Ok, this sounds cool, but when I hear Terracotta I feel like "whoaa" thats big and dangerous and an overkill for what I want, but perhaps it doesnt have to be?
08:51cemerickBjering: no, it doesn't have to be, but if you're looking for that transparent (called "orthogonal" elsewhere?) solution, then that's where you have to go
08:52cemerickPeople have built such things on top of other object systems (like CLOS), but stuff like that seems like a hairball to me.
08:52BjeringI havent been looking for anything transparent since I got burned by COBRA 15 years ago ;)
08:52Bjeringeh corba..
08:53rhickeychouser: I started this to give us a place to hang issues related to agent exceptions: https://www.assembla.com/wiki/show/clojure/Agent_exception_handlers
08:56BjeringI want persistence, and performance, at the same time. Persistence doesn't have to be immidiate, it can queue up, but in the end I need a guarantee any transactions are resolved the same as it was in RAM. All as "simple" as possible. Maybe this is impossible?
08:58chouserBjering: if you don't care about immediate, you might look at doing your database writes in an agent
08:58chouserBjering: if you send to an agent from inside a transaction, the send will be held back until the transaction commits
08:59esjBjering: have you thought about mongodb, redis, scalaris and friends ?
08:59BjeringChouser: Unless someone pulls the plug before it happens ;) but yeah for many apps that should be ok.
09:00chouserBjering: right
09:01AWizzArdWhen I modify a ref inside a transaction then there is no need to call ensure on that ref, right?
09:01chouserAWizzArd: right
09:02Bjeringesj, nope, I guess I get confused with the talk about scalability and distribution, those arent my problems. Performance and persistence are. I'll check them out now though. Thank you.
09:02chouserrhickey: can I add notes to that assembla page?
09:02chouserthat is, may I?
09:02rhickeysure
09:03StartsWithKhi, quick question about gen-class, what is a right way to declare ctor/method takes primitive type and array?
09:05StartsWithKand why if :constructors is omitted will gen-class create constructors that match base class?
09:11Bjeringchouser: I guess a condensed way to phrase it is that if I want to be sure that unless a state is recreateable from disc, I don't want anyone to see it. And that for now, I either have to solve this by reading all state from the DB after it has runs its transaction (as I am used to) or investigate 3rd party solutions (such as terracotta or the ones esj suggested) until the STM integration with a Transaction Coordination happens.
09:13chouserhm, yeah.
09:13chouserI wonder if you could do some kind of speculative blocking write within the transaction.
09:14chouserblocking so that the STM commit doesn't happen until the write is complete
09:14chouserspeculative so that an STM retry even after the disk write could still be "re-done"
09:16BjeringIf so I think that would solve it yes.
09:19chouserI guess I don't know how you'd finally "commit" that speculative write without still risking out-of-sync if something failed right after STM commit.
09:20chousermaybe at startup in such circumstances you could manually reveiw all writes that were neither committed nor rolled back and resolve them yourself. :-/
09:22BjeringAlthough I don't know how myself, I get the feeling its exaclty this kind of problem any DBMS has to solve to provide ACID. So there should be a well tested way.
09:23chouserrhickey: I like a queue. Our first-class asynch queue is an agent, so the handler is an agent and an action.
09:24chouserthis nicely closes the door on fixing the error and all its incidental complexity
09:25chouserthough it does leave the question of what is the meaning of the error-agent's state. hrmmm
09:25AWizzArdbtw, while you are at agents: is there a way to make agents await (await-for) for the job which was sent off in the current thread?
09:25AWizzArdCurrently I need to serialize parallel requests on my webserver to an external program. I do so via an agent and forward it a promise which I am setting inside the agent fn
09:26chouserAWizzArd: what's wrong with await and await-for?
09:26AWizzArdThis way I get for sure the value for the current thread.
09:27AWizzArdchouser: await does not return a value
09:27AWizzArdI mean, not the agents value
09:28AWizzArdwhen I deref the agent again it may already contain the result of a different request
09:28chouserah
09:28AWizzArdeven if the await will await only the current threads send
09:28AWizzArdSo I pass in a promise, and instead of await I will just deref the promise.
09:29chousernot a bad solution
09:30chouserand more or less what 'await' is doing anyway. :-)
09:30chouseroh, I see -- await is good for multiple agents
09:31AWizzArdyes, my solution is usable
09:31chouserwhich doesn't fit with your feature request
09:31AWizzArdit's maybe not too important
09:31AWizzArda special case of serialization
09:32chouserthere's an undocumented await1 that could potentially return the value of the agent at that moment rather than the agent itself
09:33chouserit could be implemented using a promise
09:34chouser(let [p (promise)] (send agent (partial deliver p)) @p)
09:36chouserheh. but don't actually do that.
09:38rhickeychouser: an agent isn't a full queue, it's a sink
09:38cgrandAWizzArd: or use java's futures with a single-thread pool
09:39chouser(let [p (promise)] (send a #(do (deliver p %) %)) @p)
09:39chouserrhickey: because you can't choose to pull, poll and/or block on it?
09:40rhickeychouser: right, it's not a conveyance. A queue might have multiple consumers, for instance
09:41rhickeywhen you need a queue, use a queue
09:43AWizzArdI see.
09:43rhickeychouser: I know fixing adds complexity, but it's not incidental. Without it, you are just leaving many real scenarios unaddressed - like action where order is important. Many of the complexities revealed by 'fix' still exist - what about the rest of the queued actions? the future life of the agent?
09:45rhickeyArmstrong's thesis remains a good read on error handling: http://ftp.sunet.se/pub/lang/erlang/download/armstrong_thesis_2003.pdf
09:45rhickeyI just don't know that we could/should dictate the strategy as Erlang does
09:49ambienti'd be happy if somebody actually told me how things should be done
09:50ambientmultiple ways of doing things, if there's really no difference between them, just makes things harder
09:52ambientthe ideal, for me, would be having just one proper tool for the job, and not having to choose between the red and the blue hammers, when there are no practical differences
10:18dmiller7,(namespace 'ab/cd/e)
10:18clojurebot"ab/cd"
10:19dmiller7http://clojure.org/reader says '/' can be used _once_ in the middle of a symbol to separate namespace from name
10:19dmiller7It is mute on multiple occurrences, but I always thought that would be an error.
10:19dmiller7Is this correct behavior?
10:20chouserI think the docs may be out of date on that.
10:20chouser(namespace 'http://foo.bar/qux/my-thing)
10:20chouser,(namespace 'http://foo.bar/qux/my-thing)
10:20clojurebot"http://foo.bar/qux&quot;
10:21rhickeychouser: thoughts on proposal at bottom of: https://www.assembla.com/wiki/show/clojure/Agent_exception_handlers ?
10:27chouserI haven't yet experienced the need for industrial strength error handling, just that agents' current default of reporting nowhere and killing the agent is pretty much never what I want.
10:28chouserSo I'm easy to please. Your proposal is entirely acceptible.
10:28chouseryou don't like tying :on-error :continue to the existance of a handler?
10:29rhickeychouser: no, because the handler could be just about centralized reporting, but the from-agent exception ties into the call chain, so if you wanted to fail because a component you rely on has failed, you can
10:31chouserdo you have something in mind for :die that's different than what agent-errors do now? For example, if you have 2 actions queued, A and B, even if A fails and queues an error, B will proceed.
10:31rhickeythe default can be :continue if handler
10:31rhickeychouser: what they do now is broken in the pending actions proceed
10:31rhickeyin that
10:32chouserok
10:32rhickeyas for un-die, dunno
10:33chouserif you could :on-error :pause, I wonder if you could get some error-fixing features without some of the complexity
10:34chouserhrm, maybe not. I guess you still have all the questions about what's paused. pending sends? pending watchers? etc.
10:34rhickeypause could be cool, but restart has it's own set of stuff - with what state, what about pending actions, is a restart an action (e.g. notifies watchers)
10:35rhickeywe could add later
10:35chouseryes
10:35rhickeythis seems to be the simplest thing that doesn't box us in
10:35rhickeyI'm ok w/o synch fix
10:36rhickeyuse a proper transactional queue if you never want to drop anything
10:37chouserwith a static :on-error policy, we have a perfect place to plug in broader changes if needed.
10:37chouserlater
10:37rhickeyyeah
10:37rhickeyjust a question about the meaning of :on-error with no handler
10:38chouserI mean, handler may currently fire after pending sends are cleared, but if :pause or something else were added it could change even that, having the handler fire earlier or whatever makes sense.
10:38chouserI wonder how often people use clear-agent-errors except manually at the repl
10:39rhickeyyes, the big toggle is on handler does policy or agent does
10:40rhickeychouser: yeah, clear-agent-errors is difficult for program policy
10:40chouserif it's not used much, maybe :die and stay dead is default?
10:41rhickey:on-error could be ignored if no handler - thus same as before semantics
10:41chouserkeep the broken queued actions proceed?
10:42chouseror maybe replace the error seq with a single error and all pending actions, pending sends, watchers, etc. are dropped.
10:42rhickeychouser: that's trickier, I'd like to fix it, but fix requires that clear-agent-errors restarts queuing, else clear and pending actions wouldn't happen
10:44chouserI didn't realize until yesterday that pending actions proceed after error, and so I hadn't understood how errors could ever have more than one exception
10:44rhickeyIt tends to happen that all actions sent before the first fails fail themselves, often due to some bogosity in the agent state, and you end up with a bunch of the same failures. simply clearing errors without being able to fix state won't help, so maybe throw away pending actions is best
10:45rhickeyi.e. if we are keeping clear-agent-errors the same
10:45chouserok. and this would be part of the :die policy that could be toggled to some new feature later
10:46rhickeyI saw this as separate from the die policy, as clear-agent-errors leavesa viable agent
10:46chouserah.
10:47rhickeywithout a handler, you are saying, I'll deal with this manually, with a handler, automatically, and thus policy-driven
10:48rhickeythen we can eventually deprecate clear-agent-errors since we haven't tied it into the new stuff
10:49chouserso :die means forever dead?
10:50chouserand no handler would mean something else -- hold the error, drop pendings, wait for clear.
10:58rhickeyI think :or-error :continue or :propagate (or something)
10:59rhickeythe latter will rethrow the error to future sends, and leave the pending actions in place, the agent suspended
11:00rhickeythen 2 functions - (clear-pending-actions agt) , and (restart a new-state)
11:00rhickeyso, no permanent death
11:01rhickeyonly ever one error on agent, we can get rid of the error list and clear errors at some point
11:01rhickeyyou can restart with the pending actions or with (by clearing them first)
11:01rhickeywithout
11:02rhickey:continue or :pause, :pause seems too weak for this state (throwing until restart)
11:03rhickey:continue or :fail ?
11:03rhickeya failing agent will throw until restarted
11:04rhickeygotta run for now, bbl
11:21AWizzArd,(doc await-for)
11:21clojurebot"([timeout-ms & agents]); Blocks the current thread until all actions dispatched thus far (from this thread or agent) to the agents have occurred, or the timeout (in milliseconds) has elapsed. Returns nil if returning due to timeout, non-nil otherwise."
11:22AWizzArdOn my system await-for returns false when timed out.
11:23stuartsierraFirst wave of survey results: http://groups.google.com/group/clojure/msg/df61abf2aca68985
11:25the-kennyI think some informations about Chunked Sequences should be provided ;)
11:25chouserheh
11:25chouserpart of what needs to be documented for 1.1 :-/
11:26stuartsierraSequences are a great abstraction; maybe we need ways to specify different kinds of sequences for different situations.
11:27stuartsierraE.g., chunked/unchunked, caching/non, lazy/non, ...
11:29stuartsierraRight now, the sequence interface is tied to a single implementation - chunked lazy sequences with caching.
11:30paosorry for the dump question
11:30paohow do I build a lazy seq starting from 1 to "infinity"?
11:30stuartsierrapao: (iterate 1 inc)
11:30paostuartsierra: thanks
11:31stuartsierrapao: you're welcome
11:32chouserwow, I was off by more than 50%. We've got many more 1.0 users than I thought.
11:33stuartsierraLots of people like downloading binaries.
11:33stuartsierraClojure's about the only Java software I regularly compile myself.
11:33the-kennyI think there should be a build-bot, as the github-checkouts tending to be very stable
11:34the-kennystuartsierra: Yes, same for me.
11:34the-kennyI have a small script for pull, update, clean and build for clojure and contrib
11:35stuartsierrathe-kenny: that's basically what Hudson does
11:35the-kennyhm.. never heard of it
11:36stuartsierrahttp://build.clojure.org/
11:37stuartsierraYou can always download the latest stable jar from http://build.clojure.org/job/clojure/lastStableBuild/artifact/clojure.jar
12:05bgs100Hi. How could you convert a list/vector of characters to a string? (Already tried str)
12:05hiredmanapply str
12:06bgs100hiredman, Thanks
12:16churibhm, in my irc-client ctrl-k doesnt seem to kill the line, it kicks people from the channel
12:22chouserrhickey: wrote up my understanding of your latest suggestions as Proposal B on the assembla page
13:03danlarkinmccraig mccraig of the clan mccraig?
13:12drewrdanlarkin: +1
13:30KirinDave2Is there a more formal way to do this (or am I doing something terrible that makes babies wail?)
13:30KirinDave2https://gist.github.com/4c8d5e355d69cd140811
13:32chousertaking keywords args like that is not uncommon
13:33j0niwin 1
13:33the-kennyKirinDave2: There is a special defn for functions with keyword argument in contrib
13:33the-kenny(contrib.core or so)
13:34chouseryou can also use destructuring to declare in one place what keyword arks you're expecting.
13:34the-kenny,(doc defnk)
13:34clojurebot"clojure.contrib.def/defnk;[[fn-name & fn-tail]]; Define a function accepting keyword arguments. Symbols up to the first keyword in the parameter list are taken as positional arguments. Then an alternating sequence of keywords and defaults values is expected. The values of the keyword arguments are available in the function body by virtue of the symbol corresponding to the keyword (cf. :keys destructuring). defnk accepts
13:34KirinDave2I should use that.
13:34KirinDave2Would be way better.
13:34KirinDave2I am surprised defn doesn't integrate that functionality by default.
13:35chouserKirinDave2: I might also recommend that you separate the creation of the object from modifying global state
13:35the-kennyKirinDave2: It's integrated in Common Lisp ;)
13:36chouserit has performance implications that keep it out of defn, I think.
13:36KirinDave2the-kenny: AndPLT Scheme
13:37KirinDave2chouser: I have separate functions for that as well, this is the state push. The :name is just a convenience.
13:37replaca_Rich wants function invocation to be as fast as raw JVM function calls can be. Keyword parsing would undermine this
13:38KirinDave2replaca_: I don't think that's a valid reason to dismiss the functionality being integrated.
13:38the-kennyreplaca_: I like the way it's now. Just use a seperate macro for functions with keyword-arguments :)
13:38KirinDave2replaca_: defn could make the decision if there are no keywords specified to use a faster piece of generated code.
13:39KirinDave2That's one of the many reasons why I love macros, they can have conditionals for optimizations.
13:39chouserI believe there was a proposal on the list for this
13:39KirinDave2Btw can you tell how heavily tasked I am at my job right now? :D
13:40KirinDave2No managers, just a computer installing software (AGAIN), and clojure writing a foosball scoring app.
13:40KirinDave2Yes, I work hard.
13:40KirinDave2chouser: Have there been proposals for macro-by-example systems as well?
13:41KirinDave2chouser: The more I read into it the more it looks like clojure could allow for this along with automatic capture protection.
13:41chouserI don't think anyone's made a deep proposal for macro-by-example.
13:42KirinDave2Doing an MBE without automatic capture protection is not terribly difficult.
13:42chouserI assume the biggest obstacle there is (perceived or real) lack of need.
13:42KirinDave2What's difficult is the protection.
13:42KirinDave2chouser: I dunno. Once you get used to MBE it's WAY clearer and faster for 90% of all macros.
13:42chouserclojure macros are already hygenic
13:42KirinDave2chouser: Uh, so symbol# was abolished?
13:42drewris there any limitation on using exceptions in fns called from proxy methods?
13:43KirinDave2chouser: If you have to decide which variables to gensym, it's not really hygienic.
13:44chouserKirinDave2: no, but if you forget in a context where you need a gensym, the compiler won't let you use your macro.
13:45KirinDave2Well anyways, I'm hoping that the new defproto stuff will make this very noun-y code easier.
13:51hiredmanKirinDave2: why not just use map destructuring directly?
13:51hiredman,((fn [{:keys [a]}] a) {:a 1})
13:51clojurebot1
13:51hiredmanno need for defnk
13:53KirinDave2hiredman: Now you're passing a map in though
13:53hiredmansure
13:53hiredmanwhy not?
13:53KirinDave2hiredman: That's why.
13:54KirinDave2Because unless that's done implicitly that's a tedious convetion for the caller which is seldom consistent.
13:54KirinDave2hiredman: Calls in clojure pass maps when they mean to pass maps, not as a convention for keyword args.
13:54KirinDave2hiredman: Further there are already examples of keyword args and they are not maps.
13:54hiredmanKirinDave2: those examples are dumb
13:55hiredmanKirinDave2: the difference between what you want, and what is by default available in every binding form is a single set of curly braces
13:56KirinDave2hiredman: Yes.
13:56hiredmanso just use the curly braces
13:56KirinDave2No.
13:56KirinDave2It's ugly. Sorry.
13:56KirinDave2Small differences count here.
13:57hiredmanhow is it ugly?
13:57KirinDave2Worse than ugly, it's inconsistent. That's not an acceptable tradeoff.
13:57hiredmanhow is inconsistent?
13:57hiredmankeyword args are a map
13:57KirinDave2Some keyword args are as maps, some keyword args are inline.
13:57KirinDave2Keyword args get represented to the callee as a map
13:57KirinDave2but standard destructuring syntax (i.e., :as …) is not represented as a map to the callee.
13:58KirinDave2err, the callerr
13:58hiredmanKirinDave2: it is a linear collection of things
13:58hiredman[[a b]] vs {:keys [a b]}
13:58hiredmaner
13:58hiredman[[a b]] vs [{:keys [a b]}]
13:59KirinDave2hiredman: Do you get that I don't agree with you at all yet, or shall we continue?
13:59hiredmanI get that you are stuck in the mud
13:59KirinDave2hiredman: I do appreciate help, but I find that decision unacceptable. Especially when the much more consistent defnk is already written and available.
13:59hiredmanbut I am just so tired of defnk and apply hash-map
14:00KirinDave2So maybe it would make sense to provide something like & for this kind of mapping?
14:00hiredmanno
14:01KirinDave2[% :a 1 :b 2]
14:01hiredmanmap destructuring is fine as is
14:01hiredmandefnk actually generates a map at runtime from keyword args
14:01KirinDave2Does it support defaults?
14:02hiredman~destructuring
14:02clojurebotdestructuring is http://clojure.org/special_forms#let
14:02hiredmanyes
14:02KirinDave2Okay. Well I'm going to use denfk though. In fact, I just did.
14:03chouserreference type factory methods also use apply hash-map to generate a map at runtime from keyword args
14:03chouseragent, ref, atom, etc.
14:04hiredman:(
14:05hiredmanI am well aware of the prevelance of apply hash-map
14:05chouserI guess I don't see the problem
14:05chouserdoing work in an API to make life easier of the API-user seems right to me
14:06hiredmanchouser: which map destrucuring does
14:06chouseryes, but requiring users of my fn to insert extra {} does not
14:06hiredmanwhy?
14:07hiredmanclojure has literal maps, they are not some add on
14:07KirinDave2Well, the major weakness of lisp syntax (and smalltalk caller syntax, incidentally) is that it requires prediction. Increasing the depth of that prediction is not a good idea.
14:07chouserwhen used in a fn call where they aren't required, the extra {} is just clutter
14:08KirinDave2At least with paredit mode it's easy when you get the prediction wrong.
14:08hiredmanchouser: you don't need them in every fn call, just the fns that expect a map
14:08KirinDave2But adding extra glyphs just to make the author's life slightly easier.
14:08KirinDave2hiredman: Hence inconsistency, again.
14:08hiredmanhow is that inconsistent?
14:08hiredmana map is a value like 1 or 2, or a list
14:09KirinDave2Because you're not passing a map. the function doesn't require a map
14:09KirinDave2You're using a map as a calling convention.
14:09KirinDave2You're asking the caller to think about your impl details.
14:09hiredmanthe function does require map
14:09hiredmanif the function did not require a map, then why are you generating one?
14:10chouserwhy would I want to write (ref v {:meta m}) when I could write (ref v :meta m) ?
14:10hiredmanchouser: why write (ref v :meta m) when you can write (ref v {:meta m})?
14:12chouserbecause in that case the {} is unnecessary clutter
14:13chouserto be more purely what 'ref' itself care about there would be no keyword args at all, and I'd have to write (ref v nil nil nil m nil) or something.
14:13hiredmanref treats those params as a map, and generates a map internally
14:14hiredmanso a {} is exactly what it is
14:14chouserand then destructures the map to get at the specific values for :meta and :validator
14:14chouserwhat ref really wants is meta and validator args
14:14chousernot a mpa
14:14chousermap
14:15hiredmanI'm late for work
14:15slyrus_has anyone tried getting swank-clojure to work with the "new" branch?
14:16chouserhiredman: ok, ttyl. :-)
14:16the-kennyslyrus_: It's working here.
14:17slyrus_the-kenny: hmm... wonder what I'm doing wrong. master HEAD works fine, but I get java.lang.NoSuchMethodError: clojure.lang.RestFn.<init>(I)V (pprint.clj:1) with new
14:17the-kennyslyrus_: You have to recompile contrib, clojure and maybe swank-clojure itself.
14:17the-kenny(a complete rebuild, with ant clean)
14:18slyrus_oh, forgot about contrib. thanks the-kenny.
14:18the-kennyYou're welcome
14:18the-kennyclojurebot: restfn
14:18clojurebotI don't understand.
14:18the-kennyclojurebot: RestFn
14:18clojurebotExcuse me?
14:18the-kennyhm ok
14:20slyrus_the-kenny: that works. thanks again!
14:21slyrus_it would be nice if "new" bumped the version number or name such that both master and new didn't say: "Clojure 1.1.0-alpha-SNAPSHOT"
14:22chouserheh. that's a good point. There was much wrangling over just getting what we've got.
14:23chouserI guess it was assumed that alpha-SNAPSHOT was sufficient to communicate the broad category of unreleased versions people might be using.
14:23technomancyconsidering new is not going to make it into 1.1.0, it could be considered misleading
14:24slyrus_and the name "new" itself is rather suspect, IYAM. something that describes the functionality (protocols, perhaps?) rather than the age of the branch would seem appropriate
14:24dysingerslyrus_: also we could have "new" in the maven repo if it didn't have the same version.
14:24slyrus_but, hey, who am I to complain? :)
14:25dysingertechnomancy: I think the point is "not the same version & qualifier as master"
14:25slyrus_i'm sensing a common theme here...
14:26chouser"new" *does* describe the feature, it's just the feature go renamed from 'new' to 'reify'
14:26chouserit's not "new" as in less old, it's "new" as in (new Foo) was getting updated features.
14:27slyrus_chouser: ah! I see... never mind then :)
14:27chouserheh
14:27slyrus_let's hope the inverse of reify isn't named old
14:28alinphi guys
14:28alinpis there a way to use time for a map ?
14:28alinpe.g. (time (map fib (list 38 39)))
14:28alinpwhich is not working accordingly
14:28the-kennyalinp: doall
14:29alinp(time (doall (map .... ?
14:29the-kennyYes
14:29alinpcool, thanks
14:29the-kenny(time (doall (map inc (list 38 39))))
14:29the-kenny,(time (doall (map inc (list 38 39))))
14:29clojurebot(39 40)
14:29clojurebot"Elapsed time: 0.172 msecs"
14:29alinpyeah, that's right
14:29the-kennyhm... bad example ;)
14:32alinpah, map is returning a lazy seq
14:32alinpthat's why time is irelevant when used with a lazy seq
14:32alinpand that's why doall is needed ;)
14:33chouserClojure 1.1.0-new-alpha-SNAPSHOT
14:33chouseruser=>
14:33the-kennyalinp: Exactly
14:35technomancychouser: nice; thanks.
14:35dysingerInice
14:35chouserwell, I can't check that in
14:35chouserwithout approval
14:36lisppaste8Chouser pasted "tweaking clojure version reporting" at http://paste.lisp.org/display/91109
14:37chouserbut it makes sense to me for public branches to contain tweaks like that.
14:37dysingeragree
14:37chouserWhen doing a major merge from, say, 'new' to 'master', we just have to remember to correct the version number.
14:37alinpThe thing is that I knew a while a go that doall is needed
14:37alinpbut ... I forgot exactly why
14:37alinpand I used it like this: (doall (time (map .... :)
14:37alinpobviously is not right
14:37dysingerwe can the build them on the CI server and have them accessable to lein, mvn & ivy
14:37dysingers/the/then
14:38chousermaybe it would make more sense to replace the word "alpha" with the branch name
14:38dysingerskeptomai ! {hello}
14:39chouser1.1.0-master-SNAPSHOT, 1.1.0-new-SNAPSHOT, etc.
14:39dysingerchouser: agree
14:39skeptomaidysinger: how are things?
14:39chouserassuming we don't do non-SNAPSHOT pre-releases
14:40dysingerskeptomai: great - see otp news today re: github :)
14:40dysinger?
14:40skeptomaialready forked & built. putting my crypto changes in now :)
14:40skeptomaiit's a happy day
14:41dysingerskeptomai: there's already 11 forks and 170 watchers in a couple hours
14:41skeptomaiclearly much of the community has been waiting for this
14:42dysingeryes
14:42skeptomaiI'm still puttering about with the otp_build script and understanding how it's supposed to work though
14:49cemerickwell, it's (mostly) settled, I'm getting dragged into maven. Joining the dark side, as it were.
14:49chouservia lein?
14:50cemerickno, totally divorced from that
14:51cemerickI had cooked up my own little dependency mgmt system based on git submodules...which is *way* nicer than ivy or maven for smaller stuff, but it's now creaking under the weight of our aggregate codebases.
14:51alexykhow do you take a length of a list or a vector?
14:51chouseralexyk: count
14:51cemerick,(count [1 2 3])
14:51clojurebot3
14:52chouseralexyk: use 'counted?' to see if its fast or slow for a certain object.
14:52chouser,(counted? [1 2 3])
14:52clojurebottrue
14:52alexykis it the same for a seq?
14:52chouser,(counted? (map inc [1 2 3]))
14:52clojurebotfalse
14:52chouser,(count (map inc [1 2 3]))
14:52clojurebot3
14:52chouseralexyk: yes, 'count' works on seqs
14:52chouserbut it's linear time
14:53chouserconstant time on lists and vectors (where counted? is true)
14:53alexykhow can I measure the time someting takes, e.g. the count on a long seq?
14:53cemerickdue respect to technomancy, I can't bring myself to jump on lein yet. By the time we're transitioned to maven, lein will be matured (for a clojure project).
14:53chouser,(time (count (map inc [1 2 3])))
14:53clojurebot3
14:53clojurebot"Elapsed time: 0.164 msecs"
14:54alexyknice
14:54technomancycemerick: of course; it's only been announced for a week. caution is prudent.
14:54cemericktechnomancy: I'm rootin' for you, though :-D
14:55danlarkinwe're trying!
14:55cemerickA friend of mine is using lein for a side project of his, so I can draw karma from there.
14:55chouserI'll have to try out lein and clojars for clojure-jna or something.
14:56cemerickwhat do people here use for internal maven repos, anyway?
14:57technomancycemerick: you can just drop ~/.m2/repository behind a static web server, but hudson is pretty easy to set up too, and you get CI as a bonus.
14:58rhickeychouser: your subset example shows a problem - now the validity of clear-pendind-actions and restart call into question their validity in a handler
14:58cemericktechnomancy: hrm. If it's so easy, when what's with all the commercial options?
14:58chouserrhickey: I thought they might. :-)
14:59rhickeyI don't see the equivalence you are making
14:59rhickey:continue doesn't clear actions
14:59technomancycemerick: auto proxying-and-caching jars from central is nice, I guess. I don't really know beyond that.
14:59alexykeverybody in JVM world cooks up their own build systems. Which is the one preferred in clojure these days?
15:00cemerickhrm, if that's all it is....
15:00rhickeyand restart must kick the queue off again, tricky while in action
15:00chouseroh, yes, I seem to have confused myself.
15:00alexykbtw, for maven, it would be nice to have full pom.xml files in clojure and clojure-contrib
15:01rhickeyso maybe (restart a new-state :clear-pending-actions true/false), only allowed on failed agent, and an agent failing is not yet failed
15:01chouserthe actions pending sends are thrown away on error immediately. clear-pending-actions is about actions queued from elsewhere.
15:02rhickeyactions are about the agents queue
15:02rhickeymaybe just clear-actions
15:02chouserright, I tripped up, thinking clear-pending-actions was about the held sends
15:03rhickey(restart a new-state :clear-actions true/false)
15:03rhickeydefault :clear-actions false
15:03chouserI like that.
15:03rhickeybut the important job of restart, reprimingthe queue, can't happen in an action
15:03rhickeyso calling restart in handler a no no
15:04chouserI don't see why yet.
15:05rhickeythat pop/CAS stuff is very tricky
15:05chousermaybe it'll be clear when I go to implement. :-)
15:06rhickeyit ensures that only a returning action or a new dispatch to an idle agent will place a single action into thread pool, and that the agent never stalls
15:06rhickeyalso ensuring the one-thing-at-a-time rule
15:07technomancyalexyk: I recommend http://github.com/technomancy/leiningen, but I'm admittedly biased
15:07rhickeyso you are in the middle of handling an error, haven't even set the error state up, and restart is called - what is it going to do?
15:08rhickeyvs you have a failed agent not in an action, with a stalled queue - what is retart going to do?
15:08rhickeythe latter case is the one we need, the former somewhat pathological - not yet failed or stopped
15:09chouserok, I see. Being in a state of :fail but not yet done with handler is broken
15:09rhickeyyeah, and restart needs to spin the queue up again
15:10rhickeywhich will be tricky enough
15:10chouserso agent goes to :fail atomically after handler is done
15:10rhickeyi.e. its interaction with dispatch
15:10rhickeychouser: right
15:10chouseruntil then, send is ok but restart is an error
15:10rhickeyright
15:12chouserafter agent is :fail, send is error but restart ok.
15:12chouserrestart goes atomically back again.
15:12rhickeyI'm wondering if we should throw on deref of failed or not
15:12rhickeyright
15:13chouserok, I put that in because of current behavior, but didn't consider alternatives
15:17rhickeyso, just a single restart function, always taking a state and optionally a clear-actions flag?
15:17rhickeyrestart never notifies watchers
15:18rhickeyrestart state could fail validation, immediate exception, stays failed for original reason
15:18chouserok
15:18chouserwant a keyword arg on restart, or just true/false?
15:19rhickeykeyword
15:20rhickeyputting it in restart saves us from having to define when clearing is ok
15:21chouseryes, and it's pointless to clear unless you intend to restart
15:21rhickeyright, we don't want a separate clearing concept
15:22chouserno backward compatibility for clear-agent-errors or agent-errors? We could try to deprecate but leave a "similar" behavior for now.
15:23rhickeythe latter
15:23chouserclear-agent-errors is a bit like (restart @a :clear-actions true)
15:23rhickeythere will never be more than one error, but we can wrap in list
15:24chouserI mean (restart @a :clear-actions false)
15:24rhickeychouser: since the actions went through before, it's like (restart a @a)
15:24chouserright
15:24rhickeywhic is how it should be defined now
15:24chouserok
15:24rhickeyand deprecated
15:25chousernew agent-error to retreive the single exception?
15:26alexykhow do you use reduce to count the size of a collection, i.e. to implement count? just for learning
15:27chouser,(reduce (fn [count _] (inc count)) 0 '[a b c d e])
15:27clojurebot5
15:28alexykah... I've tried: (reduce #(inc %1) 0 [1 2 3]) ; failed -- why?
15:28chouser#() looks at the highest-numbered % to see how many args it should expect
15:28chouserin your case, 1. But reduce calls with two args.
15:28alexykchouser: so I'd have to uselessly employ %2
15:29chouseryes
15:29alexykhow?
15:29chouserdon't
15:29chouser:-)
15:29alexyki.e. what's a null way to use it? just for fun
15:29chouser(fn [count _] ...) is clear -- I'm taking a second arg and ignoring it (the idiomatic meaning of _ in clojure)
15:29chouser,(reduce #(do %2 (inc %)) 0 '[a b c d e])
15:29clojurebot5
15:30chouser^^^ less clear
15:30alexykhmm, %2 ... % -- so % always means %1?
15:30chouseryes
15:31timothypratleyhow do I git the 'new' branch to test a patch against it? the 'new' branch doesn't appear when a do a normal git clone...
15:31alexykand do returns the last value, so %2 is evaluated and discarded?
15:31chouseralexyk: yes
15:31alexyktimothypratley: git checkout -b new origin/new, or something like that
15:31timothypratleythanks!
15:39rhickeychouser: yes, agent-error
15:40alexykif I have a prog.clj file, do I need to compile it to run?
15:40alexykor just unleash clojure on it?
15:40chouserrhickey: I'm updating assembla now
15:41rhickeychouser: thanks
15:43hiredmanif I have two vars that == says are not the same, why would alter-meta! on one effect the metadata on the other?
15:43rhickeyhiredman: ==?
15:44rhickeydid you mean = ?
15:44hiredmanshould I be using =?
15:44rhickeyalmost always
15:44hiredmanoh right
15:45hiredmanI want identical
15:45hiredmanI want identical?
15:45rhickey= for reference type is identical, use =
15:45hiredmanok
15:45rhickey== is for numbers only
15:45hiredmanand it, of course, returns true, which explains the problem
15:46hiredmanthanks
15:46rhickeynp
15:56qedalexyk: You could C-c C-k it if you have a slime repl open in emacs, otherwise yes, you need to compile it
15:57the-kennyC-c C-l is possible to (slime-compile-file or something is mapped to this)
15:57the-kennyEw I mean slime-load-file
15:59alexykthx!
15:59qedyeah or that
15:59qedor C-c at the end paren of a line to load aprts of it into slime
15:59qedC-c C-c
16:00qedI wish there was some way for me to hit a hotkey at the end of a function im writing in a SLIME repl that would paste it into a currently open corresponding buffer
16:00qedthe-kenny: do you know if that's possible?
16:00the-kennyI'm sure it's possible.
16:00qedsometimes i test something and then i have to re-write it quick or copy/paste it, it would be nice to just pop it over from slime
16:01the-kennyShould be a few lines in elisp...
16:01the-kennyJust press C-M-b, M-x mark-sexq, M-w, C-c o, C-y :D
16:01the-kennyYou could record a macro for that
16:01qedhaha, too much work!
16:02the-kennyThen just create a macro :)
16:02qedsure, i think that's what ill do
16:02qedhow do you record a macro?
16:02the-kennyEw.. I don't know
16:02qedill figure it out
16:02qedthanks though
16:02the-kennyNo problem
16:05the-kennyI think it's fairly easy to write a "real" function for that. Just write out these shortcuts
16:05the-kenny(There's also M-x copy-to-buffer, maybe that's helpful)
16:07qedyeah thats better
16:07qedthat way ill just copy to whatever .clj is open
16:16zaphar_pswget doesn't like clojure.org
16:17zaphar_psit keeps asking for index.html which gets it a wikispaces page instead :-(
16:17zaphar_psback to the drawing board
16:28KirinDave1Is there an elegant way to insert something into a vector at index n, displacing the other elements?
16:28KirinDave1Or is that a for loop?
16:28hiredmanassoc
16:28hiredman,(assoc [1 2 3] 0 4)
16:28clojurebot[4 2 3]
16:28chouservectors are no good at shifting around their elements
16:29KirinDave1Is there a way todo that for lists?
16:29hiredmanoh
16:29hiredmandisplay
16:29chouserinto and subvec is about as good as it gets for now
16:29KirinDave1Okay, so it's a for loop. :)
16:29KirinDave1That's fine, just wanted to make sure I wasn't missing anything.
16:29hiredman:|
16:30chouseryou're missing finger trees is what you're missing
16:30hiredmanit's definite possible to do it as a lazy-seq
16:30KirinDave1chouser: Pardon?
16:31rhickeyKirinDave1: you really want a data structure oriented towards insertion, and none of the Clojure data structures are like that. There is a finger tree in the works that will have fast insertion. operations that would have linear time are usually not included (there are some exceptions)
16:31KirinDave1What I want is given (let [ladder '(:a :c :d)] (displace ladder :c :b)) => (:a :b :c :d)
16:32chouser,(let [v '[a b c d e]] (-> (subvec v 0 2) (conj 'X) (into (subvec v 2))))
16:32clojurebot[a b X c d e]
16:32hiredmanchouser: if he is fine with a seq or list instead of a vector, it is doable as a seq
16:32KirinDave1rhickey: It's fine if I just do it as a list in this place, the size of this structure is limited to 10.
16:34technomancyfoosball doesn't scale
16:34chouserhehe
16:35KirinDave1technomancy: It's the "ladder"
16:35KirinDave1Which is the top 10 teams.
16:35KirinDave1Not by absolute wins, but by wins recently.
16:35chouserrhickey: assembla updated. still some questions about handler args and what to do if a handler throws
16:35hiredmanit's a ring buffer
16:36KirinDave1hiredman: Is it?
16:36hiredmanwell, not really
16:36KirinDave1Actually this foosball project has been surprisingly good as way to get familair wih clojure. And I'm really excited to get to the compojure part of it.
16:36hiredmanhmm
16:38arohneris there a way to refer to the "default" (.assoc) method for a deftype that implements IPersistentMap?
16:39arohnerI'd like to write my own validator for a deftype. I was thinking that I could do something like (.assoc (my-validator ...) (default-assoc-method))
16:39hiredmanarohner: I think the idea is you don't hang methods on deftype
16:40chouserI think that default method is generated only if you don't provide your own implementation.
16:40hiredmanbut assoc would be a operation in the protocol Associative
16:41arohnerhiredman: is there a protocol Associative yet?
16:41hiredmanarohner: ask chouser
16:41chouserno, clojure lang interfaces don't have protocols yet, afaik
16:44rhickeychouser: reading
16:45ordnungswidrigre
16:53rhickeychouser: I've updated, with answers to al q's, but am still unsure about :on-error default when handler provided
16:53qedrhickey, you wont sue me for buying getclojure.org/com will you?
16:54drewrqed: that entirely depends on what you do with it
16:54rhickeyqed: dunno - what are you going to do with them
16:55qedhaha, it's just going to be a clojure learning site, beginner/intermediate/advanced tutorials and examples, and then links to off-site reference material
16:57qedfor free of course...
16:57qedare you consulting a lawyer?
16:58hiredmancrack team of legal beagles
16:58danlarkinBob Loblaw
16:58djorkgetclojure.com -- where you can buy a clojure + contrib jarfile with enterprise license for the low price of $4999
16:58djorkhah
16:58djorkBob Loblaw Lobs Law Bomb
16:59djorkalso http://thebobloblawlawblog.blogspot.com/ (not really related)
16:59djorkok that's enough of my rambling
17:02chouserrhickey: :continue is a poor default when there's no handler. I suspect :fail is going to be relatively uncommon when there *is* a handler.
17:03chousermaybe if we list the handler first document it carefully, changing the default won't feel like bad magic?
17:03rhickeychouser: right, that's why I initially advocated the 'magic'
17:03KirinDave1blugh thats not pretty. :\
17:04KirinDave1https://gist.github.com/c1345f116c96f19564c4
17:04chouseror could default to :continue with a default handler as well.
17:04chouserthat ... prints the exception to *err* or something.
17:05KirinDave1I guess I could move that calc out ofthe let and maybe abstract an index function.
17:05rhickeychouser: or just a user-supplied default handler
17:05chouserKirinDave1: there's an indexed function in contrib seq-utils
17:05KirinDave1chouser: I suppose it's not ugly given that I wrote the whole thing without that. :D
17:05chouserKirinDave1: but you might try avoiding indexes altogether. insert using mapcat or something.
17:06rhickeychouser: I'm not sure I consider it magic to say - if there's a handler it won't fail (by default) and if no handler it will, unless you explicitly say otherwise
17:07rhickeyless about the default value of a flag than what it means to have a handler
17:07chouseryeah, with careful docs may not be bad. Feels worse if there are other policies later.
17:09chouserwell, this should be plenty to start coding. not sure when that will happen :-/
17:09rhickeywell, the fact of it is there is no universally good default
17:10rhickeychouser: do you still want to shoot for 1.1., or should we just approved backlog it?
17:10rhickeyno code made it in already did it?
17:10chouserright, no code. just an aborted patch
17:11rhickeysounds like post 1.1
17:11chouserI would hate to hold up 1.1 -- this is the last patch. otherwise just docs, right?
17:11rhickeythere's still: https://www.assembla.com/spaces/clojure/tickets/210
17:12rhickeypatch fails tests
17:13timothypratley1Hi rich
17:13timothypratley1I've found the reason for that!
17:13rhickeysince there is so much new-ness in this agent thing I think definitely post 1.1
17:13chouserok, fine with me
17:13michaeljaaka, (letfn (me [mm e] e) 12 )
17:13clojurebotjava.lang.RuntimeException: java.lang.RuntimeException: java.lang.IllegalArgumentException: Don't know how to create ISeq from: clojure.lang.Symbol
17:13michaeljaakawhat is wrong with that?
17:13chousermichaeljaaka: still need []
17:13rhickeytimothypratley1: and?
17:13chouser,(letfn [(me [mm e] e)] 12)
17:13clojurebot12
17:14michaeljaakaok
17:14timothypratley1the problem with #210 is more deletion is required :) For some reason there are some other shadowed methods
17:14timothypratley1which work fine on my setup
17:14timothypratley1but I can see if they get called (and they are on your report)
17:14timothypratley1would fail
17:14timothypratley1Its a trivial fix
17:14michaeljaakachouser: the doc doesn't say that
17:14timothypratley1but I'm struggling with making the git patch atm
17:14timothypratley1sorry taking so long
17:14rhickeytimothypratley1: np
17:15chousermichaeljaaka: "Takes a vector of function specs"
17:15michaeljaakachouser: ok :)
17:25mccraigdanlarkin: aye, tis me
17:26timothypratley1rhickey: patch is up http://www.assembla.com/spaces/clojure/documents/bHx3hk2Her3QkseJe5aVNr/download?filename=ssb2.diff for #210 just FYI :)
17:46qedis there a partition-with floating around?
17:46qedi seem to remember one existing in a contrib pkg
17:47danlarkinprobably in seq-utils
18:10rhickeyhttps://www.assembla.com/spaces/clojure/tickets?milestone_id=93750&amp;tickets_report_id=5
18:12chouserso ... what now?
18:12chouseroh, I remember. ...dinner.
18:13timothypratley1cool! :)
18:13nathanmarzis there any sort of object I can use in clojure that can be destructured as either a seq or a map?
18:13rhickeytimothypratley1: thanks for the patch
18:14timothypratley1np :)
18:17Knekkhow do I cast a float to an int again?
18:18timothypratley1,(doc int)
18:18clojurebot"([x]); Coerce to int"
18:18timothypratley1,(doc cast)
18:18clojurebot"([c x]); Throws a ClassCastException if x is not a c, else returns x."
18:18Knekkthanks
18:21nathanmarztried using LinkedHashMap, but it doesn't respond to "nth"
18:23rhickeynathanmarz: LinkedHashMap doesn't implement RandomAccess
18:24nathanmarzi see
18:24rhickeynathanmarz: nth doesn't make sense for non-sequential things, and isn't fast for non-indexed things
18:25nathanmarzyea, that's ok for my use case, just want the convenience of it
18:25rhickeyyou can always seq it first
18:26nathanmarzbut then it wouldn't be able to be destructured as a map?
18:27rhickey, (nth (seq (java.util.LinkedHashMap. {:a 1 :b 2 :c 3})) 1)
18:27clojurebot#<Entry :b=2>
18:28rhickey,(let [[a b] (nth (seq (java.util.LinkedHashMap. {:a 1 :b 2 :c 3})) 1)] [b a])
18:28clojurebot[2 :b]
18:28rhickeylegos
18:32nathanmarzhmmm, let me clarify
18:32nathanmarzi want to be able to say (defn foo [[a]] ...)
18:32nathanmarzor (defn foo [{a :field1}] ...)
18:33nathanmarzwhere both versions are passed the exact same object, some sort of ordered map
18:34rhickeyin the first case you'll have to move the destructuring into a let, (defn foo [amap] (let [[a] (seq amap)] ...
18:36ChousukeWhich reminds me, what happened to the -> destructuring?
18:36nathanmarzif i wrote a class in java which implements map and randomaccess, would that work?
18:36Chousukeis there a ticket on it or was it just irc talk?
18:43rhickeynathanmarz: clojure.lang.Indexed is the simplest way to add nth
18:44nathanmarzrhickey: thanks, will check that out
18:44rhickeyfor RandomAccess you also have to implement j.u.List, which is a bigger deal
19:08cadshey it possible to somehow reduce the number of parentheses in lisp expressions by defining an equivalent enriched syntax?
19:09carkhehe not gain !
19:09carknot again i mean
19:09cadshehe, I'll try to be as non-aggravating as possible with this line of question :D
19:10carki guess you're new to lisp ?
19:10chouserChousuke: https://www.assembla.com/spaces/clojure/tickets/211
19:10hiredmanit's not aggravating, just, you know, something that has recured since the begining of lisp
19:10chouserthere's even a reader for Clojure that does it
19:11cadsnaw, I've studied lisp a bit, built a toy version and such... but I'm also interested in m-expressions as well
19:11chouserand, as it has been since the begining of lisp, nobody uses it much
19:11cadschouser, I remember reading about something that does something like this which can be used to wrap virtually any lisp
19:11hiredmanso you will have to prove you have something better/different over the last 100 or so attempts that no one cares about or uses
19:12_atosweet-expressions or some such
19:12carkyou'll end up with as many brackets either way, they could be curly, begin/end or python style spaces, but they'll be there
19:12cadshiredman, I'm just interested in something to make my own coding more fun, I don't really have any ideas :)
19:13cadsI think I got the idea of using unicode math charachters for function names from someone's code repository here - I love that
19:13_atooh no
19:14_atoall well and good until someone tries to call you function and can't figure out how to type your crazy character
19:14hiredman,(pl (↕map (replicate 3 (↕apply vector $ (↕map range $ 10 inc · inc · inc) call · ⌽* $ 10 · call · (⌽+ -2) map)) shuffle))))
19:14clojurebot((60 100 70 50 10 30 20 90 40 80) (100 40 20 60 90 70 80 50 30 10) (100 50 90 40 70 20 60 80 30 10))
19:15cadsoh, it was you hiredman. kudos.
19:15hiredman:)
19:15cadsato, with a little editor support it's really convenient and mnemonic
19:15carkhaha hiredman loves to show off his point free skills !
19:16cadsbut I agree that I would at first be inconvenienced using someone else's notation
19:16_atocads: http://www.dwheeler.com/readable/
19:17carkspa mal
19:17_atopersonally I can't really see the point
19:17_atoit just makes the syntax more complicated
19:17carkerr ignore that
19:17cadsI've used Lisp my whole programming life and I still don't find prefix math expressions natural. - Paul Graham
19:19Chousukecads: if you can represent lists, vectors and maps with reduced delimiters while keeping the macro system as powerful and straightforward as it is, that might be interesting
19:19cadsthat mostly hits it on the head, there are more human understandable ways of encoding term trees
19:19hiredmanonly for a subset of trees
19:19hiredmanmath trees
19:19cadsChousuke, that would remind me of the kind of things the mathematica language does
19:20hiredmansome other kid of tree
19:20hiredmanand they might have different representations
19:20ChousukeLuckily you often don't need to write big math expressions in lisp :P
19:20Chousukeor if you do, you should break them into smaller functions :)
19:21hiredmanor just write a parser
19:21chouser~infix
19:21clojurebotinfix is not worth the trouble; see http://groups.google.com/group/clojure/browse_thread/thread/319a1c77ed718ba/3e4be7484b7cbe38
19:21cadswish there was a way to turn a mathetical derivation of an algorithm directly into code :/
19:22liebkespeaking as someone that does write lots of math expressions in clojure, it starts to feel very natural after a while :)
19:22Chousukeit's always possible to write a macro like (math [1 + 2])
19:23funkenblattyeah, i usually do that
19:23cadshmm
19:23funkenblatti also like to add a macro for reverse polish notation
19:23Dawgmatixfwiw - the usual syntax feels pretty normal after a while :)
19:23carktime to introduce the notion that remembering precedence rules is a pain
19:24cadsyou mean it's hard to remember whether something has left or right precedence and associativity?
19:24funkenblattit's a lot easier to remember if you get to set precedences yourself
19:24funkenblatthence the advantage of writing your own macro for it
19:25chouserI have even have a non-macro fn that does infix, but I can never find it.
19:26chouserah, there it is http://paste.lisp.org/display/75230
19:26chouserask me how often I've used it in actual programs
19:26chousergo on, ask me
19:26chouserthat's right, never. :-)
19:27cads:P
19:27cadswell yeah
19:28ChousukeHm.
19:28ChousukeI found a version of Lord of the Rings written in Northern Finnish dialect. This is amusing.
19:29hiredmanhttp://www.ted.com/talks/barry_schwartz_on_the_paradox_of_choice.html <-- speaking of choice I was just watching this
19:29hiredman(choice of precedence, choice of parens or not, etc)
19:31cadsI wonder how often people use haskell's quasiquoting... it lets you define a monadic parser for some expression type and then you can use that grammer in your code, but you have to enclose it like this: eval [$expr|1 + 3 * 5|], where the expression inside the || folls your own rules
19:32hiredmanpossibly applies to the choice of currency primitives
19:32cadsI just don't think I'd often go through the trouble of typing eval [$exprtyp||], and I'd get sick of reading it
19:33funkenblattdepends on how complicated your expression is going to be i guess
19:33cadsis that why you don't use your infix thing, chouser?
19:34hiredmancads: embed your expression as a string and write use fnparse
19:34hiredmaneopl assumes some scheme parsing package, but when I first gut it I started futzing with fnparse
19:35hiredmanand ended with something that spit out valid clojure for the first toy language
19:35cadslemme see what this fnparse is about
19:35hiredmanwhich defeated the point, because I could just call eval on it instead of interpreting it myself
19:38hiredmansomething in my irssi freaks out if I try to tab complete a space
19:43cadswish it was easier to find papers about hybrid lisp systems, the all seem to be about scheme or cl. But for example mathematica, which is made of pure expressions where each expression, whether it is a form using advanced LaTeX like typesetting or a basic ascii expression, has a lisp like form
19:43cads4
19:43cadserr
19:43cadsignore that..
19:44defn`best way to convert ("10" "00") to (10 00)?
19:44cadsmap a str -> num function over your list
19:44Knekk_Integer.parseInt()?
19:45defn`like (apply #(num %) ("10" "00"))?
19:47chouser(map #(Integer/parseInt %) ["10" "00"])
19:47the-kenny,(map #(Integer/parseInt %) ["10" "00"])
19:47clojurebot(10 0)
19:47chouserding ding ding
19:47the-kennyFirst :)
19:47defn`No way to do it with num or int?
19:48chouserno
19:48cadshired man, it's so cool to write a family of functions represented by a single symbol indexed by a subscript! Even though that's simply seen as a function with an additional parameter, it is useful, maybe I get this from doing math
19:48defn`really? no way at all? That seems weird, I feel like I've done this before
19:48twbrayFor your pre-Thanksgiving pleasure, more Clojure I/O grinding: http://www.tbray.org/ongoing/When/200x/2009/11/25/Clojure-grinding
19:49avitalGood night
19:49avital,(print-str '(""))
19:49clojurebot"()"
19:49avital,(print-str '("a"))
19:49clojurebot"(a)"
19:49avitalIs this a bug? Shouldn't it be "(\"\")" and "(\"a\")" respectively?
19:50Chousukeprint prints for humans
19:50Chousuke,(pr-str '(""))
19:50clojurebot"(\"\")"
19:50avitalAha I see
19:50avitalRight
19:51avitalSuddenly it does make sense... Ok right so the bug I had when using pr-str was because of something _I_ was doing...
19:51technomancytwbray: wow, that's a bummer to find so much time is getting wasted on the UTF-16-ness. kind of powerless to do much about that. =\
19:52twbrayI should go look at the Java library source code; seems like it shouldn't be that expensive.
19:55defn`w00t, I just got approval to use Clojure on a massive data set at work which is currently taking 6 hours to parse
19:55defn`I'm confident I can get it to below an hour
19:56defn`twbray: nice post, thanks
19:59chouserdefn`: what's doing it now?
19:59defn`perl
19:59chousernice. let us know how it goes
20:00defn`It's a hack job -- I've seen some of the code, basically terrible
20:00chousersuch is the way of perl, down in the trenches, doing its job.
20:00defn`but yeah I'm planning on setting up a dedicated clojure blog tonight to start documenting
20:00chouserexcellent
20:01defn`one question i have on twbray's post, if youve had a chance to read it
20:01chessguy'ello
20:01twbraydefn`: Perl is ugly but fast
20:01defn`why use the java.nio.charset.CharsetDecoder?
20:01hiredmantwbray: what does "erlang bias" mean?
20:01defn`simply to demonstrate how it runs in a single threaded loop?
20:02twbrayhiredman: I've been a fan of Erlang for years. If it weren't for the putrid syntax, lousy file handling, and broken string processing...
20:02twbraydefn`: If I could avoid doing the decoding, I'd be real happy.
20:02hiredmanok
20:03twbraydefn`: At the end of the day I need to pass an ordinary string to the per-line function. I think I have to change from the UTF-8 (ascii actually) in the input to Java chars to do that. Do you have a better idea?
20:04technomancytwbray: maybe configure your web server to log in UTF-16? =)
20:05twbraytechnomancy: Ewwwwwwwwwwwwwww
20:05bitbcktlol
20:05technomancybonus: 45GB of logs becomes 90GB of logs; much more impressive!
20:05Chousukeis it just ASCII?
20:05Chousukemaybe you could read and compare just byte arrays? :/
20:05bitbckttwbray: take a picture of that
20:06twbrayChousuke: I'm trying to write something so that a user can create a function that takes a string and do ordinary string stuff with it.
20:06twbrayAlso I want to use regexes, which require strings.
20:06Chousukehmm :/
20:07_atoare hava strubgs UTF-16? Huh... I never knew that
20:07ChousukeI wonder if Java strings are really internally UTF-16, or if just the characters are.
20:07twbrayYeah, it's UTF-16 :(
20:08technomancythis is due to the JVM predating UTF-8, correct?
20:08hiredmanthat is what the internet tells me
20:08twbrayBack in the early nineties, the Unicode people thought they could get away with what they called "UCS2" and stuff all the characters in 64K. So adopting 16-bit characters seemed plausible for Java back at the time.
20:09bitbckt"seemed like a good idea at the time"...
20:11bitbckttwbray: are you using the equiv. of new String(<bytes>, 0, <length>, "UTF-16BE") to convert these byte sequences?
20:12twbraybitbckt: but the input isn't UTF-16, it's ASCII, i.e. UTF-8
20:12bitbcktIn that case, use "US-ASCII" as the final arg.
20:13twbrayWell... there could conceivably be some non-ASCII in the user-agent and so on.
20:13bitbcktYou have these to choose from: http://java.sun.com/j2se/1.3/docs/api/java/lang/package-summary.html#charenc
20:14bitbckt8859-1, perhaps.
20:14bitbcktIt may use the j.n.c.CharsetDecoder, internally.
20:14bitbcktI don't know.
20:15bitbcktOver the wire, they're UTF-8, most often.
20:15bitbcktAt least, everything I've done with them lately has been.
20:15twbrayAnyhow, the decoder still seems WAY too slow.
20:15twbraybitbckt: Increasingly, everything is UTF-8. So I assume you're right.
20:15bitbcktDefinitely.
20:16bitbckt(re: WAY too slow)
20:16hiredmanlooks like http headers are US-ASCII
20:17twbrayAnyhow, I'll look at the Java library code. Wouldn't be surprised if there's something int here that's causing bad behavior whenI ask it to do 32M at a time.
20:17twbrayLater
20:22michaeljaakahi
20:22michaeljaakawhy we can nest #() ?
20:22michaeljaakacan't
20:22michaeljaakaand how to write own macro characters?
20:23Chousukemichaeljaaka: 2) you can't and 1) because #(foo % #(bar %)) is kind of confusing and ambiguous
20:24michaeljaakabut we could make something like
20:24michaeljaaka#( a b -> .... )
20:25michaeljaakaso I explicite names the arguments
20:25Chousukethat's (fn [a b] ...) :)
20:25the-kennymichaeljaaka: (fn [a b] (+ a b))
20:25michaeljaakaI knew that you will say that
20:25technomancyfor everything but the simplest functions, usually for java interop.
20:26the-kennyI'm using #() for simple predicate-like functions
20:26Chousuke(map #(foo %) ...) seems to be a common anti-idiom :P (where foo is a clojure function)
20:26michaeljaaka;)
20:27michaeljaakahmmm I often have to make
20:27michaeljaaka(map #(apply foo %) ... )
20:28Chousukethat's fine
20:28Chousukethough I might use (map (partial apply foo) ...)
20:28michaeljaakaI have even one function where I have d(g(f(x))) and some have apply and other not, so I can use (-> .... ) :(
20:29Chousukethat would be (comp d g f) wouldn't it? :/
20:29michaeljaakaohhh If it is then thanks!
20:29michaeljaakaI will try
20:30Chousukethough that ofcourse requires that the output of f is suitable for g as is, and same for g and d
20:31Chousuke(partial apply blah) seems pretty common actually
20:31michaeljaakawell I wanted to say taht I can't use (-> .. )
20:31michaeljaakaI said "I can use (-> ... )
20:32ChousukeI wonder what would be a good name for a function that does that operation
20:32michaeljaakai mean I can't
20:38defn`nested-partial?
20:38defn`deep-partial?
20:38notallamaChousuke: perhaps apply with 1 arg could just do that. i was calling it uncurry, but that doesn't really make a lot of sense since functions aren't curried in clojure.
20:38ChousukeI guess you could define succinct names for function transformation operations in another namespace and then just expect it to be used with an abbreviated namespace qualifier
20:40michaeljaakahow to quickly generate x long vector by filling its value with a func result?
20:41the-kennyiterate, repeat, repeatedly
20:41the-kennyor for
20:41the-kenny(take 10 (repeatedly (rand-int 10)))
20:41the-kenny,(take 10 (repeatedly (rand-int 10)))
20:41clojurebotjava.lang.RuntimeException: java.lang.ClassCastException: java.lang.Integer cannot be cast to clojure.lang.IFn
20:41the-kenny,(take 10 (repeatedly #(rand-int 10)))
20:41clojurebot(1 9 3 6 2 8 6 5 2 7)
20:41Chousukenotallama: that could be good. I guess calling apply with one arg makes no sense otherwise?
20:41Chousuke,(apply *)
20:41clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: core$apply
20:42michaeljaakathe-kenny: ok, thanks!
20:42Chousukenotallama: very haskellish though :P
20:42defn`chouser: what's your formal education in CS?
20:43Chousukewas that for me? :P
20:43defn`really for anyone
20:43ChousukeI'm still a student.
20:43defn`same here
20:44defn`im trying to get an idea of what sorts of stuff i should be taking (if available) to get better at this stuff (concurrency, lisp)
20:44notallamaChousuke: haskellish is usually a good thing, i think.
20:45defn`we have a scheme course im going to take next semester but other than that im not sure if i should take compilers, etc. or if there is a better place to put emphasis
20:45Chousukenotallama: well, sometimes.
20:45the-kennydefn`: For concurrency, there is a presentation available at blip.tb
20:45the-kennys/.tb/.tv/
20:45defn`yes ive watched that
20:46Chousukenotallama: though my opinion of point-free style in Clojure is that it's sometimes good, but not nearly as often as in haskell :)
20:46defn`itd be nice to do some small project work using those techniques in school
20:46the-kennyAnd lisp.. hm.. it's experience. You have to learn to think functional ;)
20:46defn`:) im still so new to it, i just wanna get better now!
20:46Chousukepoint-free stuff is really neat in haskell because of currying and succinct syntax for comp and whatnot, but with lisp it just doesn't quite work :P
20:46the-kennyIt's important to know the api of clojure. There are so much cool functions :)
20:47the-kennys/clojure/every functional language/
20:47defn`yeah that's a good point, im gonna just start documenting a-z the functions of clojure
20:48the-kennyAnd else.. try to do some things. Implement some algorithms, work on projecteuler or something like this
20:48defn`yeah ive been doing project euler
20:48notallamaChousuke: yeah, that's one place where all the parens can hurt. it works sometimes, but it's rather ugly other times.
20:48defn`but i gotta a little bored with it
20:48defn`i think its time to try and build something tangible i can use
20:48michaeljaakawhat is wrong with that? http://gist.github.com/243169
20:48defn`the build system is a bummer
20:48hourhickey, following agent error queue discussion. don't you think it's also an incidental complexity of inverse of control, lost of continuation point, "don't block thread" yada ..., all due to async modeled api. I know you have doubts on continuation, but I'm still wondering if delimited continuation, like scala's or jvm's, is the right model for user api. In fact, I hate all async api (jms, nio, aio) for the same reason. IMHO, they can
20:48houhowever async they like at implementation level, but they should all be wrapped in delimited continuations. Just give me back my straight through flow control :-)
20:49the-kennydefn`: then do something interesting. Hook yourself into the continuous twitter feed and do some data-crunching
20:49Chousukemichaeljaaka: repeatedly takes a function
20:49houlink http://weblogs.java.net/blog/forax/archive/2009/11/19/holy-crap-jvm-has-coroutinecontinuationfiber-etc
20:49Chousukemichaeljaaka: also, github does have Clojure syntax highlighting :)
20:50defn`the-kenny: there's a cool idea, twitter feed time :)
20:50Chousukemichaeljaaka: it's just hidden towards the bottom.
20:50the-kennyI really like the new continuous feed. You get a stream with one tweet per line :)
20:51the-kennymichaeljaaka: The JVM can't optimize tail-calls. Try recur
20:52michaeljaakarecur can't be used it says something about not being in a tail
20:52michaeljaaka:(
20:52the-kennyhm.. I should go to bed.. I have to get up in appros 4 hours.
20:52the-kennymichaeljaaka: Look at an example for a recursive funtion in clojure and modify it to your needs
20:52michaeljaakaok
20:53Chousukethat's a lazy seq
20:53Chousukerecursion is expected
20:53defn`how do you use accessor?
20:53Chousukeyou *can't* use recur :)
20:53the-kennyChousuke: Oh sorry
20:53michaeljaakauff :)
20:54michaeljaakanothing to do then ;)
20:54Chousukeexcept for the rand-int thing
20:54the-kennydefn`: Here is something to get you started: http://gist.github.com/243175 ;) I'll go off to sleep now... byw and good night.
20:54michaeljaakaI have found myself often using seq of diff size for my playing with clojure, so I hvae created that function ;)
20:55defn`the-kenny: you're great :) Thanks man
20:55ChousukeI think you could do it without an explicit lazy seq though
20:56michaeljaakawell I'm going to produce very long data
20:56Chousuke,(take 2 (map vec (partition 5 (repeatedly #(rand-int 100)))))
20:56clojurebot([80 2 2 21 58] [48 84 39 98 0])
20:56Chousukehigher-order functions :)
20:57michaeljaaka:)
20:57michaeljaakavery long seq are needed
20:57Chousukeoh, that's fully lazy too
20:57michaeljaaka!
20:57michaeljaakawow
20:57Chousukerepeatedly is lazy, partition is lazy, map is lazy, so the whole thing is lazy
20:58michaeljaakahmm but partition splits it in wrong way
20:58michaeljaakauhhh maybe not
20:59michaeljaakai will study it
20:59notallamais there a built in way for types to take less arguments than they have fields? i could roll my own, but it seems like it'd be a handy feature.
20:59Chousukenotallama: deftype? probably not.
21:00notallamayeah, deftype.
21:00michaeljaakaChousuke: it is ok, thanks :)
21:01Chousukenotallama: you should suggest it to Rich I guess. deftype isn't finalised yet as far as I know
21:05zaphar_psare there any coverage tools for clojure?
21:11defn`hmmm, where did base64/encode-str come from?
21:11defn`java.lang.Base64?
21:11hiredmannope
21:11hiredmanthere is no "official" base64 in the jre
21:11hiredmanthere is one in sun.misc somewhere
21:11defn`java.lang.Object?
21:12defn`k thanks
21:12hiredmansun.misc.BASE64Encoder
21:14defn`no such namespace Base64
21:15defn`BASE64Encoder is there, but no method encode-str
21:15defn`ahh this is from clojure contrib
21:24michaeljaakawhy this outputs 332 instead of 2 332? http://gist.github.com/243190
21:27hiredmanmichaeljaaka: you must put function calls inside parens
21:27qedhttp://gist.github.com/243191 How do I use get-stream now that I have it setup?
21:27michaeljaakaok works
21:28qedLike let's say I want to get 10 tweets, how can i turn get-stream into a seq?
21:28michaeljaakaI have still problem with that: sometimes parens can change the behaviour
21:28somniummichaeljaaka: not sometimes, always
21:28hiredmanuh
21:28hiredmanyeah
21:28michaeljaakayeah
21:28michaeljaaka;)
21:29hiredmanparens mean "this is a function call"
21:29michaeljaakabut without it too works but not like expected :D
21:29hiredmanso of course parens change the bahaviour
21:29hiredmanmichaeljaaka: for various reasons that would be tedious to explain
21:29michaeljaakaat least compiles without problems
21:29qedi edited the gist so it's readable now
21:30hiredmanqed: pass the inputstream to clojure.xml/parse
21:30qedhiredman: thanks
21:30notallamafn returns the result of the last thing in it. which in your case is y, michaeljaaka.
21:31michaeljaakaok
21:31michaeljaakathat explains all
21:32qedNo matching method found: parse for class com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl
21:32qedhmmm
21:33hiredman(doc clojure.xml/parse)
21:33clojurebot"([s] [s startparse]); Parses and loads the source s, which can be a File, InputStream or String naming a URI. Returns a tree of the xml/element struct-map, which has the keys :tag, :attrs, and :content. and accessor fns tag, attrs, and content. Other parsers can be supplied by passing startparse, a fn taking a source and a ContentHandler and returning a parser"
21:33hiredmanhmmm
21:34nroot[
21:34hiredmanoh
21:34hiredmanqed: some is not right
21:34qedhiredman: yeah i went out and got the library, i think i was missing it
21:35qedlibxerces2?
21:35hiredmanqed: no
21:35hiredmanyou are not missing the library
21:35hiredmanit says the method+argument type combination doesn't exist
21:36hiredmanqed: how exactly are you passing the output of get-stream to clojure.xml/parse ?
21:36hiredmanoh
21:36hiredmanduh
21:36hiredmanthis is json
21:36qedlol oops
21:36hiredman(still the wrong error)
21:36hiredmanso use onf of the json parsers
21:36qedThanks hiredman
21:36hiredmaneither clojure-json, or the one from contrib
23:39KirinDave1_ato: How long is "a few seconds"?
23:40_atoKirinDave1: 2.8s
23:40_atojust a first run, so not JITed
23:40KirinDave1Can't wait to get your version of clojure. :)
23:40carkthat's an average of 2 record per user ... not much
23:40KirinDave1Aww, ran out of heap space.
23:40_atoerr wait
23:40_atomaybe I mistyped
23:40alexykwhen I wrap time around a def, (time (def users (...))), how do I still get users defined at the top level of repl?
23:41_atono I misread
23:41_atoit said 28000 I read 2800 ms
23:41_ato:p
23:41carkalexyk : def doesn't need to be top level to do its work
23:41alexykcark: how does clojure do scoping then? let?
23:42alexykand def injects at the top?
23:42somniumdef creates vars
23:42alexyksomnium: in which scope?
23:42_atonamespace-scoped
23:43_atoso def essentially creates global variables
23:43_atowherever it is called from
23:44alexykok, same result with long, 776261 user, and about 700M also eaten. Probably first slow run was a fluke, although scary.
23:45nrootI am trying to write a echo server in clojure. I did in java using the one thread per client model but its not very scalable.
23:45alexykthis is very sizzling! it means I can use maps to do data mining on twits. Next I'll run it on 100M twits, somnium, we;ll see how congomongo holds up :)
23:45nrootBut it works fine in Erlang because of low cost of creating a thread
23:45nrootWhat is the scalable way to do it in Clojure ?
23:46somniumalexyk: let me know, I've mostly been using it for prototyping :)
23:47_atonroot: you need to use non-blocking sockets
23:47_atousing java's "nio" IO library
23:48alexyksomnium: I was wondering, congomongo jar has only one class in it, the rest are .clj files. How does clojure execute them?
23:48somniumalexyk: the current assessment seems to be that it's 'not obviously broken'
23:48alexyksomnium: I like it!
23:48somniumalexyk: clojure compiles .clj files to .class files when you load them
23:48alexykah, ok.
23:49nrootSo it will be parallel to NIO implementation of Java. Does clojure as a language provide any advantage in this ?
23:49alexyksomnium: if I want to use coerce, is the example in congomongo_test.clj the one to follow?
23:49alexykI'd read json from stdin and insert
23:49_atonroot: not at the moment as far as I know
23:49somniumyeah, its a pretty short function, the source is hopefully readable too
23:50_atonroot: http://ossareh.wordpress.com/2009/10/12/learning-nio-via-clojure/
23:50nroot_ato: Thanks :-)
23:51_atoI agree with the author of that post though, nio and (Java IO in general) sucks pretty bad compared to more posixy languages
23:51somniumI have a version with deftype and defprotocol thats about 3x faster, but 1.1 isn't even official yet
23:51alexyksomnium: if you push it into a branch on github, I'd be happy to test
23:52_atonroot: looks like there's a followup post as well: http://ossareh.wordpress.com/2009/10/13/learning-nio-via-clojure-pt-2/
23:52alexykI'm using 1.1-alpha-snapshot from github anyways
23:52somniumok, you'll need clojure-new branch and recompiled contrib too :p
23:52somniumI hope deftype and friends makes into 1.1
23:53alexyksomnium: so (1) clojure-new then (2) recompile the master of contrib from github?
23:53somniumyeah
23:55qedhey all