#clojure logs

2012-12-09

00:00seangroveI'm trying to build something around it, and it's alright, but there's going to have to be a somewhat substantial wrapper around it to make it fit what I want
00:00RaynesWas this seangrove's paste?
00:00seangroveYeah
00:00RaynesDamn all of you who don't have user accounts.
00:01Raynesseangrove: You're famous now. I tweeted it and everything.
00:01seangroveThe embedded javascript for refheap looks great Raynes
00:02RaynesAlso, let this be a lesson for everyone: if your paste is public, I will one day use it for some demonstration somewhere. It's only a matter of time.
00:02seangrovebut tomoj, when you get a chance, would love to hear your thoughts
00:02tomojI guess branch is OK
00:02tomojand when
00:03seangroveHmmm, so bad compared to what, then?
00:04tomojtrying to get them in my repl so I can confirm they are broken :)
00:14tomojright
00:15tomojseangrove: https://www.refheap.com/paste/cf279b53c2f6168fa30ce1e0b
00:16tomojif you do (.addCallback (.branch d) ...) instead, you get the, uh, correct results
00:19seangroveSure, but isn't that expected behavior?
00:20tomojin what sense? I expected it of Deferred, because I expected Deferred to be wrong :)
00:21seangroveHeh, in that the result is cascaded through callbacks sequentially
00:21seangroveDo you expect all callbacks to be called with the same value?
00:21tomojyes
00:21tomojDeferred seems like a deferred mutable value
00:21tomojI want a deferred immutable value, naturally
00:22seangroveI see, I kind of saw it as analagous to ->
00:22tomojif it's restricted to a lexical scope, maybe
00:23tomojbut the burden is on you to be careful not to expose the wrong Deferred and let others mutate it
00:24tomojlike (-> x inc inc inc) might be analogous to (-> d (.addCallback inc) (.addCallback inc) (.addCallback inc) .branch) ?
00:24seangroveAh, as in someone else could attach a callback somewhere and potentially mess up any later callbacks you add?
00:25seangroveOr (doto (.branch d) (.addCallback inc) (.addCallback inc) (.addCallback inc))
00:26tomojeven after you branch, that branched thing is still a Deferred, so it's still broken :)
00:27seangrovehmm, interesting
00:27seangroveIf you could *only* apply callbacks to a branched deferred unless you created it in a local scope, would that be better?
00:28seangroveObviously not possible, but hypothetically
00:28tomojunbranched, you mean?
00:29tomojI think it's safe to do (.addCallback (.branch d) inc) no matter where d came from
00:29seangroveno, branched, so that you couldn't affect the original deferred from the pov of whoever gave it to you
00:29tomojif you created d and are caring for it, then you might not need to call branch
00:29seangroveYeah, that's right
00:29seangroveAnd if you hand it to someone else, they wouldn't be able to add a callback to it that would affect any of yours
00:30seangroveEffectively, they would have to call .branch on it first, and could then add callbacks on the newly-returned deferred
00:30tomojyeah
00:30seangroveI suppose that's what you meant by immutable deferreds though ;)
00:30tomojI think this is very relevant though I've only skimmed it https://gist.github.com/3889970
00:30tomojif you're wrapping Deferred maybe you can make your wrapper safe
00:31tomojpersonally I'm ignoring Deferred and implementing, uh, correct promises directly in cljs, then someday I'll provide some wrapper that converts a Deferred into a correct promise
00:32seangroveThe problem I have is you can't implement deferred from the outside of functions
00:32seangroveFor example, I can't pass an xhr request to a deferred and expect them to work together, unless I've built my own wrapper around both of them
00:33seangroveAnd then that wrapper won't work for any other library or code that doesn't conform to my specific patterns
00:33seangroveFor example, I think you could probably implement something close to it by building something on deferreds, xhr, and goog.events, but it'd be more code for less effect than I'd like
00:34tomojsurprised XhrIo doesn't return a Deferred of a response
00:35seangroveDoesn't return anything :P
00:35tomojyeah :(
00:36seangrovePresumably you could make a module that copied the innards of xhrio and returned deferreds... it'd be much nicer if it were included as a standard though
00:37tomojwhat do you mean by 'pass an xhr request to a deferred'?
00:38seangrove(.callback my-deferred (my-xhr-fn))
00:40seangroveI have to have to something similar to: (defn my-xhr-fn [...] (if (success) (.callback my-deferred)))
00:40seangroveLike you said, if XhrIo returns a deferred, I think that'd work well
00:44tomojwell, dunno. but protocols may help with the "won't work for any other library or code" problem
00:44tomojof course, only for other cljs libraries or code..
00:53gaze__yo! I can't find anything definining the behavior of carats in the documentation, just references (def ^:dynamic, for instance
00:53gaze__what do they do?
00:56p_lreader macro to set metadata stuff
00:57tomoj&(meta (read-string "^:dynamic []"))
00:57lazybot⇒ {:dynamic true}
00:57tomoj&(meta (read-string "^{:foo :bar} []"))
00:57lazybot⇒ {:foo :bar}
01:22seangrovetomoj: Yeah, I think protocols might be the way to go about it eventually, but just frustrating how much basic infrastructure will need to be built out
01:53gaze__say I have some macro that defines a symbol, and I want stuff inside the macro to be able to manipulate that symbol, without explicitly making reference to it
01:54gaze__using name# I guess assigns a special name
01:55gaze__and if I just remove the hash, it complains that it's not making reference to a qualified name
01:59gaze__or... is there a better way to do implicit arguments?
02:02amalloy$google clojure anaphora macro symbol
02:02lazybot[Unhygienic ("anaphoric") Clojure macros for fun and profit] http://amalloy.hubpages.com/hub/Unhygenic-anaphoric-Clojure-macros-for-fun-and-profit
02:02amalloyhey, that's me! anyway, gaze__, that's the name of the thing you're talking about, if i understand you
02:03gaze__YES
02:03gaze__thanks :D
02:13tpopebbloom: do you have a proposed solution? eval top level form?
02:19gaze__amalloy: I should actually just ask the question I mean to ask... let's say I want to have a macro called defx, where any time (go a) is called within it, a is appended to a list. The result of a definition of defx is to be the list.
02:20gaze__(defx foo (let [x 5] (go x) (go (+ 5 x))))
02:20gaze__then (foo) should be '(5 10)
02:22gaze__in my version I'm both defining an unhygenic symbol and trying to make a mutable bound variable... is there a more sensible way to do this?
02:27amalloythis is unpleasant, but there's nothing obviously better unless you're willing to really dive off the deep end and use continuations, which i suspect would do it
04:14adxpI'm getting a "Could not locate clojure/instant__init.class or clojure/instant.clj on classpath" error when trying to use fetch with cljsbuild. As far as I can tell, others have fixed this by upgrading to clojure 1.4 or cljsbuild 0.2.9. I'm using those already, though. Anyone have any ideas as to what else I could try?
04:15tomoj*clojure-version* is 1.4.0?
04:17adxpthat's what's in my project.clj, and what's reported by manually running clj, yep. I'm still pretty new to clojure, so I'm not sure if there's anything else I should check...
04:17tomojadxp: you have a new-ish version of leiningen?
04:18adxprunning with --version reports "Leiningen 1.7.1 on Java 1.7.0_09 Java HotSpot(TM) 64-Bit Server VM"
04:18tomojSgeo|web: could you write (letrec [a [b] b [a]] [a b]) with it?
04:18tomojthat's pretty old
04:18Sgeo|webThis exists https://gist.github.com/486880
04:18tomojadxp: but, since it's old, check to see which clojure jar is in lib/
04:18Sgeo|webtomoj: I assume that some things would infinite loop
04:19adxptomoj: clojure-1.4.0.jar is in lib/, but I can look at upgrading leiningen if that might help
04:19tomojdoubt it should help..
04:19tomojbut it would be a good idea in general
04:19tomojprobably..
04:20adxpok, will do; thanks
04:20tomojso the only other question I have is, if you upgraded from something older than clojure 1.4, did you restart the jvm since upgrading?
04:21adxpwhat do you mean by restart?
04:21tomojwell, where are you getting that error?
04:21adxpwhen I run "lein cljsbuild [auto / once]"
04:21tomojoh
04:21adxpI did upgrade my JDK earlier, but I doubt that's related...
04:22tomojthat doesn't make any sense to me, sorry
04:22adxpthe error?
04:22tomojI mean I can't think of any explanation
04:22tomojclojure/instant.clj is in my 1.4.0 jar
04:23adxpyeah, ditto
04:23adxpjar tf lib/clojure-1.4.0.jar | grep instant | head
04:23adxpclojure/instant/
04:23adxphum.
04:23tomojwell, further down you should see clojure/instant.clj
04:23adxpyeah, that's there too
04:23tomoj`lein classpath` shows a dir with that jar in it?
04:24tomojpresumably..
04:24adxpyup
04:24tomojmaybe you just need to upgrade lein
04:24tomojI could imagine that cljsbuild assumes lein 2
04:24tomojnot sure though
04:25tomojnot sure how that would cause your error, either
04:25adxptrying that now
04:26adxphuh, worked. thanks!
04:28gaze__how do I inject an array of stuff into the arguments of something? like... I have (defn x [a & b] ...) and I want b to take the values ['p 'q]
04:28Sgeo|webUgh, I think to do what I really want would require writing my own sort of container
04:28tomojcontainer like an IDeref?
04:29Sgeo|webYes
04:29Sgeo|webAlthough come to think of it, maybe I'm imagining a lazy letrec when that's not what letrec typically is
04:29amalloy$findfn list 'a 'b ['p 'q] '(a b p q)
04:30lazybot[]
04:30amalloywhat the hell, findfn. the answer is apply
04:30Sgeo|web,(+ 1 2)
04:30clojurebot3
04:30Sgeo|web,(apply + [1 2])
04:30clojurebot3
04:30gaze__sweeeet. Thanks :D
04:30Sgeo|web,(apply + 1 2 [3 4])
04:30clojurebot10
04:33Sgeo|webWhat special forms besides quote take lists as arguments that are not treated like code?
04:35tomojI've been pondering letrec for asynchronous IDerefs, like maybe (letrec [a (merge (periodic 1) (postpone Math/PI a))] a)
04:39borkdudesomeone asked me: what are the new features for clojure 1.5. I told him: reducers and a lot of new threading operators… am I right and what else?
04:40tomoj(which has occurrences at 0,1,2,3,pi,4,pi+1,5,pi+2,6,pi+3,2pi,7,pi+7,2pi+1.. I think?)
04:41tomojborkdude: http://dev.clojure.org/jira/secure/attachment/11744/changes-draft-v11.md
04:42borkdudetomoj many tnx
04:45Sgeo|webas->'s doc seems inconsistent
04:45Sgeo|webIt sounsd like it does do threading, although it claims it does not
04:56tomojas->^
04:56tomoj?
04:56tomojoh, sweet
04:56tomojI didn't like 'test->
04:58tomojSgeo|web: the doc is inconsistent with the name?
04:59Sgeo|web"then binds name to that result, repeating for each successive form"
04:59Sgeo|webSo the name doesn't stay the expr throughout the as->, it changes, as a sort of threading
05:00Sgeo|webWhich, while possibly useful in some circumstances, is inconsistent with the stated goal "Instead it allows the user to assign a name and lexical context to a value created by a parent threading form."
05:00Sgeo|webIn order to do that goal, you'd have to do something like (as-> some-name (do ...))
05:00Sgeo|webIf you want to use multiple forms
05:01amalloySgeo|web: (-> foo inc blah whatever (as-> bar (for [x bar] ...)))
05:01Sgeo|webamalloy: the issue pops up when there's more than 2 forms (the name and a form) in the as->
05:01tomojyou could say that is a kind of threading
05:02Sgeo|webI would
05:02amalloythat's not an issue, man. if you want more threading, you didn't need as-> in the first place
05:02tomojI think the changes md means that it is not the syntactic threading of ->
05:02amalloyi'm showing you the intended usage of as->, and why it doesn't make sense to continue threading the form
05:03Sgeo|webamalloy: my point is that the documentation says that it continues threading (kind of, just in a different way)
05:03Sgeo|webSuppose you want to do side-effects in the as->
05:06borkdudearen't all these extra threading macro's adding extra "syntax" to clojure, I wonder if it's worth it?
05:07borkdudebut then again, I don't really mind
05:08gaze__how do I get a defmacro to put multiple things at the toplevel?
05:08borkdudegaze__ use multiple defns in it?
05:09borkdudegaze__ generally a bad thing, unless you are writing a framework or smth
05:09tomojgenerally a bad thing then too :P
05:10borkdudehehe
05:10Sgeo|webgaze__: do
05:10tomojwhy does clj-http parse the url, never look at it, then just convert it back to a url when doing the request?
05:10gaze__yeah it feels kinda dirty. But... I need after each definition to push the name of the function and the actual symbol into a table
05:10tomoj"for ring compliance" I think, but.. really? :/
05:10gaze__and it looks like defmacro is variadic and everything it sees it just pushes
05:11gaze__so... cool :D
05:11Sgeo|webdemacro is variadic because it takes in code, just like defn does
05:11Sgeo|webCode which can consist of multiple forms
05:11Sgeo|webOutputting multiple forms is impossible, but wrapping it in do works fine
05:11Sgeo|web,(do (println "A") (println "B")) ; one form
05:12clojurebotA
05:12clojurebotB
05:12tomojoh, actually, I see some reason for it
05:12tomoje.g. :query-params -> :query-string conversion
05:15gaze__http://pastebin.com/pdzUSBvv
05:15gaze__here's what I'm doing
05:15gaze__does all this seem reasonable?
05:16gaze__lotta mutable stuff... would like to have less mutable stuff
05:16gaze__but I don't see much way out of it
05:17Sgeo|weba) You're not going to be outputting the defn
05:17Sgeo|webb) caller and trxn will be visible from the body. Do you really want that?
05:18gaze__a) Ah... I'll wrap it in a do
05:18gaze__b) caller, yes. trxn, no
05:18gaze__but I don't see a way around having trxn visible to go
05:50zamaterianIs it possible to get syntax highlightning in lein repl ?
05:53tomojit's probably possible, but there is no support for it now, and it seems like it would be a lot of work. it would probably be much easier to get syntax highlighting at a repl embedded inside an editor that can already do clojure syntax highlighting
05:54zamateriantomoj, thx (i
05:55zamateriantomoj, i'm using vim+vimclojure+foreplay - but uses lein repl for all my prototyping..
05:57rodnaphhi - i've copied some java source files into my leiningen project src directory (with namespace folders) then set the :java-source-path, but leiningen doesn't seem to be doing anything with them (the classes are not available if i start a repl) - can anyone help?
06:00andrewmcveighrodnaph: I think you have to compile them first, but I've never worked with java & lein together.
06:03tomoj`lein javac` maybe?
06:04tomojdnolen: would you be interested in a patch which copies cond-> and friends from 1.5 into cljs/core.clj (to be pulled only after 1.5 is out, I suppose)?
06:06rodnaphah - got it! the property has changed in lein 2.0 :E https://github.com/technomancy/leiningen/blob/master/sample.project.clj#L210
06:07rodnaphthanks both
06:14Sgeo|webI wonder, if it's possible to take a threading macro and pass it in and convert it to a let-like thingy
06:15Sgeo|webThreading macros are really just cheap hacks around the lack of nice monad syntax
06:15Sgeo|webOr, alternatively, they are in a sense a nice monad syntax
06:16Sgeo|web(bind mv f) == (-?> mv (f))
06:16Sgeo|webI think?
06:17Sgeo|webCan I go the other direction, from a bind into a threading macro? Kind of, but wouldn't be a perfect implementation of a threading macro
06:18Sgeo|webI think
06:19Sgeo|web(-?> mv (a b c)) == (bind mv #(a % b c))
06:19Sgeo|webPeople might be more willing to use monads if they took the form of threading macros
06:19Sgeo|webTo me, both do syntax and threading feels "intuitive"
06:21Sgeo|webclojure.algo.monads has monads be first-class values, which is generally useful. My big objection to it is with one of the monad implementations, not with the core concept behind it itself
06:21Sgeo|webAlthough I do dislike needing to use defmonadfn
06:22Sgeo|webIf I were to write my own monads library, I would just use dynamically-scoped variables
06:24tomojso you could write a (defn foo [x] (m-> x f)) and then use it in different monads?
06:24tomoj(I'm not familiar with defmonadfn)
06:24Sgeo|webdefmonadfn is the macro you need to use to use bind and return in your own functions with clojure.algo.monads
06:25Sgeo|web(
06:25Sgeo|web(iirc)
06:26Sgeo|webclojure.algo.monads uses a bunch of macros to try to have bind and return effectively be lexically scoped
06:27ambrosebsif anyone's bored, I recorded some experiments with Typed Clojure https://vimeo.com/55196903
06:28ambrosebsObviously rough, but feedback welcome.
06:28Sgeo|webambrosebs: will Typed Clojure allow for polymorphism on the return type of a function?
06:29ambrosebsHaskell type class style? no
06:29Sgeo|webWill Typed Clojure allow for the semantics of a program to rely on being run with Typed Clojure?
06:29Sgeo|webOh, ok, darn.
06:29Sgeo|webThank you
06:29ambrosebsI'm definitely interested in this area though.
06:30ambrosebsIt seems like TC is a starting point for such a thing.
06:32Sgeo|webI wonder what sort of things one can do with bind but no return
06:32tomojwhile you're here, why not put the annotations in metadata? because you want to be able to annotate things which can't have metadata, I guess?
06:33Raynesambrosebs: What's the problem with return type polymorphism?
06:33ambrosebstomoj: I thought about it, but I don't really want to rely on runtime behaviour much. eg. what if the var doesn't exist yet?
06:34ambrosebsRaynes: Firstly, Typed Clojure doesn't affect runtime behaviour at all atm
06:35ambrosebsRaynes: Further than that, I'm not sure of the details, but I assume something like Haskell's inference + type classes is needed.
06:35ambrosebsThe most practical issue is how to best affect runtime behaviour: how to communicate with the compiler.
06:36Sgeo|webPass the type to a function that somehow indicates that it wants access to the type that it should be outputting
06:36Sgeo|webAs in, make it be an argument
06:36Sgeo|webOr maybe dynamic variable?
06:37ambrosebsIt's a hard problem. But my trail of though was operating directly on the AST before it gets compiled.
06:38Raynesambrosebs: Call it cheeky a few times and I bet it'll get easier.
06:39ambrosebsRaynes: just run it backwards.
06:40Sgeo|webWould there be any significant problems to just having a dynamic variable *return*
06:40Sgeo|webAnd *bind* I guess
06:40ambrosebsSgeo|web: You might be on the right track.
06:41tomojif all you're trying to do is monads, maybe?
06:41Sgeo|webclojure.algo.monads's macrology scares me
06:41Sgeo|webI'm not particularly thinking in terms of TC
06:42Sgeo|webBut I also want to have Functor and Applicative stuff, and those don't rely on re... Functor doesn't rely on return type polymorphism
06:43ambrosebsSgeo|web: so who binds the dyn vars?
06:44Sgeo|webThe user. In, say, a with-monad macro, and some macros that might take a first-class monad
06:44Sgeo|webSuch as domonad
06:46ambrosebsInteresting.
06:46ambrosebsAre you thinking more like protocol-monads than algo.monads?
06:47Sgeo|webActually, I think it's more like algo.monads than protocol-monads, because I'm not looking at the types of the arguments, just using functions in a structure passed in from a higher-up-the-call-stack caller
06:49Sgeo|webambrosebs: also, you missed my musings about threading macros and monads
06:49ambrosebsI'll have a look
06:49tomojdomonad is like let?
06:49tomoj(syntactically)
06:50Sgeo|webtomoj: similar, yes
06:50ambrosebsSgeo|web: I think I'm missing something. Is there any inference going on, or have we pushed the work to the user?
06:50Sgeo|webambrosebs: pushed the work to the user
06:51ambrosebsok
06:51Sgeo|web,(-> nil (and 1 2 (do (println "Side-effect") true)))
06:51clojurebotnil
06:51Sgeo|web,(-> true (and 1 2 (do (println "Side-effect") true)))
06:51clojurebotSide-effect
06:51clojurebottrue
06:51Sgeo|webWait, and still operates on values, not on code, it just expands into code that operates on values
06:52Sgeo|web,(macroexpand '(and a b c))
06:52clojurebot(let* [and__2241__auto__ a] (if and__2241__auto__ (clojure.core/and b c) and__2241__auto__))
06:52Sgeo|web,(macroexpand '(and a b))
06:52clojurebot(let* [and__2241__auto__ a] (if and__2241__auto__ (clojure.core/and b) and__2241__auto__))
06:52Sgeo|web,(macroexpand '(and a))
06:52clojurebota
06:56ambrosebsSgeo|web: wouldn't dynamic vars be a perf issue vs. algo.monads local bindings?
06:57ambrosebssounds slower
06:57tomoj(also, no bound-fn in cljs :/)
06:57Sgeo|webperf issues ... I guess people really care about that sort of thing :/
06:59ambrosebsSgeo|web: I thought Clojure was supposed to be fast :)
06:59Sgeo|web<elliott> so you can only use one monad at once
06:59Sgeo|webNot entirely sure what he means
06:59ambrosebsI'd suspect protocol monads would be the fastest.
07:00tomojis that conal?
07:00Sgeo|webtomoj: no
07:06ambrosebsSgeo|web: what exactly do we need to know to be able to statically generate the required code?
07:06Sgeo|web?
07:07Sgeo|webNeed to know the expected type of the result of return
07:08Sgeo|webAnd/or have the code somehow know a function to use when return is called
07:08ambrosebsI assume langs like Haskell would have some sort of implicit arg?
07:09ambrosebs(sorry, forgot exactly the issue, makes sense now)
07:10Raynesambrosebs: You should learn Haskell.
07:10ambrosebsRaynes: agreed.
07:11Sgeo|webambrosebs: you could say that return has an implicit arg, passed to it from the type checker
07:11Sgeo|web(return is just an ordinary function, btw, if that wasn't clear)
07:12ambrosebsGot it. return is polymorphic and the type checker infers and instantiates the correct types, *which then affect runtime*
07:13Sgeo|webRight
07:13ambrosebsYes, I have scratched my head for awhile as how to achieve this in TC.
07:14ambrosebsCould we possible make a new kind of function?
07:14ambrosebs*possibly
07:15ambrosebsDoes everything here basically occur in a domonad?
07:17Sgeo|webNo. domonad is basically clojure.algo.monads's macro for Haskell's do syntax
07:17Sgeo|webMy idea is that with-monad would supply the information that the type-checker would normally supply. But you can use bind and return outside of any special syntax (at least, you could if the type-checker were supplying what it needed to to the runtime)
07:18borkdudeI'm experimenting a bit with linuxes on a vps… when I use Arch on a 256 I see the memory is almost all used (with free), but when I try Debian on a 512 MB it's also almost used.. does debian really use twice as much when doing nothing, or does linux have a weird way of using memory that's not allocated?
07:18borkdude(this is off-topic, but I do want to host a clojure app on it ;))
07:19ambrosebsSgeo|web: Ok. Sounds like a lot of extra work.
07:19Raynesborkdude: Arch for a server is kinda like jumping off a bridge, or so I hear.
07:19RaynesIt feels good on the way down, but eventually you hit bottom and die.
07:19borkdudeRaynes yes, I heared this
07:20borkdudeRaynes that's why I'm trying debian now
07:21alex_baranoskywhat's the best place to report a bug with the new reducers?
07:23tomojcurious, what's the bug?
07:24ambrosebsSgeo|web: perhaps if we wrap each position that needs dyn vars provided with some macro, Typed Clojure can generate the right bindings for you.
07:24Sgeo|webdyn vars are just a substitute for having something like TC generate bindings
07:25ambrosebsoh right.
07:25ambrosebsThat was an optimistic suggestion :)
07:25ambrosebsYou should implement your idea.
07:26ambrosebsI'd love to see it in action.
07:26Sgeo|webWhat would make sense is for all uses of return to accept an extra argument and TC fills it in
07:27ambrosebsSgeo|web: yes.
07:28Sgeo|webI have Javascript stuff I was supposed to be writing tonight
07:28Sgeo|webUgh
07:33wei_what happened to the s3 utils in noir?
08:05borkdudeisn't this a bit weird, why memory usage increases after openjdk install?
08:05borkdudehttps://www.refheap.com/paste/7439
08:10borkdudeI guess the +/- buffers cache is most important after reading up a bit on this
08:16bonegaIf I have a def-style macro, what are my options for getting doc-tools to pickup my docstrings?
08:16bonegaI basically have something that evaluates to a defn-form
08:17bonega(doc thesymbol) works
08:17clojurebotexcusez-moi
08:17bonegabut the tools for generating documentation of course fails
09:16borkdudeany advice on how to start and stop "java -jar someleinuberjar.jar" in a a script in /etc/init.d in debian?
09:17yerinleis there a way to import multiply java classes in one command (import '(java.util *)) ?
09:18yerinleor do I have to import each class separately?
09:28gfredericksseparately, though you can save space with (import '[java.util List Map ...])
09:33borkdudeI guess this is kind of how people do it?
09:33borkdudehttp://www.shayanderson.com/linux/add-startup-script-or-service-with-linux-on-bootup.htm
09:33borkdudekillall -v java… hmm
09:33cmnthis is what pid files are for
09:34borkdudecmn tnx for the pointer, will read about it
09:34cmnjust look under /var/run
09:36borkdudecmn yeah, it looks like I have to create my pid file manually for a .jar running?
09:37cmnyour distribution may have helpers
09:38borkdudecmn I could also use this, what do you think? lsof -t /home/borkdude/twitter-service-0.1.0-SNAPSHOT-standalone.jar
09:38cmnon Debian and derivatives, start-stop-daemon(8) can do this for you
09:38borkdudecmn I'm using Debian
09:39cmnthat would bind your startup script to a specific version of the service
09:41borkdudecmn yes, I could resolve that with a symbolic link, or isn't that your point?
09:42borkdudecmn whatever, start-stop-daemon looks better
09:42cmnit would not let your script upgrade
09:42cmnas you'd be searching for something that's not running
09:57jonasendnolen: I couldn't find any examples of (usage of) core.logic/cvar. I tried https://www.refheap.com/paste/7336 but that didn't work as I expected.
10:23jonasendnolen: looking at https://github.com/clojure/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L4026 I also tried https://www.refheap.com/paste/7449 without success
11:08yedidoes anyone have examples of people using clojure to do ML/AI?
11:19mpenetyedi: prismatic
11:20yediright
11:20yedii wish they would write more about their experiences with it
11:20mpenetyeah, they used to be more open. They removed all their repo from github
11:22yedireally?
11:22yediwhackkk
11:22mpenetthey used to publish under getwoven (or woven) and then clj-sys orgs
11:22mpenetthere are some forks left here and there, but it's > 2yo
11:23mpenetex: https://github.com/seancron/work
11:25arcatanzenrobotics uses clojure to do ML/AI. they haven't written about their experiences either, though.
11:31gfredericksis joda the best way for doing math on dates (without time)?
11:34mpenetgfredericks: less painfull yes (using clj-time), when it's trivial stuff I just convert to long and do it manually, depending on the context
11:42gfredericksa long representing a day?
11:42mpeneta java.util.Date instance
11:42mpenetbut as I said, for trivial stuff
11:43mpenet,(.getTime (java.util.Date.))
11:43clojurebot1355070867468
11:43gfredericksokay, so representing milliseconds
11:43mpenetyes
11:43gfredericksI'd rather avoid the redundant information
11:45gfredericksjoda has LocalDate, which seems to be the closest to what I want
11:45gfredericksotherwise I'd just roll my own. local date math is a lot simpler than time.
11:51borkdudegfredericks wasn't there a library for this, clj-time?
11:52borkdudeit just wraps joda
11:56gfredericksright of course
11:57gfredericksborkdude: the readme doesn't suggest it handles bare dates explicitely
11:58borkdudegfredericks don't know how well it's maintained either, never really used it
12:02gfrederickswoah; the clj-time project.clj uses numeric keywords (e.g., :1.2)
12:02gfredericksI think I saw an issue on jira complaining that the reader accepts those
12:46devngfredericks: i think the documentation for edn makes that complaint null
12:55solussddoes anybody know how to tell the clojurescript compiler to minify?
12:58solussdnevermind, looks like setting :pretty-print to false does it
13:07bsteubersolussd: you might want advanced mode
13:08solussdyup, i set it to pretty-print false when compiling advanced mode (compiling clojurescript code via noir-cljs)
13:08devnbsteuber: if you're not using external javascript libraries definitely use :optimizations :advanced
13:08seangroveJesus, there are too many videos to watch from the clojure eXchange
13:08devnlol
13:09solussdusing advanced + pretty-print took a 780KB clojurescript file down to 149KB. I think that's noticable to clients. :)
13:09bsteuber:)
13:09solussd(+pretty-print false)
13:15gfrederickssolussd: I bet it gzips quite well as well
13:15solussdno doubt
13:15gfredericksI gzipped an advanced CLJS file that was about 3x the size of jquery, but when they were both gzipped they were almost the same
13:16solussdclojurescript is a godsend.. I *hate* writing javascript- totally breaks my flow. Clojurescript + the fetch XHR library makes it almost fun. :)
13:23gfredericksmy `lein repl` keeps timing out while it compiles
13:24bsteubersometimes happens to me, too
13:24bsteuberI just do lein compile first then
13:32ivansomeone on the mailing list needs to know which Closure Library jar actually contains third_party
13:32ivanor perhaps he must make his own or something
13:50dnolentomoj: yes about the patch for the new threading operators
13:51dnolenjonasen: you need to look at how cvars are used in the simple unifier - I don't really want to explain any high level interfaces much because they are bound to change soon.
13:56gfredericksI feel like I've had this issue before. I enter a data-reader literal at the repl, and it prints a runtime exception. But then *1 is bound to the correctly read form.
13:57gfredericks(the exception claiming that it doesn't know about the tag I used)
13:59jonasendnolen: I'll take a look, thanks
14:02dnolenjonasen: basically cvars aren't really meant to be anywhere except to support the simple unifier - if you're using run* they are completely unnecessary.
14:02dnolen"meant to be used", I mean.
14:03amalloygfredericks: i wouldn't be too surprised to hear it's a problem of nrepl (or whatever repl frontent) having a different set of data readers than your app
14:03gfredericksamalloy: yeah I started thinking that, because anything not involving the repl seems to work fine
14:03dnolenjonasen: because of that I don't believe I've done any work to guarantee they are actually run in the general case - if you look at the simple unifier you'll see there is some extra code to ensure they are actually run.
14:06jonasendnolen: ok, so when using run* i should drop down to 'project' instead
14:06dnolenjonasen: no
14:07dnolenjonasen: you don't need project if you have constraints
14:07dnolenjonasen: what I'm saying is that cvar is not a part of the API at all
14:07dnolenjonasen: it's an implementation detail for the simple unifier
14:08dnolenjonasen: it sounds like your use case is simple and you're already using run* in kibit right?
14:11dnolenjonasen: if that's the case try defc which is likely to become something people can actually use, (defc numberc [x] (number? x)), (run* [q] (numberc q)), (run* [q] (numberc q) (== q "foo"))
14:22jonasendnolen: what's the difference between constraints and core.logic/pred?
14:23dnolenjonasen: do you mean predc?
14:23jonasenno, I mean https://github.com/jonase/core.logic/blob/master/src/main/clojure/clojure/core/logic.clj#L2005
14:23jonasenIt's the "non-relational", right?
14:24dnolenjonasen: yes that's non-relational, clause order matters.
14:25dnolenjonasen: constraints basically defer their execution until some or all arguments have become ground. so they allow you to work relationally.
14:26dnolenjonasen: now that we have constriants any usage of project is pretty much discouraged.
14:27jonasenI see. Could you give a minimal example of using constraints with the unifier?
14:27rodnaphinterop question - how do i call a java method with no args? (.getMessages folder) is giving me the error that no property getMessages exists...) have read the docs and it seems this should work?
14:28gfredericksyep, should work
14:29rodnaphgfredericks: ok thanks, must be something else i'm doing then. will keep trying.
14:30dnolenjonasen: I don't have a minimal example because I haven't decided how that is going to work.
14:30dnolenjonasen: Kevin and I wrote something up that I think could work but I need to implement it.
14:31samfloresI believe that it was asked millions of times, but what's the most idiomatic way to load libs/namespaces: require or use?
14:32gfredericksrequire
14:33jonasendnolen: are you considering (? x number?), or some other syntax? Can I read what you have written, link?
14:33ziltigfredericks: Why that? When using :as, aren't they pretty much the same?
14:34gfrederickszilti: the use functionality has been added to require, so I think use is quasi-deprecated
14:34samfloresgfredericks: thanks.
14:35ziltigfredericks: Thanks.
14:35ziltiI have a library here that's not in a repository. I placed it in projectroot/lib, how do I tell Leiningen to use it?
14:36gfredericksleiningen really really wants that library in a maven repo
14:36ziltiBut I really really don't want to create a repo just for that jar file
14:37gfredericksyou have to argue with leiningen about it for twenty minutes first
14:37dnolenjonasen: 90% sure it'll work by passing a map of lvars or sets of lvars -> constraints
14:37gfrederickszilti: maven has a local repo on your computer
14:38dnolenjonasen: http://gist.github.com/4156747
14:38ziltigfredericks: Ah, yes, the .m2 dir..
14:39gfrederickszilti: there are maven commands for adding jarfiles there
14:39gfredericksI think install-file is the main one
14:39gfredericksyou'll need a pom
14:43jonasendnolen: thanks for your help. I was confused about A) what cvars were meant to be used for (I thought you could use them interchangeably with lvars) and B) that I could use constraints (today) with the unifier. Things are clearer now.
14:43jonasendnolen: I'll take a look at the unifier proposal
14:45dnolenjonasen: sorry for the confusion. yet constraints work great today when working directly w/ the run* interface. the high level interface is still getting sorted out.
14:45dnolenyet -> yes
14:46jonasenand if I want to use constraint with (run* ...) I should pre-define my constraints with (defc ..)
14:54ziltilein-localrepo plugin looks POMising.
15:03jonasendnolen: Is this the correct usage of predc (It seems to work): (run* [q] (== 3 q) (predc q number?))? And should predc be used instead of the old pred?
15:06bordatouein clojure how do i implement a queue where insertion at the rear and deletion at the head
15:06gfredericksthere's a queue data structure
15:06gfredericks,(into clojure.lang.PersistentQueue/EMPTY [2 3 4])
15:06clojurebot#<PersistentQueue clojure.lang.PersistentQueue@6b58c280>
15:06bordatouegfredericks: can you make use of list to attain this behaviour
15:07gfredericksbordatoue: if you're interested in implementing one you could google the baker's queue
15:07gfredericksotherwise the PersistentQueue type should work fine
15:07gfrederickslists will not naively work, as you probably suspect
15:08bordatouethanks gfredericks
15:09jonasendnolen: What is the difference between (defc numc [x] (number? x)) and (defn numc [x] (predc x number?))?
15:11bordatouegfredericks: i couldn't find information on persistentQueue, i have been searching clojure datastructure,http://clojure.org/data_structures is this a part of clojure data structure
15:11gfredericksit's built in, just not well documented
15:11mthvedtdoes clojure/lein support remote debuggers?
15:11gfredericks,(-> clojure.lang.PersistentQueue/EMPTY (conj 7) (conj 3) (conj 4) (pop))
15:11clojurebot#<PersistentQueue clojure.lang.PersistentQueue@8d94be90>
15:11gfredericks,(-> clojure.lang.PersistentQueue/EMPTY (conj 7) (conj 3) (conj 4) (pop) seq)
15:11clojurebot(3 4)
15:12gfredericksbordatoue: you can get the empty queue as per above, and use conj/pop/peek as necessary
15:13bordatouegfredericks: is there any way to know what interfaces this type inherits and the methods inherited by the interfaces
15:13gfredericks,(ancestors clojure.lang.PersistentQueue)
15:13clojurebot#{clojure.lang.Seqable java.lang.Iterable clojure.lang.IPersistentStack java.util.Collection clojure.lang.Obj ...}
15:14gfredericksbordatoue: the clojure source is always available as well
15:14bordatouecool, is this the only datastructure that inherits IPersistanceStack
15:14gfredericksit'll be in there with the java code
15:15gfredericksno vectors do as well
15:15gfredericksin fact it is odd to me that a queue would want to be considered a stack
15:15gfredericksoh and lists are stacks
15:16bordatouegfredericks: so a pop on queue pops from head whereas pop on a vector from the rear
15:16gfredericksyep
15:17gfredericksit pops from whence it is efficient to pop
15:17bordatouecool, thanks for the information. Its been helpful
15:17gfredericksno probalo
15:24dnolenjonasen: I haven't made any promises about anything in 0.8.0
15:24dnolenjonasen: but predc is a little bit more flexible then using defc.
15:26dnolenjonasen: defc is more likely to survive - and yes you should prefer a constraint based solution like predc / defc over pred
15:33mpenetbordatoue: you can also use this fn https://gist.github.com/2053633 to get an overview of the ancestors. ex: https://gist.github.com/4121044
16:04thorwilis there a way to take a var as argument to a function and to use the varname to build a keyword in the function?
16:05gfrederickslike you want to turn #'first into :first?
16:06Bronsa, (keyword (.sym #'+))
16:06clojurebot:+
16:07bbloomBronsa: or with metadata rather than interop:
16:07bbloom,(-> #'+ meta :name keyword)
16:07clojurebot:+
16:07Bronsaoh, that's better
16:08thorwilBronsa: that does not work within a fn
16:09gfrederickshere is the worst way I can think of to do it on short notice:
16:09gfredericks,(-> #'first str (clojure.string/split #"/") last clojure.string/reverse (str ":") clojure.string/reverse read-string)
16:09clojurebot:first
16:09Bronsathorwil: are you trying to do eg (fn [x] (-> x var .sym keyword))?
16:10gfrederickspresumably worse methods could be developed if it was important
16:10thorwilBronsa: yes
16:10Bronsayou can't do that
16:10gfredericksoh oh are we about to learn about macros?
16:11hyPiRiongfredericks: an interesting method, indeed.
16:11thorwilgfredericks: what i want is trivial with macros
16:11gfredericksthorwil: oh is that why you were asking about functions specifically?
16:11thorwili just thought for a moment there might be a more flexible fn based approach
16:12thorwilyes
16:12gfrederickseither the function has to accept a var instead of a symbol, or you need to use resolve to turn a symbol into a var -- but know that the latter is namespace-relative
16:14hyPiRion,((fn [foo] (-> foo meta :name keyword)) #'+)
16:14clojurebot:+
16:14hyPiRionWith the name itself (e.g. +) it's impossible.
16:14hyPiRionAs a function, that is
16:16thorwilhmm, that might do it
16:16thorwilthanks folks, gotta get back to this tomorrow. and likely read up on smybols/var/resolve :)
16:38tgoossenshow can i do this: (defn add [& args] (+ ?????)) (i know i can use reduce for such things but that's not the point
16:39ssideristgoossens: what are you trying to achieve?
16:39tgoossens(defn create [class* & args]
16:39tgoossens (new class* args))
16:40tgoossenshow can i get the args right?
16:40tgoossensconcrete example
16:40ssiderisI think you may be looking for (defn add [& args] (apply + args))
16:40ssiderisyeah apply should work
16:40ToxicFrogThis may be a stupid question but couldn't you just do: (def create new) ?
16:41kmicu, (doc apply)
16:41clojurebot"([f args] [f x args] [f x y args] [f x y z args] [f a b c d ...]); Applies fn f to the argument list formed by prepending intervening arguments to args."
16:41kmicutgoossens: ok?
16:41tgoossenshmm myes
16:41tgoossensi think i get it
16:41kmicu, (+ 1 2 3 4)
16:41clojurebot10
16:41kmicu, (apply + [1 2 3 4])
16:41clojurebot10
16:42RaynesYikes https://github.com/cgrand/enlive/pulls
16:42Raynes:\
16:42RaynesGuess that's where all pull requests go to die.
16:42kmicusubmitted to cgrand/enlive 2 years ago...
16:43tgoossens,(apply new String)
16:43clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: new in this context, compiling:(NO_SOURCE_PATH:0)>
16:43tgoossenswhy doesn't that work but
16:43mpenetapply wont work with new
16:43tgoossens(new String "a")
16:43tgoossens,(new String "a")
16:43clojurebot"a"
16:43tgoossenswhy?
16:43clojurebotwhy is the ram gone is <reply>I blame UTF-16. http://www.tumblr.com/tagged/but-why-is-the-ram-gone
16:43kmicuwhy new? :/
16:43tgoossensi'm making a tool in clojure for manipulating java objects to study them
16:44tgoossensdon't be afraid i'm not trying to do OO in clojure :-)
16:44ToxicFrogtgoossens: "new" is a special form, not a function or macro
16:44mpenetspecial form for java interop, I think you at least need to know the number of args, and then use a lambda to wrap the calls
16:44mpenetor use some java magic I don't know about
16:44ToxicFrog,(doc new
16:44clojurebot#<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading>
16:44ToxicFrog,(doc new)
16:44clojurebotHuh?
16:44ToxicFrogDammit clojurebot
16:44tgoossenslol
16:45tgoossenstardis.core=> ,(doc new)
16:45tgoossens-------------------------
16:45tgoossensnew
16:45tgoossens (Classname. args*)
16:45tgoossens (new Classname args*)
16:45tgoossensSpecial Form
16:45tgoossens The args, if any, are evaluated from left to right, and
16:45tgoossens passed to the constructor of the class named by Classname. The
16:45tgoossens constructed object is returned.
16:45tgoossens Please see http://clojure.org/java_interop#new
16:45tgoossensnil
16:45ToxicFrogYes, I know, I was trying to get clojurebot to display that for your benefit.
16:45Raynesdsantiago: tinsel is still faster than enlive and capable of the same things, right?
16:45tgoossensi know
16:45tgoossensand thats why i posted it
16:45tgoossensbecause mr clojurebut didn't want to :p
16:45kmicutardis x])
16:46dsantiagoRaynes: I don't know, has enlive been extensively rewritten? I haven't heard otherwise.
16:46RaynesNope.
16:46tgoossensi don't have any idea on how to achieve what i want atm :p
16:46Raynesdsantiago: You still maintain tinsel, right? I mean, when it needs maintained of course.
16:46dsantiagoRaynes: It's capable of doing many of the same things, but not all.
16:46dsantiagoI do consider it maintained. Don't know of any problems, can't think of anything to add. Works for me.
16:47kmicutgoossens: can you describe what do you want?
16:47Raynesdsantiago: I need to use *something* to transform some markdown code that has been transformed to HTML before storing it in the db.
16:47kmicu, (map #(new String %) ["a" "b" "c"])
16:47clojurebot("a" "b" "c")
16:47dsantiagoRaynes: I think tinsel is probably not a good match for that.
16:48RaynesThat's sad.
16:48tgoossenskmicu: i want a function (create classname & parameters)
16:48dsantiagotinsel is for pre-parsed templates. Things that aren't going to change. It actually invokes the compiler on each template to make it go fast.
16:48RaynesEnlive has 11 open pull requests and a version range.
16:48dsantiagoThat is going to be much slower than just parsing and interpreting the template.
16:48dsantiagoFor a one-shot, I mean. It's a pay-up-front to go fast a million times type model.
16:50tgoossensi'll just experiment until i have something that works
16:50tgoossensprobably have to write a macro
16:50tgoossensa nice challenge for me :p
16:50tgoossens:)
16:53Raynesdsantiago: I'm gonna see if I can do a little work on a fork of enlive. Also, hickory is cool. Thank heavens for jsoup, amirite?
16:54sshackAre there any decent split testing libraries for clojure?
16:54dsantiagoRaynes: I was going to suggest you pull a bultitude on it, if that's the case.
16:54dsantiagoAnd yes, jsoup is fantastic.
16:54Raynesdsantiago: I have this nasty habit of deciding to maintain projects and rewriting half of them and stuff and then hating myself in the morning.
16:55dsantiagoRaynes: I have a very similar problem.
16:57ghengiswhere do clojure programmers usually publish release announcements?
16:57mpenetghengis: on the mailing list
16:57ghengiscool, thanks
16:59tomojwhere did "ANN: foo" come from?
16:59ToxicFrogtgoossens: does this work?
17:00tomojoh, just.. usenet, says wikipedia
17:00ToxicFrog,(defmacro create [class* & args] `(new ~class* ~@args)) (macroexpand '(create String "a" "b" "c"))
17:00clojurebot#<Exception java.lang.Exception: SANBOX DENIED>
17:00tgoossenswow
17:00ToxicFrog,(printf "eat me clojurebot")
17:00clojureboteat me clojurebot
17:00tgoossenscool
17:01ToxicFrogAnyways that appears to work for me locally
17:01tgoossenswhat does the ~@ exactly?
17:01mpenettgoossens: unsplices the sequence [a b c] becomes a b c
17:01tgoossensinteresting
17:01ToxicFrogThat's an "unquote-splice", replaces the symbol with its sequence-contents.
17:02ToxicFroguser=> (macroexpand '(create String "a" "b" "c"))
17:02ToxicFrog(new String "a" "b" "c")
17:02ToxicFrogPlain "~" would cause it to expand to (new String ["a" "b" "c"])
17:02tomojyou can't apply that macro, though..
17:03tgoossenshmmm
17:03tgoossensi get what it does
17:03ToxicFrogHmm, point.
17:03tgoossensi don't get how it does it
17:06amalloy&'`(new ~class ~@args) ;; maybe instructive?
17:06lazybot⇒ (clojure.core/seq (clojure.core/concat (clojure.core/list (quote new)) (clojure.core/list class) args))
17:07amalloyi mean, that is literally how ~@ works. `(new ~class ~@args) is identical to (concat (list 'new) (list class) args), or to (list* 'new class args), if you like
17:09tomoj(defn document [] js/document)
17:10tomojcompiles to: function document() { return document }
17:10tomojexpected?
17:10ToxicFrogtgoossens: can you expand on what you don't get about it? Did amalloy's explanation help?
17:11tgoossenstoxicfrog: oh. Its just i have no experience at all with macro's so i was a bit confused
17:11tgoossens(and still am)
17:11ToxicFrogtgoossens: aah.
17:12tgoossensbut i should just read the documentation
17:12ToxicFrogSo, (defmacro create [class* & args] `(...)) is saying "when expanding macros, replace (create ...) with the `(...)"
17:13ToxicFrogWithin that `(...), ~foo means "in the generated code, insert the value of foo" and ~@foo means "insert the contents of foo, which should be a list"
17:13p_ldefinitely better than syntax-rules :)
17:14ToxicFrogSo, (create String "a" "b" "c") results in macro expansion with class* being String and args being ["a" "b" "c"]
17:14tgoossensmmmyes
17:14ToxicFrog`(new ~class* ~args) would expand into (new String ["a" "b" "c"]); using ~@args instead "unpacks" args, so you get (new String "a" "b" "c")
17:15tgoossenscool
17:16ToxicFrog(I think the fundamental thing to "get" here is that a macro is a function that takes some arguments and returns a code fragment - an abstract syntax tree - based on those. The `(...) is the AST to return; ~ and ~@ let you "fill in" parts of that with values at macro expansion time, rather than when the result of the expansion is actually executed)
17:17tgoossensi think i start to get it :)
17:17tgoossens*i'm starting
17:18ToxicFrog<3 macros
17:18tgoossensyeah its really amazing
17:18tgoossensonce you start learning them
17:18tgoossensin java for example
17:19tgoossenswhen something was not possible
17:19tgoossensyou had to think long time how you can "patch" / workaround that problem
17:19tgoossenshere
17:19ToxicFrogAnd the fact that in lisp you're basically writing everything in ASTs already makes them go down much smoother than the equivalent in something like metalu.
17:19ToxicFrog*metalua.
17:19tgoossens"lets add a new feature!"
17:21tgoossensg2g
17:21tgoossensso long and thanks for all the fish ;)
18:23jweisscan the ns macro just create an alias to a ns without :require'ing it? (just for using namespaced keywords)
18:30cemerickjweiss: doesn't look like it. refer itself doesn't accept vectors (necessary for :as) anyway.
18:38tomojinto-kv: https://www.refheap.com/paste/f83eb49d4520e7522014c7395
18:38tomojbblöom: ^
18:38tomojbut, seqs of pairs are not reduce-kv
18:38tomojshould they be, somehow?
18:39tomoji.e. seq implements IKVReduce by assuming the values are pairs?
18:40tpopecemerick: do you have time to discuss this issue we've been going back and forth about in the channel?
18:41cemericktpope: About 5 minutes. Hadn't been following the channel tho; do you mean the github issue?
18:41tpopeyes the github issue
18:41tpopebbloom: ^
18:41bbloomtpope: yeah, i just saw the email
18:42tomojbblöom: nvm, since you wanted (into {} (partition 2 kvs)), this is irrelevant
18:42Raynes!last
18:42RaynesWrong channel.
18:42tpopecemerick, bbloom: the session business I demonstrated is weird, but since clone works, it's not really a big deal
18:43tpopethe main issue is where is out and err disappearing to
18:43bbloomcemerick: i was surprised to see string keys rather than keywords. i dunno anything about nrepl, but i was about to warn tpope and his fledging clojure skills that keywords and strings aren't interchangable, but then i saw your example used them, so maybe they are interchangeable for nrepl :-)
18:43cemericktpope: the sid in your example is nil, which is bizarre
18:44cemerickbbloom: they're turned into keywords by the time middleware/handlers see them
18:44bbloomcemerick: makes sense
18:44cemerickthey're strings if you're using the default bencode transport
18:44tpopecemerick: err, it wasn't when I was playing with it interactively
18:44cemericks/strings/strings on the wire
18:44tomojthough (into-kv {} (partition 2 kvs)) would work if (partition 2 kvs) were IKVReduce.. hmm
18:44cemericktpope: spooky
18:44bbloomcemerick: gotcha.
18:45tpopecemerick: in fact, I
18:45cemericktpope: re: "parsing"; you really need to consume things in terms of messages, not e.g. grepping for "done", etc.
18:45cemerickdunno how that percolates into vimscript, etc
18:45tpopejust added a println on sid and it's set for me
18:45tpopethe error that comes back mentions the same sid
18:46cemerickvery spooky
18:46cemericktpope: what rev of nREPL?
18:46tpope0.2.0 beta 9
18:46cemerickhrm
18:46cemericktpope: try 0.2.0-RC1
18:47cemerickI quashed some wonkiness between b9 and b10/RC1
18:48tpopecemerick: same
18:48cemerickhrmph
18:48cemericktpope: I'll sink into it tomorrow morning
18:48tpopecemerick: so nrepl/client just slurps up everything available within 100ms, correct?
18:48tomoj";;aseqs are iterable, masking internal-reducers" in clojure/core/protocols.clj. so this impl for ASeq relies on the undefined choice of that over the Iterable impl? interesting...
18:48tpopeor whatever timeout you pass in
18:48cemericktpope: right
18:49cemerickthough, it's not slurping; it's a seq of responses
18:49tpopeokay
18:49tpopeso what happens when something takes longer than 100ms to eval?
18:49tpopeI guess what I'm getting at is how does a client know when to print a prompt again?
18:50cemerickyou'll get an empty seq
18:50cemerickFor interactive usage, most clients just wait indefinitely
18:50cemerickthough I understand you can't do that
18:50tpopewell my client isn't in clojure, so I'm not sure how "empty seq" translates
18:50cemerickoh, no data, EOF
18:51tpopemy socket should actually eof?
18:51cemerickThe timeout is critical for noninteractive use cases, where you don't want a tool blocking on getting e.g. code completion data
18:51cemericktpope: sorry, being fast and loose with terminology
18:52cemerickthere will be no data
18:52tpopeI'm trying to find the difference between "no data" and "no data *yet*"
18:52cemerickAlways the latter
18:52cemerickThis is related to the (tricky) semantics of "done"
18:53cemericke.g. if you've sent an eval message with a given ID, and it spins up a future that prints stuff, when do you send a "done" message?
18:54tpopewell, I kind of have to give up on that case. which is why I keep going back to a "when does a client print its prompt"
18:54cemerickright now, nREPL's eval middleware prints "done" when all forms sent in the code have evaluated, but messages with the same ID may be seen later with :out and :err entries
18:54tpopeokay
18:54tpopestuff that happens after that "done" I'm going to have to give up on
18:54bbloomcemerick: done-ness is tricky in general, then cancel-ing is even more tricky… clojure's futures lack a notion of a process tree
18:55cemerickbbloom: right; for exactly that reason, nREPL's interrupt won't touch futures, threads, queued agent sends, etc.
18:56tpopeall this aside, the blocking issue is out and err. If I send an eval request on a new request with an existing session, I don't get out and err back
18:56tpopenew connection*
18:57bbloomat the risk of venturing off onto a tangent, there's some work going on surrounding listenable futures and future seqs. i'm pushing for process trees :-)
18:58cemericktpope: well, something's wonky there.
18:58cemerickFirst, I'm going to figure out why I'm seeing something different than you with the code you posted.
18:58cemericktpope: got to run; I'll be back tomorrow morning.
18:59tpopeokay cheers
19:00bbloomtpope: a simple @cemerick spurred him to help. maybe i'll @kotarak and we can get the VimClojure runtime files "decomplected" too :-)
19:00tpopeyeah I've been meaning to reach out :
19:00tpopewhat with my snarky README and all
19:00bbloomtpope: i can just open a ticket to eliminate dependency on VimClojure, this way i'm the bad guy :-P
19:01tpope:)
19:03tpopebbloom: I'd love for the static versions to ship with vim
19:03tpopeit's weird that he started them separate, but then complected them
19:03bbloomtpope: i'll mention that in the ticket. i don't know enough about the vim distro processes to help there
19:04tpopebbloom: you email bram and say "hey I wrote these runtime files I think should be included" and he replies like "k"
19:04bbloomtpope: heh, simple enough
19:04bbloomtpope: https://github.com/tpope/vim-foreplay/issues/12
19:05tpopeoh wow, you weren't kidding
19:07bbloomtpope: i've inadvertently been the guy who writes the inflammatory email so many times, that i've learned when to intentionally apply to quasi-inflammatory email
19:07bbloomit's a curse.
19:12tpopetime to play good cop I guess
19:17tpopeokay guys! so I'm actually trying to learn clojure myself
19:17bbloomtpope: happy to help. if you have any questions, fire away
19:18tpopeI thought a good first task might be "parse a netrc". it basically looks like machine foo.bar login baz password quux over and over
19:18tpopesimple enough, right?
19:18tpopeso here's my first stab: https://www.refheap.com/paste/7456
19:19bbloom(doc into)
19:19clojurebot"([to from]); Returns a new coll consisting of to-coll with all of the items of from-coll conjoined."
19:19bbloom,(seq {:x 1 :y 2})
19:19clojurebot([:y 2] [:x 1])
19:20bbloom,(into {} [[:x 1] [:y 2]])
19:20clojurebot{:x 1, :y 2}
19:20bbloomtpope: ^^ that should help you clean up your reduce block
19:20tpopelet me try!
19:21tpopeokay, that was simple. no more outer reduce
19:21bbloomtpope: new pastie?
19:22tpopebbloom: https://www.refheap.com/paste/7457
19:22bbloom(doc ->>)
19:22clojurebot"([x form] [x form & more]); Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the last item in second form, etc."
19:22bbloom(doc ->)
19:22clojurebot"([x] [x form] [x form & more]); Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, inserts the first form as the second item in second form, etc."
19:23bbloomthose are useful for flattening the nesting of multistep proceedures
19:23bbloomso you can have netrc-tokenize, reduce, and into all at the same level and appear in the order that they are evaluated
19:23tpopeokay, I know the threading macros. I'm missing how to apply them here
19:24tpopethat's enough for me to take a stab
19:26ToxicFrogtpope: rather than going (into (reduce (netrc-tokenize ...))), you can (->> ... netrc-tokenize reduce into) or similar.
19:29bbloomwe'll just keep providing one hint at a time until it's pretty!
19:31tpopeokay I think I got it: https://www.refheap.com/paste/7459
19:33tpopethe peek and pop business was what felt particularly ugly
19:34bbloomtpope: yup
19:34bbloompeek and pop aren't that common to use
19:34bbloomlet me see…. hm
19:36tpopeI should add that I have additional requirements that may well render this moot :)
19:36bbloomtpope: eh, the learning won't be moot
19:36tpopeyeah I agree
19:36tpopewhich is why I didn't lead with "help me bolt more crap onto this"
19:36bbloomso i'm not familiar with netrc files
19:37tpopeif you've ever used heroku, you have one
19:37bbloomheh ok
19:37tpopeall they are is login/passwords for hostnames
19:37bbloomthe goal is to get a map of machine name to login credentials?
19:37amalloyi think you want to partition your input, tpope. instead of trying to do everything in the reduce step on a single k/v, split it up into chunks between each instance of "machine"
19:37tpopeyes
19:38bbloomthe goal is to get something like {"mylaptop" {:username "brandon" :password "abc123"}}
19:38bbloom ?
19:38tpopebbloom: yeah
19:38tpopeI have tests actually, let me paste them
19:38bbloomtpope: amalloy is right, netrc-parse should be broken down into a part that parses individual records, and one that parses the whole thing
19:39tpopeI agree
19:39bbloomeach individual record should be [machine-name credentials]
19:39bbloomand then it's trivially to map that over a file and into {}
19:42tpopetests: https://www.refheap.com/paste/7461
19:42tpopefirst two pass, third is a new requirement: a "default" machine
19:43tpopeI bring up the default machine now because this two pass thing seems like a good time to introduce it
19:44tpopeokay, so how would I split it into machines?
19:45bbloom,(clojure.string/split "machine foo login bar machine baz login quux" #" +")
19:45clojurebot["machine" "foo" "login" "bar" "machine" ...]
19:45tpopegot that. my re-seq was basically the same thing
19:45bbloomoh dur, yeah
19:46bbloom(doc partition-by)
19:46clojurebot"([f coll]); Applies f to each value in coll, splitting it each time f returns a new value. Returns a lazy seq of partitions."
19:46bbloomyou can use sets as a predicate:
19:46bbloom,(#{:foo} :bar)
19:46clojurebotnil
19:46bbloom,(#{:foo} :foo)
19:46clojurebot:foo
19:46tpopehmm
19:47bbloom,(partition-by #{"machine"} ["machine" "foo" "bar" "machine" "baz"])
19:47clojurebot(("machine") ("foo" "bar") ("machine") ("baz"))
19:47bbloom(doc take-nth)
19:47clojurebot"([n coll]); Returns a lazy seq of every nth item in coll."
19:47tpopebbloom: what if someone's login or password *is* machine?
19:47bbloomtpope: heh, good point....
19:47amalloytpope: do you have a sample input somewhere? i haven't really been following but this isn't a hard problem if i know the inputs
19:48tpopeamalloy: I can make one, sec
19:48bbloomi don't know enough about the format, i would have to read the man page to see how machines are actually parsed...
19:49bbloomamalloy: i'm trying to avoid giving him a solution, he's trying to learn :-)
19:50bbloomtpope: oh, i didn't realize that each field is labeled
19:50bbloom(parition 2 ["machine" "foo" "login" "bar" "password" "baz" "account" "quux"])
19:51bbloom(parition 2 ["machine" "foo" "login" "bar" "password" "baz" "account" "quux"])
19:51bbloom,(parition 2 ["machine" "foo" "login" "bar" "password" "baz" "account" "quux"])
19:51clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: parition in this context, compiling:(NO_SOURCE_PATH:0)>
19:51bbloomer, typing is hard.
19:51bbloom,(partition 2 ["machine" "foo" "login" "bar" "password" "baz" "account" "quux"])
19:51clojurebot(("machine" "foo") ("login" "bar") ("password" "baz") ("account" "quux"))
19:51bbloomthen you can use partition-by and your predicate can be on the first element
19:51bbloomor split-with and a loop
19:52tpopeamalloy, bbloom: https://gist.github.com/4247721
19:53tpopethe macdef stuff is gross. you can omit it if it's simpler
19:54tpopebbloom: okay, that's pretty reasonable, although it breaks down at the "default" cases
19:54tpopecase*
19:54tpopebear with me, ssh has gone to lag city
19:57amalloyyeah, if you want to support "default" rather than "machine default" or something, i don't think anything pretty works well. possibly the best you can do is a reduce over each token, where the reduce is running a miniature little state machine that reminds you what to do with the next token
19:58tpopewell, it's strangely reassuring to hear that the elegant solution I couldn't find probably doesn't exist
19:59bbloom#{"default" "machine"} is a reasonable predicate to split by
19:59tpopeis it easy to show me what that state machine might look like?
20:00tpopebbloom: true, and even/odd sorts out which it is. but you're back to the "what if their login is machine?" problem
20:00bbloomoh, dur, again… default doesn't take an argument
20:01tpopeit's such a simple yet infuriating format
20:01bbloomheh, yeah, b/c you can just imagine that the underlying original implementation is a manual C loop :-)
20:01bbloomanyway, ignoring "real" parsing strategies
20:01tpopebtw, curl and wget both read this file, which is what makes it handy for api credentials
20:02bblooma simple loop is the way to go
20:02tpopedoes this mean I have to use recur?
20:02bbloommaybe? :-P
20:02bbloomso imagine a simple recursive decent parser for a moment
20:03bbloomyou have some token stream and some AST accumulator
20:03bbloombut here, you don't want to mutate the token stream
20:03bbloomso each parse production function should return two values: the AST as transformed, and the new token stream
20:04bbloomso if you have ["machine" "foo" "machine" "bar"] and you parse-machine on that, you should get back [{"foo" {}} ("machine" "bar")]
20:05bbloomif you use that calling convention, you can write a simple recursive solution
20:06tpopeokay
20:06bbloomthen you can loop/recur at the top level until your input token stream is empty
20:07tpopesounds totally possible
20:07tpopedo you have any thoughts about macdef?
20:08bbloomtpope: what's it do exactly?
20:08tpopebbloom: slurps up till the next double newline as a string
20:09tpopebbloom: so in that example, you'd get {"ftp.server" {... :macdefs {"somemacro" "cd somewhere\n..."}}}
20:09bbloomah, i see… hm
20:09bbloomyou need double-newline in your token stream :-/
20:10tpopeI mean, I bet virtually nobody needs this
20:10tpopebut if I was to, say, package it up and release it, it'd be nice if it implemented the full spec
20:10bbloomso #"\S+" probably isn't sufficient for re-split
20:10tpopeyeah
20:10tpopeI'd think you'd need to switch to some sort of reader api
20:11bbloomsignificant whitespace is annoying for parsers :-P
20:12amalloytpope: https://www.refheap.com/paste/7462 is a state-machine impl, which doesn't handle macdef at all
20:13jonasacam i insane for thinking that always aliasing imports and always qualify imported functions with the alias ?
20:13jonasacis a good idea
20:13bbloomjonasac: nope
20:14bbloomuse is mainly for interactive work and some DSL-ish libraries
20:14tpopeamalloy: awesome man
20:15amalloyand it's just splitting on whitespace, so if there's some significance to newlines vs spaces you probably need to toss the whole thing in the trash
20:15tpopeamalloy: I see you raising plain old Exception. is that common for this sort of miscellaneous stuff?
20:15tpopeamalloy: no significance except macdef :/
20:15bbloomtpope: unfortunately, yes :-/ (it's annoying for CLJS portability)
20:15amalloyoh, i dunno. something else might be better, but i rarely bother with anything more than Illegal(State|Argument)Exception
20:16jonasacbbloom: good, seen alot of code that don't do that tho, makes it harder to read
20:16amalloyand it wasn't clear which of those this is
20:17tpopeamalloy: thanks for this. it may take me a bit to grok it
20:20amalloyyou're welcome. keep bringing the light of clojure to the vim savages
20:21tpope:)
20:23bbloomparsing always winds up harder than you expect
20:23bbloomi don't even bother with hacky parser attempts any more, i go straight to formal grammars :-)
20:25bbloomtpope: although it's arc instead of clojure, there is a good example of parser combinators that Hodapp mentioned here: http://awwx.ws/combinator/toc
20:26bbloombut i haven't found a parsing library for clojure that i really like yet… i've tried a few
20:27tpopeneat
20:28bbloomcombinators are fun
20:29bblooma long time ago i made a trivial bullet hell game out of combinators: http://code.google.com/p/bulletcombinators/
20:29bbloompowerful technique
20:29tpopeso long ago that google code was in fashion!
20:30bbloomnov 2009
20:30bbloom:-P
20:30tpopeokay, maybe not in fashion :P
20:30bbloomheh
20:31bbloomi was still working for msft then…. git was practically unusable on windows still
20:31bbloomso glad that period of my life is over....
20:34brehautbbloom: the biggest problem with clojure parsing libraries is they all eventually fade into disrepair
20:40bbloomwe've got max, max-key, but no max-comparer or similar?
20:45amalloybbloom: i think that function is called sort
20:46bbloomwell it's (first (sort …))
20:46bbloombut sort is less efficient really, since max can be implemented O(N)
20:46bbloomeven if sort is lazy, i don't think first sort gives you linear time
21:00stuartsierra`sort` is not lazy.
21:01stuartsierraYou can implement "max-comparer" with reduce.
21:07jonathanwallacei'm attempting to use rich hickey's cartesian product with a couple of ranges which is giving me a lazy sequence like ((1 0) (1 -1)...)
21:07jonathanwallacei'd like to then use the first element in that sequence apply a function to it but i believe first element is being evaluated which is generating an error
21:12jonathanwallacei'd like to apply(map?) a function onto each element returned by cartesian-production function (found here https://github.com/richhickey/clojure-contrib/blob/2ede388a9267d175bfaa7781ee9d57532eb4f20f/src/main/clojure/clojure/contrib/combinatorics.clj#L107)
21:12jonathanwallacecmeiklejohn: it was good sharing a cab with you at rubyconf!
21:13Apage43(map somefn (cartesian-product …)) ?
21:15cmeiklejohnjonathanwallace: Oh, totally!
21:16cmeiklejohnSmall world :)
21:17Apage43jonathanwallace: depending on what you're trying to do you may just want for
21:17Apage43,(for [x [1 2 3] y [4 5 6]] (str x "," y))
21:17clojurebot("1,4" "1,5" "1,6" "2,4" "2,5" ...)
21:26jonathanwallacecmeiklejohn: heh, yep
21:28jonathanwallaceApage43: when i try (map + (cartesian-product ..)) i get an error :(
21:28jonathanwallace,(map + (cartesian-product (range -1 2) (range -1 2)))
21:28clojurebot#<CompilerException java.lang.RuntimeException: Unable to resolve symbol: cartesian-product in this context, compiling:(NO_SOURCE_PATH:0)>
21:29jonathanwallacebut not that error :)
21:29Apage43,(map (partial apply +) [[1 1] [1 2] [1 3]])
21:29clojurebot(2 3 4)
21:31Apage43cartesian-product returns a seq of seqs, so map + was calling + on seqs, instead of numbers
21:31bbloomstuartsierra: that's precisely what i did, i called it max-by: https://www.refheap.com/paste/7463
21:32Apage43I've needed that several times
21:32jonathanwallaceApage43: thank you so much
21:32jonathanwallacei'm only one month (maybe 4 hours total) and was ignorant of partial
21:33jonathanwallaces/only one month/only one month into learning clojure/
21:33tomojthere is also https://github.com/chrismgray/clojure-heap-sort
21:33tomojunfortunately not published anywhere
21:34tomojuseful when you want a lazy seq instead of just the biggest element
21:34Apage43or perhaps a top-N, I'd guess
21:36tomojI'd guess a strict top-N could be done more quickly directly than with a heap sort, dunno though
21:36amalloywow, he's using a single vector to simulate a tree instead of just using an actual tree? really dedicated to performance, or slavishly transliterating from C, i wonder
21:37tomojrewrite it and publish it, please :)
21:38Apage43there's a lot of existing writing on doing heaps that way, I expect it's not a perf thing.
21:39amalloytomoj: i wrote lazy-shuffle; lazy-sort is someone else's problem :P
21:46tomoj(take-shuffled n coll) is statistically equivalent to (take n (shuffle coll)) ?
21:48amalloytomoj: indeed, provided (<= n (count coll))
21:49amalloyi don't really remember why i wrote it as take-shuffled instead of just lazy-shuffle
21:51aaelonyOn large data, I've found it faster to do something like (def random-int [upper-bound] (.nextInt (Random.) upper-bound))
21:51aaelonyif i remember correctly...
21:51tomojso you can either have the output lazy (lazy-shuffle), or the input lazy (reservoir sampling). but not both, I assume?
21:52tomojI think you really don't want to create a new Random every time
21:52aaelonyfine.
21:52aaelonybut rand-nth I've found to be really slow
21:53tomojmaybe because it counts the coll every time?
21:53tomoj..plus the nth every time
21:54aaelonyyeah, unless there's a nice way to memoize it. but even so, sometimes i'd rather not count something very very large
21:54tomojin that case, I think you want reservoir sampling?
21:54tomojbut then it seems you have to decide ahead of time how many you want to pick..
21:55aaelonyi'm content with picking a random number like above
21:55tomojwhere do you get the upper bound if you don't count?
21:55aaelonyI may know it already
21:55aaelonyor something large enough to suffice, that i know exists
21:56amalloyrand-nth is, as expected, egregiously slow for anything that is not both counted and indexed, but is pretty reasonable if you have that condition
21:57aaelonythat's my experience too
21:57tomojrandom-int seems a tiny bit faster than rand-int if you don't recreate the Random every time
21:57tomojs/a tiny bit/moderately/
21:58aaelonyfor me just separating the getting of the random int and then using it to get an nth has been faster
21:59aaelonyideally there's an even faster way
21:59amalloytomoj: you could probably have the input and output both lazy, if you can (a) count the input, and (b) produce the nth input item on demand without needing any other inputs
21:59aaelonyperhaps best is to compute a set of random ints and then asking for the nth
21:59aaelonywhen needed
22:00tomojif you count the input, you don't have the input lazy (or you don't have what I meant when I said "input lazy")
22:01amalloycertainly you can't work on an input that is a lazy-seq
22:01tomojassuming you want lazy output, right?
22:02amalloyi guess what i'm imagining is really just equivalent to (map f (lazy-shuffle (range n-items))
22:02amalloyie, a function to produce the nth item, and knowledge of the upper limit
22:03aaelonybut, isn't (range n-items) wasteful and slow if n-items is large?
22:03tomojwould be interesting if (range n) were IIndexed
22:04gfrederickstomoj: so it'd have to be a special seq type, no?
22:04tomojright
22:05tomojwhich means you have to go add it to all your protocols.. :(
22:05gfredericksit certainly could be, but if you're ever in a situation where you need that then you're doing it weird :)
22:05amalloymy patch to make range foldable is similar to making it indexed
22:05amalloygfredericks: not at all
22:05gfredericksamalloy: what? you disagree with something I said about clojure?
22:06amalloyclojurebot: note the date and time
22:06clojurebotmultimethods are http://clojure.org/multimethods
22:06tomojamalloy: how? there's no r/nth, and r/drop will still be O(n), yes?
22:06gfredericksamalloy: so anyhow I'm curious
22:06amalloytomoj: but the same steps are involved. to fold it in chunks, you have to be able to ask for the nth through mth items
22:07tomojI see, but that functionality is not exposed in a way that lets you skip in O(1)
22:07tomojsince there's no IDrop or whatever
22:07Sgeo|webHow many threading macros are there out there? As in, Enlive's do-> for example
22:08amalloyyeah
22:08Sgeo|webHow many macros are there that are like threading macros except treating some values specially
22:08gfredericksSgeo|web: well if you count libraries then it's difficult to give an exhaustive answer
22:08Sgeo|webAre there likely to be a lot
22:09nightfly_Probably
22:09Sgeo|web:o)
22:09Sgeo|webGiven such a macro, it's easy to write bind...
22:12Sgeo|webThe other direction is probably a very good idea too, a nice easy to understand way to use monads
22:15brehauttype annotations for conj are crazy
22:15tomojthe special treatment is that if the last step returned an m v, the next step is automatically bind instead of normal invoke?
22:18tomojdoes that cause trouble related to m (m a)?
22:28frozenlockRaynes: A little Noir question. On the top of your head, any ideas why when I use (flash-get :some-key), it returns something for two retrievals, instead of one like mentioned in the docs?
22:29RaynesNo idea. It shouldn't.
22:29RaynesI never saw that behavior.
22:30frozenlockHmm... so it's _very_ probably in code.
22:30frozenlockThanks
22:36Raynesfrozenlock: If you can't figure it out, try to get a small reproduce case and create an issue on the lib-noir project.
22:41Sgeo|webtomoj: hmm?
22:42Sgeo|webWhich direction are we talking? Making a threading macro from a monad? Each step in the threading is automatically bind
22:42Sgeo|webHmm, although I guess that might be inconvenient in some cases?
22:43Sgeo|webFor the maybe monad, can treat nil as nothing, everything else as Just whatever
22:43Sgeo|webFor the Just Nothing case, we make a special type called Escape
22:43Sgeo|web(Escape. nil) corresponds to Just Nothing
22:44Sgeo|webInstead of Just (Escape. nil)
22:44Sgeo|webAnd you can escape escape, etc.
22:45frozenlockRaynes: Before I do, could you tell me if I'm missing something important here? Is there a need to be on a different page or something? https://www.refheap.com/paste/7465
22:46RaynesOh. OH.
22:46frozenlockoh?
22:46Raynesfrozenlock: Are you expecting that after the first call to flash-get, it'll vanish?
22:47frozenlockWell.. yes
22:47RaynesYeah, that's how it used to work. Now it works for one *request*. Meaning, you can get the value multiple times, but it goes away after that request.
22:47frozenlockOooooh :)
22:47Raynesfrozenlock: I'll fix the dcos.
22:47Raynesdocs*
22:49Sgeo|webWhat special forms besides quote take lists and don't treat them like code?
22:49frozenlockI will just make my own with the session/swap! then. Thank you for the explanation!
22:50Raynesfrozenlock: I released 1.3.0 tonight and Chris will be pushing the updated website… soon.
22:51frozenlockwait--- you mean 1.3.0 NOT beta4? :P
22:51RaynesI do.
22:51Raynes<3
22:51RaynesNothing has changed from the last beta though.
22:52RaynesIt needed to be a final release so we could update all the documentation.
23:00Sgeo|webHmm, auto-return like I envisioned could really suck in some circumstances
23:01tomojI've been struggling with auto-return too
23:01tomojI think it could sometimes require satisfies? checks?
23:01tomoj..which are slow
23:16sshackRaynes any major changes in 1.3.0?
23:18Sgeo|webtomoj: my concern isn't performance
23:18Sgeo|webtomoj: my concern is, what happens when you give it whatever, and suddenly you accidentally give it a list (say, if you're in the list monad), and instead of acting like you expect it to, it treats it specially
23:19Sgeo|webWhy should your code need to check "Oh, and if it's a list, do this extra thing"