#clojure logs

2009-12-03

00:13qedIs there anything out there to simplify using Swing? using clojure, of course
00:13qedgit://github.com/ztellman/penumbra.git
00:13qedthats cool either way
00:14cgordonI'm trying to call this bit of Java: IndexWriter.MaxFieldLength.UNLIMITED, but I can't figure out how to do it. I've tried "(.. IndexWriter MaxFieldLength UNLIMITED)" and (. IndexWriter.MaxFieldLength UNLIMITED)". What am I missing?
00:14qedcgordon: what's the exception?
00:15cgordonwell, in the second case, I get: error: java.lang.ClassNotFoundException: IndexWriter.MaxFieldLength (Gutenberg.clj:13)
00:15cgordonin the first I get: error: java.lang.NoSuchFieldException: MaxFieldLength
00:15arbscht_IndexWriter$MaxFieldLength refers to the nested class
00:15qedI'm not too good with the Java interop yet, but IndexWriter and MaxFieldLength should be separate I think
00:16cgordonarbscht_: that did it, thanks!
00:16arbscht_np
00:16qedah-ha, i havent seen anything like that yet cgordon
00:17cgordonah, my bad, it's in the docs: If the first operand is a symbol that resolves to a class name, the access is considered to be to a static member of the named class. Note that nested classes are named EnclosingClass$NestedClass, per the JVM spec. Otherwise it is presumed to be an instance member and the first argument is evaluated to produce the target object.
00:17cgordonI just missed it
00:17qedhttp://github.com/travis/lein-cuke
00:17arbscht_:)
00:24technomancydanlarkin: lol @ "we aren't that serious"
00:25technomancy"honestly! the other day someone told a joke in stand-up, and everyone was cool with it."
00:25danlarkinsrsly
00:28defnhttp://github.com/travis/lein-cuke
00:28defn^@technomancy
00:42JAS415anyone ever use Runtime.exec to compile LFE code from within clojure?
00:42JAS415it almost works but seems to block for some reason
00:46chouserLisp Flavored Erlang?
00:46JAS415yup
00:47JAS415I've got the command line command working from my shell, but it doesn't seem to do anything from the lisp interpreter
00:47JAS415and i'm just printing the command to the interpreter and copying it to the shell at the moment
00:48technomancydefn: interesting
00:49technomancyI'm not one for english-like programming, but different strokes for different folks I guess.
00:54_atoI don't get it, what's the point? Oh is the idea so that people who can't code can read the tests?
00:55technomancyI think so. for customer-centric acceptance-testing.
00:55technomancyI don't really have much interaction with customers.
00:55JAS415yeah that's what i thought, 'looks like tech support'
01:00defntechnomancy: I've never used cucumber to be honest
01:00defnbut I thought it was neat he was using leiningen
01:00cp2man, i feel like a born-again christian
01:00cp2clojure is so awesome
01:00cp2after doing a bunch of stuff in c++.. damn i forgot how nice it is
01:00replacatechnomancy: did you want someone to apply the patch for contrib issue 29?
01:02technomancyreplaca: I'm not using 1.0 anymore, so I don't have any personal attachment to that issue
01:03technomancybut it'd be nice just for the sake of having fewer perfectly good tickets sitting around waiting to be applied.
01:03replacaok, I'll slam it in
01:04technomancyspeaking of which, it's quite a shame that stuartsierra can no longer fix bugs in his own library now that test-is has been promoted. =(
01:04replacaI'm in the midst of writing a new ticket that I'll actually have to think about, so it'd be nice to make an easy one go away :-)
01:04replacayeah, interesting
01:05replacaI think our dev process is still shaking down
01:05replacawhich is ok
01:10technomancyreplaca: I'm about to push out leiningen 1.0 (probably tomorrow) and then start to sit down and think through the doc plugin
01:10technomancylooking forward to how that shakes out
01:15replacatechnomancy: cool. I'm beginning to think about that too
01:16replacatechnomancy: so ping me when you're starting to think and we can compare notes
01:16technomancyaye
01:17replacathere's a *lot* of hair on fire in the current version of autodoc
01:38defnif you guys were to design an extended documentation site for clojure, how would you lay it out?
01:38defnid like to start working on examples for all of the existing docs
01:38defnsimilar to how the ruby API core docs work
01:39cgordonhow does Ruby lay out it's documentation?
01:39defni think it should be a community effort, a wiki maybe?
01:39cgordonI'm only really familiar with the way Perl and Java do documentation
01:40cgordonSeems like you'd want most of the documentation to come from the source files, which tends to leave out wikis (except as manuals and examples)
01:40cgordonThe "doc string" seems to actively discourage that though
01:40defnarray.assoc(obj) → an_array or nil; Searches through an array whose elements are also arrays comparing obj with the http://ruby-doc.org/core/classes/Array.html#M002164 element of http://ruby-doc.org/core/classes/Array.html#M002173 contained array using obj.==. Returns the http://ruby-doc.org/core/classes/Array.html#M002164 contained array that matches (that is, the http://ruby-doc.org/core/classes/Array.html#M002164 associated array), or nil if no match is fou
01:40defnalso http://ruby-doc.org/core/classes/Array.html#M002208.; s1 = [ "colors", "red", "blue", "green" ]...example follows...
01:41defndid you get all of that?
01:41cgordonyes
01:41cgordonis there any sort of standard markup (or markdown) used in doc strings for Clojure?
01:41defni dont believe so
01:42defnid like to work on better documentation, i see a lot of things where (doc x) returns something like ([s key])
01:42cgordonI'm with you; I'd be happy to spend time documenting the core libraries, but I'm not sure where to do it, or how
01:42cgordonit would, at least, be a great way to learn more about them
01:42defnin this case it means struct, but in other cases it means string
01:42cgordonyes, I haven't found the documentation to be very helpful when learning a function
01:42cgordonalthough they are fine for quick reference
01:43cgordonI keep a copy of core.clj open in Emacs at all times as "documentation" :)
01:43defncgordon: i think it should just be a wiki where the "talk" page is a comments place, kind of a blog in that sense, where there can be discussion about the example, and it can be improved
01:43timothypratleyhttp://en.wikibooks.org/wiki/Clojure_Programming#API_Examples <- I started this a long time ago and various others have added to it
01:43defnyou can "watch" doc pages so you can edit them and fix them when it's appropriate
01:43timothypratleywhat I'd really like to do is put them into actual example meta-data on functions
01:43timothypratleyand have them be tests that get run
01:44timothypratleyand able to be looked up with (doc)
01:44defntimothypratley: it's a good reference, but i think it could be done better, as a single effort to create examples for the API docs
01:44timothypratleyor (example ...)
01:44timothypratleyYup totally agree
01:44timothypratleythat's what I'm saying :)
01:44defnhehe :)
01:44timothypratleyIt needs to be done as code
01:44timothypratleythat can be run, and attached to the actual functions, and part of autodoc generation
01:44timothypratleyI can imagine cases where you want it in autodoc and not
01:44defnyeah totally, i started on the a's, and i just got to B, i dont know a lot about agents and refs and such yet, im just providing basic examples where i know how
01:45defnim doing it in org-mode in emacs and then exporting to HTML
01:45defnbut i think it should be a wiki
01:45nospaceshave something that addresses problems such as "java.io.FileNotFoundException: Could not locate compojure/http/servlet__init.class or compojure/http/servlet.clj on classpath: "
01:45nospacesand things like "java.io.FileNotFoundException: Could not locate compojure/http/servlet__init.class or compojure/http/servlet.clj on classpath: "
01:46hiredmanyou should put compojure on the classpath
01:47defn:)
01:47defntimothypratley: would you want to work on something?
01:47timothypratleydefn: yup
01:47defntimothypratley: I have getclojure.org and .com -- thought those might be a good place for API docs
01:48defnwhat i have in mind is a site which looks like a nice way to browse API docs first and foremost
01:49defnand then hidden away is the way to log in
01:49defnnot hidden so much-- more like, not intruding on every other link on any given page
01:50defnhiya twbray
01:50defni enjoyed your post
01:50twbraydefn: Thanks. But read the comments, and you'll see that I'm a clueless fucktard :)
01:51defnheh
01:51defnIt's just the internet
01:51defnit's good to have stances and opinions
01:51defnotherwise everyone just clones the same ole
01:52twbrayOh, I'm not upset. The reactions establish that at least people are thinking. Blog as long as I have and your skin is 3 feet thick.
01:53hiredmanit's amazing how fast comments on anything mentioning lisp deteriorates
01:54hiredmanthere must be something like godwin's law that covers it
01:55twbrayAmused at the commenters saying "If you only used an editor that s-exp balancing and hopping You'd Get It".
01:55timothypratleylol
01:56hiredmanI was 2
01:56_atothat's before I was born!
01:57cgordonwow, now I feel old, and I didn't start using Emacs until 1990
01:59nospacesthat classpath thing will be a barrier to the newbies who come into clojure without java - so, some notes on that would be good.
02:00hiredman~google java classpath
02:00clojurebotFirst, out of 295000 results is:
02:00clojurebotSetting the class path
02:00clojurebothttp://java.sun.com/j2se/1.3/docs/tooldocs/win32/classpath.html
02:03nospacescan't it be set automatically via ant or something?
02:04nospacesi'm on a mac - and have to go through stuff like this - http://www.ibm.com/developerworks/java/library/j-classpath-unix/?ca=dgr-lnxw06clspth-Unix-MacX
02:04headiusjruby allows you to add to classpath at runtime
02:05cgordonI've been using "swank-clojure-project" with Emacs, and that works like a charm
02:05headiusI'm still amazed other langs have not done that
02:05timothypratleydefn: while I think your idea of a public wiki has merit, I'm thinking to be most useful you need to enforce 4 things: 1) A function/var that the example relates to. 2) The code. 3) The result. 4) any additional comments. So the data needs to be stored in some sort of format that allows programmatic access to that [maybe I'm just complicating things]
02:05hiredmannospaces: seriously?
02:05headiusin fact, JRuby allows you to simply "require 'something.jar'" and its classes will be available to you
02:05_atoI think we just need to figure out the right combination of classloader magic to make add-classpath work reliably
02:05hiredmanthat is your sob story?
02:05defntimothypratley: with org-mode that actually is working quite well
02:06hiredmanyou are calling the steps clearly laid out in that article pain?
02:06_atoI noticed the ant classloader has some stuff about forcing files in higher classloaders into lower-level ones
02:06replacadidn't someone start writing examples for functions on the clojure wikibook (that seems to have died)?
02:06timothypratleydefn: oh, cool! how can I help?
02:06defntimothypratley: do you use org-mode?
02:06defnemacs?
02:07nospacesyeah - try installing everything from scratch on a clean machine and see what things are required - great docs are written up from tabula rasa configs
02:07defntimothypratley: either way ping me your email, im still brainstorming, i might just build something to do what we need, there are wikis out there, just need to combine one with what we need
02:07nospacesthat way hidden assumptions are off
02:07timothypratleydefn: I use vim mainly but this is a good chance for me to learn :)
02:07_atodefn: why not just use a git repo instead of a wiki? then you can put org-mode docs or code or whatever in it?
02:07hiredmannospaces: what assumptions?
02:08defn_ato: yeah that works, i mean, there'd be a repo regardless i suppose
02:08defnbut im thinking more about presentation, and how people will edit it in the long term
02:09defni think a wiki inspires more activity than a repo might
02:09nospacesclasspath settings, git, et al
02:09defni think we'd have fewer authors with a repo, i guess is my main concern
02:10hiredmannospaces: the classpath stuff is part and parcel of the jvm, if you wish to work with it, then it behooves you to know of it and how it works
02:10hiredmansun has docs
02:10_atodefn: hmm, I guess. I suppose I was assuming that most Clojure uses would be used to using git anyway
02:10defnyeah i suppose they could be
02:10hiredmanif a project is hosted in git, is it unreasonable to expect people to know git to use it?
02:11defnyou can get clojure through macports though...
02:11tomojI was thinking of a web app
02:11nospaceshiredman - understood - just saying that there will be folks who come in contact with clojure with no java experience - and they'll do searches like http://www.google.com/search?q=Could+not+locate+compojure/server/jetty__init.class and there will be no hits
02:11defnhiredman, if you can remove a bit more of the pain for a n00b, you have another user
02:11tomojwith the functions/macros to be documented autogenerated and then people can hang (running?) examples off of them and vote the examples up/down
02:11tomojthen top examples get shown in the main view and the power users can go in and look at the rest
02:12hiredmannospaces: and they will come to irc and the mailing list and we will rectify what is wrong
02:12JAS415i found compojure to be a pretty easy setup considering
02:12defni dont know about the voting, i think most people are pretty amicable here, id probably just leave it open, whoever wants to edit can edit, there can be discussion and maybe it'll change, no worries
02:12hiredmancompojure actually has an ant target to download all it's deps, including clojure
02:12tomojyeah I hadn't thought of just using a wiki -- too simple :P
02:12_atonospaces: What do you think it is that other languages do differently?
02:13defntomoj: it sort of is a webapp, with a wiki behind it
02:13hiredmanif I recall, compojure even has a run script that will launch compojure with all the deps on the classpath
02:13defnthat is correct
02:13tomojhow does it know what handler to use?
02:14hiredmannospaces: so, was there anything else?
02:14nospaces_ato : rails have been handling the deprecations pretty well - you see a lot of people running around with older books - but the deprecation blogs help them get on board and still power through - but things which are setup wise - should be complete - rather leaving new folks stuck and needing to get support - if they can hello world in 15 minutes - then that's great.
02:14nospacesnot everyone runs on super fast broadband - or the latest computers
02:15nospacesbut as always, it's a darwinian process at the end of the day :D
02:16_atoyeah, partly it's just that Clojure and Clojure libs are very young, so the way to do things changes a lot
02:16_atowe're trying to solve the dependency problem with Leiningen
02:17timothypratley_ato: I salute you
02:17nospacesI guess a place that can store the error messages and become the number 1 search link would help a lot - stuff like this should get some hits somewhere - http://www.google.com/search?q=ava.lang.ClassNotFoundException:+org.mortbay.jetty.Server+(NO_SOURCE_FILE:0)
02:18hiredmannospaces: that is the exact same error as with compojure
02:18nospacesyeah, i know - noobs are going to keep banging at the same wall :)
02:18nospacesin different ways
02:18_atoyeah, for searches it's just a matter of popularity and time. The only reason other languages are better there is there's more people blogging about them
02:19nospacessince it's claimed to be fast and powerful - then they'll just face the wall from all angles
02:19hiredmanI don't care about your hypothetical "noob"
02:20nospacesthat's where i think clojure with the lisp AI background may come in handy - to generate auto blogs -
02:20nospacestoday's noob - tomorrow's contributor
02:20hiredmanhave you looked at the tutorial linked from the compojure github page?
02:21nospacesthis one? http://groups.google.com/group/compojure/browse_thread/thread/3c507da23540da6e
02:21hiredmanor the other 3 or 4 under it
02:22hiredmando you have any problems besides the not having setup your classpath?
02:23nospaceswas great up to classpath :)
02:23nospacesthe other issue is that git should have a 404 error message
02:23_atonospaces: http://incanter-blog.org/2009/11/20/leiningen-clojars/
02:24nospaces"The remote end hung up unexpectedly" is way too cryptic
02:24nospacesbut that's another story
02:24hiredman
02:24_atowait.. that's not the one I was thinking of
02:24_atohttp://incanter-blog.org/2009/11/29/incanter-webapp/
02:24_ato^ the webapp one
02:25nospacesthanks _ato
02:25_atoand just leave out the incanter bits
02:25_ato;-)
02:26_atoyeah.. git is pretty obscure there. It says that even if it can't resolve an IP
02:26nospacesi guess as the community grows, stuff like this will float up on stackoverflow
02:27hiredman:|
02:27nospacesso that would take care of all the pesky noobs :)
02:27nospacesplus they have a nice badge incentive
02:27hiredmanstackoverflow often seems like the blind leading the blind, it would be great if people could just read documentation
02:28hiredmanor even source code for that matter
02:28nospacesthe tutorial has nothing on classpath though - heh.
02:29hiredmannospaces: clojurebot googled you up a link to sun's classpath docs
02:29hiredmanread them
02:29hiredmanI think those docs may assume windows
02:30_atonospaces: in the incanter one Leiningen is handling the classpath for you
02:31nospacesok - thanks guys
02:32_atoI guess the only difference is that rails generates a script ./script/server which sets up the load path to lib vendor/*
02:32alexyktechnomancy: can lein use a loval maven repo, and download *there*, too, if needed?
02:32alexyklocal
02:32_atoalexyk: lein always uses your local maven repo in ~/.m2/repository
02:33alexykgood... does it download there, too?
02:33_atoyeah, it uses it like a download cache
02:33alexyknice. is it using maven, in fact?
02:33_atoit first downloads there and then copies to your projects lib/ directory so other tools like swank-clojure can find the libs
02:34_atoit is indeed just using maven internally for depedency resolution (but sssh! don't tell anyone)
02:34_ato;-)
02:34alexykcan it symlink instead of copying?
02:34_atonot at this stage. Are you worried about disk space with lots of projects?
02:35alexykscala people said you can't emulate maven instead of maven, so SBT uses Ivy... and at that point I thought enough of java world build tools
02:35alexyk_ato: I am worried about staleness. Maven proper will update all snapshots for you.
02:35alexykIf I use clojure snapshot form maven, it updates every night.
02:35alexyka copy will go stale quick.
02:35_atolein will update as well
02:36_atoif it doesn't it's a bug
02:36alexykI didn't try, I'm just gauging :)
02:36alexykI'm ok with clojure-maven so far... in fact so far I'm ok with cut'n'paste, but we'll see.
02:37alexykI just got clojuratica working on my mac, wohoo!
02:37replacatechnomancy: still here?
02:37_atotechnomancy's gone to bed
02:37replacawimp :-)
02:37somniumalexyk: btw, did the protocol-version of congo have any difference in performance?
02:37replacathx
02:37headiuswhat's this about vendor and script/server and maven and dependencies?
02:38headiussounds like rails, but I assume it's compojure
02:39hiredmanI imagine it was someone talking about rails
02:39_atoheadius: maven stuff is a seperate discussion
02:39headiusI dunno how similar they are
02:39headiusahh
02:39headiusone of my goals I'll get to some day is getting rubygems and maven repos working together seamlessly
02:39hiredmanit's not like there aren't a lot of rubyists in here
02:39headiusso that you can specify dependencies on maven artifacts in gemspecs on jruby
02:39headiusso that's why I was curious
02:39alexyksomnium: ah! you here! protocol didn't do much, alas, looks like my bottleneck.
02:39_atoI was just saying that rails is slightly easier for newbies than compojure when it comes to classpath stuff as it provides scripts that set them up for you
02:40headiusahh, sure
02:40headiushopefully compojure isn't following the all-maven path that lift is
02:40headiusmaybe that's changed for lift, I dunno
02:40alexyksomnium: for a moment, I had PermGen errors doing mass-insert! in blocks of 10000, then increased MaxPermSpace and have a 1 GB size collection inserted in an hour
02:40_atonah I don't think James Reeves likes maven
02:40nospaceslol - http://news.ycombinator.com/item?id=675984
02:41_atoI don't think he likes Leiningen either though, he's working on his own dependency tool called Capra
02:41headiusalexyk: I'm still confused what that code would be doing that busts permgen
02:41headiusthere's not much that goes in there other than class data
02:41alexykheadius: one hunch was it's partial, but I moved it outside the doseq and increased PermGen at the same time
02:42somniumalexyk: 1hr ... yikes
02:42alexyktakes a while to stuff the database, may try running old code overnight with default PermSpace to see what kills it
02:42hiredmanalexyk: if chouser says it wasn't partial then it wasn't
02:42headiusan hour doesn't seem very good
02:42hiredmanput it in a profiler
02:43headiusyeah, jack up permgen and do some heap inspection once it gets large
02:43alexyksomnium: ha, it's a 3 million collection with 1-8000 list members in each element
02:43headiusI've dealt with my share of permgen issues, as you can imagine
02:43somniumalexyk: trying to get a simple one-connection clojure driver working atm
02:43headiusbut of course, this shouldn't be your job :)
02:43alexykheadius: I wonder if there's any Clojure/JRuby shootout out there :)
02:43headiusdifferent tools for different jobs
02:44headiusI know several folks using them together
02:44headiusnothing can really compete with what Rails does for webapps right now, and Clojure obviously does a great job of concurrent services
02:44headiusthe two together are a pretty nice combination
02:44alexyksomnium: you mention a desire to auto-chunk mass-insert!, how do I know when the chunk's too big?
02:45headiusperf-wise, we're roughly the same as clojure for most things
02:45headiuswe have some extra overhead for a few ruby features, but we're slowly eliminating that when it's not necessary
02:45alexykheadius: I do pure data mining, and clojure does OK so far. I need dense fast code, that's all. :)
02:45TheBusbywhat's the easy way to increase the value of a map element by one and return the new map?
02:45hiredman,(update-in {:a 1} [:a] inc)
02:45clojurebot{:a 2}
02:46TheBusbyhiredman: much thanks!
02:46alexyk,(update-in {:a 1} [:b] inc)
02:46clojurebotjava.lang.NullPointerException
02:46somniumalexyk: its due to laziness I think, Im not sure how to guard against it
02:46headiusI'm hoping I can get around to Duby with Clojure collections/refs/stm soon...I have taken on too many projects lately (and no, hiredman, I have not completed that work yet...)
02:47alexyk,(update-in {:a 1} [:b] (comp inc #(or % 0)))
02:47hiredman:P
02:47clojurebot{:b 1, :a 1}
02:47somniumalexyk: another good argument for a pure clojure driver though
02:47alexyk-- that was hiredman's advise to my earlier question, TheBusby :)
02:48headiusclojure and scala make me angry, because I want some of their features without all of their features
02:48headiusI'm an "a la carte" language guy these days
02:48alexyksomnium: but how does mass-insert work? besides RTFC :)
02:48TheBusbyalexyk: yeah I hate asking easy questions that I should be able to lookup myself...
02:48_atoheadius: do you feel the same way about ruby?
02:49headiusyes
02:49alexykheadius: I use both Clojure and Scala allright. Can have both in the same Maven project, too. :)
02:49tomojalexyk: does (comp inc #(or % 0)) look better to you than #(inc (or % 0)) ?
02:49headiusI would most definitely remove some things from ruby that confound other features or make them less efficient than they could be
02:49headiusbut in general it fits my sensibilities most closely right now
02:50alexyktomoj: hiredman etched the former in my brain first, then I got burned on an update-in writing (cong ... #(...)) without comp. I think always having #(...) outside is safer.
02:50alexykconj I meant
02:51tomojoutside? how'd you get burned?
02:51alexykI suddenly like (fn ...) better than #(), I can destructure fn's args.
02:51TheBusbyand no nesting problems...
02:51_atoheadius: what would you remove from Clojure? S-expressions, macros, the require/use mess? Any of the concurrency primitives?
02:51alexyktomoj: grow lists as map nodes. (conj #(or % []) x) fails, #(conj (or % [] x) works.
02:52alexykfor the update-in fn.
02:52somniumalexyk: it passes a j.u.Map to the java driver which tries to realize the whole thing iirc
02:52tomojhuh
02:52_atomultimethods, maybe
02:52somniumer, List, not Map
02:52alexyksomnium: I tried to stuff the whole huge map with 3 mil keys as one element, and the thing cranked till I killed it.
02:53hiredmanalexyk: you have to comp conj, just like inc
02:53alexykI think you're right about pure clojure, at least for control.
02:53alexykhiredman: right
02:53hiredman(comp inc #(or % 0)) v. (inc #(or % 0))
02:54headius_ato: I'd remove lisp
02:54tomojnooo
02:54hiredman:(
02:54headiusbut that's just me, I know others really like lisp as a language
02:55alexykheadius: then we remove rubies
02:55headiusI'm more interested in the backend
02:55headiusalexyk: be my guest, if ruby's backend is what you want
02:55headiusI don't care
02:55somniumill take sexps over instance_eval any day
02:55_atoalexyk: I'd use #(if % (inc %) 1) instead of comp and or.. I think it's more readable
02:56headiussomnium: no argument there...a nicer macro capability in ruby would be welcome
02:56headiusbut I don't use evals with strings all that often anyway
02:57headiusI was debating some ways to represent clojure primitives in duby
02:57alexyk_ato: nice too
02:57headiusmaybe fields would only be initializable in constructor or maybe they'd be refs by default
02:57headiusit would basically be a separate dialect of duby that uses all immutables except where you tell it to use refs
02:58headiusand maybe syntax to do refs easily
02:58tomojare you stealing clojure's persistent data structures?
02:59somniumheadius: is duby usuable as a drop-in for .java now?
02:59headiusit supports a (small) subset of java features
02:59headiusI've been slowly adding more as time permits
02:59TheBusbywhat's the clojure way, to generate a vector of 100 empty hash-maps?
02:59_atoheadius: yeah understandable. There's a trade-off between readability and power with LISP syntax. I'm not one of the people who think LISP is as readable as syntaxes more like Ruby or Python
02:59headiusit needs a better type model
03:00headius_ato: right...I think it's possible to do a mostly-immutable ruby-like language with plain java types, clojure refs/collections/stm
03:00headiusduby is probably the easiest way
03:00alexykTheBusby: (repeat 10 '{}) ; probably?
03:00headiusone of a dozen projects I'd like to work on, unfortunately
03:00alexyk, (vec (repeat 10 '{}))
03:00clojurebot[{} {} {} {} {} {} {} {} {} {}]
03:01TheBusbythanks, I need a ruby to clojure cheat sheet...
03:01tomoj{} will not be a hash-map, but I don't think you care :)
03:01tomoj(+ no need to quote an empty map)
03:01alexykok
03:02headiusI guess the ruby would be Array.new(10) {{}}
03:02headiuser 100
03:02tomoj[{}]*100 ?
03:02alexyk_ato: I didn't parse your last sentence. :) Are you saying lisp is not as readable as ruby? :)
03:02headiustomoj: works too, but less efficient (probably not by enough to matter)
03:02alexykheadius: Ruby looks almost like Scala, btw
03:03headiusalexyk: yeah, and duby blurs that line even more
03:03somniumespecially with the new lambda
03:03headiusdef foo(args:List)
03:03headiusduby's parser is based on ruby 1.9, so it has the 1.9 features like literal lambda too
03:03_atoalexyk: yes. I think once you're used to it, you can find lisp pretty readable. But it's always going to less approachable to someone who doesn't know it
03:03headiushaven't built clojure support into duby yet
03:04headiuser
03:04headiusclosure
03:04headiusdamn that name
03:04alexyk_ato: I'm getting a hang of it, in fact. Then again it's *my* dense code I wrote yesterday which I see clearly. :)
03:05_atoon the other hand there's some things that S-expressions give you that other syntaxes don't: simple macros and better editor integration (code navigation and manipulation hotkeys and the like)
03:05headiuscertainly true
03:05alexykyeah. my textmate handles it admirably
03:05headiusI would like duby to have some sort of macro capabilities (probably compile-time, though)
03:06headiuseditor integration is pretty easy though...duby should have as much editor capability as Java
03:06headiusintellij guys already expressed an interest in adding duby support
03:06headiusmy immediate thought was "what have I gotten myself into"
03:06_atohehe
03:07headiusI'm rather underqualified to build a consistent static-typed language
03:07headiusbut I was underqualified to build a dynamic-typed language four years ago
03:08headiusanyway, I'll shut up about duby
03:08alexykheadius: wow, duby is like 20 months old! does it talk already? :)
03:09headiussure.... bin/duby -e "puts 'hello world!'"
03:09_atohehe it's nearly as old as Clojure then
03:10headiusyeah, though it's had a bit less effort put in :)
03:10headiusbasically no work from last fall until late this past summer
03:10alexykheadius: is it just you, or other folks too?
03:11headiusthere's one other guy doing a lot of commits, and a handful of people who have done minor things
03:12headiusa lot of stuff works, a lot of stuff doesn't
03:13headiushttp://github.com/headius/duby/blob/master/examples/simple_class.duby
03:13headiusother examples there
03:13headiusit's basically ruby, but not
03:14hiredmanit's kind of a shame to see all this language work and still write the os in C
03:14alexykoh boy, there's also Juby, a dynamic Duby, which was a static Ruby!
03:14headiusduby could target other backends
03:15headiusalexyk: yeah, juby became surinx, and then I just decided to add dynamic types to duby
03:15headiushave not done that yet
03:15headiusso duby will be hybrid static/dynamic like fan
03:15hiredmanwithout gc?
03:16headiushiredman: there are ways..."new" could do a normal struct allocation, and "free" could be added as a language-level primitive for clearing memory
03:16headiusa runtime with GC would be easier though
03:16hiredmansure
03:17headiusthere's a stupid broken C compiler for it as a proof of concept
03:17hiredman:D
03:17headiusand of course there's a .java compiler, so if you can write a backend that outputs source, you can do anything
03:19headiushiredman: http://gist.github.com/247982
03:19headiusDuby .class and .java output for a simple script
03:26eevar2headius: how strong/elaborate is Duby's type system? fairly close to Java's, or ML/Haskell/Scala-ish?
03:26headiusit's mostly symbolic now
03:27headiusbut the JVM backend does define a Java-like set of types
03:27headiusit's not as rich as scala's (yet?) but will need to evolve a bit more than what we have currently
03:27headiusI'm not an expert on that stuff, so I'll have to learn
03:31TheBusbyso how do you use update-in if your key is an integer?
03:31TheBusby.(update-in {5 "five", 6 "six"} 5 "boo")
03:31TheBusby,(update-in {5 "five", 6 "six"} 5 "boo")
03:31clojurebotjava.lang.UnsupportedOperationException: nth not supported on this type: Integer
03:32hiredmanTheBusby: []
03:32hiredmanhave a closer look at the example I gave and the docs for update-in
03:34TheBusbyahh, I get it now
03:35headiusnite folks
03:53angermanWhat are the pros/cons of a PushbackReader?
03:55_atoangerman: compared to what?
04:22angerman_ato: I want to read a larger file, linewine
04:22angermanlinewise
04:24_atoangerman: okay, but are you comparing PushbackReader to a regular Reader, to a line-seq or to slurp or what?
04:24_atonote that PushbackReader doesn't have a readLine method
04:24_atoyou need a BufferedReader for readLine
04:25angermanhmm.
04:26angermanI was using (read-lines) from duck-streams
04:26angermanso I'm basically looking for a facility that hands me a line if I request one.
04:26angermanas long as there are lines available.
04:27_atoread-line is just a lazy-seq wrapper around a BufferedReader
04:27_ato~def read-lines
04:28_atonote that read-lines is lazy, it won't pull the whole file into memory unless you ask it to
04:28_atoso it's suitable for large files
04:28angerman_ato: ok, but how do I take one element off the sequence and let clojure forget the item?
04:28angermane.g. use it as a queue and "pop"
04:29_ato,(next ["line1" "line2" "line3"])
04:29clojurebot("line2" "line3")
04:31_atoit sounds like you might be trying write your code in an imperative style rather than a functional style
04:31angerman_ato: I guess so :(
04:31_atowhich you can do
04:31_atojust use (reader some-file) and then call (.readLine) on the reader object
04:32_atobut it'd be more Clojureish to restructure your program in a functional way, using map, reduce and filter
04:32angermanfor the algorithm, I have in mind looks like the following: (open file) (process lines until #"^SV$" with process-header-fn) (process lines with process-sv-fn until eof)
04:33_atoah, ok, just a sec, I'll write an example
04:33angerman_ato: what I have is http://gist.github.com/247236 starting at lines 38
04:35_atoah
04:35_atothat is okay, the only problem is you're keeping a handle on the "model" binding
04:35_atoso it's keeping everything in memory
04:39angermanso I should have that out in a different function and assign the result to *model*?
04:40angermanI'm also curious abou the way I handle the second part of the file, I basically return the (next lines) from the (loop ... recur) and use that on the rest of the file, while I still have the model variabiable bound to the (read-lines ...
04:41angermanso (to mee) it looks like I have two pointer to the file
04:41angermanas I don't really discard the model var.
04:41angermanshould I start it in the loops binding?
04:42_atoyes exactly
04:42_atohttp://gist.github.com/248018
04:42_atojust move the call to read-lines into the loop's binding
04:42_atoand then you won't be holding onto the reference to the start of the lines seq
04:42_atoso the garbage collector can clean it up as it goes
04:44_atothe problem was you weren't really losing the head, because model was holding on to it
04:46_atoah you'll run into the same problem when parsing the body
04:47_atoalthough the JVM might optimize it away
04:49BjeringHello, I have a mutable->immutable transition pain. I wonder what the idiomatic way to handle possible cyclic relationsships in immutable datastructures are. Say two persons being married. As I understand there are no immutable references, is the only way to use a kinf of relational model where "the marrige" lives outside the two persons?
04:50tomojthat's what I've been doing
04:50tomojedges in a graph stored separately and outside the nodes
04:51angerman_ato: I'll give it a second thought
04:51tomojbut I need ids on everything anyway so it's not too bad
04:52angerman_ato: I could chain it, right? assign the results of the (loop for the header to a loop for the body) shouldn't that work?
04:52Bjeringtomoj: Thanks, ok, and well I guess the value of the "Person" themselves could work as keys in that map of marriges, with two entries per "Marrige" and I would get constant time two-way navigation.
04:52_atoangerman: yes, that should work. If you split it into multiple functions it might be easier to structure it chained like that
04:52angerman(loop [[a b] (loop ... recur) ...)
04:53angermanyes, moving the inner loop recur into a fn depending on the file name
04:58_atoBjering: another option is to have keys for your data, so have an entry like {:id :bob, :spouse :jane}. But I think for this sort of thing an external marriage map is nicer, as you want the marriage to be bidirectional
05:00angerman_ato: is loop really fast or is doseq with transient types faster? (though I don't know how to break out of doseq
05:00tcrayfordIs there an easy way to get the last 20 items out of a vector?
05:01_atoangerman: doseq uses loop internally, so loop will be just as fast
05:01tcrayfordor reverse a list for that matter
05:01_ato,(take 2 (reverse [1 2 3 4 5 6]))
05:01clojurebot(6 5)
05:02tcrayfordchairs
05:02_atocheers? :-)
05:02tcrayfordmm
05:02tcrayfordjust more fun saying chairs
05:02angerman_ato: so If I'm going to modify a value very often in a tight loop recur session. Using an external transient ref or atom is faster then recuring with a modified immutable?
05:04_atoangerman: recurring with a modified immutable should be faster than a ref or atom
05:05_atonote there's no reason you can't use a transient in a loop
05:06angerman_ato: I just thought that recuring with modified immutables would put a huge burdon on the GC
05:08_ato,(loop [v (transient [])] (if (< (count v) 10) (recur (conj! v 1)) (persistent! v)))
05:08clojurebot[1 1 1 1 1 1 1 1 1 1]
05:09_atoit's exactly the same amount of work for the GC using an atom vs using a loop binding
05:10_atoloop and recur is basically implemented underneath using a goto and variable assignment
05:11angermanI thought more about (let [v transient []] (loop [r (range 100)] (conj! v (first r)) (recur (next r))) (persisten! v))
05:11_atoah
05:11angermanok
05:11_atothat won't work
05:11_atoyour transient code should look exactly the same as non-transient, except adding ! to the end of functions
05:12_atotransient doesn't mean imperative
05:12angermanMaybe I'm messing transient up. In my initial version I used an atom
05:12angermanthough I guess that would cause tremendous overhead for locking
05:13angermanor a ref, but that would need dosync too
05:13_atoyeah, that's what loop bindings are for
05:14_atoso you can "change" value of the binding on each loop by pasing in a new value to recur
05:14_atoso in your case there you'd use two bindings
05:14_atolike this:
05:15_ato(loop [v (transient []), r (range 100)] (recur (conj! v (first r)) (next r)))
05:15angermanwith ref like this: (let [v (ref [])] (loop [r (range 10)] (dosync (alter conj v (first r))) (recur (next r))) @v) ;; looks messy
05:16_atoyeah, so you don't need the ref if you make "v" a loop binding as well
05:16angermanok. I think I'm getting it slowly. So using loop recur will be quite fast and under the hood do a reassignment or a variable
05:16_atoyep exactly
05:17angermanthe whole idea of taking the ref out of the loop, was to prevent sending data between loop head and the recur
05:18_atoright, but you're still sending it, you're just sending v to the ref before recur, and then getting it back again from the ref in the next loop iteration
05:19_atoAnyway you don't have to worry about passing extra things that don't always change with loop and recur -- the JVM will optimise any unnecessary assignments away
05:20_atoeg: (loop [x 1, y 2] (recur x (inc y)))
05:20_atothat'll compile to something where x never changes
05:21_atocause underneath it's just a loop
05:21_atoI mean an imperative loop
05:21_atox = 1; while(true) { x = x; y = y + 1; }
05:21angermanok
05:22_atoI think Clojure needs some better high-level functions for doing parsing stuff though
05:23_atoso you don't have to resort to using loop/recur at all
05:23angerman_ato: probably.
05:23angermanfor simple parsing I found fn-parse pretty nice
05:23hiredman~parse
05:23clojurebotGabh mo leithscéal?
05:23hiredman~fnparse
05:23clojurebotPardon?
05:23hiredmanclojurebot: are you kidding me?
05:23clojurebotYou will not become skynet
05:23hiredmanclojurebot: parsing
05:23clojurebotNo entiendo
05:24angerman~on vacation?
05:24clojurebotI don't understand.
05:24hiredmanclojurebot: google fnparse
05:24clojurebotFirst, out of 53 results is:
05:24clojurebotjoshua-choi&#39;s fnparse at master - GitHub
05:24clojurebothttp://github.com/joshua-choi/fnparse
05:24_atoah cool, I hadn't seen fnparse
05:28_atoQt takes sooooo long to compile.
05:48angermanif I have two collections with possible many duplicates, how would I construct a combination with unique items?
05:49vyangerman: merge and remove duplicates?
05:50_atoangerman: what sort of collections? maps?
05:50angerman_ato: (1 2 3 4 5 6 ...)
05:51angermanI'm thinking of (let [A (set collA)] (map #(conj A %) collB) collA)
05:51vydo you want order to be preserved?
05:51_ato,(union (set [1 3 4 5]) (set [1 2 3 6]))
05:51clojurebotjava.lang.Exception: Unable to resolve symbol: union in this context
05:51_ato,(use 'clojure.set)
05:51clojurebotnil
05:51_ato,(union (set [1 3 4 5]) (set [1 2 3 6]))
05:51clojurebot#{1 2 3 4 5 6}
05:52_atoor yeah... (into (set [1 3 4 5]) [1 2 3 6))
05:52angermanif I want to preserve order, I need to use sorted-set?
05:52_ato,(into (set [1 3 4 5]) [1 2 3 6))
05:52clojurebotUnmatched delimiter: )
05:52_ato,(into (set [1 3 4 5]) [1 2 3 6])
05:52clojurebot#{1 2 3 4 5 6}
05:52_ato,(into (sorted-set [5 4 3 1]) [6 1 2 3])
05:52clojurebotjava.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number
05:53_atooh
05:53angermanapply
05:53_ato,(into (apply sorted-set [5 4 3 1]) [6 1 2 3])
05:53clojurebot#{1 2 3 4 5 6}
05:53_atoyeah.. so that's not preserving order, it's sorting it
05:53angermanok, need to do some speed comparisons
05:53clojurebotspeed is dangerous
05:55hiredman,(doc distinct)
05:55clojurebot"([coll]); Returns a lazy sequence of the elements of coll with duplicates removed"
05:56djpowell198 people? is that the highest ever?
05:56_atoah ha!
05:56_atoI wrote that function the other day
05:56_atoha!
05:57angermanhmm set and sorted-set seem to have comparable perormance characteristics
05:57_ato~max people
05:57clojurebotmax people is 222
05:58_ato,(distinct (concat [1 3 5 6] [1 2 2 4 6 7]))
05:58clojurebot(1 3 5 6 2 4 7)
05:59angermanwell calling sort on it is giving it the same speed as the sorted-set version.
06:00angermanassuming both collections are sorted hmm.
06:01_atooh, are your collections presorted?
06:03_atoif so you could do a sorted merge which could be completely lazy
06:03_atoand not require memory
06:10angermanhttp://gist.github.com/248074
06:11angermanhmm. so nowerdays I can use multiple recurs? intersting. somehow I think I remember it did not work that way
06:12_atoit's okay as long as they're all tail calls
06:14tcrayfordato, cheers for putting compojure on clojars (assuming that's you)
06:17angermanhm. ok my combine functions seems to be a good candidate for reduce
06:20_atoangerman: a lazy version: http://gist.github.com/248080
06:21_atoand with my crazy naming scheme :p
06:22_atotcrayford: no worries :)
06:23angerman_ato: humilating :)
06:23powr-tocHas anyone got leiningen working with swank/slime?
06:24angermanpowr-toc: yes? exactly on how it's on the website
06:24powr-tocangerman: which site, the lien github page?
06:24angermanhttp://wiki.github.com/technomancy/leiningen/emacs-integration
06:25angerman_ato: but that [[x & xs*] xs] ... I've been so stupid not to know that tick :(
06:25powr-tocangerman: thanks... I had that one open in a long lost browser tab :-)
06:26angermanis sort lazy?
06:26_atosort can't be lazy
06:26opqdonuta correctly implemented insertion sort can be
06:27_atoah well maybe it is then
06:27angermanhmm no. it's not. ok
06:27_atohmm
06:27_ato~def sort
06:27opqdonuttaking k first elements of sort xs only finds the k smallest ones from xs
06:27opqdonutyeah it's not in clojure
06:27opqdonutbut it could be
06:27opqdonutat the price of performance for sorting the whole list
06:27_atoah right, yeah, I see what you mean
06:28_atoit'd quicly get expensive with a long list though, unless it was already almost sorted
06:29opqdonutmhmm
06:31angerman_ato: well. I was just wondering for the second def http://gist.github.com/248085
06:32angermanit's missing some parens and a sort :( on the last line
06:34_atoyeah that might be faster than the set implementation as it skips all the hashing and such
06:34angermanhm. the lazy version seems to be a little slower.
06:34angermanI wonder why
06:35_atothan non-lazy?
06:35_atolaziness has some overhead
06:35_atoit creates temporary objects
06:37_atothat's why rich introduced chunked-seqs, but chunked seqs don't help for this sort of algorithm
06:38angermanhere are both http://gist.github.com/248087
06:48powr-tocOk... when running "lein swank" and finally slime-connect from inside emacs it complains with "Versions differ: 2009-05-17 (slime) vs. nil (swank). Continue? (y or n) " continuing then yields "error in process filter: cond: No inferior lisp process" any ideas?
06:48powr-tocwhat version of slime do I need to install to work with leiningen?
06:58AWizzArdto emacs+slime users: does your (tab) autocompletion works when you put a @ in front of a var?
06:59AWizzArdOn my system: *lengthy-nam<tab> ==> *lengthy-name-of-var* but @*lengthy-nam<tab> ==> can't find completion
07:00AWizzArdtechnomancy: do you happen to know something about this?
07:00somniumsame here
07:00powr-tocAWizzArd: doesn't work for me either
07:01powr-tocwhat version of slime do I need to work with leiningen?
07:01AWizzArdà propos new version of slime.. does a fresh checkout work again with swank-clojure?
07:02powr-tocI think the version of slime I'm running is the one that was installed by clojure-mode
07:03AWizzArdwhen you start it it should print its most recent entry date of the change log
07:05angerman_ato: (if-let [[ x & xs ] '()] 1) => 1
07:10angermanwhere do I retain any thing here?
07:10angermanhttp://gist.github.com/248105
07:11angermani've added the output just now.
07:11angermanit's getting slower and slower and slower ...
07:12Chousukeangerman: the lines reference I think
07:13Chousukeangerman: wrap the loop in a function and call it, instead :)
07:13somnium,(if-let [[x & xs] (seq '())] 1 2)
07:13clojurebot2
07:16Chousukeangerman: http://gist.github.com/248106 this should be fine, but I didn't test it
07:16angermanChousuke: thanks. I'll examine it carefully
07:18Chousukeangerman: basically, since function arguments are only cleared at tail calls, the lines reference exists for the duration of the entire loop
07:18Chousukeangerman: but if you instead create an inner function and call it, that counts as a tail call, and the reference is cleared
07:21aav-anyone knows if test-is from clojure.contrib 1.0 works with clojure 1.0? i always get 'actual: java.lang.IllegalStateException: Var clojure.core/if is unbound.' exception
07:21Chousukeit might be clearer if you did (defn compute-metrics [[header lines]] (letfn [(worker [[ln & lns] fs exps] ...)] (worker lines nil 0)))
07:21Chousukeit ought to work
07:22Chousukethat's what the branch is for :)
07:22cemerickoh-my-god annotations are awful
07:23Chousukeaav-: you sure there aren't any stale classfiles around or something like that?
07:23Chousukeaav-: or that you really *do* have the correct versions :)
07:24aav-Chousuke: hope so. will check once again.
07:26angermanChousuke: doesn't make a difference :(
07:27angermanwhat I so much do not understand is, why the timing for the combining goes up.
07:27angermanthat should be near constant at least to my understanding.
07:27angermanas it's always doing the exactly same
07:28Chousukehmm
07:29ChousukeI suppose closing over header shouldn't keep the lines ref around? :/
07:30Chousukethat would be silly.
07:30Chousukeanyway, can you show lazy-combine-sorted?
07:30angermanhttp://gist.github.com/248122
07:30aav-Chousuke: my clojure-contrib is built from clojure-1.0-compatible branch
07:32Chousukeangerman: looks like building the combination takes X+Y time, and X grows with each iteration of course.
07:33angermanno, X stays the same
07:33angermanit's 44928 items large
07:33angermanon each iteration
07:33somniumangerman: the (if (empty? ...) lines dont have any effect
07:34angermansomnium: yep. I know. I just saw that. They were there wen I tried to work out how to handle empty input
07:34somniumangerman: call seq on the input in the if-lets
07:34somnium,(true? '())
07:34clojurebotfalse
07:35_atobecause "features" is getting longer and longer
07:35ChousukeI can't see how features is *not* growing.
07:35somnium,(if '() true)
07:35clojurebottrue
07:35angermanChousuke: when you look at the output log
07:35Chousukesomnium: true? tests whether foo is the boolean value true
07:35somnium,(if (seq '()) true)
07:35clojurebotnil
07:35_atooh wait
07:35angermanhttps://gist.github.com/248106/449e604d5c190c452ac4c50bdde1f81dcabe6e24
07:35_atoyou're right
07:36_atoso it merges them all
07:36angermanI print experiment and the size of the features each iteration
07:36somniumChousuke: yeah, I realized that when clojurebot replied :/
07:36_atothere are the same number of lines in each experiement?
07:37angermanright now. yes. but that's not the general case
07:37angermanright now it's a dense case, where each experiment (line) has the same amount of features
07:37_atoweird
07:37angermanso it's basically computing something very stupid in this edge case
07:37_atoI can't see why it'd be getting slower :/
07:38angerman_ato: me neither. it just makes no sense to me
07:38ChousukeI obviously need a cup of coffee.
07:38angermanit's like computing (x A B) with the exactly same input values 100 times in a row and it's getting slower the longer it computes it.
07:39angermanI could probably speed it up by putting it into a memorize block
07:39_atoI guess it could be a garbage collection effect, but you'd expect the performance to be spikey if it was GC instead of growing linearly line that
07:39_atoor well not linearly
07:40angermanseems more exponentially
07:40_atoyeah
07:41Chousukethe lazy-seq keeps a reference to all the xs and ys seqs? :/
07:41Chousukethat might be it.
07:43_atohuh? it drops them as it goes doesn't it? so once it's through the map, the shorter of xs and ys should be nil
07:43angermanChousuke: but should not doall force the evaluation ?
07:44_atoerr yeah, doall, not map
07:44_atoI'm getting too sleepy
07:45Chousukeyes it should, but somehow I'm suspicious
07:45angermanI'll see what happens if I just make it unlazy
07:46angermanthat causes a sraight stackoverflow
07:47Chousukeuse recur
07:47Chousuke:P
07:47_atoyeah remove lazy-seq and change the (lazy-combine-sorted ...) to recur
07:47Chousukethe calls in the cond are in tail position, so you can do that.
07:47_atooh wait
07:47_atoit's not tail
07:47_atoyeah
07:47_atoangerman: what about your other version?
07:47_atohttp://gist.github.com/248122
07:48_atodoes it happen with that?
07:48angermanmy other version doesn't work at all ... no idea why
07:49angermancrap, I've a lecture.
07:49angermanbbl
07:49Chousukehmm
07:51_atoI'm stumped, perhaps the problem is actually in extract-features
07:52Chousuke,(map (fn [x y] (cond (> x y) y :else x)) [1 1 3 3 4 5] [1 2 2 2 3 8])
07:52clojurebot(1 1 2 2 3 5)
07:52Chousukeisn't that sorted-combine? :P
07:53_atoI think it's also supposed to remove duplicates
07:53Chousukeit doesn't :/
07:54_atoI mean (combine-sorted [1 2 3] [1 2 3]) => (1 2 3)
07:54_atodistinct inputs and outputs
07:55_atocond (= x y) (cons x (lazy-combine-sorted xs* ys*))
07:55_ato^ pops from both lists
07:57Chousukethe map does that... what it doesn't do is not advancing both of the lists when there's a mismatch :/
07:58_atoah right
07:58_ato,(map (fn [x y] (cond (> x y) y :else x)) [1 2 3] [1 2 3])
07:58clojurebot(1 2 3)
07:59_ato,(map (fn [x y] (cond (> x y) y :else x)) [1 3 5] [2 4 6])
07:59clojurebot(1 3 5)
07:59Chousukeand now I realised the whole fn is just min :P
08:01_atowhat?
08:02_atohow? :/
08:02ChousukeI mean in the map
08:02mikemhe means (fn [x y] (cond (> x y) y :else x)) == min
08:02Chousuke,(map min [1 1 3 3 4 5] [1 2 2 2 3 8])
08:02clojurebot(1 1 2 2 3 5)
08:02_atooh right
08:02_atoyeah
08:03_atohehe
08:03_atoI thought you meant combine-sorted was just a min
08:05cemerickhrm, looks like PersistentVector serialization is broken again, though I'm not sure it could because of the AtomicReference<Thread> field
08:05Chousukelazy-combine-sorted *does* cause the seq to grow though, unless they're identical or if the other seq is a kind of a "superseq" :/
08:05cemerickcould be serializable, that is
08:06Chousukebut for some reason this leads me to think that maybe maps would be better :P
08:07Chousukean integer key and count and you could just merge-with min
08:09Chousuke~def merge-with
08:10Chousukedoesn't seem to use transients.
08:12cemerickI suppose making that field transient will make vector serialization possible again without much of an issue. Not sure if edited transient vectors would be properly serialized, though.
08:16AWizzArdfoo takes an object and returns a sequence of "tags". Example: (map foo my-coll) ==> ((:a :b :c :d), (:d), (), (:a :d), (:e)). Is there a good bar which would accumulate those "tags"? (bar (map foo my-coll)) ==> {:a 2, :b 1, :c 1, :d 3, :e 1}? Or maybe even better: ((:d 3), (:a 2), (:b 1), (:c 1), (:e 1)).
08:16powr-tocwhats the best way to install clojure-mode/slime right now?? I've tried to go through ELPA and supposedly have the packages installed, but I can't get them to load properly
08:19_ato,(apply merge-with + (map (hash-map % 1) [:a :a :b :c :d]))
08:19clojurebotjava.lang.Exception: Unable to resolve symbol: % in this context
08:19_ato,(apply merge-with + (map #(hash-map % 1) [:a :a :b :c :d]))
08:19clojurebot{:a 2, :c 1, :b 1, :d 1}
08:20_atoactually
08:20_atoin seq-utils I think there's something
08:21_atoyeah
08:21_ato,(frequencies [:a :a :b :c :d])
08:21clojurebot{:d 1, :c 1, :b 1, :a 2}
08:22_ato,(frequencies (concat [:a] [:a :b] [] [:a :b :c]))
08:22clojurebot{:c 1, :b 2, :a 3}
08:22_atoAWizzArd: ^
08:23AWizzArdoh good, thx
08:32cconstantineIs there a clojure lib that does diffing of sequences?
08:33ohpauleezcconstantine: if the seqs are small you can turn them into sets and diff them
08:34cconstantineI'm afraid the seqs might get large
08:34cconstantinelike gigibytes in size
08:34ohpauleezah
08:35ohpauleezyou might just want to make a filter function that returns a lazy sequence of matches
08:35chousercconstantine: you want full order-aware patch-producing type diff?
08:35ohpauleezbut someone here might have a much much better idea
08:35cconstantineobviously if they are gigibytes in size and a pathilogical case for diffing we have problems, but lets assume they are very similar
08:35chouserinsert/delete detection and such?
08:35cconstantinechouser: I would like that, but I wouldn't call that a requirement
08:36cconstantinethe big idea is to diff the output of two programs line-by-line, where I convert the lines of their outputs into lazy sequences and compare them
08:37chouserif you don't care about insert/delete, you should be able to just (map = coll1 coll2)
08:37cconstantinefor my use-case of this program they will have the same number of lines, but to be a generic solution inserts/delete would need to be supported
08:38cconstantineoh... right.
08:39ohpauleezchouser: what if he did care about insert/delete?
08:40chouserohpauleez: then I'd say it's high time someone look into the diff research that's been done, maybe find some analysis of the gnu diff algorithms, and port them to Clojure seqs.
08:41chouserAnd put that in contrib.
08:41ohpauleezgotcha
08:41cconstantinehehe
08:41cconstantineie, "that sounds damned useful, and we don't have it" :)
08:41chouserheh. exactly.
08:42cconstantine*sigh*... I have 4 hours to implement this program
08:42chouserI've frequently wanted access to those algorithms for things other than lines of a file. Clojure seqs should be perfect.
08:42cconstantinethats what I was thinking
08:43Chousukecan't look a gnu diff though.
08:43Chousukeit's GPL :P
08:43chouserA friend of mine implemented a very nice english-text differ that treats all whitespace the same (newlines as well as spaces in a line)
08:44chouserhe did it by munging the input, running it through diff, then reassembling the results. The results are beautiful. The means ... not so much.
08:44_atohttp://en.wikipedia.org/wiki/Diff#Algorithm
08:44chouserhttp://agriffis.n01se.net/adiff/
08:45ohpauleez_ato: That's what I though, a LCS modification
08:45ohpauleezI wrote a program analyzer that normalized java code and tried to find plagiarized code
08:46ohpauleezit was all based on LCS and Euclidean distance (effort measured operations need to transform one to the other)
08:46cemerickwriting a proper diff for arbitrary seqs isn't really that hard. We have one that is the basis of the scorer for an approximate regex library. *shrug*
08:52powr-tocWhen you run lein swank in the terminal, does anyone else find the terminal REPL halts?
08:52powr-toci.e. it blocks... and doesn't allow input?
08:52powr-toc(except via emacs slime-connect)
09:00_atopowr-toc: yeah I get the same thing
09:00_atoI don't use lein-swank though
09:00_atoI use M-x swank-clojure-project in emacs
09:01ohpauleezit's ok to include Apache licensed code into a EPL licensed project, correct?
09:01ohpauleezbeing that Apache is rather similar to BSD in that regard
09:02powr-toc_ato: ok, might give that a try... I found that "lein repl" with a call to my (swank-server) function in my user.clj worked though... giving me both terminal and emacs access to the same repl
09:02powr-tocnot sure why I like having both a terminal based repl and the emacs one
09:03martenpowr-toc: (swank.swank/start-server "/tmp/swank.4005" :port 4005 :dont-close true)
09:03martenthat works for me
09:06powr-tocmarten: yeah, that's what I have in my swank-server fn...
09:08powr-toc_ato: swank-clojure-project seems to work quite well too
09:18alexotthello all
09:19alexotti have one question about using send-off with long-running functions. If i have some long-running function, and start it with send-off, then modification of state, that this function will receive as argument, could affect other send-off functions?
09:21alexottfor example, i call (send-off agent func), func receives agent's state, do some job (in parallel with other jobs), and return modified state. what will happen, if some another job had already changed agent's state
09:21rhickeyalexott: you are sending mutable data as an argument, and mutating it?
09:21alexotti'm sending map {}
09:21rhickeyalexott: the function sent to an agent will always see the current state at the time it is applied
09:22rhickeynot at the time it is sent
09:22alexottrhickey: ok, thanks
09:22alexottrhickey: thank you for this language ;-) I don't like Java, but I'm very happy with Clojure
09:23rhickeyalexott: you're welcome
09:26djorkwhy doesn't the with-meta reader macro attach metadata to quoted forms? (if those are the right terms... let me demonstrate)
09:26djork,(meta #^:bar '(foo))
09:26clojurebotnil
09:26chouserdjork: it attaches to the (quote ...) form
09:27chouser,(meta (quote #^:bar '(foo)))
09:27clojurebot{:tag :bar}
09:27djorkhmm
09:27djorkI'm not sure I understand
09:27chouser'(foo) is read as (quote (foo))
09:28chouser#^ attaches metadata to read-time forms, not to runtime data objects
09:28djorkah, I see
09:28chouserso the seq (quote (foo)) gets the metadata in your example
09:28clojurebotfoo is is Short, Self Contained, Correct (Compilable), Example http://sscce.org/
09:29chouserwhen compiled and evaluated, metadata on a (quote ...) form is ignored
09:29chouserperhaps you want to quote the whole thing:
09:29djorkyeah
09:29chouser,(meta '#^:bar (foo))
09:29clojurebot{:tag :bar}
09:30djorkI might also want to be using with-meta and list instead of fiddling with quoting :)
09:30chouserthat one ' quotes (foo) with its metadata
09:30chouserdjork: also possible. :-)
09:30djorkthanks
09:30aav-does anyone know which branch of clojure.contrib is compaible with clojure 1.0 ? 1.0-compatible fails to build
09:30djorkinteresting how quoting the #^ reader macro quotes the next form too
09:30chousersuffix metadata will help decrease confusion about interaction with quoting
09:31chouserdjork: as far as the reader is concerned, #^:bar foo is a single form
09:31djorkright
09:31djorkstill weird to me
09:31chouseryes
09:31chouserthe space there is I think the culprit
09:31djorkgood to know though
09:31chouserfoo^:bar looks more like a single form
09:32alexottrhickey: and another question about agents - is it possible to control number of running threads for given agent?
09:32chouserand 'foo^:bar would do what you expect, as would '(foo)^:bar ... but that meaning of ^ is a ways off yet.
09:32rhickeybut there sill never be [a data structure]^:bar
09:32chouserrhickey: really?
09:32rhickeyreally
09:32chouserwhy's that?
09:33rhickeybecause foo^:bar is enough of a hack on symbol reading, allowing ]^ etc would totally trash the concept of what it means to be a delimiter
09:34rhickeyand, who want's to search to the end of a long data structure to see if there's metadata?
09:34rhickeywants
09:35rhickey I'm completely unconvinced about suffix metadata
09:36rhickeybut I think moving from #^String foo to ^String foo will be welcome noise reduction
09:36djorkyuck, good points
09:36djorkwait, so #^ is becoming ^
09:36djorkbut ^ currenty means the opposite of #^, doesn't it?
09:37rhickeydjork: maybe someday, first comes a period of deprecation for ^
09:37djorkah
09:37somniumis there a way to add #^Klass type-hints in a macro (when Klass is a string)?
09:37djorkyeah, I don't mind (meta foo)
09:37rhickeydjork: not, it isn't the opposite, and that's one of the problems
09:37djorkI see
09:38chousersomnium: yes. type hints are symbols, so you just make sure the forms the macro is returning has the right tag metadata
09:38chousersomnium: (with-meta 'Foo {:tag (symbol "Klass")})
09:39somniumawesome! thanks
09:39rhickeywe still need a plan for deprecating ^
09:40djorkhiredman: I took inspiration from your clojurec gist and am using metadata + multimethods to really accelerate this codegen process
09:40djorkI'm planning on being able to define C modules in pure clojure using namespaces and macros
09:40djork(c-module hello-world (:import stdio stdlib))
09:40djorketc.
09:43chouserc-in-parens
09:49lisppaste8rhickey annotated #91445 "bring back :as ?" at http://paste.lisp.org/display/91445#2
09:50rhickey:as this-name optional, use only when you need to refer to this
09:51chouserhm, I had thought of a non [] marker, but :as has nice symmetry with destructuring that I hadn't thought of.
09:51rhickeyit was in early newnew design
09:52rhickeybut I hate the floating thisnames, this anchors them
09:52rhickeyand gives a context for :other settings
09:52ohpauleezrhickey: I really like this idea
09:52chouserthat's interesting terminology. I'm not confident I understand everything you mean by "floating"
09:55rhickeychouser: it's not a precise thing, more of afeel issue, in (deftype Foo [...] this Protocol (method [] ...)), Protocol feels like it is floating, having this floating too is too much
09:56rhickeywhereas :keyword val pairs feel anchored
09:58rhickeyreify read a little better in the original newnew: (reify [Interface] :as this (method [] ...)...)
09:58shr3kst3rwhen passing a script to clojure.main, how to i tell it to execute -main?
10:00rhickeybut I think P1 + methods P2 + methods ... will be important for deftypes, which might get large. It is a real mess in Java when overrides don't end up bunched by interface, and they often don't, also you can search for the protocol and find the entire implementation
10:00rhickeyso reify follows, but doesn't have the same needs as it will usually be one protocol/interface
10:02rhickeyand should there be other options, the structure will remain (deftype name [fields] options* proto+methods*), (reify options* proto+methods*)
10:02shr3kst3rfigured out my question
10:44angermanat least combine-sorted works now
11:12StartsWithKlisppaste8: help
11:12lisppaste8To use the lisppaste bot, visit http://paste.lisp.org/new/clojure and enter your paste.
11:13lisppaste8StartsWithK pasted "Generalized -> and ->> forms, no special symbols" at http://paste.lisp.org/display/91522
11:15StartsWithKjust cooked this, there are examples at the end
11:15StartsWithKwhat do you think?
11:24cemerickStartsWithK: so x is always replaced with the prior value?
11:26chouserI certainly like it better than using $
11:26StartsWithKcemerick: yes, but 'as' works ib both =>> (->>) and => (->) as espected
11:26StartsWithKin*
11:26chouserI'm just not sure it carries it's weight
11:27cemerick...the objective being threading arguments in arbitrary positions?
11:27StartsWithK(=>> [1 2 3] (map inc) (as [x y z] [(-> x inc inc) (-> y inc inc) (-> z inc inc)])) is valid too
11:28cemerickoh, I see, => defaults to -> placement =>> to ->> placement
11:28StartsWithKyes, just a quick placeholders
11:28StartsWithK'as' is normal macro, you can create a wrapping macro for it, it still work, destructurin too
11:29StartsWithKarbitrary position will never work withoud magic symbols, this is second best thing :)
11:29rhickeythere is let
11:30StartsWithKbut you cant do (-> [1 2] (let ...))
11:30chouser(let [[x y z] (map inc [1 2 3])] [(-> x inc inc) (-> y inc inc) (-> z inc inc)])
11:30rhickeyonce you put as in there the simplicity of -> and ->> is gone
11:30rhickeyso why push it?
11:30stuartsierraagreed
11:31StartsWithKrhickey: true, it was just a small experiment i just did
11:31chouserthis is what I meant by "weight". Although there are occasions when I start with -> or ->> and realize an out-of-place arg is required and so I have to break out into 'let', in the end such complex expressions feel better as 'let' anyway.
11:31rhickeyStartsWithK: that's fine, just my $.02
11:32stuartsierrachouser: I find the same thing
11:32chouserHuh. I haven't used doto in ages.
11:32chouserI guess that has mostly to do with the APIs I'm interacting with.
11:32rhickeyI think it is important that -> and ->> convey that the entire expression is chained or piped
11:32rhickeynot woven
11:33stuartsierraor knotted
11:33rhickeyheh
11:34Raynesrhickey: I read that as "not women"
11:34clojurebotwomen are just jealous, since lisp has nice curves. -- Chousuke
11:34chouserI did write and use a macro like -$> early on.
11:34rhickeyso http://paste.lisp.org/display/91445#2 is the winner, barring some substantive objections
11:34chousercalled mine >>_
11:35Chousukeif you're going to have arbitrary position pipelines you might just have the arg be explicit in every expression.
11:35chouserrhickey: good.
11:38chousermethods aren't functions, but might they support :pre/:post anyway?
11:39fogus_Not to beat a dead horse, but an additional benefit to -> and ->> is that they can be used programmatically to build functions/forms pretty generically. -$> and the like require some precise knowledge about the pipeline elements
11:40rhickeychouser: :pre and :post are interesting - I had originally planned to put them on the protocols themselves, but that is trickier with the inline implementation of protocols in deftype and reify
11:41chouseroh, right, I remember that now. hm...
11:42angermanis c.c.duck-streams read-lines or reader specifially mean?
11:43chouserread-lines is a bit dangerous. I don't like tying the closing of the file to consuming the whole seq.
11:44chouserangerman: but if you're running out of memory, the most likely problem is that the head of the seq is being held somewhere, preventing GC from freeing it.
11:45stuartsierraUsing lazy sequences for large file processing is very difficult.
11:47stuartsierraduck-streams is written for convenience, with no consideration of memory usage.
11:50angermanmy utilities http://gist.github.com/248319 , my code: http://gist.github.com/248320 , my sample file http://dl.dropbox.com/u/281539/upps.data.model.bz2 [60M]
11:50angermanstuartsierra: what's the best way to read a file linewise then?
11:50stuartsierraangerman: your problem is in (defn compute-metrics [[header lines]]...)
11:50stuartsierra"lines" is the head of the sequence, not released until the tail call of the compute-metrics function.
11:51angermanyes, somewhere there it's crashing
11:51stuartsierraMy rule of thumb is this: never bind a lazy sequence to a local variable, including function arguments.
11:51angermanstuartsierra: initially i thought about using (with-in-reader), hoping I could just (read-line) after another and process it. :(
11:52neilmockis surrounding a var definition in * idiomatic for something?
11:52AWizzArdIs there a .csv parser for Clojure?
11:53angermanstuartsierra: ok, but mapping and reducing is allowed, right?
11:53stuartsierraangerman: sure, that's not the problem.
11:53chouserneilmock: *earmuffs* suggest the var is meant to be re-bound using 'binding'
11:54stuartsierraneilmock: or used as a global variable/constant
11:54angermanstuartsierra: how would I approch my problem then, to parse the file with parse-header until it hit's the line SV and then continue to parse the rest with compute-metrics?
11:55rhickeystuartsierra: looking into liveness tracking is next on my todo after incorprating the latest forms of deftype and reify
11:55angermansomehow I need to hand over the point where parse-header left of to compute-metrics.
11:55rhickeyunless someone else wants to do the latter
11:55neilmockchouser: ah, thanks!
11:55stuartsierraangerman: my best suggestion is to work with the java.io.Reader directly.
11:55StartsWithKisn't +foo+ a convention for global/constant?
11:56stuartsierrarhickey: great
11:56stuartsierraStartsWithK: sometimes, but not used as often, lots of people use *foo* for that too
11:56angermanstuartsierra: so in the wide-finder thing, it only works because he's explicitly mapping and mergine the lazy-seq
11:57stuartsierraangerman: haven't seen that code
11:59angermancan I implement something like http://code.hammerpig.com/how-to-read-really-large-files-in-java.html in pure clojure?
12:00stuartsierraangerman: in http://technomancy.us/130#c it works because the result of line-seq is never bound to a local variable.
12:00stuartsierraangerman: You can do this in Clojure, you just have to be careful.
12:00Chousukeangerman: that's just line-seq, isn't it?
12:01chousera non-caching line-seq, perhaps.
12:01Chousukewell, just don't hold onto the head
12:02angermanhmm. alternativly I could write a function, and rebind it with a sideeffekt?
12:03lisppaste8stuartsierra pasted "Safe lazy sequences" at http://paste.lisp.org/display/91525
12:04chouserit's pretty unfortunate how subtle that is.
12:04stuartsierrayes
12:04chouserstuartsierra: but that's a nice clear, specific example. thanks.
12:04stuartsierraTook me ages to figure it out.
12:04stuartsierrachouser: you're welcome
12:05Chousukehm.
12:05rhickeythis is one area where hotspot has definitely let me down - those local references should be plainly dead to the GC
12:05stuartsierraActually, (read-lines (reader filename)) is redundant
12:07Chousukeso wait, why does process-lines hold on to the head? the map returns immediately, and isn't reduce a tail call? I don't quite see what's happening there
12:08Chousukeassuming that process-stuff in the latter code is supposed to be process-lines
12:08stuartsierraChousuke: yes
12:08rhickeywhat's with the read-lines example though?
12:08stuartsierraChousuke: I'm not sure if process-lines is actually safe; maybe "lines" gets cleared and reduce is a tail call
12:09Chousukelooks fine to me.
12:09stuartsierrarhickey: That's usually the first place people get hung up on non-GC'd lazy sequences, trying to read a large file line by line.
12:10rhickeystuartsierra: is the problem in read-lines or process-stuff?
12:11stuartsierraThe problem (I think) is passing the sequence as an argument to process-stuff.
12:11rhickeystuartsierra: if you have a test case for that can you try it in master and new?
12:12lisppaste8stuartsierra annotated #91525 "Safe lazy sequences (2)" at http://paste.lisp.org/display/91525#1
12:12stuartsierrarhickey: sure, I'll try to come up with a test case
12:14angermanwell. I think my code could probably be a testcase, he :)
12:15rhickeystuartsierra: nm, I thought you had a case of invoke holding, but your latter example is just data literal is not a tail call
12:16rhickeyfrom the perspective of locals clearing
12:16stuartsierrarhickey: right, that's why it doesn't work
12:17rhickeybut not a problem with read-lines
12:17stuartsierraNo, there's no problem with read-lines, it just returns a sequence. It's what people do with that sequence that's a problem.
12:18rhickeyshiny: http://github.com/bradford/crane
12:19stuartsierrayeah, I've been looking at that
12:19rhickeystuartsierra: there was a subtle hold inside apply and restfn (Java code) which I removed in the new branch
12:20rhickeymost of the examples I see are just clear realization of a seq prior to tail call, needs liveness tracking to fix
12:20stuartsierraok
12:21chouser,(time (try (let [s (iterate #(java.util.Arrays/copyOf % (count %)) (int-array (range 1e5)))] [(first s) (last s)]) (catch Error e (prn e))))
12:21clojurebotchouser: Huh?
12:21rhickeyso for all of you testing fans out there, I have some feedback
12:21rhickeyin working on new branch I kept controb working
12:22rhickeyseveral times something I did caused a contrib test to fail
12:22angermanin the future, will i be able do use a seq, the way i tried to use it?
12:22rhickeynever did the test failure help me figure out how what I did affected the code that failed
12:23chouserdid it help you discover a possible drawback to a change that you hadn't considered?
12:23rhickeyjust meaningless stuff like (not (= 42 43))
12:23fogus_rhickey: Uncle Bob just felt a pain in his temple
12:24stuartsierrarhickey: was the problem with the way the tests were defined, lack of documentation, poor naming?
12:24rhickeythe tests themselves were nigh unreadable
12:24rhickeyand the failure message conveyed little other than - 'unexpected result'
12:24stuartsierraWell, what else could it convey?
12:25chouser,(let [s (iterate #(java.util.Arrays/copyOf % (count %)) (int-array (range 1e7)))] [(first s) (last s)])
12:25fogus_To put valueable error messages would only add further obfuscation
12:25rhickeystuartsierra: I'm not proposing an answer, just conveying my experience
12:25clojurebotExecution Timed Out
12:25chouser,(let [s (iterate #(java.util.Arrays/copyOf % (count %)) (int-array (range 1e5)))] [(first s) (last s)])
12:25clojurebotjava.lang.OutOfMemoryError: Java heap space
12:26chouserthere. that's the fastest-failing infinite lazy seq I've found yet.
12:26chousersmaller or larger arrays take longer to fail
12:28rhickeystuartsierra: the author of a test knows it should produce 42, given a full understanding of the original code, the consumer of a failed test knows 42 != 43
12:29angermanok. I'll have to write that BigFile as a clojure option.
12:29stuartsierrarhickey: yes, I tried to help with that in "is" by printing both the unevaluated form and the evaluated result, but it's not perfect
12:29rhickeysomewhere inside the code a semantic invariant was violated, but the test treats the semantics as a black box
12:30rhickeyI guess something like pre/post conditions would be better for me
12:30stuartsierrarhickey: So rather than specific results, it would be better to test semantic invaniants?
12:30stuartsierra*invariants
12:31rhickeystuartsierra: I don't know, like I said, just conveying my experience. The tests worked in that I knew I broke something, but that was the extent of the help
12:32bitbcktrhickey: Seems like useful input for something like git bisect, though.
12:32bitbckte.g. "What commit broke that?"
12:32stuartsierrarhickey: Better than nothing. That's been my experience with testing as well, though.
12:32rhickeybitbckt: but I knew that information
12:33rhickeyit's more a matter of, what about what I did matters to this failing code and why?
12:33stuartsierraThat's a lot harder.
12:33rhickeygiven I know nothing about the failing code
12:33stuartsierraI think it's like error messages and stack traces - they tell you something went wrong, but don't tell you why.
12:34angerman(with-big-file (read-big-file "....") (next-line) ;; return next line // (rest-seq) ;; returns lazy sequence for the rest of the file)
12:34bitbcktstuartsierra: It's exactly like that, to me.
12:34rhickeystuartsierra: but there can be a useful locality there - failing tests just says - this end result is bad
12:34angermandoes that seem like a suitable wrapper?
12:34stuartsierrarhickey: "useful locality" - can you explain more?
12:35rhickeystuartsierra: well, if there were pre and postconditions inside the implementation of the code under test, any violation would report about the inside of the codebase, not its results
12:38stuartsierraSo you're looking to know specifically where the failure occurred?
12:39bitbcktThe test failing is merely a flag, to me. It signals that something I didn't intend to break, broke, and I need to investigate.
12:40bitbcktThe "why" comes from reasoning, not from the test.
12:40rhickeystuartsierra: well, with an exception for instance I get a pointer inside the code in question
12:40stuartsierrabut often several layers removed from the actual cause of the bug
12:40rhickeybitbckt: that's not an answer here, I can;t reason about code I didn't write without a huge amount of work
12:40rhickeystuartsierra: still, there's a path too
12:41stuartsierrayes
12:41stuartsierraI think what we're getting at here is that unit tests on library code are not helpful for debugging language implementations.
12:42rhickeystuartsierra: I don't think that's the issue
12:43stuartsierraI guess I'm having trouble visualizing pre/post conditions that could provide better failure diagnosis.
12:43rhickeyconsider the difference between unit tests and pre and post conditions
12:44rhickeya precondition says - I expect this input to be even, a unit test produces 43 instead of 42 when it isn't
12:44rhickeythe precondition is in the head of the test author, but gone at test runtime
12:45bitbcktThat seems like a poorly-written test.
12:45stuartsierraBut isn't that just the fault of the test author? i.e., instead of testing (is (= 42 foo)) they should test (is (even? foo))
12:45bitbcktThe point is to avoid "a huge amount of work"
12:46rhickeystuartsierra: (is (even? foo)), then pass 17 - what's the point? if the test for evenness isn't in the code called
12:47rhickeyi.e. the test should verify that the precondition is validated by the runtime code
12:47bitbcktrhickey: Are you looking for greater coupling between the tests and the implementation? That's what it sounds like...
12:47rhickeyyou can't move a precondition into a test
12:49stuartsierraOk, so you're looking for functions to do more run-time validation, then use the tests to verify that they are doing it correctly?
12:50rhickeystuartsierra: if the latter is even needed, given the former (or the former in a validation mode, sometimes the checks are too expensive)
12:50rhickeyasserts > tests
12:50stuartsierraOk, now I get it.
12:50bitbcktThere we go. You finally said it.
12:51stuartsierraI think of unit tests as guarantees of future behavior. E.g., I changed the implementation of this function to make it more efficient, but did I accidentally change the behavior as well?
12:51rhickeyum, I think Bertrand Meyer figured this out a while ago
12:52rhickeystuartsierra: no doubt, they do that - my scenario is different than the code author's
12:53stuartsierraMaybe I should learn Eiffel.
12:55stuartsierraRecalling my Algorithms class, defining invariants is MUCH harder than writing unit tests. :)
12:55rhickeywell, clojure has ;pre and :post now, so people can play with them
12:56stuartsierrais there a summary of those somewhere?
12:59rhickeyhttp://github.com/richhickey/clojure/commit/0ac482878a1dd520cbee2faa0f5f6ab1082ffa76
13:00rhickeystuartsierra: speaking of the documentation punchlist for 1.1 ... :)
13:00fogus_Seems like we're heading down the road to incorporating Datalog
13:00rhickeyI've cleared the plate of 1.1. features other than some deprecate/doc stuff
13:00bitbcktfogus_: Sadly.
13:01rhickeybitbckt: how is that sad?
13:01fogus_bitbckt: You misspelled "awesome"
13:01bitbckthaha
13:01lisppaste8stuartsierra pasted "Simple laziness test cases" at http://paste.lisp.org/display/91528
13:01rhickeystuartsierra: do you want to marshall the dev troops around 1.1 prep?
13:02stuartsierrasure, what do you need?
13:02rhickeyfirst step is determining what we need
13:02rhickeysome things already known - a list of changes since 1.0
13:02stuartsierra:)
13:03rhickeydocs for bigger features that won't be found in doc strings (e.g. chunks, transients)
13:03rhickeyany packaging issues (we've had complaints about the .zip littering the expansion dir)
13:04rhickeynew API docs from Tom Faulhaber's process (these are underway)
13:04rhickeymaven stuff
13:04stuartsierraok
13:06stuartsierrarhickey: What do you think of packaging a contrib snapshot with 1.1?
13:07rhickeystuartsierra: definitely interesting, will require some commitment from contrib to maintain a 1.1 branch if needed
13:07rhickeythese are all good things to raise in clojure-dev
13:07stuartsierraok
13:08rhickeya plan for release candidates
13:09rhickeythese are the only open items right now for 1.1: https://www.assembla.com/spaces/clojure/tickets?milestone_id=93750&amp;tickets_report_id=1
13:10stuartsierraworking on 214
13:10alinphi guys
13:10alinpI have an issue here, that I can't build the clojure-contrib
13:11alinpant -Dclojure.jar=clj.jar
13:11alinp[java] Caused by: java.io.FileNotFoundException: Could not locate clojure/walk__init.class or clojure/walk.clj on classpath:
13:12alinpthis is from where I got the sources: git://github.com/richhickey/clojure-contrib.git
13:12stuartsierraalinp: you have the 1.0 release of Clojure and the github master release of contrib
13:12alinpah
13:12alinpso, there is a way to use the old version of clojure-contrib ?
13:12alinpor a stable version or something like that
13:12stuartsierraalinp: yes, checkout the "clojure-1.0-compatible" branch of contrib
13:13alinpok, great
13:13alinpthanks
13:14rhickeystuartsierra: I guess one pre-req for contrib release with clojure is that there be some cordoning off of the code destined to be 1.1 while new work proceeds (akin to new vs master right now in core)
13:15stuartsierraThe biggest problem is that different contrib libraries are at different levels of release-readiness.
13:16rhickeyyou could create a 1.1 branch and trim off any libs not ready
13:17rhickeydefinitely needs discussing on clojure-dev
13:17stuartsierrako
13:17stuartsierraok
13:49chouserMmm...
13:55cemerickrhickey, stuartsierra: FWIW, I'd be happy to help with the maven bits, if no one else is ready/willing.
13:55ohpauleeznice
13:56rhickeychouser: it's a refinement of the argument Will Clinger made at Lisp 50 at OOPSLA last year
13:57rhickeythe Cook paper he refers to is more interesting
13:57chouserheh
13:58rhickeysomething I'd just been reading while working on protocols
13:59chouserwell, the tail-call argument is so frequently trotted out by people trying to avoid learning clojure, that I feel I need to understand its best-reasoned arguments.
14:00chouseroh! it's just what we saw with counting in ASeq
14:01rhickeyright, that was Clinger's example recursive OO contains in Java
14:01rhickeySteele's point can't be understood without reading Cook's paper
14:07chouserwell, before reading Cooks paper, it seems to me that explicit trampoline methods in the interface, while relatively messy, would resolve this particular issue.
14:08chouserI guess I could implement it in clojure to demonstrate that point.
14:08rhickeychouser: but that's just admitting the point, you need that style of recursion to work
14:09rhickeywhere you put it is a separate question
14:10rhickeyanyway, Cook's paper is a great survey of a set of interesting issues, even if his point is quite subtle
14:10tomojwhich paper is this? sorry, just got here
14:11rhickeytomoj: http://www.cs.utexas.edu/~wcook/Drafts/2009/essay.pdf
14:11tomojthanks
14:12rhickey"While Java is not a pure object-oriented language, it is pos-
14:12rhickeysible to program in a pure object-oriented style by obeying
14:12rhickeythe following rules""
14:12tomojhuh, unfortunately never had a class with that guy
14:12rhickeyClasses only as constructors A class name may only be
14:12rhickeyused after the keyword new.
14:12scottjAnyone know of a good serious doc that outlines "these are the things you can't do in static typing systems", "this is why they're important and where they come up in writing real software", "this is how you have to work around it", and does it for a good typing system (I hear haskell or ocaml)? I'm fine w/ if there's a dynamic bent to it.
14:12rhickeyNo primitive equality The program must not use primitive equality (==).
14:13rhickeyIn particular, classes may not be used as types to declare members, method arguments or return values. Only interfaces may be used as types. Also, classes may not be used in
14:13rhickeycasts or to test with instanceof.
14:13chouserthe comments on the blog post itself as well as elsewhere suggest that explicit trampolines would be insufficient, that the only alternative to proper TCO is an explicit closed case statement covering all possible types.
14:14rhickey"This is generally considered good object-oriented style.
14:14rhickeyBut what if you were forced to follow this style, because
14:14rhickeythe language you were using required it?"
14:15stuartsierraOne thing I've wondered about deftype is how to define a type in which some fields are computed rather than stored.
14:16chouserstuartsierra: I *think* that's an abuse of deftype. Should use a protocol for that.
14:16rhickeystuartsierra: they are not fields then
14:16stuartsierraThat's what I thought.
14:17stuartsierraI like the separation of methods (protocols) from fields (types).
14:23konrwhat was the function that could generate [0 1.5 3 4.5 6 ...]?
14:24the-kenny,(iterate #(+ % 1.5) 0)
14:24Chousukerange?
14:24clojurebotEval-in-box threw an exception:java.lang.OutOfMemoryError: Java heap space
14:24Chousuke,(range 1 5 0.5)
14:24clojurebot(1 1.5 2.0 2.5 3.0 3.5 4.0 4.5)
14:24the-kenny... that's easier :)
14:25konrthanks!
14:25Chousukeit can even generate exact fractions
14:25fogus_,(take 5 (iterate #(+ % 1.5) 0))
14:25clojurebot(0 1.5 3.0 4.5 6.0)
14:25Chousuke,(range 1 5 3/4)
14:25clojurebot(1 7/4 5/2 13/4 4 19/4)
14:25lpetit,(doc range)
14:25clojurebot"([end] [start end] [start end step]); Returns a lazy seq of nums from start (inclusive) to end (exclusive), by step, where start defaults to 0 and step to 1."
14:25lpetityou cannot use range to produce an infinite lazy-seq of step <> 1
14:26Chousukewell, yeah.
14:26scottjwhen java heap space is exhausted from a dumb mistake (evaluating a infinite sequence), does it wait for a while to gc all that garbage so there's more space on the heap or does it keep all that dumb stuff around? (when you're in the repl)
14:26Chousukein that case just use iterate.
14:35stuartsierraSo real-world modeling should be done in terms of protocols, not types? E.g., we have an Employee protocol, operating on some (hidden) type representing the data that define an employee.
14:36rhickeystuartsierra: yes
14:36stuartsierraThat's what I thought.
14:36rhickeystuartsierra: that's really the way Clojure's abstractions were designed
14:37stuartsierraBut everybody gets it wrong by trying to model with defstruct.
14:37rhickeyJust had onlu interfaces to represent them, and the RT.* functions bridged the abstractions beyond the interfaces, but was a closed system
14:38rhickeystuartsierra: defstruct isn't a model - no functions
14:38iceyHas anyone compiled a list of Clojure best-practices? It might be nice to have a short document that says "Hey, if you're modeling, use this. If you need concurrency, here are the use-cases and why." etc.
14:38stuartsierraI like this: "When implementing data abstractions, there are two important dimensions of extensibility. New representational variants can be added, or new operations can be added. This observation suggests it is natural to organize the behaviors into a matrix with representations on one axis and observations/actions on the other. Then extensibility can be viewed as adding a column or row to the matrix."
14:39rhickeyprotocols + deftype deliver exactly that
14:40stuartsierrayes!
14:40stuartsierraicey: It's still evolving, mostly on IRC and the mailing list.
14:41rhickeyI liked: "One conclusion you could draw from this analysis is that the untyped λ-calculus was the first object-oriented language."
14:41lpetitrhickey: so accessing a type's field from anywhere but the type's definition or the literal code of a protocol's type implementation should be considered a code smell
14:41lpetit?
14:43stuartsierra"academics tend to be more interested in correctness than flexibility. Finally, programming language researchers tend to work with data abstractions that are more natural as ADTs."
14:43stuartsierralpetit: yes, I think so.
14:43rhickeylpetit: no, because in order to make a type you don't own reach a protocol, you might need to access its fields. At that point it is acting as a concrete type. Consumers must understand that this is a tight binding. Otherwise concrete types will just expose their fields via a type-specific protocol and, well, that's not much different
14:45rhickeybut limiting the set of abstractions a type can reach to the original author is a known loser - see every OO language without open classes
14:45rhickeyHaskell gets by pretty well with type classes applied to types with fully exposed structure
14:45lpetitrhickey: didn't I write "or the literal code of a protocol's type implementation" ? :) that is : you can access fields of the type when you're extending the protocol for that type
14:46lpetitrhickey: aren't we saying the same thing with different words ?
14:46rhickeylpetit: I thought you meant the implementations of protocols in the deftype
14:47rhickeyconfused by "a protocol's type implementation"
14:47lpetitrhickey: I said both, right in the deftype, and in extends for that type, but not anywhere else in the code (or you're starting to be coupled)
14:47lpetitrhickey: my bad, not native english speaker, sorry
14:47stuartsierraSo fields of a type should rarely, if ever, be accessed outside of a protocol implementation.
14:48rhickeyhad you said extends I would have seen it, so yes - ok to access type in definitions of protocols, but also in type-specific helper functions to facilitate that
14:49replacaOK, API doc is up at http://richhickey.github.com/clojure/. Enjoy!
14:49rhickeystuartsierra: I;m not so focused on the prohibition than on the positive recommendation - modeling in terms of protocols will serve you well
14:49rhickeyreplaca: thanks!
14:49lpetitreplaca: now that's something, congrats !
14:50rhickeyalso via: http://clojure.org/api
14:50cconstantinereplaca: very nice :)
14:50replacastill lots more work to do
14:50replacathanks, all
14:50lpetitrhickey: wow, so the move is official ! But what is it: the doc for 1.0, or a fresh checkout of main ?
14:50stuartsierrarhickey: fair enough.
14:51replacanext up, support for leiningen (so your project can have pretty doc too)
14:51replacalpetit: fress checkout of main
14:51replaca*fresh
14:52stuartsierrareplaca: patch on #217 will add docstrings for core namespaces.
14:52lpetitrhickey: maybe you should keep the old 1.0 page around (and easily visible) for users of official 1.0 release ?
14:52rhickeystuartsierra: the bigger prohibitions are - don't use new, or '.', or the protocol interface other than in a Java extension
14:52cemerickreplaca: far be it for me to offer design advice, but perhaps allowing the TOC to be separately scrollable would be a good tweak
14:53lpetitreplaca: it would also be great to have the version of the "library" the doc applies to displayed. Though I don't know how to do this right now ...
14:53replacastuartsierra: yeah, I saw you working on it. When it's applied, it will flow through naturally
14:53stuartsierracool
14:54djorkis there a setting to get full stack traces in the REPL?
14:54stuartsierradjork: no, but (.printStackTrace *e) will do it
14:54replacacemerick, lpetit: good ideas. lpetit: I have that info, so I'll look at where to add it
14:54djorkthanks
14:54rhickeystuartsierra: also avoid instance?, isa?, extends? and satisfies?
14:54cemerickreplaca: it's amazing how much javadoc got right :-)
14:55cemerickrhickey: my poor multimethods are such second class citizens now ;-)
14:55stuartsierrajavadoc is one of the best doc systems around, only thing it lacks is a link to the source of each method.
14:56rhickeycemerick: not really, but they serve a different purpose. Some of the things I did for protocols might apply to multimethods
14:56replacacemerick: yeah, though Java SE overwhelms it
14:56lpetitcemerick: not if you're still doing multiple dispatch, even a very controlled one just on types (think the classic Visitor pattern)
14:56cemerickMaybe I should have used two or three winks ;-)
14:57rhickeyso one problem with the new docs it that they break all internal API links in the rest of clojure.org
14:57rhickeyof course the new docs have even better anchor tag support, so should be straightforward to map everything
14:59rhickeylpetit: but double dispatch with protocols doesn't require the intrusion as does the Visitor pattern
15:00rhickeyi.e. can be open
15:00lpetitrhickey: ok, thanks to the oppenness of the system, but still a lot of boilerplate, no ?
15:00lpetitopenness
15:00replacahttp://richhickey.github.com/clojure/&lt;namespace&gt;-api.html#&lt;namespace&gt;/&lt;function-name&gt;
15:00replacae.g. http://richhickey.github.com/clojure/clojure.stacktrace-api.html#clojure.stacktrace/print-throwable
15:00rhickeylpetit: you'll still have x*y implementations
15:01replacaNow that I look at it, I'm surprised that the / after the # doesn't mess things up
15:01replacathough it works fine for me
15:01rhickeyreplaca: yes, I saw that - nice, hopefully not subject to wikispace's problems with some characters in anchors, lemme try...
15:03lpetit~protocols
15:03clojurebothttp://clojure-log.n01se.net/date/2009-10-13.html#12:02
15:03lpetitoh, it's been redefined
15:03rhickey(defprotocol Addable (add [x y]))
15:04replacarhickey: easy to make some extra translation rules if we need 'em
15:04rhickey(defprotocol AddableToInteger (add [x i]))
15:04replacarhickey: just let me know
15:05rhickey(extend Integer Addable :as i (add [y] (addi y i))
15:05rhickeyshould have been AddableToInteger (addi...
15:06stuartsierrarhickey: Is arithmetic a protocol?
15:06rhickeythat style of double dispatch is how Clojure math used to work when it had it's own numbers
15:06rhickeystuartsierra: oh, no
15:06lpetitrhickey: oh, btw, I missed an information: explicit or none "this" is what you've come up finally ?
15:06rhickeyjust an example for lpetit
15:06rhickeylpetit: :as this
15:07rhickeylpetit: pretty much what you wanted but no dots
15:07rhickeylpetit: http://paste.lisp.org/display/91445#2
15:08lpetitrhickey: yes, the double dispatch is still needed, more like in Smalltalk I guess, but still need a double dispatch where it would not have been necessary with multimethods
15:08lpetitrhickey: thanks
15:08rhickeyreplaca: looks like it works fine - I think the problem was with their anchors, not external ones
15:09rhickeylpetit: yes, but it will be much faster than multimethods
15:09lpetitrhickey: of course, manual double dispatch is the price to pay for performance ...
15:10replacarhickey: great!
15:10rhickeylpetit: I mean specifically manual double dispatch for this case will be faster than multimethods for this case
15:10chouserAll the links to specific api docs from clojure.org pages are now broken.
15:10lpetitrhickey: yes
15:11lpetitrhickey: I like the last version with :as
15:11rhickeychouser: yes, I just mentioned that
15:11lpetitI must leave, cu
15:11chousersorry, behind on the log.
15:11rhickeychouser: fortunately the anchors are good in the new doc, and we won't have the hiccups with special characters
15:12chouserok, excellent. Just need to walk through and fix the wiki pages?
15:13rhickeyyup
15:16chousertime for some vimmin'
15:17replacathis is one of many things that makes me happy to be producing pure html rather than dealing with wiki stuff. In the old google code version, dealing with anchors was a major headache
15:18drewrwhat am I doing wrong here? http://gist.github.com/248466
15:18drewrI would expect (car (Cons 1 nil)) to return 1
15:19drewralso, is there a better way to model this?
15:20drewr"Consable" is admittedly lame
15:21ohpauleezdrewr: you most likely want rest or last, not cdr
15:21ohpauleezmost likely rest
15:22ohpauleezdrewr: clojure uses first and rest, not car and cdr
15:22hiredmanohpauleez: he implementing his own
15:22drewrohpauleez: clojure doesn't have cons cells :-)
15:22ohpauleezahh nvm, you're defining the protocol for it
15:23ohpauleezright, I see that now, I didn't see the defprotocol when I took a quick look
15:23drewrjust using a known construct for experimenting
15:23drewrtrying to compare to haskell
15:25rhickeydrewr: returns 1 for me here
15:26drewrlet me update my new branch then
15:26drewrI'm on dd152aed9c from Monday
15:27stuartsierrarhickey: I've put in patches for the remaining 1.1 tickets
15:28rhickeystuartsierra: awesome - thanks!
15:28stuartsierraMy patch for #217 may be sufficient #216 as well.
15:28drewrrestarting the jvm helped
15:28drewrI must've polluted the user ns
15:29drewrwould have thought everything would have been redefined though
15:30rhickeystuartsierra: yes
15:30stuartsierraNeed to improve error message on #215, working on that
15:30rhickeyheh, was just going to say...
15:32drewrfrom the previous conversation, I guess I should name my protocols Cons and List instead
15:32drewrand then create concrete types?
15:34drewrthen I lose the ability to say (Cons 1 nil), which is more natural
15:35drewr(deftype Cons [car cdr] [ICons] ...) perhaps
15:36stuartsierrarhickey: ok, better patch for #215
15:39AWizzArdclojurebot: max people
15:39clojurebotmax people is 239
15:39AWizzArd:-)
15:40chouserstuartsierra: should that be System.err?
15:40rhickeyAWizzArd: amazing, as too, almost 25k messages and 3k members on the group
15:40angermanwhat does "clojure.proxy.java.io.StringWriter cannot be cast to java.io.PrintWriter" want to tell me?!
15:41stuartsierrachouser: I thought about it, but so many IDE's hide System.err
15:42stuartsierraangerman: You're using PrintWriter-specific functions inside with-out-str ?
15:42chouserstuartsierra: ok
15:43AWizzArdrhickey: yes, it is happening, and I congratulate you to this :)
15:43rhickeyso, how many uses of ^ have we got in clojure itself?
15:43stuartsierrarhickey: I removed them; it was ~2 in core.clj, a dozen or so in xml.clj, and 1 in genclass.clj
15:43rhickeystuartsierra: cool, thanks
15:44stuartsierraPlus a couple in test-clojure, which I also removed
15:45angermanstuartsierra: I'm trying to ad an extention to c.c.d-s
15:45angermanhttp://gist.github.com/248498
15:45angermanand then eveluate (.readLine (random-access-reader "/Users/angerman/testfile"))
15:45angermandon't see the link :(
15:48stuartsierraangerman: first of all, you should use in-ns, since you're re-opening the namespace.
15:49hiredmanis there a replacement for ^ yet?
15:49stuartsierrahiredman: (meta foo)
15:49hiredman
15:49angermanstuartsierra: ok. that's what I was wondering for anyway ;) thanks for clearing that up
15:49hiredmanI meant a replacement reader macro
15:49stuartsierraI don't think there is meant to be; the goal is to use ^ in place of #^
15:50hiredmanok
15:51prhlava1hello, how to I upload files to the "files" section of the clojure google group? I need to upload fixes (as the code examples are broken for clojure 1.1.0), and AFAIK only managers can upload...
15:52konrHas anyone tried to play an mp3 song using clojure?
15:52angermanstuartsierra: but apart from the ns -> in-ns issue. is there any connection to the PrintWriter issue?
15:53stuartsierraangerman: Why are you binding *file*?
15:53angermanthat was an initial, though, I plan to rewrite the macro. As *file* is probably the most stupid thing i could have come up with
15:54stuartsierra*file* is already used by Cloure
15:54angermanthe idea to bind it to a var is to support some additional function.
15:54angermanstuartsierra: yes, saw that.
15:54angermanbut the error arises without using the macro. just from (.readLine (random-access-reader "/Users/member:angerman/testfile"))
15:55angermanyey. for colloquy rewriting the path :(
15:56stuartsierradunno; check the return type of random-access-reader
15:56angermanohh.
15:56angermanMaybe it comes from the File call
15:57tmountaincan someone remind me how to test if a vector contains a given element?
15:58angermanwow.
15:58the-kenny(get vec elem nil)
15:58the-kenny(Will return nil if elem is not present)
15:59stuartsierratmountain: I think you want (some #{elem} vector)
15:59stuartsierra(get vec elem nil) will return nil if elem is not a valid *index* into vector.
16:00stuartsierra,(get [:a :b :c] 2)
16:00clojurebot:c
16:00the-kennyagh
16:00the-kennysorry :/
16:00tmountainstuartsierra: thanks!
16:00angermanstuartsierra: I'm sorry to have bugged you. Baiscally (File. (str "/User/angerman/" "testfile")) was causing the error :'(
16:00angermanand that wasn't even clear from my sample
16:00stuartsierraok
16:01djorknow this might not be everybody's taste, but... (c (defn int main [int argc, char** argv] (printf "%i args" argc) (return 1)))
16:01djork:P
16:02the-kennydjork: I like this idea
16:02the-kenny:D
16:02djorkscriptjure influenced it a lot
16:02djorkalso supports objc
16:02chouserdjork: very cool.
16:03djorkwill be on github soon enough
16:03chouserdjork: any code in common between what you have and scriptjure?
16:03djorkI borrowed the "emit" and "emit-special" approach but other than that it's pretty much from scratch
16:04chouseras in, could there be a library that makes it easy to write new foo-in-parens for various languages of foo?
16:04stuartsierrachouser: String Template!
16:04djorknot a bad idea
16:04djorkit was shockingly easy, actually
16:05djorkso doing other languages would probably only improve this code
16:05djorkI took the liberty of adding things like let and using terms like ref and deref for pointers
16:05ska2342schaf5: hi, everything fine with your Emacs setup?
16:07angermanok. Problem not solved
16:07angermanit's the (.readLine method on the RandomAccessFile) that cases clojure.proxy.java.io.StringWriter cannot be cast to java.io.PrintWriter
16:09hiredmanangerman: you are wrapping something in a proxied StringWriter
16:12prhlava1? ok, so no-one from "normal mortals" can upload to files section of clojure google group these days?
16:13chouserprhlava1: I'm pretty sure anyone subscribed to the group can upload a file
16:13stuartsierraBut I would tend to discourage file uploads to the group anyway.
16:13chouserprhlava1: though that's not used for submitting patches or anything
16:14stuartsierraProbably most of the files currently there should be deleted.
16:14angermanhiredman: but how did I do that? so I have a RandomAccessFile object. and .readLine (according to the api) returns a String. now, even if I put that into a let binding, and output nil, e.g. (let [line (.readLine raf)] nil) i get that exceptions. It's really puzzeling me
16:14prhlava1cheers, but I can only see rename & delete now. What I have is (simple) examples of Clojure usage. Where is the better/preffered place to post this?
16:14hiredmanangerman: lets see your code
16:15prhlava1? wiki ?
16:17angermanhierdman http://gist.github.com/248532
16:18hiredmanangerman: and what is the exception
16:19chouserprhlava1: you might consider http://en.wikibooks.org/wiki/Clojure_Programming which is linked right from clojure.org
16:19hiredmanand what does file-str do?
16:19angermanclojure.proxy.java.io.StringWriter cannot be cast to java.io.PrintWriter [Thrown class java.lang.ClassCastException]
16:19angerman(file-str "...") converts the String into a File object, it's from c.c.duck-streams
16:19stuartsierraprhlava1: I would suggest just posting a message to the group for feedback first.
16:19hiredman~def file-str
16:20hiredmanangerman: what is the result of the call to file-str?
16:21angermanhiredman: http://github.com/richhickey/clojure-contrib/blob/master/src/clojure/contrib/duck_streams.clj#L86 ; result is #<File /Users/angerman/upps.data.model>
16:21angermanRandomAccessFile API http://java.sun.com/javase/6/docs/api/java/io/RandomAccessFile.html
16:21prhlava1chouser: thank you, I am going to put it there. :-)
16:22prhlava1stuartsierra: and will post to the group first :-) .
16:23hiredmanangerman: works fine here
16:23angermanO_O
16:23hiredmanmust be an issue in some other piece of your code
16:24angermanhas clojure "1.1.0-alpha-SNAPSHOT" issues?
16:24hiredmanthis is alpha
16:24angermanhmm... maybe I shouldn't have just copied the project spec :(
16:25hiredmanI wouldn't worry about clojure
16:25hiredmanfind the bug in your code
16:25hiredmanis it possible that the code you pastebin'ed is not the exact code you running?
16:28ska2342Hi. The section on Maps on http://clojure.org/data_structures says that the sorted map has slower access than the hash-map, just "log(N)". Is it right to assume log_2(N) here?
16:29chouserska2342: I think that's right
16:29chouserprobably not log_e
16:29ska2342na, ln would be strange for trees :-)
16:29chousersorted maps and sets are currently persistent red-black trees
16:30ska2342ok, I'll look their access up. Thanks for the info!
16:31angermanhiredman: I could swear I did run exactly that code. though, restarting swank, and the slime session twice. now it works.
16:31angermano_O wtf?!
16:33lpetitDoes the -i option of clojure.main accept lib names (which it would then search from the classpath) or just resource names ? Can the resource names be relative to the classpath ?
16:33chouserska2342: I see left/right fields in Node classes in the code. I think it's safe to assume base 2
16:33lpetits/search/require/
16:34chouserlpetit: from the --help: Paths may be absolute or relative in the filesystem or relative to classpath. Classpath-relative paths have prefix of @ or @/
16:34ska2342learned something new in O(log(N)) according to Landau notation docs the base doesn't matter. Funny though, that we keep on writing log_32 in Clojure-documents
16:34hiredmanangerman: must have forgot to re-def something function after you changed something
16:34lpetitchouser: thanks
16:35chouserska2342: it's because it matters in real life
16:35chouserjust like constants do
16:35ska2342the reason for not caring about the base is that they differ only in a constant factor which doesn't grow. Obvious, but my university days are long gone
16:35lpetitchouser: oh yes, it was on the bottom of the help, I missed that, sorry
16:36chouserlpetit: np. it's a somewhat unusual use of @, easy to forget.
16:37ericthorsenFYI, with-bindings is defined both in clojure.core and clojure.main on the new branch
16:37lpetitchouser: I have a doubt, right now. If I use -i with @/some/ns.clj , will 'load use either the AOT compiled version either the .clj if fresher, or always the .clj ?
16:38lpetitericthorsen: thanks
16:38chouserlpetit: I don't know. I would hope use of ".clj" means it will always use the .clj file, but I don't know that for sure.
16:40lpetitchouser: well, I'm not sure it will be a problem for me, but I'm correcting a bug in ccw where I'd like to be close to the behaviour of requiring a ns. The closest is to use -i with @/ , but there may still be side effects I can't think of right now ...
16:40lpetitrequiring a ns at launch time
16:40clojurebota is b
16:41chouserlpetit: you're not willing to use -e "(require 'foo)" ?
16:41lpetitchouser: I want to let the end user be able to specify -e for its own options ; is it possible to have several -e in the command line ?
16:41chouserlpetit: I think so
16:42chouserit is
16:42lpetitchouser: great, so
16:43lpetitchouser: you're my hero
16:43chouserheh
16:43chouserthanks, glad to be of service. :-)
16:44chouserbuy my book: <insert link here>
16:44angerman~source repeatedly
16:46lpetitchouser: if that's not "kitch" :-) : http://www.ezilon.com/e-cards/index.php?step=makecard_step1&amp;ec_id=524&amp;lang=
16:46chouserha! juding by that image, I would say "yes"
16:49lpetit;)
16:50lpetitchouser: but finally, no, my user is able to select a predefined set of clojure files on the classpath to "launch" at startup, but those file do not necessarily have to be namespaces, so blindly using -e will not work 100% of the cases. I'll try with @/ for the moment ...
16:53technomancylpetit: I've been thinking about having a -m argument that would be the equivalent of specifying a "main" class on the java command-line, but would work whether or not you'd done AOT
16:53technomancyI guess that's a little different from what you're looking at
16:53technomancynm
16:55lpetittechnomancy: really, pointing to a "main" class in java is pointing to some static method, equivalent to a function somewhere in a namespace in clojure. Though in java the "loading" of the class is also done at the same time, due to the naming conventions
16:56angermannja.... RAF is slow
16:56jkoppelRunning clojure-update broke my working Clojure/SLIME/Aquamacs setup
16:57jkoppelNow I'm having trouble getting it working again :(
16:57lpetittechnomancy: so, the generalized equivalent, for clojure.main, could be to pass the fully qualified function name to -m, e.g. my.ns/toto (or why no my.ns/-main), with an implicit requirement for clojure.main to try to 'require my.ns first .. ?
16:57lpetittechnomancy: but yes, it's different from what I'm after :)
16:57technomancylpetit: that would be great.
16:58ska2342jkoppel: did you do a new checkout of Slime, maybe from CVS? Current Slime-HEAD does not work with current swank-clojure. We had a discussion in the group on this.
16:58technomancyunfortunately I've already got a workaround, so my incentive to implement it is reduced. =)
16:58lpetit:)
17:00jkoppelwhisper ska2342 Thanks, looking at the discussion
17:00jkoppelGah, IRC fail
17:08ska2342chouser: I tried to find a publishing date for your book. Is there any public information on this?
17:08chouserska2342: no, but there will be Real Soon Now. Haven't quite pinned down a title yet.
17:09ska2342chouser: I thought you were talking about "idiomatic clojure"?
17:09chouserska2342: that's been the working title, yes.
17:09shr3kst3rha, lein compile seems to have hung
17:10ska2342chouser: really looking forward to reading it
17:10chouserska2342: fantastic! I'm really looking forward to being done writing it. :-)
17:11ska2342chouser: how many pages down, how many to go?
17:11ska2342chouser: approx.
17:12chouserfogus_: how much of this are we talking about?
17:13chouserska2342: well, I expect it to fluctuate a bit. Let's put it this way: Manning likes to have about 1/3 of it done for the early online access (MEAP), and we're expecting that to happen in the next couple weeks.
17:14ska2342chouser: thanks. Didn't mean to be impolite
17:14chouserno, it's not at all impolite. Thank you very much for your interest!
17:15JorejiHey guys, is there some way to call a protected (final) supermethod from within a proxy?
17:15chouserI'm just not sure what I know (if anything) that's not meant to be shared.
17:15ska2342chouser: FULL ACK
17:15chouserJoreji: no good way. But, if you really need to, contrib java-utils wall-hack-method
17:18Jorejichouser: For some reason wall-hack-method does not find the method I am looking for. I think that is because the method I'd like to invoke gets "int" as its parameter, and I can only specify "Integer" as a parameter.
17:18angermanahh. now it's speedy
17:18JorejiIs there some way to get the type of a native int? (i.e. not the object type)
17:18ChousukeJoreji: Integer/TYPE represents int
17:19Jorejiah, thanks!
17:21supernovamaniaccan someone help me with a code problem that im having? (I just started clojure)
17:22lisppaste8dakorne pasted "is line-seq really that much slower than slurp?" at http://paste.lisp.org/display/91554
17:22Chousukesupernovamaniac: go ahead and ask.
17:23Chousukedakrone: add type hints for starters
17:23supernovamaniachttp://codepad.org/2iZyLOCS when i try (fun "5") or anything else for the string it gives me java.lang.ClassCastException: clojure.lang.PersistentHashSet cannot be casted to clojure.land.IDeref (NO_SOURCE_FILE:0) error
17:23hiredmandakrone: lazy seqs have overhead
17:23dakroneChousuke: okay, I'll turn on warn-on-reflection
17:24Chousukethough most likely you need it only for the "%"
17:24supernovamaniac(i also declared (def visitors #{}) before i defined fun
17:24hiredmansupernovamaniac: pick a simpler function to start with
17:24supernovamaniackk
17:24hiredman(and write it instead of copy and pasting it_
17:25_atosupernovamaniac: did you forget to make visitors a ref?
17:25ska2342supernovamaniac: should that read (def visitors (ref #{}))?
17:25angermanok, here we go: BufferedRandomAccessFile c.c.duck-streams extention http://gist.github.com/248603, required BufferedRandomAccessFile.java http://gist.github.com/248605
17:27supernovamaniac_I did write it
17:28hiredmanangerman: I don't believe that whatever you say was required was required
17:29angermanhiredman: hmm. well. it does work without the BufferdRandomAccessFile, but using the bare RAF is very slow
17:29_atoSNM|Away: you absolutely sure you did (def visitors (ref #{})) not (def visitors #{})? cause that error is saying you're passing a hashmap to @ instead of a ref.
17:30angermanhere's a sample of how I intended to use it http://gist.github.com/248618
17:30hiredmanangerman: why would it be faster?
17:31hiredmanhorrible
17:31hiredmanfunction calls with no arguments
17:31hiredmanatoms everywhere
17:31gbt_b
17:31hiredmanstate state state
17:31hiredman:(
17:31angermanhiredman: because when reading line-wise, the RAF calls read over and over again which hit's the filesystem, and that's slow.
17:31angermanhiredman: I'm very open to any suggestions
17:33hiredmanhonestly I haven't been paying that close attention, so I don't have specific suggestions
17:33twbrayHmm... wondering if anyone here has looked at -Xprof output.
17:33twbray 49.5% 3 + 101 org.tbray.read_lines$proc_block__24.invoke
17:33hiredmanthe one off use of atoms is icky
17:34hiredmanthe reliance on some code from a blog post somewhere is icky
17:34twbrayI have a function org.tbray.read-lines/proc-block
17:34SNM|Away...dope
17:34twbrayLooks to me like it's saying 49% of the time was in that function.
17:35angermanhiredman: well, I did read the code of the BRAF. And I have no clear idea how to keep track of the current line no.
17:35angermanthough I have to admit, I don't really need the line-no right now. So the atom and swaps could just go away.
17:36hiredmanangerman: if you must use the atom, at least lose the bindings
17:36hiredman(binding is also ick)
17:36angermani tried hard to get it to work with what c.c.d-s was providing
17:37hiredmanmacros that shadow are ick
17:37angermanbut ran into a OutOfMemory wall fast
17:37hiredmanetc, etc
17:37hiredmannever used duck-streams except when looking at problems other people had using
17:37hiredmanit
17:38angermanhiredman: as I said earlier. I'd love to get suggestions how to turn this into a very nicely fitting clojure code. But I'm unexperienced at best, if not totally lacking any ability to improve on that alot.
17:39hiredmanI would at least follow the example of with-open and use a binding vector instead of just binding to *file*
17:39angerman~source with-open
17:39hiredman(with-random-access-reader [file "/Users/angerman/upps.data.model"] ...)
17:39j3ff86is there a "replace value at index i with value x" function?
17:39hiredman(next-line file)
17:40hiredman,(assoc [1 2 3 4] 0 :a)
17:40clojurebot[:a 2 3 4]
17:40j3ff86ah cool, thanks
17:40hiredmanthe implicit parameter passing via binding is very annoying when you try to compose code
17:40angermanhiredman: yes, that looks better. I'll try to turn it tune it that way
17:41angermanif i drop the not (really) required line-no, it would become binding less
17:41angermanthough I'm not sure how I'd loose the shadowing in the save-recursion
17:42angermanerr save-excursion
17:43angermanhiredman: thanks for the input. Very much appreciated
17:44Qvintvsis there a simple way to convert a string "like this" to a list of symbols '(like this) ?
17:44chouser,(map symbol (.split #"\s+" "like this"))
17:44clojurebot(like this)
17:45hiredman,(import 'java.io.ByteArrayInputStream)
17:45clojurebotjava.io.ByteArrayInputStream
17:46hiredman,(import 'java.io.InputStreamReader)
17:46hiredmanclojurebot: well?
17:46clojurebotjava.io.InputStreamReader
17:46clojurebotNo entiendo
17:46j3ff86haha
17:46hiredman,(doc read)
17:46clojurebot"([] [stream] [stream eof-error? eof-value] [stream eof-error? eof-value recursive?]); Reads the next object from stream, which must be an instance of java.io.PushbackReader or some derivee. stream defaults to the current value of *in* ."
17:46chouserhuh. we have cycle but not rotate?
17:47hiredman,(import 'java.io PushbackReader BufferedReader)
17:47clojurebotjava.lang.ClassNotFoundException: java.io
17:47hiredman,(import '(java.io PushbackReader BufferedReader))
17:47clojurebotjava.io.BufferedReader
17:48hiredman,(letfn [(io [string] (-> string .getBytes ByteArrayInputStream. InputStreamReader. BufferedReader. PushbackReader.))] (io "foo"))
17:48clojurebot#<PushbackReader java.io.PushbackReader@1e2b2a6>
17:48chouserhm. rotate's a bit messy.
17:49hiredman,(letfn [(io [string] (-> string .getBytes ByteArrayInputStream. InputStreamReader. BufferedReader. PushbackReader.))] (let [x (io "like this")] (take-while identtity (repeatedly #(read x)))))
17:49clojurebotjava.lang.Exception: Unable to resolve symbol: identtity in this context
17:49hiredman,(letfn [(io [string] (-> string .getBytes ByteArrayInputStream. InputStreamReader. BufferedReader. PushbackReader.))] (let [x (io "like this")] (take-while identity (repeatedly #(read x)))))
17:49clojurebotjava.lang.RuntimeException: java.lang.Exception: EOF while reading
17:49hiredmanbah
17:49chouser(defn rotate [[x & xs :as all]] (when (seq all) (concat xs [x])))
17:50hiredman:(
17:51hiredmanI guess
17:52chouseryeah, it's not exactly beautiful
17:53chouserneither seqs nor vectors like to do what 'rotate' tries to do.
17:58duncanmsigh
17:59duncanmtechnomancy: i keep on having trouble with the slime installed from ELPA
19:23defn(areduce (into-array [1 2 3]) k 0 +)
19:24defnobviously this is wrong... how do I use areduce?
19:24chouser(doc areduce)
19:24clojurebot"([a idx ret init expr]); Reduces an expression across an array a, using an index named idx, and return value named ret, initialized to init, setting ret to the evaluation of expr at each step, returning ret."
19:25defni dont understand the index,init,return
19:26defnwhy do we need an index or a return value
19:26defnand what does it mean initialized to init
19:31twbrayGrrr: java.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn
19:31ohpauleeztwbray: wrap it in an anon function
19:31hiredmanthe exception is correct
19:32twbrayhiredman: For some definition of "correct"
19:32hiredmanwell a Boolean cannot be cast to an IFn
19:33hiredmansuch clarity is enviable
19:33ohpauleezright, and if you need to eval it like a function, you can return an anon/lambda function
19:33defn,(doc array-map)
19:33clojurebot"([] [& keyvals]); Constructs an array-map."
19:33twbrayhiredman: Not obvious why such a cast is unreasonable
19:34Chousuketwbray: Those are annoying :/
19:34Chousukeit basically just tells you you have a type error. :P
19:34twbraypreferred idiom from getting a java.lang.Boolean into something I can feed into an (if?
19:35hiredmanif takes Booleans
19:35Chousukeyou might have extra parens somewhere.
19:36hiredmanalthough
19:36hiredman,(if (Boolean. "false") :a :b)
19:36clojurebot:a
19:36ohpauleezclojure.lang.IFn is for if's? Not Function Interfaces?
19:36hiredmanohpauleez: no
19:36Chousuke,(boolean (Boolean. "false"))
19:36clojurebotfalse
19:36Chousukemmh.
19:37twbray,(let [ trailing-nl (. "foo" endsWith "o") x (if trailing-nl "yes" "no") ] (println x))
19:37clojurebotyes
19:38hiredman,(println (if (.endsWidth "foo" "o") "yes" "no"))
19:38clojurebotjava.lang.IllegalArgumentException: No matching method found: endsWidth for class java.lang.String
19:38hiredman,(println (if (.endsWith "foo" "o") "yes" "no"))
19:38clojurebotyes
19:39Chousukeare you sure you haven't wrapped the predicate in extra parens?
19:40hiredman,((true))
19:40clojurebotjava.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn
19:41Chousukeit's probably pretty easy to write (if(somebool) ....) and then be completely blind to it if you're used to C-ish syntax.
19:42itistodayreading the monad tutorial for clojure: http://onclojure.com/2009/03/05/a-monad-tutorial-for-clojure-programmers-part-1/
19:42hiredmanpossible an unquoted list
19:42hiredman,(true 1 2 3)
19:42clojurebotjava.lang.ClassCastException: java.lang.Boolean cannot be cast to clojure.lang.IFn
19:42itistodayin my repl m-bind seems to do something else
19:42itistodayin the tutorial it's defined as: (defn m-bind [value function] (function value))
19:43itistodayhas its definition changed?
19:43hiredmanare you sure?
19:43Chousukem-bind is a bit special.
19:43hiredmanpossibly
19:43hiredman~def m-bind
19:43clojurebotIt's greek to me.
19:43itistodayuser=> (m-bind 1 (fn [a] (+ a 1)))
19:43itistoday#<user$eval__75$fn__77 user$eval__75$fn__77@508aeb74>
19:43itistoday,(m-bind 1 (fn [a] (+ a 1)))
19:43clojurebotjava.lang.Exception: Unable to resolve symbol: m-bind in this context
19:43hiredmanclojurebot doesn't seem to thing it exists
19:44itistoday,(use 'clojure.contrib.monads)
19:44clojurebotnil
19:44hiredmanthink
19:44itistoday,(m-bind 1 (fn [a] (+ a 1)))
19:44clojurebot#<sandbox$eval__4712$fn__4714 sandbox$eval__4712$fn__4714@1984acb>
19:44hiredmangrrr
19:44itistodaysee?
19:44itistodayin the tutorial it should return 2
19:44hiredmanI wonder my m-bind was left out of the docstring gerneration
19:44Chousuke~def m-bind
19:44clojurebotI don't understand.
19:44Chousukehm
19:44hiredman,((m-bind 1 (fn [a] (+ a 1))))
19:44clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: sandbox$eval--4718$fn
19:45Chousuke~def defmonadfn
19:45Chousukesymbol macro stuff :/
19:46hiredman~macros
19:46clojurebotHoly Crap.
19:46ChousukeI suppose that m-bind is specific to the identity monad.
19:46itistodayso... how can i learn monads now?
19:46itistodaytutorial seems out of date :-p
19:47Chousukecontinue with the tutorial for now.
19:47ChousukeI think that m-bind definition is just a simplified example
19:48itistodayChousuke: the tutorial makes it seem like m-bind is "fundamental"
19:48itistodayif i don't know what it's doing i can't follow the tutorial
19:48Chousukeit is, but each monad has its own definition of m-bind
19:48Chousuke(function value) is what it is for the identity monad
19:48Chousukesome other monad will have a different definition
19:50itistoday,(identity-m 1 (fn [a] (+ a 1)))
19:50clojurebot#<sandbox$eval__4724$fn__4726 sandbox$eval__4724$fn__4726@1e513fb>
19:50Chousukeyou probably need some function to extract the value from the monad. :)
19:51itistodayChousuke: yeah... trying to figure out what that is...
19:51Chousukeas far as I understand monads, m-bind defines the "composition operation" for whatever class of operations the monad represents
19:51Chousukefor functions, it's just comp
19:51Chousukefor some other monad, it's... something else :P
19:51itistodayare monads used a lot in clojure?
19:52ChousukeWell, I wrote some monadic code once for fun
19:52Chousukebut not really.
19:52itistodayi've been reading about them for about an hour now
19:52itistodaystill have close to zero clue how they work
19:53Chousuke,((identity-m 1 (fn [a] (+ a 1)) identity)
19:53clojurebotEOF while reading
19:53Chousuke,((identity-m 1 (fn [a] (+ a 1))) identity)
19:53clojurebotjava.lang.ClassCastException: clojure.core$identity__4959 cannot be cast to java.lang.Number
19:53Chousukehmm
19:53Chousuke,((identity-m 1 (fn [a] (+ a 1))) 3)
19:53clojurebot4
19:53Chousukecurious. what's the value doing.
19:53Chousuke(doc identity-m)
19:53clojurebot"; Monad describing plain computations. This monad does in fact nothing at all. It is useful for testing, for combination with monad transformers, and for code that is parameterized with a monad."
19:54itistodayis there an updated guide on clojure monads somewhere?
19:55itistodayi like how the source in the namespace declaration links to the post i'm reading currently... yet it's outdated :-\
19:55itistodaymaybe i'll send this guy an email
19:55Chousukethere's another definition of m-bind at the bottom of the page.
19:55ChousukeI don't see how that's outdated.
19:56itistodayChousuke: what are you referring to?
19:56Chousukeitistoday: the m-bind for the maybe monad.
19:57Chousukehttp://intensivesystems.net/tutorials/monads_101.html maybe take a look at this instead? :P
19:58itistodayChousuke: thanks, i just noticed that in the comments too
19:58itistodayi'll try to figure out based on this and the code you linked to
19:58itistodayChousuke: thanks!
19:58itistodayi've gotta run
19:58ChousukeI should re-read those things too
19:58itistoday:-)
19:59ChousukeI think I know the why and what of monads but I am not yet enlightened. /:
20:06twbray,(let [ trailing-nl (. "foo" endsWith "o") x (if trailing-nl "" "no") ] (println x))
20:06clojurebot
20:07twbray,(let [ trailing-nl (. "foo" endsWith "o") x (if trailing-nl "" (last ["foo", "bar"])) ] (println x))
20:07clojurebot
20:09timothypratley,(.endsWith "foo" "o")
20:09clojurebottrue
20:13qedre-matches and re-find returns ["original string" "match"]
20:13qedhow do i just have it return match?
20:14Chousukeyou can use java methods or just drop the first element from the vector :)
20:14ohpauleezor filter
20:14qedfilter #(rest %)
20:14qedsure, i just thought there might be a better way
20:18timothypratleyqed: http://groups.google.com/group/clojure/msg/7578ed1f513df2b8 <-- this is my take
20:19qedthanks tm
20:19qedtim
20:27qedI have a list of strings, to concat them all I?
20:27qednevermind
20:27ohpauleezstr
20:35twbrayHah... that exception on Boolean was in fact a stinky Clojure 1.0 bug, perfectly reproducible. WIll report. Had this huge vector, 50k long or more, and (last huge-vector) went nuts.
20:35twbray(get (dec (count huge-vector)) huge-vector) works fine.
20:36qed(reduce str (flatten (map #(rest %) (map #(re-find #".*\s+.*\s+(.*)\Z" %) (re-split #"\n" input-string))))))
20:36qedthere has got to be a better way to do that
20:36Chousuke#(rest %) == rest
20:37qedeven across a list of lists Chousuke ?
20:37Chousukeacross anything.
20:37Chousuke#(rest %) is just a function that calls rest with its argument.
20:38qed(("a" "b") ("c" "d"))
20:38qedso you'd just (map rest ...)?
20:38Chousukeyeah
20:38qedah ok, thanks
20:38Chousukein general, #(foo %) can be reduced to foo, if foo is a function
20:39qedoh right, because it's only when we're doing something like #(foo 1 %) that it matters
20:39qedwhere we have additional arguments, yes?
20:39Chousukeit's not like it changes anything though. it just removes noise
20:39Chousukeyeah
20:39qednod
20:39Chousukeit's an easy mistake to make, though.
20:40qedyeah seems like kind of a bad habit more than anything
20:40qedpoor style i guess
20:40Chousukeyeah.
20:40qedhere's one more regex question: \W is a non-word char right?
20:40notallama(partial foo 1) also works for that. whichever syntax you prefer.
20:40Chousukeit's so often that you need a #(foo whatever) in a map and a filter so your fingers learn to type #() :P
20:40Chousukes/and/or
20:41qedfor some reason #"0x(.*)\W" is matching past % and ('s
20:41qedChousuke: yeah that makes sense
20:41chouserqed: maybe (map second ...)
20:42notallama(.*) is greedy, isn't it?
20:42chouserqed: . will match % and (, so on it goes
20:42chousernotallama: right. * is greedy
20:43chousermaybe #"0x(\w*)" or #"0x(.*?)\W"
20:43qedthanks chouser
20:43chousernp
20:45timothypratleyqed: how come you split them by line then flatten them again later? am I missing something important this does?
20:45qedjust sloppiness, i'll likely switch that \Z to a \n
20:45qedand get rid of the split
20:46timothypratleyoh :) also I think reduce str would have poor performance compared to just apply str?
20:46timothypratley[just a guess though]
20:47timothypratleybecause it would construct a whole lot of intermediate strings
20:47clojurebota is t
20:48timothypratleyI'm probably wrong about that though as I'm sure apply would have to do similar work
20:48timothypratleyforget I spoke!
20:57ohpauleezre: reduce vs apply, I think apply is usually faster. There's a blog post or tutorial somewhere
20:59Chousuketimothypratley: no, you're correct. If you use apply, then str will only need one StringBuilder for the whole seq
20:59ohpauleezthere we go
21:00timothypratleyoh, great! :)
21:55polypus,'just-testing
21:55clojurebotjust-testing
22:08interferongiven a sequence of key names (e.g. ["a" "b") and a seq of [[1 2] [3 4]]), is there a built-in that will give me [ {"a" 1, "b" 2}, {"a" 3, "b" 4} ] ?
22:13chouser,(let [keys ["a" "b"], val-vecs [[1 2] [3 4]]] (map #(into {} (map vector keys %)) val-vecs))
22:13clojurebot({"a" 1, "b" 2} {"a" 3, "b" 4})
22:30_ato,(map #(zipmap ["a" "b"] %) [[1 2] [3 4]])
22:30clojurebot({"b" 2, "a" 1} {"b" 4, "a" 3})
22:33interferonthanks!
22:36chouser_ato: nice!
22:40_atozipmap doesn't get enough love :)
22:43defnI need to find a good way to do this clojure example documentation -- a wiki + comments is what I'm going for here, but it's looking more and more like I'm going to need to build the whole thing from scratch
22:44chouserdefn: on top of google wave, right?
22:44chouser:-)
22:44defnhaha, nah
22:44defni just have this vision and im looking for stuff that's already been built, but there's not really anything out there
22:45_atodefn: what does it need to do that a regular wiki doesn't?
22:45defni think mainly im just trying to get away from all the bells and whistles
22:46defni want it to behave more like an editable blog post
22:46defnmaybe im getting too hung up on the details
22:46chousersounds like ... google wave
22:46defni just have this picture in my head
22:46defnchouser: touché
22:46hiredmanideally you'd like to break the editable parts up per function instead of per page
22:46defncorrect
22:46chouserI don't think one function per page would be too few
22:47hiredmanyou have a block with the docstring text, and when you click on the block, it turns into a textarea
22:48_atodon't most wikis do some sort of subpage editing? eg you can edit just part of an article in wikipedia
22:49defnyeah i guess i just feel like giving this more of a face, something that looks more like an API documentation site and not a wiki, is my main goal
22:50defni want to go to the site and navigate it like it's a static site for the most part, with only tiny hints of the wiki poking out
22:50defnthe wikis out there right now tend to be so filled up with sidebars and sub-sidebars and sub-sub-sidebars, and 1400 links per article -- it's just noise
22:52_atokeep it simple to start with
22:52_atoyou can add bells and whistles later
22:52clojurebotYou will not become skynet
22:52defnhaha
22:52_atootherwise you'll never get it done
22:53defn_ato: yeah, i think my main concern here is not the functionality and such, it's just building something that works properly, and a wiki is not what it is, IMO
22:53defnerr by functionality i mean bells and whistles
22:54_atooh well, best not to listen to me anyway. I still like the idea of git repository with text files and a script to spit out HTML. But I'm weird like that. :-P
22:54_mstsounds like my website :)
22:55defn_ato: i think you're right actually
22:55defnthat's the way im gonna go
22:56tomojunconventional uses of git make me happy
22:57ohpauleeznice work guys
22:57interferonhow can i get the contents of a URL?
22:58interferonhttp-agent?
22:58interferonthe examples in its docs don't work....there's no symbol called string in the http-agent namespac e
22:58tomojif it's really just a URL you want, duck-streams will work I think
22:59tomoje.g. (slurp* "http://www.google.com/&quot;)
22:59defnquite handy
23:00tomojif you want to do more http stuff there's also clojure-http-client
23:01defnhttp://github.com/defn/clojure-examples
23:01interferontomoj: wow, thanks
23:01interferonslurp* is perfect
23:02tomojdefn: are you going to write the code involved in clojure? or use some other static-html-generated-from-git kinda thing?
23:02defnhtml-gen'd-from-git
23:03defnjust make blocks delimited by some special operator get pygmentized
23:03defnand handle the rest as textile or something
23:04tomojgotta have some kind of basic layout thing too right?
23:04defnyeah, definitely
23:04interferonis there a clojure analogue to activerecord?
23:05tomojI wonder how jekyll is coming along lately
23:05defnnot too good IMO
23:05defnI'm not a fan of jekyll
23:06defnbut maybe i should give it a second chance
23:06tomojI always loved the idea but never liked the implementation
23:06defnsame here
23:06tomojalways felt like a huge pain in the ass
23:06defnglad im not the only one
23:06defni kind of felt like "am i stupid or something?"
23:06defnnone of the "edges" are clean
23:07defni dont know where one part of jekyll ends, and the next begins
23:08defnit'd be sort of cool to make the clojure-examples my user page, and just use jekyll
23:08defnbut like you said, sort of a pain
23:09tomojhmm.. writing a replacement for jekyll in clojure sounds like fun
23:18tomojI wonder if it's worth it to use pygments in clojure through jython
23:22technomancydefn: srsly; you can do static HTML generation in like a hundred lines of code; never saw the use for a generalized tool like that where everyone pitches in to add their pet feature
23:32alexykanybody tried incanter here? I'm drooling over it, reading the site.
23:33alexykR in Clojure, now that's ambition.
23:33ohpauleezalexyk: just started looking at it today
23:33alexykapparently it got some machine learning today
23:34alexykwith Scala Processing, these two look good now for some serious stuff
23:34alexykand clojuratica of course
23:35tomojalexyk: I don't see the commits
23:36tomojthe machine learning ones I mean
23:36alexyktomoj: it says FlightCaster merged its ML code into it on incanter-blog
23:36alexykor agreed to :)
23:36tomojoh I see
23:37alexyktomoj: are you playing with incanter?
23:38tomojnope, but I am interested in machine learning
23:38alexyktomoj: me too
23:39tomojdang, why didn't I take a look at incanter before
23:39tomojI was trying all this matrix crap with ugly java libraries
23:41alexyktomoj: clojuratica feeds of fantastic Mathematica matrix routines :)
23:42tomojhaving mathematica embedded in my couchdb view server sounds awesome
23:42ohpauleezcool thing about incanter is that it wraps all of parallel colt, so you get all the math/algebra stuff too
23:42ohpauleeznot just the stat stuff
23:44interferonshouldn't (use '[clojure.contrib.str-utils2 :only (split trim) :rename {:replace :string-replace}]) give me a function named string-replace?
23:45ohpauleezinterferon: is this on the repl or in a .clj file?
23:45interferonthat's on the repl but ultimately i want it to work in a clj file. and it doesnt work there either :)
23:46ohpauleezhttp://richhickey.github.com/clojure-contrib/str-utils2-api.html
23:48ohpauleezdoes it also fail in the file when you use require?
23:48tomoj(use '[clojure.contrib.str-utils2 :only (split trim replace) :rename {replace string-replace}])
23:49tomoj(two things: add replace to the :only list, and use symbols in the :rename map)
23:52interferonah i see
23:52interferoni had this kludge: (def string-replace clojure.contrib.str-utils2/replace)
23:53interferonbut adding it to :only is much cleaner
23:53interferonthanks
23:53interferonalso, can i share a clojure moment?
23:53interferoni was building a cache to prevent pulling data from a web service after it had already been filled
23:53interferonusing refs, dosync, etc
23:53interferonthen i realized memoize is built in
23:53interferonbrilliant!
23:56_atoalthough the problem with memoize is you can't clear the cache, but yeah it's great for simple cases