#clojure logs

2010-02-05

00:33hiredmanuser=> (expression-info '(jop / (float 4) (float 1.1)))
00:33hiredman{:class float, :primitive? true}
00:33hiredman:D
00:35chouserhuh!
00:35chouserdoes it work for any java operator?
00:40hiredmanchouser: no
00:40hiredmanstill a work in progress, the operands need to be of the same type
00:41hiredmanI don't imagine that will change, the dispatch would be taken care over via a protocol like c.l.Numbers
00:41hiredmanof
00:42hiredmanwhich at the bottom level would call jop something
00:45hiredmanat least those are my thoughts, who knows what rhickey is up to :P
00:45chouser:-)
00:51hiredmangah, suddenly none of the three web browsers I have installed are working and I am without reference to javadocs
00:51chouserjavadoc from repl-utils might still work via swing
00:54qedsomeone comfort me
00:55hiredmancontrib has been altered, pray that stuart does not alter it further
00:55qedheh -- im actually fond of his changes, just not so fond of changing all of my code
01:22qed/go clojurebot
02:10LauJensenMorning team
02:26tomojis there any alias for the current ns inside the ns declaration?
02:27tomojas in, to avoid the duplication in (ns foo.bar.baz.bang (:require [foo.bar.baz.bang [biz bing bong]]))
02:27tomojguess it's not that bad
02:28tomojreally for me it becomes (ns foo.bar.baz.bang (:require [foo.bar.baz.bang [[biz :as biz] [bing :as bing] [bong :as bong]]]))
02:28tomojwhich is ugly but not too much work to type, I guess
02:33vu3rddIs there a way to get source code thru lein? (like apt-get source)
02:34vu3rddhmm.. ignore my question. I misunderstood lein.
02:59LauJensenlein just gets jars, but if those jars contain the source, you can get it at from Emacs, M-x ; I think
02:59LauJensens/it at/at it
03:08hiredmanhttp://gist.github.com/295631
03:08hiredmanway too excited about this I think
03:13tomojhiredman: what exactly is it you're excited about?
03:13tomojI don't understand the gist :(
03:14hiredmanif you look at the last method in the output of javap, that is what is the body of the fn function
03:14tomojok
03:15hiredmanand the jop compiles directly to a call to fadd instead of clojure.lang.Numbers/add
03:15tomojI think whatever you're doing is simply beyond me :)
03:15tomojoh, hmm
03:15hiredmanfadd takes two floats off the stack and pushs the result of adding them onto the stack
03:15tomojso, are you compiling certain pieces of clojure directly to fast jvm bytecode?
03:16hiredmanI don't know, it is possible, but speed is not my object
03:16tomojwhat _is_ your object?
03:16hiredmanthat is part of what is exciting, I have a beachhead in the compiler
03:18hiredmanif the operations in Numbers are replaced with a protocol, they will need math ops that don't compile to method calls
03:21LauJensenWow
03:22LauJensenhiredman: The term beachead is new to me, can you explain that without tipping over your bikeshed-o-meter? :)
03:23hiredmanhttp://en.wikipedia.org/wiki/Beachhead
03:24LauJensenOk
03:24unfo-hiredman is going to peacefully invade the compiler and cause upheave its internal structures?-)
03:26hiredmanunfo-: in an alternate universe (my personal clojure repo)
03:26unfo-:-)
03:38nathanmarzi'm having a weird issue where "lein compile" works but spits out a ton of "ZipException"'s - does anyone else see this?
03:39hiredmanweird
03:40hiredmanmaybe some of the jars you depend on are damaged?
04:11nathanmarzmy program still runs though... i guess i'll try unjarring and rejarring manually
04:33avarushi
04:36AWizzArdhey avarus
04:37esjmorning all
04:38avarushow are you guys?
04:38AWizzArdtired
04:39esjditto that
04:39esjFriday is always brutal
04:39avarushehe
04:46avarusbrb :)
05:23AWizzArdBald ist Wochenende :)
05:25krumholt_yes!
07:14vu3rddLauJensen: good afternoon
07:14LauJensenHey :)
07:15vu3rddgoing thru the cloneit code
07:16vu3rddwhat does the line 19 do? http://github.com/LauJensen/cloneit/blob/master/src/cloneit.clj
07:16vu3rddI am still confused with java.. printTo is a method of who?
07:19LauJensenhttp://joda-time.sourceforge.net/api-release/org/joda/time/format/PeriodFormatter.html
07:23vu3rddOk, so toPrinter gives a PeriodPrinter and then we use the printTo to print it?
07:25vu3rddI should re-read chapter 3 of programming clojure.
07:26AWizzArdMoin Lau
07:36zaphyris there something like a destructuring let*?
07:43LauJensenvu3rdd: I think thats right
07:45LauJensenMoin AWizzArd
07:46RaynesLauJensen: Did you see that C# version of the newsgroup scraper in the comments on your Clojure vs Scala & Ruby thread?
07:47RaynesGuy said it completed in like, 10 seconds. Shocked me.
07:49LauJensenRaynes: Yea I dialoged with the author - I haven't benchmarked it yet, but his system is quite a bit faster than mine. I've promised him that once I get some time to set up Mono I'll take it out for a spin
07:52vu3rddLauJensen: Thanks
07:52vu3rddLauJensen: you should write a book on clojure
07:57AWizzArdMoin ulfster, alles klar?
07:57ulfsterMoin
07:59sparievis that #clojure.de :) ?
08:00AWizzArdspariev: nah, just a german greeting. And the clojurebot also knows "alles klar" *g*
08:00ulfsterfunny thing is, i am german ;)
08:00AWizzArdThat was the intention.
08:01vegaiwhere's this thread?
08:02esji like alles klar
08:02sparievI only know "aller klar" and "Ich moechte essen" in german :)
08:02esjalthough I'm not German
08:04AWizzArdThough the bestest language of them all is Clojure.
08:08RaynesI speak redneck, or at least LauJensen certainly thinks I do. :>
08:20jcromartieClojure.org says "for a better experience, try running it via the JLine ConsoleRunner"
08:21jcromartiebut I found JLine to be incredibly frustrating and incomplete compared to rlwrap, which is available for cygwin, macports, and any linux distro
08:21jcromartieIt should get a mention. I feel like it's a hidden gem and most people don't know about it.
08:22unfo-LauJensen, clojure vs scala & ruby - where? -)
08:23chouserjcromartie: I use rlwrap too, but am under the impression most people use emacs slime and spend half their time trying to get that to work instead of learning Clojure. *shrug*
08:23Raynesunfo-: http://www.bestinclass.dk/index.php/2009/12/clojure-vs-ruby-scala-transient-newsgroups
08:23unfo-ty
08:23unfo-since those are the three languages i am currently interested in
08:24RaynesIt's not a real comparsion.
08:24RaynesI mean, not in the way you might think it is.
08:25unfo-from a brief glance it's pretty much what i wanted :)
08:34ohpauleezhaha chouser, are you still a vimclojure user
08:34AWizzArdohpauleez: why not?
08:34jcromartiemy main case against Ruby: "or" exists
08:34jcromartiehttp://gist.github.com/295413
08:34cemerickchouser: that can be easily parameterized to "I use % too, but am under the impression that most people use emacs %2 and spend half their time trying to get that to work instead of learning %3. *shrug*"
08:35ohpauleezno no no, I'm a vimclojure user
08:35ohpauleezI love it
08:35chouseryeah, well, really just vim. I still don't do the live repl integration stuff.
08:35wlr(> help-request-per-vim-user help-request-per-emacs-user) -> true
08:35chousercemerick: you're right. I don't know why I'm feeling snarky this morning.
08:35ohpauleezI rarely use the live repl, but I do like the doc lookup and omnicompletion
08:35AWizzArdI don't use vim, but if it works well for some people it's perfectly fine I think.
08:35jcromartieyeah I gave up on swank for my current project because I can't be bothered to sort out the current working directory issue
08:35ohpauleeztotally AWizzArd, I completely agree
08:35cemerickchouser: s'ok. Emacs brings that out in people.
08:36ohpauleezit's the first lisp I felt like I COULD pick an editor
08:36cemerickSlime is a compounding factor.
08:36jcromartieI should be loading resources from the classpath or env vars or something
08:36ohpauleezusually you're pushed into emacs
08:36chouserActually, I think it's the emacs advocates that bring it out in me. Emacs itself bothers me rather less.
08:36chousers/the emacs/some emacs/
08:36RaynesI tried to use Vim. Didn't work out for me.
08:37chouserI ought to spend a chunk of time improving my clojure environment. But investing in either single-threaded editor with ancient scripting language seems a poor use of time.
08:37rhickeyemacs + clojure-mode + paredit seems much simpler than Slime
08:38cemerickvim's no walk in the park, IMO either, but the issue is dismissive evangelism rather than...just about anything else.
08:38jcromartie_fogus_: right on
08:38jcromartiebash + rlwrap + clojure for my repl
08:38RaynesI don't know how I would code without an integrated REPL.
08:38tcrayfordalso my refactoring tool depends on slime
08:39rhickeydoes slime do Java completion?
08:39tcrayfordyep
08:39_fogus_I have to spend a few moments to get rlwrap working... jline seems to go into limbo too often
08:39jcromartie_fogus_: there's nothing to get working :)
08:39jcromartieinstall and rlwrap-away
08:40jcromartieso what's the deal with working directories and swank-clojure-project
08:40_fogus_Even better
08:40tcrayfordjcronmartie, you might have to use ,cd inside slime to switch your working dir to be correct
08:40vu3rddtcrayford: Is there anything to be done to get java completions in slime?
08:41tcrayfordjust c-c tab inside slime and it'll complete it
08:41tcrayfordif you want autocomplete, go look at company-mode (its on elpa) and slime-company.el (on the emacs wiki)
08:41jcromartietcrayford: would I start slime, cd, and *then* start swank-clojure-project then?
08:42RaynesWhen I do swank-clojure-project, it asks me which directory I want to be root.
08:42RaynesAfter that, everything is perfect.
08:42jcromartieyay!
08:43vu3rddtcrayford: thanks. will look into it. I can't get C-c TAB to work in my slime..
08:44tcrayfordvu3rdd: m-x slime-complete-symbol
08:44tcrayfordvu3rdd: bind that to something if you have something conflicting with C-c TAB
08:45vu3rddtcrayford: it tries to find it, but says can't find completion for so and so.
08:45tcrayfordwhat are you trying to complete?
08:46vu3rddSay, (StringBuffer.)
08:47tcrayfordinsert (StringBuf and tab it
08:47tcrayfordit works fine here
08:48vu3rddtcrayford: still same issue.
08:48vu3rddI don't have the company mode installed though..
09:00chouserBleh. http://www.kroah.com/log/linux/android-kernel-problems.html
09:02jcromartieAndroid is dead to me.
09:02chouserI guess it's still less closed and more Clojure-friendly than iPhone, but ... bleh.
09:02jcromartieonly slightly
09:02jcromartieI still haven't seen clojure running well on Dalvik
09:03jcromartiea jailbroken iPhone runs Java better
09:03chouserhuh
09:03Chousukegoogle is being really foolish with android :
09:03Chousukeit might work for them now but they're just wasting resources in the long run :(
09:04zaphyrgiant globalised tech company wasting resources? unheard of! :)
09:04jcromartieandroid is just another marketing idea
09:04jcromartietrying to get the Google name in more places
09:05jcromartietechwise, eh... take it or leave it
09:05chouserzaphyr: :-)
09:05jcromartieunless I want to build a mobile OS I don't care about the code for a mobile OS
09:05jcromartieso open source it or not, it doesn't matter to me
09:05jcromartieit's not like you can really contribute
09:06ltyphairi got a free droid last night at ADL2010 in Austin. Planning on trying to get clojure running on it.
09:06jcromartieltyphair: was ADL good?
09:07ltyphairthe droid was nice. no power, my laptop ran out of juice by the time the code session started
09:08ltyphairso if you are going don't turn on your laptop till the end.
09:08jcromartiek
09:08jcromartieI might go in DC
09:08ltyphairjcromartie: i would go. just for the chance of a real device to dev on.
09:09ltyphairjcromartie: and they will probably have all the wrinkles out.
09:09jcromartieyeah
09:13rysYou get the java runtime on Android?
09:14jcromartierys: no, just a custom VM
09:14jcromartieyou compile Java bytecode to Dalvik (the VM) bytecode before loading it on the device
09:14jcromartieso you can compile *compiled* Clojure code to Dalvik bytecode
09:15jcromartiebut you can't compile on the device since Clojure produces Java bytecode and those libraries don't work on Dalvik
09:15jcromartiethat's my understanding of it
09:16jcromartiewhere's cinc when you need it :)
09:20ltyphairthere is an android scripting environment but does not do clojure http://code.google.com/p/android-scripting/
09:20sparievI'm trying to translate from java the following code TermAttribute term = (TermAttribute) stream.addAttribute(TermAttribute.class)
09:21sparievif I write (.addAttribute stream (class TermAttribute)) compiler complains addAttribute() only accepts an interface that extends Attribute, but java.lang.Class does not fulfil this contract.
09:22sparievso, how can I do TermArtribute.class in clojure ?
09:22jcromartie(.class TermAttribute)
09:22chouserJust TermArtribute actually
09:23jcromartieah
09:24sparievchouser: thanks, that works
09:28ohpauleezI think this weekend I'm going to wrap the jdb stuff up for clojure, so I can use a clojure repl as my jdb interface
09:30AWizzArdchouser: btw, about yesterday: lock, deref atom, put the derefd value into a w-l-v... one other idea about agents which can do the locking and derefing implicitly:
09:30AWizzArdthe challenge with them was that the caller thread can't know if there was an exception, because of a constraint.
09:31AWizzArdBut one possibility is that my transaction macro uses a promise as an argument which the agent will then deliver. This way a thread can block as long the agent is working on its query, and then also detect if there was an Exception or not.
09:34chouserohpauleez: I didn't know you were working on anything like that. sounds *fantastic*
09:35tegood morning
09:35chouserAWizzArd: yes, there would be a few ways to make agent errors report back the way you wanted, but I think it's just a poor fit.
09:35ohpauleezI have real need for it in my day-to-day work. I've been working on a few clojure projects in the off time, but none that public on github yet
09:36vu3rddtcrayford: No luck with the java auto complete thing.. does it work without slime-company.el?
09:36chouserAWizzArd: the way exceptions were working strikes me as a symptom, not the root problem.
09:43AWizzArdchouser: where do you see a root problem?
09:44chouserusing agents for sychronous tasks
09:45AWizzArdWell, there can easily be tens of DBs that are asynchronously transactioned.
09:46AWizzArd(send db1 ...), (send db2 ...) vs (locking db1 ...), (locking db2 ...)
09:51rhickeyasynchronous transaction seems like a contradiction
09:55AWizzArdWell, both solutions have +/- the same programmatic complexity, so I can easily go with either agent+promise or atom+lock to do the transaction.
09:55chouserthe cells model is really very close, deriving from the use of locks.
09:56AWizzArdYes, the cells sound very interesting.
09:56AWizzArdMaybe I now do it with locks+atom and can later remodel it to the Cells.
09:56chouserfor example, if you do want to support a transaction on multiple dbs, you'd just list them all in the same form so that it could sort the locks consistently.
09:57jcromartieI want to implement a parser to turn whitespace and indentation into sexps... like Logo syntax
09:57AWizzArd(locking [db1 db2] ...) you mean?
09:57jcromartienot to do general programming in, but for things like config files
09:57AWizzArdjcromartie: look at fnparse
09:58AWizzArdEfficiency-wise the solutions for the transactions are probably all bounded by the sync to disk anyway.
09:58rsynnottassuming that you actually force sync-to-disk, of course
09:58rsynnottsome people consider OS buffering to be sufficient
09:59rsynnott(or have battery-backed writeback cache which actually works)
09:59AWizzArdrsynnott: yes, i mean forcing data to disk
09:59rsynnottand assuming that your operating system takes notice of you forcing a sync ;)
10:00AWizzArdThis can be done with a FileChannel via .force
10:00AWizzArdor, as hiredman pointed out, with java.io.FileDescriptor’s .sync
10:01AWizzArdrsynnott: if the disk or the OS are lying, then no db system can be used safely on such a system
10:01AWizzArdrsynnott: I will just forward the lie :-)
10:01rsynnottAWizzArd: indeed :)
10:01rsynnottand yet, the disk and/or OS often are lying
10:01AWizzArdrhickey: why does Su.. Oracle not change it in Java 7?
10:02rsynnottthere are various articles out there on how to make very sure they're not
10:02rhickeyAWizzArd: change what?
10:02AWizzArdsupport for boxed numbers
10:02rsynnott(though depending on perspective use of a proper write-back cache might or might not be considered a lie in that case)
10:03AWizzArdsbcl is using some nice tricks
10:03AWizzArdto calculate with native numbers
10:03rhickeythe tricks are old and well known
10:03chouserthe total amount of effort required in the compiler, type "system", collections, etc. to support primitives is daunting
10:03rhickeybut there's no motivation for Java since it has primitives
10:04rhickeychouser: but are primitives wrong? they are what the hardware can actually do
10:04rhickeyLisp Machines RIP
10:04rhickeyno tagged numbers in hardware
10:05chouserwhatever requires the most work is wrong. :-)
10:05rhickeyand if tagged numbers could only ever be 1/100th as fast?
10:05AWizzArdrhickey: is there any eta on Cells?
10:05chouserJava doesn't support primitives for its own collection types, does it?
10:06chouserother than array of course
10:06chouserI guess what I mean is, do Java generics support primitives?
10:07rhickeythey don't. but .Net generics do
10:07chouserC++ templates do, but again, is it worth the complexity cost?
10:07cemerickrhickey: but don't they just get boxed in .NET anyway?
10:07rhickeycemerick: no
10:08rhickeytrue generics over value types
10:08rhickeypacked representation
10:08chouserbut not using type erasure, right? does that complicate things for Clojure support?
10:08cemerickthat was my impression from some time ago
10:08rhickeychouser: yes, much more complex. But the question is, can you do without primitives without driving everyone back to C++?
10:09rhickeyi.e. could Java do without primitives?
10:10rhickeyall industrial strength CLs also have untagged full-width fixnums and unboxed floats, with commensurate grief and incompatibility
10:10rhickeybecause not being able to reach the hardware is death
10:10chouserIt does seem likely that might shrink its user base. But I have so rarely written any code (except actually inside the kernel) that demands enough performance from math that it would matter at all.
10:11cemerickyeah, same here
10:11rhickeyheh, but you both rely on code that does
10:12cemerickeh, actually, there's a big hunk of matrix stuff I wrote years ago that I *still* depend on :-P
10:13cemerickrhickey: doesn't this largely go away once IFn.invoke has float and double overloads?
10:14rhickeylong and double args returns, yes, but that's primitive support
10:14rhickeyalso move to non-objectifying math
10:14_fogus_Up until a couple years ago most of what I did was pretty dependent on fast math. These days not so much
10:15rhickeyi.e. long arithmetic that throws on overflow rather than convert to reference type
10:15rhickeyif you use Clojure vectors you depend on fast math
10:15cemerickThe real kicker is that it's way, *way* cheaper to spin up 2x, 10x nodes on ec2 than stress too much about perf
10:16cemerickI may think differently once the baseline changes. :-)
10:17rhickeyif Clojure doesn't get these things then some code will always have to be written in Java
10:18AWizzArdOne CL guy implemented a type of neural networks (Boltzmann Machine) and used arrays to represent his matrix. Those arrays are huge and eat very much RAM. He needs mutable arrays for this because he does not want to have two big arrays in RAM at once, and it is probably faster to mutate array cells than calculating up a full new Vector.
10:18cemerickrhickey: post a couple inflammatory messages comparing clojure to ocaml or something under an alias, and everyone will get revved up. :-)
10:19_fogus_ocaml is the fastest language evar! (or so I've read)
10:20cemerickyeeouch
10:20rsynnottcemerick: even cheaper now; did you see their spot pricing thing?
10:21rsynnott(you can bid on spare capacity)
10:21cemerickrsynnott: yes, I'm aware of it, though I haven't researched it. I will before we go to production, tho.
10:21cemerick'course, just how much spare cap is there anymore ;-)
10:25tedamn you ocaml with your tail recursion
10:27jcromartiete: what about it? clojure has recur
10:27cemerickI quite love recur vs. "unbounded" tail recursion
10:29AWizzArdrecur is easily searchable and allows for anon functions that can do recursion, without requiring the y-combinator.
10:30_fogus_Haven't had too many chances to whip out the Y, even before recur
10:30ChousukeI wonder if it would be possible to implement a recur-like construct for mutual recursion :/
10:31Chousukesomething like (recur-at somefunc args)
10:31jcromartierecur is nice :) it does what it says on the tin
10:31jasappI've never end up using mutual recursion much
10:31AWizzArdChousuke: you don't talk about trampolines right?
10:31somniumChousuke: maybe a case statement with function names and pass [& args] to the right one?
10:32ChousukeAWizzArd: no, I mean a real recur form, except that it supports a target
10:33ChousukeI think I would prefer one to having a TCO guarantee
10:33somnium(loop [fnname args] (case :foo ... case :bar))
10:33Chousukesomnium: I don't think that's what I want :P
10:34teChousuke: there's a trampoline isn't there?
10:34Chousukeyeah, but it's not very convenient to use :/
10:35somniumChousuke: a macro could make it more magical tco-ish, I wonder if it would offer any performance benefit for hordes of tailcalls
10:37rhickey(definterface IName
10:37rhickey [foo [int int String] int])
10:37rhickeyor
10:37rhickey(definterface IName
10:37rhickey (foo [int int String] int))
10:38_fogus_(foo +1
10:38rhickeyor
10:38rhickey(definterface IName
10:38rhickey (#^int foo [#^int x #^int y #^String s]))
10:39tethe 2nd one
10:39tei take that back
10:39tethe 1st one
10:39chousershould match defprotocol, right? so (foo or (#^int foo
10:40chouserI vote (foo^int [x^int y^int s^String])
10:41rhickeythe more I see the trailing ^type the less I like it
10:41chouser:-(
10:41rhickey(definterface IName
10:41rhickey (^int foo [^int x ^int y ^String s]))
10:42Chousukehm, removing the # really does make it cleaner :/
10:42te[int [int int String] foo]
10:42_fogus_I'm always partial to these types of layouts: (foo [x y x] {x int, y int, z String, :ret int}) but it's a departure
10:43tethere is something more concrete about []'s
10:43chouserI don't know about losing the method name from the first word in the list
10:45teid like to respectfully change my vote back again to (foo [int int String] int)
10:46chouserI guess protocols will never need types for args or return?
10:48rhickeychouser: only if long/double arg/return support is added
10:49chouserdefprotocol uses (foo [x] [x y]) so should defintereface as well?
10:51chouser(foo [^int x] int [^int x ^String s] String) ? or do all bodies have the same return type?
11:01alexykliebke: how do we save a dataframe to disk so it could be read by R? :)
11:01liebkealexyk: save
11:02alexykok
11:02alexykI resorted to PDF'ing in R for now
11:02alexykneed tick names, etc.
11:04alexykbut that's not to say the charts are not pretty on screen! :)
11:41jasappis there another one coming?
11:42jkdufairwhere are you, fogus? ours has started here in Indiana, USA
11:50chouserjkdufair: not here. are you in Indy?
12:04AWizzArdchouser: one thing did not get through, from about 2 hours ago. You said: “if you do want to support a transaction on multiple dbs, you'd just list them all in the same form so that it could sort the locks consistently”.
12:04AWizzArdThen I asked if you mean something like (locking [db1 db2] ...) by that.
12:05chouserAWizzArd: sorry, didn't see that. Yes, that's what I mean. rhickey mentioned something similar for cells
12:07AWizzArdchouser: yes, this is an advantage of locks. I could order them by the DBs internal id.
12:07AWizzArdadvantage here of locks over the agent approach
12:08hiredmanrhickey: http://gist.github.com/295631 jop is a special form that allows for directly calling java operators (+,-,*,etc), I picture it as being at the bottom of a protocol that takes care of all the dispatch like Numbers.java, would you be interested in a patch?
12:10hiredmanthat might be kind of premature since I haven't figured out what the eval() method on an Expr does yet
12:10chouser~scopes
12:10clojurebotGabh mo leithscéal?
12:10chouser~scope
12:10clojurebotscope is at http://paste.lisp.org/display/73838
12:21arohnerhere's a problem I'm having trouble converting into a purely functional implementation
12:22arohnerI have two seqs of items, and I have a predicate I need to call on all combinations of items from the seq
12:22chouser,(for [a (range 4), b (range 4)] (= a b))
12:22clojurebot(true false false false false true false false false false true false false false false true)
12:22arohnerbut if the predicate returns true, one of the items doesn't need to be compared again
12:23arohnerand the not comparing is important, because this is an expensive operation
12:23arohnerif (pred a b) returns true, b doesn't need to be in any comparison after that
12:23arohneris there a way to do this without refs/atoms?
12:23chouseryes!
12:24chouserit's just a matter of figuring out how. ;-)
12:24chouserwhat do you want returned?
12:25arohnerthe set of items for which (pred a b) did not return false
12:25arohnera little more background
12:26arohnerboth lists are identical, I'm just comparing the individual items
12:26arohnerand this is original adapted from an algorithm that sets the return value to the input list, and removes items as it goes along
12:26chouser,(map (fn [a] (some #(when (= a %) [a %]) (range 4))) (range 4))
12:26clojurebot([0 0] [1 1] [2 2] [3 3])
12:28chouseroh, I see -- once 1 has participated as either arg in a successful predicate, you don't want it included as either arg ever again.
12:28chouserhmm...
12:30arohnerit's not either arg, it's the second arg
12:31arohnerif (pred a b) is true, b should not be included ever again
12:32chouserok, the one I gave above does: if (pred a b) is true, no (pred a ...) will never be tested again (which is right, right?) but (pred? b ...) will (which is wrong, right?)
12:43arohnerI can generate the combinations, and then pass those to a recursive function
12:43arohneryou'd have to filter the pairs each time you want to "remove" an item
12:43chouserbut once you generate the combinations, you've lost useful info about which ones can be skipped
12:44arohnerI was thinking: 1) generate all possible pairs, pass them to a recursive function
12:44arohnerrun (pred a b)
12:44arohnerremove the first item from the list
12:44arohnerif (pred a b) is true, run filter on the generated pairs, and recurse
12:45chouserif (pred 1 2) is false, you still want to check (pred 2 1), right?
12:45mabesHow do I have a macro take a symbol and then use that symbol as a suffix for a function that gets defined?
12:46chouserand were my previous statements correct?
12:47mabesFor example, I can define I macro that defines a fn: (defmacro square-fn [fn-suffix] `(defn ~fn-suffix [x#] (* x# x#))) But in this example I would like to have square-"fn-suffix" defined
12:48chouserarohner: this doesn't have to be lazy, does it?
12:48arohnerchouser: no
12:48arohnerif (pred 1 2) is false, you still want to check (pred 2 1)
12:48arohnerhttp://gist.github.com/296026
12:48chouser,`(defn ~(symbol (str "foo-" 'bar)))
12:48clojurebot(clojure.core/defn foo-bar)
12:49chouserarohner: are you content with that?
12:49mabesarg.. I was looking for that! I thought it would by called sym. Thanks chouser
12:49chousermabes: np
12:49arohnerI think so
12:49arohnerI don't know how much better it can get
12:49arohnerdoesn't seem like much
12:50chouserarohner: remove is doing another O(n) pass, but if the expense is 'pred' and not the size of myseq, then you should be fine.
12:50arohnerright
12:51arohnerchouser: thanks!
12:51chouserI think your 'for' is missing something. or something.
12:51arohneryeah, that was typed out hastily into the browser
12:51arohnerI'm too used to paredit
12:52chouserto avoid that O(n) scan I was trying to uses sets, but it's a bit of a pain.
12:54arohnerchouser: actually, two sets isn't that bad
12:55arohnerone for the winners, and one for the losers
12:55arohnercheck if either item of the pair is in the losers set
12:55arohnerif a value loses, remove it from the winner set and add to the loser set
12:56arohnerwhen the pairs list is empty, return the winner set
12:57arohnerchouser: thanks again
13:25alexykis there something like ->, but working right to left? I have a data structure and access like,
13:25alexyk,(let [m {:a {0 "a", 1 "b"} :b {4 "z", 1 "c"}}] ((m :a) 1))
13:25clojurebot"b"
13:25alexykas you see, I start with the data structure m, and then fetch keys from nested maps. I guess I can do get-in... but still
13:25alexyksomething like <- would be cute
13:26jkdufairdoesn't ->> work right to left?
13:26alexyknot in this case
13:26alexykhere, the keys would go into function positions and cause Clojure swearing like a sailor
13:27alexykcause they're not all keywords, and can be strings or ints
13:27jkdufairhow would you access it with <-
13:27jkdufair?
13:29alexykthe idea is to put the result into the first position, of a function; since it'll be a map
13:29alexykor an array
13:30alexykthe fixed things go into second, to look things up
13:30jkdufairah!
13:30alexyk(<- m k1 k2)
13:30jkdufairseems like it's be easy to implement as a macro
13:30alexykyeah :)
13:30alexykbut I'm new to macros still
13:31somniumhttp://paste.pocoo.org/show/174299/
13:31jkdufairme too in a practical sense. but if you look at the code for -> and ->> they are very straightforward
13:31somnium^^ it is :)
13:31jkdufairwow. this channel is like the north pole
13:32somniumnot as general as it could be, may prefix-> or smthing
13:34alexykwow that was quick! thx somnium
13:34alexykI like <- though
13:36somniumalexyk: all these -> <- >>= make it look (sort of) like haskell-in-parens
13:37somniumI would go with <--(>_<)--<< but as you like :)
13:37alexyksomnium: well, haskell in parens is better than one without parens! :) all those stupid $ for precedence
13:37alexyksomnium: you drew an arrow through a pokemon there :)
13:38nubahahaha
13:42alexykhttp://blog.clemens.endorphin.org/2009/01/liskell-standalone.html
13:43alexykhttp://clemens.endorphin.org/ILC07-Liskell-draft.pdf
13:58alexykliebke: (mean []) is NaN, but median is 0.0?
14:01liebkealexyk: because you're getting a divide by zero error for mean, but not median. That's the underlying pcolt library
14:01alexykah ok
14:05alexykI'm using code like: (let [x ... y ...] (when (and x y) [x y])). Can I simplify it via with-let, or with-let is only for a single binding?
14:11Chousukesingle bindings only
14:11Chousukeand I guess you mean when-let :/
14:12fdaoud,(doc when-let)
14:12clojurebot"([bindings & body]); bindings => binding-form test When test is true, evaluates body with binding-form bound to the value of test"
14:13somniumalexyk: a good opportunity to write 'and-let :) (the source for when-let is quite concise)
14:17the-kennyjust a small macro which expands to nested when-lets :)
14:19Chousukehmm... (defmacro and-let [bindings & body] (let [names (map first (partition 2 bindings))] `(let ~bindings (when (and ~@names) ~@body))))
14:20Chousukeno support for destructuring, but oh well
14:20ChousukeI suppose you could use (map first (partition 2 (destructure bindings))) :P
14:30konrCan I define additional commands to leiningen? In my specific case, I want something like `lein use foo` to generate a foo.jar file containing src/foo.clj
14:31somniumhttp://paste.pocoo.org/show/174331/ << recursive and-let
14:31konr*having foo.clj as the main file
14:33tomojkonr: you can write plugins
14:33tomojI don't know how though
14:33tomojlein-swank is an example
14:34Chousukesomnium: that supports only one expression in the body though :/
14:34avarushi
14:35somniumChousuke: ah, easy to fix
14:36Rayneskonr: In your project.clj, in the defproject, you can do :main ns.of.main.file and then 'lein jar' it.
14:37somniumhttp://paste.pocoo.org/show/174338/
14:37somniumChousuke: that was a good catch, thanks
14:38konrRaynes: yes, but then I'd have to create a script to change it... it seems that it's not so hard to create a plugin: http://groups.google.com/group/clojure/browse_thread/thread/11ee44e988022289
14:38Chousukesomnium: I think you still need a ~@body in the (and-let ...) part as well)
14:38somnium39 :)
14:38somniumI knew it was coming, copy/paste fail :/
14:39the-kennygist.el in emacs ftw! :)
14:41somniumI wonder why assert-args in core is private
14:41the-kenny,(doc assert-args)
14:41clojurebotI don't understand.
14:42Chousukethat lodgeit pastebin seems better than gist though :/
14:42Chousukesince it doesn't require javascript :P
14:42the-kenny,(doc clojure.core/assert-args)
14:42clojurebot"([fnname & pairs]); "
14:42the-kennyChousuke: does gist require js? Really?
14:42Chousukelast time I checked, yes.
14:43the-kennyhttp://gist.github.com/279651 displays without js here. (please ignore the code ;))
14:43Chousukehm, looks like it does.
14:44the-kennyIncluding gists in other sites doesn't work without js, but simple pasting and viewing ist just plain html
14:44Chousukemaybe it's just the blog-embeddable gists that require js :/
14:44Chousukethey always throw me off since I usually browse with javascript disabled
14:44the-kennyYes, they use js.. I don't know why
14:44tomojthe embeds I saw are just <script> tags
14:44the-kennyAs far as I understand the code, they don't need to use js
14:49tomojI guess the js makes it so that the latest version will show?
14:49AWizzArdSo.
15:11mattreplhey nathanmarz, hope you'll post about clojure-cascading hacking =)
15:11nathanmarzmattrepl: i absolutely will
15:11nathanmarzsometime within the next week
15:12avarusmhmh...are you guys all hacking on vim or emacs?
15:13the-kennyavarus: I think most people here use Emacs
15:13avarushrm...I only need syntax highlighting and some ability to "run" some shellscripts :P
15:14avarusI'd have to learn the whole emacs stuff for that
15:14chouserI use vim
15:14the-kennyavarus: Trust me.. if you try slime, you don't want to use shellscripts anymore :)
15:14avarusand I guess you are using clojure-mode?
15:14chouserlast poll there were about as many people using emacs as vim+all other IDEs combined.
15:14chouserso half, not most. :-)
15:15avarusI tried enclojure and the idea plugin for idea
15:15avarusdidn't like it
15:16avarusI'm normally on linux and using "gedit" :P...but parens highlighting sucks!
15:16avarusI am currently working on a mac and tried aquamacs which has brilliant parens highlighting
15:16avarusbut no idea if aquamacs is a good alternative to "pure" emacs
15:16tomojaquamacs is perfect
15:17tomojreally easy to set up for clojure, as well
15:17tomojthough, learning how to use aquamacs is a different story...
15:17the-kennyBut Aquamacs is ok, absolutely
15:17the-kennyEspecially for starters
15:17tomojI mean, you can get away with just treating it like gedit probably (?), but you will be missing out
15:17somniumI miss the gmate themes on emacs
15:17IntertricityThese are a bit of silly questions but, do I need JDK to run clojure? I downloaded clojurebox and it works pretty well
15:18Intertricitybut I don't know what I could be missing
15:18somnium90% of color-theme.el is border-line offensive
15:18tomojcolor-theme pissed me off because themes would leave stuff behind and reverting didn't work
15:18tomojended up just building my own color theme :/
15:18chouserIntertricity: you need JDK to *build* clojure, but only the JRE to use it (including running and compiling clojure code)
15:18avarustomoj: so what? aquamacs or pure emacs? :P I have to learn something nevertheless
15:18mattreplre: aquamacs, gnu emacs has cocoa support now but aquamacs tries to be a good mac app
15:19tomojpersonally, I use aquamacs on the mac
15:19tomojI didn't know there was a reason not to
15:19the-kennyavarus: Just use Aquamacs. It's Emacs as a nice Cocoa app
15:19Intertricitychouser, so I don't even need JDK to compile clojure programs or use api related things like speech synth?
15:19tomojexcept for use inside screen maybe
15:19avarusnot using screen here
15:19chouserIntertricity: right
15:19Intertricitywow nice
15:19billsmithaustinIntertricity: that's all in the JRE.
15:19Intertricitychouser, thanks :D
15:20tomojavarus: also, I happened to write a blog post the other day about setting up from scratch http://tomojack.com/?p=8
15:20avarusah! :)
15:20tomojthat process worked for me in aquamacs
15:20avarusgreat
15:20tomojthough you might need to be sure package.el's initialization stuff gets put in the right place
15:20IntertricityI used to ignorantly despise java until I saw clojure.. now that little cup icon is pretty to me, hehe
15:21somniumanyone used Clojure-CLR with mono?
15:21Intertricitysomnium, I'm eagerly waiting a binary to play with
15:21avarusI'm not
15:22IntertricityOne more simple question, I don't mind reading if anyone has a link- is there anything specific I need to know about installing new java libraries to use with clojure?
15:22the-kennyIntertricity: Just put them in the classpath
15:23avarusya, simple as that
15:23Intertricityclasspath- this folder? C:\program files\java\jre6\lib
15:23mattreplIntertricity: and there has been some work on a dependency manager, with various libs thrown up on http://clojars.org
15:23the-kennyIntertricity: For example, yes.
15:24avarusthe-kenny: tomoj: mmh...which version are you running? on aquamacs.org there is 1.9 but also 2.0 preview 1 which says it's based on coca
15:24billsmithaustinIntertricity: I wouldn't put them there. Better to install them someone outside of the JRE and then add that directory to the classpath. Otherwise you'll have problems when you upgrade your JRE.
15:24the-kennyavarus: I used the preview. It's pretty stable
15:24Intertricitybillsmithaustin, oh I see
15:24the-kennyBut I'm using a self-compiled recent version now
15:24avarusI did "java -cp $MYOWNCLASSPATH ... "
15:24mattreplIntertricity: the classpath can be set when you run the JVM.. `java -cp /some/path:/another/path:a/relative/onetoo ...`
15:25liebkealexyk: if you're still around, I created a save-pdf function that writes incanter.charts to a pdf file: https://gist.github.com/b91cc35f1c7c71b7fafe
15:25avarusthe-kenny: ok, thanks :)
15:25avarusthe-kenny: snow leopard, too?
15:25the-kennyavarus: Yes
15:25avarusok :)
15:25mattreplliebke: nice
15:25technomancyjust as a warning, Aquamacs breaks^H^H^H^H^Hchanges core behaviour in strange and unpredictable ways
15:25Intertricitymattrepl, thanks :)
15:25technomancymaking it difficult for maintainers to target it for compatibility since it's not cross-platform
15:26neotykyep
15:26avarus:>
15:26liebkemattrepl: yeah, I just used a library called itext, which fortunately is in a public maven repository -- so I can just include it in a project.clj or pom.xml file
15:27the-kennytechnomancy: Hehe
15:28technomancyI try to steer people towards http://emacsformacosx.com/ as much as possible
15:28avarusya, just tell me like that
15:28avarusI'll have a look
15:28neotyklike following code http://clojure.pastebin.com/m3e22d711 will output stuff to *inferior-lisp* buffer
15:29technomancyI mean, it's your choice; enough people use aquamacs that some one is likely to find the bugs before you do, but I just thought I'd throw that out there.
15:29neotykand not where you would except that is: slime-repl
15:30neotyktechnomancy: this emacsfotmacosx is normal emacs 23?
15:30neotykhow different it is from aquamacs?
15:30technomancyneotyk: yeah, it's just a convenient build of the official source tree IIRC
15:30technomancyneotyk: Aquamacs is a fork
15:30technomancythis is GNU Emacs
15:30neotykvery nice
15:31mattreplyeah, cocoa support is in the official repo
15:31the-kennyYeah, there's also Emacs.app
15:31mattreplfor more info: http://www.emacswiki.org/emacs/EmacsForMacOS
15:31technomancyEmacs.app is just the name for the artifact you get when you compile GNU Emacs 23+ with the OS X flags turned on
15:31technomancyaka "Cocoa Emacs"
15:32neotykhow many emacs is there anyway?
15:32neotyksame as linux distros?
15:32technomancyneotyk: you don't want to know: http://www.jwz.org/doc/emacs-timeline.html
15:32technomancythe history goes back much further than Linux
15:33avaruscome on guys...the confusion makes me installing textmate :P
15:34neotykis not that bad though, compared to number of linux distros
15:34konrGuys, what is wrong with (with-ns 'foo (println "bar")) ?
15:34mattreplit's really just GNU Emacs (and platform-specific, unofficial ports) and XEmacs
15:34mattreplnowadays, that is
15:34konrI get a "no namespace found" error, but should it create one?
15:34konr*shouldn't
15:34tomojtechnomancy: is that what used to be called "carbon emacs"?
15:34hiredman,(doc with-ns)
15:34clojurebot"clojure.contrib.with-ns/with-ns;[[ns & body]]; Evaluates body in another namespace. ns is either a namespace object or a symbol. This makes it possible to define functions in namespaces other than the current one."
15:34tomojit looks familiar
15:34neotyklike there is no hannah montana emacs fork while there is such a distro: http://hannahmontana.sourceforge.net/Site/Home.html
15:35technomancytomoj: Carbon Emacs was the old official port
15:35tomojah
15:35avarusI so fucking hate hannah montana
15:35hiredman~def with-ns
15:35technomancybut it used deprecated OS X APIs, so it was dropped in favour of Cocoa
15:35neotykavarus: the distro? :O
15:35technomancytomoj: Carbon only works with 22, which is several years old
15:35technomancyanyway, it's much simpler outside OS X.
15:35avarusneotyk: no :P
15:35technomancyjust pick a version number =)
15:35tomojI do find myself going through trying to make aquamacs act more like normal emacs
15:35hiredman,(doc the-ns)
15:35clojurebot"([x]); If passed a namespace, returns it. Else, when passed a symbol, returns the namespace named by it, throwing an exception if not found."
15:36hiredmankonr: the doc doesn't say it does, and the code definitely doesn't
15:40konrhiredman: thanks!
15:41Intertricityhrm, I thought c-c c-c was send buffer? I'm only getting send line
15:41the-kennyIntertricity: C-c C-c is compile-defun
15:42Intertricityit's only sending one line at a time to the repl for me
15:43Intertricityahh c-c c-k for clojurebox
16:01BrandonWhello, does anyone here have the progamming clojure book?
16:01jasappyeah
16:01BrandonWI have a question on faux-curry vs partial, and the faux-curry implementation in general
16:02BrandonWokay, page 165/166 (on the ebook)
16:02BrandonWnot sure if it is the same on the paperback copy
16:02BrandonWthe faux-curry definition seems to behave in exactly the same manner as the partial function. is that true? is that intentional?
16:03jasappit must be on a different page
16:04jasappI'm not sure, it's been awhile since I've looked at this
16:05BrandonWit is in the lazier than lazy sub chapter of the functional programming chapter
16:05billsmithaustinIn the ebook, page 165 has the heading, "Lazier than lazy".
16:06billsmithaustinIt starts right after this code sample: (defn
16:06billsmithaustincount-runs
16:07billsmithaustin"Count runs of length n where pred is true in coll."
16:07billsmithaustin[n pred coll]
16:07billsmithaustin(count-if #(every? pred %) (partition n 1 coll)))
16:07billsmithaustinSorry for the link breaks.
16:08BrandonWokay, it is the page after that
16:15BrandonWit's kind of weird
16:15BrandonWi can see why the extra apply is needed in the definition of faux-curry
16:15BrandonWbut i don't quite understand it
16:17duncanmis it a design flaw if i'm too aggressive with agents?
16:19avarustomoj: I'm just setting up aquamacs but I fail at the first pasted code where I should press "C-j" :P
16:20avaruscontrol-j? but where
16:20avarusif I do it in aquamacs it just makes a new line
16:21tomojok
16:21tomojyes, heh
16:21tomojaquamac's *scratch* buffer was in text-mode by default, forgot about that
16:21tomojtry doing 'M-x emacs-lisp-mode' first
16:22avarusok
16:22lancepantzforgive my lack of java-foo, but i get #<Input org.mortbay.jetty.HttpParser$Input@27e91a4d> when i try to println on request :body in compojure
16:22lancepantzhow can i just print out the request body?
16:22tomojavarus: and lemme know if that works so I can add that to the post
16:22lancepantzas a string
16:23tomojC-j is bound to newline by paredit for me :(
16:23tomojC-x C-e should work
16:24BrandonWlancepantz: it looks like it is a stream
16:25BrandonWyou might have to call the appropriate java stream methods in order to read the data in a string representation
16:25BrandonWhttp://jetty.codehaus.org/jetty/jetty-6/apidocs/org/mortbay/jetty/HttpParser.Input.html
16:25lancepantzso in this case, read?
16:26hiredmanI think compojure depends on a bunch of apache stuff, one of their utility methods might turn it into a string
16:26BrandonWprobably true
16:26BrandonWseems like something that could be easily abstracted away from
16:27kotarakmaybe it has a toString method?
16:27hiredmankotarak: I image the representation he is seeing is the toString
16:28lancepantzwell, (println (.read (request :body))) prints 123, which is not the body
16:28BrandonWyeah, it looks like the only way to read the bytes through the java interface is via integer values that would have to be converted into string representation
16:28BrandonWread only reads one byte
16:28lancepantzjesus
16:28lancepantzi hate java
16:28BrandonWwell not byte actually
16:29BrandonWoh nevermind
16:29BrandonWyou can get one block at a time, or send in a byte array and get back an arbitrary amount of the stream
16:29avarustomoj: that thing is killing me :P..don't think I can contribute anything to that post for now :P
16:29cemerickcompojure doesn't depend on any apache anything
16:29cemerickwhat's the issue?
16:30billsmithaustinBrandonW: faux-curry is a little different from partial. I'll give you an example.
16:30avaruscompojure has some libs from apache as deps (for uploads e.g.?!)
16:30tomojavarus: didn't work?
16:30lancepantzcemerick: i'm just trying to println on a request, so i can look at it for debugging purposes
16:30cemerickyeah, optional though
16:30BrandonWlancepantz: you may be able to use somethign from duck-streams contrib
16:30cemericklancepantz: from within a handler, I presume?
16:31lancepantzyeah
16:31cemerick(println request)
16:31hiredmanyou can use http://paste.lisp.org/display/93138 to turn an input stream into a bytebuffer
16:31avarustomoj: sure, I clicked somewhere and activated the emacs lisp mode and I could again click in some context menu to evaluate the code and something happened :S
16:31tomojyou should be good, then
16:31hiredmancemerick: compojure sure comes with a lot of the apache commons libraries
16:31hiredmanfor something that doesn't depend on them
16:31tomojif 'M-x package-list-packages' now works, you're good
16:31billsmithaustinTry ((faux-curry + 1 2 3)) vs ((partial + 1 2 3))
16:31avarustomoj: wouldn't it be better to first learn some "pure" emacs first? I feel so list in that :)
16:32avaruslost*
16:32hiredmana bytebuffer can be turned into an array of bytes, and the constructor for String takes an array of bytes
16:32tomojlearning emacs can't hurt
16:32alexykto the tune of "unbreak my heart": unclog my repl! My repl grows steadily to hold 30gb out of 31.5gb allotted. Things are slow as it gc's all the time. DIs it just the (def x ...) vars I created? If I do (def x nil) for some, should it get better? Is there a way in JVM to do a crude sizeof(x)?
16:32tomojaquamacs is not all that different for the basics
16:32alexykcemerick: don't you do a PDF library?
16:33tomojbut yeah, switching to pure emacs wouldn't be a bad idea
16:33cemerickhiredman: I *think* the file upload/multipart stuff is the only dependency, and optional if you're not doing uploads. *shrug*
16:33cemerickalexyk: It's what we're known for, yeah: http://snowtide.com
16:33hiredmancemerick: it also has commons codec and io
16:33tomoj(oh, I misunderstood you I think. but yeah)
16:33lancepantz(println request) still prints the body as HttpParser$Input
16:34alexykcemerick: 'cause I just saw iText liebke used to PDF-ize the Incanter charts and was wondering where's your pro bono contribution to the OSS movement or something! :)
16:34avarusI'll try http://emacsformacosx.com/, tomoj :)
16:34BrandonWbillsmithaustin: i understand that the faux-curry doesn't evaluate the function even if it has all the required args because clojure can't know in advance if the user is done sending args toa function, so you need to evaluate the function twice to retrieve the result
16:34cemerickalexyk: we don't generate PDFs, we extract content + data from them :-)
16:34BrandonWbut i don't quite understand why
16:34tomojavarus: hopefully the instructions in the post should work perfectly there, when you're ready
16:34itistodayis there a way to precompile .clj files to .class files?
16:35alexykcemerick: ah, now I am deconfused. in , not out
16:35BrandonWi can kind of see the importance of applying partial to itself before beginning to apply the arguments to the resulting function
16:35lancepantzhttp://www.pastie.org/811705
16:35avarusoh, too bad, the download doesn't work at that website :>
16:35BrandonWbut i don't quite understand why leaving the first 'partial' out prevents the faux-curry from working
16:35lancepantzi want to see the body as a string
16:35alexykcemerick: do you determine structure: tables, hierarchy?
16:35avarusit redirects me to the main website: http://emacsformacosx.com/
16:35itistodaylike say if you have two .clj files in a directory and they call code from each other, how would you run that from the command line?
16:35arohneritistoday: yes, http://clojure.org/compilation
16:35kotarakitistoday: http://clojure.org/compilation
16:36tomojavarus: hmm, when I click download a dmg tries to download
16:36cemerickalexyk: Yes, in many circumstances. We're currently working on something that is generally-applicable, and outrageously accurate and absurdly configurable.
16:36avarusoww..the world hates me today :)
16:36cemerickand can be applied to any file type
16:36technomancyitistoday: you can also use clojure.main
16:36tomojcemerick: just curious then, did you investigate tika?
16:36itistodaytechnomancy: how?
16:36alexykcemerick: can it also regrow hair and obtain models?
16:37itistodaytechnomancy: just specify both of the files?
16:37kotarak,(doc compile)
16:37clojurebot"([lib]); Compiles the namespace named by the symbol lib into a set of classfiles. The source for the lib must be in a proper classpath-relative directory. The output files will go into the directory specified by *compile-path*, and that directory too must be in the classpath."
16:37technomancyitistoday: java -cp /path/to/clojure.jar:/path/to/your/project/src clojure.main -e "(use 'my-project) (invoke-my-projects-function)"
16:37avarustomoj: oh great, I'm downloading it 15 times now lol
16:37tomojhaha
16:37technomancyitistoday: not exactly what I'd call convenient
16:37technomancymost people write bash wrappers
16:38cemericktomoj: briefly, it's not particularly interesting, IMO
16:38alexykcemerick: I know a business interested in detecting the hierarchy, with an end-user product for PDF conversion.
16:38itistodaytechnomancy: right, 'clj' etc. this is actually a question someone asked on the mailing list that i'd like to answer for them, but I've been bad and haven't even attempted to reproduce this because of how little clojure coding i've done. thanks for the answer! i'll pass it along
16:38tomojcemerick: ok, I just discovered it and haven't looked at any details
16:39tomojI guess our requirements probably don't match anyway
16:39cemerickalexyk: send them our way, we might be able to help
16:39BrandonWalexyk: that is an interesting question. i wonder if you could correlate activity in this irc channel with data on who is in here, what time zone they are in, if they are using clojure in the workplace, or in their own time at home
16:40cemericktomoj: it's fundamentally content-oriented, which is OK, but not up to snuff for structured data extraction
16:40tomojsounds perfect for me then :D
16:40cemerickyeah, tons of useful things you can do with it
16:40tomojBrandonW: based on when they're working?
16:40arohnerchouser: I came up with a new arrow trick. You've probably already thought of it, but it amuses me
16:41arohner(-> (fn [x] ...) (reduce my-seq))
16:41tomojI'm in here during work hours all the time, but hardly ever actually using clojure at work :/
16:41alexykcemerick: sure, will forward the idea (they are on .NET and may be doing it in-house in some G-dawful Y# thing though)
16:41cemericktomoj: our aim is to be able to take any document type (invoice, resumé, financial disclosure, tax form, the federal register, etc etc), a configuration, and have fundamentally database-ready data flow out.
16:42cemerickalexyk: PDFTextStream.NET is available :-)
16:42tomojsounds... fun
16:42alexykcemerick: did you see the guy with OCaml PDF ported it all into F# too?
16:42cemerickalexyk: no, link?
16:43alexykhold on
16:44alexykhttp://www.coherentpdf.com/ -- and ocaml code exists as a literate book
16:44alexykI bet you can translate ocaml into clojure almost literally or programmatically
16:44BrandonWtomoj: yeah. you'd have to assume a lot about average working hours, but it would be an interesting experiment to graph the activity of this channel and try to infer things from it
16:45tomojyeah
16:45BrandonWi'm here usually during work, but same as you
16:45BrandonWi'm learning it at home
16:45tomojeven just looking at the activity patterns would interest me
16:45BrandonWbut occasionally at work i will read up on the pdf and try stuff out
16:45alexyklet's start with metadata "I'm at work pretending to work" or "I'm at home working from home", etc. :)
16:45BrandonWthen i come here with my questions on currying :)
16:45alexykthen some powerful machine learning will be running in Incanter!
16:46alexykwe need volunteers to tell us their true status at all hours of the day
16:46hiredmanasking for the truth is cheating
16:46tomojI have only gotten to use clojure at work for a couple days, and I've been doing that in the middle of the night
16:46alexykhiredman: ground truth is necessary for the training data
16:46hiredmanyou must use statistics to determine it
16:47tomojis the ml stuff in incanter now? :D
16:47avarusI want to use clojure for a project at work so I'm the only one able to master it :P
16:47BrandonWwe will actually have the freedom to use clojure at work, once we finish our initial re-implementation of everything that we inherited (in C#)
16:47alexykhiredman: statistics cannot pull ground truth out of, well, air
16:47avarusso I will be at least :P
16:47kotarakI seem to be the only one to be knocked out by corporate firewall. :/
16:47BrandonWunfortunately my co-worker is a bit more enamored by scala (but that is mostly because of lift)
16:47tomojI got an e-mail from a co-worked about lift the other day.. ignored it
16:47avarusI learned scala...it's a big language imho
16:47BrandonWyeah
16:48BrandonWit will be better than java and C#, and i think i would like it more than python/ruby
16:48avarusI like "simple" and light languages
16:48BrandonWbut i definitely am leaning towards clojure. compojure just isn't quite as far along as lift is
16:48BrandonW(in terms of convincing my co-worker :D)
16:48tomojI think that's on purpose, though
16:48avarusI don't like lift because it puts me quite in a straight jacket
16:48BrandonWyeah
16:49BrandonWyep
16:49BrandonWi only just realized the other day
16:49alexykas I said earlier on #scala: Scala. She was a strict, bossy bitch. Clojure: he was a bad-ass drifter. Together, they had to fight the Java mob.
16:49tomojso those of us that want more need to build it on top of compojure I suppose
16:49BrandonWhow easy it is to implement authentication/authorization in compojure
16:49avarusalexyk: hehe
16:49tomojBrandonW: really? I've been thinking about that
16:49BrandonWat first i thought it was funky that it was left out, then i realized it really is only 30 or so lines of code, and you can completely customize it then
16:49tomojBrandonW: just basic user/pass auth?
16:49somniumit seems compojure is trying to dissolve into an library for ring so someone else can write liftjure or whatever
16:49BrandonWthe example from the compojure wiki
16:49BrandonWwell not necessarily basic
16:50BrandonWbut that's where customization comes in
16:50tomojah, I need to write an oauth provider :/
16:50BrandonWit is really easy to just grab a value from a form for user/pass, auth it against database/xml/hardcoded values, etc
16:50BrandonWand then store it in a cookie via jetty
16:50avarustomoj: I already spotted a lib for oauth in clojure
16:50avarusat github
16:50tomojprobably client only, I bet
16:50avarusya
16:51avarusah "provider"
16:51avarusmissed it :)
16:51itistodayok i'm actually trying this myself now, i've got two clj files, both of them seem to specify the same namespace but the files obviously have different names
16:51BrandonWi didn't realize jetty takes care of all the cookie information for you, which is great. you just add the information about how the user is authenticated to the session, and everything is taken care of for you
16:51somniumalexyk: :) what was the reaction to that comment?
16:51tomojBrandonW: what exactly do you mean?
16:51itistodayfoo.clj and foo-utils.clj, how do i run them using the typical 'clj' shell script?
16:51tomojmy cookie code doesn't care about jetty
16:51BrandonWbasically, i didn't realize that compojure doesn't need to implement cookie handling of authentication; that jetty does it for you
16:51BrandonWoh
16:52itistodayhe/I are obviously not using the ns/use/require functions correctly
16:52tomojhmm, strange
16:52BrandonWmaybe i mis-read the wiki
16:52BrandonWlet me load it up
16:52tomojnah, you're probably right
16:52tomojcompojure is still largely mysterious to me
16:52itistodaywant to just be able to do: clj foo.clj
16:53itistodaydoes foo-util.clj have to be in a different namespace?
16:53avarusI asked the other day what template engine I can use and some said "compojure". I realized it doesn't have such a thing...only (html [:h1... etc...
16:53itistodayit has a single function defined in it that's called from foo.clj
16:53tomojBrandonW: link, though?
16:53itistodayavarus: use gulliver
16:53tomojavarus: enlive is an option
16:53BrandonWhttp://ericlavigne.wordpress.com/2009/01/04/compojure-security-authentication-and-authorization/
16:53itistodayenlive doesn't let you do PHP-style templating
16:54tomojgood
16:54tomoj:P
16:54itistodaytomoj: it's not
16:54avarusitistoday: I'll have a look, thanks
16:54itistodayi mean, it's useful sometimes to do it the enlive route, but for example if you're serving "static" pages, like a homepage, it's not good
16:54itistodaytomoj: designers hate it
16:55itistodayavarus: http://www.brool.com/index.php/a-modest-proposal
16:55itistodaynow, if someone can help me with this damned newbie question
16:55itistodaythere should be a page somewhere that tells you how to run two .clj files from the command line
16:55itistodayit's like clojure 101
16:56BrandonWtomoj: read that page i linked, then look at the comment from James, jan 5th 2009 6:27 PM
16:56tomojitistoday: why would designers hate it? I'd think it'd be better
16:56BrandonWstarts with "Jetty uses an in-memory session store..."
16:57Chousuketomoj: that's my impression too
16:57tomojthey can just make a static html page which they can view in their browser locally
16:57itistodaytomoj: yes, if that's all they want to do
16:57tomojah, I see
16:57itistodaybut usually designers want to be able to do the equivalent of PHP's include()
16:57tomojso, designers that want some access to code stuff but don't want to deal with enlive?
16:57itistodaytomoj: yes
16:57tomojah, yeah
16:58tomojyou could probably hack that in, but, yeah
16:58itistodaythat's really all they want, to use include so they don't have to change code in 20 million places
16:58Chousukewell, you could use a placeholder element for that..
16:59tomojI haven't figured out layouts/subtemplates with enlive yet
16:59tomojBrandonW: I'm confused by that
16:59itistodayso here's what the guy posted to the mailing list: http://paste.pocoo.org/show/174385/
16:59kotaraktomoj: simply functions
16:59tomojBrandonW: there's no with-session
16:59itistodayi'm guessing he's using 'require' incorrectly
17:00ChousukeBut I think designers would like to be able to write a template which has placeholder elements that will be replaced and modified by systems like enlive :/
17:00itistoday,require
17:00clojurebot#<core$require__6458 clojure.core$require__6458@1eed1e1>
17:00itistoday,(doc require)
17:00clojurebot"([& args]); Loads libs, skipping any that are already loaded. Each argument is either a libspec that identifies a lib, a prefix list that identifies multiple libs whose names share a common prefix, or a flag that modifies how all the identified libs are loaded. Use :require in the ns macro in preference to calling this directly. Libs A 'lib' is a named set of resources in classpath whose contents define a library of Cloju
17:00kotarakitistoday: require must be load
17:00tomojmaybe he is doing sessions in some other way besides using compojure's session middleware?
17:00kotarakitistoday: the ns in foo-utils must be in-ns 'foo
17:01alexyksomnium: I'm using both clojure and scala and promote world peace in general, so folks take it the right way
17:01Chousukeperhaps you could have a simple preprocessor for such templates that allows for includes or some other simple manipulations
17:01tomojmy understanding was that the choice of where to put the session is made when you wrap the with-session middleware, not by jetty
17:02BrandonWtomoj: i'm not fluent in compojure at all at this point, but it looks like his login-controller method takes in a session & params, alters teh session by adding the user's authenticated name to the dictionary of session key/vals
17:02itistodaykotarak: here's where i am now: http://paste.pocoo.org/show/174387/
17:03tomojyeah, I just don't understand where the session ref comes from in the first place
17:03itistodaykotarak: still getting an exception :-p
17:03BrandonWand then at that point, the plaintext name/val of the authenticated user would be stored in memory on the server, and the cookie would have a securely random key pointing to that piece of data
17:03kotarakitistoday: because you obviously don't load foo-utils: (ns foo (:load "foo-utils"))
17:03BrandonWso then jetty takes care of cookies for you, and all you have to worry about is the act of authenticated the user (which is easy)
17:04tomojI guess either compojure has changed since that was written or there's some sessions-without-with-session feature.. did you try running that code?
17:04BrandonWno
17:04BrandonWhaven't even finished learning clojure at this point
17:04tomojoh well, in any case, you're right, it's easy :)
17:04arohnerthe default session handler is in-memory
17:04arohnerI believe it's a middleware
17:04itistodaykotarak: thanks! that's what i was missing, because I had no idea. :-p
17:04tomojarohner: yeah, that was my understanding
17:04BrandonWbut what i'm thining is it doesn't really even matter exactly what compojure can or can't do, unless you're saying compojure doesn't allow you to add variables to the session?
17:04arohnerbut yes, you can replace session handling with e..g a database if you want
17:04tomojlooking at code that is using sessions without with-session somehow
17:04BrandonW*thinking
17:05tomojBrandonW: I'm saying there is no session at all unless you use with-session
17:05itistodaykotarak: you know, i'm looking on the clojure site and i don't see this documented anywhere
17:05arohnerbut compojure by design has no dependency on a database
17:05tomojand in that case, compojure sends the cookies and manages the sessions in memory
17:05arohnerthat's higher up the stack
17:05BrandonWhmm
17:05BrandonWby manages the cookies, you mean it doesn't let jetty do it automatically?
17:06tomojwell, jetty sends the cookies to the browser
17:06tomojbut compojure builds it
17:06tomoj"Set-Cookie: compojure-session=...." or something like that
17:06BrandonWinteresting. yeah i'll have to play around with it once i get to that point
17:07tomojand you could swap out jetty with whatever and it would work the same
17:07BrandonWi have a couple smaller projects i want to use clojure for first, but after that a web site is my primary goal.
17:07kotarakitistoday: well, you have to leave something to the gurus to shine. ;)
17:07tomojI think it's a good idea to wait a while before tackling compojure
17:07BrandonWwhy?
17:07clojurebothttp://clojure.org/rationale
17:08BrandonWin terms of clojure experience? or waiting for the api to be more stable?
17:08tomojwell, I was thinking the former
17:08BrandonWthis is my first foray into functional programming AND in a lisp variant
17:08tomojbut compojure is getting refactored, so the latter is relevant as well
17:09tomojwell, good luck :)
17:09BrandonWi definitely feel like i'm living in flatland trying to comprehend 3 dimensions, sometimes (to rip off carl sagan :))
17:09tomojI seriously watched that video earlier today
17:09somniumflatland is a great book :)
17:10technomancyBrandonW: that would be 4 dimensions then. =)
17:10tomoj(and downloaded cosmos :D)
17:10BrandonWyeah i have cosmos on my netflix. haven't watched it yet though
17:10alexykhmm -- my manual clojure repl starter doesn't load the user.clj in the current dir. Is it the job of the clojure.main?
17:10BrandonWjust rented contact and watched that again. that movie is very different from when you were like 13, to when you're 25... haha
17:11hiredmanalexyk: is . on your classpath?
17:11hiredmanuser.clj is loaded from the classpath
17:11alexykhiredman: qed, thx
17:14BrandonWokay so i still don't quite understand faux-curry from programming clojure, if anyone wants to take a stab at helping me before i go home :D
17:15BrandonW(defn faux-curry [& args] (apply partial partial args))
17:15avarusdo you have to?
17:15BrandonWis the only reason to apply the partial function to itself, so that you end up with something that needs to be evaluated twice in order to obtain the result at the end?
17:16BrandonWno, but it seems like one of the things that if you don't understand it, it limits your power within the functional paradigm
17:16BrandonWand i like having power :D
17:16avarusok :)
17:16alexykhmm: I had in my user.clj, (set! *print-length* 42), and upon launch, repl fails with: Can't change/establish root binding of: *print-length* with set. But I can do it once the repl is up manually. ?
17:16somniumBrandonW: theres always monad tutorials :)
17:16BrandonWyeah i'll wait a bit on those :)
17:17BrandonWstuart halloway does frequent this channel, right?
17:18BrandonWthat would be pretty cool, being explained a concept from the book by its author, heh
17:19tomoj(faux-curry + 1) == (apply partial partial [+ 1]) == (partial partial + 1)
17:20tomoj((faux-curry + 1) 2) == ((partial partial + 1) 2) == (partial + 1 2)
17:20tomoj(((faux-curry + 1) 2) 3) == ((partial + 1 2) 3) == (+ 1 2 3) == 6
17:21tomojguess it's clearer with just (faux-curry +)
17:23tomojbut yeah, you end up with something that when called returns something that when called returns the answer
17:24tomojas opposed to (defn faux-curry [& args] (apply partial args)) where you can just do ((faux-curry + 1) 2) and get the answer with one call
17:24hiredmantomoj: that is partial
17:24tomojI don't remember that from the book.. seems strange
17:25tomojyep
17:25arohneralexyk: you can only set! bindings when you're already inside a binding for that var
17:25arohnerthe repl sets up bindings for *print-length* and a few other things
17:26arohneruser.clj gets loaded "outside" of the repl, so it doesn't work
17:26alexykarohner: so why can I do that one the repl shows me the prompt, but not from user.clj? am I doomed to manually do that?
17:27arohnerthe repl code looks like
17:27arohner(binding [*print-length* ...] (do-repl))
17:27arohnerwhen you require from the repl, you're inside do-repl
17:27arohneri.e. inside the binding for print-length
17:28alexykarohner: (set! *print-lengtn* 42) works fine in repl though
17:28arohnerright
17:28arohneryou can set! a var, if you're inside a binding
17:28alexykso when does clojure.main read user.clj?
17:28arohnernot inside the repl
17:28alexykpity
17:29alexykis the purpose of user.clj to serve the repl, or any old clojure launch?
17:30arohnerhow are you starting clojure?
17:30tomojuser.clj has a purpose?
17:30alexykarohner: java ... clojure.main
17:30alexyktomoj: yeah, it's like .clojurerc
17:31tomojyou put it in your home directory?
17:31alexyktomoj: on the classpath
17:31tomojoh, crazy, for adding stuff to the repl?
17:31tomojI was thinking earlier I wanted to auto-require repl-utils
17:31alexykbut, it just let me down, in terms of the crucial failure to set print-length to prevent Britannica from being shoved into my screen
17:32alexyklast time rlwrap consumed it for 10 hours
17:33alexykbut I wonder how can we hack the repl to run stuff form inside
17:33alexykautomatically
17:33alexykarohner: is there any other way to start a repl? aside from swank or something?
17:34arohner(clojure.main/repl)
17:34arohneryou can even
17:34arohner(binding [*print-length* 42] (clojure.main/repl))
17:35arohnerthat probably won't work if you're connecting over swank
17:36alexykarohner: so I'd put it into a file, myrepl.clj? what's the full command line then?
17:37alexykjava ...clojure on classpath... clojure.main myrepl.clj # ?
17:37arohneralexyk: yup
17:37alexykso if not given a file, clojure.main starts repl itself?
17:37arohneralexyk: (doc clojure.main/main)
17:38alexyk,(doc clojure.main/main)
17:38clojurebot"([& args]); Usage: java -cp clojure.jar clojure.main [init-opt*] [main-opt] [arg*] With no options or args, runs an interactive Read-Eval-Print Loop init options: -i, --init path Load a file or resource -e, --eval string Evaluate expressions in string; print non-nil values main options: -r, --repl Run a repl path Run a script from from a file or resource - Run a script from standard input -h, -?, --help Print this help me
17:38alexykaha
17:38arohneralexyk: it's longer than clojurebot will print, and looks better formatted correctly ;-)
17:38alexykarohner: somehow I feel more energized to read it along with 222 other people :)
17:38alexykand clojurebot
17:39alexykdamn, 4 escaped
17:39arohneroh, another option would be to eval (require 'myuser.clj)
17:40arohnerit looks like eval'ing gets run inside the repl
17:41alexykarohner: that's good, no need to modify launchers
17:41alexykstick stuff into user.clj and user-eval.clj
17:42arohneryou're not using the --init option, are you?
17:42arohnerI think that does (require 'foo) for you
17:42alexykarohner: how does it know to bind before, but eval after, repl-in'? no --init, never heard of it
17:42arohnerclojure.main --init foo file.clj
17:42alexykbut I can
17:42alexykinit is ok
17:43arohnerif you specify a file and no --repl, it runs the file and quits
17:45arohnerman, it seems like slime-repl has an n^2 loop somewhere
17:45arohnerfinding parenthesis or something, but it gets sluggish after awhile
17:47technomancyarohner: there's a clear-output command
17:47technomancybut I haven't noticed it myself
17:48arohnertechnomancy: I'm running an old, funky version. maybe it's been fixed already
17:49arohnerhah: Warning (undo): Buffer `*slime-repl clojure*' undo info was 33180469 bytes long.
17:49arohnerThe undo info was discarded because it exceeded `undo-outer-limit'.
17:49arohnerthere's your problem
17:49arohnertechnomancy: thanks
17:58duncanmis there an easy way to queue up agents so that i don't have too many concurrent agents running at the same time?
18:00hiredmanduncanm: send uses a fixed-sized threadpool, so it will only run 2+cores actions
18:01duncanmhiredman: what about send-off?
18:01hiredmansend-off is an open pool, it grows as needed
18:04duncanmhiredman: i have a big grid of tiles, and these tiles show up one by one - right now, there's loop that looks out for these tile, and for each tile, it fires off some agents looking for adjacent tiles, and stalls when the adjacent tiles are not available (yet)
18:04duncanmhiredman: so that seems to be a reasonable design; but the issue is, right now i want to run it on a grid where all the tiles are already there - i don't want all the agents to go crazy all at once (is that a problem?)
18:07hiredmanthe looking for tiles part sounds like a canidate for send-off, and the other stuff you do (once the tile is found?) maybe for send
18:09duncanmhiredman: http://gist.github.com/296362 - i think you saw this yesterday already
18:09duncanmhiredman: the looking and calculating stuff is all in one step
18:10hiredman*shrug*
18:10duncanmalso, i feel kinda guilty using a map with [x y z] keys instead of something more specific
18:11duncanmin fact, a sorted-map
18:12duncanmhiredman: oh! i can just wrap the 'really-calculate-offset' part in another agent....
18:12hiredmanyou could thread it through a few sends and send-offs to the same agent
18:12duncanm (not (false? tile)) (send (agent "calculating...") really-calculate-offset file (:file tile) direction)
18:12duncanmhmm
18:12duncanmahh
18:12hiredmansort of CPS with agents
18:13duncanmright
18:13hiredman*agent* is bound to the current agent in an executing action
18:14duncanmi'm only using send-off because of the Thread/sleep
18:14duncanmchecking if the tile exists doesn't involve IO, because i have an in-memory set for all the known files
18:14duncanma ref to a set
18:15duncanmhiredman: i fear that i'm over-engineering - the problem itself doesn't actually have much concurrency to it
18:17hiredmanyou could use future and hydra :D
18:17duncanmwhat's hydra?
18:17duncanmi should look into using future
18:17AWizzArd,(find-doc "hydra")
18:17clojurebotnil
18:18hiredman~hydra
18:18clojurebotIt's greek to me.
18:18hiredmanclojurebot: worthless
18:18clojurebotGabh mo leithscéal?
18:19hiredmanhttp://github.com/hiredman/Repl/blob/master/src/hiredman/hydra.clj
18:19duncanmhmm, what's the difference between future and agent?
18:20hiredmana future is one shot, you cannot send an action to it
18:20duncanmand futures are run off a finite threadpool?
18:20hiredmanhydra is a linkedblocking queue that when deref'ed gives you a lazy seq of the items placed in the queue
18:21hiredmanbasically it is a sort of shared message bus
18:21hiredmanduncanm: futures use the same threadpool as send-off
18:21hiredman(so yes)
18:21duncanmso it's not finite, right? it grows as needed?
18:21hiredmanuh
18:22hiredmanwhat is the difference?
18:22duncanm18:00 <hiredman> duncanm: send uses a fixed-sized threadpool, so it will only run 2+cores actions
18:22duncanmeither way
18:22hiredmanRepl uses hydra and ends up with 23 threads blocking waiting for stuff at startup
18:23duncanmi should probably try it and see if it thrashes my machine before thinking about all this
18:23hiredmanduncanm: the send threadpool is bounded, the send-off is not
18:23duncanmand you're saying future's threadpool is not bounded?
18:24hiredman"the send threadpool is bounded, the send-off is not" + "futures use the same threadpool as send-off" = "future's threadpool is not bounded"
18:24duncanmhiredman: agreed
20:02kmurph79is anyone using textmate? the clojure bundle doesn't autoformat correctly
20:19avarushi kmurph79
20:19avaruswhich bundle are you using?
20:19avarusI know two, but I don't like both
20:19avarusfor me the parens highlighting doesn't work
20:19avarussucks incredibly
20:19kmurph79avarus: nullstyle's
20:20kmurph79i guess we should go to emacs?
20:20avarushttp://github.com/stephenroller/clojure-tmbundle <-- at least this works
20:20avarusya, I guess :(
20:21avarusI tried aquamacs...seems easy but is a pita as well if you want to do more :P
20:21kmurph79the bundle code is pretty scary, not sure how to fix it
20:21avarushehe
20:22avarusand it's old, not updated since 2 years or so
20:22kmurph79i've used carbon emacs with success previously
20:23kmurph79textmate is just so much easier
20:23avarusthere is a lisp bundle on the svn server at macro* but I haven't tried it yet
20:23avaruslooks old, probably sucks as well .P
20:24tomojavarus: it's a pita because emacs is difficult to learn?
20:25avarusbecause I never used emacs before
20:25avarusI don't know if it's hard to learn
20:25avarusnever tried to
20:25tomojah
20:25tomojit is, I think :)
20:25jasappit's not hard to learn the basics
20:25tomojif I say "it's worth it" I guess it won't mean much because I'm just another emacs zombie
20:26tomojsure, type a key to have that character show up on the screen?
20:26jasappyeah, I'm just an emacs zombie too
20:26tomojarrow keys and mouse work too, so
20:26jasappavarus: do you use screen?
20:26avaruson my server I do, not on my workstation
20:26tomojI never used textmate for clojure so I dunno what features feel missing for an emacs noob
20:27jasappthink of emacs as a version of screen that's actually a text editor
20:27avarustomoj: imagine clojure or lisp code without parens being highlighted
20:28avarusnot being matched
20:28tomojhard for me to imagine clojure or lisp code without parens
20:28avarusjust horror
20:28tomojoh, I see what you mean
20:28tomojbut, what feels missing in emacs I mean?
20:28tomoji.e. what makes you want to use textmate instead
20:29kmurph79textmate beats emacs for 90% of my actions, but emacs has a bunch of crazy stuff
20:29tomojI guess general editor stuff feels easier
20:29tomojhmm
20:29jasappcan you evaluate clojure code with a command in textmate?
20:29avaruseh yes, I want to use textmate because it's idiot-proof
20:29tomojI highly doubt textmate could beat emacs for 90% of your actions if your actions include typing clojure code
20:29kmurph79tomoj: probably not
20:29tomojlooks like they have a hacked up repl
20:29jasappahh
20:29tomojruns in screen in the background
20:30avarusthat would not even be a requirement for me :)
20:30avarusjust proper highlighting would be enough :>
20:30tomojit should be, imo
20:30avarusna, i have my scripts
20:30tomojyou have scripts which amount to a repl in-editor?
20:30avarusand when I want the repl, I can start it :)
20:31tomojeh, maybe someday you'll understand :P
20:31tomojor like I said maybe I am just a zombie
20:31avaruswhat do you mean?
20:31tomojI mean I could not imagine using textmate for clojure even if it had highlighting
20:31tomoj(and parens matching)
20:32avarusI have no special requirements for things like that :)
20:33blbrown_win,(+ 1 1)
20:33clojurebot2
20:34tomojhuh, waitaminute
20:34blbrown_win,(.replaceAll " x " "x" "y")
20:34clojurebot" y "
20:34tomojM-. just opened up core.clj for me
20:34blbrown_win,(.replaceAll " x " "\\w+" "y")
20:34clojurebot" y "
20:34blbrown_win,(.replaceAll " x " "\\w+" "y")
20:34clojurebot" y "
20:34blbrown_win,(.replaceAll " x " "\\w" "y")
20:34clojurebot" y "
20:34blbrown_win,(.replaceAll " x " "\w" "y")
20:34clojurebotUnsupported escape character: \w
20:35jasappI love M-.
20:35tomojguess it only works for clojure.jar?
20:35blbrown_win,(.replaceAll " x " "\\s" "y")
20:35clojurebot"yxy"
20:35tomojI thought it didn't work for jars at all
20:36jasappI found out about it a month or two ago, and it's opened jars since then.
20:36jasappI think
20:36tomojhuh, appears to work for any clojure jars, yeah
20:36tomojsomeone told me the other day it only worked for .cljs on the classpath
20:37tomojanyway, that's a good example I think. point at a function and press M-. and you jump to the function's definition
20:37tomojcmd-t in textmate is pretty cool, but
21:11avarusgood night
21:11avarus*megayawn
21:52AWizzArd~max people
21:52clojurebotmax people is 245
22:12BrandonWis anyone here familiar with the partial function vs currying?
22:13BrandonWi feel that i might have an obsession with understanding this... haha
22:14hiredman,((partial (partial + 1) 2) 3)
22:14clojurebot6
22:15BrandonWright, in Programming Clojure, it defines a faux-curry as (apply partial partial args)
22:16hiredmanI doubt it
22:16BrandonW(defn faux-curry [& args] (apply partial partial args))
22:16hiredmanwhat page?
22:16BrandonW145
22:16BrandonWon the text version
22:17BrandonWat the bottom
22:17BrandonWLazier than lazy, soon after the gray box titled 'Faces of def'
22:18hiredmanthat is dumb
22:18BrandonWi see that the partial function is extremely close to faux-curry, but i don't understand what the significance of faux-curry is, if you have to add an extra set of parens to force it to eval
22:18hiredmanBrandonW: you don't
22:19BrandonWis there a better implementation of curry out there that doesn't require the extra eval?
22:19hiredman,(letfn [(faux-curry [& args] (apply partial partial args))] (faux-curry +))
22:19clojurebot#<core$partial__5034$fn__5036 clojure.core$partial__5034$fn__5036@16c426b>
22:19hiredmanBrandonW: you can't really curry in clojure because functions can (and often do) have variable arity
22:20hiredman,(letfn [(faux-curry [& args] (apply partial partial args))] ((faux-curry +) 1))
22:20clojurebot#<core$partial__5034$fn__5036 clojure.core$partial__5034$fn__5036@83dcf8>
22:20hiredman,(letfn [(faux-curry [& args] (apply partial partial args))] (((faux-curry +) 1) 2))
22:20clojurebot3
22:21hiredmanthat is not really currying because + can a variable number of args, so there is no way to tell when you finished applying
22:21BrandonWright
22:21BrandonWso if it was real currying, would it work exactly the same way as partial already does?
22:21BrandonWexcept that once it knew all args were satisfied, it would evaluate the result?
22:21hiredmanyes
22:22BrandonWi don't understand what the point of faux-curry is then
22:22BrandonWit seems to complexify the partial method for a reason i don't understand
22:22BrandonWerr partial function :D
22:23hiredmanBrandonW: partial takes a function and at least one argument
22:23hiredmanyou can't partially apply a function to nothing
22:24hiredmanpartial results in a function that has been partial applied, faux-curry will result in a function that can be partially applied to one argument
22:24hiredmanbut yes, I think faux-curry is dumb
22:25hiredman,(pl (↕map (replicate 3 (range 3)) call · (⌽map inc)))
22:25clojurebot((1 2 3) (1 2 3) (1 2 3))
22:25danlarkinclojurebot dsl scares me
22:25johannhIs there a map-accum (like Haskell's) anywhere in clojure-contrib? I can't seem to find it.
22:26hiredmanjohannh: what does map-accum do?
22:26johannhIt threads state through a map. Like scan, if that helps. Half-map, half reduce.
22:27hiredmanexample input and output?
22:31johannh(map-accum (fn [acc x] [(assoc acc x) (acc x)]) #{} '(:a :b :b :c :d :c)) -> (nil nil :b nil nil :c)
22:31johannhIt takes a function that takes a state and and value, and returns a new-state and a new-value.
22:32johannhGiven an initial-state and a list, it threads that state through the items in the list, collecting the values as it goes.
22:32hiredman#{} is a set
22:32hiredmanassoc won't work
22:32johannhShoots. conj. I keep forgetting. Is that right?
22:33hiredmanhow is that different from a reduce?
22:33hiredmanconj will work sure,
22:33hiredmanor a fold?
22:34johannhOh, sorry. The result should be [final-accum new-list], so [#{:a :b :c :d} (nil nil :b nil nil :c)]
22:34johannhWell, it's a reduce on the accumulating parameter, but like a map on the input.
22:35johannhReduce/fold takes a seq and returns a single item. Map takes a seq and returns another seq.
22:35johannhIn any case, sounds like I might as well implement my own.
22:35hiredmanhmm
22:39johannhAnother example: (map-accum (fn [sum x] [(+ sum x) (* x sum)]) 0 '(1 2 3)) -> [6 '(0 2 9)]
22:39hiredman,(reduce (fn [{:keys [accum result]} x] {:accum (conj accum x) :result (accum x result (conj result x))}) {:accum #{} :result []} [:a :b :b :c :d :c])
22:39clojurebotjava.lang.IllegalArgumentException: Wrong number of args passed to: PersistentHashSet
22:39hiredmangah
22:39hiredmanteaches me to be clever
22:40hiredman,(reduce (fn [{:keys [accum result]} x] {:accum (conj accum x) :result (conj result (accum x))}) {:accum #{} :result []} [:a :b :b :c :d :c])
22:40clojurebot{:accum #{:a :c :b :d}, :result [nil nil :b nil nil :c]}
22:42hiredman,((comp (juxt :accum :result) reduce) (fn [{:keys [accum result]} x] {:accum (conj accum x) :result (conj result (accum x))}) {:accum #{} :result []} [:a :b :b :c :d :c])
22:42clojurebot[#{:a :c :b :d} [nil nil :b nil nil :c]]
22:43johannhThe context is that I'm trying to unmarshall a vector of values. As I go, I want to thread a map of id->refs through, so if I run into a reference to a ref that I've seen before, I can insert the same reference.
22:44hiredmanwhy not reduce into a map of ids to refs?
22:46johannhBecause I want to return the vector of unmarshalled-refs, not just the ref lookup map.
22:46johannhI think that's the first time I actually saw a use of juxt.
22:47hiredmanwell, it's new
22:55johannhThat's a nice example, thanks. How does the (fn [{:keys [accum result]} x ..) work. I feel like I've seen that before, but it's not syntax I'm familiar with.
22:56johannhAh, found it in the destructuring docs. I should remember that.
22:58wilignewbie question: why is this false? (contains? [:user :password :email] :user)
22:58hiredman,(doc contains?)
22:58clojurebot"([coll key]); Returns true if key is present in the given collection, otherwise returns false. Note that for numerically indexed collections like vectors and Java arrays, this tests if the numeric key is within the range of indexes. 'contains?' operates constant or logarithmic time; it will not perform a linear search for a value. See also 'some'."
22:58hiredmangood?
22:59wiligah, ok.
23:03somniumjohannh: theres the state monad in c.c.monads, which sounds exactly like the haskell fn you describe
23:03somniumthough a reduce or loop is more common in clojure
23:06johannhI don't think the state monad is quite it. Monads go from M a -> (a -> M b) -> M b, so if the monad were just keeping around state, you'd have to provide some extra rule to accumulate the state.
23:08johannhMaybe I don't understand the state monad well, but I figured it would be going from [state x] -> (x -> [state' y]) -> [state'' y'], where the monady-bit would be responsible for combining state and state' into the final result.
23:09johannhHere, my basic function is state -> x -> [state' y], which is different.
23:10somniumthats the basic signature of it as Ive read (I cant really claim to understand them)
23:14somniumyes, so in m-bind (?) you decide what to do with y, so you can use an accumulator between do forms (sorry if my vocabulary is imprecise, I barely know haskell or monads)
23:15somniumin any case in c.c.monads theres an example with an accumulator iirc
23:16johannhEh, I don't know them well myself, but I just re-read the ever-useful Typeclassopedia a few days ago, while wrestling with this same problem. It just feels like there should be a monad answer, but I couldn't find it.
23:18johannhI went through a short Haskell kick about this time last year, while in a haze of baby-related sleep deprivation. Memory's fuzzy.
23:21somniumah then reduce or loop will probably be much easier since theres not so much 'stateful' behavior
23:24somnium,(require clojure.contrib.monads)
23:24clojurebotjava.lang.ClassNotFoundException: clojure.contrib.monads
23:25somnium,(use 'clojure.contrib.monads)
23:25clojurebotjava.lang.IllegalStateException: write already refers to: #'clojure.contrib.pprint/write in namespace: sandbox
23:27somnium,(require '[clojure.contrib.monads :as m])
23:27clojurebotnil
23:27somnium,(doc m/state-m)
23:27clojurebot"; Monad describing stateful computations. The monadic values have the structure (fn [old-state] [result new-state])."
23:28somniumjohannh: is that the signature or am I misunderstanding (quite probable)
23:33johannhHm. It's not quite it. Really, I have (fn [input old-state] [result new-state]); the result depends on a input, not just the state.
23:36somniumah, I see
23:36johannhAh, okay. I get it. The state monad would work.
23:37johannhIt would just have to be (fn [input] (fn [old-state] [result new-state])); it's a partial-application.
23:37somniumprobably I would use loop here to be honest :) I just happened to find the state-monad useful in practice last week
23:38somnium,(doc m/state-t)
23:38clojurebot"([m]); Monad transformer that transforms a monad m into a monad of stateful computations that have the base monad type as their result."
23:39somniumthis thing too, but Ive drawn the line at transformers thus far :)
23:40somniumhth
23:41johannhWell, for now map-accum will solve my problem, so I think I'll stick with that, but if things get hairier, I can look deeper into the state monad.
23:41johannhI don't know if that helped, but it was fun, so thanks.
23:44somnium:)