#clojure logs

2011-09-09

00:25nickmbaileyso I have a function in namespaceA that gets a string that represents a function in namespaceB, how do I convert that to the var representing the function in namespaceB so I can call it?
00:30brehaut(resolve (symbol "prn"))
00:31nickmbaileyyeah i'm having trouble with prefixing the symbol with namespaceB
00:31nickmbaileyand then resolving
00:32brehaut,(symbol "hello" "world")
00:32clojurebothello/world
00:32nickmbaileyaha
00:32brehautwhat are you trying to achieve?
00:33nickmbaileyone compojure route to call any of the functions in a specific namespace
00:34brehauthiredman has a thing you want to look at. give me a moment
00:36brehautnickmbailey: unfortunately hiredmans github is giant and i cant remember what its called
00:37nickmbaileyhehe, well that worked, i'll look around on his github
00:37nickmbaileythanks :)
00:38brehautyeah. i wouldnt be surprised if theres a some security concerns about taking a string from the wide web and resolving it on a NS
00:39brehautnickmbailey: https://github.com/hiredman/graft
00:39nickmbaileyyeah i'm sure that sentence makes someone cringe
00:42nickmbaileyalthough it could only be resolved on that specific namespace, and anything in there is fine to call
00:42nickmbaileymaybe there are other concerns though
00:42brehauti dont know enough about the mechanics of resolution and namespaces to be not afraid
00:44nickmbaileyperhaps I should ask on the mailing list
00:44brehauthave a look at graft
00:45brehautyou might glean some tricks out of there too
00:47nickmbaileyyeah i'm merging the body of the request and the url params to pass as the function args so I don't think I can use it directly but good to learn from
00:49brehautpersonally i prefer just making a map of strings to fns
00:49nickmbaileyyeah this is kind of a "wouldn't it be cool if ..."
00:50brehaut(or clojure.lang.Named if you wish)
00:50brehautgo nuts then ;)
00:50lrennnickmbailey: also https://github.com/flatland/wakeful
00:51nickmbaileylrenn: cool
00:51nickmbaileyhave some code browsing to do
03:30pyris repl-utils available in new contrib ?
05:28simonjI think something is misconfigured with my slime setup - probably something noobish.
05:28simonjI can never see any locals in sldb
05:28simonjhttps://gist.github.com/1205835
05:31raeksimonj: unfortunately, this is the way it is with "valilla" slime in clojure. you need to hook up a debugger like swank-cdt to get the locals.
05:31raekwhen swank catches the exception, the stack is already unwound and the locals are gone
05:32simonjraek: ah ok. Do you think swank-cdt or swank-clojure 1.4.0 snapshot is the way to go? I seem to remember reading that it's included in that.
05:33raeksimonj: you can also use swank.core/break to pause the program at a certain point. there you can access the locals of the lexical scope of the break form
05:34raeksimonj: sorry, I don't know about which version is recommended nowadays
05:34simonjraek: fair enough. Thanks for your help.
05:35cees_Currently I'm also trying to hook up a debugger to clojure.
05:36cees_In the past swank/break worked fine for me. But now it fails.
05:37cees_For some reason it prints the prompt and then falls through te reader (does not stop)
05:37cees_Now using the debugger-code from "Joy of clojure". Similar approach and similar failure.
05:38cees_Anyone having any similar experience (or even better: a solution?)
05:39simonjcees_: sorry, I just tried it and it works here and I'm far too
05:39simonjnew at all of this to be of much help. swank-clojure version maybe?
05:40cees_I skipped swank and started to work at the clojure repl. The hot-swapping of swank sometimes hides your failures/errors.
05:41cees_Starting at a clean repl (lein test) gives a better test.
05:41tsdhamalloy_: Hi
05:41cees_In my experience at least.
06:05tsdhDoes anyone have a deeper understanding of clojure persistence using *print-dup* and can tell me why I gat the error shown at http://pastebin.com/H64WH8gU ?
06:07tsdhHm, doing manually what the reader should do works fine: http://pastebin.com/x5MU1Q0S
06:17ZabaQ1I'm trying to wrap my head round the use of ^
06:18ZabaQIt's suppsed to be (with-meta ..) right?
06:18raekZabaQ: which clojure version?
06:18ZabaQ1.2.1
06:18raekZabaQ: well, not exactly. it attaches metadata to the source code data structure. with-meta attaches metadata to a runtime value
06:19raekso only things that can see the code data structures can see the ^ metadata, e.g. the clojure compiler and macros
06:20raekor ordinary functions, if the piece of code was quoted
06:21raekalso, metadata on vector and map literals is evaluated with the usual evaluation rules.
06:22raek,(set *print-meta* true)
06:22clojurebot#<ArityException clojure.lang.ArityException: Wrong number of args (2) passed to: core$set>
06:22raek,(set! *print-meta* true)
06:22clojurebot#<IllegalStateException java.lang.IllegalStateException: Can't change/establish root binding of: *print-meta* with set>
06:26ZabaQHmm. So I need to be careful what I'm actually setting the metadata of..
06:27ZabaQ^ tends to end up with metadata bound to a symbol at readtime.
06:28clgvcees_: maybe they also changed something in their repl. in CCW the debug-repl/break macro stopped working similarily when they switched their architecture to a client-server-approach with nrepl
06:51tsdhWhy does #=(java.util.Date. 1 2 3) work, but #=(new java.util.Date 1 2 3) errors with "Can't resolve new"?
06:55manutter,(doc new)
06:55clojurebotExcuse me?
06:55manutter*snap*
06:56manutter,(new 'java.util.Date 1 2 3)
06:56clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: (quote java.util.Date), compiling:(NO_SOURCE_PATH:0)>
06:56manutterah well my guess was wrong anyway
06:56tsdh:-)
06:56manuttermaybe the parameter list is ambiguous?
06:57manutterClojure will say "can't resolve" if there are two or more possible constructors
06:57manutterlike if there were a Date(int, int, int) and a Date(long, long, long)
06:58tsdhmanutter: But #=(new java.util.Date) errors in the same way.
06:59manutterhm, yeah, if it were ambiguous constructors I'd expect (java.util.Date. 1 2 3) to fail in the same way
06:59tsdhMaybe it's some security thing, so that one isn't able to create arbitrary objects when reading strings?
06:59manutterthat one seems less likely to me
06:59tsdhMe, too...
07:01tsdhArgh. That's what you get when trying to fiddle together some stand-alone, minimal example for another error...
07:02manutter,(new java.util.Date 1 2 3)
07:02clojurebot#<Date Sun Mar 03 00:00:00 PST 1901>
07:02manutteroh
07:02manutterlol
07:07CozeyHello. I have a function named 'send', which replaces the built in send function; i get a warning about this. What should be done here? Disable the warning somehow (with metadata), or change my function to some other name? What's the better approach in a methodological sense?
07:08tsdh,(new (Class/forName "java.util.Date") 1 2 3)
07:08clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: (Class/forName "java.util.Date"), compiling:(NO_SOURCE_PATH:0)>
07:08clgvmanutter: you only have to quote if you want to provide just the symbol and not the resolved value
07:09clgvin your case you want to provide the Class and not the Symbol
07:09manutterindeed
07:09manutterin tsdh's case, actually :)
07:09manutterI was just testing whether new took a quoted symbol instead of a class
07:10tsdhmanutter, clgv: Class/forName doesn't return the class?
07:10manutter,(new ( . Class/forName "java.util.Date") 1 2 3)
07:10clojurebot#<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: (. Class/forName "java.util.Date"), compiling:(NO_SOURCE_PATH:0)>
07:10manutterinteresting
07:10manutter,(Class/forName "java.util.Date")
07:10clojurebotjava.util.Date
07:11clgvCozey: you can use (refer-clojure :exclude [send]) then the warning is gone for that file. but you will get it again if you want to include it in another file wwith use. refer will avoid this
07:11manuttertsdh, ##(new java.util.Date 1 2 3) works as is, did you see that?
07:11lazybot⇒ #<Date Sun Mar 03 00:00:00 PST 1901>
07:11clgv,(type (Class/forName "java.util.Date"))
07:11clojurebotjava.lang.Class
07:11Cozeyclgv: i will require it anyway, the solution is good, thanks!
07:12clgvtsdh: the problem is that you actually get an instance of the class Class. you cant call new with it. but it has a createInstance method
07:12manutterI really shouldn't try to debug before my first coffee....
07:13clgv&(use '[clojure.contrib.repl-utils :only [show]])
07:13lazybotjava.io.FileNotFoundException: Could not locate clojure/contrib/repl_utils__init.class or clojure/contrib/repl_utils.clj on classpath:
07:13clgv,(use '[clojure.contrib.repl-utils :only [show]])
07:13clojurebot#<RuntimeException java.lang.RuntimeException: java.io.FileNotFoundException: Could not locate clojure/contrib/repl_utils__init.class or clojure/contrib/repl_utils.clj on classpath: >
07:13manutter,(.createInstance (Class/forName "java.util.Date") 1 2 3)
07:13clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: createInstance for class java.lang.Class>
07:13manutter,(-> (Class/forName "java.util.date) (.createInstance 1 2 3))
07:13clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading string>
07:13clgvmanutter: newInstance it is
07:14manutterah
07:14clgv&(.newInstance (Class/forName "java.util.Date"))
07:14lazybot⇒ #<Date Fri Sep 09 04:15:30 PDT 2011>
07:14manutter&(.newInstance (Class/forName "java.util.Date") 1 2 3)
07:14lazybotjava.lang.IllegalArgumentException: No matching method found: newInstance for class java.lang.Class
07:14clgvmanutter: if you want to pass parameters you have to get the appropriate constructor in advance
07:14manutteroh, that's interesting
07:15clgvvia getConstructor
07:15manutterI haven't played with interop stuff that much before
07:15clgvthats not interop, thats reflection ;)
07:15manutterpersonally I'd just stick with ##(new java.util.Date 1 2 3)
07:15lazybot⇒ #<Date Sun Mar 03 00:00:00 PST 1901>
07:15manutterwell, I mean calling Java constructs from clj
07:15clgvindeed. stick to that^^
07:16clgvyou are not just calling java stuff - you are doin java reflection with the above.
07:16clgvin most cases you wont need java reflection for java interop
07:17clgv(new java.util.Date 1 2 3) or in short (java.util.Date. 1 2 3) is fine
07:17manutteryeah, I'm just messing around to see what I can find out about tsdh's situation anyway.
07:17clgveven shorter if you use (:import java.util.Date) in your ns-statement
07:17manutterhe said he was getting an error when he tried to call (new java.util.Date 1 2 3)
07:18tsdhclgv, manutter: I'm just trying to create some self-contained example for some other error when trying to read my own objects, so don't expect that code to make any sense. ;-)
07:19tsdhclgv: .newInstance has the same problem with the reader
07:19manutterI haven't had my coffee yet, I EXPECT stuff not to make sense.
07:19tsdh,(.newInstance (Class/forName "java.util.Date"))
07:19clojurebot#<Date Fri Sep 09 04:20:28 PDT 2011>
07:19tsdh,#=(.newInstance (Class/forName "java.util.Date"))
07:19clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
07:19clgvreading own deftypes/defrecords back in via read-string does not work with clojure 1.2.1
07:19tsdh,(binding [*read-eval*] #=(.newInstance (Class/forName "java.util.Date")))
07:19clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
07:19clgvthere are posts about that afaik
07:19tsdh,(binding [*read-eval* true] #=(.newInstance (Class/forName "java.util.Date")))
07:19clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
07:20tsdhclgv: I use 1.3 with plain Java objects.
07:20clgvhummm well. maybe you found a bug - it's called beta for a reason ;)
07:20tsdhclgv: And *print-dup* magick as amalloy_ demonstrates in one of his posts.
07:21tsdhI'll ask on the list...
07:22clgvcan I somehow typehint int[][] for deftype?
07:32ilyakclgv: ^objects?
07:32ilyakand inside of that ^ints?
07:32ilyakor how is that
07:33clgvno that wont work. it's pretty different. there should be literally "int[][]" in deftype class.
07:37tsdhShouldn't (.foo o) be the same as (. o foo)?
07:38tsdhHm, actually it's (. (identity o) foo)...
07:39raek,(binding [*read-eval* true] (read-string "#=(.newInstance (Class/forName \"java.util.Date\"))"))
07:39clojurebot#<RuntimeException java.lang.RuntimeException: Can't resolve .newInstance>
07:40tsdh,(. java.util.Date newInstance)
07:40clojurebot#<CompilerException java.lang.RuntimeException: java.lang.NoSuchFieldException: newInstance, compiling:(NO_SOURCE_PATH:0)>
07:40clgv,(binding [*read-eval* true] (read-string "#=(.newInstance ^Class (Class/forName \"java.util.Date\"))"))
07:40clojurebot#<RuntimeException java.lang.RuntimeException: Can't resolve .newInstance>
07:40tsdh,(. (identity java.util.Date) newInstance)
07:40clojurebot#<Date Fri Sep 09 04:41:47 PDT 2011>
07:40raekclgv: IIRC, you can use raw descriptors as type hints in the form of strings. the descriptor of int[][] is "[[I". could you try ^"[[I" ?
07:40clgvraek: I'll try.
07:42tsdh,#=(identical? java.util.Date (identity java.util.Date))
07:42clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EvalReader not allowed when *read-eval* is false.>
07:42tsdhHm, ok. Here it's actually false...
07:47clgvraek: no, ^"[[I" did not work within deftype to get int[][]
08:30mattmitchellAnyone know of a good example showing how to use catch/throw/finally in clojure?
08:30pyr,(try (Exception. "foo") (catch (Exception e (println "caught: " e))))
08:30clojurebotpyr: I don't understand.
08:31pyrsorry
08:31pyr,(try (throw (Exception. "foo")) (catch Exception e (println "caught: " e)))
08:31clojurebotpyr: Gabh mo leithscéal?
08:31clgvmattmitchell: analoguous to java with the following template: (try (do-something-that-might-throw) (catch Exception e (print-stack-trace e) (throw e)))
08:32mattmitchellOK great, how about custom error classes?
08:33clgvmattmitchell: if you need them you probably have to create them via gen-class or write them in java directly
08:33mattmitchellI see. So is there a better way to catch specific kinds of errors other than create new classes?
08:35JulioBarros340 484 2300
08:35clgvmattmitchell: depends on what exactly you do
08:35Fossithere's a lispier condition handling somewhere
08:35raekmattmitchell: https://github.com/scgilardi/slingshot
08:35clgvI used plain Exception in the cases where I could not easily avoid using an Exception
08:36raekyou can catch java exceptions with catch, but there is no convenient way of creating new exception classes in clojure
08:36Fossiis slingshot the new contrib/condition?
08:37Fossior are they seperate concepts?
08:37raekI think they are separate
08:37raekand slingshot is maintained
08:37raekI really hope something like this gets into the core of clojure
08:38clgvraek: +1. it would be great if there was an agreement on one standard error-handling for most of the cases
08:39raekthe classical lisp problem: things like these are not technical problems in lisps, but social problems
09:44bartjI am using clojure.contrib.prxml to print xml
09:44bartjbut it is not pretty
09:44bartjie. it is not formatted properly
09:44bartj<a>blah</a><a>xyz</a>
09:45bartjam unable to find any option to pretty print it
09:53bartjanyone ?
09:56megalomanbartj: I wrote an xml printer that tabs things out.
09:57megalomanLet me try and dig it up.
10:00cees_It is easy to pretty-print (indent) with prxml.
10:02cees_bartj and megloman : use (binding [*prxml-indent* 5] (prxml .... ) )
10:02megalomancees_: Cool
10:03megalomanbartj: You could also try this. http://pastebin.com/f8ghWakr I wrote it when I was just starting clojure, so it's not very lazy, but it might work for you. :)
10:04cees_Does anyone know a good method to check the type of an object? I currently use (= (str (type x)) "class xyz")
10:04cees_This, works but there should be a shorter way to write my preconditions :-)
10:09megalomanWould this be a good place for a macro: (defmacro classis [x classstring] `(= (str (type ~x) !classstring)
10:10megalomanWould this be a good place for a macro: (defmacro classis [x classstring] `(= (str (type ~x)) ~classstring))
10:10megalomanI screwed up the parens earlier :)
10:11raekmegaloman: you don't need a macro here
10:11joegallocees_: is there a reason you can't just use the literal class there?
10:11joegallo,(= (type "foo") String)
10:11clojurebottrue
10:11raek(defn classis [x classstring] (= (str (class x)) classstring))
10:11joegallo,(= (type (java.util.Date.) java.util.Date)
10:11clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
10:11joegallo,(= (type (java.util.Date.)) java.util.Date)
10:11clojurebottrue
10:12joegalloalso, a problem with using = and type there is that you aren't accounting for subclasses, which might be something you'd like to do.
10:13raek,(instance? (java.util.Date.) java.util.Date)
10:13clojurebot#<ClassCastException java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.Class>
10:13raek,(instance? java.util.Date (java.util.Date.))
10:13clojurebottrue
10:13megaloman(= (type (java.util.Date.)) java.lang.Object)
10:13raekI always get the ordering of that wrong...
10:13megaloman,(= (type (java.util.Date.)) java.lang.Object)
10:13clojurebotfalse
10:15cees_joegallo. This works for java-classes. However, if I do a defrecord in clojure this trick does not work anymore.
10:15bhenry,(instance? java.lang.Object (java.util.Date.))
10:15clojurebottrue
10:15megalomanbeat me to it bhenry.
10:15megalomanThat's useful.
10:16cees_joegallo, sorry for the confusion. It works fine.
10:16megalomanIs there a function like (implements? Comparable (...))
10:17cees_joegallo, thanks.
10:19bartjcees_: that worked! thanks!
10:19bartjmegaloman: thanks as well
10:20joegallonp
10:20megaloman,(implements? java.lang.Comparable (java.math.BigDecimal.))
10:20clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: implements? in this context, compiling:(NO_SOURCE_PATH:0)>
10:20megaloman,(instance? java.lang.Comparable (java.math.BigDecimal.))
10:20clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching ctor found for class java.math.BigDecimal, compiling:(NO_SOURCE_PATH:0)>
10:21megaloman,(instance? java.lang.Comparable (java.math.BigInteger.))
10:21clojurebot#<CompilerException java.lang.IllegalArgumentException: No matching ctor found for class java.math.BigInteger, compiling:(NO_SOURCE_PATH:0)>
10:21megaloman,(instance? java.lang.Comparable (java.lang.String.))
10:21clojurebottrue
10:22megaloman:bartj, good luck.
10:25TimMc$findfn java.lang.Comparable (java.lang.String.)
10:25lazybot[clojure.core/with-out-str]
10:25TimMcHa! Oh, lazybot...
10:26TimMc,(doc with-out-str)
10:26clojurebot"([& body]); Evaluates exprs in a context in which *out* is bound to a fresh StringWriter. Returns the string created by any nested printing calls."
10:26TimMcOh, I invoked it wrong.
10:26TimMc$findfn java.lang.Comparable (java.lang.String.) true
10:27lazybot[clojure.core/instance? clojure.core/not= clojure.core/distinct? clojure.core/not-any? clojure.core/every?]
12:11Bronsahttp://sprunge.us/DiRF
12:11Bronsawhy isn't this working?
12:12Bronsaif i am doing it wrong, how to access namespaces of a project within lein repl or from slime?
12:15hiredmanBronsa: you need to load the namespace before you can use it, via use or require
12:16VinzentBronsa, from slime: compile ns with C-c C-k, then C-c M-p RET
12:16Bronsathanks both
12:54mindbender1Please I need a recommendation of the most logical introduction to clojure. Something straight to the point. I already have a number of them which tend to drool on certain topics
12:55mindbender1I figured some are just better at teaching things than others so I'll like to reap from your experiences
12:56mindbender1:)
12:56dnolenmindbender1: are you familiar with another functional programming language?
12:57mindbender1no
12:58mindbender1but I introduced myself to lisp some years ago so it wouldn't be hard to grasp advanced concepts
12:58mindbender1really I need something straight to the point not for beginners
12:59chousermindbender1: Have you considered 4clojure or koans?
12:59dnolenmindbender1: have you looked at The Joy of Clojure?
13:01mindbender1dnolen: I once did but that was when I was still trying to evaluate which resource to followlet me give it another look
13:06chousermindbender1: If you skip the first 3 or 4 chapters of JoC, I would be surprised if you found the rest to proceed too slowly.
13:07chouserthat said, choosing problems from 4clojure.com that you find intersting can be a great way to drive learning at whatever pace you desire.
13:12mindbender1chouser: thanks I'm loking at it now and hope it will soon start telling me how to solve real world problems with clojure
13:13mindbender1I also considering looking at noir tutorials cos that's basically what I want to do with clojure... web development
13:13mwillhiteI haven't seen 4clojure, pretty cool…going through the koans was quite helpful at first as well…
13:14chousermindbender1: JoC will not move you directly toward the goal of creating a web app
13:14mindbender1you know..
13:15mindbender1it's more fundamental
13:15chouserI would hope it would help you do a better job once you get there, but for more direct movement toward a web app, perhaps Clojure in Action or yes some web tutorial.
13:16mindbender1then as you solving the web tutorial and some concept seem hard to grasp then we can fallback on
13:16mindbender1you know..
13:16mindbender1that's how I like to learn
13:17mindbender1so if you are surfing and come across anything realistically practical it'd be nice to send them this way
13:18dnolenmindbender1: https://github.com/mmcgrana/ring/wiki
13:18mindbender1I would even prefer an opensource project I can be looking at if you know of any
13:19dnolenmindbender1: most web dev stuff for Clojure is built on top of Ring.
13:19technomancyclojuresphere is a nice new oss clojure web app
13:19mindbender1dnolen: thanks for sending that across
13:20mindbender1I prefer these fields for learning something I can be looking at applying to business
13:22mindbender1I'd even like if some guru can open a channel like clojure for business
13:23mindbender1where they share experiences applying clojure to the trade
13:23mindbender1WDYT
13:24chouserwould that happen more in some other channel than it already does here?
13:25hiredmanyeah, I fail to see the point
13:26hiredmanis "clojure for business" some how not clojure?
13:26chouserhiredman: but you prefer point-free, right? so that's ok then.
13:26hiredman:)
13:26chousersorry. failed to resist.
13:27mindbender1I think we also have clojure for education and hobbyist
13:27hiredmanwhat is the difference?
13:27mindbender1you don't know?
13:28mindbender1One set just want to have an understanding while the other wants to amke money
13:28hiredmanmindbender1: do people often ask you questions that they know the answer to?
13:28mindbender1*make
13:28mindbender1sorry about that
13:28mindbender1more like pun
13:28dnolenmindbender1: business is usually about solving problems. Clojure is designed for problem solving. Hobbyists and academics also like to solve problems too. No need for separate channels.
13:29mindbender1dnolen: I think you are probably right maybe I was over exaggerating the diff
13:30hiredmanright, clojure is a tool, home depot doesn't divide up tools into "tools used for hobbies/tools used to make money"
13:30mindbender1:-D
13:30hiredmanbut there are tools of varying quality and power
13:30mindbender1and there are application of tools
13:31hiredmanyou don't drive a nail differently for a pet project vs. for work
13:31hiredmanit may be the case you have a higher quality tool if you are doing it for work, but not always
13:32mindbender1why is the a difference between community support and professional support
13:32mindbender1or a need for it
13:33hiredmanfor example I once helped a carpenter earthquake retrofit an old house, I dunno if he got paid for it, I certainly didn't so it might fall under "hobby" for me, but I used his tools (like a palm nailer) which were definitely professional
13:34mindbender1but the owners of the house where certainly not holding you responsible
13:34mindbender1even with your tools
13:34hiredmanwhat do you mean?
13:35chousermindbender1: entirely apart from IRC channels, would you be interested in hiring the services of a personal Clojure trainer?
13:35mindbender1as in you were helping not in charge
13:35hiredmanmindbender1: you want a channel for pointy haired bosses who have to mange clojure programmers?
13:36mindbender1Certainly..it will ease of a lot of the burdens of learning
13:36mindbender1on my own
13:36mindbender1hiredman:it's still clojure discussion
13:37hiredmanmindbender1: so that is a yes?
13:37TimMcI would imagine professional support to even include such things as "contribute a patch to fix this long-standing bug that is affecting our code".
13:37jorgebis there something equivalent to the (time) macro that does NOT return the value of expr?
13:37TimMcNo, wait, I take that back -- I'm conflating that opinion witha nother one.
13:37chouserTimMc: I think that kind of full-team consulting work is available from Clojure/core
13:37mindbender1;-)
13:37hiredman(time (do … nil))
13:37Bronsajorgeb: (do (time expr) nil) ?
13:37hiredmanmindbender1: I'm just going to /ignore you then
13:38jorgebBronsa: thanks
13:38mindbender1why?
13:38clojurebotwhy not?
13:38mindbender1why not why?
13:41TimMcmindbender1: Looks like a combination of poorly explicated desires on your part and crustiness on hiredman's part.
13:41TimMc(Not precisely the adjective I wanted, but it will do.)
13:42TimMcmindbender1: I agree that there is a real distinction between different support levels, but hobbyist/professional is not quite it.
13:43TimMcIn my mind, the proper distinction is the time investment required from the supporters.
13:43mindbender1TimMc: all parties are equally essential
13:43user317so i implemened an interface via reify
13:43user317but when i pass it to some java code, i get a java.lang.ClassCastException
13:43redingermindbender1: Can I interest you in Clojure training? :)
13:43TimMcheh
13:43mindbender1just that I'm saying that interests differ
13:44TimMcuser317: gist a stripped down testcase, maybe someone can spot something
13:44user317i think, at least i cant tell where that exception is occuring
13:44hiredmanuser317: the exception should tell you problem, class x cannot be cast to class y
13:44mindbender1redinger:And how would negotiations start
13:45user317hiredman: how do i get more out of the error, right now thats the only thing thats printed in repl
13:45mindbender1I'm serious
13:45redingerYou simply sign up for the official Clojure/core training in November
13:45sauaweird, I'm trying to install leiningen on windows, but I kept getting classpath errors unless I edited this line "set CLASSPATH="%CLASSPATH%";%LEIN_USER_PLUGINS%;%LEIN_PLUGINS%;test;src" to "set CLASSPATH="%CLASSPATH%";%LEIN_JAR%;%LEIN_USER_PLUGINS%;%LEIN_PLUGINS%;test;src" any idea why it's not including the jar?
13:45saua(difference being, i added %LEIN_JAR%)
13:45mindbender1A detail of objectives would be a selling point
13:46hiredmanuser317: (.printStackTrace *e) ; and get a better repl
13:47chouserredinger: Is that training for hobbiests or professionals?
13:47redingerchouser: Yes
13:47mindbender1redinger: what's the location of the training.. any web info?
13:47redingermindbender1: http://clojure-conj.org/training
13:48hiredmanI have clojurebot sitting in our work irc channel (different instance of clojurebot) does that make clojurebot professional clojure code?
13:49user317here is my implementation https://gist.github.com/1206861
13:50hiredmanyou have two interfaces there, maybe you need a third
13:51hiredmanthe other possiblity is one of your methods is returning an object that cannot be cast to the correct return type
13:52hiredman^- professional opinion
13:54user317hiredman: well, here is their sample implemetnation https://gist.github.com/1206876 it only implements the two, but one extends the other
13:55hiredmanuser317: so either the return type thing I mentioned, or the java code you hand it off to is trying to cast it to something else
13:56`fogusHi all.
13:59user317hiredman: all the methods return void
14:00hiredmanuser317: well?
14:01user317hiredman: total java newb, so i may be missing something obvious, could returning something when the return type is void cause a crash?
14:01hiredmanuser317: have you looked at the stacktrace?
14:02jlihiredman: he said the exception was all that was printed at the repl. user317: try throwing it in a file for a better error
14:03user317hiredman, jli, https://gist.github.com/1206899
14:03jlioh ho
14:03user317the last chunk is the one that actually caused it, right?
14:04jliuser317: are you hooking into the interactive brokers api?
14:04jlijust curious :)
14:05user317jli, yea, it sucks :), i have a half baked haskell wrapper for their posix api's, i thought i might use what they recommend and learn clojure
14:06jlia couple of years ago I used the Erlang java interop stuff - it was actually pretty smooth
14:09hiredman at ibclj.core$get_hist_data.invoke(core.clj:105)
14:09hiredmanis the function and line number
14:10user317hiredman: yea, that one is pretty simple
14:11user317hiredman: https://gist.github.com/1206924
14:13choffsteinAnyone use clj-doc-test?
14:14user317well, i've got an idea that kind of sucks, i can use their sample implementation as a proxy
14:15upwardindexWhat is missing in 4clojure is a way to sort problems by the difference with the best code golf score
14:31kzarI'm really stuck on this problem http://4clojure.com/problem/79 , didn't want to ask for help but I'm fully bamboozled. Anyway don't tell me the answer but could anyone show me how to make a list of the paths? I can see how to make a tree structure of the paths something like [3 [[2 [[1 nil] [2 nil]]] [4 [[9 nil] [3 nil]]]]] but I can't figure out how to make a flat one like [[3 2 1] [3 2 2] [3 4 9] [3 4 3]]. Getting
14:31kzar the recursion right is warping my brain, keeping it as tail recursion even more so.
14:38gfrlogkzar: I can't really tell what your "flat tree" example is supposed to be. It looks rather rectangular.
14:41kzargfrlog: I probably messed it up, in the puzzle you need to find the shortest path through the triangle. I figured the first step is listing all the paths and that's where I'm stuck. I'm able to get a tree structure of the paths but not a list of each path as a flat vector
14:41gfrlogah ha
14:41gfrlogwelp
14:42kzargfrlog: I can't figure out the recursion because for each iteration you need to cons the current value on to a growing number of lists, but you can't know how many until afterwards let alone what they contain.
14:42kzarI get the feeling I'm thinking about it backwards somehow but I'm stuck
14:43gfrlogthat should be a simple recursive definition:
14:43gfrlogsay you have an arbitrary triangle
14:43gfrlogyou don't know how deep it is
14:44gfrlogall you can get is its first element, a list of paths down the left side, and a list of paths down the right side
14:44gfrloggiven those three things it should be pretty easy to combine them together appropriately, right?
14:45donperignonHello, everybody i am starting with clojure, and i have a very basic question, i have some data structure in this way:
14:45donperignon(("a" "b")("c" "d")("e" "f"))
14:45donperignonin python i used to call zip funciotn to turn into this:
14:45donperignon(("a" "c" "e")("b" "d" "f"))
14:45donperignon
14:45donperignonhow can i make this in clojure?
14:45donperignonthanks in advance and sorry for the silly question.
14:46chouser,(apply map list '((a b) (c d) (e f)))
14:46clojurebot((a c e) (b d f))
14:47chouser,(apply map vector '((a b) (c d) (e f)))
14:47clojurebot([a c e] [b d f])
14:47donperignonthanks chouser, i will try right now
14:47chouser,(map set '(a b) '(c d) '(e f))
14:47clojurebot#<ExecutionException java.util.concurrent.ExecutionException: clojure.lang.ArityException: Wrong number of args (3) passed to: core$set>
14:47chouser,(map hash-set '(a b) '(c d) '(e f))
14:47clojurebot(#{a c e} #{b f d})
14:47chouseretc.
14:48kzargfrlog: Not sure I follow you
14:49gfrlogkzar: lemme put it another way
14:49gfrlogif you had a function that could return the left "subtree" and the right "subtree"
14:49gfrlogmaybe "subtriangle" is clearer
14:49donperignonchouser, that whats perfect
14:49gfrlogand so you could call your function recursively on each side
14:49donperignonyou save a lot of work, thanks
14:49chouserdonperignon: np
14:49gfrlogthen you could combine the two lists
14:50donperignoni still dont get the magic behind some functional tricks
14:50gfrlogkzar: I'm trying not to be TOO explicit since you said "don't tell me the answer"
14:51kzargfrlog: Still don't see how it helps, say we start with that first example on the page. I have 1, left sub tree nad right subtree. I can do [1 [left-subtree right-subtree]], follow it down recursively to get a tree of the paths. But that's what I can already see how to do.
14:52kzarWhen you don't know what's in left-subtree how can you cons 1 on to each path within it?
14:52gfrlogkzar: your left subtree would look like [[2] [5 1] [2 3 4]], right?
14:58kzargfrlog: Oh right, I was thinking more [[2 [[5 [[2 nil] [3 nil]]] [[1 [[3 nil] [[4 nil]]]]]]]] again I might have messed that up
14:58gfrlogkzar: of course if you care about the efficiency of the algorithm, this isn't the way to go
14:59gfrlogbut it will certainly work for the sake of passing the exercise
15:01upwardindexWhy can't I (apply do [1 2 3])?
15:01upwardindexHowever I can (do 1 2 3)
15:01kzargfrlog: Hmm OK that's a good hint anyway cheers. I'll have more of a think over it
15:02jolyupwardindex: do is a special form, so it can't be treated like a normal function
15:03upwardindexjoly: So I have to (defn mydo [& rest] (apply do rest)) and then do what I want?
15:04upwardindexlol
15:04upwardindexnvm
15:04jolyupwardindex: it means you can't pass do to apply like you could a normal function
15:04upwardindexI'm thinking in circles
15:04gfrlogupwardindex: what're you trying to accomplish?
15:05upwardindexgfrlog: Trying to beat 4clojure 19 in 7 characters ;)
15:05upwardindex"apply do"
15:09chouserupwardindex: what's the record?
15:09chouserI just did it in 15 chars
15:10upwardindexchouser: I find it really hard to see the record for problems where the spread is more than 25 because of the histograms implementation
15:10chouser14
15:11chouserthere are histograms?
15:11chouserah, found it.
15:11upwardindexit seems to be around 10
15:11upwardindexbut could be 9 or 11
15:12gfrlog&(count "(comp first reverse)")
15:12lazybot⇒ 20
15:22mindbender1please someone advice me on this error when slime-connect to vagrant:
15:23mindbender1Connecting to Swank on port 2222.. [2 times]
15:23mindbender1Entering debugger... [2 times]
15:23mindbender1Lisp connection closed unexpectedly: connection broken by remote peer
15:23user317java.lang.reflect.InvocationTargetException, what does that mean?
15:24dnolenmindbender1: are you just trying to play around w/ Clojure? If so I recommend this, https://github.com/arthuredelstein/clooj
15:25mindbender1no serious work
15:25dnolenmindbender1: double-click
15:25gfrloguser317: what are you doing when it happens?
15:25dnolenmindbender1: just click the downloads button and you'll see the latest executable.
15:26mindbender1ok I'll try that out
15:26user317gfrlog: trying to create a java class, but i pass a reifyied implementation of an interface to it
15:27mindbender1dnolen: does it work with lein
15:28gfrloguser317: hrm :/ I don't know much about that, sorry. I'd just fiddle with it to try to figure out what part is killing it. You can also implement an interface using deftype, if that helps with fiddling.
15:29dnolenmindbender1: yes
15:30upwardindexIs #(do %2) the shortest way to return the second argument?
15:31gfrlogupwardindex: only works if there are exactly two args
15:32hiredman,(comp second list)
15:32clojurebot#<core$comp$fn__3786 clojure.core$comp$fn__3786@240de4>
15:32hiredman#(second %&)
15:32gfrlogI doubt there's anything shorter though
15:33hiredman,#((vec %&) 0)
15:33clojurebot#<sandbox$eval6514$fn__6515 sandbox$eval6514$fn__6515@5e66cc>
15:33hiredman,(#((vec %&) 0) (range 10))
15:33clojurebot(0 1 2 3 4 ...)
15:33hiredmanhmmm
15:33hiredman,(#((vec %&) 1) (range 10))
15:33clojurebot#<IndexOutOfBoundsException java.lang.IndexOutOfBoundsException>
15:34hiredman,(apply #((vec %&) 1) (range 10))
15:34clojurebot1
15:34hiredman,(count "#((vec %&) 1)")
15:34clojurebot13
15:34hiredman,(count "(comp second list)")
15:34clojurebot18
15:34hiredman,(count "#(second %&)")
15:34clojurebot12
15:35gfrlog,(count "(fn[&[a b]]b)")
15:35clojurebot13
15:35hiredman,(count "#((vec %&)1)")
15:35clojurebot12
15:35chouserooh, #(second %&) is nice
15:36chouser#(peek(vec %)) was my closest
15:36chouseroh, that's something else. nm.
15:37hiredmanI've used (comp type first list) a lot as a dispatch for multimethods
15:39sjlDoes 4clojure's code golf counter strip whitespace automatically or something?
15:39sjlAh, apparently so. Neat.
15:39user317:e#
15:40tufflax,(count "#(fnext %&)")
15:40clojurebot11
15:45upwardindexHow can I apply and to a sequence?
15:46dakrone,(reduce 'and [true true 0 1 false])
15:46clojurebotfalse
15:46dakronelike that
15:48chousernope
15:48chouser,(reduce 'and [true true true true])
15:48clojurebottrue
15:48chouserha!
15:48user317ha, i was passing an integer where a String was expected
15:48chouserwhat?
15:48clojurebotwhat is moustache
15:49chouser,(reduce 'and [false true true true])
15:49clojurebottrue
15:49TimMcWHAT
15:49chouserthere we go
15:49TimMcAh, much better.
15:50upwardindexRespect to the black wizard that did 4clojure 19 in 10 chars!
15:50TimMcFor a bit there I thought there was some magic there I didn't know about.
15:50upwardindexI can't seem to go under 13 chars
15:51chouserupwardindex: (reduce #(and %1 %2) ...) or (every? identity ...)
15:51chouser(reduce 'and ...) doesn't do what you want
15:51dakronechouser: you are correct, my mistake
15:52tufflaxupwardindex it can be done in 8 ;)
15:52upwardindextufflax: WHAAAAAAT *bows down*
15:52tufflaxas amalloy_ told us someone did
15:54hiredmanit just takes a lot of tries to do it in 8
15:54TimMcI can get the first two tests in just 5. :-P
15:54upwardindextufflax: Ah sweet just did it in 9
15:55tufflaxupwardindex really? it's pretty good if it works every time
15:55upwardindextufflax: yup i can pm the solution if you want to verify
15:55tufflaxhm, hold on a bit
15:55tufflaxill try myself
15:57jolyhow many characters for a program that outputs all 8-character Clojure snippets? ;)
15:58gfrlog,(count "(comp {1 5 5 3 \"b\" \"d\"} first)")
15:58clojurebot30
15:58gfrlogI beat all of you
16:02upwardindexI want a list of clojure.core functions sorted by length :P
16:02tufflaxeasy to do i think
16:02TimMchiredman: Oh no... I got it. That's terrible.
16:03dpritchetti did the first 20something problems on 4clojure today
16:04dpritchettand then i got to the one where i was supposed to return the first N fibonacci numbers with an inline function (no defs!) and my stack overflowed and i had to take a break
16:04upwardindexhiredman, TimMc: Is it tailored to the test set or would it work with a more thorough test bench?
16:04dpritchettis it really helping me to do all of this within a single set of parens?
16:05TimMcupwardindex: I don't think I can answer your question as stated. What I can say is that it's not a good solution.
16:05upwardindexTimMc: Would it work with more tests that are different from the 3 that are there?
16:06TimMcmaybe?
16:07TimMcOK, so I got an honest solution in 13 chars.
16:07upwardindexlol, can't wait to find that nasty solution
16:07upwardindexTimMc: honestly, the 9 char solution is pretty legit
16:07TimMcI cheated (in a way) to find the nasty one.
16:09hiredmandpritchett: letfn
16:09dpritchettthanks hiredman
16:09dpritchettnow i can get back to it without feeling like i need to write entire solutions in a single sexp
16:10hiredmanletfn is a sexp
16:10hiredmanas is let
16:11dpritchetti like a REPL where i submit more than once while building a solution
16:11dpritchettnot to say i won't wind up with a tiny golfed solution eventually
16:11dpritchettbut it'd be nice to be able to define helper functions and compose them as i go along
16:11dpritchettrather than doing it all in a big bang
16:11hiredman,((fn x [i] (lazy-seq (when-not (zero? i) (cons i (x (dec i)))))) 10)
16:11clojurebot(10 9 8 7 6 ...)
16:12hiredman,(((fn [x] (partial x x)) (fn [x i] (lazy-seq (when-not (zero? i) (cons i (x x (dec i))))))) 10) ; if you want to get classical
16:12clojurebot(10 9 8 7 6 ...)
16:12jolyI went the helper function and composition route. It made piecing together solutions for some of the graph problems a lot easier
16:14gfrlogif the expression doesn't start with three opening parens it's not real lisp.
16:14dpritchettso how do you define your helpers? a bunch of letfns at the beginning of your expression?
16:14jolyyes, I used letfn to define a number of functions
16:14jolyit's definitely not a winning approach for code golf, but it allowed some interesting solutions
16:14hiredmanletfn is nice, I'd really like to get the compiler to lift letfn's that qualify out into static methods
16:15hiredmanhint hint if anyone is interested in a compiler project
16:28dpritchetthow can i replace the values in a seq via map?
16:29dpritchettsay i was reimplementing count and i tried to map everything to a 1 and then reduce with +
16:29dpritchettfor some reason i couldnt figure out how to directly replace with a literal one so i made a helper function (fn [n] 1) instead
16:29joegallo(map (constantly 1) values)
16:30dpritchettthanks
16:30hiredman(for [x y] 1)
16:30TimMcnice
16:31TimMchiredman: (for[x y]1) :-P
16:31TimMcIf spaces count...
16:32dpritchettcan you show me an example of (for [x y] 1)?
16:32dpritchettdoesnt do anything for me
16:32joegallo,(for [x [1 2 3]) 1)
16:32clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )>
16:32TimMcdpritchett: bind y
16:32joegallo,(for [x [1 2 3] 1)
16:32clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Unmatched delimiter: )>
16:33joegallothird time's the charm
16:33joegallo,(for [x [1 2 3]] 1)
16:33clojurebot(1 1 1)
16:33joegallowahoo!
16:33dpritchettthanks
16:34sauaIf I have a sequence like this: [1 2 3 4 5] how would I best be able to permutate it to this [[1 2] [2 3] [3 4][4 5]] ?
16:35TimMc,(map (fn [x] (*)) [1 2 3 4])
16:35clojurebot(1 1 1 1)
16:35TimMcsaua: partition-all
16:35TimMcor maybe just partition
16:35hiredman,(doc partition-all)
16:35clojurebot"([n coll] [n step coll]); Returns a lazy sequence of lists like partition, but may include partitions with fewer than n items at the end."
16:35sauaty
16:36TimMcYeah, you don't want -all here.
17:25Bronsahttp://sprunge.us/dWUR
17:25Bronsawhy isnt this working?
17:28Bronsabut if i write it manually without using a macro it works
17:29Bronsaperharps there is something wrong with the evaluation time
17:31tufflaxwhich one tarcieri
17:31tarcieri28
17:31tarcieriI'd like to do it with arity overloading
17:31tarcierimaybe that's because I haven't yet purged all the Erlang out of my system
17:33joegalloBronsa: if you type those forms at the repl in exactly the order you gave in your paste, it doesn't compile. you are referring to x before x was defined.
17:33tarcieriif I were writing Erlang, each time I encountered a nested seq I'd make a recursive call to the flatten function, but one that took the flattened-list-in-progress in addition to the one I was trying to flatten
17:33tarcieriI don't know how to do that in Clojure
17:33tarcieriwell I do
17:33tarcieribut not without a named function
17:34tufflaxyou can name an fn (fn name [] ...)
17:34tarcieriohai nathanmarz
17:34tarcieriyeah so
17:34tarcieriI can actually call it that way?
17:34tufflaxyes
17:34tarcieriI thought I tried that and it didn't work
17:35Bronsajoegallo: you're right, i had x defined before
17:35Bronsaanyway, i just found out the problem
17:35Bronsawhat i want is (str x ~y) not ~(str x y)
17:36tarcieriif I'm iterating and want to build an in-order list, what's more idiomatic: build the list in reverse order then reverse it at the end, or build a vector in-order then convert it to a list when I'm done?
17:37hiredmantarcieri: vector
17:37tarcieriok
17:48tarcieriugh, well I solved it
17:48tarcierithis is ooglaaay
17:48tarcierilol
17:48tarcierihttp://4clojure.com/share/code
17:48tarcieriblah
17:48tarcierihttps://gist.github.com/1207424
17:49tarcierithat was the first one I really struggled with
17:49tufflaxwow that's a lot of code
17:49tarcieriyeah
17:49tarcieriI suppose the loop is unnecessary
17:51tarcierihttps://gist.github.com/1207431
17:52tufflaxyeah that's a little better ;)
17:52tarcierimarginally
17:52tarcieristill ooglaay
17:56tufflaxtarcieri I think you should try to use higher-level functions; try to avoid let, first and rest.
17:57tarcieriI've still got Erlang on the brain
17:57tufflax(in this case)
17:58tarcieritufflax: about all I can think to use there is a fold
17:58tarcierihaven't even tried to use one in Clojure yet
18:00tufflaxSo try that :p
18:01tarcieriheh, k
18:02tufflaxI'll also try. fold (reduce right?) is not my first pick for this
18:02tarcieriyes
18:02tarcierireduce
18:02tarcieriis what I'm trying
18:06tarcierihttps://gist.github.com/1207458
18:06tarcierithere we go
18:06tarcierithat's marginally better
18:07tufflaxbtw sequential? is what you want for the test
18:07tarcieriaha
18:07tarcieriwas gonna ask about that
18:08tarcierihttps://gist.github.com/1207462
18:09tufflaxtry to do it with map now :p
18:09tarcieriwith map?
18:09tufflaxyes, imo that's simpler
18:09tarcieriI'm confused as to how
18:09tarcierieach iteration can add N elements to the output list
18:10tufflaxat every level you want to do the same thing to every element in the list, right? you want to flatten it. so that's where map comes in
18:11tarcieribut you want to flatten the whole list, not just every element inside of it
18:12tufflaxyes, but if you have a list of flattened lists, what do you do then to make 1 flattened list?
18:12tarcierireduce? :)
18:13tufflaxno
18:13tufflaxconcat
18:13tarcieriorly
18:13TimMcapply concat
18:13tarcieriI was looking for something like that
18:13tarcieriI see
18:14tufflaxI don't know if map is "best" but it's short and simple imo. (the flatten in core is a bit funny, not something i would have come up with)
18:18solussdbronsa: because a macro doesn't evaluate its arguments
18:21tarcieriso
18:22tarcierimap produces a list I want to pass as arguments to concat
18:22tarcierihow do I do that exactly?
18:22tufflax(apply concat (map ...))
18:22tarcieriaha
18:22tufflax(or mapcat)
18:22tarcieri:O
18:22tufflaxmapcat is a shortcut for that
18:24tufflaxbtw in your version with reduce, the vararg thing is totally unnecessary :P
18:24tufflaxor, no, sorry
18:24tufflaxthe way you did it it's not
18:25tarcieriit's kind of how I would do it in Erlang, ported to Clojure
18:26tufflaxdoesn't erlang have map? :p
18:26tarcieriyes, however, I probably wouldn't use map in Erlang for this problem
18:26tarcieriyou don't end up using map in Erlang much
18:26tarcieribecause it has list comprehensions
18:26tufflaxclojure has that too
18:26tufflaxbut map is often useful anyway
18:27tarcieriI wouldn't use list comprehensions in the Erlang version either
18:27tufflaxhow's your map version coming along? :p
18:27tarcieriI'm kinda roadblocked on it
18:27tarcieriI was gonna bust the Erlang version really quick for the lulz
18:28tufflaxthis is what i ended up with when trying to use reduce: http://pastebin.com/38vC2KvZ
18:29tufflaxforgot a paren in the end there :P
18:30tufflaxand forgot to change the call from "flatt" :P
18:32TimMcI feel kind of bad leaving my debugger paused in the middle of execution overnight.
18:33tufflaxhah, you made me think of this http://steve-yegge.blogspot.com/2007/01/pinocchio-problem.html
18:33tufflaxTimMc
18:36tarcierilater
20:26user317how come i dont always see the prints
20:29Beta-83Hello! :)
22:09chewbrancablist
22:10chewbrancabah wrong window :/
23:38sridis anyone hosting apps on heroku with cron/background-tasks and yet manage to keep the costs low? (for just cron, 24x7 workers seem silly)