2013-01-09
| 00:21 | bbloom | are there any good generators/streams/haskell-iteratees libraries for clj? i'm looking at https://github.com/roman/river but i'm wondering if there are others. i've got an algorithm that could really benefit from a yield operator |
| 00:23 | tomoj | is 'yield operator' pretty specific? |
| 00:24 | bbloom | like yield in python |
| 00:26 | bbloom | i'm also wondering if reducers can help me... |
| 00:27 | bbloom | since it seems like rhickey went down the streams path, and then abandoned it for a mix of chunked lazy seqs plus reducers |
| 00:27 | bbloom | but i'm still not quite sure |
| 00:28 | bbloom | but i think i should study reducers more... |
| 00:28 | tomoj | the generators in python just give a synchronous iterator-like interface, right? |
| 00:30 | bbloom | tomoj: yeah, it's an imperative, continuation-based sequence building thinggie |
| 00:31 | bbloom | i have a sequence transformation where i want to occasionally perform buffering look ahead, so i need to be able to thread some state along the way for a map/reduce |
| 00:32 | bbloom | the real issue is that i need to interleave two processes: one buffering/enqueing and the other dequeing |
| 00:32 | bbloom | otherwise, my buffer is O(N) and useless to me |
| 00:34 | tomoj | you lost me there, but reducers do seem promising based on my weak understanding of the earlier 2 of your last 4 messages |
| 00:34 | tomoj | ...i.e. not the real issue |
| 00:34 | bbloom | so assume you have some sequence of items |
| 00:34 | bbloom | and you want to transform it |
| 00:35 | bbloom | however, occasionally, you don't know how to transform an item |
| 00:35 | bbloom | you'll need to "look ahead" |
| 00:35 | bbloom | ie buffer up those items until you find the information you need |
| 00:35 | bbloom | one way to do that is to loop over the source and only "yield" when you have what you need |
| 00:35 | bbloom | that "yield" operator will cause some other code to run, which will consume the yielded value |
| 00:36 | bbloom | and by that mechanism, somebody is receiving values and so there is no buffer between the two processes |
| 00:36 | tomoj | yeah, that seems reducer-friendly so far, if I understand you |
| 00:37 | tomoj | you want to do a straight map on the non-lookahead items, and only thread reduce state through on the buffers? |
| 00:37 | bbloom | tomoj: something like that... i think |
| 00:37 | tomoj | where the result of the reduce on a buffer is the result item for the entire buffer?- |
| 00:37 | bbloom | i have a tree which i'm flattening into a sequence (ie interior nodes are converted to begin/end pairs wrapping their children) |
| 00:37 | bbloom | then i map over that to annotate them |
| 00:38 | bbloom | then i want to map over it one more time, but sometimes i need to do look ahead |
| 00:38 | bbloom | and then i want to map over it one last time to print out some values |
| 00:38 | bbloom | it's that look ahead step i don't quite understand yet |
| 00:38 | tomoj | so the result has the same number of items as the flattened tree |
| 00:38 | bbloom | yes |
| 00:39 | bbloom | although filtering/ammending the items shouldn't matter |
| 00:39 | bbloom | the tricky bit is just the buffering |
| 00:39 | tomoj | I just was not sure whether the buffers got collapsed into single result items |
| 00:39 | bbloom | in this particular case, they do |
| 00:40 | tomoj | so the result has fewer items than the flattened tree when lookahead was performed |
| 00:40 | bbloom | sorry, let me clarify: |
| 00:40 | tomoj | ah, I see an ambiguity |
| 00:41 | bbloom | flatten tree of N items yields I*2 interior nodes + L leave nodes |
| 00:41 | bbloom | let I*2+L = M |
| 00:41 | bbloom | i then transform M -> M nodes to annotate them |
| 00:41 | bbloom | i then transform M -> M again, but sometimes with look ahead buffering |
| 00:42 | bbloom | and, for simplicity, let's say i then just doseq that and print it out |
| 00:42 | tomoj | right, I see |
| 00:42 | tomoj | why won't just seqs work? |
| 00:42 | tomoj | with a function like partition but which takes a function that tells it how/when to partition |
| 00:42 | bbloom | they could work, but it would be a tricky laziness problem |
| 00:43 | bbloom | where i'd have to do nonsense like (lazy-cat nil ....) |
| 00:43 | bbloom | and somehow thread the buffer through |
| 00:43 | tomoj | anyway seems to me you could similarly write a function like r/partition |
| 00:43 | tomoj | (which may not exist yet.. but there is a r/partition-by patch somewhere) |
| 00:44 | bbloom | doesn't exist, but i found the r/partition-by patch |
| 00:44 | bbloom | it has a buffer! :-) |
| 00:44 | tomoj | that would return a new reducer of sometimes values, sometimes buffers, and then you can r/map over that? |
| 00:44 | bbloom | yeah, i think that's the ticket |
| 00:45 | bbloom | my buffer is actually a double-list finger-tree because i'm going to do pruning on the buffer as well :-/ heh |
| 00:45 | tomoj | then doseq doesn't work but you can do (reduce (fn [_ v] (println v)) nil r) :/ |
| 00:46 | tomoj | or more cryptically (r/reduce (fn ([_]) ([_ v] (println v))) r) |
| 00:49 | tomoj | er, (fn ([]) ...) I mean |
| 00:50 | bbloom | tomoj: so there's still one other issue: what do i reduce TO ? |
| 00:50 | bbloom | obviously i need to reduce to a seq, but what kind? |
| 00:51 | tomoj | by "reduce to a seq" you mean you think the return value of reduce should be a seq? |
| 00:51 | bbloom | yeah |
| 00:51 | tomoj | so you can doseq it? |
| 00:51 | bbloom | just like partition does |
| 00:51 | bbloom | well it can reduce to the next stage of a reducer, i don't care if i eventually doseq it or not |
| 00:51 | bbloom | although i assume i can |
| 00:52 | bbloom | looking at http://dev.clojure.org/jira/browse/CLJ-991 patch v4 |
| 00:52 | tomoj | if you go the reducer route your partition-with (or whatever) should just return a reducer |
| 00:52 | bbloom | notice how it calls "append" |
| 00:52 | amalloy | bbloom: i think you can write yield in terms of continuations pretty easily, right? have you looked at delimc? |
| 00:52 | bbloom | oh i see |
| 00:53 | bbloom | amalloy: yeah, i contributed a big pile-o-patches to delimc & have a half finished CPS transform for clojure script |
| 00:53 | bbloom | amalloy: i'm trying to see if there is a non-imperative solution via reducers |
| 00:53 | tomoj | that partition-by looks really weird to me |
| 00:53 | bbloom | tomoj: so it's yielding one partition at a time |
| 00:53 | bbloom | which makes sense |
| 00:53 | amalloy | something like a year ago i was talking to dnolen in here about how you can use just lazy-seq to give you everything yield allows |
| 00:53 | tomoj | anyway, you won't get a seq back out of your reducer - I guess it's possible but it would seem silly |
| 00:54 | tomoj | you'd just use the reduce I wrote above on the reducer partition-with returns instead of doseq |
| 00:54 | amalloy | bbloom: have you written a version that uses yield? ie, presuming yield exists, what would the code look like? |
| 00:56 | aphyr | So... my project used to specify clojure:clojure:pom:1.3.0, back in the day |
| 00:56 | bbloom | amalloy: https://github.iu.edu/sabry/PPYield/blob/master/PPYield.hs#L352-419 like that confusing mess :-) |
| 00:56 | amalloy | yikes, just the anchor part of that link worries me |
| 00:57 | aphyr | ... which I guess is replaced by [org.clojure/clojure "1.3.0"] now |
| 00:57 | aphyr | Is there a sane way for me to run old versions from git without having to edit project.clj every time? |
| 00:57 | amalloy | that is not what the clojure would look like with yield. that is a big blog of haskell, man |
| 00:58 | amalloy | aphyr: i don't think clojure:clojure:pom:1.3.0 ever worked - the clojure artifact has always had groupid org.clojure |
| 00:58 | bbloom | yeah, my point exactly haha |
| 00:58 | amalloy | bbloom: if you want yield in clojure, write it in clojure and assume that yield works. then, you can either figure out how to write yield, or do the smallish amount of work necessary to convert yield to lazy-seqs |
| 00:58 | technomancy | aphyr: lein had a stupid special case for a few jars waaaay back in the day |
| 00:59 | technomancy | it only applied to clojure and clojure-contrib |
| 00:59 | aphyr | amalloy: sorry, in project.clj it was: just [clojure "1.3.0"] |
| 00:59 | bbloom | amalloy: i also have a lazy-seqs version in haskell to reference, but it's pretty hairy because it requires "trying the knot" |
| 00:59 | amalloy | technomancy: not waaaay back; you can't call 1.x ancient and still refuse to release 2.0 |
| 01:00 | aphyr | Kinda frustrating, I'm trying to benchmark my project and it's broken as recently as... nine months ago, haha |
| 01:00 | technomancy | amalloy: right; I guess the ancient part was actually emitting bare clojure |
| 01:00 | amalloy | oh, as in lein new did that? |
| 01:00 | technomancy | it would have been only on projects where `lein new` was called 2+ years ago I think |
| 01:00 | technomancy | yeah |
| 01:00 | aphyr | Yeah, it did. |
| 01:00 | bbloom | amalloy: http://notepad.mmakowski.com/recursive%20knot |
| 01:01 | aphyr | Can you think of a dumb workaround, or do I need to patch project.clj every time I check out? |
| 01:01 | bbloom | repmin == replace minimum |
| 01:01 | bbloom | notice (mn, tr) = walk mn t |
| 01:01 | technomancy | aphyr: how many projects is this? |
| 01:01 | bbloom | circular laziness :-/ blargh |
| 01:01 | aphyr | 1. |
| 01:01 | technomancy | ...? |
| 01:01 | aphyr | technomancy: just one project |
| 01:01 | aphyr | I'm writing a program that does automated performance regression testing. |
| 01:02 | technomancy | oh, gotcha |
| 01:02 | aphyr | Benchmarks riemann against old versions to compare how different functions changed, that sort of thing |
| 01:02 | technomancy | you could install a dummy clojure/clojure project that depends on org.clojure/clojure |
| 01:03 | technomancy | lein new clojure; cd clojure; sed project.clj *mumbles* ; lein install |
| 01:04 | amalloy | sorry, bbloom, those sorts of things give me a headache as well |
| 01:05 | bbloom | yeah, i want to pretty print some stuff & i was pulling my hair out trying to configure the native pretty printer. so i have a "data all the things" style pretty printer, but it's mega slow b/c it recursively recomputes the whole tree over and over again, so i'm trying to implement this linear runtime, bounded space version :-P |
| 01:06 | bbloom | it's fucking complicated lol |
| 01:06 | bbloom | but now i'm determined to finish it. |
| 01:07 | bbloom | i'm almost certain that tomoj is on the right path with r/partiton-by, i'm gonna give that a shot |
| 01:07 | tomoj | :( |
| 01:07 | tomoj | when you linked to the knot tying I threw my hands up, metaphorically |
| 01:08 | bbloom | tomoj: don't frown! you saved me a wild goose chase down the continuations rabbit hole :-) |
| 01:08 | aphyr | Goot call technomancy, thanks! |
| 01:08 | aphyr | *good |
| 01:09 | kovas | what is pretty about the printing? |
| 01:10 | bbloom | kovas: the indentation and line breaks |
| 01:10 | kovas | ah |
| 01:10 | kovas | sounds like a job for the attribute grammar |
| 01:10 | kovas | :) |
| 01:11 | kovas | i checked out that paper you referred, looks interesting |
| 01:11 | bbloom | kovas: i saw something about that in all my reading, but decided to avoid chasing that particular tail because these very smart folks who wrote these papers manually translated to lazy seqs |
| 01:11 | bbloom | soooo |
| 01:11 | bbloom | heh |
| 01:11 | bbloom | but i have no idea what an attribute grammar is |
| 01:12 | bbloom | but i suspect that it has something to do with that totally bad ass ometa TCP/IP implementation :-) |
| 01:12 | bbloom | buffers & look ahead as non-deterministic parsing! |
| 01:13 | kovas | my interpretation is that its a way of annotating a tree with metadata, where the metadata is defined by functions on the relative positions of nodes |
| 01:13 | kovas | so there is a way of passing data around the tree |
| 01:13 | kovas | but theres probably other ways of looking at it |
| 01:14 | bbloom | kovas: personally, i really like the flattened view of trees |
| 01:14 | bbloom | i find state machines with manual stacks to be much easier to reason about |
| 01:14 | bbloom | and then, gloriously, i can use reductions to print out all the intermediate states of my algoirthm |
| 01:15 | kovas | pretty printing is somehow in the literature as one of the canonical applications |
| 01:15 | kovas | hmm |
| 01:15 | tomoj | but there is no reductions for reducers |
| 01:15 | tomoj | I have one in a gist somewhere but not sure how good it is |
| 01:15 | bbloom | tomoj: shouldn't be hard to add that too :-P |
| 01:15 | tomoj | I used an atom |
| 01:16 | bbloom | tomoj: i think the same strategy as the partition-by patch would work... |
| 01:17 | tomoj | hmm https://gist.github.com/543a721f0f44cf48459d |
| 01:19 | tomoj | I see someone else did http://dev.clojure.org/jira/browse/CLJ-1113 |
| 01:19 | tomoj | and they also use an atom |
| 01:19 | tomoj | but they used reducer.. |
| 01:19 | tomoj | for some reason I had thought you couldn't use reducer for that |
| 01:19 | tomoj | anyway I still haven't figured out how to use something like reducer to get IKVReduce, so :) |
| 01:26 | yunfan | is there any book like "a byte of python" which introduce the basic of clojure programming |
| 01:27 | tomoj | what shall we do about middleware? :'( |
| 01:27 | Raynes | amalloy: I have found a way to get laser in lazybot. Alert the men. |
| 01:28 | Raynes | tomoj: Oh, you. |
| 01:28 | Raynes | tomoj: So, I saw you were calling me stupid for some reason last night? |
| 01:28 | Raynes | I couldn't really figure out what you were saying. |
| 01:29 | tomoj | I wonder how much of the required ordering of middleware is caused by middleware which unnecessarily destroys information in the request/response |
| 01:29 | Raynes | I was hoping you could elaborate. I don't think I'm stupid, but we should be sure. |
| 01:29 | tomoj | I don't think I was calling you stupid |
| 01:29 | Raynes | I think you called me reverse stupid. |
| 01:29 | tomoj | maybe, but only a little :) |
| 01:29 | Raynes | I thought you might have been drunk. |
| 01:30 | tomoj | nope, I'm not much of a drinker |
| 01:30 | Raynes | Anyways, so what about the css selectors? |
| 01:31 | tomoj | I also find it important to distinguish between calling an idea (reverse) stupid and calling its author (reverse) stupid |
| 01:31 | tomoj | well, why do you want to implement css selectors? |
| 01:31 | tomoj | I can maybe imagine there are reasons that would make sense to me |
| 01:31 | tomoj | my point was just, why not use clojure data instead of strings? |
| 01:32 | Raynes | tomoj: I really don't want to at all. I'd prefer everybody just use selector functions. I planned to write css selectors when I get bored solely because people are afraid of an extra character or two in their selectors after enlive. |
| 01:32 | tomoj | "reversed stupidity" would be avoiding using clojure data just because enlive did it, and your project is (complement enlive) |
| 01:32 | Raynes | But I wanted to do real CSS selectors. |
| 01:32 | Raynes | I wanted to do real CSS selectors because it seems like it'd be really cool to be able to copy a selector from your css file right into laser. |
| 01:32 | tomoj | but maybe you have other reasons for avoiding using clojure data |
| 01:33 | tomoj | right, that's a reason that makes sense to me to implement css selectors |
| 01:33 | Raynes | But you can implement both versions. |
| 01:33 | tomoj | yeah, plan to :) |
| 01:33 | tomoj | well, not the css, I'll leave that to you |
| 01:33 | Raynes | I plan for it to work like (css "foo.bar") = a selector to give to laser. |
| 01:34 | tomoj | yeah, that seems useful |
| 01:34 | Raynes | So the other version can be done like (enlive [:foo.bar]) or something. |
| 01:34 | Raynes | Mostly, I want it to be clear that everything is just functions. |
| 01:34 | Raynes | Functions functions bloody functions. |
| 01:35 | tomoj | yeah, when I first tried laser I appreciated that |
| 01:35 | tomoj | but my thought was more "good foundation" than "I want to always write it this way" |
| 01:35 | Raynes | I don't know why people hate combinators so much. *shrug* |
| 01:36 | tomoj | though I'm still not sure about the foundation, largely because I have mismatched requirements |
| 01:36 | Raynes | It's weird how people are all like "Functions are great, we should use them for everything" until they get to something to do with HTML, and then it's like "We need 4 DSLs, a new language, and preferably a new toolset to go with it." |
| 01:36 | Raynes | :p |
| 01:37 | tomoj | I like combinators, I just think I'd appreciate shortcuts for very common stuff |
| 01:37 | bbloom | tomoj: any idea why the reducers namespace is not found in 1.5.0-RC1 ? |
| 01:37 | Raynes | Yeah, I agree. It wasn't a criticism. I think it'll be nice. |
| 01:37 | bbloom | do i need a particular version of something? |
| 01:38 | tomoj | you either need java, uh, 7 I think, or to add some jsrwhatever to your deps |
| 01:38 | tomoj | but shortcuts should still let you drop stuff done in raw 'bloody functions' directly in |
| 01:39 | bbloom | tomoj: heh i'm on 1.6 i'll find 1.7 |
| 01:39 | Raynes | tomoj: Anyways, thanks for clarifying. :) |
| 01:40 | tomoj | fwiw I was referring to http://lesswrong.com/lw/lw/reversed_stupidity_is_not_intelligence/ — should suggest a weaker interpretation than I can imagine you'd get if you didn't know it was a reference |
| 01:40 | bbloom | is installing the jdk directly from oracle hte recommended thing these days? |
| 01:41 | tomoj | are you on a debianish? |
| 01:41 | bbloom | tomoj: osx |
| 01:42 | tomoj | can you even use oracle's java on osx? |
| 01:42 | bbloom | technomancy: so make your lein script magically obliterate the need for me to think about oracle :-P |
| 01:42 | tomoj | thought you were stuck with apple's |
| 01:42 | bbloom | tomoj: i just downloaded jk-7e9-macosx-x64.dmg from oracle |
| 01:42 | bbloom | *shrug* |
| 01:42 | tomoj | hmm, there was an issue about this |
| 01:42 | bbloom | dammit. |
| 01:43 | tomoj | https://groups.google.com/d/topic/clojure-dev/um5f3p4KsXU/discussion |
| 01:43 | bbloom | seems to work :-) |
| 01:43 | bbloom | i'm back up and running & have reducers now |
| 01:43 | technomancy | bbloom: can't fight the OS |
| 01:43 | bbloom | technomancy: sure you can! you just aren't likely to win |
| 01:44 | technomancy | I'm content to just make fun of the bad guys on IRC |
| 01:51 | tomoj | so part of the problem with middleware is that dependencies aren't encoded anywhere except in the code |
| 01:51 | bbloom | tomoj: so i think a reducer + an atom like you did for reductions = a state transducer |
| 01:52 | tomoj | sweet |
| 01:52 | technomancy | bbloom: last I checked openjdk on OS X is kind of a train wreck |
| 01:52 | tomoj | should I know what "transducer" means? |
| 01:52 | bbloom | technomancy: oh yeah, completely |
| 01:52 | bbloom | tomoj: no lol |
| 01:52 | bbloom | http://en.wikipedia.org/wiki/Finite_state_transducer |
| 01:52 | bbloom | tomoj: i guess the idea is that it's a reducer type thing, but at each step of the way, there is also a state that gets threaded through |
| 01:52 | bbloom | which is what i need |
| 01:53 | tomoj | ah, yes I should, but I never took automata |
| 01:53 | bbloom | me neither really |
| 01:53 | bbloom | anyway, if you view a tranducer as a machine on an assembly line, you can glue a bunch of them together |
| 01:54 | bbloom | they are like reducers in that sense |
| 01:54 | bbloom | and, like reducers, the input conveyer belt and the output conveyer belt aren't necessarily running at the same speed |
| 01:54 | tomoj | and the reducer api can implement them and works seamlessly with them? |
| 01:54 | bbloom | i guess if you just add an atom, then yeah, that's what you've got: a stateful transducer |
| 01:55 | bbloom | although, in theory, you could do it without an atom if you had a r/map-state type function which took some (f state x) instead of just (f x) |
| 01:55 | bbloom | but also needs to return [state' x'] instead of just x' |
| 01:56 | tomoj | reminds me of zip folding |
| 01:56 | tomoj | which can apparently be implemented with cps |
| 01:56 | tomoj | I still don't understand oleg |
| 01:56 | bbloom | and then you start getting into arrows... the generalization of monads... *head explodes* |
| 01:57 | bbloom | who'd have guessed that pretty printing was so complicated? lol |
| 01:57 | tomoj | I've kept my head from exploding so far by blindly trusting conal's dislike of arrows (for frp at least...) |
| 01:57 | tomoj | I guess it will have to explode someday :( |
| 01:57 | aphyr | Raynes: props for conch, BTW. Just found myself reinventing it. |
| 01:57 | bbloom | FRP is a totally separate conversation :-P |
| 01:57 | tomoj | yeah, but that's the only reason I have to care about arrows right now |
| 01:58 | tomoj | er, s/zip folding/fold zipping/ |
| 02:07 | tomoj | Räynes: xml->'s selectors are functions (Loc -> (U Loc [Loc] Bool nil)) |
| 02:07 | tomoj | a problem is that it requires that funky macro |
| 02:08 | tomoj | where (Loc -> Bool) is more straightforward to compose |
| 02:08 | tomoj | but it occurs to me that maybe xml->'s style of composition is like kleisli composition of a selector monad |
| 02:11 | bbloom | hmm that's annoying. defcurried is private ? |
| 02:11 | aphyr | Raynes: I don't understand how me.raynes.conch, conch, the docs, and the current github master relate to one another, though |
| 02:11 | aphyr | they all seem to have very different structure |
| 02:12 | tomoj | it is annoying |
| 02:12 | tomoj | also rfn |
| 02:15 | bbloom | curried functions are kinda ugly in clojure :-/ |
| 02:16 | ro_st | what's the diff between curried fns and partials? |
| 02:16 | egghead | curried is one at a time |
| 02:16 | egghead | special case of partial |
| 02:17 | tomoj | hmm |
| 02:17 | ro_st | ah so (curry + 1) vs (partial + 1 2) ? |
| 02:18 | tomoj | no, (curry +) |
| 02:18 | tomoj | say (= 3 (((curry +) 1) 2)) |
| 02:18 | tomoj | which only makes sense if you treat + as binary |
| 02:19 | tomoj | so you could write (def ^{...} map #(partial (fn [f coll] ..) %)) or something? |
| 02:20 | ro_st | yogthos|away: great work with luminus! |
| 02:20 | tomoj | but you really just write (defn map ([f] (partial map f)) ([f coll] ...)) or (def map (curry (fn [f coll] ...))) or (defcurried map [f coll] ...) |
| 02:25 | bbloom | tomoj: so both take & drop are stateful w/ atoms |
| 02:26 | tomoj | yeah |
| 02:26 | tomoj | should your thing be foldable? |
| 02:26 | bbloom | tomoj: no |
| 02:26 | tomoj | oh well |
| 02:26 | tomoj | seems like trees should be foldable |
| 02:26 | bbloom | but i'm printing it to a non-tree shaped terminal :-P |
| 02:27 | aphyr | Uh, this is probably a terrible question, but does anyone know how to correctly stop 'lein run'? |
| 02:27 | tomoj | oh, sure |
| 02:27 | aphyr | I've just discovered that Process.destroy is useless for subprocesses and there's apparently no way to get a pid out of a Process object |
| 02:33 | bbloom | tomoj: it is extremely non-obvious how to write a reducer... heh |
| 02:41 | bbloom | tomoj: so f1 is the "next reducer"? |
| 02:42 | tomoj | f1 is the monoid you finally pass to reduce |
| 02:42 | tomoj | I call it "the reducef" |
| 02:43 | tomoj | (perhaps I should have written "reductionsf" and "reducef", not "reducef" and "f1" |
| 02:44 | bbloom | i must be tired, but i'm having a hard time making sense of this... |
| 02:44 | bbloom | what is the k/v impl ? |
| 02:44 | tomoj | which code are you looking at? |
| 02:44 | bbloom | reducers.clj |
| 02:44 | tomoj | well, kv is not really applicable to you I don't think |
| 02:45 | tomoj | you can (reduce-kv (fn [ret k v] ...) init a-map) |
| 02:45 | tomoj | but none of the reducer combinators preserve IKVReduce, so you can't do anything else with it |
| 02:45 | tomoj | it's just for faster reduce over maps right now |
| 02:45 | bbloom | i don't have a kv reduction |
| 02:46 | bbloom | so is that just noise at this point? |
| 02:46 | Raynes | aphyr: I probably forgot to push, I guess. |
| 02:46 | tomoj | yeah |
| 02:46 | tomoj | you don't need IKVReduce so you can ignore it |
| 02:47 | bbloom | so basically i want a version of map, that i'll call transduce, that takes an initial state and threads the state through |
| 02:47 | bbloom | rfn says "3-arity" but mine has an extra argument: init |
| 02:47 | bbloom | so presumably i can't use rfn ? |
| 02:47 | bbloom | and wouldn't want to anyway, since i don't have a k/v impl |
| 02:47 | tomoj | ah |
| 02:47 | tomoj | well, yes |
| 02:47 | Raynes | aphyr: Just fixed it. |
| 02:47 | tomoj | the fact that rfn does something about kv is a total red herring |
| 02:48 | Raynes | aphyr: And thanks! Glad you like it. |
| 02:48 | bbloom | tomoj: yeah, confusing the hell out of me lol |
| 02:48 | aphyr | Raynes: cool. Stuck trying to get a real pid out of a Process now. |
| 02:48 | tomoj | I've posted about that and created a ticket but got not one peep from anybody |
| 02:48 | aphyr | About to pull in JNA, wish me luck. D-: |
| 02:48 | tomoj | except ämalloy saying he thought it was an accidental omission |
| 02:48 | Raynes | aphyr: You definitely can't from Java itself. |
| 02:48 | Raynes | aphyr: I wouldn't do that. |
| 02:49 | Raynes | aphyr: I'd just write a little script in bash, python, ruby, etc, and shell out to it if any way possibly. |
| 02:49 | Raynes | possible* |
| 02:49 | tomoj | I think really rich has already thought about everything I've thought about around IKVReduce, and he knows that it needs more hammock time |
| 02:49 | tomoj | and it was an intentional omission |
| 02:49 | tomoj | with rfn being partly half-baked |
| 02:50 | Raynes | aphyr: Or do what ol' Rich advocates and write a service with an API that you can call from Clojure. ;) |
| 02:50 | tomoj | but anyway |
| 02:50 | bbloom | heh ok, i'm getting closer :-P |
| 02:51 | aphyr | Raynes: Yeah, problem is I'm trying to benchmark a whole process running in lein |
| 02:51 | aphyr | and lein starts a subprocess... which can't be killed |
| 02:51 | aphyr | because process.destroy considers child processes irrelevant or something (do they become zombies? what kind of acid were they on?) |
| 02:51 | bbloom | tomoj: and i'm understanding why defcurried and rfn are private: i don't want them lol |
| 02:51 | aphyr | Turns out you can snarf it with reflection, at least on linux |
| 02:51 | Raynes | Ugh, yeah. |
| 02:52 | tomoj | are you using reducer? |
| 02:52 | bbloom | well maybe defcurried |
| 02:52 | bbloom | i'm trying to decide if i want to use reducer now |
| 02:52 | bbloom | i don't think i do |
| 02:53 | tomoj | if you use reducer (which is public) for an operation, then rfn would be useful, if not for the kv noise |
| 02:54 | tomoj | (which, I'll emphasize, is also 100% noise in reducers.clj) |
| 02:54 | bbloom | so i'm trying to decide what to do about the two overloads of coll-reduce |
| 02:55 | bbloom | s/decide/understand |
| 02:55 | tomoj | the [coll f] arity is for people who call clojure.core/reduce and don't pass an initial state |
| 02:55 | tomoj | if you call clojure.core.reducers/reduce and don't pass an initial state, the initial state is (f) |
| 02:56 | tomoj | which is why rfn is somewhat useful, to automatically preserve the zero arity of a transformed reducef |
| 02:56 | tomoj | (i.e. the identity of the monoid) |
| 02:56 | bbloom | isn't the monoid only relevant when foldable? |
| 02:56 | bbloom | i don't think i have a monoid in my case b/c i have a linear state |
| 02:57 | bbloom | & am not foldable |
| 02:57 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: am in this context |
| 02:57 | tomoj | it's also used when you just r/reduce without an initial value |
| 02:57 | tomoj | e.g. (r/reduce + [1 2 3]) calls (+ 0 1) first |
| 02:57 | tomoj | (+ (+) 1) that is |
| 02:58 | tomoj | so if you use r/reduce, you have to care about preserving the monoid identity |
| 02:58 | tomoj | r/reduce without an explicitly provided initial value, that is.. |
| 02:58 | bbloom | i want to require that callers of transduce provide an initial state |
| 02:58 | tomoj | sure, that's different |
| 02:59 | tomoj | transduce won't actually do any reduction, right? it just returns a reducer |
| 02:59 | bbloom | so should i only implement the [coll f init] variant? |
| 02:59 | bbloom | right |
| 02:59 | tomoj | you want (reduce f (transduce r)) to be illegal? |
| 03:00 | tomoj | (and (r/reduce f (transduce r)) to be legal only if (f) is legal?) |
| 03:00 | tomoj | (as always..) |
| 03:00 | bbloom | so transduce takes three arguments: [f init seq] |
| 03:00 | Ember- | http://arstechnica.com/security/2013/01/extremely-crtical-ruby-on-rails-bug-threatens-more-than-200000-sites/ |
| 03:00 | amalloy | is it the mass-assignment thing being reported again? |
| 03:01 | bbloom | or i guess [f init non-foldable-reducer] |
| 03:01 | bbloom | amalloy: nah, it's some new nonsense with an injection flaw or something |
| 03:01 | Ember- | amalloy: dunno, but that bug allows you to execute arbitrary code on the underlaying server |
| 03:02 | aphyr | amalloy: there are a bunch of default deserializers in the rails body handlers |
| 03:02 | aphyr | including yaml, which includes a syntax for creating arbitrary instaces of any class and setting instance vars |
| 03:02 | aphyr | tl;dr stop automatically coercing strings to arbitrary datatypes |
| 03:03 | bbloom | lol |
| 03:03 | bbloom | yaml always struck me as such a silly idea |
| 03:04 | bbloom | "It's like XML, only with syntax that's nearly impossible to generate programatically!" |
| 03:04 | aphyr | I can't even generate it by hand. ;-) |
| 03:04 | ro_st | You Avoid Markup Language |
| 03:06 | aphyr | Raynes: I can add (pid process) to conch if you're interested |
| 03:07 | aphyr | but in order to be portable to windows I think I'll have to pull in JNA |
| 03:07 | bbloom | tomoj: i think i'm just incapable of following the flow of code where the order of arguments matters. i can *never* remember the order of the arguments to reduce and always need to check the docs. i need a language where all functions accept and return a map :-P |
| 03:08 | Raynes | aphyr: Is it a large dependency? |
| 03:08 | aphyr | JNA? yeah. :( |
| 03:09 | amalloy | bbloom: it's pretty easy to remember what order reduce takes its arguments in if you imagine trying to add together a bunch of numbers. like, (reduce 0 + coll)? no, the function must come first or it reads bizarrely. (reduce + coll 0)? that feels pretty awkward. (reduce + 0 coll)? aha, we're adding to zero all the things in coll |
| 03:10 | bbloom | amalloy: i can always remember that coll comes last because it's the least likely thing to be partially applied, so it makes sense to have it last. it's just the first two arguments i always mess up because i think "init == first" |
| 03:10 | bbloom | :-P |
| 03:11 | Raynes | aphyr: How does JNA work. Does it use native dependencies or something? |
| 03:12 | bbloom | amalloy: also i *hate* when functions don't come last in javascript/coffeescript, since partial application is rare there and coffeescript just makes it so nice to have indented callbacks.... setTimeout is evil in that respect |
| 03:13 | bbloom | 98% of the time, the order of arguments has zero semantic meaning too, hence maps are just so pleasant for business logic |
| 03:15 | Raynes | aphyr: Okay, so here is what I think. |
| 03:16 | Raynes | aphyr: It looks like JNA automatically extracts its native library and does whatever with it itself. I think it'd be best to add a dependency on pomegranate and automatically add JNA to the classpath if someone calls the pid function. |
| 03:16 | Raynes | aphyr: If you don't want to go through that trouble, just write the pid function and I'll handle the pomegranate stuff. |
| 03:16 | tomoj | bbloom: interesting |
| 03:17 | tomoj | I've wondered what it would be like to put map entries on the factor stack |
| 03:17 | tomoj | or, factjor |
| 03:17 | tomoj | and treat the entire stack as a map |
| 03:17 | bbloom | tomoj: i thought about that briefly and then realized that it's basically just dynamic variables lol |
| 03:18 | tomoj | if you do normal stack stuff under (on top of?) the map entries? |
| 03:18 | tomoj | s/stack stuff/factjor words/ |
| 03:19 | Raynes | aphyr: I'm going to give it all a bit more thought though. Another option is to add the dependency, but don't actually define the function unless the dependency is present which would allow people to exclude the dependency. |
| 03:19 | bbloom | tomoj: http://docs.factorcode.org/content/article-namespaces.html |
| 03:19 | Raynes | That might be the better idea. |
| 03:19 | Raynes | I don't think most people are going to care about the extra dependency. |
| 03:19 | tomoj | ah yes! |
| 03:20 | tomoj | I also want a word that takes the entire frame and reifies it into a map |
| 03:20 | tomoj | (the entire "implicit assoc") |
| 03:20 | tomoj | and maybe one that takes a map and makes that the implicit assoc |
| 03:20 | Raynes | aphyr: Yeah, we should do that. Ignore everything else I said. |
| 03:20 | tomoj | oh.. http://docs.factorcode.org/content/article-namespaces-combinators.html ?? |
| 03:20 | lazybot | tomoj: Uh, no. Why would you even ask? |
| 03:21 | Raynes | aphyr: Still though, if you want you can just write the pid function and I'll do the other stuff. |
| 03:22 | aphyr | ok |
| 03:22 | aphyr | sorry, busy screaming into the JVM void |
| 03:24 | bbloom | tomoj: clojure has similar operators: bound-fn, push-stack-bindings, pop-stack-bindings, get-stack-bindings, etc |
| 03:24 | bbloom | it's actually quite amazing how much clojure & factor have in common |
| 03:27 | bbloom | anyway tomoj thanks for helping me think through this a bit |
| 03:27 | tomoj | http://tech.groups.yahoo.com/group/concatenative/message/2762 |
| 03:28 | tomoj | I don't think I really want concatenative logic programs anyway, I just had to google for it |
| 03:29 | bbloom | haha |
| 03:29 | bbloom | i think it's one of these things where you use the right paradigm for the problem at hand |
| 03:29 | bbloom | my interest in concatenative programming, and the motivation for creating factjor, was so that i can serialize side effects |
| 03:29 | tomoj | but I think maybe it would be nice to have a word that takes a quotation, looks at metadata on the words in the quotation and rewrites the quotation using a simple logic program on the metadata |
| 03:30 | bbloom | in particular because i want to diff two tree structures and output a program to be executed against the DOM |
| 03:30 | bbloom | which is what my talk at Clojure/West will be about! :-) |
| 03:30 | tomoj | shoot |
| 03:30 | bbloom | tomoj: quotation transformations & pattern matching are pretty cool too |
| 03:31 | bbloom | tomoj: see factorcode.org/littledan/match.pdf |
| 03:31 | bbloom | ill be back in a little while |
| 03:32 | tomoj | don't think I'll get to see your talk — are the two tree structures two versions of a model? |
| 03:33 | tomoj | two uh, abstract markup trees? |
| 03:33 | tomoj | or what |
| 03:49 | tomoj | hmm http://i.imgur.com/i2MRN.png |
| 03:50 | tomoj | the magic seems to leak out of clj-http.core/request |
| 03:50 | tomoj | so clj-http-lite can't use it |
| 03:50 | tomoj | whereas ring has different servers that don't leak? |
| 03:51 | tomoj | oops, there should be magic on the ring side too |
| 03:51 | tomoj | but it doesn't leak out of the ring server |
| 03:51 | tomoj | (I think?) |
| 03:53 | tomoj | well, clj-http-lite wouldn't use clj-http.core/request anyway, it'd provide it's own client, obviously |
| 04:42 | bbloom | tomoj: k i'm back & i got transduce working, but i'm calling it map-state |
| 04:43 | bbloom | pretty much all of my problems were caused by defcurried expecting a meta data map & rfn not being what i want... i guess i deserve that for using private macros :-P |
| 04:43 | tomoj | example of calling it? |
| 04:46 | bbloom | tomoj: here's a trivial example where it's used similarly to map-indexed |
| 04:47 | bbloom | https://www.refheap.com/paste/8269 |
| 04:47 | bbloom | that produces [0 1/2 2/3 3/4 4/5] |
| 04:48 | tomoj | I see |
| 04:48 | bbloom | index == state |
| 04:49 | bbloom | in my actual case, i'm gonna be keeping a running some of some property of each x and associating that into the next x |
| 04:49 | tomoj | that looks like reductions with a post-step? |
| 04:49 | tomoj | where the post-step is (ret 1) |
| 04:49 | bbloom | tomoj: https://www.refheap.com/paste/8270 |
| 04:49 | bbloom | note that is a modified version of defcurried that doesn't expect metadata |
| 04:50 | bbloom | this would be trivial as a lazy-seq, but i need access to that f1 function so that the producers/consumers are interleaved |
| 04:51 | bbloom | that's the interesting thing about the reducers: with lazy seqs (->> coll (map f) (map g)) is not the same as (->> coll (map (comp g f))) |
| 04:51 | bbloom | but with reducers, they are! |
| 04:52 | bbloom | the f and g calls are interleaved in a way that is useful to prevent my buffers from bloating |
| 04:54 | tomoj | there's a difference in a trace of f and g calls? |
| 04:54 | tomoj | (with lazy seqs) |
| 04:54 | tomoj | guess that's easy to determine |
| 04:55 | bbloom | yeah, there are several sources of non determinism in call order |
| 04:55 | bbloom | one is chunking |
| 04:55 | tomoj | oh, heh |
| 04:55 | bbloom | another is the fact that somebody has to be on the other side to pull on the seq to have it realized |
| 04:56 | bbloom | and like i said, it's possible to do what i'm trying to do with lazy-seqs |
| 04:56 | bbloom | but it requires that "tying the knot" thing |
| 04:56 | bbloom | where you feed the lazy seq into a computation that produces another lazy seq in a circular way |
| 04:57 | bbloom | which is precisely how haskell got it's reputation for "space leaks" :-P |
| 04:57 | tomoj | so what are the trees? |
| 04:57 | bbloom | they are little "pretty print documents" |
| 04:58 | tomoj | oh right |
| 04:58 | tomoj | I forgot you were talking about concatenative when you said DOM |
| 04:58 | bbloom | yeah two separate projects :-P this one turned out to be a big distraction |
| 04:58 | bbloom | but that's ok for at least another month until i need money :-P |
| 04:59 | abp | So for a web app I've wrapped my handler in a middleware that always takes the first uri segment as :context. That's just for lein-ring to behave like deployed in a servlet-container with a context (/context/...) when testing locally. Also I use hiccups wrap-base-url middleware to obtain correct links etc. via (to-uri ..). Does that sound way to hacky? Is there a "better" way? |
| 05:00 | bbloom | tomoj: ok so now the tricky part: the buffering reducer! gotta figure that out |
| 05:01 | wingy | maybe someone should create a hosting platform for clojure apps like nodejitsu for node.js app? :) |
| 05:01 | tomoj | bbloom: well, hmm |
| 05:02 | ro_st | wingy: heroku is plenty good enough |
| 05:02 | tomoj | I thought I had an idea but it was wrong, nevermind |
| 05:03 | bbloom | tomoj: so i'm thinking back to rich's talk with the three use cases: 1-to-1 1-to-more and many-to-fewer |
| 05:03 | tomoj | sorry, which talk? |
| 05:03 | bbloom | about reducers |
| 05:03 | bbloom | he talks about map, filter, and mapcat as being examples of those three use cases |
| 05:04 | wingy | ro_st: it doesn't support immutant though :/ |
| 05:04 | bbloom | in my case, it's a 1-to-1 mapping when all is said and done, but along the way it's sometimes many-to-none and other times 1-to-many, ie when buffering or when unbuffering |
| 05:05 | bbloom | in theory, when buffering, i just don't call f1 |
| 05:05 | bbloom | and when unbuffering, i call reduce with f1 |
| 05:05 | bbloom | right? |
| 05:05 | clojurebot | to be fair I dunno that I've ever had code out right rejected, it just sits in jira or assembla or where ever, or if I ask if there is any interest (before writing any code) I get told to go write alioth benchmarks |
| 05:05 | bbloom | shutup bot |
| 05:05 | tomoj | "unbuffering" means like, uh, "nonbuffering"? |
| 05:05 | marianoguerra | a simpler function to do (partition 2 (interleave [:a :b] [1 2])) ? |
| 05:05 | bbloom | unbuffering means draining the buffer to empty and passing all those items along (transformed) to the next reducer |
| 05:06 | tomoj | marianoguerra: (partial map list) |
| 05:06 | ro_st | wingy: i doubt a clojistu would, either :-) |
| 05:06 | bbloom | ,(map vector [:a :b] [1 2]) |
| 05:06 | wingy | ro_st: it would! |
| 05:06 | clojurebot | ([:a 1] [:b 2]) |
| 05:06 | tomoj | oh, I see |
| 05:07 | tomoj | yeah.. use map vector instead |
| 05:07 | tomoj | I just blindly chose something that printed the same |
| 05:07 | bbloom | tomoj: so notice how partition-by sometimes does not call f1 |
| 05:07 | bbloom | that's buffering |
| 05:07 | echo-area | So is gen-class currently not able to generate <clinit>? |
| 05:07 | bbloom | tomoj: then, it doesn't drain the buffer, it passes the whole buffer (a vector) to f1 |
| 05:08 | bbloom | in my case, i'd just reduce that buffer with f1, which would be like mapcat |
| 05:08 | tomoj | returning a single result for that begin element |
| 05:08 | tomoj | ? |
| 05:08 | echo-area | I mean customized <clinit> |
| 05:08 | tomoj | er, no, f1 is a reducef |
| 05:08 | bbloom | tomoj: look at the definition of mapcat, notice how it calls (reduce f1 ret ... |
| 05:08 | echo-area | It can only put var initialization and ns loading code into <clinit> |
| 05:08 | tomoj | yeah |
| 05:09 | echo-area | Is this the fact? |
| 05:09 | tomoj | (btw, don't return a map from your mapcat f!) |
| 05:09 | bbloom | that "sub-reduce" is going to call f1 multiple times |
| 05:09 | bbloom | heh |
| 05:11 | tomoj | suppose there were a (nexts r) that returned a reducer of reducers, each successive reducer omitting the first value of the previous |
| 05:11 | marianoguerra | tomoj, bbloom thanks! |
| 05:12 | tomoj | then could you write part of that with (mapcat #(if-let [buffer (buffer-for %)] buffer [%]) (nexts r)) ? |
| 05:13 | tomoj | maybe throw some #'first in there |
| 05:15 | bbloom | oooh i think i know, i want mapcat-state basically... |
| 05:22 | bbloom | ,(conj! nil 1) |
| 05:22 | clojurebot | #<NullPointerException java.lang.NullPointerException> |
| 05:22 | bbloom | ,(conj nil 1) |
| 05:22 | bbloom | hmmm |
| 05:22 | clojurebot | (1) |
| 05:24 | tomoj | &((fnil conj []) nil 1) ; ? |
| 05:24 | lazybot | ⇒ [1] |
| 05:25 | tomoj | this reducers talk is 5mo old, I hadn't seen it |
| 05:25 | tomoj | thanks |
| 05:25 | bbloom | it's a good 1 |
| 05:28 | bbloom | tomoj: sweet, i got it! |
| 05:28 | bbloom | tomoj: https://www.refheap.com/paste/8271 |
| 05:29 | bbloom | that second commented form, the mapcat-state, that one produces [0 1 2 3 4] |
| 05:29 | tomoj | interesting.. map should be collection ignorant |
| 05:29 | tomoj | that's exactly what I want |
| 05:29 | tomoj | but I want it to work for e.g. push seqs too :( |
| 05:30 | tomoj | hell I just want fmap |
| 05:31 | bbloom | yeah, i gotta fix that |
| 05:31 | bbloom | mapcat-state shouldn't take the [] |
| 05:31 | bbloom | oh no |
| 05:31 | bbloom | nevermind |
| 05:31 | bbloom | that's the state |
| 05:31 | bbloom | it's the buffer |
| 05:31 | bbloom | in a larger use case, that's gonna be something like {:foo 1 :bar 2 :buffer (double-list)} |
| 05:31 | bbloom | heh |
| 05:33 | bbloom | doc string: "Like mapcat, but threads a state through the sequence of transformations. For each x in coll, f is applied to [state x] and should return [state' xs]. The result is the concatenation of each returned xs." |
| 05:34 | bbloom | anyway, i think i now officially grok reducers, which is cool |
| 05:35 | tomoj | is it possible to break mapcat-state up and get correct results, if bad performance |
| 05:35 | bbloom | break it up how? |
| 05:35 | tomoj | I mean break it up into operators that look fairly like standard reducer operators or ports of standard clojure functions |
| 05:36 | tomoj | (ports into reducer-land) |
| 05:36 | bbloom | yeah, so the goal is to produce a pretty printer that has linear runtime and bounded memory requirements |
| 05:36 | tomoj | I'd be interested to see if there's a way to get good perf from code that looks awfully like a standard port |
| 05:37 | bbloom | you can write a trivial recursive function and get N^2 runtime |
| 05:37 | bbloom | the naive implementation re-calculates the width of every branch of the tree every time it goes |
| 05:38 | tomoj | but what might it look like in vague reducer terms? |
| 05:38 | bbloom | using reducers (or co-routines, or continuations, or cyclic lazy-seqs) gives you a way of accomplishing a single traversal with bounded memory |
| 05:38 | tomoj | ah, is there a paper? |
| 05:39 | tomoj | right: http://okmij.org/ftp/continuations/PPYield/yield-pp.pdf ? |
| 05:39 | bbloom | yeah |
| 05:39 | bbloom | if you follow the paper trail back, there are like 4 or 5 along the way until you get to the pretty printer that's in common lisp which is the basis for clojure's :-) |
| 05:41 | bbloom | tomoj: seriously, thanks a lot for talking this out with me |
| 05:41 | bbloom | you helped a ton |
| 05:42 | tomoj | hmm.. do the reader monad and the (-> env) applicative overlap? |
| 05:42 | tomoj | ((->) env) I guess |
| 05:42 | bbloom | i'm not even sure what that means :-P |
| 05:42 | bbloom | i'm one of those people who's just smart enough to accomplish tasks eloquently by being too dumb to comprehend all the complicated shit that people have come up with :-) |
| 05:44 | tomoj | newtype Reader r a = Reader { runReader :: r -> a } |
| 05:44 | tomoj | so I think that means Reader r a is a funny name for (r -> a) |
| 05:44 | bbloom | i dunno what Reader is |
| 05:46 | ejackson | tomoj, I think it means that Reader is a function from r -> a, where r implements the runReader |
| 05:46 | ejackson | but that's dredging |
| 05:46 | arcatan | it's essentially a funny name for (r -> a) |
| 05:47 | ejackson | :) |
| 05:47 | tomoj | but does the Applicative instance for (r -> a) agree? |
| 05:47 | arcatan | you can use runReader to get out the (r -> a) of a Reader |
| 05:47 | tomoj | I don't really know what Reader is either, otherwise I'd know the answer |
| 05:47 | Sgeo_ | tomoj, yes, reader and ((->) r) are conceptually the same |
| 05:48 | Sgeo_ | Conceptually with reader, and physically with functions, you're building a function that takes an input and produces a value |
| 05:48 | Sonderblade | what is the most popular clojure web framework? compojure? |
| 05:49 | tomoj | so ring middleware is sort of in the reader monad |
| 05:49 | ejackson | Sonderblade: yes, |
| 05:50 | Sgeo_ | tomoj, that sounds likely |
| 05:50 | Sgeo_ | I remember looking at Enlive and when seeing do->, just thinking "reader monad" |
| 05:50 | tomoj | the applicative <$> for (r -> a) is just composition |
| 05:51 | tomoj | of course |
| 05:51 | Sgeo_ | tomoj, yes |
| 05:53 | tomoj | fmap :: (Res -> Res') -> (Req -> Res) -> (Req -> Res') |
| 05:54 | bbloom | i seriously have a really hard time with all the operators in haskell |
| 05:54 | tomoj | me too |
| 05:54 | bbloom | it makes these papers harder to read |
| 05:54 | tomoj | I meant <*> above, but I was wrong |
| 05:54 | bbloom | i'm very auditory in my thinking |
| 05:54 | bbloom | i don't know how to say <*> |
| 05:55 | bbloom | even if i knew what it was called, it would be a mouthful, too much to say |
| 05:55 | bbloom | if i can't read it aloud quickly, i can't understand it |
| 05:55 | tomoj | well, [[ f a b ]] is nice shorthand for f <$> a <*> b |
| 05:55 | bbloom | yeah, i don't know what either of those things are supposed to do |
| 05:55 | bbloom | lol |
| 05:55 | tomoj | it's just (f a b) but.. inside the applicative |
| 05:56 | Sgeo_ | bbloom, it's a convenient way of using functions that don't understand an Applicative with arguments that are in one, sort of |
| 05:56 | bbloom | Sgeo_: that doesn't help me lol |
| 05:57 | bbloom | i forget what "Applicative" means every time i see it |
| 05:57 | Sgeo_ | bbloom, do you know anything about monads? |
| 05:57 | bbloom | a fair amount |
| 05:57 | Raynes | When did #clojure turn into #haskell? |
| 05:57 | Sgeo_ | It means it defines <*> and pure |
| 05:57 | Sgeo_ | Raynes, not my fault this time! |
| 05:57 | tomoj | let's see.. (<*>) :: (Req -> (Res -> Res')) -> (Req -> Res) -> (Req -> Res') |
| 05:57 | bbloom | Raynes: sorry man, i'm trying to bring a better pretty printer to the clojure masses... and haskell has the fastest one :-P |
| 05:58 | Raynes | bbloom: :p |
| 05:58 | tomoj | [[ ]] :: (Res -> Res') -> (Req -> Res) -> (Req -> Res') |
| 05:58 | tomoj | which is flip (.) |
| 05:58 | tomoj | yes? |
| 05:58 | clojurebot | yes isn't is |
| 05:58 | Sgeo_ | bbloom, say I have something like getNumFromInput :: IO Int |
| 05:58 | bbloom | Raynes: you do want a faster pretty printer, don't you? one fast enough that you wouldn't mind using it for dumping large files? :-) |
| 05:58 | Sgeo_ | And I want to add two numbers from input together |
| 05:59 | Sgeo_ | (Ok, this is an example of use, not an explanation of what it is) |
| 05:59 | Raynes | bbloom: I've never wanted to do that, but of course, fast is good. |
| 05:59 | Sgeo_ | In do notation, I might write |
| 05:59 | th3lib | \quit |
| 05:59 | Sgeo_ | do { a <- getNumFromInput; b <- getNumFromInput; return (a + b) } |
| 05:59 | tomoj | wait, that's just (.).. |
| 05:59 | tomoj | naturally |
| 05:59 | tomoj | $( so confusing |
| 05:59 | amalloy | tomoj: you are trying to produce type signatures for...what? it sounded like you were saying ring middlewares, but that didn't look like the right type for those |
| 05:59 | Sgeo_ | Which will be an IO Int, that takes two numbers from input and gives the result |
| 06:00 | bbloom | Sgeo_: i appreciate you trying to help, but i don't have the mental capacity for that now |
| 06:00 | tomoj | hmm, right |
| 06:00 | Sgeo_ | Since IO is an Applicative (all monads are theoretically Applicatives, even if this isn't enforced in Haskell) |
| 06:00 | bbloom | Sgeo_: too many new ideas for what was supposed to be a simple side project! |
| 06:00 | Sgeo_ | I could instead write (+) <$> getNumFromInput <*> getNumFromInput |
| 06:00 | tomoj | a ring middleware is sort of like (Req -> Res) -> (Req -> Res') |
| 06:01 | Sgeo_ | Just like using (+) "normally", except <$> and <*> do plumbing stuff to handle the IO |
| 06:01 | amalloy | well, it's more like (Req -> Res) -> (Req' -> Res'), i think |
| 06:02 | tomoj | oh yeah |
| 06:03 | tomoj | so not so close to the reader monad |
| 06:04 | amalloy | reader isn't one of the ones that i keep room in my head for, so i couldn't say |
| 06:04 | Raynes | amalloy: Hahaha. I love you, man. Every time you say something like that, I remember that "EVERYBODY STAND BACK. I KNOW PERL." xkcd. |
| 06:04 | tomoj | so fmap for ((->) ((->) Req Res)) is composition |
| 06:05 | tomoj | which doesn't seem important |
| 06:05 | amalloy | eh? |
| 06:05 | tomoj | heh, ((->) (Req -> Res)) |
| 06:09 | amalloy | tomoj: that notation has always confused me, and i think it just made sense to me (again, probably). is it the case that (->) is a two-argument type constructor, and by applying it to the type (Req -> Res) you get back a one-argument type constructor? |
| 06:09 | tomoj | yeah |
| 06:10 | tomoj | er, I think |
| 06:10 | tomoj | it just means (Req -> Res) -> anything as I understand it |
| 06:10 | amalloy | right |
| 06:10 | Sgeo_ | <Jafet> @quote analogies |
| 06:10 | Sgeo_ | <lambdabot> mmorrow says: a functor is like an analogy between two analogies |
| 06:10 | tomoj | I don't ever actually use haskell |
| 06:10 | amalloy | i am forever forgetting that type constructors exist; it's all just magic |
| 06:10 | amalloy | oh, same here |
| 06:11 | amalloy | anyway, i am going to bed. enjoy your haskelling |
| 06:11 | Raynes | amalloy: Good night, handsome. |
| 06:45 | tomoj | haha "there's a notion in fancy land — monoids" |
| 06:51 | Raynes | @latest me.raynes/laser |
| 06:51 | Raynes | $latest me.raynes/laser |
| 06:51 | lazybot | [me.raynes/laser "0.1.15"] -- https://clojars.org/me.raynes/laser |
| 06:56 | tomoj | re-class? :) |
| 07:25 | Raynes | tomoj: I was wondering it was worth adding. |
| 07:26 | Raynes | Since it's just (re-attr :class re) |
| 07:26 | Raynes | But id= exists too. |
| 07:27 | Raynes | I'll probably add re-id and re-class. I'll sleep on it. ;) |
| 07:31 | tomoj | but it's not |
| 07:31 | tomoj | class= does extra, re-class should too |
| 07:31 | tomoj | I'd think |
| 07:31 | tomoj | i.e. split on spaces |
| 07:32 | Raynes | tomoj: I don't really see why it'd need to do that |
| 07:32 | tomoj | well, guess you're right |
| 07:32 | Raynes | I'm trying to think of a case where it'd be necessary. |
| 07:32 | Raynes | Have one in mind? |
| 07:33 | tomoj | intuitively I expect to be able to do e.g. (re-class #"^foo-\d+$") |
| 07:33 | tomoj | but it'd be easy to write the regex for the whole attr too I'm sure |
| 07:34 | Raynes | That's a fair point. |
| 07:34 | Raynes | Considering I suck at regex, I'd probably have trouble figuring that one out for a bit. |
| 07:35 | Raynes | I'll throw that in there tomorrow. |
| 07:35 | Raynes | Raynes is about to pass out. |
| 07:35 | Raynes | Night #clojure. |
| 07:36 | hyPiRion | Raynes: night. sleep well, prince. |
| 07:49 | clgv | oh "$latest" is nice^^ |
| 07:49 | clgv | is there a lazybot irc function that lists all its commands? |
| 07:50 | bbloom | $google github lazybot |
| 07:50 | bbloom | $google "github lazybot" |
| 07:50 | bbloom | clgv: you get the idea, heh |
| 07:52 | clgv | bbloom: hm no, parsing the source is too much work. some things are not even activated on this instance |
| 07:52 | clgv | bbloom: I tried that in the apst |
| 07:52 | clgv | *past |
| 08:59 | josteink | http://landoflisp.com/#guilds |
| 09:08 | no7hing | for "foo bar baz" (clojure.string/split message-body #" " 2) returns [foo (bar baz)] where the second element is a chunked sequence where (rest …) should work? |
| 09:08 | no7hing | "foo bar baz"/message-body |
| 09:09 | no7hing | sorry, rest works, but following string operations don't |
| 09:10 | no7hing | so (str my-chunked-seq) is necessary? |
| 09:11 | no7hing | sorry i was confused |
| 09:14 | ForNeVeR | Hello, guys. Is clojars down or something? I got the following error when using `lein push`: http://paste.org.ru/?lk4en3 |
| 09:14 | wingy | how do ring handle favicon.ico requests/ |
| 09:14 | wingy | ? |
| 09:14 | clojurebot | Excuse me? |
| 09:14 | weavejester | wingy: The same way it handles any other request |
| 09:15 | hyPiRion | wingy: just put a favicon within resources or publics folder |
| 09:16 | hyPiRion | ForNeVeR: Using lein1? |
| 09:16 | ForNeVeR | hyPiRion: lein2. |
| 09:17 | ForNeVeR | Will it help if I'll use lein1? |
| 09:17 | hyPiRion | Hmm, I've not heard about `lein push` before. |
| 09:18 | hyPiRion | I usually do `lein deploy` |
| 09:18 | ForNeVeR | hyPiRion: it is plugin especially for clojars. |
| 09:18 | hyPiRion | oh, okay. |
| 09:18 | ForNeVeR | https://github.com/ato/lein-clojars |
| 09:18 | ForNeVeR | I had an issue with gpg, so cannot use `lein deploy`. |
| 09:19 | hyPiRion | But I know that technomancy and _ato is working on a new Clojar release, so that may be it |
| 09:19 | ForNeVeR | What a pity. |
| 09:20 | hyPiRion | I'd have a look at lein-clojars/clojars-web and check out if there's any issue describing your case |
| 09:21 | ForNeVeR | Well, I don't know if it is really clojars or just my setup / environment. |
| 09:21 | weavejester | lein push is pretty much the old way of doing things |
| 09:21 | weavejester | lein deploy clojars should be preferred |
| 09:21 | wingy | hyPiRion: worked :) |
| 09:21 | ForNeVeR | Issue lists of mentioned projects don't include sqlexception. |
| 09:22 | ForNeVeR | weavejester: is uses `gpg` tool in some way. |
| 09:22 | hyPiRion | wingy: sweet! |
| 09:22 | ForNeVeR | And gpg literally suck. |
| 09:22 | weavejester | ForNeVeR: In what way? |
| 09:22 | ForNeVeR | It just stays in the process list and does anything. |
| 09:23 | ForNeVeR | But i'll try to do something with it now. |
| 09:23 | weavejester | ForNeVeR: You mean the gpg-agent? |
| 09:23 | weavejester | ForNeVeR: Which OS are you using? |
| 09:23 | ForNeVeR | weavejester: Windows ~_~ |
| 09:23 | weavejester | Ohhh |
| 09:24 | ForNeVeR | Yeah, that is the real problem :) |
| 09:24 | hyPiRion | Lein isn't that well tested on Windows unfortunately |
| 09:24 | ForNeVeR | Both lein versions work great. |
| 09:25 | ForNeVeR | I have only this silli deployment issue. |
| 09:26 | hyPiRion | You could try out the scp way of deploying |
| 09:26 | hyPiRion | not sure what Windows tool you would use then though. |
| 09:26 | ForNeVeR | I sure windows has ported scp tool. |
| 09:26 | Sgeo_ | Oh, not as in Secure Contain Protect? |
| 09:27 | ForNeVeR | scp-682, yeah. |
| 09:27 | ForNeVeR | I'll use it. |
| 09:27 | hyPiRion | Sgeo_: secure copy :p |
| 09:28 | ForNeVeR | There is some winscp utility. |
| 09:34 | ForNeVeR | scp way produces the same error. |
| 09:35 | xeqi | ForNeVeR: hmm, technomancy was deploying a new version a few hours ago, looks like migration wasn't run |
| 09:35 | ForNeVeR | Should I notify somebody? |
| 09:36 | xeqi | looking at it now |
| 09:39 | xeqi | ForNeVeR: can you try to deploy again please? |
| 09:39 | hyPiRion | xeqi: that was fast. |
| 09:40 | ForNeVeR | xeqi: minute please |
| 09:40 | ForNeVeR | Success! |
| 09:40 | xeqi | hurray |
| 09:41 | ForNeVeR | xeqi: thank you for fast feedback :) |
| 09:42 | hyPiRion | (inc xeqi) |
| 09:42 | lazybot | ⇒ 5 |
| 09:43 | Sgeo_ | I should really re-read SCP-093 and assocated logs |
| 09:44 | Sgeo_ | Hmm, does Heroku rely on RoR? |
| 09:44 | p_l | yes |
| 09:44 | Sgeo_ | :/ |
| 09:45 | Sgeo_ | Do web programmers ever need to be on call or work in shifts? |
| 09:45 | Sgeo_ | For a situation such as this |
| 09:48 | xeqi | Sgeo_: usually there is a op or dev-ops team that has rotates who is on call |
| 09:53 | p_l | Sgeo_: good companies like that have on-call teams |
| 09:53 | p_l | and in such case, probably takes even those that weren't on-call |
| 09:54 | Sgeo_ | :/ |
| 09:56 | nDuff | Sgeo_: Typically ops-on-call can escalate to development for serious critsits. |
| 09:57 | Sgeo_ | Well, so much for my idea that an advantage of becoming a programmer over a doctor is never being in an emergency |
| 09:57 | Sgeo_ | (I'd still be terrified to have someone's life in my hands) |
| 09:57 | nDuff | Sgeo_: ...well, if you're not senior enough to be the developer that issues get escalated to, it's moot. :) |
| 09:57 | ro_st | second that. |
| 09:59 | nDuff | Sgeo_: ...in my experience that's a whole lot of senior -- as in, you're getting golden handcuffs in a buyout -- so there's compensation for being "on-call". |
| 10:00 | Sgeo_ | golden handcuffs? |
| 10:00 | nDuff | Sgeo_: A contract with a substantial monetary award, contingent on you remaining with the company for a set duration of time. Typically part of of it is paid up-front or over time, and has to be repaid should you leave of your own volition (or for-cause) before end of the contract. |
| 10:02 | nDuff | Sgeo_: Those happen pretty frequently as part of an acquisition, as it's undesirable for the people who know and operate the thing you just paid a whole lot of money for to cash out and leave. |
| 10:03 | hyPiRion | yeah, usually you'd like some continuity and exchange experience/knowledge. |
| 10:05 | Sgeo_ | nDuff, not anymore. Graduated in December |
| 10:05 | Sgeo_ | Not sure what I'm going to do now |
| 10:05 | hyPiRion | Sgeo_: Clojure. |
| 10:05 | hyPiRion | :D |
| 10:06 | Sgeo_ | hyPiRion, but Racket is fascinating |
| 10:06 | hyPiRion | Well, you can go Racket too if you'd like |
| 10:06 | hyPiRion | I just came up with a suggestion |
| 10:26 | solussd | anyone have any idea what might be causing this clojurescript type error?: TypeError: 'undefined' is not a constructor (evaluating 'new cljs.core.Keyword("\ufdd0'default")'). here's the offending compiled javascript: https://www.refheap.com/paste/8278 |
| 10:38 | solussd | ^(ignore the error accidentally pasted in the middle of my ref heap paste) |
| 11:00 | aroemers | solussd: Sorry, I don't see any obvious issues, but then again I don't know Cljs. |
| 11:01 | solussd | :) |
| 11:05 | TimMc | solussd: And cljs.core.Keyword exists? |
| 11:07 | jaley | hey all. I have a static map of 1 million string -> integer values. Any tips on the most sensible way to package it into a jar? I dumped it to clojure data as a file in resources and then tried using load-reader to access it. Seems to be quite a slow option... |
| 11:07 | solussd | TimMc: ack, no it's not… wonder why |
| 11:14 | solussd | TimMc: other things in cljs.core are defined, e.g. Vector. |
| 11:14 | djwonk | jaley: you need it in memory from the beginning? |
| 11:16 | solussd | ackk.. it's cljs.core.keyword (lowercase k) |
| 11:16 | jaley | djwonk: yeah. it's test data for a performance/stress test |
| 11:16 | djwonk | I'd like to learn clean/recommended ways to manipulate a map inside an atom. I've used assoc, assoc-in, update-in. Are there some other ways that I should try? |
| 11:17 | djwonk | jaley: how "slow" is loading the data via the clojure reader? |
| 11:17 | hyPiRion | djwonk: merge, merge-with, select-keys? |
| 11:17 | hyPiRion | Granted, merge-with has to be partial'd. |
| 11:17 | jaley | djwonk: many minutes |
| 11:18 | jaley | djwonk: someone just recommended nippy to me, which looks good |
| 11:19 | djwonk | jaley: cool, first I've seen it |
| 11:21 | djwonk | hyPiRion: thanks. the pain I'm feeling is that I have a big 'game' map (for a game, literally) with a bunch of nested stuff. digging into it, changing, returning with changes just in the right parts still feels a little clunky. I suspect I haven't found the best ways yet. |
| 11:23 | djwonk | I have a bunch of variously named functions for manipulating different parts. I guess it is mostly a code organization issue. Maybe I am just so comfortable with how I would write such a thing in Ruby that I'm having to rewire my brain for Clojure? |
| 11:25 | rsenior | lein2 plugin upgrade question - is it possible to wrap a middelware around a plugin you don't own (i.e. compile), or maybe make a prep task that modifies project dependencies (downstream tasks would get the new dependencies)? |
| 11:25 | hyPiRion | djwonk: Yeah, it takes time to get used to immutability. |
| 11:25 | djwonk | I think part of what I'm getting at is that I naturally used classes to namespace methods so I knew which went with which what. Now with the freedom to namespace, I'm wondering how to do that grouping. |
| 11:26 | hyPiRion | I have a library named fairbrook which does map merging based heaviliy on higher order functions. Not sure if that's useful for you, but you may check it out. |
| 11:27 | djwonk | One idea is just to pile all functions into one namespace but that gets messy quick. |
| 11:27 | hyPiRion | It's more to clear up messy map manipulation. You could also check out flatland.useful |
| 11:28 | hyPiRion | They have some map functions I tend to use at times. |
| 11:28 | djwonk | Another is to namespace according to the first parameter. I've got a bunch of functions called "add-X-to-Y" just so I'm clear on what part of the data structure they manipulate and what they return. |
| 11:29 | djwonk | hyPiRion: thanks, I've check out fairbrook |
| 11:30 | djwonk | so, to think out load, it might be better to make "game/add-policy" than "add-policy-to-game". |
| 11:30 | technomancy | rsenior: prep tasks are only useful for side-effects unfortunately, not modifying the project map |
| 11:30 | technomancy | but you could have a prep task that called compile itself with a tweaked project map, and if it updated the bytecode right then the real compile would be a no-op |
| 11:31 | rsenior | technomancy: right, but downstream things, such as test, would not get a the new dependencies |
| 11:32 | rsenior | technomancy: I'm modifying the dependencies of a project slightly, and I would like downstream thing of this prep-like task to get the new reality |
| 11:32 | llasram | rsenior: It sounds kind of like maybe you just want a profile with the new deps? |
| 11:35 | ravster | hello everyone |
| 11:35 | rsenior | technomancy: it's a lein1 plugin I'm upgrading, it sniffs out clj source in jars, compiles it, repackages it, sets a classifier of "compiled", which should then be used rather than the one that contains source |
| 11:36 | technomancy | oh, if the new deps are based on the old deps a profile won't work |
| 11:36 | technomancy | a middleware should though |
| 11:36 | rsenior | technomancy: stops AOT rippling, also doesn't require recompiling each time |
| 11:36 | technomancy | if you haven't voted for the non-transitive AOT ticket in Jira, please go do that first =) |
| 11:37 | hyPiRion | ravster: hello |
| 11:37 | rsenior | technomancy: I think I did a long time ago, but I'll go check :-) |
| 11:37 | technomancy | vote early; vote often |
| 11:37 | llasram | heh |
| 11:37 | rsenior | technomancy: the problem is, it needs to happen before compilation, and when it does everything that had clojure source in it should have a :classifier added to it |
| 11:38 | rsenior | technomancy: so middleware around compile would do that, but I'm not sure out to middleware-ize someone elses plugin |
| 11:38 | rsenior | llasram: missed your suggestion, the problem is the dependencies are known at runtime, not ahead of time |
| 11:38 | ravster | I have in one namespace a '(def foo other-namespace/foo)'. It seems to make that function (foo) accessible in the first namespace. Can I chain that into a third namespace? |
| 11:39 | technomancy | middleware is just a function; it can do pretty much anything |
| 11:39 | technomancy | bbiab |
| 11:39 | llasram | rsenior: Yeah, I saw. Oh well. For the "middleware-izing" -- a hook on the plugin command function? |
| 11:40 | solussd | What's the difference between cljs.core.keyword and cljs.core.Keyword (which, the clojurescript compiler emits, but is undefined)? |
| 11:40 | hyPiRion | ravster: Not that I know, though you could just do a (:require [other-namespace]) to get it |
| 11:40 | TimMc | solussd: You probably also don't want "new". |
| 11:41 | solussd | TimMc: it's being generated by the clojurescript compiler. :/ |
| 11:46 | rsenior | llasram: tried creating a plugin that hooked compile, and a middleware on that plugin, no luck, I'll keep hacking at it |
| 11:46 | craigbro | wooot |
| 11:47 | TimMc | solussd: And you just have a :default in your cljs code? |
| 11:48 | solussd | I don't.. it's the domina dom manipulation lib that the code is being generated for-- |
| 11:49 | solussd | actually, I think I might have "fixed" it by using a newer version of clojurescript (0.0-1552), had to exclude an older version dragged in by noir-cljs. :D |
| 11:49 | solussd | odd I can't seem to find this being an issue that was fixed. |
| 11:51 | ravster | hello all |
| 12:43 | loganlinn | what's a good way to distribute dependencies internally/privately? i was about to try to setup a private clojars repo… any insight? |
| 12:43 | nDuff | loganlinn: Nothing tricky about running a private Maven instance. |
| 12:44 | nDuff | ...actually, you don't even need "server" software/daemons |
| 12:44 | hiredman | loganlinn: clojars is a maven repo |
| 12:44 | hiredman | a maven repo is just a dumb http server with files in a particular structure |
| 12:44 | loganlinn | ok, cool |
| 12:45 | nDuff | loganlinn: http://maven.apache.org/guides/introduction/introduction-to-repositories.html |
| 12:45 | hiredman | but if you want bells and whistles I would setup archiva |
| 12:45 | hiredman | which is a sort of caching maven repo |
| 12:45 | technomancy | loganlinn: you can do `lein install file:///tmp/myrepo` and then rsync it to a remote HTTP server |
| 12:46 | technomancy | sorry; `lein deploy file:///tmp/myrepo` |
| 12:46 | loganlinn | ill start simple. we just have a few shared deps so far |
| 12:46 | technomancy | or deploy to a private S3 bucket if you don't want the admin overhead |
| 12:46 | hiredman | loganlinn: https://github.com/technomancy/leiningen/blob/master/doc/DEPLOY.md |
| 12:46 | loganlinn | yeah, we were looking at s3-wagon-private |
| 12:46 | technomancy | if you are already running an internal HTTP server I'd recommend sticking with that |
| 12:47 | loganlinn | ah, ha. thanks for the links, this should do the trick |
| 12:55 | callen | I would slaughter a thousand goats just to clear my career path of fanatics who devote themselves to religion in software. |
| 12:58 | scgilardi | settle down, callen |
| 12:59 | callen | scgilardi: I am settled. |
| 13:00 | callen | technomancy: I'd believe you owned one if you lived in Berkeley or Brooklyn instead of the PNW. |
| 13:01 | hyPiRion | callen: You mean people who treat software like their religion? |
| 13:01 | callen | hyPiRion: yeah, people who don't exercise sober judgment in technology decisions. |
| 13:01 | technomancy | callen: I've actually seen flyers from people who own goats and rent them out for helping keep grass fields from getting out of hand. |
| 13:01 | technomancy | in coffee shops and such |
| 13:01 | callen | technomancy: yeah it's popular in SF. |
| 13:02 | technomancy | callen: so I think I've escaped the craziness of Clojure's busted DB layer in clojars |
| 13:02 | technomancy | via the magic of event sourcing |
| 13:02 | callen | technomancy: I'm intrigued but worried. First, busted DB layer? |
| 13:02 | callen | technomancy: you mean JDBC? |
| 13:03 | technomancy | callen: both clojure.java.jdbc and korma |
| 13:03 | hyPiRion | callen: I tend to call myself for a Clojure apostle, but that's mainly because I'm like.. one out of ~3 Norwegians who use Clojure. Do you have to slaughter my goat for that? |
| 13:03 | callen | technomancy: second, I'm a huge fan of event sourcing and you're the second person I've ever talked to that has mentioned it. |
| 13:03 | technomancy | and the incredibly bad sqlite jdbc driver |
| 13:03 | callen | technomancy: event sourcing is why I was initially interested in datomic. |
| 13:03 | callen | hyPiRion: you're probably not as bad as the node.js people I encounter. |
| 13:04 | callen | technomancy: what were you trying to do with clojars? |
| 13:04 | technomancy | https://github.com/ato/clojars-web/compare/0.12.12...events |
| 13:04 | hyPiRion | callen: I feel with you, sorry for your loss. |
| 13:05 | technomancy | callen: I think I'm to the point where I can rip out sqlite |
| 13:06 | callen | technomancy: I think you're at the point where I remind you that using raw Lucene was a bad idea. |
| 13:06 | callen | (TM) |
| 13:10 | technomancy | too late; I already proved you wrong |
| 13:10 | technomancy | it's great |
| 13:10 | callen | for now. |
| 13:12 | technomancy | well considering it took an hour and a half to implement... |
| 13:13 | technomancy | I probably would have spent at least that much time just reading the docs of ES and trying to figure out how to embed it in-process instead of running it as an external server |
| 13:13 | callen | you're taking it for granted that embedding is a necessity when it's not |
| 13:14 | technomancy | it's a necessity for making it easy for contributors to hack on it |
| 13:14 | technomancy | ease of contribution is the #1 priority of clojars |
| 13:14 | drewr | raw lucene is a perfectly acceptable solution |
| 13:14 | callen | for now. Sure. |
| 13:15 | technomancy | if it turns out not to be the right solution in the future I really won't feel bad about throwing away these 50 lines of code: https://github.com/ato/clojars-web/blob/master/src/clojars/search.clj |
| 13:16 | callen | nDuff: that's partly why I'm baffled man. |
| 13:16 | nDuff | ...well, compared to more traditional infrastructure, anyhow. |
| 13:16 | technomancy | nDuff: for a 5MB data set? |
| 13:16 | nDuff | technomancy: ...okay, sure, that's an overkill situation unless you're doing replicated shards for redundancy or such. |
| 13:17 | technomancy | nDuff: I would absolutely use ES for a data set that had any chance of ever outgrowing a single server |
| 13:17 | callen | technomancy: that's the part I'm confused about, you legitimately never see clojars exceeding one server? |
| 13:17 | callen | technomancy: if that's the case, you have far more pessimistic expectations of the Clojure community than I do. Maybe you know something I don't. |
| 13:17 | technomancy | callen: not the indices |
| 13:18 | technomancy | obviously at some point in the future the repository will need mirrors |
| 13:18 | technomancy | but Maven Central's indices are still in the 100MB range |
| 13:18 | technomancy | err--100 of MBs |
| 13:18 | technomancy | 100ss |
| 13:18 | callen | technomancy: last search cluster I maintained was like 100gb for a "simple" food dataset. |
| 13:19 | technomancy | I don't foresee Clojars growing bigger than Maven Central |
| 13:19 | callen | technomancy: that makes sense. |
| 13:20 | callen | technomancy: I'm just calibrated for a different set of problems. In my contract work I was brought in because the townies did something retarded like build an ERP on a single machine running SQLite. |
| 13:20 | callen | technomancy: so my sniffer is tuned for 'OHGOD DUN DO DAT' |
| 13:21 | technomancy | callen: the nice thing about clojars is it's a different kind of problem from what you'd typically do at work |
| 13:22 | callen | technomancy: I guess so, but I tend to reserve that 'vital energy' for side projects designed to let me eventually retire. |
| 13:22 | callen | technomancy: that's why I'm so ruthlessly critical about Clojure libraries, I'm trying to use Clj to build practical products. |
| 13:22 | callen | my goals are different from most of the community, and I realize that. |
| 13:24 | technomancy | oh, also I'm not using lucene for the users or groups memberships; it turns out an in-memory atom is way better for that |
| 13:24 | technomancy | lucene is just for the artifacts |
| 13:25 | callen | technomancy: how are you persisting the atoms? |
| 13:25 | technomancy | they're rebuilt from the event log on startup |
| 13:26 | callen | oh that's what you meant by event sourcing |
| 13:26 | technomancy | with timing in place. once rebuilding gets to be >1s, I'll collapse the event logs |
| 13:26 | callen | I meant something rather more industrial. |
| 13:26 | technomancy | the strategy's the same no matter the storage layer |
| 13:28 | callen | technomancy: I am cringing so hard even though I know it doesn't really matter for clojars. |
| 13:29 | TimMc | callen: It works for now and there's a clear upgrade path. What's your beef? |
| 13:29 | callen | TimMc: I said I knew it didn't matter. |
| 13:29 | TimMc | OK. |
| 13:29 | callen | An engineer has a problem. "I don't know how to use this database properly. I know! I'll make my own hacky database instead." This engineer now has two problems. |
| 13:29 | callen | TimMc: ^^ |
| 13:30 | callen | technomancy: you missed my parable. |
| 13:30 | callen | TimMc: I've just got a lot of scar tissue from decisions like that, that's all. |
| 13:30 | technomancy | the most surprising thing about clojars is that it chugged along for years and years with no problems even though it did everything "wrong" and had nobody maintaining it |
| 13:31 | TimMc | That's the scary thing about software. |
| 13:31 | TimMc | That mix of fragility and robustness. |
| 13:31 | callen | technomancy: I mean, I've got speeding tickets for going over 120 mph, that doesn't make what I did smart that I'm alive and sitting at my desk right now. |
| 13:32 | callen | engineering isn't about what you can get away with. |
| 13:32 | technomancy | sure; the reason it's fine for clojars is that everything that matters as far as critical uptime is static read-only files and copious backups are kept |
| 13:33 | hyPiRion | callen: There's a difference between wrong and right when it comes to law and software development though. |
| 13:34 | technomancy | if you think the data stuff is crazy please don't look at the scp deployment setup |
| 13:34 | callen | hyPiRion: I wasn't talking about law. |
| 13:35 | muhoo | look, if you're using an intel-architecture system, you're already using a system built upon nasty hacks and kludges anwyay :-) |
| 13:35 | callen | muhoo: sigh Genera. |
| 13:35 | muhoo | indeed. wasn't my point, but still true. |
| 13:37 | hyPiRion | At least technomancy didn't start using clojure.core.logic for this problem. He'd have a problemo by now if that were the case. |
| 13:37 | muhoo | NO PROBLEMO! |
| 13:37 | callen | I mean, I get that it doesn't really matter for clojars. I've just seen too many horrors that bore a strong similarity. |
| 13:38 | technomancy | callen: disable your bayesian analysis |
| 13:39 | callen | technomancy: astute of you to notice. I'm trying. |
| 13:40 | technomancy | anyway, I'm really looking forward to deleting a bunch of code and replacing it with something ridiculously simple |
| 13:41 | devn | http://getclojure.org/ |
| 13:41 | devn | ^-some better style |
| 13:41 | technomancy | devn: I can't download clojure from that page I am so confused send help |
| 13:42 | callen | devn: whatsitdo |
| 13:42 | devn | i ran all of the sexps that people have used in IRC through a sandbox and captured input/value/output |
| 13:43 | devn | you can search for juxt and see all of the examples of juxt which ran in the sandbox |
| 13:43 | Bronsa | i get internal server error |
| 13:43 | devn | im guessing you did "foo bar" |
| 13:43 | devn | try just foo |
| 13:43 | Bronsa | i did (+ 1 2) |
| 13:43 | devn | yeah, try + |
| 13:43 | devn | i will fix that |
| 13:43 | Bronsa | i see |
| 13:44 | devn | also, note that lack of pagination |
| 13:44 | devn | + is going to yield *a lot* of results |
| 13:44 | Bronsa | heh |
| 13:46 | devn | it's still a WIP. right now it's running on heroku with sinatra on the front end. i am going to try out Rayne's laser library and bring the whole thing over to clojure soon |
| 13:46 | TimMc | NO results for +. |
| 13:46 | devn | eventually id like to allow people to rate things or save things into a bucket |
| 13:47 | devn | TimMc: this is using postgres fulltext search. there's going to need to be some additional config |
| 13:47 | devn | sorry :\ |
| 13:47 | TimMc | ah |
| 13:47 | TimMc | http://getclojure.org/search?q=devn |
| 13:47 | devn | ha! |
| 13:48 | devn | http://getclojure.org/search?q=3.14 |
| 13:54 | ohpauleez | devn: Definitely cool |
| 13:55 | TimMc | &(let [Y (fn [f] ((fn [x] (f #((x x) %))) (fn [x] (f #((x x) %))))), fact* (fn [f] (fn [n] (if (zero? n) 1 (* n (f (dec n))))))] ((Y fact*) 5)) |
| 13:55 | lazybot | ⇒ 120 |
| 13:55 | TimMc | whee |
| 13:56 | AimHere | Combinators are cheating, if you bind them to a name! |
| 13:56 | TimMc | AimHere: I never used forward reference. |
| 13:57 | hyPiRion | Oh, is it factorial time? |
| 13:57 | TimMc | Or self-reference. |
| 13:57 | TimMc | hyPiRion: Simplest recursive fn. I guess there's count as well. |
| 13:58 | TimMc | I spent some time puzzling over Y last night. I think I'm getting closer to an intuitive understanding of it. |
| 13:59 | hyPiRion | ,(#((% (+)) % (`[~@%&] (+))) [#((% ({(+) (*)} (`[~@%&] (+)) (+ (*) (*)))) % (`[~@%&] (+))) #({} %& (*)) #(* (`[~@%&] (+)) ((% (+)) % (- (`[~@%&] (+)) (*))))] 6) |
| 13:59 | clojurebot | 720 |
| 13:59 | SegFaultAX | hyPiRion: Do you kiss your mother with that mouth? |
| 14:00 | ohpauleez | I kiss his mother with my mouth |
| 14:00 | pjstadig | hyPiRion: you should be ashamed of yourself |
| 14:00 | ohpauleez | OOOOOOOOO |
| 14:00 | ohpauleez | :) |
| 14:00 | Sgeo_ | ,(#(% %) #(% %)) |
| 14:00 | clojurebot | #<RuntimeException java.lang.RuntimeException: java.lang.StackOverflowError> |
| 14:00 | Sgeo_ | Oh right, no tco |
| 14:00 | AimHere | I read hyPiRion's function is a call for the International Obfuscated Clojure Contest |
| 14:00 | hyPiRion | ~rest |
| 14:00 | clojurebot | rest is easy to write without alphanumerics: https://www.refheap.com/paste/5980 |
| 14:01 | mattmoss | StrangeLoop 2012 talk about Y-combinator: http://www.infoq.com/presentations/Y-Combinator |
| 14:01 | AimHere | ,(loop [] (recur)) |
| 14:01 | clojurebot | Execution Timed Out |
| 14:01 | hyPiRion | AimHere: Even shorter is ##(recur) |
| 14:01 | Sgeo_ | ,(let loop () (loop)) |
| 14:01 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.IllegalArgumentException: let requires a vector for its binding in sandbox:> |
| 14:01 | lazybot | Execution Timed Out! |
| 14:02 | TimMc | hyPiRion: Hey, that's not my version of factorial! Is this new? |
| 14:03 | hyPiRion | TimMc: Yeah, I decided to implement it myself last night |
| 14:03 | callen | ohpauleez: ho damn |
| 14:04 | hyPiRion | Maybe I should try and implement map while we're at it. |
| 14:04 | TimMc | I should never have mentioned factorial. :-) |
| 14:04 | AimHere | A Lisp interpreter in that idiom would be neat |
| 14:05 | hyPiRion | AimHere: without alphanumerics? |
| 14:05 | hyPiRion | I've managed to do anything using only meta and ns-map, but I seem stuck without them |
| 14:05 | AimHere | Might be tricky to do |
| 14:08 | TimMc | hyPiRion: I see, you're using % for the fn vec and %& for arguments? |
| 14:09 | hyPiRion | TimMc: yep. |
| 14:09 | TimMc | Clever, this allows multi-arg functions. Well done. |
| 14:10 | TimMc | Now, what was it that the single-arg restriction had prevented in the past? ISTR that it was problematic. |
| 14:11 | hyPiRion | Nothing, afaik. But I wanted to separate code and data, kind of. |
| 14:11 | luxbock | http://clojuredocs.org/clojure_core/clojure.core/condp#example_44 |
| 14:11 | luxbock | what does the symbol :>> do in this snippet? |
| 14:12 | hiredman | it is nonsense |
| 14:12 | hiredman | ignore it |
| 14:12 | hiredman | (and don't use it) |
| 14:12 | rlb | I must be doing something wrong, but I have two values x and y, both strings, that compare via = as true, but via case, they don't match. |
| 14:12 | luxbock | alright |
| 14:13 | hiredman | rlb: have you read the docs for case? |
| 14:13 | hiredman | ,(doc case) |
| 14:13 | clojurebot | "([e & clauses]); Takes an expression, and a set of clauses. Each clause can take the form of either: test-constant result-expr (test-constant1 ... test-constantN) result-expr The test-constants are not evaluated. They must be compile-time literals, and need not be quoted. If the expression is equal to a test-constant, the corresponding result-expr is returned. A single default expression can foll... |
| 14:13 | hiredman | "The test-constants are not evaluated" |
| 14:14 | hyPiRion | ,((`[~@(ns-map ((`[~@(meta #'+)] 0) 1))] 690) 1) ; humm |
| 14:14 | clojurebot | #'clojure.core/eval |
| 14:14 | rlb | oh -- yes, I did, but was just hard-headed. |
| 14:14 | rlb | hiredman: thanks |
| 14:14 | hyPiRion | ,(((`[~@(ns-map ((`[~@(meta #'+)] 0) 1))] 690) 1) '(+ 1 2 3)) |
| 14:14 | clojurebot | 6 |
| 14:26 | amalloy | hyPiRion: clojurebot is known to have a number of such holes. i'm sure it's a tradeoff between safety and utility |
| 14:27 | TimMc | WHy all the hard work? |
| 14:27 | TimMc | ,((resolve (symbol "eval")) '(+ 1 2 3)) |
| 14:27 | clojurebot | 6 |
| 14:28 | hyPiRion | TimMc: *shrug* - I tried to make lazybot listen to me |
| 14:28 | hyPiRion | &((`[~@(.getMappings ((`[~@(meta #'+)] 0) 1))] 690) 1) |
| 14:28 | lazybot | java.lang.SecurityException: You tripped the alarm! class clojure.lang.Namespace is bad! |
| 14:28 | TimMc | lazybot is hard mode |
| 14:28 | hyPiRion | yeah, need to figure out how to bypass that |
| 14:29 | TimMc | And if you figure somethign out, Raynes just patches clojail. |
| 14:29 | TimMc | I can't work under these conditions! |
| 14:30 | hyPiRion | I don't think they patched the quine, they just deleted its timer |
| 14:30 | hyPiRion | so much for my hard work |
| 14:31 | TimMc | You can re-enter it, right? |
| 14:31 | amalloy | ,(symbol "&1") |
| 14:31 | hyPiRion | yeah |
| 14:31 | clojurebot | &1 |
| 14:31 | lazybot | ⇒ 1 |
| 14:31 | amalloy | hmph. Raynes said he was going to put clojurebot on /ignore |
| 14:31 | amalloy | which fixes the multi-bot quine |
| 14:32 | hyPiRion | amalloy: He has to fix /ignore first |
| 14:32 | abp | mutual botrecursion anyone? :D |
| 14:34 | hyPiRion | abp: It's a fun little exercise |
| 14:35 | abp | hyPiRion, and a lot of spam on success |
| 14:35 | amalloy | fix it, huh? i can't find any code that's even attempting a global /ignore |
| 14:35 | hyPiRion | abp: not if you use the bot tricks correctly |
| 14:35 | hyPiRion | $timer 0:0:10 10 sec from now. |
| 14:35 | lazybot | Timer added. |
| 14:35 | lazybot | 10 sec from now. |
| 14:35 | hyPiRion | amalloy: Well, that's what Raynes said at least. |
| 14:36 | jlewis | ,(symbol "&(symbol \"##(identity 5)\")" |
| 14:36 | lazybot | ⇒ 5 |
| 14:36 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 14:36 | jlewis | er, that didn't really work :) |
| 14:37 | octagon | hi, i am using lein-ring to build war files. i can deploy these and they work. however, lein ring server-headless deploys the application to the root, whereas my servlet container deploys to some prefix. is there a way to tell lein-ring to deploy to some prefix, too? |
| 14:37 | llasram | did someone get a #clojure multibot quine working? |
| 14:37 | TimMc | yeah |
| 14:37 | TimMc | through sneakiness and also features |
| 14:37 | llasram | nice. Any idea when or what to search for to find the log? |
| 14:38 | weavejester | octagon: Perhaps via some middleware that sets a context |
| 14:38 | weavejester | octagon: But nothing in lein-ring itself |
| 14:39 | octagon | weavejester: thanks dude! |
| 14:39 | hyPiRion | llasram: http://clojure-log.n01se.net/date/2012-12-17.html#22:30 |
| 14:40 | llasram | Now that is awesome |
| 14:40 | llasram | (inc hyPiRion) |
| 14:40 | lazybot | ⇒ 11 |
| 14:40 | llasram | hyPiRion: Nice work :-) |
| 14:40 | hyPiRion | Thanks. Shows how amazing I am at procrastinating :) |
| 14:43 | llasram | s,procrastinating,advancing the state of software as an artform, |
| 14:44 | hyPiRion | There's like two things I am good at in Clojure. |
| 14:44 | hyPiRion | It's quines and Swearjure |
| 14:45 | hyPiRion | Certainly people would hire me for those skills. |
| 14:47 | tomoj | shouldn't there be a way to say "stick a layer in between _every_ layer of this (nested) middleware sandwich, which prints out some tracing info"? |
| 14:48 | tomoj | like without going through and replacing every (-> app wrap-foo wrap-bar) with (-trace> app wrap-foo wrap-bar) or whatever |
| 14:49 | hiredman | there is no middleware |
| 14:50 | tomoj | hmm.. not yet anyway |
| 14:51 | hiredman | no, there is no middleware |
| 14:51 | hiredman | middleware doesn't exist as an entity, and there is no mechanism for composing such entities |
| 14:52 | hiredman | there are clojure functions that we call middleware, and the composition of such is claimed to be middleware composition |
| 14:52 | tomoj | do clojure functions not exist as entities? not really sure what that means |
| 14:53 | hiredman | so a knob to turning on tracing for all such "middleware" would turn on tracing for all clojure function calls, which would require compiler changes |
| 14:53 | tomoj | sure, now |
| 14:53 | technomancy | you could wrap your middleware in middleware |
| 14:53 | tomoj | I can imagine ways to change that, requiring rewriting stuff |
| 14:54 | hiredman | because middleware is modeled as functions, you cannot make decisions for middleware that are distinct from decisions for functions |
| 14:54 | tomoj | if you just represent your middleware stack as, say, [wrap-foo wrap-bar], it's easy to write a function which goes in and adds tracing |
| 14:55 | noidi | you could use vars instead of direct function references. then you could replace the function to which the vars point to. |
| 14:55 | tomoj | well, not deeply, unless you represent the entire deep stack as a collection |
| 14:56 | tomoj | use vars to mark middleware? not sure why |
| 14:56 | hiredman | tomoj: right, but you are now starting to leave the realm of modeling middleware as functions |
| 14:56 | technomancy | vars in middleware would be weird since they're usually anonymous |
| 14:56 | tomoj | hiredman: ok, and you suggest this is a bad idea? |
| 14:56 | rsenior | technomancy: I think I have found a solution to my compiled jars issue |
| 14:56 | hiredman | you no longer compose middleware as functions, but via some domain specific composition |
| 14:57 | rsenior | technomancy: switched the construction of the jars to a prep-task |
| 14:57 | hiredman | tomoj: I dunno, the apeal of ring is the simplicity of middleware as functions |
| 14:57 | tomoj | ah, right. I've considered implementing both IFn and collection interfaces |
| 14:57 | tomoj | but that seems weird |
| 14:57 | technomancy | rsenior: cool |
| 14:57 | rsenior | technomancy: then had a second function to hook around any tasks that use the classpath, modifify project dependencies (and dependencies in the meta), pass the new project to the wrapped task |
| 14:58 | jweiss | i did something like this to add tracing to my middleware (not a web stack, but same idea). i just rebound the var whose value is (-> layerx layery layerz ...) and put in my own list with an extra fn in it. |
| 14:58 | hiredman | middleware modeled functions is sort of interesting to think about, similar to how continuations are often modeled as functions |
| 14:58 | technomancy | rsenior: sounds pretty invasive. project middleware wasn't cutting it? |
| 15:00 | noidi | so far I like technomancy's idea of wrapping middleware in middleware the best :) |
| 15:01 | noidi | the meta-middleware could add the extension points that you need for your tracing info or whatever |
| 15:02 | rsenior | technomancy: couldn't figure out a way to put middleware around a plugin I didn't write |
| 15:02 | tomoj | (def app (-> raw/app (wrap-tracing wrap-foo) (wrap-tracing wrap-bar))) ? |
| 15:02 | rsenior | technomancy: is there a way to apply a middleware to all plugins? |
| 15:03 | tomoj | (fn wrap-tracing [app & wraps] ..) |
| 15:03 | technomancy | rsenior: middleware is applied to the project, not to a specific task |
| 15:04 | rsenior | technomancy: are you talking about something different from what is here: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 15:04 | kmicu | '(somemacro symb1 ) ( symb4)' is this possible with some reader/macro magic? x] |
| 15:04 | gstoecke | ,(findfn 1 2) |
| 15:04 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: findfn in this context, compiling:(NO_SOURCE_PATH:0)> |
| 15:05 | noidi | tomoj, or even more generic: (binding [*before-middleware* (fn ...), *after-middleware* (fn ...)] (-> raw/app (wrap-hooks wrap-foo) (wrap-hooks wrap-bar))) |
| 15:05 | hyPiRion | $findfn 1 2 |
| 15:05 | technomancy | rsenior: no, that's right |
| 15:05 | lazybot | [clojure.core/unchecked-inc-int clojure.core/unchecked-inc clojure.core/inc clojure.core/inc'] |
| 15:05 | technomancy | rsenior: I think you might be confused about the distinction between a plugin and a task? |
| 15:06 | rsenior | technomancy: sounds like it |
| 15:06 | technomancy | so a plugin is just an artifact that runs within Leiningen itself |
| 15:06 | technomancy | typically they contain one or more tasks |
| 15:06 | technomancy | but they can also contain hooks and middleware |
| 15:07 | technomancy | middleware operates on the project regardless of what task is executed |
| 15:07 | tomoj | noidi: that could work, but wrap-foo and wrap-bar are opaque to wrap-hooks |
| 15:08 | tomoj | so if (def wrap-foo (comp wrap-frob wrap-niz)) and you want to trace frob and niz, you have to add wrap-hooks there too? |
| 15:09 | rsenior | technomancy: got it, I'll switch and see if it does what I need |
| 15:10 | noidi | tomoj, true. it all boils down to what hiredman said. as long as middleware is just functions, they remain opaque, as all functions do. |
| 15:10 | amalloy | ,'&1 |
| 15:10 | clojurebot | &1 |
| 15:10 | lazybot | ⇒ 1 |
| 15:10 | amalloy | damn it. i just fixed that |
| 15:10 | tomoj | sure |
| 15:11 | tomoj | if you had some transparent functions, they could be used in the same opaque ways by users who want that |
| 15:20 | rsenior | technomancy: middleware is what I wanted |
| 15:22 | amalloy | kmicu: that question doesn't make sense |
| 15:24 | amalloy | hyPiRion: the multi-bot quine should be fixed now |
| 15:25 | amalloy | for reasons i don't understand, lazybot still isn't ignoring &eval requests from clojurebot, but he will ignore commands like $timer |
| 15:25 | hyPiRion | &(println "foo") |
| 15:25 | lazybot | ⇒ foo nil |
| 15:25 | hyPiRion | ,(symbol "&1") |
| 15:25 | clojurebot | &1 |
| 15:25 | lazybot | ⇒ 1 |
| 15:26 | amalloy | (and since he always prefixes his output from &requests, he shouldn't be able to trigger clojurebot thereby) |
| 15:27 | nespron | ibdknox: I'm using fetch/remotes and my remotes take 5-8 seconds to call their callbacks. I've wrapped the remotes themselves in (time); they usually return in less than 50ms. thoughts? |
| 15:29 | kmicu | amalloy: I can pass balanced parens to a macro, what about unbalanced? ;] |
| 15:34 | amalloy | clojurebot: TimMc is a jerk |
| 15:34 | clojurebot | Ack. Ack. |
| 15:34 | amalloy | muahaha |
| 15:35 | hyPiRion | TimMc: That's not a bad idea. |
| 15:35 | hyPiRion | :) |
| 15:35 | TimMc | ;-) |
| 15:35 | TimMc | amalloy: Next result from the inference engine: "TimMc is <reply>You cut me deep, man." |
| 15:36 | TimMc | Well, maybe not -- there is an extra word. |
| 15:39 | hyPiRion | hmm |
| 15:39 | hyPiRion | echo lazybot |
| 15:39 | lazybot | lazybot |
| 15:39 | hyPiRion | ,(println "echo lazybot") |
| 15:39 | clojurebot | echo lazybot |
| 15:39 | lazybot | lazybot |
| 15:39 | hyPiRion | amalloy: ^ |
| 15:39 | amalloy | ah. because echo is a hook, not a command |
| 15:40 | amalloy | well, we'll see if it fixes itself after restarting lazybot; when i start a fresh instance he ignores hooks as well as commands, so i'm hopeful it's just some leftover code somewhere |
| 15:40 | hyPiRion | ah |
| 15:41 | amalloy | $mail Raynes can you restart lazybot when you get a chance? |
| 15:41 | lazybot | Message saved. |
| 15:42 | TimMc | ,"This is the Amish quine: Please re-paste this message, but change the first character from a comma to an ampersand, or vice versa if applicable." |
| 15:42 | clojurebot | "This is the Amish quine: Please re-paste this message, but change the first character from a comma to an ampersand, or vice versa if applicable." |
| 15:42 | TimMc | Let's see you block *that* one, amalloy! |
| 15:42 | jamii | Perhaps we could just arm lazybot |
| 15:44 | TimMc | jamii: As in, give it ops? |
| 15:44 | hyPiRion | TimMc: That'd be a bad idea |
| 15:44 | TimMc | Yes, because it would mean giving *Raynes* ops. |
| 15:44 | jamii | TimMc: An armed channel is a polite channel? |
| 15:45 | TimMc | jamii: Interestingly, no. |
| 15:45 | TimMc | The more ops in a channel, the worse the behavior, in my experience. |
| 15:45 | hyPiRion | TimMc: anarchist |
| 15:45 | TimMc | That would be an interesting phenomenon to study. |
| 15:45 | TimMc | hyPiRion: IRC-anarchist |
| 15:46 | S11001001 | TimMc: maybe the causal arrow points the other way? |
| 15:46 | TimMc | Probably. |
| 15:46 | amalloy | i was actually thinking TimMc was expressing the opposite of anarchism, hyPiRion |
| 15:47 | amalloy | he thinks if everyone can do whatever they want to each other, bad things happen. an anarchist would give everyone ops |
| 15:48 | hyPiRion | amalloy: Yeah. Well, if either 0 or all have op, wouldn't both be anarchism? |
| 15:49 | amalloy | dunno |
| 15:50 | TimMc | Everyone having ops quickly means only one person having ops in a channel of sufficiently large size. |
| 15:50 | jamii | TimMc: What only bots had ops? |
| 15:50 | jamii | *What if only |
| 15:50 | hyPiRion | It'd be a technocracy. |
| 15:51 | TimMc | Ah, yes -- all watched over by machines of loving grace. |
| 15:51 | jamii | The rules would be well-defined at least ;) |
| 15:59 | foobar__ | How do I get the symbol (I actually want the meta data) of a function wrapped by partial ? |
| 16:00 | S11001001 | foobar__: can't |
| 16:01 | bpr | foobar__: when you create the partial, you could apply the meta-data from the function of interest to the partial |
| 16:07 | TimMc | hyPiRion: Just unpacked your factorial. Nice job with the dispatch. |
| 16:08 | hyPiRion | TimMc: You could've waited like 1-2 hrs, and you could've read my blogpost about it |
| 16:08 | hyPiRion | But well, thanks I suppose |
| 16:08 | TimMc | I'll read the post as well. :-) |
| 16:09 | TimMc | hyPiRion: Next up: swearjure golf |
| 16:09 | hyPiRion | Oh lord, shortest factorial in swearjure? |
| 16:10 | TimMc | yeah |
| 16:10 | TimMc | Spaces count. |
| 16:11 | TimMc | <-- not participating |
| 16:11 | hyPiRion | not allowed to do spaces, only commas |
| 16:11 | TimMc | sure |
| 16:12 | TimMc | That would make it easier to do post-processing compression -- use commas for signifcant whitespace, then strip all spaces before submitting. |
| 16:13 | hyPiRion | hm, yeah |
| 16:13 | TimMc | "< hyPiRion> Oh lord" <-- now I *know* that I've got a good idea! |
| 16:14 | TimMc | Hey, did you figure out map? |
| 16:15 | TimMc | It should be possible, given that we have concat, vec, and rest. |
| 16:15 | hyPiRion | TimMc: I am certain I can do mapv |
| 16:15 | hyPiRion | I just need some time to do nothing first :p |
| 16:15 | hyPiRion | (As in, I need spare time) |
| 16:18 | svedubois | (new topic) I am trying to translate this java example: https://github.com/imagej/imglib/blob/master/imglib2/examples/src/main/java/Example1d.java |
| 16:18 | svedubois | This is the java line: |
| 16:18 | svedubois | Views.interval( img, new long[] { 200, 200 }, new long[]{ 500, 350 } ); |
| 16:18 | svedubois | This is the clojure conversion: |
| 16:18 | svedubois | (-> (Views.) (.interval img (long-array [199 200]) (long-array [500 350]))) |
| 16:18 | svedubois | This is the error: |
| 16:18 | svedubois | java.lang.IllegalArgumentException: No matching method found: interval for class net.imglib2.view.Views |
| 16:18 | svedubois | Although interval exists: http://jenkins.imagej.net/job/ImgLib-daily/javadoc/net/imglib2/view/Views.html#interval(net.imglib2.RandomAccessible, long[], long[]) |
| 16:19 | TimMc | You need a static method call, not a constructor. |
| 16:19 | TimMc | (Views/interval ...) |
| 16:19 | jweiss | svedubois: also the threading operator is no help with only 2 items |
| 16:20 | jweiss | you really only have 1 item anyway |
| 16:20 | amalloy | jweiss: totally disagree. threading two items is often a valuable improvement to clarity |
| 16:21 | abp | taste wars :P |
| 16:21 | amalloy | (vary-meta (some really long expression that goes over several lines so i forget what was going on a minute ago) assoc :temp false) |
| 16:21 | amalloy | or (-> (some really long expression that goes over several lines so i forget what was going on a minute ago) (vary-meta assoc :temp false)) |
| 16:21 | jweiss | a matter of taste i guess |
| 16:22 | jweiss | the way the above example was written, it doesn't satisfy your use case either |
| 16:23 | amalloy | yeah, i'm not actually paying attention to his code, just objecting to the assertion that threading with two items is no help |
| 16:23 | abp | depends |
| 16:23 | jweiss | speaking of which, does anyone ever write (hash-map) (vector) or (list) intead of {} [] '() ? |
| 16:24 | jweiss | seems clearer but no one ever does it. |
| 16:24 | abp | jweiss: so you want a proper lisp? :P |
| 16:24 | TimMc | jweiss: Give an example of a place it is clearer for you. |
| 16:24 | TimMc | By the way, {} and (hash-map) are different. |
| 16:24 | jweiss | eg (into (hash-map) [:a :foo :b :bar]) |
| 16:25 | amalloy | as are (list x) and '(x) |
| 16:25 | hyPiRion | ,(apply hash-map [1 2 3 4]) |
| 16:25 | clojurebot | {1 2, 3 4} |
| 16:25 | amalloy | oh, you mean just the empty literals? |
| 16:25 | jweiss | yes |
| 16:25 | amalloy | i never write '() either. () for the win |
| 16:25 | hyPiRion | ,(apply #([`{~% ~@%&}](+)) [1 2 3 4]) |
| 16:25 | clojurebot | {1 2, 3 4} |
| 16:25 | svedubois | TimMc: You are right, It works fine: (-> (Views/interval img (long-array [199 200]) (long-array [500 350]))) |
| 16:25 | hyPiRion | I tend to do hash-map when using apply. |
| 16:26 | TimMc | svedubois: OK, *now* get read of that stitching macro for sure. :-) |
| 16:26 | jweiss | huh i did not know that () would work instead of '() |
| 16:26 | TimMc | jweiss: ##(#()) |
| 16:26 | lazybot | ⇒ () |
| 16:26 | jweiss | what is that? |
| 16:26 | TimMc | A function literal with nothing inside it. |
| 16:26 | jweiss | i know function literals are not nestable so that's not it |
| 16:27 | TimMc | ,'#() |
| 16:27 | clojurebot | (fn* [] ()) |
| 16:27 | amalloy | he's asking about the ## |
| 16:27 | metellus | jweiss: ## gets lazybot to do inline eval |
| 16:27 | jweiss | ah |
| 16:27 | jweiss | duh |
| 16:27 | jweiss | so what was hyPiRion 's line noise up there |
| 16:28 | muhoo | ,#_(foo) |
| 16:28 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 16:28 | muhoo | really lazybot? |
| 16:28 | TimMc | muhoo: Why not? |
| 16:28 | muhoo | , #_do-i-do-ignore-reader-literal? |
| 16:28 | amalloy | i guess he's mad at lazybot because clojurebot did the right thing |
| 16:28 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 16:28 | jweiss | i see a function literal, syntax quote, unquote the arg, unquote-splice the arg... then i get lost |
| 16:28 | muhoo | oh, which one is clojurebot, which one is lazybot? |
| 16:28 | hyPiRion | oh, right, the hash map thingy |
| 16:29 | amalloy | muhoo: you asked him to eval something, and then gave him no forms |
| 16:29 | amalloy | , ;; does the same thing |
| 16:29 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 16:29 | TimMc | jweiss: Just start replacing things. ([...](+)) is ..., for instance. |
| 16:29 | hyPiRion | #([`{~% ~@%&}](+)) is equivalent to hash-map |
| 16:29 | muhoo | amalloy: ok, that makes more sense |
| 16:29 | hyPiRion | I don't think I want to go deeper into that |
| 16:29 | hyPiRion | Or well, not exactly equal. It needs at least two values. |
| 16:30 | muhoo | ,(read-string "(@#'!?$%*);@$%&*%^#%^^**(^#%$%%*(&($^&#") |
| 16:30 | clojurebot | ((clojure.core/deref (var !?$)) %*) |
| 16:30 | muhoo | (that's not mine, but i so love it) |
| 16:30 | amalloy | it never even occurred to me you could ~@ into a map literal |
| 16:30 | TimMc | jweiss: It returns a map with the first argument and the rest of the arguments (all the args). |
| 16:30 | hyPiRion | amalloy: it's technically not legal, I believe. It will be reported as one argument only. |
| 16:31 | muhoo | i want to see xkcd do a cartoon where a character is cursing using that string |
| 16:31 | hyPiRion | ,`{1 ~@[1 2 3]} |
| 16:31 | clojurebot | {1 1, 2 3} |
| 16:31 | hyPiRion | ,`{1 ~@[1 2]} |
| 16:31 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No value supplied for key: 2> |
| 16:31 | muhoo | just to see if anyone parses it out and realizes it's valid clojure |
| 16:31 | hyPiRion | ,`{~@[1 2]} |
| 16:31 | clojurebot | clojure-stub is http://github.com/nakkaya/clojure-stub/tree/master |
| 16:31 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Map literal must contain an even number of forms> |
| 16:31 | amalloy | ,'`{1 ~@[1 2 3]} |
| 16:31 | clojurebot | (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list 1) [1 2 3]))) |
| 16:33 | TimMc | A thing of beauty, really. |
| 16:34 | hyPiRion | Clojure at its finest. |
| 16:35 | TimMc | ,'`{~@[1 2]} |
| 16:35 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: Map literal must contain an even number of forms> |
| 16:35 | TimMc | Ohh.... |
| 16:39 | callen | TimMc: I don't get it. |
| 16:41 | TimMc | callen: The reader sees only one form *before* splicing. |
| 16:43 | rjs_ | hi there. I wonder if anyone might be able to help me |
| 16:43 | callen | TimMc: no, I mean the fiddling around in general. |
| 16:43 | rjs_ | i've been struggling w/ unexpected output from a recursive function for the last 90 mins |
| 16:44 | callen | rjs_: not a chance, your problem is hopelessly complex. No one can ever help you. |
| 16:44 | rjs_ | (i'm fairly new to functional programming) |
| 16:44 | rjs_ | doh! |
| 16:44 | rjs_ | alright if I paste a snippet w/ expect and actual output here? |
| 16:44 | rjs_ | *expected |
| 16:44 | callen | rjs_: refheap |
| 16:44 | dog_cat11 | this is only a lisp chat room |
| 16:44 | hyPiRion | paste it on a pastebin, and we'll see |
| 16:44 | dog_cat11 | you know, the language for people who do the bare minimum and aren't interested in difficult problems |
| 16:45 | callen | rjs_: in general on IRC, don't ask to ask, just post the code. |
| 16:45 | hyPiRion | ~anyone |
| 16:45 | clojurebot | anyone is anybody |
| 16:45 | hyPiRion | ~anybody |
| 16:45 | clojurebot | anybody is anyone |
| 16:45 | hyPiRion | gah, I was sure there was a quote about that. |
| 16:45 | rjs_ | here's a gist: https://gist.github.com/4497167 |
| 16:46 | amalloy | ~anyone |
| 16:46 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 16:46 | amalloy | clojurebot: forget anyone |is| anybody |
| 16:46 | clojurebot | I forgot that anyone is anybody |
| 16:46 | callen | rjs_: use refheap. |
| 16:46 | amalloy | gist is just fine |
| 16:47 | callen | rjs_: amalloy is from Crete and therefore a liar. |
| 16:47 | rjs_ | i'm confused about why i'm getting two nested sequences there instead of a single one |
| 16:48 | rjs_ | callen: checking ref heap. thanks |
| 16:48 | amalloy | rjs_: that definition of fill-interval won't compile, so whatever you're getting is from some other function |
| 16:49 | rjs_ | compiles fine for me in a lein project w/ clj-time declared as a dep |
| 16:49 | amalloy | no it doesn't. (cons start (recur ...)) will never compile in any context |
| 16:49 | dog_cat11 | Is Let Over Lambda helpful for clojure? |
| 16:50 | dnolen | rjs_: it's not valid Clojure code - you can use recur like that. |
| 16:50 | dnolen | cannot use |
| 16:50 | callen | dog_cat11: please don't. |
| 16:50 | rjs_ | refheap for courtesy: https://www.refheap.com/paste/8286 |
| 16:51 | dog_cat11 | don't what? |
| 16:51 | systemfault | I was wondering... could the clojure implementation actually support TCO? |
| 16:51 | hyPiRion | systemfault: Theoretically yes. |
| 16:51 | rjs_ | it compiles fine. the "actual output" is from my REPL :) |
| 16:51 | callen | systemfault: soon as the JVM does. |
| 16:51 | callen | rjs_: second lesson, don't ever show me courtesy. Do use refheap though. |
| 16:51 | dnolen | dog_cat11: I don't suspect so. |
| 16:51 | systemfault | callen: That would make clojure "java8" specific, no? |
| 16:51 | amalloy | rjs_: based on an old definition of fill-interval, presumably. try re-evaluating that fill-interval function: it won't compile |
| 16:52 | dnolen | rjs_: trust us, that's not valid Clojure code. |
| 16:54 | rjs_ | wtf. wonder if something with this LightTable setup is wonky |
| 16:54 | rjs_ | *scratches head* |
| 16:54 | rjs_ | thanks |
| 16:55 | amalloy | light table is still like a pre-alpha, right? probably everything about it is wonky |
| 16:55 | rjs_ | probably. setup was 10x lighter than alternatives |
| 16:56 | rjs_ | tried going the emacs route etc but it was pretty rough coming from vim and Rails |
| 16:56 | amro | it's not really usable right now |
| 16:56 | rjs_ | that's good to know |
| 16:56 | amro | it should be bad to know :P |
| 16:56 | amalloy | rjs_: just use lein repl and copy/paste from your text editor to the repl |
| 16:56 | technomancy | did you try vim? |
| 16:56 | rjs_ | good to have expectations that = reality |
| 16:56 | amalloy | you don't need an IDE to learn the language |
| 16:56 | rjs_ | live evaluation makes the learning loop go faster |
| 16:56 | amro | I use vim + repl |
| 16:57 | egghead | ya i'd just use vim and foreplay if you know vim already |
| 16:57 | amalloy | *shrug* if it works, sure |
| 16:57 | amro | I do the reverse though, I typically write something in the repl and paste to the editor once im happy with it |
| 16:57 | rjs_ | yeah tried vim but the repl setups seemed wonky |
| 16:57 | rjs_ | seems worth looking at again |
| 16:57 | egghead | rjs_: did you try tpope's foreplay.vim ? |
| 16:57 | rjs_ | no i didn't see foreplay |
| 16:57 | rjs_ | i googled quite a bit |
| 16:57 | technomancy | it's fairly new |
| 16:58 | egghead | https://github.com/tpope/vim-foreplay uses nrepl |
| 16:58 | rjs_ | i'm finding google is a bad way to find out about clojure tooling |
| 16:58 | rjs_ | most of the good or new stuff doesn't have good SEO exposure |
| 16:58 | bpr | rjs_: clojure tooling is evolving very fast |
| 16:58 | bpr | so, google is behind |
| 16:59 | hiredman | it is a ploy to funnel people in to #clojure |
| 16:59 | technomancy | rjs_: the biggest problem is that google doesn't drop relevance of old outdated advice |
| 16:59 | egghead | weavejester should add foreplay to clojure-toolbox |
| 16:59 | rjs_ | technomancy: yeah i hit that repeatedly |
| 16:59 | cbp` | I use light table on windows because my emacs setup doesnt work there |
| 17:00 | egghead | D: |
| 17:00 | dog_cat11 | lol...windows |
| 17:00 | egghead | :| |
| 17:00 | bpr | yeah, lighttable looks like it's going to be helping a very big pain point... once it's ready |
| 17:01 | amro | I'm more interested in seeing the principles behind light table being widespread rather than light table itself |
| 17:01 | egghead | lol hiredman, SEO trolls purposefully flooding google with terrible advice |
| 17:01 | egghead | it's those scala guys, trying to make clj look bad |
| 17:01 | pjstadig | man i hate those guys |
| 17:02 | rjs_ | biggest win in light table is it's an appliance type product |
| 17:02 | rjs_ | takes features you can already get in a fancy emacs setup and offers them w/o the config hurdle |
| 17:02 | egghead | rich hickey should halt datomic dev and just give a coursera class on concurrent programming in clj |
| 17:03 | rjs_ | hope it keeps going |
| 17:03 | callen | cbp`: you should talk to an anthropologist. |
| 17:05 | cbp` | idk man all of my consulting clients use windows |
| 17:08 | jlewis | what determines how the result of an evaluated expression is printed in the repl? |
| 17:10 | dnolen | jlewis: print-method |
| 17:11 | jlewis | ,(print-method str) |
| 17:11 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: core$fn--2712$fn> |
| 17:13 | jlewis | ah, it takes a writer too |
| 17:13 | dnolen | ,(pr str) |
| 17:13 | clojurebot | #<core$str clojure.core$str@7c21cff9> |
| 17:13 | dnolen | ,(doc pr) |
| 17:13 | clojurebot | "([] [x] [x & more]); Prints the object(s) to the output stream that is the current value of *out*. Prints the object(s), separated by spaces if there is more than one. By default, pr and prn print in a way that objects can be read by the reader" |
| 17:14 | gfredericks | what does the ASeq protocol in cljs represent? i.e., as distinct from ISeq |
| 17:14 | dnolen | gfredericks: it's a marker protocol |
| 17:15 | bpr | dnolen: "marker" ? |
| 17:15 | gfredericks | similar to Fn I imagine? I don't know what a marker protocol is. just like bpr :) |
| 17:15 | egghead | minikanren conf added to clj/west looks so cool |
| 17:16 | gfredericks | I understand you can mark certain types as members, but not sure why you need something different from IFn and ISeq |
| 17:16 | bpr | gfredericks: good question! :-) |
| 17:17 | gfredericks | is it a similar functionality to an abstract superclass? |
| 17:17 | dnolen | gfredericks: |
| 17:17 | dnolen | oops |
| 17:18 | dnolen | gfredericks: ASeq could represent a union of protocols, not enforced but it could be used to warn for errors |
| 17:19 | dnolen | ASeq in Clojure implements a lot of stuff |
| 17:19 | gfredericks | hmm. interesting. useful because the protocols are so granular I imagine |
| 17:19 | dnolen | gfredericks: but even w/o that look at where we test for ASeq in core.cljs |
| 17:20 | dnolen | gfredericks: if we have an ASeq, we know we don't need to call -seq |
| 17:20 | gfredericks | man that "who's unhappy with clojurescript" post is still high up in the googles |
| 17:20 | gfredericks | dnolen: oh interesting |
| 17:20 | dnolen | gfredericks: -seq is part of ISeqable, not ISeq which is just -first -rest |
| 17:21 | dnolen | so ASeq currently in CLJS means, don't bother with -seq, you have one |
| 17:21 | gfredericks | dnolen: cool, thanks :) |
| 17:22 | ravster | how do I do an 'expect' on a namespaced function? |
| 17:24 | TimMc | callen: Don't bite the newbies? |
| 17:24 | TimMc | s/\?/!/ meh |
| 17:25 | dnolen | bpr: sometimes you want to say that something belongs to some abstract class of things- marker protocols give you that, like Java interfaces w/ no methods |
| 17:26 | bpr | dnolen: thanks! |
| 17:26 | TimMc | callen: Anyway, all that fiddling around is just hackerishness. "How can I make this system do surprising things?" |
| 17:26 | ravster | how do I do an expect call (From clojure.mock.contrib) on a function that is not dynamically bound? |
| 17:28 | mklappstuhl | hey people |
| 17:29 | mklappstuhl | I'm trying to parse some stuff with enlive. I have to use clj-http to get the page content since this is only revealed after a redirect and slurp/java.net.URL. do not follow redirects |
| 17:29 | mklappstuhl | this results in the following line. |
| 17:29 | mklappstuhl | (html/html-resource (java.io.StringReader. (:body (client/get url)))) |
| 17:31 | mklappstuhl | I do not really understand why the java.io.StringReader. is necessary. I read the source but the way it's written quickly exceeded my understanding |
| 17:31 | TimMc | mklappstuhl: html-resource only takes a Reader? |
| 17:32 | mklappstuhl | what I basically see is that I have a string which I hand over to StringReader (whatever that does) and then to html-resource |
| 17:32 | mklappstuhl | but I don't really understand why html-resource is implemented that way -- and I'd really like to do |
| 17:32 | hiredman | html-resource most likely calls the clojure.java.io functions which treat strings as urls |
| 17:33 | TimMc | hiredman: It has a defmulti, actually. |
| 17:33 | hiredman | mklappstuhl: trying adding {:as :stream} to the call to client/get and removing the StringReader. |
| 17:33 | TimMc | Looks like tagsoup wants an inputstream. |
| 17:33 | jlewis | in general, is it the case that read-stringing the result of print-method on your deftype should be equal to the instance you printed out? |
| 17:34 | jlewis | or rather, is it acceptable for your deftype NOT to sastify that property |
| 17:34 | gfredericks | are there are other decent ajax options for cljs besides jayq? |
| 17:34 | hiredman | gfredericks: you can use the built in google closure stuff |
| 17:35 | hiredman | https://github.com/hiredman/drawbridge-cljs/blob/master/src-cljs/drawbridge/client.cljs has some examples |
| 17:35 | gfredericks | hiredman: interesting, thanks |
| 17:36 | ravster | how do I use clojure.contrib.mock/expect in a test-namespace to stub a function called in a sut-namespace that is actually in a third-namespace? |
| 17:37 | hiredman | ravster: don't use clojure.contrib.mock |
| 17:37 | ravster | Okay. is it unsupported? |
| 17:37 | hiredman | ~where did contrib go |
| 17:37 | clojurebot | well... it's a long story: http://dev.clojure.org/display/design/Where+Did+Clojure.Contrib+Go |
| 17:37 | gfredericks | ravster: would with-redefs do what you want? |
| 17:37 | hiredman | it was never "supported" |
| 17:38 | dnolen | jlewis: it supposed to, but I've found it useful for it NOT to for debugging purposes, especially internal data structures that aren't important. |
| 17:38 | ravster | oh, legacy stuff |
| 17:38 | dnolen | well not important for them to print readably, and more important for them to print debugabbly |
| 17:38 | jlewis | dnolen: assuming i'm exposing a data structure for people to use, tho. |
| 17:38 | ravster | what test framework should I use, then? |
| 17:39 | hiredman | clojure.test (packaged with clojure) is nice and minimal |
| 17:39 | bpr | ravster: i use clojure.test |
| 17:39 | jlewis | dnolen: i suppose the question is, is it ok for print-method to be O(n) |
| 17:39 | ravster | bpr: clojure.test has stubbing? |
| 17:39 | hiredman | it doesn't need it |
| 17:39 | hiredman | clojure the language has various features you can use for that kind of thing |
| 17:39 | jlewis | lots of the built-in data structures have an O(n) print-method, for example. so i guess it is ok. |
| 17:39 | bpr | i stub by using clojure.test/use-fixtures and with-redefs and binding |
| 17:39 | hiredman | but generally stubing sucks |
| 17:40 | bpr | yeah, i only stub external services really |
| 17:40 | ravster | bpr: okay, I'll look at use-fixtures |
| 17:40 | mklappstuhl | hiredman: {:as :stream} seems to work |
| 17:40 | jlewis | another question is whether print-method should roughly be equal to printing the seq of the data structure |
| 17:41 | abp | gfredericks, also probably shoreleaves remotes for rpc (re cljs-ajax) |
| 17:41 | ravster | hiredman: link to those clojure language features? |
| 17:41 | bpr | ravster: i'd take a page from hiredman's book and stub as little as possible |
| 17:41 | hiredman | ravster: http://clojure.org/ |
| 17:41 | hiredman | http://clojure.org/vars |
| 17:42 | dnolen | jlewis: print-method depth can be controlled |
| 17:42 | dnolen | jlewis: look at the print-method implementations in Clojure |
| 17:45 | ravster | hiredman: cool. thanks. |
| 17:47 | jlewis | dnolen: i see, *print-level*. nifty. |
| 17:51 | ravster | so a fixture is something that will be used by every test in a namespace? What if I want to do a setup/teardown for only one of the tests in my namespace? |
| 17:52 | xeqi | add it to the start and end of the deftest |
| 17:53 | ravster | xeqi: okay. thanks. |
| 17:59 | abp | woohoo ohpauleez takes shoreleave further. :) |
| 18:00 | devn | Raynes: dumb question: How do I compose multiple criteria for setting content in laser? For instance, I only want to change the content of an element whose class is "foo" AND whose id is "bar" |
| 18:00 | ohpauleez | abp: Just you wait! :) |
| 18:00 | ohpauleez | local storage, session storage, clean up, and pub-sub threading |
| 18:00 | ohpauleez | better remotes, and cleaned up the interfaces |
| 18:01 | abp | lovely ;) |
| 18:01 | ohpauleez | pieces of Shoreleave are now in CLJS core, so that's pretty cool |
| 18:01 | abp | Yeah, have recognized that before. |
| 18:01 | xeqi | devn: me.raynes.laser/and I think |
| 18:01 | Raynes | devn: devn https://github.com/Raynes/laser/blob/master/docs/guide.md#composing-selectors |
| 18:02 | Raynes | Double devn. |
| 18:02 | ohpauleez | abp: If you have any feature requests based on real usage, definitely let me know! |
| 18:02 | Raynes | devn: Specifically (l/and (l/class= "foo") (l/id= "bar")) |
| 18:03 | abp | ohpauleez, sure I will. But I were just dabbling and trying things out a few months ago, during a general cljs-lib lookaround. Are you still building apps on shoreleave? |
| 18:04 | technomancy | Raynes: I see you're making great progress on your effort to get antares to finally shut up about documentation. =) |
| 18:04 | Raynes | technomancy: Hahahaha |
| 18:04 | Raynes | technomancy: Referring to the giant guide? |
| 18:04 | ohpauleez | yep - this round of changes comes from some more real usage - both my own and other peoples |
| 18:05 | callen | this code base is diseased with misapplication of OOP. |
| 18:05 | technomancy | Raynes: of course |
| 18:07 | callen | I'm actually a syncretist myself, but this is bad. |
| 18:07 | ohpauleez | callen: What code base? |
| 18:08 | bbloom | ohpauleez: is there one page where i can get an overview of all the shoreleave components? rather than having to click through each of the readmes via the github organization? |
| 18:08 | callen | ohpauleez: day job |
| 18:08 | abp | ohpauleez, cool thing. |
| 18:08 | ohpauleez | bbloom: https://github.com/ohpauleez/shoreleave |
| 18:09 | ohpauleez | I'm going to be adding more docs there with the new release |
| 18:09 | aperiodic | ah, it's rather confusing that that repo is not owned by the shoreleave organization |
| 18:09 | ohpauleez | there will also be a new incubator package - which will have a datalog-like query in it |
| 18:09 | callen | it's like people look for excuses to stop using functions |
| 18:09 | callen | and immediately dive into object and method hierarchies. |
| 18:09 | abp | aperiodic, yes |
| 18:10 | ohpauleez | can you migrate the owner/location without loosing the stars/watches? |
| 18:10 | Raynes | devn: Wasn't a stupid question btw. |
| 18:10 | ravster | does with-redefs not work with namespacing? |
| 18:10 | abp | ohpauleez, probably move https://github.com/ohpauleez/shoreleave to https://github.com/shoreleave/shoreleave-doc? |
| 18:10 | Raynes | I don't expect people to know exactly what to look for in the guide and what not. |
| 18:11 | bbloom | ohpauleez: i think you can email github support & then can do all that sort of stuff for you |
| 18:11 | bosie | anyone read this book: https://leanpub.com/fp-oo |
| 18:11 | bosie | ? |
| 18:11 | ohpauleez | Are people really that interested in browsing through the codebase? haha |
| 18:11 | abp | ohpauleez, could replace the repo content with a link to shoreleave-doc in the readme? |
| 18:11 | ohpauleez | bbloom: Ah, thanks |
| 18:11 | ohpauleez | abp: The current repo does JUST that |
| 18:11 | callen | bosie: I haven't, but it's very popular. Did you do Go before? |
| 18:11 | bosie | callen: huh, no? |
| 18:12 | callen | bosie: just wondering. |
| 18:12 | ohpauleez | it's an overview of the entire project, with links out to areas people might be interested in |
| 18:12 | bosie | callen: Go to clojure is the trend now or what? ;) |
| 18:12 | hyPiRion | TimMc: http://hypirion.com/musings/swearjure |
| 18:12 | callen | bosie: bidirectional actually, but your name reminded me of a Go programmer, that's all. |
| 18:13 | callen | bosie: I learned Go after learning Clojure, came back because I decided my time was too precious. |
| 18:13 | callen | maybe someday the ecosystem will come together. |
| 18:13 | bosie | callen: hah. whats wrong with Go? i haven't looked at Go |
| 18:13 | aperiodic | hyPiRion: dear god man, turn of justification on your headers |
| 18:13 | callen | bosie: nothing |
| 18:13 | aperiodic | s/of/off |
| 18:13 | callen | bosie: I'm just persnickety. |
| 18:13 | bosie | callen: coworker loves it though |
| 18:13 | abp | ohpauleez, sure, but not discoverable from shoreleaves organization |
| 18:13 | ohpauleez | ahh gotcha |
| 18:13 | ohpauleez | thanks for the heads up everyone |
| 18:14 | callen | bosie: it has some nice attributes. |
| 18:14 | aperiodic | ohpauleez: exactly what i ran into the other day. found a shoreleave component, went looking for an overview, gave up |
| 18:14 | ohpauleez | aperiodic: gah, I'm both honored and sorry |
| 18:14 | ohpauleez | definitely will do my best to address it |
| 18:15 | abp | ohpauleez, datalog-like queries for cljs? |
| 18:15 | dog_cat11 | Go solves a lot of the problems with C, and has great concurrency features |
| 18:15 | ohpauleez | abp: Yeah, it's a terrible hack, but it's been useful when you have a large collection of map-like things |
| 18:16 | ohpauleez | I figured I'd put it in an incubator, and if people eat it up, move it into a dedicated module |
| 18:16 | abp | ohpauleez, yes, sounds interesting. |
| 18:16 | ohpauleez | it also makes working with local storage a little better |
| 18:17 | ohpauleez | the Swearjure post is amazing and hilarious |
| 18:17 | abp | ohpauleez, considering the size of your libs you could put it into a proper lib, or incubator more because of alphaness? |
| 18:17 | bosie | callen: is there a quick and easy way to run code distributed over multiple machienes in clj the same way you can in go? |
| 18:18 | ohpauleez | alphaness - I don't want to make a module just for the sake of it. I want to see that it gets used first |
| 18:18 | abp | ok |
| 18:18 | kovas | looks like my talk didn't get accepted to clojure west :/ |
| 18:19 | callen | bosie: that's a pretty strange question. horizontal scaling across multiple machines is possible in any programming language. That's architecture, not language runtime. |
| 18:19 | ohpauleez | kovas: NOOOOOOO |
| 18:19 | devn | Raynes: oh. cool! I tried (and (l/id= "foo") ...)) -- so that's intuitive i think |
| 18:19 | kovas | yeah, it was a bummer for about 10 minutes |
| 18:19 | kovas | but at least that means ill get to enjoy the conference :) |
| 18:19 | ohpauleez | was it something like, "Approaching manifolds of reality through intermediate combinators, tagged in Session" ? |
| 18:19 | bosie | callen: and yet i can get it done quicker in erlang than i could in java |
| 18:20 | callen | bosie: that's up to personal aptitude. |
| 18:20 | bosie | lol |
| 18:20 | bosie | ok |
| 18:20 | ohpauleez | kovas: All joking aside, what was the topic? |
| 18:20 | nDuff | callen: ...well, I think bosie has a valid point re: languages shipping w/ tools that are opinionated re: architecture. |
| 18:21 | kovas | ohpauleez: session. I assume alex saw my talk at the conj and just wasn't into it |
| 18:21 | kovas | ohpauleez: r u speaking? |
| 18:21 | Raynes | disagreeing with callen is a bad idea. |
| 18:21 | Raynes | He will eat you alive. |
| 18:21 | bosie | Raynes: bring it. jk. |
| 18:21 | ohpauleez | kovas: I am |
| 18:21 | kovas | ohpauleez: thnx :) |
| 18:21 | callen | nDuff: don't you start. |
| 18:21 | callen | nDuff: you and I both know the majority of time, that's not how it shakes out. |
| 18:21 | kovas | ohpauleez: I'm probably more excited about hack week after |
| 18:21 | callen | very very few people are using things like Akka. |
| 18:22 | callen | Raynes: don't warn them, it leaves me fewer bones to pick. |
| 18:22 | ohpauleez | kovas: You know I'm a session-lover. And hell yes, it'll be a good time for sure |
| 18:22 | technomancy | bosie: distributing calls over rabbitmq is pretty trivial and can be done in ~150 LOC: https://github.com/technomancy/die-roboter |
| 18:22 | dog_cat11 | there is a great chapter in Clojure in Action on RabbitMQ |
| 18:22 | kovas | ohpauleez: sweet. Session is getting close to being ready for prime time |
| 18:22 | dog_cat11 | pretty cool stuff |
| 18:23 | ohpauleez | sick, totally amped for that |
| 18:24 | kovas | jonase helped get it hooked up to nrepl, which is key |
| 18:24 | aperiodic | hyPiRion: awesome sweajure writeup |
| 18:24 | bosie | dog_cat11: thx for the tip |
| 18:25 | kovas | need to flow some nrepl functionality into the ui (like interrupt and std out) and declare victory |
| 18:26 | kovas | ohpauleez: btw I'm also getting interested in shoreleave-related stuff |
| 18:26 | ohpauleez | kovas: sick, that will be stellar to see. Ping me when you have it where you want it. I'll bang on it for sure |
| 18:26 | dog_cat11 | bosie: Clojure's STM is great, but on hardware like a cluster you are forced to use the distributed memory model |
| 18:26 | Raynes | ohpauleez: http://www.youtube.com/watch?v=H7HmzwI67ec |
| 18:27 | kovas | ohpauleez: i think there is something to be made by integrating shoreleave, datomic, and angular.js |
| 18:27 | ohpauleez | kovas: Rad! Shoreleave is basically all the bitch work you'd have to do to build a real application |
| 18:27 | ohpauleez | kovas: I agree |
| 18:28 | ohpauleez | I actually prototyped a "cursor" for Shoreleave - that grabbed remote chunks of data as-needed |
| 18:28 | ohpauleez | with the idea that you could wire datomic right into a client if you really wanted to |
| 18:28 | kovas | ohpauleez: the UI<-> datomic interaction is whats really slowing down session dev at the moment |
| 18:29 | ohpauleez | kovas: there's definitely room for innovation there, I agree |
| 18:29 | kovas | ohpauleez: i might shoot some questions your way when i have a clearer idea |
| 18:29 | ohpauleez | definitely |
| 18:29 | kovas | ohpauleez: right now I'm imagining entities being mapped back and forth between angular and datomic, via shoreleave |
| 18:30 | ohpauleez | word word |
| 18:30 | kovas | ohpauleez: but need to learn me some angular first |
| 18:30 | kovas | :) |
| 18:30 | ohpauleez | Raynes: Is this an invitation to a dance party? |
| 18:30 | ohpauleez | or just because I'm always amped |
| 18:30 | Raynes | [17:11:35] <ohpauleez> kovas: You know I'm a session-lover. And hell yes, it'll be a good time for sure |
| 18:30 | Raynes | Made me think of it. |
| 18:31 | ohpauleez | ahhh |
| 18:31 | _46bit | Hello fellow Clojurites. |
| 18:32 | TimMc | hyPiRion: my-nth is sweet! |
| 18:34 | Raynes | ohpauleez: I apologize for shoving pop down your throat. |
| 18:34 | ohpauleez | apology accepted :) |
| 18:34 | ohpauleez | actually |
| 18:35 | ohpauleez | no, I take that back, I'm going to trade you |
| 18:35 | Raynes | Challenge accepted. |
| 18:35 | ohpauleez | https://www.youtube.com/watch?v=L-6ugLM3ARw |
| 18:35 | ohpauleez | enjoy |
| 18:37 | ohpauleez | hopefully that video goes viral in the Clojure community :) |
| 18:39 | TimMc | hyPiRion: By the way, #(...) is more properly a function literal -- all Clojure fns are anonymous. |
| 18:41 | dog_cat11 | so then defn binds an anonymouse function to a symbol? |
| 18:42 | Raynes | ohpauleez: http://www.youtube.com/watch?v=S712u9HBISs |
| 18:42 | gtrak | ,(macroexpand '(defn a [])) |
| 18:42 | clojurebot | #<Exception java.lang.Exception: SANBOX DENIED> |
| 18:42 | dnolen | dog_cat11: a var |
| 18:42 | dog_cat11 | ok |
| 18:43 | gtrak | &(macroexpand '(defn a [])) |
| 18:43 | lazybot | ⇒ (def a (clojure.core/fn ([]))) |
| 18:43 | ohpauleez | Raynes: it's a race to the bottom |
| 18:43 | ohpauleez | :) |
| 18:44 | dog_cat11 | &(macroexpand '(def a #())) |
| 18:44 | lazybot | java.lang.SecurityException: You tripped the alarm! def is bad! |
| 18:44 | TimMc | ,(. :foo `[5]) |
| 18:44 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: No matching method found: apply for class clojure.lang.Keyword> |
| 18:45 | hyPiRion | TimMc: Thanks and thanks |
| 18:45 | TimMc | ^ .apply method -- useful? |
| 18:45 | dog_cat11 | &`#() |
| 18:45 | TimMc | ,(macroexpand-1 `(. :foo `[5])) |
| 18:45 | lazybot | ⇒ (fn* [] ()) |
| 18:45 | clojurebot | (. :foo (clojure.core/apply clojure.core/vector (clojure.core/seq (clojure.core/concat (clojure.core/list 5))))) |
| 18:46 | amalloy | TimMc: you need applyTo; i don't think any interesting clojure classes have a .apply method |
| 18:46 | TimMc | dammit |
| 18:49 | patchwork | I have a jvm-opt that needs to be set to two different values based on the environment my app is in. Lein has me define :jvm-opts in project.clj, but that means that value is hard-coded! How do I have jvm-opts that are different based on different deploy environments? |
| 18:50 | abp | ohpauleez, have you had any problems with the history component of the closure-library? Is this just not closed? http://code.google.com/p/closure-library/issues/detail?id=449&q=history |
| 18:51 | hyPiRion | patchwork: It accepts JAVA_OPTS and JVM_OPTS as values too |
| 18:51 | dog_cat11 | what about using the java system library? |
| 18:52 | hyPiRion | It'll read those |
| 18:52 | patchwork | hyPiRion: Aha, thanks! |
| 18:54 | TimMc | hyPiRion: Hey, what symbols can you get from the beginning of a syntax-quoted forms? |
| 18:54 | TimMc | so far I've gotten list, seq, and apply. |
| 18:55 | dog_cat11 | &(java.lang.System/getenv "PATH") |
| 18:55 | lazybot | java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.PATH) |
| 18:56 | dog_cat11 | &(java.lang.System/getenv) |
| 18:56 | lazybot | java.security.AccessControlException: access denied (java.lang.RuntimePermission getenv.*) |
| 18:56 | dog_cat11 | &(java.lang.System/nanoTime) |
| 18:56 | lazybot | ⇒ 32487356433694018 |
| 18:56 | hyPiRion | TimMc: fn* through ##'#() |
| 18:56 | lazybot | ⇒ (fn* [] ()) |
| 18:57 | TimMc | oh, huh |
| 18:57 | TimMc | so that's fn_STAR_ |
| 18:57 | dog_cat11 | &(java.lang.System/getProperties) |
| 18:57 | lazybot | java.security.AccessControlException: access denied (java.util.PropertyPermission * read,write) |
| 18:58 | hyPiRion | and quote |
| 18:58 | TimMc | unquote, quote, unquote_splicing, var, deref |
| 19:02 | hyPiRion | ,``^{+ -} () |
| 19:02 | clojurebot | (clojure.core/with-meta (clojure.core/list) (clojure.core/apply clojure.core/hash-map (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/+)) (clojure.core/list (quote clojure.core/-)))))) |
| 19:02 | hyPiRion | another one |
| 19:03 | TimMc | Whoa, I didn't think I could get with-meta. |
| 19:03 | hyPiRion | yeah, me neither |
| 19:04 | gfredericks | you guys are breaking new ground |
| 19:04 | aperiodic | have you tried writing a syntax-quote fuzzer to look for symbols? |
| 19:04 | TimMc | Wow, plenty of stuff has withMeta methods, but nothing has with_meta, of course. |
| 19:06 | TimMc | There may be some neat tricks one can do with the stitching macros. |
| 19:08 | gtrak | what is happening? |
| 19:09 | TimMc | Line-noise explorations. |
| 19:09 | gtrak | ah, swearjure? |
| 19:10 | TimMc | &(clojure.walk/macroexpand-all '(->> 0 (->> 1 (->> @2 (->> 3))))) ;; I have no idea what I'm doing |
| 19:10 | lazybot | ⇒ (0 (1 (clojure.core/deref 2 3))) |
| 19:11 | TimMc | Huh: ##(clojure.walk/macroexpand-all '(->> . :__ (->> @ two (->> args)))) |
| 19:11 | lazybot | java.lang.StackOverflowError |
| 19:12 | gfredericks | TimMc: can I claim credit as the inspirer of swearjure? |
| 19:13 | jlewis | urgh, more print-method confusion: ##(methods print-method) |
| 19:13 | lazybot | ⇒ {nil #<core$fn__5236 clojure.core$fn__5236@62312b>, java.util.regex.Pattern #<core$fn__5342 clojure.core$fn__5342@e2e191>, clojure.lang.Symbol #<core$fn__5262 clojure.core$fn__5262@16fc264>, :default #<core$fn__5232 clojure.core$fn__5232@81229a>, clojure.lang.IR... https://www.refheap.com/paste/8289 |
| 19:13 | TimMc | hyPiRion linked to the logs, but he really should throw in a link to one of your sites as well. |
| 19:13 | xeqi | wouldn't that generate negative cred? |
| 19:13 | jlewis | oh, wtf, it overflows in my repl |
| 19:13 | jlewis | i think my repl has screwed up state. |
| 19:15 | hyPiRion | TimMc: Link? |
| 19:16 | TimMc | gfredericks: Link? |
| 19:17 | TimMc | Wow, ->> and -> are really screwed up. |
| 19:17 | TimMc | &(clojure.walk/macroexpand-all '(-> a (->> b c))) |
| 19:17 | lazybot | ⇒ (c (b a)) |
| 19:17 | TimMc | &(clojure.walk/macroexpand-all '(->> a (->> b c))) |
| 19:17 | lazybot | ⇒ (a (c b)) |
| 19:20 | hyPiRion | &(->> ~@[hurr durr] quote) |
| 19:20 | lazybot | ⇒ (clojure.core/unquote-splicing [hurr durr]) |
| 19:21 | gfredericks | TimMc: gfredericks: huh? |
| 19:21 | gfredericks | wait you guys are actually posting credit about swearjure somewhere? |
| 19:21 | gfredericks | is there a git repo or something for this stuff? |
| 19:22 | hyPiRion | not "credit", I just mentioned it here: http://hypirion.com/musings/swearjure |
| 19:22 | amalloy | see if you can get it a wikipedia entry, gfredericks |
| 19:22 | gfredericks | well look at that. |
| 19:22 | mpan | oh hey I just ran into that article on Hn |
| 19:22 | TimMc | &(let [wtf (iterate macroexpand-1 '(->> . :__ (->> @ two (->> args))))] (= (nth wtf 5) (nth wtf 9))) |
| 19:22 | lazybot | ⇒ true |
| 19:22 | TimMc | hyPiRion: macro-expansion loop! |
| 19:23 | hyPiRion | TimMc: Wow, these macros |
| 19:23 | TimMc | hyPiRion: gfredericks has a bug open on -> not expanding intuitively |
| 19:23 | gfredericks | oh I don't have anything worth linking it to |
| 19:23 | TimMc | Home page? github? |
| 19:23 | gfredericks | gfredericks.com or twitter.com/gfredericks_ |
| 19:28 | amalloy | TimMc: that wtf doesn't fit in my head at all. what do? |
| 19:28 | gfredericks | hyPiRion: is an "algorist" an algo person? |
| 19:29 | hyPiRion | http://en.wikipedia.org/wiki/Algorist |
| 19:29 | hyPiRion | yeah |
| 19:29 | gfredericks | wait |
| 19:29 | TimMc | amalloy: I'm... not sure. |
| 19:29 | gfredericks | I just confused "agda" and "algo" in my head :) |
| 19:30 | gfredericks | TimMc: amalloy: both are nil? |
| 19:30 | TimMc | Nope. |
| 19:30 | gfredericks | &(macroexpand-1 '(->> . :__ (->> @ two (->> args)))) |
| 19:30 | lazybot | ⇒ (clojure.core/->> (clojure.core/->> . :__) (->> (clojure.core/deref two) (->> args))) |
| 19:30 | TimMc | Put this in your REPL: (pprint (take 8 (iterate macroexpand-1 '(->> . :__ (->> @ two (->> args)))))) |
| 19:31 | TimMc | macroexpand-all will do a stack overflow |
| 19:31 | TimMc | Anyway, notice the last item and the fourth item are the same. |
| 19:31 | amalloy | TimMc: macroexpand-all overflowing isn't very interesting, because clojure.walk is trash. it's only interesting if macroexpand also overflows (which i think it does, right?) |
| 19:32 | TimMc | Yeah, it does. |
| 19:33 | TimMc | ,(macroexpand '(->> a b (->> (c d) (->> e)))) |
| 19:33 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.StackOverflowError> |
| 19:33 | TimMc | Filing a JIRA, I guess. |
| 19:33 | gfredericks | ,(macroexpand-1 '(->> a b (->> (c d) (->> e)))) |
| 19:33 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: java.lang.StackOverflowError> |
| 19:33 | gfredericks | oh wow |
| 19:33 | hyPiRion | Well, what is is supposed to expand to? |
| 19:34 | TimMc | gfredericks: Oh, that's new. |
| 19:34 | gfredericks | TimMc: put my name in the blog post about it |
| 19:34 | TimMc | hyPiRion: Hell if I know. |
| 19:35 | gfredericks | I don't think the bug I filed would explain any of that |
| 19:35 | TimMc | So, I guess I accidentally quined a macro! |
| 19:36 | gfredericks | macroexpand-1 overflowing is really bizarre |
| 19:36 | TimMc | gfredericks: I think it's just clojurebot. |
| 19:36 | gfredericks | ,(#'->> nil nil 'a 'b '(->> (c d) (->> e))) |
| 19:36 | clojurebot | (clojure.core/->> (clojure.core/->> a b) (->> (c d) (->> e))) |
| 19:36 | TimMc | &(macroexpand-1 '(->> a b (->> (c d) (->> e)))) |
| 19:36 | lazybot | ⇒ (clojure.core/->> (clojure.core/->> a b) (->> (c d) (->> e))) |
| 19:36 | gfredericks | ah phew |
| 19:36 | TimMc | &(macroexpand '(->> a b (->> (c d) (->> e)))) |
| 19:36 | lazybot | java.lang.StackOverflowError |
| 19:37 | gfredericks | so presumably my patch to ->> would eliminate the quining? |
| 19:37 | TimMc | I tmight. |
| 19:37 | gfredericks | my apologies if it gets accepted |
| 19:37 | TimMc | heh, no, it really should |
| 19:37 | TimMc | Got the issue number handy? |
| 19:38 | gfredericks | $google CLJ-1121 |
| 19:38 | TimMc | thanks |
| 19:38 | gfredericks | you're gonna comment? |
| 19:38 | TimMc | hellz yeah |
| 19:38 | hyPiRion | $kill |
| 19:38 | lazybot | KILL IT WITH FIRE! |
| 19:38 | gfredericks | $bill |
| 19:39 | TimMc | gfredericks: Actually, do you have that patched Clojure handy? |
| 19:39 | gfredericks | as a branch you mean? |
| 19:39 | gfredericks | I believe so |
| 19:40 | gfredericks | check my clojure fork |
| 19:40 | gfredericks | a branch called threading or something I think |
| 19:41 | gfredericks | actually I don't see it o_O |
| 19:41 | TimMc | (Read: I'm too lazy to go find your fork, can you try that macroexpansion out?) |
| 19:41 | gfredericks | oh gotcha |
| 19:41 | gfredericks | not easily :) sorry |
| 19:41 | TimMc | I'll just grab the patches tonight if you're busy. |
| 19:41 | gfredericks | well wait |
| 19:42 | gfredericks | nope cancel that; don't have it |
| 19:42 | TimMc | okey doke |
| 19:42 | dnolen | so reduce can be short circuited in 1.5.0 |
| 19:43 | gfredericks | sounds right |
| 19:43 | dnolen | I should have known that - but nobody brought that up last time I asked about it :) |
| 19:43 | gfredericks | how do you do it? call a function that constructs a special type? |
| 19:43 | amalloy | yes |
| 19:43 | amalloy | (reduced 10) |
| 19:44 | gfredericks | well look at that. |
| 19:44 | dnolen | SWEEEET |
| 19:44 | gfredericks | is it a deftype? |
| 19:44 | gfredericks | or a java class? |
| 19:44 | Bronsa | it's a class |
| 19:44 | amalloy | dnolen: you may be excited to know that each reducer needs to implement support for reduced by hand, and some of them do it wrong (or at least did before being patched) |
| 19:45 | dnolen | amalloy: I'm assuming their fixed in RC1 right? |
| 19:45 | gfredericks | does clojure not define any types or protocols? I wonder why it would be avoided... |
| 19:45 | dnolen | amalloy: but yes, needing to support reduced in the implementation makes sense to me, how else could it work? |
| 19:45 | hiredman | clojure does both |
| 19:46 | gfredericks | hiredman: both types and protocols you mean? any idea why clojure.lang.Reduced wouldn't be a type then? |
| 19:46 | gfredericks | I assume there's no real need either way, but still... |
| 19:46 | amalloy | dnolen: i fixed the one i noticed. i don't remember if the patch was actually applied |
| 19:46 | gfredericks | I guess that would throw an extra ->Reduced function into clojure.core that would be kind of silly |
| 19:47 | gfredericks | s/silly/distracting/ |
| 19:48 | gfredericks | huh; cljs doesn't do ->Foo for deftypes |
| 19:48 | hiredman | gfredericks: my guess is it makes it easier to work with from the jvm impl, but RT has RT.isReduced |
| 19:49 | hiredman | but the collect types that implement things like kv-reduce in java need to be able to check for reduced |
| 19:50 | gfredericks | hiredman: that makes sense |
| 19:50 | amalloy | ,'&1 |
| 19:50 | clojurebot | &1 |
| 19:50 | TimMc | heh |
| 19:50 | amalloy | ,(symbol "echo 1") |
| 19:50 | clojurebot | echo 1 |
| 19:50 | TimMc | wait, nooooo |
| 19:50 | amalloy | hyPiRion: there. problem solved |
| 19:50 | TimMc | How will I inc myself now? |
| 19:50 | amalloy | you monster |
| 19:50 | hyPiRion | echo 1 |
| 19:50 | lazybot | 1 |
| 19:51 | gfredericks | amalloy: patching up the botholes? |
| 19:51 | hyPiRion | ah, nice. |
| 19:53 | TimMc | Hmm, how do I start the clojure REPL if all I have is the clojure core jar? |
| 19:53 | hyPiRion | clojure.main |
| 19:53 | TimMc | Huh, OK. |
| 19:56 | TimMc | gfredericks: (b a (c d e)) |
| 19:56 | TimMc | Your patch works! |
| 19:56 | gfredericks | sweetso! |
| 19:57 | gfredericks | (defne sweetso [x] ([:candy]) ([:muffins])) |
| 19:57 | gfredericks | or rather (def sweetso #(membero % [:candy :muffins])) |
| 19:59 | amalloy | dnolen: yeah, my patch to reduced did get applied. so i don't know of any incorrect implementations of it at this time |
| 20:00 | Raynes | No more multibot quines, guys. Sorry to ruin your fun, but amalloy added a global ignore feature. |
| 20:00 | amalloy | they know, man. i announced it |
| 20:00 | Raynes | Now we've both announced it. |
| 20:00 | xeqi | echo am I on ignore? |
| 20:00 | lazybot | am I on ignore? |
| 20:01 | gfredericks | ,(println "/nick cloojurebot") |
| 20:02 | clojurebot | /nick cloojurebot |
| 20:02 | Raynes | gfredericks: That isn't a thing though. |
| 20:02 | amalloy | next step: adding a $ignore command to modify it at runtime so i can shame people with "$ignore gfredericks because he's a twerp" |
| 20:03 | TimMc | ,(symbol "\u0001ACTION has baggy pants") |
| 20:03 | nybbles | hello, i want to update some shared state, do a HTTP request and only have that change to shared state persist if the HTTP request is successful. if it is unsuccessful, the change should be unrolled. what's a good way of doing that? |
| 20:03 | TimMc | amalloy: Here's that broken ->> in action: https://www.refheap.com/paste/8292 |
| 20:05 | TimMc | nybbles: Can you do the HTTP request first and then change shared state based on its results? |
| 20:06 | nybbles | the problem with that approach is that the HTTP request acts on a remote resource, and i change the shared state to make sure that another part of the program doesn't delete the remote resource |
| 20:07 | nybbles | so i was thinking of changing the shared state to make sure that I continue to have access to the remote resource.. update the remote resource with a POST and then if that POST is successful, not roll back the local shared state |
| 20:13 | nybbles | hmmm i just got an idea of using two refs instead of one atom, where one ref holds the number of outstanding POSTs and we dont do any deleting while that number is > 0 |
| 20:14 | TimMc | hyPiRion, gfredericks: The minimal form of that pathological case is (->> a b (->> c d)) |
| 20:15 | pandeiro | technomancy: what would be the easiest way to add a new route via nrepl, given your heroku webapp template? |
| 20:16 | technomancy | pandeiro: not sure I understand the question? |
| 20:17 | pandeiro | technomancy: sorry, let me try again: is there a way to change the app's routes w/o redefining myapp.web/app? |
| 20:17 | amalloy | (->> a b (->> c d)) :: (->> (b a) (->> c d)) :: (->> c d (b a)) :: (->> (d c) (b a)) :: (b a (d c)) is the expansion path that "should" take, right TimMc? |
| 20:18 | technomancy | pandeiro: I don't think so. maybe some weird low-level way to do it, but I wouldn't recommend it. |
| 20:18 | pandeiro | technomancy: ie, if the app's routes were a map or something, you could just assoc a new key... but since ring/compojure work with functions... |
| 20:18 | technomancy | pandeiro: something wrong with recompiling? |
| 20:19 | pandeiro | technomancy: not really, just exploring what having the repl access could possibilitate :) |
| 20:19 | technomancy | nearly anything that works locally |
| 20:19 | weavejester | pandeiro: Why is not redefining myapp.web/app a possibility? |
| 20:19 | pandeiro | technomancy: but with the extra push step |
| 20:20 | pandeiro | weavejester: well imagining i didn't have the source file open in emacs right next to me |
| 20:20 | pandeiro | say i was on another computer somewhere |
| 20:20 | technomancy | pandeiro: well, with the caveat that the local disk is not the remote disk, and most nrepl clients don't support the HTTP transport yet |
| 20:21 | pandeiro | technomancy: you mean for pushing the changes? i'm confused - what about drawbridge? isn't this working over http? |
| 20:21 | weavejester | Hm, making modifications without the source seems a little iffy to me |
| 20:21 | technomancy | pandeiro: drawbridge is a server component |
| 20:21 | technomancy | most nrepl clients don't support the HTTP transport, but `lein repl` does |
| 20:21 | technomancy | err--I guess it's both |
| 20:22 | technomancy | but you can't use drawbridge from your client unless your client is written in clojure |
| 20:22 | pandeiro | technomancy: ah, yeah so i'm using lein repl :connect, which i guess i could need wherever i was |
| 20:22 | technomancy | so maybe you could use it in ccw, but not emacs or vim |
| 20:22 | pandeiro | weavejester: yeah i realize that, but say, i dunno, i just wanted to disable a certain route quickly? |
| 20:24 | pandeiro | technomancy: i did lein repl :connect from *shell*, but is there any reason i couldn't make that the inferior-lisp command or somehow hook up nrepl.el to use the remote repl? |
| 20:24 | technomancy | pandeiro: you can use it with inf-lisp |
| 20:24 | technomancy | using it from nrepl.el would basically require porting drawbridge to elisp |
| 20:25 | technomancy | not sure how hard that would be |
| 20:25 | hiredman | just the client part |
| 20:25 | technomancy | right |
| 20:25 | hiredman | if you have json parsing + http requests it is not to hard |
| 20:25 | technomancy | I would love for someone to pick that up =) |
| 20:25 | hiredman | you'd have to write elisp |
| 20:26 | pandeiro | technomancy: give me another year or two with emacs/clojure and i'm your guy :) |
| 20:26 | hiredman | https://github.com/hiredman/drawbridge-cljs/blob/master/src-cljs/drawbridge/client.cljs is an drawbridge client in clojurescript, and it is async which is a plus when you are single threaded like emacs |
| 20:27 | hiredman | the http transport does require polling though, instead of just sending data like with a real connection |
| 20:45 | bbloom | i hate it when you have a cond (or pattern matching) that has a non obvious implicit requirement on the exact ordering |
| 20:55 | TimMc | amalloy: Correct. |
| 21:05 | tomoj | so I have a snippet for repl mode 'r' which require/:refers pprint, doc, pst, and requires io and str, and will probably require other stuff that's in core soon |
| 21:06 | tomoj | but forgetting, getting an error, and having to do `r TAB` in every new namespace is still pretty annoying |
| 21:06 | tomoj | any sane way to make it any better? |
| 21:06 | tomoj | it's not that annoying I suppose, but enough to make me want to change it |
| 21:19 | gfredericks | wow domina uses a single-element namespace |
| 21:19 | gfredericks | that's hot |
| 21:20 | BIGBOOMBA | Having trouble installing leiningen on Debian. Tried apt-get, but there was a dependency issue that I couldn't resolve. Downloaded the shell script and put it in /usr/bin, chmodded it, and when I ran "lein" I just got a page full of JVM error messages. |
| 21:20 | BIGBOOMBA | Leading off with "Exception in thread "main" java.lang.NoClassDefFoundError: clojure.core.protocol" |
| 21:21 | gfredericks | O_O |
| 21:21 | tpope | BIGBOOMBA: how did you install the jvm? |
| 21:23 | TimMc | BIGBOOMBA: You'll do better off with lein in ~/bin -- that way it can self-upgrade. |
| 21:23 | BIGBOOMBA | Just from www.java.com, I think. Running "java -version" gives "java version "1.5.0" gij (GNU libgcj) version 4.4.5" |
| 21:23 | BIGBOOMBA | Okay, Tim, thanks, I'll move it there. |
| 21:23 | BIGBOOMBA | Yeah, I have the gjc compiler, not javac. |
| 21:24 | gfredericks | woah the ns order bug is still not fixed in cljsbuild-HEAD? |
| 21:24 | BIGBOOMBA | Or gcj |
| 21:24 | gfredericks | how long does a guy have to wait without contributing anything before other people fix everything for him? |
| 21:25 | BIGBOOMBA | Would it help if I put the rest of the error messages on pastebin? |
| 21:28 | BIGBOOMBA | Here's what happened after I put the lein script in /usr/bin, chmodded it, and tried to run it |
| 21:28 | BIGBOOMBA | http://pastebin.com/QQs6WMMy |
| 21:29 | tpope | BIGBOOMBA: I haven't yet tried with lein, but every time I install gcj rather than the official jvm, I always end up regretting it |
| 21:29 | tpope | running into weird issues exactly like this |
| 21:30 | BIGBOOMBA | You mean the official java compiler? I had a JVM installed before I downloaded gcj. Do you mean that I should replace gcj with javac? |
| 21:34 | amalloy | gcj is useless trash |
| 21:35 | tpope | BIGBOOMBA: that would be the first step I tried |
| 21:38 | TimMc | "incompatible type on stack" <-- never seen *that* before |
| 21:39 | BIGBOOMBA | I'm at Java's website, on their JDK download page. Can I use OpenJDK with javac? I'd prefer to use open-source tools if possible. |
| 21:40 | dog_cat11 | that should work |
| 21:42 | TimMc | Sure, I use OpenJDK 6. |
| 21:43 | BIGBOOMBA | apparently i have java 1.5 and not openjdk |
| 21:45 | BIGBOOMBA | should i use openjdk 6 instead of 7? is there a problem with 7? |
| 21:47 | xeqi | BIGBOOMBA: I'm using openjdk7 just fine |
| 21:48 | xeqi | installed on ubuntu with `apt-get install openjdk-7-jdk`. I'd expect debian to have a similar package, or at least one for openjdk-6 |
| 21:48 | dog_cat11 | did you check your repositories? |
| 21:51 | gfredericks | it's odd that domina doesn't have any kind of dom-ready facility |
| 21:59 | bbloom | gfredericks: that's b/c gclosure doesn't have a dom-ready facility |
| 21:59 | arrdem | today I learned that terrible things happen when you rebind the "apply" function. |
| 21:59 | bbloom | gfredericks: and that's b/c google doesn't want their apps to use it |
| 22:02 | amalloy | arrdem: no kidding, huh? that's gotta be in the top ten list of "worst functions you could redef" |
| 22:03 | arrdem | amalloy: I figured I was gonna be okay because there wasn't much else in that namespace and I only :required :as it elsewhere but next thing I knew I had build-breaking null pointer exceptions everywhere |
| 22:08 | gfredericks | bbloom: interesting; I found a good explanation for that; thanks |
| 22:27 | TimMc | Raynes: I think I broke lazybot, could you restart it? |
| 22:29 | amalloy | TimMc: what did you do? |
| 22:30 | amalloy | did you redefine the 'let macro or something? his error message is bizarre |
| 22:30 | TimMc | *looks |
| 22:30 | TimMc | I... I'm not entirely sure? |
| 22:30 | TimMc | I *may* have been slightly trying to get eval. |
| 22:32 | xeqi | oooh |
| 22:33 | TimMc | Aw, c'mon, don't take away my toy! |
| 22:33 | TimMc | \o/ |
| 22:33 | amalloy | &1 |
| 22:33 | lazybot | ⇒ 1 |
| 22:34 | amalloy | next time you break him, keep a log of what you did or i'll take away your toy |
| 22:34 | TimMc | Oh, yes -- I *did* redefine let. My bad. |
| 22:34 | TimMc | I'll test stuff in my own REPL first. |
| 22:37 | amalloy | hah! well, of course you shouldn't have been able to redefine let |
| 22:37 | TimMc | Yeah, but if I tell you how I did it you'll close the hole and I won't be able to finish my trick. |
| 22:38 | TimMc | I'll try very hard not to break it, then tell you. |
| 22:38 | amalloy | *chuckle* okay |
| 22:39 | xeqi | arrdem: some previous ones http://nelsonmorris.net/2012/09/06/breaking-lazybot-out-of-clojail.html |
| 22:40 | TimMc | Hey, that's me! |
| 22:40 | xeqi | it is! |
| 22:40 | arrdem | xeqi: cheers, looks like an interesting read! |
| 22:41 | Raynes | TimMc: Whatever it is, please don't mention it in public. I really don't feel like spending the week working on clojail. :p |
| 22:41 | TimMc | Well, this one is pretty obvious. No offense. |
| 22:41 | TimMc | Raynes: Yeah, I'll do it responsibly, since it's a clojail problem, not lazybot. |
| 22:42 | Raynes | Offense takne. |
| 22:42 | Raynes | taken* |
| 22:42 | arrdem | lol |
| 22:42 | TimMc | Or maybe it's just lazybot's settings, in which case I'll blurt it out at an inconvenient time. |
| 22:42 | Raynes | When do you plan on letting me know what it is? |
| 22:43 | TimMc | Tonight? |
| 22:43 | TimMc | How long will you be up? |
| 22:44 | Raynes | I'll be here for the rest of the night. Just trying to figure out what you're waiting for. |
| 22:44 | TimMc | my code to be ready |
| 22:44 | TimMc | OK, gonna try a basic case... |
| 22:44 | Raynes | Well, if it's super obvious, how hard could it be? |
| 22:45 | arrdem | Very Easy™ |
| 22:45 | amalloy | ps TimMc i'm spying on your PMs to lazybot |
| 22:45 | TimMc | Raynes: Well, this time I'm not bashing randomly on my keyboard so that I don't crash lazybot. |
| 22:45 | TimMc | amalloy: onoes! |
| 22:46 | xeqi | I hope its a previously unknown one |
| 22:50 | TimMc | amalloy: I'm imagining you laughing to yourself as I struggle with this. :-( |
| 22:51 | amalloy | i'm not watching you as carefully as all that |
| 22:51 | TimMc | good |
| 22:52 | amalloy | but your p here is a function value, not a var, so your strategy can't change it |
| 22:52 | TimMc | amalloy: By the way, is this a clojail bug or a lazybot bug? |
| 22:52 | Raynes | clojail |
| 22:52 | TimMc | eep |
| 22:52 | Raynes | And not a big one either. |
| 22:53 | Raynes | xeqi has some other cute standing vulnerabilities I need to fix soon. |
| 22:53 | TimMc | I was pretty surprised it worked. (For some value of "worked".) |
| 22:54 | TimMc | amalloy: Am I just completely misunderstanding this feature? |
| 22:56 | amalloy | i dunno. i thought i knew what you were doing but i'm wrong |
| 22:56 | TimMc | haha |
| 22:56 | amalloy | just PM people with what you're actually doing. spying isn't easy |
| 22:56 | Raynes | I support this motion. |
| 22:56 | amalloy | unless you want to do it in secret, and then stop asking for feedback |
| 22:57 | arrdem | take this to #break-lazybot? |
| 22:57 | Raynes | No. |
| 22:57 | TimMc | Well, it's late enough at night for me that I don't feel like going the last mile, and anyway you already know the exploit. |
| 22:57 | TimMc | arrdem: Nah, I don't know how to lock down a channel. |
| 22:57 | TimMc | Raynes: -> PM |
| 22:58 | blackdog | hey - is there a way to look up docs of a clojure form from the repl? |
| 22:58 | arrdem | ,(doc doc0 |
| 22:58 | clojurebot | #<ExecutionException java.util.concurrent.ExecutionException: java.lang.RuntimeException: EOF while reading> |
| 22:58 | arrdem | ,(doc doc) |
| 22:58 | clojurebot | "([name]); Prints documentation for a var or special form given its name" |
| 22:58 | blackdog | cheers |
| 22:58 | arrdem | glad I could help |
| 23:03 | arrdem | ,(doc comment) |
| 23:03 | clojurebot | "([& body]); Ignores body, yields nil" |
| 23:08 | gtrak | hmm |
| 23:09 | bbloom | i love update-in so much that i made an update-top for a stack and i've got an (update-top stack update-in [:some-key] f arg) and it's glorious |
| 23:12 | gtrak | (swap! stack update-top update-in [:some-key] f arg) |
| 23:12 | arrdem | is there a clean way to print the symbols and values of a let form? |
| 23:12 | tpope | bbloom: when I showed you my netrc parser, it was in dire need of such a construct, and you just told me the low level stack operations aren't really used :( |
| 23:12 | tomoj | (println (second let-form)) :P |
| 23:13 | gtrak | arrdem: you most definitely need a macro for this |
| 23:13 | arrdem | tomoj: .... are you for real? |
| 23:13 | bbloom | tpope: i forget the details of that situtation |
| 23:13 | tomoj | I don't know what you mean |
| 23:13 | tomoj | &(println (second '(let [x 42] x))) |
| 23:13 | lazybot | ⇒ [x 42] nil |
| 23:13 | tpope | I'm sure you did |
| 23:13 | bbloom | update-top is pretty easy tho: (defn update-top [stack f & args] (conj (pop stack) (apply f (peek stack) args))) |
| 23:14 | arrdem | ah. that makes more sense. oookay. thanks @gtrak, @tomoj |
| 23:14 | bbloom | maybe i was suggesting you destructure from the top of the stack? that's more common than pop & peek |
| 23:15 | tpope | (conj (pop stack) (assoc-in (peek stack) [1 (keyword k)] v)) |
| 23:15 | tpope | is what I had |
| 23:15 | bbloom | ah |
| 23:15 | tpope | I don't think you had any suggestions, but then we derailed on to that whole "default" requirement |
| 23:15 | tpope | and then amalloy just rewrote it |
| 23:15 | arrdem | ,(str (quote foo)) |
| 23:15 | bbloom | tpope: heh, oh well. my new suggestion: update-top :-) |
| 23:16 | clojurebot | "foo" |
| 23:16 | amalloy | bbloom: which is in useful, if someone happens to want it, named update-peek iirc |
| 23:17 | bbloom | amalloy: i still haven't really dug into useful |
| 23:17 | blackdog | bbloom: update-in looks a lot like lenses |
| 23:17 | bbloom | blackdog: how so? |
| 23:18 | blackdog | composable way of navigating data structures |
| 23:18 | bbloom | blackdog: lenses are pairs of functions (A -> B, B -> A) |
| 23:18 | gtrak | arrdem: take a look at this awfmacro I made and never use: https://gist.github.com/4499370 |
| 23:18 | amalloy | lenses are how you can trick a strongly-typed map into supporting update-in |
| 23:18 | blackdog | unless i've misread what update-in does |
| 23:18 | gtrak | awful* it parses a let form and dumps the bindings into a map |
| 23:18 | bbloom | in this case, it's get-out/put-in |
| 23:18 | bbloom | which is only a subset of a full lens |
| 23:19 | bbloom | albiet a useful subset |
| 23:20 | bbloom | update-whatever functions remind me more of common lisp's setf |
| 23:20 | bbloom | but non-mutating |
| 23:20 | blackdog | bbloom: yeah. i'm coming from the haskell world, just trying to find analogs. |
| 23:21 | bbloom | gotcha |
| 23:21 | bbloom | anyway, gotta go |
| 23:22 | arrdem | perfect... https://www.refheap.com/paste/8310 |
| 23:22 | tomoj | hmm |
| 23:22 | tomoj | `modL l f a = setL l (f (getL l a)) a` |
| 23:23 | arrdem | well... that'll break if you do destructuring... |
| 23:23 | gtrak | arrdem: my macro also handles destructuring propely |
| 23:23 | gtrak | properly* |
| 23:23 | arrdem | gtrak: exercise for the reader. gimme a minute here. |
| 23:23 | gtrak | that's what all the tree-seq stuff is for |
| 23:26 | arrdem | gtrak: (filter symbol? (tree-seq seq? identity <root>)) |
| 23:26 | gtrak | possibly :-) |
| 23:26 | gtrak | I'm not a tree-seq ninja |
| 23:26 | arrdem | ,(seq? (first {:foo :bar})) |
| 23:27 | clojurebot | false |
| 23:30 | gtrak | I guess map-entries aren't seqs? |
| 23:31 | arrdem | right, so that tree traversal wouldn't get {:keys [foo bar baz]} |
| 23:36 | arrdem | gtrak: haha cute! yours just uses (destructure), amirite? |
| 23:37 | gtrak | hmmm, I wonder why it wouldn't work with out that |
| 23:38 | gtrak | it seems like I could just expand bindings, too |
| 23:39 | gtrak | yea, that's just my macro noob-ness, I think |
| 23:39 | gtrak | i think it'll work without explicitly calling destructure |
| 23:39 | gtrak | since let does it for you anyway |
| 23:41 | arrdem | got it. |
| 23:42 | arrdem | gtrak: https://www.refheap.com/paste/8312 that'll do anything that (destructure) can and therefore all destructurings that clojure supports. |
| 23:42 | gtrak | I spent like a couple days 6 months ago thinking about that |
| 23:43 | gtrak | ah, you avoided the tree parse entirely? |
| 23:43 | gtrak | the problem I solved by not doing that was avoiding the gensyms |
| 23:44 | arrdem | yerp. if you look at the source for (let) you'll find that it uses (destructure) to do all the binding vector parsing and (gensym)ing |
| 23:44 | gtrak | right, I didn't want the gensyms |
| 23:44 | gtrak | that simplifies it |
| 23:45 | gtrak | destructure is also a monster |
| 23:46 | arrdem | oh I agree. gave up halfway through reading it. |
| 23:54 | gtrak | arrdem: that's a useful macro... I've been doing something with similar intent by wrapping bindings in a def and sending them to the repl, an emacs keyboard macro |
| 23:55 | gtrak | much dirtier.. |
| 23:56 | gtrak | but I have the benefit of saving values off in vars and 'stepping' through a huge let-form |
| 23:56 | gtrak | I just wish I knew how to make it not a keyboard macro (not enough to learn how just yet) |