#clojure logs

2013-08-21

00:01amalloycallen: (doall #(future ...)) throws an exception for any ... :P
00:05fberniervalidating and converting a string into a number is harder than I thought...
00:05sinistersnarefbernier: no regex?
00:11fbernier... makes sense I guess :)
00:11sinistersnarefbernier: what?
00:11fbernierthanks for the idea
00:12sinistersnaregreat!
00:25TEttingerfbernier, ##(map #(when-let [num (re-find #"\d+" %)] (read-string num)) ["argh" "11" "a1 steak sauce"]) not sure what validate means here
00:25lazybot⇒ (nil 11 1)
00:26TEttingerfbernier, if you only want pure numbers, no letter allowed, ##(map #(when-let [num (re-find #"^\d+$" %)] (read-string num)) ["argh" "11" "a1 steak sauce"])
00:26lazybot⇒ (nil 11 nil)
00:28callenamalloy: I wasn't typing to type it accurately.
00:28callenanyway, I'm experimenting with a medium weight based implementation and one using core.async now.
00:44amacdougallTEttinger: I'll give it a shot! Wonder if it'll pause execution?
01:12ozzloywhat about 1e5
01:12ozzloythat's a number
01:13ozzloyan integer even
01:51ddellacostais there a way to use limit for a query using the SQL dsl in clojure.java.jdbc? That is, if I'm using sql/select, how do I add a limit clause?
01:56callenddellacosta: looking at the query syntax, I see two plausible places for a :limit 10 type dilly to go. Did you try both?
01:58ddellacostacallen: well, from what I can tell, all of the clause-type options are provided as functions within the sql namespace. I did try passing in a hashmap like (java.clojure.jdbc.sql/select [:some_col] :some_table {:limit 1}) which is not supported (obviously, when you look it up), and I searched for a limit function, and there is none. So I'm falling back on just using the normal way of specifying the query, as a
01:58ddellacostastring, although it's not ideal.
01:59ddellacostacallen: but, did I miss something? Not sure if what I tried falls within the two options you were thinking of.
02:00callendrop the { and } around :limit 1
02:00callensee what it does.
02:00ddellacostalemme give that a shot
02:01ddellacostaNope, just ignores it. Bummer: => (s/select [:some_col] :some_table :limit 1) ; ("SELECT some_col FROM some_table")
02:01ddellacostaheh
02:03ddellacostacallen: honestly, I think it's just not supported by the SQL dsl--the select function is pretty straightforward, and ends at "order-by" more or less. No alternative options seem to get parsed. I suppose I could stuff it into a string and pretend it is the where-clause, perhaps, but I should probably just submit a patch. But it's low priority, and very easy to get around with clojure.java.jdbc (why I'm using it).
02:04ryanfit looks like it just doesn't support limit clauses
02:04callenthere's no way it's that limited.
02:04ryanfyeah
02:04callenno. that would be insane.
02:04ryanfthe code is pretty clear
02:04callenI refuse to believe cjj is that misconceived.
02:04callenddellacosta: while I'm poking around the code, try moving the :limit 1 outside of the select to the query section.
02:04ddellacostacallen: I mean, let's be clear--I'm just talking about the dsl
02:04callenI get that just fine.
02:04ddellacostacallen: ah, okay--I wasn't trying that, let me give it a shot
02:04ryanfhttps://github.com/clojure/java.jdbc/blob/master/src/main/clojure/clojure/java/jdbc/sql.clj#L229-265 really doesn't leave any room for extra clauses
02:05ryanfyou can see exactly where each part is coming from, and the interface of the function doesn't have any way to add more to the string part of the query
02:05ryanfoh I guess you could put it in the order-clause position actually, since it lets you pass a string for order
02:06callenthat's...jfc.
02:06callenI really thought they'd fixed all this. ;|
02:06ryanfthat actually wouldn't be that bad if they just documented the order-by param as representing the whole end of the query instead of specifically ordering
02:07ddellacostayah
02:08ddellacostaryanf: yeah, that works. callen, I wasn't able to pass in limit within query (but outside dsl) as a map or in a named arg kinda form either. But ryanf's suggestion is better than what I was doing before. I think this is just not baked in yet.
02:08callenKorma has had limit since forever :|
02:09ddellacostacallen: yeah, but I mean to be fair, this dsl is not trying to solve the same problems as korma--it's much smaller in scope. Part of the point (as I understood it) is that it allows you to get more low-level more easily, but doesn't give you as much magic as korma
02:10callenI'm not sure a DSL that doesn't enable non-hacky limit clauses is really accomplishing being low-level.
02:11callenI understand the objective, but that is...a frightening oversight.
02:12ddellacostacallen: well, I mean, I suspect a lot of people are using the java.clojure.jdbc.sql stuff in a limited fashion. The real power in the lib is in the clojure.java.jdbc namespace. I don't need the dsl to use anything in there.
02:13ddellacosta…which is to say, I suspect if you need a "serious" dsl for SQL, you'll use…Korma. haha
02:15ddellacostahaha
02:15ddellacostaimprecation is not a word I encounter with any frequency. Lovely.
02:15callenddellacosta: what did the Japanese in your recent tweet say?
04:08sontekAre there any good examples of a getting started with web development in clojure?
04:08sontekWant to play with it in my spare time and see if I could make the switch from python
04:18shdwprincesontek: see webnoir.com
04:19shdwprincesontek: after django I was impressed
04:20shdwprinceoh, not webnoir
04:20shdwprincesearch for noir framework
04:20fredyr.org is it
04:21sontekI use Pyramid, so hoping for something a little like that inside of Django like
04:21sontekI'll checkout noir
04:22fredyrthere's also pedestal
04:22fredyrhttp://pedestal.io/
04:23dark_elementsontek, noir is deprecated now. Take a look at compojure or pedestal
05:13mpenetsontek: there is also luminus
05:38noncomhow do i in clojurescript treat javascript'b object "method" as a function?
05:39noncomlike i want to pass it around and then call on a particular instance and with args
06:05augustlnoncom: methods in javascript is pretty easy to do by hand. The only thing that really changes in a method is what "this" is.
07:10dissipateanyone have a recommendation for a good book to learn clojure?
07:10vijaykirandissipate: http://www.clojurebook.com/
07:11NiKo`dissipate: I much enjoyed Clojure Programming from O'Reilly
07:11NiKo`what vijaykiran said
07:11Saturnationhow do you get pprint loaded in emacs nrep-jack-in?
07:12dissipateNiKo`, surely that book is out of date though? doesn't cover clojure 1.5?
07:12SaturnationI know it's something easy, I just keep forgetting it :/
07:13NiKo`dissipate: dunno if it's been updated, though the core concepts aren't changing that much
07:14NiKo`btw do you guys know who's in charge of maintaining clojuredocs.org? seriously needs to cover 1.5
07:15shdwprincedissipate: 1.5 is not much from 1.4. I forgotted to change dep in lein project and programmed for 1.4 for week, but thought it was 1.5.
07:16dissipateNiKo`, that book says it was tested on version 1.4
07:17dissipateshdwprince, i see
07:18shdwprincedissipate: nvm, 1.5 generally brings a bunch of functions, which you can read about on documentation
07:19dissipateshdwprince, how important are those functions for learning clojure?
07:21shdwprincedissipate: it was not important for me
07:22shdwprinceand I can recomment http://java.ociweb.com/mark/clojure/article.html - short and hard introduction to clojure's aspects if you dont wanna read tons of text explaining simple things
07:53calvin91good morning clojure!
08:39ker2xmeep
08:39ordnungswidrigpong
08:43ker2xi'm reading shdwprince's link :)
08:51instilledhi! I'm wondering if it is possible to extend an existing protocol method with additional dispatch methods implementations. I would be grateful if someone could point me into the right direction. Thanks!
08:59dnoleninstilled: extending an implementation of protocol? Not supported though you could probably come up with something that will work for you.
09:03instilleddnolen: i use deftype to extend a protocol and would like to define additional dispatch on some of the functions of that type (protocol or implementation thereof).
09:03freiksenetis that expected behaviour? https://gist.github.com/freiksenet/057398a16478a6c8856d
09:04dnoleninstilled: like i said not directly supported. a deftype can provide one implementation of a protocol fn that's all. You can make this flexible yourself if you like.
09:05instilleddnolen: ok. wasn't sure if I put it clear enough. thanks. could you briefly describe what to do? …I'm quite new to clojure.
09:05noncomwhat is the current recommended AJAX approach for clojurescript?
09:06noncomi assume core.async would do if it were net-capable, but looks like it is not yet, so whats the usual alternatives?
09:06stuartsierrafreiksenet: I believe so, yes. Sequences over mutable collections are not guaranteed to be stable.
09:06noncomcalvin91: good morning, man!
09:07freiksenetclojure docs say "When seq is used on native Java arrays and objects that implement Iterable, the resulting sequence is still immutable and persistent, and will represent a single pass across the data. B"
09:07dnoleninstilled: a component entity design is one possibility I've played around with, but I don't have any more guidance than that.
09:07freiksenetstuartsierra: so in a way it is supposed to be guaranteed
09:08freiksenetI would say array copy is missing in ArraySeq.java if it is to follow the idea of seqs
09:08instilleddnolen: cheers! I'll ponder about it more deeply and see what I can come up with...
09:09stuartsierrafreiksenet: Interesting.
09:10dnolenfreiksenet: it's intentionally missing for performance reasons as far as I can tell, you can clone the array yourself.
09:10freiksenetobviously that would be a major performance hit
09:10freiksenetdnolen: then this should be explicetely mentioned in docs
09:10freiksenetexplicitly*
09:11freiksenetcause currently they are misleading in a sence that they claim persistence of the seq over native arrays
09:11freiksenetalso IMO that is a bad behaviour design-wise as it breaks the contract of the seq interface. You have to worry about implementation if you are to be sure that your seq is immutable
09:12dnolenfreiksenet: performance matters, if you're dealing with primitive arrays you obviously know what you are doing.
09:12freiksenetit's not like you are always in control of your code or that you can easily say that this seq is an arrayseq
09:12freiksenetof all your code*
09:13dnolenfreiksenet: anyways the other choice is equally undesirable without complicating the seq api - aka, seq-mutable, or seq w/ a flag
09:13freiksenetdocumentation should be fixed anyway
09:13stuartsierraIt's definitely an inconsistency with the documented behavior on clojure.org/sequences
09:13dnolenfreiksenet: anyways it's a design choice that balances the desire to work with mutable arrays w/o incurring copy on write.
09:14tbaldridgecouldn't ArraySeq cache array[idx] at each next? Thats what LazySeq on top of an array would do.
09:14dnolenfreiksenet: stuartsierra: I don't disagree the docs are off.
09:14freiksenetI understand)
09:14freiksenettbaldridge: that would mean it will take double the space
09:14tbaldridgeonly if you realized the entire seq
09:14freiksenetat worst case
09:15freiksenetis there a bugtracker for clojure docs?
09:15tbaldridgealthough, if you're doing seq on array do you really care about extreme performance? As long as it isn't O(n)
09:15dnolentbaldridge: you do
09:16dnolentbaldridge: on CLJS at variable arity call sites, we wrap the array in seq
09:16dnolentbaldridge: no copy on write and no traversal overhead critical
09:16stuartsierrafreiksenet: There's no JIRA for clojure.org, but I'll push the issue to those who can fix it.
09:16tbaldridgednolen: I just wonder if I'm already allocating a ArraySeq item for every single array element, what's one more pointer?
09:16freiksenetthanks!
09:17tbaldridgednolen: you have the transversal overhead of allocating ArraySeq
09:17dnolentbaldridge: every variable arity in the core library slows down. When I read through ArraySeq I breathed a sigh of releaf.
09:18dnolentbaldridge: overhead of allocating ArraySeq is very low, it's just a wrapper, traversal is just incrementing an integer
09:18dnolenand another wrapper
09:19tbaldridgeI wonder what the perf impact would be if it was cached on the first get. That way at least doing (first s) several times in a row wouldn't return different values.
09:20tbaldridgethat way there is not transversal cost, only a cost on a get.
09:20freiksenetyou would have a cost of either allocating an full array for that at double space cost
09:21freiksenetor having to allocate buffers or smth like that on time cost every time you have to allocate new/expand
09:21freiksenetIMO in such case it's better to copy
09:30dnolentbaldridge: so with ring buffer drop in - pushing 1 million events in core.async takes about 2.5 seconds under Chrome/Safari. I think this good enough for a good number of applications :)
09:30stuartsierrafreiksenet: I chatted with Rich & Alex Miller: We're going to fix the docs on clojure.org.
09:30tbaldridgednolen: is that with the new dispatch code?
09:31dnolentbaldridge: I left everything else alone, I think my tick idea was misguided. just w/ ring-buffer change that made Chrome 3-3.5X faster
09:31freiksenetstuartsierra: great
09:33cmajor7are there any built in ways to monitor/restart if down threads (i.e. futures)?
09:37dnolentbaldridge: most of my problem was that I didn't really understand how core.async works - that writes will proceed if you use buffers and only dispatch if it can't proceed
09:37tbaldridgednolen: yeah, and I learned something about semantics yesterday as well.
09:37dnolentbaldridge: I finally understand why Rich kept saying we don't need a scheduler, you can express task granularity at the level of buffers
09:38stuartsierra1cmajor7: If you want notification that a thread died because of an exception, you can use Thread/setDefaultUncaughtExceptionHandler.
09:38dnolentbaldridge: the reason I was thrown off was because I was benchmarking and seeing weird behavior w/ large buffer sizes, which is no longer the case
09:39tbaldridgednolen: I'm still not convinced that we need everything in channels.cljs. I'm thinking about using ring buffers inside channels themselves, and then rewriting channels from scratch. We could add "resize" to the ring buffers, and then they'd work just fine for put/take queues
09:39tbaldridgednolen: yes, also "cleanup" is super slow on large buffers, not sure what to do about that
09:39dnolentbaldridge: what is cleanup?
09:40tbaldridgednolen: it pulls out (= (active? val) false) values in the put/take queues.
09:40cmajor7stuartsierra1: thx, let me check it out
09:40tbaldridgednolen: but because we're single threaded, I think we could move that code somewhere else.
09:42stuartsierra1cmajor7: But there's nothing like `monit` for Java threads that I know of.
09:42dnolentbaldridge: ah I hadn't even looked at the other queues in channel beyond buf
09:43dnolentbaldridge: I will say in my benchmarks so far at this point hardly any time seems spent in core.async now - it's all in dispatch
09:43dnolentbaldridge: post ring buffer change
09:43cmajor7stuartsierra1: right, I though maybe there is an elegant way to wrap a "supervisor" around one or two threads..
09:44stuartsierra1cmajor7: Sounds like Erlang ;)
09:45tbaldridgednolen: yeah, that dispatch code still needs some improvement. After testing some of it yesterday, I'm fine with the tick version you had. We may improve it later, but I haven't seen any major issues with it.
09:45dnolentbaldridge: oh cool! yeah it didn't seem to change the semantics in any interesting way - and sliding buffer performance shot way way up
09:46cmajor7stuartsierra1: it does, but I want it to sound like clojure :)
09:57mikerodDoes the map function guarantee the resulting seq is the same order as the colls given?
09:59hyPiRionyes
10:00mikerodhyPiRion: thought that was the case
10:44boblarrickIs there an idiomatic way to tell what iteration of a doseq on a lazy seq you are on?
10:47nDuffboblarrick: there's something in the standard library that emits a lazy sequence of [idx value] pairs, given a sequence.
10:48nDuffboblarrick: ...I don't remember just what it is offhand, though.
10:48boblarrick:)
10:48fredyrmap-indexed
10:48fredyris perhaps what your thinking of
10:48babilenthat still maps a function though
10:49hyPiRionwell, (map vector (range) seq) is probably what you want if you want no manipulation
10:50boblarrickI'm processing lines of a (large) file and want to print out what line i'm on periodically
10:51boblarrickatom seems a bit heavy
10:52ToBeReplacedpicking up some academic books off amazon, looking for some timeless recommendations, and need one recommendation for category theory -- quick picks?
10:52hyPiRion,(doseq [[idx value] (map vector (range) [:a :b :c :d :e :f :g])] (when (even? idx) (prn value)))
10:52clojurebot#<IllegalArgumentException java.lang.IllegalArgumentException: doseq requires an even number of forms in binding vector in sandbox:>
10:55hyPiRion,(doseq [[idx value] (map vector (range) [:a :b :c :d :e :f :g])] (when (even? idx) (prn value)))
10:55clojurebot:a\n:c\n:e\n:g\n
10:55hyPiRionmeh, sneaky whitespace
10:56dnolentbaldridge: pushing 1 millions message down a channel is now takes <1.7 seconds on Chrome
10:57dnolentbaldridge: after staring at the profiles for a long time - dispatch is not the bottleneck, there's a lot of places to optimize the code
10:57boblarrickhyPiRion: thanks!
10:58tbaldridgednolen: that's what I was seeing last night. I was actually seeing high usage of nth in some of my tests. I think we can simplify the channel code and that should help
11:02kralnamaste
11:05dnolentbaldridge: I pushed some type hinting changes and switched = to ==, big difference
11:05tbaldridgenice
11:06dnolentbaldridge: the ioc macros need to type hint terminator argument
11:06dnolentbaldridge: otherwise you're going to needlessly pay for protocol dispatch overhead
11:06tbaldridgednolen: the == ::recur part?
11:06dnolentbaldridge: no any place where the macro inserts calls to impl.protocols/put! take! etc
11:07dnolenyou need to type hint the argument to those
11:07dnolentbaldridge: at that point I think it's just optimizing the body of put! and take! of ManyToManyChannel
11:07dnolen"after that point"
11:08dnolentbaldridge: I suspect we can get pretty close to 1 million messages a second :)
11:09tbaldridgednolen: do we need more besides ^not-native here? https://github.com/clojure/core.async/blob/master/src/main/clojure/cljs/core/async/impl/ioc_helpers.cljs#L41
11:09tbaldridgeor do calls to these functions need type hints?
11:20TimMcI have a namespace in an uberjar that is somehow getting loaded even though nothing :requires it. Might AOT be responsible?
11:24llasramTimMc: What's the namespace? And is it actually getting fully loaded, or just created and having vars interned in it?
11:24llasramTimMc: gen-class classes do load their backing namespace as part of static class initialization
11:25llasramThat's the only obvious thing I can think of for the fully-loaded case
11:26TimMcllasram: There's a namespace "auth" with a defmulti, and a namespace "auth-ldap" with an implementing defmethod.
11:27dnolentbaldridge: oh ok you generate calls to ioc-helpers, ok we don't need more type hints thens
11:27TimMcNothing :requires auth-ldap, but the multimethod dispatch nevertheless contains that entry.
11:27llasramTimMc: Interesting...
11:28TimMcNeedless to say, everything blows up at the REPL.
11:28TimMcI've since fixed the code to put the defmethod in the same ns as the defmulti, but I don't know how it ever worked.
11:28llasramClojure gnomes sneak into your JARs at night, fixing up multimethod dispatch entries while you sleep
11:29TimMc*nod* That makes as much sense as anything else.
11:31TimMchttps://github.com/search?q=%22how+did+this+ever+work%22&amp;type=Code&amp;ref=searchresults
11:32llasramI like that C is the most common language for this lament
11:34hyPiRionor, if you search for "fuck", VimL is the largest one
11:34TimMcIt's a little misleading; there are a ton of duplicates in some languages.
11:36sevvie51 pages of "How did this ever work?"
11:37sevvie... sorted by "Best Match."
11:46TimMcllasram: ...and I can't reproduce it as a SSCCE.
11:48llasramTimMc: Those drive me batty
11:49llasramTimMc: Hmm. Are there any gen-class'd classes at all in uberjar? Maybe there's an expected reference to one of them, which is causing an unexpected chain of transient namespace loads
11:50llasrams,transient,transitive,
11:50TimMcThe main ns is gen-class'd, and there are others.
11:54yediis there a blogpost that depicts the stages of a clojure programmer's journey?
12:00llasramThe journey to Clojure/conj kind of depends on where you live and where the Conj is hosted in a given year. You'll probably need to fly, but other options might be available
12:05amacdougallI hereby mark this answer as "accepted"
12:20noncomkral: namaste
12:24noncomyedi: there were some, but i'm missing links
12:26yedinoncom: sucks, would have loved to read some
12:27noncomyedi: i think that if you google, you gonna find something...
12:27noncombtw, what do you expect for these stages to be?
12:36amacdougallStage 1: http://0.tqn.com/d/animals/1/0/X/7/shutterstock_714240.jpg Stage 2: http://oxun.ge/uploads/posts/2011-02/1297948507_green_lantern.jpg
12:39arrdemlol
12:45upwardindexI'm getting a Compilation error: TypeError: cljs.core.coercive_boolean is undefined on himera when trying to run a doseq, is the problem on my side?
12:45upwardindex,(doseq [x [1 2 3]] 3)
12:45clojurebotnil
12:46dnolenupwardindex: more likely something out of sync in himera
12:47upwardindexdnolen: the reason I'm trying it there is that doses with 4 bindings or more hang my cljs at home
12:48upwardindex3 bindings or less run just fine
12:48upwardindexdoseqs*
12:48dnolenupwardindex: paste please
12:48dnolenupwardindex: and what do you mean hang? hang Rhino? Hang browser? Hang Node.js?
12:49upwardindexbrowser
12:49justin_smiththis was really fun to write: http://sprunge.us/HePW?clojure (generates and prints spiral paths through 2d vectors)
12:49upwardindexI'll make a paste, one sec
12:55upwardindexdnolen: this will hang brepl when trying to compile http://pastebin.ca/2435411
12:56upwardindexas a workaround i split it into 2 doseq and it works
12:59dnolenupwardindex: yeah that generates a lot of code, the compiler seems to handle it find, but Rhino does like it too many locals
12:59dnolenupwardindex: feel free to file a ticket in JIRA
12:59dnolens/does/doesn't
13:00dnolenupwardindex: it's not obvious to me what we can do about that, also would prefer to have a lot more information about it in the ticket
13:01dnolenupwardindex: i.e. does it work under compilation and under which compilation modes
13:05upwardindexIt's very weird, if I paste the doseq in the repl it can evaluate it fine. If I paste the defn containing the doseq, repl hangs
13:08boblarrickI'm trying to use nrepl, but C-<up> isn't doing anything, I have to do M-x nrepl-backward-input. How can I track down why and fix it so C-<up> works?
13:11technomancyboblarrick: why not M-p instead?
13:11llasramboblarrick: Do `M-x describe-key RET`, then hit C-<up> (or M-p) and see what it says it's currently bound to instead
13:11technomancycontrol sequences with non-letters don't translate well over SSH, so it's best to avoid them
13:12llasramOh yeah -- that might be it. I had to tweak Emac's under standing of control characters to make it work for me
13:12llasramEmacs's even
13:15boblarricktechnomancy: M-p works great, thanks
13:25shdwprinceAnyone can offer me a handy vim plugin for dealing with lisp syntax? I know about surround.vim, but it can't, for example, delete contents of braces, or braces with content
13:29Foxboronshdwprince: paredit.vim
13:33rasmustoshdwprince: I would recommend checking out vim-sexp too, its less popular, but is a good middle-ground between paredit and normal vim editing
13:36shdwprinceFoxboron: thanks, its a plugin what I was searching for; rasmusto thanks too, I'll check it out after paredit
13:36gvickersis there anyway to retrieve the namespace loaded after (load-file) is called?
13:39gvickersnevermind, looks like load-file returns the first function in the namespace
13:48dnolenhrm it looks like Closure Compiler changes are going to force us to write a real rewriting pass in ClojureScript
13:49bbloomdnolen: what changes are coming?
13:49bbloomdnolen: also, fuck yes more clojure-level compiler optimizations :-)
13:49dnolenbbloom: Closure used to optimize if expressions where the test would emitted as a function we just invoke
13:50dnolenin Clojure|Script `and` and `or` are macros around `let`
13:50dnolenin expression context `let` is wrapped in `(function() { ... })()`
13:50dnolenwe've been getting a free ride for a long time
13:50dnolenbut it's never been as good as I would have liked
13:50bbloomyeah, they used to hoist that to a top level function?
13:50dnolenyou often have have to move these things around
13:51dnolenbbloom: no they wouldn't hoist to a function
13:51dnolenjust rewrite semantically the same things, a series of ifs
13:51bbloomand they no longer do that, why?
13:51dnolenbbloom: I don't know I sent along an email to list
13:52dnolenbbloom: still it's finicky
13:52bbloomi think we should do this: http://matt.might.net/articles/a-normalization/
13:52dnolenbbloom: you often have to manually lift
13:52bbloomit's a really easy transform, i already did a proof of concept
13:52bbloom& makes analysis much easier
13:52lazybotjava.lang.RuntimeException: Unable to resolve symbol: makes in this context
13:52bbloomer code generation, i mean
13:52dnolenbbloom: I'm ok with anything that is a surgical change around if
13:53bbloomdnolen: tty in a bit
14:06shdwprincedamn, after reading vim koans I smile every time entering the Tim Pope's plugin page
14:12silasdaviswhat is my best option for getting my project root directory when running a clojure project with leiningen
14:19`cbpsilasdavis: you mean like (System/getProperty "user.dir") ?
14:21silasdavisactually I just want to read a file that is below the root of project
14:23justin_smithsilasdavis: current directory will be the directory where you started lein
14:23justin_smithsilasdavis: since lein should be started in the root dir, just give a path under the root dir
14:24justin_smithsilasdavis: but if your code may end up in a library, use io/resource so that you could potentially load the file from a jar without changing your code
14:24justin_smith(or if your code may be packed in a standalone jar or war)
14:25silasdaviscan I use io/resources?
14:36justin_smithyou can use io/resource to load a file from the file system (if it is in your class path), or inside the same jar
14:36justin_smith(slurp (clojure.java.io/resource "project.clj"))
14:37bbloomdnolen: sorry, had a phone call. here's a surgical if transform: https://github.com/brandonbloom/cljs-cps/blob/master/src/cps.clj#L128-L135
14:37`cbpis there any framework for RESTful web services or should I just use any web framework?
14:37justin_smithjust for the heck of it ,(slurp (clojure.java.io/resource "project.clj"))
14:38amacdougall1`cbp, I've just recently got started with Liberator, and I dig it so far.
14:39`cbpamacdougall1: thanks I will try it out
14:39bbloomdnolen: the problem is that it can't be that surgical b/c you can use if inside an expression, like (foo (if x y z)), so you also need to ANF the foo invoke
14:39bbloomdnolen: this applies globally, sadly
14:39amacdougall1I considered using just Compojure and doing the plumbing myself, but Liberator really makes it easy to use only the HTTP features you need, while handling the rest transparently.
14:40`cbpamacdougall1: does it have a lein template?
14:40amacdougall1I just used lein new app and it was fine. Just follow the guide on the site.
14:40bbloomdnolen: but, adding a complete ANF pass will be < 200 lines of code & can probably remove 30-50 lines from the emitter where it has to worry about wrapping things in (function() { })() scope things
14:40bbloomdnolen: makes many optimizations much simpler too
14:41amacdougall1http://clojure-liberator.github.io/liberator/tutorial/getting-started.html — this guide covered 90% of what I needed to get started.
14:42dnolenbbloom: I'm really only concerned about a very small change at this point, unless somebody's offered up to do the ANF stuff, do all the testing, and benchmark compile times :)
14:42dnolenbbloom: I only care about optimizing (if (and ...) ...) and (if (or ...) ...)
14:43bbloomdnolen: any individual transform pass is gonna be cheaper than either the current analyze or codegen
14:43bbloomdnolen: MIGHT speed up the gclosure process a tiny bit too by having fewer functions to analyze, but unlikely to make a large impact
14:43amacdougall1`cbp: the only pitfall I ran into with Liberator was that if you're defining a route with a parameterized resource, such as (GET "/user/:id" [id] (user id)), the argument must have the same name as the path segment. "id", in this case. When you get to the part of the guide, you'll get it.
14:44dnolenbbloom: you missed what I was saying. It's not work I'm interested in doing.
14:44dnolenbbloom: happy for someone else to do all the work.
14:44clojurebotIt's greek to me.
14:44dnolenbbloom: otherwise I'll do the small amount of work that I care about.
14:45bbloomdnolen: ok, well what i'm saying is that the solution to this problem is to do an ANF transform. you can do ONLY :if, which will solve the immediate problem, but doing that mixed in to the analyze or code gen pass is likely to be a bad plan
14:45bbloomjust gonna get complicated fast
14:46dnolenbbloom: not going to touch the analyzer
14:46dnolenbbloom: just the compiler, and I don't care about handling all cases
14:46dnolenbbloom: the only place where Closure Compiler doesn't seem to life is if((function() {})()) { ... }
14:47dnolenand that only important case where I'm annoyed by that is (if (and ...) ...) and (if (or ...) ...)
14:47dnoleneverything else c'est la vie
14:47bbloomdnolen: sure, so you traverse the tree and transform only :if nodes in to ANF, the problem goes away
14:47dnolenbut these two cases are needed by all the persistent data structures and critical code like in core.async.
14:48dnolenbbloom: sure, and I'm happy to take your patch if you got one :)
14:48bbloomdnolen: would you be OK with me adding an AST pass?
14:50dnolenbbloom: I would be OK that, would need to talk over the details - but this Google Closure change has me annoyed enough that I want to put this logic into ClojureScript and not rely on Google Closure for it anymore.
14:50bbloomdnolen: btw, the following ops generate instant-call closures when in expression contexts: throw, do, try, let, loop, letfn
14:51dnolenbbloom: yes, but these are not problematic in my experience. if get it for free OK.
14:52muhoothis feels.... ugly and possibly reinvention of a wheel? https://github.com/kenrestivo/utilza/blob/cea210cdc874ff084e6497c0fe28af0c5e47cf6b/src/utilza/misc.clj#L127
14:52bbloomdnolen: at minimum, the pass would need to walk & no-op all forms except for :let and :if
14:52tbaldridgebbloom: I'd love all of those for core.async (except letfn, who uses that?)
14:52hiredman!
14:52hiredmanletfn is sweet
14:53bbloomtbaldridge: do you manually inline all of your mutually recursive functions? :-)
14:53tbaldridgebbloom: I never write non-polymorphic mutually recursive functions ;-)
14:53bbloomi use letfn occasionally when i have a bunch of auxillary functions that i don't want to heavily parameterize, so i define them in the lexical closure
14:54bbloommakes for very tidy code
14:54tbaldridgebbloom: yeah, I think I've used it for something like that....once :-)
14:54bbloomhttps://github.com/brandonbloom/cleff/blob/master/src/cleff/core.clj#L13-L20
14:54bbloomthat code was HORRIBLE before i made those two little functions
14:54tbaldridgeback on the subject though, gos in core.async use loop, if, etc. optimizing those would be nice
14:54bbloomit's still mildly horrible :-)
14:55bbloomtbaldridge: yup, i think a full ANF makes sense for lots of reasons
14:56dnolenbbloom: tbaldridge: there was one place in core.async CLJS I had to manually lift, the giant case - would be nice to not have to do that naymore.
14:56dnolen"giant case of the state machine"
14:57tbaldridgednolen: yeah, I'm not sure how to fix that with the current compiler. I did a test using letfn once (lol) but it was slower on the JVM, may not be the case in JS
14:57bbloomdnolen: the real issue is that comp/emit is a public API right now & people depend on it
14:58dnolenbbloom: eh, I think people relying too deeply on the internals of ClojureScript know they're hooking into a moving ship.
14:59bbloomdnolen: ok, well i think we should create a public "compile" api call w/ an options map
14:59dnolenbbloom: so something separate from emit which can stay stable?
14:59bbloomyes
14:59dnolenbbloom: good idea
14:59bbloomsimilarly, i think the analyzer needs a proper public API too, but that requires standardizing the AST first
14:59bbloomthat's more important than the analyze call signature
15:00bbloombut a source -> target compile function doesn't need to expose it's internal representations
15:00bbloomdnolen: my proposal is to break the API first, w/o changing anything else, then we can start to add passes & otherwise improve the structuring of the compiler
15:01dnolenbbloom: ok, but let's do this by writing it up, easier to go over the details this way before writing code.
15:02bbloomdnolen: you're the gatekeeper, so let me know how you wanna do this
15:03dnolenbbloom: just start a page on Confluence or use an existing one. I'd like to go piecemeal, so first lets talk about the step 1 - breaking API and how this will enable passes and improvements
15:04bbloomdnolen: you know that i feel that design pages are where progress goes to die :-)
15:06bbloomdnolen: i spend some of my time to write up design notes & in the rare case that somebody actually comments on or improves them, i still then have to go write the code b/c nobody else will…. meanwhile, i'm gonna have to write the code to understand the problem well enough to document it
15:06dnolenbbloom: in this case don't worry it won't die. I'll read and comment, this something I want to see fixed in a relatively short amount of time.
15:08dnolenbbloom: I was less interested in the past because I thought we could rely on Google Closure, now that this turning out not to be the case, it's a lot more interesting to push it along.
15:08bbloomdnolen: fine, but you'll note that i've got like 5 design pages that have garnered zero attention or made any progress
15:09dnolenbbloom: and this probably one of those, and now there's interest :)
15:09bbloomdnolen: http://dev.clojure.org/display/design/Compiler+Re-structuring
15:09bbloomi'll add a few notes
15:10dnolenbbloom: part of the problem is pages like this, it's too broad
15:10bbloomdnolen: i'm adding some notes, hold your horses
15:10bbloomyou can reorg it however you want
15:11dnolenbbloom: k
15:15bbloomdnolen: http://dev.clojure.org/display/design/Compiler+Re-structuring what else? i got 2 more minutes to write some more notes b4 i gotta run
15:16dnolenbbloom: that's ok start I'll work in it some more later today.
15:16bbloomk
15:17bbloomi'm happy to implement the ANF transform if you're willing to do the work to get a nice compile function & implement a no-op pass to prove we have passes :-)
15:17bbloommy existing ANF transform was like 80% of the way there. i'll fix & finish it, then do all the testing on that
15:18hiredmanbbloom: which representation is that transform working on? clojure, analyzer tree, javascript ast?
15:19bbloomanalyzer ast
15:19hiredmancool
15:19bblooman old version of it
15:19bbloombtw, this will bring up the :children debate again, lol
15:19bbloomanyway, i gotta run
15:21hiredmansure, that is why I was interested, the tree is so rich it seems actually difficult to do transforms
15:23hiredmaninvariants seem like they would be hard to maintain
15:54upwardindexI'm playing a bit with goog.ui and not exactly loving it so far
15:54upwardindexWhat are the popular ui libraries in cljs?
15:56dnolenupwardindex: probably goog.ui or jquery.ui, honestly I wouldn't use either.
15:56upwardindexdnolen: what do you use?
15:57dnolenupwardindex: I don't use anything (I work on the compiler mostly), if I used something I would probably write it from scratch.
15:59shaungilchristdnolen: do you plan on naming/releasing your core.async/ui utils? That is what I keep looking for.
16:00dnolenshaungilchrist: when its less half baked probably
16:03shaungilchristyou say half baked I say al dente
16:03cgaglet the community help you bake the other half
16:04dnolenshaungilchrist: there are a couple of missing bits that I'm trying to understand first
16:04dnolencgag: well hopefully what I've already written about coded up is sensible enough for other people to run with
16:05dnolencgag: but I'm not up for maintaining another project at the moment
16:05wkellyk
16:12gvickers`(load-file "../file.clj") returns #'file.core/foo after it loads file.clj's namespace. Now say I have N different .clj files all with their own implementations of foo. Is there any way to 1. Veriy that foo exists and 2. construct a seq of namespaces I have loaded via (load-file)
16:14gvickers`also what does the pound sign mean in my repl output?
16:15shdwprincegvickers`: (loaded-libs) can affort you a set of loaded ns's
16:16nDuffgvickers`: 'file.core/foo is a symbol; #'file.core/foo is a Var
16:17gvickers`oh cool thanks
16:18gvickers`if I am getting #'file.core/foo back as a Var, is there a way to change the var to a symbol?
16:21stuartsierragvickers`: Indirectly, by looking at the Var's metadata
16:25gvickers`stuartsierra: thanks, thats exactly what I was looking for.
16:45vmarcinkohi. noob question - is there some other REPL-oriented workflow description out beside stuart sierra one? Im just starting with clojure projects, and somehow I dunn oexactly how to define the workflow best...
16:49max2vmarcinko: how about the REPL flow described in Clojure Programming?
16:50vmarcinkook, i got it, just checking if there are some additional ones out there, or someone here can describe his...
17:15amacdougallI'm not terribly sophisticated, but I have vim set up to push code straight to the terminal via tmux; then, while working on my file in vim, I can just execute definitions to set them in the running REPL. Works nicely so far.
17:16cgaghave you checked out fireplace? I use it and it's fairly solid
17:16amacdougallI wrote this blog post about the vim->terminal thing: http://www.alanmacdougall.com/blog/2012/03/27/using-vim-slime-with-pry-for-repl-perfection/ — it's about Ruby with the Pry REPL, but applies 100% to any other terminal REPL.
17:16glosoliAny recommendations for a plugin for VIM that would keep my Parens safe, some sort of decent alternative to Par Edit ?
17:16RaynesHow about paredit? :P
17:16Raynes$google paredit.vim
17:16lazybot[emezeske/paredit.vim · GitHub] https://github.com/emezeske/paredit.vim
17:16glosoli:O
17:17cgag$google vim-clojure-static
17:17lazybot[guns/vim-clojure-static · GitHub] https://github.com/guns/vim-clojure-static
17:17Rayneshttps://bitbucket.org/kovisoft/paredit
17:17Raynesglosoli: ^
17:17glosolihmm bitbucket seems to be the only one up to date
17:18RaynesYes.
17:18glosolidamn, not sure how vundle will handle this
17:18RaynesDespite writing pretty good vim plugins, the author hates us.
17:18Raynes:p
17:18RaynesEw vundle.
17:18RaynesPathogen noob.
17:18seangrovednolen: I'm pretty confused about the constant lookup table for keywords in cljs. I've gone through the Java implementation, and it looks like the table there is a lookup of symbol => references, which doesn't seem to aply in js
17:18Raynes>:3
17:18glosoliRaynes: :DD or Emacs package manager
17:19cgagvundle is where it's at
17:19glosolihmm
17:19lolgiciani followed this guide for a happy vim->repl experience http://michaelalynmiller.com/blog/2013/02/27/vim-tmux-clojure/
17:19lolgiciani haven't tried vundle
17:19cgaghttps://github.com/tpope/vim-fireplace
17:20tbaldridgeseangrove: CLJS uses "magic strings" for keywords. They are nothing more than strings prefixed with a magic unicode character that no one uses.
17:20cgagi use this and basically the cpp, :%Eval, and cqc commands
17:20cgagand sometimes drop stuff into my files like
17:20cgag(comment (run-server))
17:20cgag(comment (run-tests))
17:20cgagand just eval those inner expressions occasionally instead of running them from the repl
17:20dnolentbaldridge: yeah we want to get rid of that
17:21glosolicgag: you was not kidding about Vundle having that paredit.vim plugin ?
17:22cgagi have Bundle 'vim-scripts/paredit.vim'
17:22cgagin my vimrc and it works for me
17:27seangrovetbaldridge: Yeah, so I'm taking a stab at implementing "real" keywords, as dnolen calls them
17:28seangroveBut could use some help with the details. Been looking at the implementation of other types, and the Java implementation of Keyword for reference, understanding the idea better, but not well enough to implement it independently
17:31amalloyseangrove: i understand the java implementation pretty well, and i agree that it's not at all obvious how to port it to a language without weak references
17:32seangroveamalloy: Took your advice to get more familiar with the clj-jvm implementation, hasn't bee too bad yet. Thanks for the suggestion
17:32amalloyi think there was once a version of clojure that interned keywords permanently; probably you could port that instead, and warn developers not to keywordize arbitrary strings
17:32dnolenamalloy: seangrove: the whole idea on anything requires weak references - it's just a constant lookup table
17:33dnolenamalloy: seangrove: the only gotcha is that keywords are supposed to be identical? I already went over this a bit with Rich, he's OK w/ documenting it's not possible in JS because no weak references, thus keyword-identical?
17:33dnolen"the whole idea on anything" -> "the idea punts on anything requiring weak refs"
17:33seangrovednolen: I'm confused on the constant-lookup part. I think the keyword symbols are the keys - what are the constants they're looking up?
17:33dnolenseangrove: a unique identifier for that constant
17:34dnolenseangrove: they are entries in a table that we preallocate
17:34seangroveOk, so the equivalent of (.hasheq :keyword)
17:36dnolenseangrove: for example :else, everywhere :else appears in CLJS should be replaced with
17:36dnolenconstant-table.keywords.else
17:37dnolenwhere that entry has been set to (Keyword. "else" ...)
17:41seangroveAlright, so the analyze finds a keyword :else for the first time, creates an entry in constant-table.keywords.else = (Keyword. "else")
17:42dnolenseangrove: well it records it during analysis, so the compiler can emit it later
17:42seangroveI'll start with just the analyzer part.
17:44seangroveI'm also unclear about the compiler/runtime separation - the (deftype Keyword ...) isn't available at analysis/compile time, so how can we instantiate (Keyword. "else") in the analyzer?
17:46dnolenseangrove: we're going to have to get clever, but very little in the standard library actually "runs" now
17:47dnolenseangrove: so we just emit the lookup table after the core library and before all user code
17:48dnolenseangrove: JS is late bound so this be fine, we just need to make sure however we emit it Closure can still optimize it.
18:18onenessany one knows if lein uberjar also calls lein clean?
18:20hyPiRiononeness: no, not by default at least
18:20onenesshyPiRion: thanks.
18:24naconHmm. Learning Clojure and having to look at this: http://imgur.com/a/WfKD4 (font alignment). I don't know why it bothers me that much..
18:24callennacon: that's a little strange.
18:25naconI suppose those are font issues..
18:30hyPiRionmy OCD would've died if that was the case for me. Is this a monospace font?
18:30hyPiRionoh wait, that's a gist.
18:30callenthat's what weird, gists are supposed to be monospaced.
18:31callenit looks like either there's an actual space there, or the font rendering is boned.
18:31naconprobably a system font issue on my side
18:31naconno, there's no extra space. the raw gists is properly aligned and looks good.
18:32callennacon: leaning towards your system font being fucked. What are you using?
18:35amacdougallIf you're on Chrome/Firefox, try using the Stylish extension to set <pre> to a different monospaced font. See if that helps.
18:35amacdougall(Or set a spot font-family style using the devtools actually)
18:36naconI'm using Chromium's default (Bitstream Vera) -- but it's the same in Firefox so I suppose it maps to the same system font
18:36amacdougallAny time you think, "man, this site I go to all the time has this one really annoying formatting issue!", just add a rule in Stylish. :+1:
18:36callennacon: OS?
18:36naconGentoo
19:06Peetskigood evening, morning, afternoon
19:09brehaut~ugt
19:09clojurebotugt is Universal Greeting Time: http://www.total-knowledge.com/~ilya/mips/ugt.html
19:10`cbp`that feeling when I can finally close IDEA and go back to emacs :-)
19:12Peetskiok then, good ugt everyone.
19:13arrdembrehaut: I'm so glad we have a convention for this
19:13arrdemit formalizes beer-30!
19:13brehautlol
19:14arrdemalright, well it's 6:00 (UGT) and I'm punching out. 'night people!
19:14brehautlater arrdem
19:15Peetskiwhat happened to ugt?
19:16cgagit's night ugt for him
19:17PeetskiAh I see. Doh!
19:29callen`cbp: what were you doing in IDEA?
19:30TakeVSuppose I have a helper function in a namespace for a few other functions, but I don't want people using the namespace to use the function. Is it more idiomatic to define it with defn-, or to wrap all defns functions in a single letfn?
19:30dnolenhrm, should this work?
19:30dnolen,(flatten (object-array [1 (object-array 2) 3]))
19:30clojurebot()
19:38holo1hi
19:38`cbpcallen: php
19:38hiredmandnolen: flatten has a history of behaving very oddly when passed non-seqs
19:38hiredman,(flatten {:a 1})
19:38clojurebot()
19:39callen`cbp: sweet jesus. I'm so sorry.
19:40akurilinQuick question. I want to write some logic to generate a large set of data for multiple "model types" and populate my DB with it. I'm debating between just writing a ruby script for this, or whether I should add this as Clojure code in my ring app that I can run as a one-off from the REPL. Anything wrong with the latter?
19:40akurilinDo people writing ring apps eventually end up with a "scripts" namespace anyway, for one-offs?
19:41cgagI did, I called it tasks a la rake tasks
19:41callenakurilin: I do. I usually use lein exec or something comparable for my scripts.
19:41callenakurilin: I script stuff with lein exec that doesn't even have anything to do with a clojure project.
19:41callenthreaded scripts is nice, yo.
19:41callenI have one such script running right now...scraping an API...
19:42akurilincallen, you still have to setup a whole new project with lein new every time, right?
19:42callenakurilin: please read the documentation to lein exec.
19:42akurilinokie dokie
19:44akurilincallen, have you been able to wean yourself off of python/ruby/perl/whatever with lein exec?
19:45callenakurilin: yes, there are odds and ends suited to Python, but it's becoming less the case over time.
19:45akurilinRight tool for the right job and all that, but I'd be quite happy to move most of the heavy scripting off of ruby.
19:45akurilinI'd be happy with just bash + clojure :)
19:45callenyeah, I was in a similar position WRT Python.
19:46callenIt'll never be 100% because I work in a company that uses a lot of Python, but my relatively "internal" scripts have all been Clojure lately.
19:46callenAPI, database, text munging.
19:48holoakurilin, i use fish shell + pyp. it keeps me away from python, yet. not that i don't like python, but i don't find it worth it for the size of my scripts
19:49callenthe scripts I write vary from trivial (bash) to small-large (clojure)
19:50callenthe one thing I don't have a good solution for is quick remote automation like what Fabric is useful for.
19:52akurilincallen, what's a use case for quick remote automation? I'm only familiar with non-quick remote configuration management with puppet/ansible.
19:53akurilinholo, I'll have to check out that combo, not familiar with either.
19:53callenakurilin: long tail of random shit that isn't necessarily about instantiating a machine via puppet.
19:54callenif it can be done in puppet/ansible, by all means
19:54callenbut I have to do random-ass stuff that would make the former annoying, and nobody uses ansible here.
19:54callenansible has a good mechanism for being used like Fabric though.
19:57akurilinyeah I do enjoy my --tags on occasion
19:58akurilincallen, so regarding lein exec, if I'm understanding correctly, there's nothing stopping me from creating a bunch of scripts under my ring app and then use the already existing data access layer from them, when calling from lein exec?
19:58holoakurilin, i'm not aware if people usually use it as a combo. i decided to use it as a combo myself. fish shell because i don't need to read the manual every time i read/write a form (like i had to do in bash). pyp cause it brings to the shell all the convenience of split/join of python lists/strings combined with pipes for text transformation
20:00akurilinholo, that's fair, I never thought of exposing the interpreter straight onto the shell
20:00akurilinthat's a pretty neat idea
20:03holoakurilin hehe.. the guys at sony pictures needed to do it.. it's basically a python script
20:04holoi'm developing a library for format conversion exposing this interface (convert "mystring" from :source-format to :target-format) . when :source-format is unknown (convert "mystring" to :target-format)
20:04holois this too many word for such simple task?
20:05callenakurilin: that's a good question @ existing data access layer.
20:05callenAnything that uses my "models" is usually more formalized than the sort of scripts I'm talking about. That sort of thing gets dispatched "in project".
20:06callenyou don't need lein exec if that's what you're doing.
20:07cgagcan also use lein run -m <namespace> if you've got a main function in there
20:08callenyep ^^
20:09hologuys/girls, i would appreciate some honest opinion about it. i don't want to expose an api that too many people hate
20:11callenholo: is that a literal representation of the function interface?
20:12callenholo: wtf is from and to?
20:12holocallen, it's a symbol
20:13holoyes, it's a literal representation, except that :source-format/:target-format can be any other key that represents some supported format
20:13callenholo: drop the from/to bullshit
20:13holohehehe.. that's what i needed
20:13callenit's weird and doesn't serve an actual function.
20:14callenholo: two arities of: (convert "blah" :target-format) and (convert "blah" :target-format :origin-format) would suffice I think.
20:15holocallen, thanks
20:15callenholo: if you wanted to be really nice, you could return a closure from convert
20:15callenand do something like: (convert :target-format) and (convert :target-format :origin-format) which both return a "converter" fn that accepts a single argument of "data"
20:15hyPiRionI would use (convert mystring :from format :to format) in that case, mayybe
20:16callenI really don't think the :from/:to is a good idea unless there's more to spec he's not telling us.
20:16hyPiRionthen destructure by doing [in-string & {:keys [from to]}].
20:16hyPiRioncallen: well yeah, :target-format :origin-format works just as well I suppose
20:16holocallen, there's nothing more about the spec. btw, your idea about returning a closure using the first argument sounds like a great idea
20:17callenholo: well it spares people needing to use partial or something in order to pass around a "converter fn"
20:17callenbut having an arity for "immediately execute this dude" is a good idea.
20:17holocallen, sure
20:17callenyou could split out the closed over, and non-closed over into separate APIs.
20:17callenthis is getting into frippery though.
20:18callenjust exploring options.
20:18callenI've had really good luck with closure based library APIs lately though.
20:18holohyPiRion, doesn't it look ugly (convert "mystring" :to :target-format) ? there's too consecutive keywords.. it seems like they are at the same level
20:20callenI don't like extraneous noun/verb keywords in function arguments unless a complicated DSL is involved
20:20calleneven then, I'm really hoping there's a simpler fn underlying it.
20:20holo"you could split out the closed over, and non-closed over into separate APIs" - looks even better
20:21callenconverter vs. convert
20:21callenformer is the closure API, latter is the "fire this off plz"
20:21hyPiRionholo: I'm not sure, you're saying "that :source-format/:target-format can be any other key that represents some supported format"
20:22holocallen hehehe.. when you said that pair converter/convert, i immediately reasoned the same thing. i think it's intuitive
20:22hyPiRion(convert mystring :target-format :my-format :source-format :some-other-format) ?
20:22hyPiRionI don't know, I'd probably pass in a map instead
20:24holohyPiRion, the clojure library guidelines give preference to (form :to format) comparing to (form :to some-map)
20:24holoi mean (form some-map), sorry
20:25callenI really don't think explicitly decorating target/source args with prefix keywords is necessary or a good API.
20:26callenagain, unless there's a more complicated DSL the function is participating in, and has overloaded meaning.
20:26clojurebotRoger.
20:26callenand in that case, you're fucked anyway.
20:26callenKISS.
20:28holocallen, converter/convert just feels great
20:28akurilincallen, back. Sounds good, I'll give that a shot. Will probably go tasks/ route as cgag suggested
20:28holohyPiRion, thanks for ideas too
20:29callenakurilin: if you're calling into code that lives in the project, that's a better idea.
20:29callenholo: supports using the global state or a closure: https://github.com/bitemyapp/bulwark/blob/master/src/bulwark/core.clj#L83-L85
20:31aaelonya couple days ago I asked if there existed a "melt" function for incanter datasets the same way it exists in R to make wide data long. Didn't get a response so cobbled the following hacky version together. I'm sure there is room for improvement. Please critique away … https://www.refheap.com/17922
20:31aaelonyshould work for *any* Incanter dataset
20:32holocallen, thanks, looking up that example
20:33callenholo: your library shouldn't need global state like that, just showing how you can adapt a function to multiple purposes.
20:33callenconvert/converter is probably better in your case.
20:38holocallen, yes, i think this one doesn't apply for global state. yes, i'll stick to convert/converter
20:42seangrovednolen: To get a bit more concrete, does this look like the right approach? https://gist.github.com/sgrove/6301866
20:42dnolenseangrove: why are you storing the .hashCode ?
20:43cgagakurilin: this is what i had https://github.com/cgag/bookmarking/blob/master/src/tasks/db.clj, and then i could run like `lein run -m tasks.db rebuild seed`
20:43seangrovednolen: updated the gist
20:43cgagonly the last like 10 lines there are of interest probably
20:43seangroveWhat should I be storing instead? (Keyword. k) ?
20:44dnolenseangrove: and you maybe shouldn't update the table there, instead do it around analyze, if analyze itself returns a constant you know you have something - keywords are an important case but we should handle everything.
20:44dnolenseangrove: it could probably just be a set, just the value
20:45seangrovednolen: Struggling with that - What is the value?
20:45dnolen:foo
20:45seangroveAh, ok
20:45dnolenseangrove: put the thing in the set of known constants
20:46seangroveOk, got it, I was overcomplicating it
20:49dnolenseangrove: I'm going to write up some notes about this
20:53seangrovednolen: I'd really appreciate it, thanks.
20:56akurilinQuick sanity check, I can't seem to get this leiningen injection to work: :injections [(require 'spyscope.core '[taoensso.timbre :as timbre])]. Spyscope works fine, timbre not so much.
21:13dnolenbbloom: I erased what you wrote earlier, I think this is a better start http://dev.clojure.org/display/design/Optimizing+Expression+Semantics
21:13dnolenanybody else interested in ClojureScript AST stuff feel free to chime in
21:13dnolenseangrove: working on Constant Optimization page next
21:17cgagdnolen: this stuff with the clojurescript compiler sounds interested, but i don't know much about it, is there anything i should read besides the compiler source itself?
21:18dnolencgag: hmm not really, fortunately the analyzer and the compiler are two relatively short programs - together ~1900 LOC i think
21:22cgagcool. i'll just dig in sometime then, i only just started using clojurescript, but it's awesome, actually has me excited to write frontend stuff
21:32fbernierIs it possible to reference an import from another namespace if this namespace is required ?
21:32holois it that bad to return truthy/falsey instead of strict boolean in "predicate?" fns?
21:33amacdougallSame here… I saw dnolen give a talk on it at nyc.js, but only recently got around to embarking on a real-life clojure/clojurescript project. We'll see how it goes!
21:33mlb-Has anyone here had much luck with manipulating WSDL files in clojure?
21:34holofbernier, if you mean cyclic requires, no, it's not possible
21:35holofbernier, it's usually an indication of smell too when you need such a dependency
21:36holofbernier, design smell
21:37fbernierholo: I've got (:import [java.awt.image BufferedImage]) in a file where I do image processing
21:37fbernierthen in another file where I do my compojure routing, I use extend-protocol to define a response for BufferedImage
21:37fbernierI was just wondering if I need to also import BufferedImage in this file
21:38fbernieror if I could just reference it since its imported in the other file I am requiring
21:39holofbernier, from what i've experienced, you don't even need import at all, if you are willing to just use java.awt.image.BufferedImage
21:39dissipatewtf, the tutorial on http://tryclj.com/ is waaaay too short
21:39TimMcfbernier: Yes, because :import is just for name resolution, not classloading.
21:39fbernierholo: aaah right
21:39fbernierstill mixing those things up
21:39fbernierthanks
21:39dissipatedoes anyone have a link to a longer interactive tutorial?
21:39holonp
21:39dnolenseangrove: http://dev.clojure.org/display/design/Optimizing+Keywords
21:40dnolenseangrove: let me know if you need me to flesh out some more
21:43holodissipate, there's 4clojure.com it's not a tutorial, but you can from there. there was also some kind of step by step learning lab built under joodoo/judoo/something.. let me try to find it out
21:43holo*can learn
21:46dissipateholo, cool, thanks
21:47holodissipate, found it! http://clojurekoans.com never tried it though looks kind of mistical
22:04holohere http://faustus.webatu.com/clj-quick-ref.html I read "The function boolean converts from Clojure logical truth to boolean true and false, primarily for Java interop.". is it maybe that pred? should return boolean true,false instead of logical truth values for java interop?
22:15saolsenIs anybody familiar with nrepl. I'm embedding it in an app where I care about which thread the code executes on so I need to write some middleware (or a handler?) that, instead of executing the code, wraps it as a function, places it on a queue, waits for another thread to pick it up, execute it and put the result somewhere and then pull the result and send it back to the nrepl client. Has anybody done something like this with nrepl middlewar
22:22akurilinIs it idiomatic to use get on vectors if I'd rather get a nil than an exception in case of out of bounds? I could also go with nth, but that requires an extra param.
22:27dnolenakurilin: intention of nth + extra param is probably going to be clearer
22:37akurilindnolen, that's a fair point, thank you.
23:14ToxicFrogSo I have here a library that tries to read input using slurp, and a string containing the input.
23:14ToxicFrogJust passing the string to the library causes it to explode (it tries to use it as a filename).
23:14ToxicFrogHow do I make the string slurpable?
23:20xeqi&(slurp (java.io.StringReader. "some string"))
23:20lazybot⇒ "some string"
23:20xeqiToxicFrog: ^
23:37amacdougallIt would be nice for the library to provide read and read-file though.
23:37amacdougalla la json, etc