2014-03-03
| 00:01 | devn | heh |
| 00:05 | firefaux | how could I apply a function to every value in a map, and return the key that corresponds to the greatest value? |
| 00:05 | firefaux | I was thinking first I'd need to apply the function |
| 00:05 | bob2 | the answers sounds pretty similar to your question |
| 00:05 | firefaux | then use map-invert |
| 00:06 | firefaux | and take value of the first item |
| 00:07 | hiredman | ,(key (apply max-key (comp inc val) (seq {:a 1 :b 2}))) |
| 00:07 | clojurebot | :b |
| 00:07 | gfredericks | ,(key (apply max-key (comp inc val) {:a 1 :b 2})) |
| 00:07 | clojurebot | :b |
| 00:08 | firefaux | nice |
| 00:20 | muhoo | what's the equivalent of "this" in om? how would i get the actual underlying dom node of a component? |
| 00:21 | muhoo | oh, doh, get-node :-/ |
| 00:21 | muhoo | though, get-node doesn't get THIS node, i have to give it a hardcoded id |
| 00:23 | firefaux | if you have the component, can you get the id from that? |
| 00:23 | pyrtsa | hiredman, firefaux: Watch out for empty inputs, though. max-key doesn't allow zero arguments. :( |
| 00:24 | pyrtsa | ,(apply max-key []) |
| 00:24 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/max-key> |
| 00:24 | firefaux | good catch, pyrtsa |
| 00:24 | gfredericks | ,(max) |
| 00:24 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/max> |
| 00:25 | gfredericks | ,(<) |
| 00:25 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/<> |
| 00:25 | gfredericks | ,(-) |
| 00:25 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: core/-> |
| 00:26 | brandon | I'm looking to get into Clojure programming. I'm mostly interested in web applications, what are some really top-notch resources? Anything you wish you knew when you started? |
| 00:33 | muhoo | brandon: read the oreilly clojure programming book, it has good background on web stuff |
| 00:34 | devn | http://clojure-doc.org/, http://www.clojure-toolbox.com/, http://getclojure.org/, http://joyofclojure.com/, http://planet.clojure.in/, http://www.clojuresphere.com/ |
| 00:34 | brandon | Thanks! |
| 00:35 | brandon | I always feel a little awkward coming into these rooms to ask a single question. What's the 'normal' thing that people do in here? |
| 00:35 | devn | https://www.4clojure.com/ another one |
| 00:45 | firefaux | alight, thanks for the help everyone, I'm off to sleep |
| 01:04 | devn | aurorcoin connects you to an irc network |
| 01:04 | devn | their qt app does |
| 01:06 | seangrove | bbloom dnolen_ : https://github.com/sgrove/om-stack-panel There's a tiny repo that's easy to experiment with. I'm not sure this is 100% feasible, there are lots of problems (rendering glitches) and it's not clear how to get it to actually be performant. Lots of thought and experimentation needs to go into it I think. |
| 01:06 | seangrove | bbloom: It's small enough that you should be able to apply some of your wizardry simply enough :) |
| 01:12 | voldyman | whats the recommended way of creating a simple socket server in clojure? |
| 01:20 | technomancy | voldyman: just use java serversockets |
| 01:20 | technomancy | check out the mire project for an example |
| 01:21 | voldyman | technomancy: ok, i was looking at your fork of server-socket, whats it current state? |
| 01:22 | technomancy | it exists and works and is unlikely ever to see another commit |
| 01:22 | voldyman | :) |
| 01:36 | seangrove | bbloom: Yeah, I'm definitely doing something horribly wrong if that's supposed to be faster. The simple ScrollView component is much smoother. I think it could make a difference if each component were more expensive to render (css effects, more complicated DOM), but the difference is pretty big so far. Will have to think about how it could be improved... |
| 01:39 | effy | does anyone have an idea if this presentation https://speakerdeck.com/log0ymxm/machine-learning-fundamentals-in-clojure has been recorded in video ? "Machine Learning Fundamentals in Clojure by Paul English" |
| 01:58 | muhoo | is it evil of me that i wish get-node would just get the node of the current compoent, instead of my having to deal with refs |
| 02:03 | johann_ | muhoo: isn't that the default behavior if you dont specify a ref? could be mistaken |
| 02:04 | muhoo | oh, that'd be awesome, but the docs say it requires a ref as an arg |
| 02:04 | johann_ | (om/get-node owner) |
| 02:05 | muhoo | https://github.com/swannodette/om/wiki/Documentation |
| 02:06 | johann_ | https://github.com/swannodette/om/blob/master/src/om/core.cljs#L697 |
| 02:29 | chare | guys have you heard of quasar pulsar? |
| 02:29 | chare | http://blog.paralleluniverse.co/2013/05/02/quasar-pulsar/ |
| 02:30 | chare | I got a question about it. |
| 02:31 | chare | anyone alive? |
| 02:32 | noprompt | deadghost: thanks for the bug reports. :) |
| 02:32 | noprompt | deadghost: sorry for tripping you up. :( |
| 02:32 | deadghost | noprompt, that's for fixing them |
| 02:32 | deadghost | *thanks |
| 02:33 | noprompt | deadghost: that should do it. lemme know. |
| 02:34 | noprompt | deadghost: feel free to bug me in here after you open the issue and it won't take me an hour to get back to you. :) |
| 02:34 | seangrove | Hrm, I could definitely use a dropping buffer so I only process the last scroll event, that would be a good idea. Will try that in the morning |
| 02:34 | deadghost | will do |
| 02:34 | noprompt | deadghost: i've been bouncing between several projects today and i think my head wasn't in the right place when i pushed 0.1.7. |
| 02:35 | noprompt | been hacking a sass->garden script which monkey patches Sass::Script::* and Sass::Tree::* to emit EDN |
| 02:35 | deadghost | noprompt, are there any compass clones on garden? |
| 02:36 | deadghost | I saw one but it doesn't seem to have much activity |
| 02:36 | noprompt | deadghost: danneu started one, not sure where he's at w/ it though. :/ |
| 02:36 | deadghost | hopefully because it was written perfectly the first time |
| 02:36 | noprompt | kind of a big undertaking though. |
| 02:36 | deadghost | yes that's the one |
| 02:36 | muhoo | on a resize event, i want a component to get the .-offsetWidth of its PARENT, not itself. i have been doing this with refs. what's the more delcarative way? |
| 02:37 | noprompt | deadghost: basically what i'm trying to do is emit mostly working garden code from a sass codebase. |
| 02:37 | muhoo | and not of the window either |
| 02:37 | noprompt | deadghost: that takes care a bulk of the hand-porting. |
| 02:37 | deadghost | seems more ideal than hand porting |
| 02:38 | noprompt | deadghost: there's some difficulty around emitting calls to mixins and functions but it's not too bad. |
| 02:39 | deadghost | one of the things I wanted to do before I even touched clojure |
| 02:39 | deadghost | was write something lispy that compiled to sass |
| 02:39 | deadghost | but skipping a step is good too |
| 02:40 | noprompt | stuff like interpolation isn't bad "foo #{$bar} baz" => (str "foo " $bar " baz") |
| 02:40 | noprompt | @mixin foo (1, 2, 3) => (foo 1 2 3) |
| 02:40 | noprompt | $foo: weeble => (def $foo "weeble") |
| 02:41 | noprompt | 1px + 2px => (+ (px 1) (px 2)) |
| 02:41 | noprompt | it's just effing tedious. |
| 02:56 | chare | what exactly is the purpose of lein trampoline, whats the purpsoe of NOT using it |
| 03:04 | muhoo | is there a way for set-state! to set the state of itself, not its owner? |
| 03:04 | muhoo | i.e. setting the state of the compoent not the owner of the component |
| 03:05 | muhoo | and is set-state! valid within a did-mount, or must it only be used within a render or render-state? |
| 03:12 | muhoo | oh, that's it. Uncaught Error: No protocol method ICursor.-path defined for type boolean: false |
| 03:12 | muhoo | owner is a boolean false |
| 03:12 | muhoo | because that's my data, and om hates it. |
| 03:22 | Nyyx | how do I 'or' a list of bools |
| 03:22 | Nyyx | without reduce |
| 03:22 | paulswilliamsesq | Hi all, here goes.... Is stubbing functions considered okay in clojure, and if so, is with-redef an idiomatic way to do it? |
| 03:23 | Nyyx | something like splicing |
| 03:23 | Nyyx | oh wait nvm apply |
| 03:24 | Nyyx | nvm again "CompilerException java.lang.RuntimeException: Can't take value of a macro:" |
| 03:24 | Nyyx | I can't (apply or ...) |
| 03:26 | Nyyx | ,(apply #(or %&) '(false true false)) |
| 03:26 | clojurebot | (false true false) |
| 03:26 | Nyyx | no... |
| 03:27 | Nyyx | ,(apply #(or % %2 %3) '(false true false)) |
| 03:27 | clojurebot | true |
| 03:27 | Nyyx | :( thats what I want but not vararg |
| 03:28 | Kneiva_ | ,(every? true? (list true false true)) |
| 03:28 | clojurebot | false |
| 03:28 | Kneiva_ | ,(every? some? (list true false true)) |
| 03:28 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: some? in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 03:28 | Kneiva_ | ,(some? true? (list true false true)) |
| 03:28 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: some? in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 03:28 | Kneiva_ | ,(some true? (list true false true)) |
| 03:28 | clojurebot | true |
| 03:28 | rhg135 | ,(eval (apply #'or [true nil true nil])) |
| 03:28 | clojurebot | true |
| 03:29 | rhg135 | ,(eval (apply #'or [true nil false nil])) |
| 03:29 | clojurebot | nil |
| 03:30 | clgv | Nyyx: why not reduce? |
| 03:30 | Nyyx | Kneiva_: thanks |
| 03:30 | rhg135 | If you do that in real code I will find you :-P |
| 03:30 | Nyyx | clgv: because I was looking for a function like every? and some? that do that already |
| 03:31 | clgv | "or" is a macro and certainly shouldnt be used like the above example |
| 03:31 | rhg135 | clgv: of course not |
| 03:32 | clgv | Nyyx: ##(some identity [false false true false]) |
| 03:32 | lazybot | ⇒ true |
| 03:32 | clgv | even with short circuiting ^^ |
| 03:33 | Nyyx | ,(println "test") |
| 03:33 | clojurebot | test\n |
| 03:34 | Nyyx | ,(some identity [true (do (println "hi") false)]) |
| 03:34 | clojurebot | hi\ntrue |
| 03:34 | Nyyx | no short circuit though |
| 03:35 | chare | what do you guys think about pulsar for clojure? |
| 03:36 | clgv | Nyyx: it short circuits. your println is evaluated outside of some befor that vector is passed to some ;) |
| 03:37 | clgv | $source some |
| 03:37 | lazybot | some is http://is.gd/IAmtiP |
| 03:38 | Nyyx | doesnt do that in the or macro |
| 03:38 | Nyyx | ,(or true (do (print "hi:"))) |
| 03:38 | clojurebot | true |
| 03:44 | michaelr525 | howdy |
| 03:47 | Kneiva | hello |
| 04:12 | chare | I've decided to use clojure with pulsar |
| 04:12 | chare | and you guys can't stop me |
| 04:20 | rurumate | Hello everyone! |
| 04:20 | rurumate | Which profiles are active by default, when doing a "lein install"? |
| 04:21 | rurumate | I've noticed that the dev profile is NOT active then |
| 04:29 | noidi | rurumate, leiningen's docs state that "By default the :dev, :provided, :user, :system, and :base profiles are activated for each task" |
| 04:29 | noidi | https://github.com/technomancy/leiningen/blob/stable/doc/PROFILES.md |
| 05:10 | lvh | Hi |
| 05:11 | lvh | If I want to use an explicit random number generator or perhaps seed inputs to rand to make a function that uses random numbers referentially transparent; do I use the java interop or is there a nice clojure way of doing it |
| 05:11 | TEttinger | yes |
| 05:11 | lvh | TEttinger: There's a nice clojure way of doing it, or yes use the java interop |
| 05:11 | TEttinger | there's at least one set of seeded random number things in pure clojure |
| 05:11 | TEttinger | I have it somewhere... |
| 05:12 | TEttinger | https://github.com/kephale/clj-random |
| 05:13 | lvh | TEttinger: Thanks! |
| 05:14 | lvh | oh my me, a :cellularautomaton generator! |
| 08:28 | mishok13 | hey, i have a small question about passing JDBC PreparedStatement parameters in HoneySQL + clojure.java.jdbc combination |
| 08:28 | mishok13 | https://gist.github.com/mishok13/9324779 <-- here you can see the current smallest example |
| 08:28 | mishok13 | in a nutshell: i want to change default fetchSize for one query |
| 08:29 | mishok13 | reading clojure.java.jdbc code didn't bring any enlightment |
| 08:32 | CookedGryphon | Hey, does anybody have any clues about testing core.async with midje when your go loop throws an exception? |
| 08:32 | CookedGryphon | at the moment it's just crashing a backgrounded thing and then passing because the desired outcome is no output |
| 08:33 | CookedGryphon | but I want to output with no exceptions! |
| 08:51 | BartAdv | I was interested to learn about the internals of lein-droid plugin, thought it would be relatively easy to just start the repl in its sources, pass my project map to functions and start experimenting |
| 08:51 | BartAdv | but I don't know how to easily grab that project map |
| 08:52 | BartAdv | anyone has some experience with developing leiningen plugins? Checked github README, it just says 'you have to pass your project map' (for now I've managed to dump it using lein-pprint, but it seems awkward) |
| 08:58 | clgv | Nyyx: ,[true (do (println "hi") false)] |
| 08:59 | clgv | ,[true (do (println "hi") false)] |
| 08:59 | clojurebot | hi\n[true false] |
| 08:59 | clgv | BartAdv: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 09:00 | clgv | clojurebot: leiningen plugin |is| https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 09:00 | clojurebot | Roger. |
| 09:00 | clgv | leiningen plugin? |
| 09:00 | clgv | ~leiningen plugin |
| 09:00 | clojurebot | leiningen plugin is https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md |
| 09:00 | clgv | clojurebot: botsnack |
| 09:00 | clojurebot | thanks; that was delicious. (nom nom nom) |
| 09:01 | BartAdv | oh haha |
| 09:04 | BartAdv | but this is generally what I've read, and it looks like one should just inspect the output of lein-pprint and prepare the project map on his own |
| 09:04 | clgv | ,(apropos "forv") |
| 09:04 | clojurebot | () |
| 09:05 | clgv | damn. guess I have to write that thing some time... |
| 09:06 | clgv | $findfn [a [1 2 3], b [4 5 6] :when (even? (+ a b))] [a b] [[1 5] [2 4] [2 6] [3 5]] |
| 09:06 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: a in this context, compiling:(NO_SOURCE_PATH:0) |
| 09:13 | CookedGryphon | does anyone have any ideas how I fail a midje test on exception in a background thread |
| 09:14 | CookedGryphon | given that it's testing the fact that nothing is emitted on a core.async channel in a given situation and so I have no further output to check |
| 09:24 | clgv | CookedGryphon: cant you test the function alone that is used in the background thread? |
| 09:34 | joegallo | is the exception uncaught in the background thread? |
| 09:34 | joegallo | if so, you could consider dropping some custom code in under http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#setDefaultUncaughtExceptionHandler%28java.lang.Thread.UncaughtExceptionHandler%29 |
| 09:35 | joegallo | just be sure to get the current value first and put it back when you're done ;) |
| 09:37 | CookedGryphon | clgv: not really, the unit which I'm testing is a core.async go-loop which takes in some data and potentially outputs some other data in response - that's what I'm testing |
| 09:38 | clgv | CookedGryphon: ah right. go-loops can only consume and write stuff within the fo-block, right? |
| 09:38 | clgv | *go |
| 09:38 | CookedGryphon | yeah, I don't have a choice but to run it in the background |
| 09:39 | CookedGryphon | joegallo: could do... doesn't feel like something I should be doing in a unit test though! |
| 09:39 | joegallo | shrug |
| 09:39 | joegallo | :) |
| 09:39 | CookedGryphon | wait, that's not the issue |
| 09:39 | CookedGryphon | I've looked at this before |
| 09:40 | CookedGryphon | I think the issue is that core.async makes its own executor, I have no way to access the threads its actually using |
| 10:34 | n0n3such | AUR seems to be taking on a life of its own |
| 10:34 | n0n3such | https://www.cryptocoincharts.info/v2/coins/show/aur |
| 10:40 | mikerod | It seems that I have a rogue macro that is generating a constant that is too large. This throws the dreaded: "java.lang.ClassFormatError: Invalid method Code length <N> in class file <X>__init" message. |
| 10:40 | mikerod | However, I only get this error during AOT-compilation |
| 10:40 | mikerod | how is that possible? |
| 10:41 | mikerod | I thought in AOT and not compilation, the same byte code would still be getting generated and verfied? |
| 10:41 | mikerod | verified* |
| 10:42 | stuartsierra | AOT is weird in many ways. |
| 10:43 | mikerod | stuartsierra: I wouldn't argue with that statement :P |
| 10:43 | mikerod | This error that is only happening in AOT concerns me though, since I think it is pointing out a potential issue I have. |
| 10:43 | mikerod | I have a macro that is generating very large constants. |
| 10:44 | mikerod | Somehow, without AOT this is not revealed to me. However, it still seems like that may be a cause for concern? |
| 10:44 | stuartsierra | It's not a great idea if you can avoid it. |
| 10:44 | stuartsierra | Alternatives: Generate them once and save in an EDN file, generate at runtime, etc. |
| 10:45 | mikerod | stuartsierra: Yes, that's the general guidelines I've heard. I think that will be the approach I try to take. |
| 10:46 | mikerod | I appreciate the feedback too. |
| 10:46 | stuartsierra | You're welcome. |
| 10:51 | sdegutis | What OpenID libraries are you all using? |
| 10:52 | jarjar_prime | @sdegutis: I just use facebook connect |
| 10:52 | jarjar_prime | haven't had much success product wise when it came to openid |
| 10:53 | sdegutis | Oh. |
| 10:53 | jarjar_prime | and on iOS you can just hand a token back without having to do anything special on the server |
| 10:54 | jarjar_prime | probably going to add google+ at some point once we get android up and running |
| 10:56 | sdegutis | Ok. |
| 11:29 | wei__ | anyone use kioo successfully with om? the example code uses an outdated version of om |
| 11:44 | goldfeld | i have that kioo-riosity too, plan to use it soon |
| 11:51 | johnjelinek | hihi all :) |
| 11:51 | johnjelinek | how's it goin'? |
| 11:51 | johnjelinek | dakrone: you around? |
| 11:52 | wei__ | hi johnjelinek, fine thanks |
| 11:52 | johnjelinek | wei__: great :) |
| 11:52 | rasmusto | its a beautiful morning |
| 11:52 | johnjelinek | I'm wondering -- how should I handle "Connection Reset" exceptions with clj-http? I have {:throw_exceptions false} but this one still gets through |
| 11:52 | wei__ | looking for some example code using kioo + Om 0.5.0, if anyone happens to know |
| 11:53 | wei__ | you could try/catch it, at worst |
| 11:54 | johnjelinek | wei__: well it's wrapped in a future and the exception only pops up with I deref ... maybe I should filter/remove within the future to only get the successful HTTP requests? |
| 11:54 | johnjelinek | basically the future calls 26 HTTP requests |
| 11:54 | seangrove | dnolen_: I was a little disappointed that the binary in "All the code that's fit to printf()" doesn't seem meaningful :( |
| 11:55 | dnolen_ | seangrove: heh |
| 11:55 | seangrove | dnolen_: Still, nice touch |
| 11:56 | abaker | Alex Miller around? |
| 11:59 | johnjelinek | (try @requests (catch java.util.concurrent.ExecutionException e (.getCause e))) -- this catches the exception, but how would I get it to ignore this and get all of the requests that were successful in the future? |
| 12:00 | johnjelinek | hmm .. maybe all of my requests threw this exception |
| 12:05 | dnolen_ | seangrove: btw I played around a bit with nodyn, seems really slow - like 300X slower than V8. |
| 12:06 | seangrove | dnolen_: Probably a better idea (if it's important) to run a separate node process, communicate over some connection |
| 12:06 | bbloom | seangrove: just saw your msges about perf... bummer... how many items are you in your views currently? |
| 12:07 | seangrove | bbloom: It's the same for either view, scrollview is consistently better. I think it's from recalc'ing all the heights though, like we talked about. Generates a ton a garbage, forces the GC on, big stutters |
| 12:08 | bbloom | seangrove: hm yeah, can you test it w/ just a fixed height w/o measuring? |
| 12:08 | seangrove | bbloom: Yeah, suppose that would just take a minute or two |
| 12:14 | dnolen_ | seangrove: btw the profile is pretty informative, appears currently all the time is lost in CLJS |
| 12:14 | seangrove | dnolen_: Yeah, recalc-heights mostly |
| 12:15 | dnolen_ | seangrove: mostly mean all |
| 12:15 | dnolen_ | meaning all |
| 12:15 | seangrove | A lot of thrashing there. Need to be more clever about it |
| 12:15 | dnolen_ | no time is actually spent rendering |
| 12:16 | seangrove | dnolen_: Sure, what I was saying earlier is I wanted to limit the number of unnecessary calls into cljs to render when I know nothing has changed |
| 12:16 | dnolen_ | seangrove: how big is the generated list of things? |
| 12:16 | seangrove | dnolen_: 1 vector pair for every item in the list. Give me a bit of time and I'll get a fixed-height version going and see how the performance is on that, shouldn't need to the list of offsets for that |
| 12:17 | dnolen_ | seangrove: it should be easy to hack in a special version of om.core/set-state! that doesn't invalidate the path btw |
| 12:17 | dnolen_ | seangrove: no need to wait for me :) |
| 12:17 | dnolen_ | at least for perf testing |
| 12:17 | seangrove | dnolen_: I did, I ended up using atoms, it helped a bit |
| 12:17 | seangrove | dnolen_: Then that mutated to channels which did the calculations and used set-state! to signal a rerender necessary |
| 12:18 | seangrove | That helped more, but still I think I'm just missing something clever here. I'm fine to take some time to get it right. |
| 12:21 | dnolen_ | seangrove: there's definitely some weird logic going on |
| 12:22 | dnolen_ | seangrove: it scrolls smoothly then completely locks up |
| 12:22 | seangrove | dnolen_: Yeah, I'd emphasize experimental. That lockup is because it triggers a round of rendering |
| 12:22 | dnolen_ | for a couple of scrolls |
| 12:22 | dnolen_ | 623000+ calls to ChunkedSeq |
| 12:22 | dnolen_ | that just doesn't make any sense |
| 12:22 | seangrove | Hah |
| 12:23 | bbloom | lol whoa |
| 12:23 | dnolen_ | I suspect something minor here |
| 12:23 | dnolen_ | which will speed things up considerably |
| 12:25 | johnjelinek | can I make a future of futures |
| 12:25 | johnjelinek | ? |
| 12:25 | johnjelinek | I'd like to do (future-done? my-future) which would deref a collection of futures |
| 12:26 | seangrove | bbloom: Even being stupid with the fixed-height virtual stack panel, it's 60fps easy |
| 12:26 | bbloom | seangrove: so you're saying the slow part is your measuring code path? |
| 12:26 | seangrove | bbloom: Yeah, all the data that's being mangled keeping track of heights and offsets |
| 12:27 | johnjelinek | (future (my-running-futures)) immediately returns true |
| 12:27 | johnjelinek | any idea why? |
| 12:27 | johnjelinek | prolly because something is lazy? |
| 12:29 | abaker | are there any library best practices documented anywhere? I'm putting together clj-sparql, a library for dealing with SPARQL endpoints (see https://github.com/AlBaker/clj-sparql ) |
| 12:30 | abaker | interested in if, say passing in a 'db-spec' style map to the query function is appropriate, or are there better ways to make the function more composable for end users |
| 12:30 | johnjelinek | I am trying (doall @my-futures-collection) |
| 12:30 | johnjelinek | and returning a future |
| 12:32 | seangrove | bbloom dnolen_ Pushed the fixed-height stack panel with windowing, performs how you'd expect. For the variable-height, need to be more clever about keeping track of item positions (height + offset) |
| 12:33 | pyrtsa | johnjelinek: How about... (future (doall (map deref my-futures))) ? |
| 12:34 | pyrtsa | It isn't optimal, since it's creating a new thread for just waiting for the futures to complete, but with the available interface (and not using e.g. core.async), you can't get much better. |
| 12:35 | johnjelinek | pyrtsa: I'll give that a shot |
| 12:41 | johnjelinek | pyrtsa: lol, wrapping my (future (doalls in (future (doalls reminds me of callback hell |
| 12:41 | johnjelinek | maybe I'm not thinking about this the right way? |
| 12:41 | pyrtsa | It's worse than callback hell. It's a spawn-thread-and-wait hell. |
| 12:42 | johnjelinek | lol -- maybe I should just be using core.async? |
| 12:43 | pyrtsa | The problem is: java.util.concurrent.Future (which clojure.core/future models) doesn't provide a callback mechanism. |
| 12:43 | pyrtsa | Yeah, core.async. Or RxJava if you're into that thing. |
| 12:43 | johnjelinek | I see |
| 12:43 | johnjelinek | lol, I've been trying to avoid core.async -- but now it feels like I may have no choice |
| 12:45 | pyrtsa | johnjelinek: This might be of interest as well, but beware, it's pretty new: https://github.com/Netflix/RxJava/tree/master/language-adaptors/rxjava-clojure |
| 12:46 | johnjelinek | I think I'll go core.async |
| 12:47 | pyrtsa | That's a good choice. |
| 13:16 | danneu | deadghost: once I started iterating on my Compass->Garden port in production, I ended up splitting it into two libs: CSS helpers and a build tool. |
| 13:16 | dbasch | I'm having a problem using openid with cemerick/friend. Whenever I try to access a protected resource without being logged in I get redirected to a blank /login page |
| 13:43 | sdegutis | Is there a built-in tagged literal to create strings from symbols? |
| 13:43 | sdegutis | Where #w[foo bar baz] would return ["foo" "bar" "baz"] |
| 13:44 | hyPiRion | It's called (mapv str '[foo bar baz]), I guess. |
| 13:44 | hyPiRion | but no, not built in. |
| 13:44 | sdegutis | Ah. I think it would be more terse as #w, so it may be worth writing a third party lib for it. |
| 13:44 | sdegutis | Especially if Clojure wants to compete with Ruby, which has this built-in. |
| 13:47 | llasram | Ruby also has Perl-inspired magical global variables tied to the regular expression engine |
| 13:47 | llasram | Do not want |
| 13:47 | sdegutis | Agreed, that feature is bogus. |
| 13:47 | johnjelinek | strange ... I did async/close! my-chan and it crashed LT |
| 13:47 | sdegutis | Oh. |
| 13:54 | TimMc | gfredericks: OK, it looks like gen-class definitely requires writing out to disk -- and then reading back from disk again. :-( |
| 13:55 | bbloom | sdegutis: llasram: that feature is *great* in perl if you're writing 3 line scripts.... but it's friggin useless in ruby b/c ruby's top-level is all kinds or weirdly broken / different than than method and class bodies |
| 13:55 | jcromartie | bbloom: I thought you said "that feature is in great peril" |
| 13:56 | bbloom | it's clear to me ruby started out as "i want a better perl" and later became "oh, smalltalk is cool" :-) |
| 13:56 | sdegutis | jcromartie: :D |
| 13:56 | llasram | If only Matz had added system images |
| 13:57 | sdegutis | bbloom: Matz himself said: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/179642 |
| 13:57 | technomancy | somehow they claim scheme got added into the mix, but I'm pretty sure that's just about "why not use question marks for predicates; those look nice" |
| 13:58 | amalloy | sdegutis: #w[x y z] is not very much terser than (w x y z). exact same number of characters, i think? |
| 13:58 | bbloom | sdegutis: there you go :-P |
| 13:58 | sdegutis | amalloy: ah but is it as clear? |
| 13:59 | amalloy | uh...yes? w is a macro, easily looked up in a namespace with M-. or whatever non-emacs equivalent; #w is in data_readers.clj, which you have to go digging around for |
| 13:59 | technomancy | well, it feels like a reader concern to me |
| 13:59 | sdegutis | amalloy: True. Although isn't data_readers.clj only looked up in the current project? |
| 13:59 | sdegutis | amalloy: If so, it wouldn't be much digging, you just open the root-level file named data_readers.clj |
| 13:59 | technomancy | I don't think it's useful enough to justify the #w shortness, but I agree the former is clearer |
| 14:00 | amalloy | sdegutis: the fact that that's even a question makes it likely that it's harder to justify. the way it's looked up is not as widely-known as namespaced things |
| 14:00 | sdegutis | technomancy: It may not be in a general project, but in one where the focus is on configuration (a la Chef) it could be very useful. |
| 14:00 | llasram | sdegutis: the implementation finds and loads all top-level data_readers.clj files on the classpath |
| 14:00 | technomancy | amalloy: M-. not working on reader literals is dumb too =) |
| 14:00 | sdegutis | amalloy: touché good sir |
| 14:00 | sdegutis | llasram: Ahh. |
| 14:01 | technomancy | also: aliases for reader literals should be able to be specified in the ns macro =P |
| 14:01 | technomancy | so you could use #w in one namespace without stomping others |
| 14:01 | amalloy | technomancy: that'd be just one more thing making it hard to read clojure code without running it, for eg analyzers |
| 14:01 | technomancy | namespaces are cool, mkay? |
| 14:02 | llasram | And non-namespaced literals are implicitly in the namespace rhickey.decided.this.was.cool |
| 14:02 | technomancy | llasram: it's very un-egalitarian |
| 14:02 | technomancy | much like the fact that you can't use namespaced :my.stuff/clauses in ns; that's super annoying |
| 14:03 | sdegutis | I'd love to see a Chef written in Clojure, although that day will undoubtedly never happen, which is a shame because Clojure is the Ruby that Ruby was meant to be. |
| 14:03 | llasram | technomancy: On these points I cannot disagree |
| 14:03 | ToBeReplaced | sdegutis: pallet? |
| 14:04 | locks | sdegutis: it is? |
| 14:04 | sdegutis | ToBeReplaced: whoa |
| 14:04 | sdegutis | locks: yessir |
| 14:05 | locks | but they're almost opposites :P |
| 14:05 | sdegutis | locks: It's dynamic, terse, written for extensibility and expressiveness, and ideal for sane and maintainable DSLs. |
| 14:05 | sdegutis | locks: yessir |
| 14:05 | sdegutis | ToBeReplaced: totally investigating. |
| 14:06 | ToBeReplaced | sdegutis: gl, i eval'd it with chef and ansible a little over a year go and it was a little rough around the edges at the time -> i imagine it's come a long way |
| 14:06 | sdegutis | ToBeReplaced: thanks |
| 14:12 | dbasch | I'm trying to write a webapp with compojure, and failing at what should be extremely basic: I want the user to identify with openid, and then I want to restrict resources only to identified users. I thought Friend was the answer, but I can't get it to work properly. Does anyone have examples of how to do this? |
| 14:14 | sdegutis | dbasch: I have been using openid4java but am looking into JOpenID. |
| 14:14 | sdegutis | I could not get Friend to work, but I think I'm not the target audience, which explains that. |
| 14:14 | dbasch | sdegutis: the openID part works, what doesn't work is restricting routes to logged in users |
| 14:15 | dbasch | I cloned this example, but it doesn't have any protected urls: friend-demo.herokuapp.com/openid/ |
| 14:15 | jcromartie | man, when it comes to application configuration, when did we forget about environment variables? |
| 14:17 | dbasch | what I want to do (but I don't know how) is wrap all my restricted handlers with something that checks for authentication, and redirects a user to the login page if not |
| 14:17 | sdegutis | dbasch: you'd have to wrap your route handler code in some kind of function that checks the current user's permissions |
| 14:17 | sdegutis | We do this with a macro that I've been trying to turn into a function for a year now with no luck. |
| 14:18 | dbasch | sdegutis: friend/authenticate supposedly does this, but it doesn't work properly |
| 14:18 | dbasch | or at least I can't get it to work |
| 14:19 | jcromartie | dbasch: what's the challenge here? we do it |
| 14:19 | jcromartie | so long as all your restricted routes are in one place |
| 14:19 | sdegutis | Ah it should have been named "Mellon". |
| 14:19 | jcromartie | otherwise it's a bit piecemeal |
| 14:19 | dbasch | jcromartie: when I try to access a restricted resource, I get redirected to a blank login page instead of my login form |
| 14:20 | dbasch | jcromartie: I |
| 14:20 | dbasch | jcromartie: I'm using essentially this code: https://github.com/cemerick/friend-demo/blob/master/src/clj/cemerick/friend_demo/openid.clj |
| 14:21 | dbasch | the only difference is that I set allow-anon? to false for the group of restricted routes |
| 14:23 | dbasch | if I try to go to mysite/restricted without being logged in, I get redirected to mysite/login which is a blank page. I have no idea how to fix it |
| 14:34 | jcromartie | don't you need to specify mysite/login ? |
| 14:34 | sdegutis | Looks like Pallet does all that we need. |
| 14:34 | sdegutis | Only lacking in docs, but the source is open. |
| 14:35 | jcromartie | dbasch: I mean do you have anything to render /login ? |
| 14:37 | dbasch | jcromartie: if I render login, then after the openid login I get redirected to my login page with a url that looks like http://localhost:8080/login?openid.ns=http%3A%2F%2Fspe...... |
| 14:38 | dbasch | jcromartie: and debugging login shows that authentication doesn't happen |
| 14:39 | jcromartie | sorry, I don't really know much about the friend/openid stuff |
| 14:39 | dbasch | jcromartie: this is what login looks like: |
| 14:39 | dbasch | (GET "/login" req |
| 14:39 | dbasch | (if-let [auth (friend/current-authentication req)] |
| 14:39 | dbasch | (a/home req auth) |
| 14:39 | dbasch | (do (println "not authenticated" req) (c/home req))))) |
| 14:40 | dbasch | jcromartie: thanks, I |
| 14:40 | amalloy | dbasch: www.refheap.com |
| 14:41 | dbasch | amalloy: sorry about that https://www.refheap.com/51256 |
| 14:42 | dbasch | I'm at the end of my rope, pulling my hair out in frustration |
| 14:42 | dbasch | cannot believe it's so hard to do something that in Sinatra would take me 5 minutes |
| 14:43 | seangrove | dbasch: There's a reasonable chance you're using the wrong tool. Friend is a big system, not something you would typically use in sinatra. |
| 14:43 | seangrove | I think it's more akin to Devise |
| 14:44 | sdegutis | Yeah we have something similar: (GET "/some/page" req ,,, (with-authorized-user req (do-some-stuff))) |
| 14:44 | dbasch | seangrove: so what's the right/easier way to wrap routes so that they do one thing if you're authenticated and something else if you're not? |
| 14:44 | sdegutis | I could de-macroize it by just putting (fn [] (do-some-stuff)) instead, but I go back and forth on that. |
| 14:45 | seangrove | dbasch: We use middleware. Wrap routes you care in with it, it checks for an api-key in the query-params or a token in the session, passes through if we can find the appropriate user, otherwise 401 or redirects |
| 14:45 | sdegutis | seangrove: Ahhh, I like that solution better I think. |
| 14:45 | dbasch | yeah, I like the with-authorized-user approach |
| 14:46 | AeroNotix | any tools that given a regex pattern would generate a string which satisfies that regex? |
| 14:46 | sdegutis | seangrove: My only gripe is that you have to separate priv routes from non-priv routes even if they're conceptually related (user-routesa, etc). |
| 14:46 | seangrove | sdegutis: I suppose that could be true. I'd have to think about |
| 14:47 | dbasch | sdegutis: right, I was hoping that you could just wrap all the routes you care about with something like friend/authenticate |
| 14:47 | sdegutis | Although they could still live in the same file, just two different (defroutes ...) |
| 14:47 | dbasch | in my case, I just don't want to accidentally leave a route unprotected |
| 14:48 | sdegutis | seangrove: also, last time I tried something similar, I accidentally made it so that in the list of routes, after the first one that required authentication, *every* next route also required authentication. |
| 14:48 | sdegutis | Not sure how to avoid that in the future, that was a gross bug. |
| 14:48 | dbasch | conceptually wrapping routes in friend/authenticate is the right thing, except I can't get it to work |
| 14:48 | seangrove | sdegutis: Yeah, it's possible. But we explicitely separate our authenticated routes and unauthenticated routes to addresss dbasch's concern. |
| 14:49 | sdegutis | Right. |
| 14:49 | seangrove | dbasch: So just write your own authenticate method, it's simple |
| 14:49 | sdegutis | Thanks for the ideas yahl. |
| 14:49 | dbasch | seangrove: how? |
| 14:49 | seangrove | sdegutis: Then we namespace the url so that we only authenticate /api/*, or whatever it might be |
| 14:49 | clojurebot | Huh? |
| 14:49 | sdegutis | seangrove: Ah. |
| 14:50 | dbasch | seangrove: I spent too much time trying to write my own method and couldn't get it to work |
| 14:51 | seangrove | dbasch: https://www.refheap.com/2776651fdf9297bcb0a77a050 Add your checks there (presumably you're storing some token id in the session, or have a param in your url) |
| 14:52 | dbasch | seangrove: I'll give it a try, thanks |
| 14:53 | seangrove | dbasch: Then wrap the authenticated routes you care about and specify a prefix https://www.refheap.com/7a62e3170452398ee2502d656 |
| 14:53 | seangrove | That way you're explicit in your code about what needs authentication and what doesn't. It also helps you structure your urls so that they can be versioned/upgraded in a sane way |
| 14:54 | dbasch | seangrove: for an api, sure. This is a simple webapp |
| 14:54 | sdegutis | Same here. |
| 14:55 | seangrove | dbasch: What's the difference? |
| 14:55 | seangrove | They both follow the same principles |
| 14:56 | dbasch | seangrove: I find it a bit strange to define routes in one place, and to have to explicitly specify the prefixes that require authentication in another |
| 14:57 | seangrove | dbasch: With that code, if you omit the prefixes, everything needs to be authed |
| 14:57 | seangrove | If not, it's just a one line change |
| 14:58 | seangrove | And if that's the case, then just wrap the routes you've defed and want authed |
| 15:03 | jchauncey | so ive asked in the leiningen chan and didnt get an answer but has anyone written a active middleware for a core leiningen task? |
| 15:05 | llasram | jchauncey: I'm not really sure what that question means... |
| 15:05 | jchauncey | im trying to write a middleware for the uberjar task |
| 15:05 | gtrak | jchauncey: my understanding is that middleware is only for the project map, not tasks, you'd have to make a new task or use a hook maybe? |
| 15:05 | llasram | Leiningen middleware doesn't apply to a task. It's just code which gets a chance to modify the map |
| 15:06 | llasram | what gtrak said |
| 15:06 | jchauncey | and doing uberjar.plugin/middleware dosnt seem to get picked up |
| 15:06 | jchauncey | thats fine |
| 15:06 | jchauncey | i just need to override a value in the project map when a task is called |
| 15:06 | jchauncey | it works if i explicitly set :middleware in the project.clj |
| 15:06 | gtrak | can you override it for all tasks? |
| 15:06 | jchauncey | but you can have it actively find all middleware if it conforms to a standard |
| 15:07 | jchauncey | thats what it does if you use :middleware in project.clj |
| 15:07 | jchauncey | i would rather not do that |
| 15:07 | jchauncey | instead only override for a specific task/plugin (uberjar |
| 15:07 | jchauncey | )* |
| 15:07 | gtrak | maybe there's a dynamic var somewhere that holds the current task |
| 15:07 | llasram | That sounds like maybe you want a hook |
| 15:07 | jchauncey | llasram: yeah maybe |
| 15:07 | llasram | But if not -- are you just trying to get automatic middleware? |
| 15:07 | jchauncey | could use preprend to run what i need before the uberjar function is called |
| 15:07 | llasram | Sure |
| 15:08 | jchauncey | llasram: yup |
| 15:08 | gtrak | yea, you want a hook |
| 15:08 | llasram | I've definitely done it before. Do you have a link to your project? |
| 15:08 | jchauncey | llasram: nope =\ |
| 15:08 | jchauncey | Like hooks, middleware will be applied automatically for plugins if you put it in plugin-name.plugin/middleware. <(------------------- from the plugins.md |
| 15:08 | llasram | Yes |
| 15:09 | jchauncey | hrm |
| 15:09 | llasram | So if you have a plugin named `my-plugin` which you include in the plugins vector (as `my-plugin`), then that var-function will get invoked automatically as middleware |
| 15:09 | jchauncey | i basically want my teams to include my plugin and get this for free |
| 15:10 | jchauncey | no need to explicitly set :middleware or :hooks |
| 15:10 | jchauncey | yes |
| 15:10 | gtrak | your plugin can provide a middleware that alters the hooks |
| 15:10 | jchauncey | but how does that work if i want middleware for a core task |
| 15:10 | llasram | Dude, you are thinking about it all wrong |
| 15:10 | llasram | Human, rather |
| 15:10 | llasram | Let's not be sexist |
| 15:10 | jchauncey | hehe |
| 15:10 | jchauncey | isA man |
| 15:10 | llasram | Middleware is task-irrelevant. |
| 15:11 | jchauncey | correct |
| 15:11 | llasram | The namespace for your plugin needs to match the name of your *plugin* |
| 15:12 | llasram | Naming `uberjar.plugin` is completely broken |
| 15:12 | llasram | You need to have a `my-plugin.plugin/middleware` var-function |
| 15:12 | llasram | Where "my-plugin" is whatever you've named your plugin |
| 15:12 | gtrak | your plugin can provide a 'project' middleware that alters the hooks, which then hook into uberjar. |
| 15:13 | llasram | gtrak: Um, or just use Leiningen's default hook auto-activation method :-) |
| 15:13 | gtrak | oh :-) |
| 15:13 | jchauncey | yeah |
| 15:13 | gtrak | middlewares can do anything :-) |
| 15:14 | gtrak | ah, I was thinking of this: 'Hooks can also be loaded manually by setting the :hooks key' |
| 15:16 | llasram | jchauncey: Here's an example of a plugin which includes an automatic hook on the `uberjar` task (as well as automatic middleware): https://github.com/timmc/lein-otf/blob/master/src/lein_otf/plugin.clj#L26 |
| 15:16 | jchauncey | thanks |
| 15:16 | jchauncey | i think a hook is what i want |
| 15:18 | llasram | OOC, what's the end-goal you're trying to achieve? |
| 15:21 | jchauncey | ive build a series of plugins for bumping versions based on SEMVER that will be used by our CI system |
| 15:21 | jchauncey | er built rahter |
| 15:22 | TimMc | Anyone know of an alternative to gen-class and proxy that will allow me to extend an abstract class and get a real Class out of it? (And doesn't involve AOT.) |
| 15:22 | gtrak | what's wrong with those two? |
| 15:23 | jchauncey | that version is used when an uberjar is built and our middleware reads that version from a VERSION file. I want to insure that the file is created before uberjar is executed but only for that task |
| 15:24 | llasram | TimMc: Write a tiny stub class in Java :-D |
| 15:25 | llasram | TimMc: Or use ASM to generate a class in-memory which you then load via Clojure's DynamicClassLoader |
| 15:26 | TimMc | D-: |
| 15:27 | llasram | The former is obvious more sane |
| 15:27 | TimMc | gtrak: proxy doesn't give you a real Class; gen-class involves barfing stuff out to disk. |
| 15:28 | llasram | TimMc: What are you trying to do at a higher level? |
| 15:30 | TimMc | llasram: Write a Zuul filter loader. |
| 15:31 | llasram | Is the class found via reflection? |
| 15:31 | sdegutis | What will Clojure be in 15 years? |
| 15:31 | TimMc | Netflix Zuul will allow you to dynamically load filters, but it gives you a source blob read from disk (and the path name it foudn it at) and expects you to give back a Class that extends ZuulFilter, an abstract class. |
| 15:31 | sdegutis | What will be different about it? |
| 15:31 | TimMc | It's great for Groovy, not as much for Clojure. |
| 15:31 | xuser | sdegutis: it will be dead |
| 15:31 | llasram | Oh, so then it needs to construct instances of the class itself? |
| 15:32 | sdegutis | I hope it'll start faster :) |
| 15:32 | TimMc | llasram: Yeah. :-/ |
| 15:32 | sdegutis | xuser: oh? |
| 15:32 | xuser | sdegutis: maybe with Java 9? |
| 15:32 | llasram | TimMc: I know you're not a fan, but sounds like it could be a case for the Java stub classes, unless you need to generate multiple of theses classes w/ different behavior |
| 15:33 | llasram | TimMc: Then I think you really actually might have a use for ASM :-D |
| 15:33 | TimMc | Multiple, different behavior, not known in advance. :-/ |
| 15:33 | xuser | llasram: is ASM the lib that generates java bytecode in the clojure compiler? |
| 15:34 | llasram | It is, although it's not necessarily a good idea to use it. It's not exposed as a public API, and they e.g. are bumping the version of it from 3 to 4 between 1.5 and 1.6 |
| 15:34 | llasram | TimMc: Not necessarily a great example, but https://github.com/llasram/esfj/blob/master/src/clojure/esfj/provider.clj#L46 |
| 15:35 | TimMc | llasram: Do you know if Clojure's lack of an "extend this class" utility is ideological or technical? |
| 15:36 | llasram | TimMc: I'd guess a combination of both, but more ideology |
| 15:36 | llasram | But really have no special insight |
| 15:37 | llasram | TimMc: FYI, ASM includes the "ASMifier" http://asm.ow2.org/asm40/javadoc/user/org/objectweb/asm/util/ASMifier.html |
| 15:38 | llasram | You run it on a Java class file, and it spits out the ASM (Java) API calls necessary to generate that class file |
| 15:38 | TimMc | Neat. |
| 15:40 | fro_ | ,(-> {:a 0 "b" 4} (:a)) |
| 15:40 | clojurebot | 0 |
| 15:40 | llasram | I think this approach will get a lot more sane once clojure.tools.jvm is "finished" |
| 15:40 | fro_ | ,(-> {:a 0 "b" 4} ("b")) |
| 15:40 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn> |
| 15:40 | fro_ | ,(-> {:a 0 "b" 4} (:b)) |
| 15:40 | clojurebot | nil |
| 15:40 | fro_ | lol |
| 15:40 | llasram | I mean, check out that code-as-data: https://github.com/clojure/tools.emitter.jvm/blob/master/src/main/clojure/clojure/tools/emitter/jvm/emit.clj |
| 15:40 | fro_ | check it, guys ) |
| 15:40 | fro_ | funny |
| 15:41 | fro_ | but |
| 15:41 | fro_ | ,({:a 0 "b" 4} "b") |
| 15:41 | clojurebot | 4 |
| 15:41 | llasram | (inc Bronsa) |
| 15:41 | lazybot | ⇒ 18 |
| 15:42 | fro_ | there is a problem with macros ->? |
| 15:42 | llasram | fro_: What there is unexpected? |
| 15:43 | fro_ | ,({:a 0 "b" 4} "b") |
| 15:43 | clojurebot | 4 |
| 15:43 | llasram | Yes? |
| 15:43 | fro_ | ,(-> {:a 0 "b" 4} ("b")) |
| 15:43 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn> |
| 15:43 | rasmusto | ,(-> {:a 0 "b" 4} (get "b")) |
| 15:43 | clojurebot | 4 |
| 15:43 | fro_ | ok |
| 15:43 | llasram | ,(macroexpand `(-> {:a 0 "b" 4} ("b")) |
| 15:43 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 15:43 | llasram | ,(macroexpand `(-> {:a 0 "b" 4} ("b"))) |
| 15:43 | clojurebot | ("b" {"b" 4, :a 0}) |
| 15:44 | rasmusto | ,(macroexpand `(-> {:a 0 "b" 4} (get "b"))) |
| 15:44 | clojurebot | (clojure.core/get {"b" 4, :a 0} "b") |
| 15:44 | llasram | fro_: ^^ all clear? |
| 15:44 | fro_ | ,(macroexpand `(--> {:a 0 "b" 4} ("b"))) |
| 15:44 | clojurebot | (sandbox/--> {"b" 4, :a 0} ("b")) |
| 15:44 | fro_ | ,(macroexpand `(->> {:a 0 "b" 4} ("b"))) |
| 15:44 | clojurebot | ("b" {"b" 4, :a 0}) |
| 15:45 | fro_ | yea |
| 15:45 | fro_ | clear |
| 15:45 | fro_ | thx |
| 15:49 | sdegutis | ,("b" {"b" 4}) |
| 15:49 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to clojure.lang.IFn> |
| 15:50 | sdegutis | ,('b {'b 4}) |
| 15:50 | clojurebot | 4 |
| 15:50 | sdegutis | ,(:b {:b 4}) |
| 15:50 | clojurebot | 4 |
| 15:50 | sdegutis | Oh. |
| 15:50 | ordnungswidrig | sdegutis: symbol and keyword implement ifn |
| 15:50 | sdegutis | ,(4 {4 :b}) |
| 15:50 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IFn> |
| 15:50 | sdegutis | ,({} {}) |
| 15:50 | clojurebot | nil |
| 15:50 | sdegutis | :D |
| 15:51 | rasmusto | ,({} {{} 'foo}) |
| 15:51 | clojurebot | nil |
| 15:51 | rasmusto | ,({{} 'foo} {}) |
| 15:51 | clojurebot | foo |
| 15:51 | sdegutis | :D |
| 15:51 | sdegutis | I'd never have guessed that one. |
| 15:51 | ordnungswidrig | ,({} {}) ;; <= clojure emoticons |
| 15:51 | clojurebot | nil |
| 15:51 | sdegutis | ,(() ()) |
| 15:51 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentList$EmptyList cannot be cast to clojure.lang.IFn> |
| 15:51 | ordnungswidrig | ,({:o :o}) |
| 15:51 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (0) passed to: PersistentArrayMap> |
| 15:51 | rasmusto | ,:D |
| 15:51 | clojurebot | :D |
| 15:51 | ordnungswidrig | ,'({:o :o}) |
| 15:51 | clojurebot | ({:o :o}) |
| 15:52 | sdegutis | Hold on now, let me remember.. |
| 15:52 | sdegutis | ,(= () '()) |
| 15:52 | clojurebot | true |
| 15:52 | sdegutis | Yes, that's a hipster. |
| 15:53 | sdegutis | He's wearing steampunk pilot goggles. |
| 16:08 | jowag | ,(:•_:•) |
| 16:08 | clojurebot | #<IllegalArgumentException java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :?_:?> |
| 16:11 | TimMc | ,'😰 |
| 16:11 | clojurebot | ?? |
| 16:13 | sdegutis | :D |
| 16:45 | asthasr | Good afternoon! |
| 16:45 | asthasr | And/or evening, as the case may be. |
| 16:45 | rasmusto | goodaften |
| 16:46 | asthasr | I'm writing a clojure program that will be reading a large file and processing it in various ways. Unfortunately, I'm getting an error on one of my preconditions, and I'd like to be able to see the line of the file that's causing the error. How can I accomplish this? |
| 16:48 | sdegutis | The exception should have a stacktrace I think. |
| 16:48 | rasmusto | asthasr: you're talking about finding the line in the large file? |
| 16:48 | asthasr | Sure, there's a stacktrace, but it doesn't include the data, just the location where it occurred (the :pre condition) |
| 16:48 | asthasr | Yes, rasmusto. I want to see what input is causing the precondition to fail |
| 16:49 | asthasr | but when I try to do printlns before the fact, they never seem to be output |
| 16:49 | rasmusto | hrm, yeah I think those functions get messed with |
| 16:50 | AeroNotix | https://github.com/AeroNotix/lapse reiddraper |
| 16:52 | rasmusto | asthasr: erm, you can do a {:pre (do (prn "blah") (assert something))} |
| 16:53 | justin_smith | asthasr: or maybe even {:pre [(and datum (f datum))]} |
| 16:53 | justin_smith | that should show datum when it fails |
| 16:53 | rasmusto | well, what if datum is nil? |
| 16:54 | reiddraper | AeroNotix: oh neat |
| 16:54 | rasmusto | I assume nil would be bad, but I don't know the context much |
| 16:54 | justin_smith | (and [x] (f x)) |
| 16:54 | rasmusto | ah, that'd do it :) |
| 16:55 | justin_smith | nope, that does not work because it prints the literal test that failed |
| 16:55 | rasmusto | ,((fn [x] {:pre [(and [x] (odd? x))]} x) 2) |
| 16:55 | clojurebot | #<AssertionError java.lang.AssertionError: Assert failed: (and [x] (odd? x))> |
| 16:55 | rasmusto | ah, darn |
| 16:55 | justin_smith | but it does not show the value it failed on |
| 16:55 | rasmusto | ,((fn [x] {:pre [(do (prn x) (odd? x))]} x) 2) |
| 16:55 | clojurebot | 2\n#<AssertionError java.lang.AssertionError: Assert failed: (do (prn x) (odd? x))> |
| 16:55 | justin_smith | better, but gives us unneeded printouts |
| 16:56 | justin_smith | ((fn [x] {:pre [(or (odd? x) (prn x))]} x) 2) |
| 16:56 | justin_smith | only prints when it fails :) |
| 16:56 | justin_smith | ,((fn [x] {:pre [(or (odd? x) (prn x))]} x) 1) |
| 16:56 | clojurebot | 1 |
| 16:56 | justin_smith | ,((fn [x] {:pre [(or (odd? x) (prn x))]} x) 2) |
| 16:56 | clojurebot | 2\n#<AssertionError java.lang.AssertionError: Assert failed: (or (odd? x) (prn x))> |
| 16:56 | rasmusto | ,((fn [x] {:pre [(if (odd? x) (do (prn x)))]} x) 2) |
| 16:56 | clojurebot | #<AssertionError java.lang.AssertionError: Assert failed: (if (odd? x) (do (prn x)))> |
| 16:57 | AeroNotix | reiddraper: I sent a PR on github for check, not sure if it's the right place. |
| 16:57 | justin_smith | prn returns nil, so the do is not needed |
| 16:57 | rasmusto | gotcha. or seems like it'd work well |
| 16:58 | justin_smith | has the right semantics at least |
| 16:58 | justin_smith | though could be opaque to other users of the code |
| 16:58 | rasmusto | yeah, name is a bit inconvenient |
| 16:58 | justin_smith | I use or / and for optional chaining so it comes naturally to me, but I am aware that's just something that makes me weird |
| 16:59 | asthasr | it doesn't seem to work for me |
| 16:59 | asthasr | let me show code |
| 16:59 | asthasr | {:pre [(or (every? (comp (partial = Name) type) original-names) (prn original-names))]} |
| 16:59 | asthasr | and in the repl |
| 16:59 | asthasr | (file->records (first data-files)) |
| 16:59 | asthasr | AssertionError Assert failed: (or (every? (comp (partial = Name) type) original-names) (prn original-names)) |
| 17:00 | asthasr | no actual output |
| 17:00 | mikerod | asthasr: sounds like you'd need to hav a bit more fine-grained error checking |
| 17:01 | mikerod | putting it all in the pre-condition isn't likely to get you a lot of useful context |
| 17:01 | justin_smith | if that failed, I think it should have printed |
| 17:01 | justin_smith | yeah, a series of assert statements is probably better here, agreed |
| 17:02 | `cbp | If anyone finds this useful: https://www.refheap.com/51314 |
| 17:03 | `cbp | They're a bunch of functions to send sexps to the cider repl which i stole from someone that had them in nrepl and i ported them |
| 17:03 | `cbp | ..to cider |
| 17:04 | RickInAtlanta | `cbp thx |
| 17:05 | `cbp | :) |
| 17:09 | asthasr | Thanks guys. I think I'm going to have to rework some of my processing logic to make asserts at more points... |
| 17:09 | asthasr | (I'm kind of a lisp noob, this is the first real project I've tried in clojure and it's kind of... awkward... so far) |
| 17:09 | TimMc | llasram: OK, I can get gen-class namespaces to compile to disk, and then load the classes. But I think that will be a bad way to handle things in production. (I'm not sure I'll have write access to the filesystem, or even *should*.) |
| 17:10 | ordnungswidrig | I want to init my app for dev from ns user, is there anything better than (var-get (ns-resolve 'my.namespace 'some-function)) to lazily resolve at runtime? |
| 17:11 | justin_smith | asthasr: another thing that helps is making more / smaller functions, making sure each one does exactly one thing, and testing their behavior individually |
| 17:11 | ordnungswidrig | repl startup will fail if anything in user refers to a broken something in another ns |
| 17:12 | justin_smith | ordnungswidrig: that's why it's helpful to have repl start out with an ns that isn't in your codebase (like user normally would be) |
| 17:12 | mikerod | asthasr: stick with it, it gets better |
| 17:13 | ordnungswidrig | yes, but I want to have some convenience functions in user to start the system |
| 17:13 | justin_smith | don't |
| 17:13 | justin_smith | put them in util, or something else |
| 17:13 | justin_smith | leave user empty |
| 17:14 | justin_smith | sorry, don't mean to sound bossy |
| 17:14 | ordnungswidrig | come on! is best practive nowadays :) |
| 17:15 | ordnungswidrig | s/v/c |
| 17:15 | technomancy | the user namespace is really not a great place to dump convenience stuff |
| 17:15 | technomancy | because it just goes away when you switch namespaces |
| 17:15 | technomancy | you need commands exposed in your client IMO |
| 17:15 | justin_smith | yeah, for that very "repl failing to start" reason for starters |
| 17:16 | sdegutis | I didn't know the user ns was so transient. |
| 17:16 | technomancy | also putting one in a library is super sketchy |
| 17:16 | sdegutis | Doesn't REPLy do that? |
| 17:16 | ordnungswidrig | "exposed in your client"? |
| 17:16 | sdegutis | In that case I think it's helpful. |
| 17:16 | technomancy | sdegutis: I think it intercepts some forms to give the illusion of having them exist in all namespaces |
| 17:17 | sdegutis | Ah interesting. |
| 17:17 | technomancy | which is neat, but I don't like how it makes them look like function calls |
| 17:17 | technomancy | slime does this better; it accepts commands like ,do-somethin |
| 17:17 | sdegutis | Yeah, they should be custom tagged readers. |
| 17:17 | technomancy | =P |
| 17:17 | sdegutis | #doc interpose |
| 17:17 | sdegutis | No srsly. |
| 17:17 | sdegutis | #examples cond-> |
| 17:17 | technomancy | no |
| 17:18 | technomancy | it shouldn't look like a value |
| 17:18 | sdegutis | But it's so terse! |
| 17:18 | technomancy | it should be something that's invalid clojure syntax |
| 17:18 | technomancy | it's so simple! |
| 17:18 | technomancy | and powerful! |
| 17:18 | sdegutis | xD |
| 17:18 | sdegutis | Invalid Clojure syntax? No such thing. |
| 17:19 | sdegutis | Invalid Clojure semantics, sure. But nearly everything is valid Clojure syntax. |
| 17:19 | justin_smith | ::::sdegutis: |
| 17:19 | justin_smith | ,::::sdegutis: |
| 17:19 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: ::::sdegutis:> |
| 17:19 | justin_smith | that's invalid clojure syntax |
| 17:19 | sdegutis | ,new Exception() |
| 17:19 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: new in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 17:19 | technomancy | ,~ohai |
| 17:19 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ohai in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 17:19 | justin_smith | for example |
| 17:19 | sdegutis | justin_smith: ah |
| 17:19 | ordnungswidrig | ,(keyword "::::sdegutis:) |
| 17:19 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading string> |
| 17:20 | ordnungswidrig | ,(keyword "::::sdegutis:") |
| 17:20 | clojurebot | :::::sdegutis: |
| 17:20 | sdegutis | Hey guys |
| 17:20 | justin_smith | right, the object can exist, but that read syntax is invalid |
| 17:20 | sdegutis | Look over there ------> |
| 17:20 | asthasr | ,(:::::sdegutis) |
| 17:20 | clojurebot | #<RuntimeException java.lang.RuntimeException: Invalid token: :::::sdegutis> |
| 17:20 | technomancy | whoa, batman |
| 17:22 | ordnungswidrig | so, in which way is ns user special? |
| 17:23 | sdegutis | ,(do (in-ns 'user) (def foo 3) ,,, (in-ns 'somethingelse) ,,, (in-ns 'user) foo) |
| 17:23 | clojurebot | 3 |
| 17:23 | sdegutis | Dunno. |
| 17:23 | ordnungswidrig | so |
| 17:24 | justin_smith | it is special because repls start up in it |
| 17:24 | ordnungswidrig | ok |
| 17:24 | justin_smith | so if it is broken the repl can't start |
| 17:24 | ordnungswidrig | "because it just goes away when you switch namespaces" |
| 17:24 | technomancy | it's also loaded at startup |
| 17:24 | ordnungswidrig | technomancy: says |
| 17:25 | justin_smith | I *think* what technomancy meant by that is that the advantage of putting things in user disappears when your switch namespaces |
| 17:25 | justin_smith | and it is easy to switch namespaces |
| 17:25 | ordnungswidrig | I see |
| 17:25 | technomancy | ordnungswidrig: (use 'clojure.pprint) ; great, now you have it. for a while, then it's gone when you in-ns |
| 17:25 | justin_smith | so why not put the stuff you want in a different one |
| 17:25 | technomancy | vs M-x cider-pprint or whatever |
| 17:25 | technomancy | which will always be with you |
| 17:25 | technomancy | till death do you part, &c |
| 17:25 | ordnungswidrig | so I better use core! |
| 17:25 | ordnungswidrig | *g* |
| 17:25 | technomancy | super tempting! |
| 17:25 | ordnungswidrig | reader macro ftw? |
| 17:26 | technomancy | no, use elisp |
| 17:26 | rasmusto | eclipse? |
| 17:26 | sdegutis | lol |
| 17:26 | rasmusto | sorry |
| 17:26 | asthasr | I think I sounded a bit too pejorative when I said it was awkward above. I should rephrase. :) I like the lisp approach, it *feels* good, but I haven't yet learned to think in lisp. I need to improve my problem decomposition |
| 17:27 | justin_smith | as I mentioned :) |
| 17:27 | ordnungswidrig | M-x (cider-eval-sync "1") => no repl connection |
| 17:27 | justin_smith | sorry, that sounds smug. I mean yeah, breaking things into smaller parts will bring happiness. |
| 17:27 | reiddraper | AeroNotix: i'm afraid clojure contrib repos can't take pull-requests |
| 17:27 | technomancy | also increase your sex appeal |
| 17:28 | ordnungswidrig | oh, my repl died |
| 17:28 | johnjelinek | ordnungswidrig: don't feel bad, my repl just died too (LT) |
| 17:28 | goldfeld | have you guys seen vinyasa from zcaudate? |
| 17:29 | goldfeld | it's pretty cool for injecting stuff you want right into core for dev purposes |
| 17:31 | PinkPrincess | So I'm having some issues with core.async (which I have no prior experience with). I've created a pastebin if anyone can be talked into helping me. :) |
| 17:31 | PinkPrincess | It's here: http://pastebin.com/EmfuMGzP |
| 17:31 | PinkPrincess | Essentially I'm trying to distribute downloading a lot of web pages (~14000) using channels. |
| 17:32 | PinkPrincess | But I'm struggling with everything either being lazy (and returning immediately, never realizing anything) or being very eager (and blocking the main thread). |
| 17:32 | bob2 | have you read http://martintrojer.github.io/clojure/2013/07/07/coreasync-and-blocking-io/ ? |
| 17:32 | PinkPrincess | I'd like to have some progress displayed during the rather long download process. |
| 17:33 | PinkPrincess | Nope. I'll go read that. |
| 17:35 | PinkPrincess | That does seem a lot simpler than what I'm getting into. |
| 17:37 | PinkPrincess | Is there an easy way to control the go block thread pool size? |
| 17:38 | bob2 | http://stackoverflow.com/questions/18779296/clojure-core-async-any-way-to-control-number-of-threads-in-that-go-thread |
| 17:38 | bob2 | but the point of the above is to avoid just spamming one thread per io-bound thing |
| 17:39 | johnjelinek | dnolen_: you around? |
| 17:40 | PinkPrincess | Thanks, bob2. |
| 17:42 | creese | api question: should you marshal first, or validate first? I'm undecided. |
| 17:43 | AeroNotix | creese: validate what? |
| 17:43 | creese | AeroNotix: the data coming in |
| 17:43 | AeroNotix | creese: what is the data, presumably JSON? |
| 17:44 | creese | AeroNotix: example: you have a date field, you want to be sure it's an actual date and not something else |
| 17:44 | creese | AeroNotix: assume JSON |
| 17:44 | AeroNotix | creese: use closchema |
| 17:44 | AeroNotix | creese: https://github.com/bigmlcom/closchema |
| 17:44 | AeroNotix | !next |
| 17:45 | amalloy | closchema sounds like some kind of medical condition |
| 17:45 | AeroNotix | It's just a JSON schema validator |
| 17:46 | AeroNotix | write your schema -> validate instances of it |
| 17:46 | AeroNotix | -> delete idiotic code you were writing yourself |
| 17:46 | AeroNotix | creese: if it's JSON you seriously should not be rolling your own validators outside of special cased fields |
| 17:46 | creese | AeroNotix: too late |
| 17:46 | AeroNotix | creese: delete the code->use closchema |
| 17:47 | dsrx | 'closchema' reminds me of 'cloact' |
| 17:47 | creese | AeroNotix: does it marshal too? |
| 17:48 | AeroNotix | creese: why would it? Use ring-json middleware for that |
| 17:49 | AeroNotix | creese: were you manually decoding the json on each request? |
| 17:49 | AeroNotix | technomancy: I'm having great success with that project |
| 17:49 | technomancy | had another team use it for a big API and said it was a great fit |
| 17:50 | AeroNotix | it really i |
| 17:50 | AeroNotix | is |
| 17:50 | tolitius | is there a way to create lein template that takes options? for example, here is that template I did for one of my presentations: https://github.com/tolitius/cccp but I also would like to do something in the lines of: "lein new cccp -with.cljs.repl [app name]", where it will also create austin based cljs repl hooks (e.g. https://github.com/tolitius/wracer/blob/master/test/wracer/brepl.clj and others)? thank you. |
| 17:50 | AeroNotix | I just added a feature where you can override certain keys with your own validators |
| 17:50 | sdegutis | technomancy: have you seen that new thing on HN? |
| 17:50 | technomancy | AeroNotix: are you using it with erlang? |
| 17:50 | technomancy | sdegutis: hm? |
| 17:50 | sdegutis | technomancy: the new Q lang, kinda related to json-schema |
| 17:50 | AeroNotix | technomancy: We use Jesse but Jesse doesn't do references, we're working on adding it. |
| 17:50 | technomancy | AeroNotix: sweet |
| 17:50 | sdegutis | technomancy: https://news.ycombinator.com/item?id=7333354 |
| 17:50 | sdegutis | technomancy: also http://www.q-lang.io/ |
| 17:51 | AeroNotix | technomancy: in fact I might tackle jesse references this week |
| 17:53 | asthasr | Are there any really good books that go into the practical aspects of designing a system using lisp? |
| 17:53 | creese | AeroNotix: the project in Python, I just come here for inspiration |
| 17:53 | technomancy | the edn fans on this thread; my goodness |
| 17:53 | asthasr | I'm thinking of, by way of comparison, "Domain Driven Design" on the OO side (although I never liked DDD) |
| 17:53 | AeroNotix | creese: https://pypi.python.org/pypi/jsonschema |
| 17:53 | technomancy | I can't help but get the "stop trying to make 'fetch' happen. it's not gonna happen" feeling |
| 17:54 | AeroNotix | creese: always use a validator! There's no reason not to. |
| 17:54 | AeroNotix | technomancy: which thread? |
| 17:54 | technomancy | AeroNotix: the one sdegutis linked to |
| 17:54 | AeroNotix | ah |
| 17:54 | sdegutis | technomancy: that's cuz EDN is the best format ever |
| 17:55 | sdegutis | It was almost HTML but ended up not being HTML. |
| 17:55 | creese | AeroNotix: can you execute arbitrary functions? |
| 17:55 | bja | I feel like I can write a portable EDN/schema validator for Python/Ruby as well as I could write a Q validator/serializer for python/ruby |
| 17:56 | AeroNotix | creese: As validators? In the python one I have no idea |
| 17:57 | technomancy | Even if edn is technically superior in ways that actually matter for real life, I'm too jaded to believe anything will replace json's penetration level in the next decade or two. |
| 17:57 | AeroNotix | Worse is better |
| 17:58 | technomancy | if you ever find yourself complaining about json, just be thankful there was a massive backlash against xml |
| 17:58 | technomancy | because it could be a lot worse |
| 17:58 | Wild_Cat | yeah, at least JSON isn't XML :p |
| 17:58 | asthasr | sadly, in some contexts, I think XML was better :( |
| 17:59 | hiredman | Things: they could be worse. |
| 17:59 | Wild_Cat | XML is better for marked-up text documents. |
| 17:59 | technomancy | hiredman: always the optimist |
| 17:59 | Wild_Cat | which isn't surprising in and of itself. What is is that the enterprise people decided it should be used everywhere and for everything. |
| 17:59 | technomancy | "my phone went into an infinite reboot loop when I attempted to upgrade the OS, but at least it didn't catch on fire or boot into windows or anything" |
| 18:00 | sdegutis | technomancy: xaml is awesome |
| 18:01 | technomancy | sdegutis: is it simple while at the same time being powerful? |
| 18:01 | sdegutis | *whilst |
| 18:01 | technomancy | oh snap |
| 18:01 | sdegutis | but otherwise yes, exactly |
| 18:03 | johnjelinek | I'm exploring core.async, and I'm getting some state machine exceptions, here is my defn: (defn query-api [uri] (let [out (chan) req (http/get uri)] (put! out @req) out)) |
| 18:03 | johnjelinek | (it's using http-kit) |
| 18:04 | johnjelinek | I thought I could test it with this: (go (while true (let [[_ results] (<! (query-api "http://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=cat"))] (println results)))) |
| 18:04 | johnjelinek | but this doesn't seem to be the case -- what's the best way to test this defn? |
| 18:04 | sdegutis | But seriously, maybe XML is a pain to parse and process.. but as an end-user I haven't had a lot of problems reading/writing it as long as I have syntax-highlighting. |
| 18:04 | sdegutis | (end-user in the programmer sense) |
| 18:04 | sdegutis | (wait, that doesn't disambiguate it at all...) |
| 18:05 | sdegutis | Gonna so investigate Pallet soon. |
| 18:05 | sdegutis | Clojure's version of Chef? Heck yeah! |
| 18:06 | amalloy | johnjelinek: put! is blocking (and thus so is query-api). i don't think core.async will be happy at all with you making a call to a blocking function inside of your go |
| 18:07 | johnjelinek | amalloy: should I use >! instead? |
| 18:09 | johnjelinek | (doc put!), |
| 18:09 | clojurebot | Cool story bro. |
| 18:09 | johnjelinek | lol |
| 18:09 | johnjelinek | (doc clojure.core.async/put!), |
| 18:09 | clojurebot | It's greek to me. |
| 18:09 | johnjelinek | hrm |
| 18:09 | johnjelinek | amalloy: docs say put! is async |
| 18:09 | johnjelinek | so it shouldn't block right? |
| 18:11 | amalloy | oh, right. i guess put! is the...non-blocking primitive on which >! is built? i don't really understand put! |
| 18:12 | tolitius | I think put! is used outside of the go block while >! is used only within |
| 18:12 | johnjelinek | tolitius: that's correct |
| 18:13 | amalloy | incidentally, johnjelinek, query-api could be better (imo) written as: (doto (chan) (put! @(http/get uri))) |
| 18:13 | johnjelinek | amalloy: ok, but then how would I pass the channel around? |
| 18:13 | amalloy | the let/munge/return pattern is easily replaced with doto, in general |
| 18:13 | amalloy | johnjelinek: i'm saying my definition is exactly equivalent to yours |
| 18:14 | johnjelinek | ok |
| 18:14 | amalloy | (doto x (f y)) macroexpands to (let [foo x] (f foo y) foo) |
| 18:15 | johnjelinek | ok, and so now how would I read from this channel? |
| 18:16 | johnjelinek | (go (while true (<! (query-api "http...")))) ? |
| 18:16 | johnjelinek | note: I'm in REPL |
| 18:18 | tolitius | @johnjelinek, was not completely following of what you are doing, but usually you _return_ a channel from a functions that produces there, and then using another function (component) you read from it |
| 18:19 | johnjelinek | tolitius: right -- so query-api returns the channel, and now I'm trying to build a processor for the channel |
| 18:20 | johnjelinek | like this? (let [c (query-api (query-api "http://urlquery"))] (go (while true (println (<! c))))) |
| 18:20 | tolitius | johnjelinek: then yes, you can do (go (while true …)) if that is what is required, or you you can compose thise q-api with other channels and alt! on them |
| 18:22 | tolitius | johnjelinek: probably more like (fun [c] (go (while true …))), and then pass (query-api ..) to it. all depends on the "whole grand design" |
| 18:22 | johnjelinek | tolitius: well, right I'm just trying to understand core.async |
| 18:22 | tolitius | johnjelinek: e.g. in case with just (fun [c] ..) you can potentially reuse this processing for other channels as well |
| 18:23 | tolitius | here is an example I did with putting HTTP requests responses into a channel, and then "racing" who is faster using "alt!": https://github.com/tolitius/wracer/blob/master/src/wracer/cljs/wracer.cljs#L15 |
| 18:25 | johnjelinek | I'm unfamiliar with alt! |
| 18:26 | tolitius | johnjelinek: I think you are correct in the way you understand it. in simple terms => [producer]: 1. Create a channel (or take is an argument) 2. Produce there within a go block 3. Return a channel. [consumer] => a function that takes a channel and (go takes) from it. |
| 18:26 | justin_smith | I still like how randomly excited people are when they talk about certain side-effecting functions |
| 18:26 | danielszmulewicz | dnolen_: ping |
| 18:27 | tolitius | johnjelinek: "alt!" is like socket selector (e.g. non blocking IO). in short: takes a vector of channels as its input, and returns the first value that was return form one of these channels |
| 18:29 | johnjelinek | tolitius: ahh, that's cool :) |
| 18:29 | johnjelinek | tolitius: so, what I'm trying to do is execute ~36000 HTTP requests in async and then aggregate the responses together (or retry if it gets 401/403/Connection Error exception) |
| 18:30 | johnjelinek | should I use multiple channels for this or just 1? |
| 18:30 | tolitius | johnjelinek: the usual example is modeling a timeout for something. you create a timeout channel (timeout t), and you have your own channel (let's say "c"), that you only want to wait for some time, and then you give these two channels "c" and "t" to "alt!", and "alt!" will return whatever is "first": e.g. if the "t" comes back first, then your "request" timed out. |
| 18:33 | johnjelinek | tolitius: well, in my scenario, I want to aggregate all of the responses, so in the end, I should have a seq of 36000 responses |
| 18:33 | tolitius | johnjelinek: 36000, what's the magic behind the number? :) One thing to remember (at least the way Go people look at it) is channels are "inproc", and IO is outside of your process. you can certainly use multiple channels to "partition" these 36000 requests, but I would think that you'd be mostly IO bound and not CPU, hence a single channel might do as well as several |
| 18:34 | johnjelinek | tolitius: because I have 36000 queries to make to a WebAPI |
| 18:34 | johnjelinek | different querystring for the same URL |
| 18:35 | amalloy | i think there's an rfc saying if you make more than 10000 simultaneous requests on the same server, the sysadmin is allowed to murder you |
| 18:36 | johnjelinek | amalloy: lol |
| 18:37 | johnjelinek | well, it's hitting a load balancer that then sends it off to a server that can take my request |
| 18:37 | johnjelinek | so it's a distributed 36000 ;) |
| 18:38 | tolitius | johnjelinek: I would first try with a single channel, but of course in case you'd like to experiment, you can have multiple channels doing these requests, in which case, you could use something like fan-in (just an example: https://github.com/clojure/core.async/blob/master/examples/ex-alts.clj#L3) to collect all the responses into a single channel (e.g. simple map/reduce) |
| 18:40 | tolitius | johnjelinek: or you can use a built in merge: https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async.clj#L931 |
| 18:41 | johnjelinek | noted :) |
| 18:43 | danielszmulewicz | Anyone knows how to use ReactCSSTransitionGroup from om? |
| 18:45 | seangrove | danielszmulewicz: Could be a bit tough, I don't think there's an extern file for it |
| 18:45 | danielszmulewicz | I would like to use CSS transitions when rendering an Om component. |
| 18:46 | danielszmulewicz | seangrove: I saw this coming up in a discussion about Reagent. They seem to have a solution: https://groups.google.com/forum/#!topic/clojure/qt4uhpFqAnc |
| 18:47 | danielszmulewicz | seangrove: Maybe I should open an issue on Om's github? |
| 18:47 | sakekasi | hi guys, I'm currently working on a project that uses ring and liberator to serve from a database. For some reason, the compiler seems to be calling one of my functions and caching the result, causing the values outputted to http to never change until a server restart. |
| 18:47 | sakekasi | here is a gist with my code: https://gist.github.com/sakekasi/9337146 |
| 18:47 | sakekasi | any ideas as to what could cause something like this? |
| 18:47 | johnjelinek | tolitius: so I'm kind of getting it to read. This prints: (let [responses (atom nil)] (go (dotimes [_ 10] (let [query (query-api "http://query")] (println (<! query))))) responses) |
| 18:48 | johnjelinek | but what I want is to send it to my atom and return the atom in the end |
| 18:48 | johnjelinek | so I tried (reset! responses (conj responses (<! query))) |
| 18:48 | johnjelinek | but that did not work |
| 18:48 | seangrove | danielszmulewicz: I wouldn't mind having access to it, certainly |
| 18:49 | seangrove | I haven't looked at how they work at all, so I don't know the challenges |
| 18:49 | danielszmulewicz | seangrove: Some discussion here: https://github.com/swannodette/om/issues/59 |
| 18:49 | amalloy | johnjelinek: (reset! x (conj x ...)) can never work, because nothing sequential is also resettable. you must mean something like (swap! responses conj ...) |
| 18:50 | johnjelinek | amalloy: yes, sorry -- but swap! doesn't work either, returns an empty atom |
| 18:50 | tolitius | johnjelinek: why atom, why not just return a channel? |
| 18:51 | johnjelinek | you mean return a channel for my consumer? |
| 18:52 | johnjelinek | I'm trying to aggregate all of the http responses -- so why would it be good to return a channel rather than the aggregate? |
| 18:54 | tolitius | johnjelinek: just something I would do :) you would decouple producing vs. consuming, otherwise why bother with channels at all, you can do it in (future ..) |
| 18:54 | johnjelinek | lol, I tried just with future previously, but I spun up too many threads |
| 18:54 | johnjelinek | and ran out of memory |
| 18:54 | johnjelinek | that's when core.async was recommended to me |
| 18:55 | hiredman | ugh |
| 18:55 | hiredman | why any one would recommend core.aync for an io task I don't know |
| 18:55 | tolitius | johnjelinek: you can limit your threads: https://github.com/tolitius/lasync |
| 18:55 | hiredman | using an executor with a fixed size threadpool |
| 18:56 | johnjelinek | tolitius: but yes, I would like it be decouple producing and consuming |
| 18:56 | johnjelinek | oy, another library :| |
| 18:56 | johnjelinek | thanks though |
| 18:57 | hiredman | johnjelinek: I doubt you need it |
| 18:57 | hiredman | http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#newFixedThreadPool%28int%29 |
| 18:58 | tolitius | johnjelinek: it's a micro library though.. just plugging in a different queue to the thread pool executor |
| 18:58 | tolitius | hiredman: it is different |
| 18:58 | hiredman | tolitius: I understand, I doubt he needs the difference |
| 18:58 | tolitius | johnjelinek: but yea, in case you would like to decouple, I would return a channel |
| 18:59 | johnjelinek | tolitius: https://www.refheap.com/51352 so you're saying the consumer should also return a channel? |
| 18:59 | johnjelinek | at what point am I building my aggregate? |
| 18:59 | tolitius | hiredman: with "lasync", johnjelinek could create number of tasks, and just through all 36000 requests to them without pool returning "false".. |
| 18:59 | seangrove | hiredman: Even for making http calls? Seems like core.async is an alright match for coordinating the order of things |
| 19:01 | dnolen_ | johnjelinek: what's up? |
| 19:02 | hiredman | tolitius: I doubt he ran out of memory from just having all the tasks around, most likely it was due to having all the results in memory, so if you limit the threadpool, he should be fine |
| 19:02 | johnjelinek | dnolen_: I was following your CS101 blogpost and was wondering how you would do the equivalent of forever reading from a channel in the repl from pure functions like you showed with CLJS |
| 19:03 | dnolen_ | johnjelinek: I don't see how it would be any different, go loops won't block the repl |
| 19:03 | sakekasi_ | hi guys, I'm currently working on a project that uses ring and liberator to serve from a database. For some reason, the compiler seems to be calling one of my functions and caching the result, causing the values outputted to http to never change until a server restart. here is a gist with my code: https://gist.github.com/sakekasi/9337146 . any ideas as to what could cause something like this? |
| 19:04 | tolitius | johnjelinek: I would have the producer produce within a go block and return a channel. as to a consumer, I would probably have a consumer that would take a vector of channels and merge their values into another channel (that would have all your 36000 responses). then I would have a function that would take this one channel and "do with these responses" as you wish. |
| 19:04 | johnjelinek | dnolen_: I see .. I'll keep playing with it ... what I was trying kept freezing LT |
| 19:04 | dsrx | hmmmm |
| 19:04 | dsrx | trying to imagine a use-case for putting core.async channels onto a core.async channel |
| 19:04 | danielszmulewicz | dnolen_: https://github.com/swannodette/om/issues/129# |
| 19:05 | dsrx | 'higher order channels' if you will |
| 19:05 | johnjelinek | tolitius: well, in the example I linked to, it's just 1 channel |
| 19:05 | dnolen_ | danielszmulewicz: I closed that it's just #59 |
| 19:05 | danielszmulewicz | dnolen_: I would love to help. |
| 19:05 | dnolen_ | danielszmulewicz: it's not an Om thing |
| 19:05 | hiredman | unless you are very careful, you are going to break things when mixing core.aync and io |
| 19:05 | dnolen_ | danielszmulewicz: even #59 is not an Om thing |
| 19:05 | danielszmulewicz | dnolen_: Fine. But what can I do to use CSS transitions? |
| 19:06 | tolitius | johnjelinek: but it does not have to be. my "grand design" :) still holds, a consumer takes a vector, in this case a vector of one |
| 19:06 | johnjelinek | hrmm ... ok, I'll keep playing with it then :) |
| 19:06 | johnjelinek | thanks! |
| 19:06 | johnjelinek | g2g |
| 19:07 | hiredman | you effectively need another threadpool any way for io, because either you are using blocking io and it doesn't belong on core.asyncs pool, or you are doing non-blocking, which everthing except the bottom most layer of comes with a threadpool |
| 19:07 | dnolen_ | danielszmulewicz: https://github.com/swannodette/react-cljs |
| 19:07 | dnolen_ | danielszmulewicz: use React Add Ons, add externs |
| 19:09 | dnolen_ | danielszmulewicz: https://github.com/swannodette/react-cljs/issues/1 |
| 19:09 | danielszmulewicz | dnolen_: Ah, OK. I haven't worked with externs yet. I will investigate. Thank you. |
| 19:09 | dnolen_ | danielszmulewicz: pull requests definitely welcome for this |
| 19:10 | hiredman | very likely derefing the http response whatever "async" http library you have is, in fact, blocking on io to some degree, so you cannot do that on a core.async "thread" |
| 19:10 | dnolen_ | danielszmulewicz: the reason I've been dragging my feet with the add ons is that someone has take the time to do the externs |
| 19:10 | dnolen_ | danielszmulewicz: packaging them up is not sufficient for ClojureScript use |
| 19:10 | danielszmulewicz | dnolen_: I understand. I'll gladly do it if I can wrap my head around it. |
| 19:11 | seangrove | danielszmulewicz: It's quite some work. |
| 19:11 | danielszmulewicz | seangrove: Is this documented somewhere? |
| 19:11 | seangrove | https://code.google.com/p/closure-compiler/wiki/FAQ#How_do_I_write_an_externs_file? |
| 19:12 | danielszmulewicz | seangrove: Thanks. |
| 19:12 | seangrove | danielszmulewicz: Depending on what level of detail you want, it's easier. It can be automated if you drop the type info |
| 19:13 | danielszmulewicz | Would this help? https://gist.github.com/Chouser/5796967 |
| 19:16 | sakekasi | hi guys, I'm currently working on a project that uses ring and liberator to serve from a database. For some reason, the compiler seems to be calling one of my functions and caching the result, causing the values outputted to http to never change until a server restart. here is a gist with my code: https://gist.github.com/sakekasi/9337146 . any ideas as to what could cause something like this? |
| 19:17 | danielszmulewicz | seangrove: What does it take to automate this (without the type info)? |
| 19:17 | tolitius | danielszmulewicz: http://www.dotkam.com/2013/07/15/clojurescript-use-any-javascript-library/ (if that helps) |
| 19:17 | danielszmulewicz | tolitius: thanks. |
| 19:18 | estebanrules | Of course this depends on the indvidual, but how easy of a "jump" would it be from Scheme to Clojure? |
| 19:20 | sakekasi | estebanrules: scheme and clojure share a lot of general semantics. The jump should be pretty easy given a reasonable knowledge of the underlying java |
| 19:20 | sakekasi | estebanrules: clojure likes to give errors that are rather cryptic unless the underlying java is understood. |
| 19:22 | estebanrules | the underlying java is going to be my largest barrier I fear. I haven't coded anything in Java in over 10 years. |
| 19:23 | bbloom | estebanrules: it's not that big a deal. it only really shows itself in stack traces, but it's usually pretty easy to bisect your way to your bug. if you are used to a repl, you'll encounter you bugs faster, so you'll know it was likely something you just touched |
| 19:23 | gfredericks | TimMc: that's a bit surprising |
| 19:23 | bbloom | beyond that, you shouldn't have any problem coming from scheme. i recommend reading the stuff on the clojure.org site: rationale, the overview docs, cheatsheet, etc |
| 19:24 | estebanrules | Oh |
| 19:25 | bbloom | estebanrules: follow some folks on 4clojure.com & do the puzzles. that's the good way to learn the stdlib and idioms in a hurry |
| 19:25 | estebanrules | Thanks. Oh yes I intend to read all of the documentation. |
| 19:27 | estebanrules | bbloom: Yes I was looking at 4clojure. I was also checking out Clojure for The Brave and True. Concerning books, is there one title in particular you would recommend? There are a bunch of titles out there. |
| 19:27 | bbloom | ~books |
| 19:27 | clojurebot | books is book |
| 19:27 | bbloom | ~book |
| 19:27 | clojurebot | book is http://www.pragprog.com/titles/shcloj/programming-clojure |
| 19:27 | justin_smith | clojure programming / emerick carper & grand is good |
| 19:29 | estebanrules | Thank you. |
| 19:31 | sakekasi | any idea as to why clojure would cache the result of a function rather than call it? |
| 19:32 | tolitius | sakekasi: memoize ? |
| 19:32 | isaacbw | memoization |
| 19:32 | dnolen_ | sakekasi: doesn't sound likely, gist? |
| 19:32 | sakekasi | https://gist.github.com/sakekasi/9337146 |
| 19:32 | sakekasi | its a ring project that uses liberator |
| 19:32 | sakekasi | get-latest-links and get-latest link are called while the server is starting up |
| 19:33 | sakekasi | for some reason, these are the returned values, even when I post to the db. |
| 19:33 | sakekasi | it takes a server restart to get the functions called again and for the values to change |
| 19:33 | dnolen_ | sakekasi: sounds like a bug in the libraries your are using - not Clojure per se. |
| 19:33 | sakekasi | huh, so liberator? |
| 19:34 | dnolen_ | sakekasi: not necessarily |
| 19:34 | sakekasi | I could see that |
| 19:34 | sakekasi | does clojure.java.jdbc cache for some reason? |
| 19:35 | justin_smith | should the :exists? things have lambdas rather than forms? with lambdas they would get called later, with the current version they would just return a truthy object or nil at definition time I think |
| 19:35 | justin_smith | which would explain the npe |
| 19:35 | justin_smith | I think you are missing # or (fn [] ...) wrapping |
| 19:36 | justin_smith | *rather than random predicate forms |
| 19:36 | sakekasi | that makes sense |
| 19:36 | sakekasi | just found this article |
| 19:36 | sakekasi | http://stackoverflow.com/questions/3161986/compojure-clojure-contrib-sql-select-query-is-being-cached-why |
| 19:36 | sakekasi | that suggests that I didn't do fn[] wrapping in my defroutes |
| 19:37 | justin_smith | sakekasi: ok, reader deeper: you need to redefine your non-nil function |
| 19:38 | justin_smith | it should expect a function as a second argument |
| 19:38 | justin_smith | (and call it) |
| 19:38 | justin_smith | and then you should wrap the call to non-nil in a lambda |
| 19:38 | sakekasi | The way I defined non-nil, I wanted my function to be evaluated on call. |
| 19:38 | justin_smith | either #() or (fn []) whichever you prefer |
| 19:39 | justin_smith | the args are evaluated before being passed in... |
| 19:39 | justin_smith | OK non-nil may be OK, but the thing calling it should be a function called at run time |
| 19:39 | justin_smith | so again about wrapping as a lambda |
| 19:40 | seangrove | danielszmulewicz: I'll take a stab at it all later this week/this weekend. Seems like they're open to having an "advanced mode test run" in their build suite. |
| 19:40 | danielszmulewicz | seangrove: Awesome. Let me know if I can help. |
| 19:41 | seangrove | I image a lot of head-banging and gnashing-of-teeth for awhile |
| 19:41 | danielszmulewicz | seangrove: :-) |
| 19:41 | dsrx | speaking of which... |
| 19:42 | dsrx | the clojure contributors page suggests sending an email to the mailing list before working on an open ticket, if I'd like to contribute to clojurescript should I direct an email like that to the clojure ML or the clojurescript one? |
| 19:42 | dnolen_ | dsrx: or ask here or in #clojurescript |
| 19:42 | dsrx | ah okay |
| 19:45 | sakekasi | justin_smith: can you give me a line#/resource name? |
| 19:46 | justin_smith | basically do a search for :exists? |
| 19:46 | justin_smith | each one has an expression that is evaluated at compile time |
| 19:47 | justin_smith | and should probably be a function evaluated each time existence is checked |
| 19:47 | sakekasi | ok |
| 19:48 | sakekasi | ahh i get it. these are all being evaluated at compile time |
| 19:48 | justin_smith | http://yogthos.net/blog/30-Making+services+with+Liberator notice in this example, exists takes a funciton as argument |
| 19:48 | justin_smith | not an arbitrary expression |
| 19:48 | justin_smith | yeah - and if it returns nil, then liberator tries to call nil at runtime as a function |
| 19:48 | justin_smith | so boom, npe |
| 19:48 | justin_smith | which you see in your stacktrace |
| 19:50 | seangrove | dnolen_: I think the one issue we have using `:optimizations none` on a ring/clojurescript project is that it creates so many files, ring chokes trying to server them all. I've seen the same thing serving a clojurescript project from `python -M SimpleHTTPSever` Do you not run into that in your dev workflow at all? |
| 19:50 | dnolen_ | seangrove: I find it strange that Ring or SimpleHTTPServer could not handle serving some files |
| 19:51 | seangrove | dnolen_: As do I. |
| 19:51 | seangrove | dnolen_: But perhaps it's PEBKAC, so checking if you run into it at all |
| 19:51 | justin_smith | how many files are we talking about here? tens? hundreds? millions? |
| 19:51 | seangrove | justin_smith: few hundred all at once |
| 19:52 | seangrove | For python, it just drops the files every now and then. For ring it serves them, but takes an awful amount of time |
| 19:52 | dnolen_ | seangrove: huh your CLJS project results in hundreds of files? I take it you're not allowing the serve to let the browser serve from cache? |
| 19:53 | dnolen_ | s/serve/server |
| 19:53 | seangrove | dnolen_: The hundreds of files are for cljs files, source maps, js files, and then all of the actual html content like images/markup |
| 19:54 | seangrove | dnolen_: Anyway, not willing to state this as a categorical problem yet, just asking if others are running into ti |
| 19:54 | seangrove | After developing with mies-om for Omchaya and seeing what it's like, I definitely want that where possible |
| 19:55 | dnolen_ | seangrove: just doesn't sound like a real issue if you configure your server a bit. This is what etags are for no? https://github.com/mikejs/ring-etag-middleware |
| 19:55 | isaacbw | is there an out-of-box way to pretty print json? |
| 19:56 | dnolen_ | isaacbw: data.json supports pretty printing |
| 19:56 | noprompt_ | isaacbw: there's a plugin for chrome called JsonView which is nice. |
| 19:56 | sakekasi | awesome! I ended up getting my project to work. thanks for all the help! |
| 19:56 | bja | python -m json.tool file.json |
| 19:56 | justin_smith | sakekasi: glad to hear it |
| 19:56 | isaacbw | dnolen_: I found pprint, but it doesn't do newlines afaict |
| 19:57 | dnolen_ | isaacbw: what do you mean doesn't do newlines? |
| 19:57 | noprompt_ | brew install jsonpp |
| 19:57 | noprompt_ | there's about dozen ways to do it. |
| 19:57 | isaacbw | dnolen_: as in, it doesn't go so far as to split the json up on multiple lines, which is what qualifies as "pretty" imo |
| 19:57 | gfredericks | I like jq |
| 19:57 | bja | cheshire can do it if you're okay with a library |
| 19:57 | dnolen_ | isaacbw: pretty sure that it does |
| 19:57 | isaacbw | hmm |
| 19:57 | gfredericks | isaacbw: did you give it small input that fits comfortably on a line? |
| 19:58 | bja | (generate-string {:foo "bar" :baz {:eggplant [1 2 3]}} {:pretty true}) |
| 19:58 | stkim1 | I have a question. Say I have a lib such as hiccup. How do I navigate list of functions like javadoc? |
| 19:58 | gfredericks | clojure.repl/dir |
| 19:59 | gfredericks | combined with clojure.repl/{doc,find-doc} |
| 19:59 | justin_smith | bja: but that's edn, not json |
| 19:59 | gfredericks | justin_smith: what? |
| 19:59 | gfredericks | he's talking about cheshire |
| 19:59 | justin_smith | ahh, never mind, I missed that it was generate-string |
| 19:59 | stkim1 | gfredericks, thank you! |
| 19:59 | isaacbw | gfredericks: oh, there we go! |
| 19:59 | isaacbw | cool, thanks |
| 20:00 | gfredericks | ,(= 1 (apply str "0." (repeat \9))) |
| 20:00 | clojurebot | #<OutOfMemoryError java.lang.OutOfMemoryError: Java heap space> |
| 20:04 | amalloy | gfredericks: that's pretty cute |
| 20:04 | amalloy | maybe it would have returned true eventually, given enough digits |
| 20:05 | amalloy | we'll just never know |
| 20:06 | isaacbw | ,(println "Hello") |
| 20:06 | clojurebot | Hello\n |
| 20:06 | isaacbw | :O |
| 20:09 | gfredericks | ,(println "Hello\\n") |
| 20:09 | clojurebot | Hello\n\n |
| 20:10 | zachmassia | Is doall needed when the seq is being passed to an update-in call? https://gist.github.com/ZachMassia/470a57e5e7a0169667c9 |
| 20:11 | gfredericks | ,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 1.0) |
| 20:11 | clojurebot | (() (() ((())) () ()) (() () () ()) () () ...) |
| 20:11 | gfredericks | zachmassia: without it the new value in the map will be an unrealized lazy seq |
| 20:12 | seangrove | :wq |
| 20:12 | amalloy | zachmassia: doall is quite rarely needed |
| 20:12 | gfredericks | zachmassia: but that's probably fine here, as amalloy says |
| 20:12 | amalloy | a doall would only be needed here if the update functions in your entities perform time-sensitive side effects |
| 20:14 | gfredericks | ,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 0.8) |
| 20:14 | clojurebot | () |
| 20:14 | gfredericks | ,((fn f [x] (->> (repeatedly rand) (take-while #(< % x)) (map f))) 0.8) |
| 20:14 | clojurebot | (() (((() ())) () () ())) |
| 20:14 | zachmassia | Hmm, the update functions only act on the inputs for now. It worked without the doall, but I only have about 5 entities so didn't know if it would be needed with more entities |
| 20:14 | amalloy | adding more entities will have no effect |
| 20:15 | amalloy | the only thing to worry about is if you call this update-state function much more often than you read the resulting state, you could theoretically run into some issues |
| 20:15 | zachmassia | Actually now that I think of it, I iterate over them to draw them, so the doall is probably redundant then, right? |
| 20:15 | amalloy | right |
| 20:15 | Cr8 | possibly. The doall can ensure that you don't *do compute in your draw routine* though. |
| 20:15 | amalloy | that's a good point, actually |
| 20:15 | Cr8 | though in that sort of situation perhaps you should swap (doall (map ...)) for (mapv ...) |
| 20:16 | zachmassia | Good call, Cr8. I'll have a look into mapv |
| 20:16 | amalloy | if you want to make sure you only start drawing once you know exactly what you will draw, eg because it's bad to tie up the drawing thread, you might want to use doall or something like it to force the computation |
| 20:17 | zachmassia | I'm using https://github.com/rm-hull/big-bang to coordinate update and draw calls. afaik it only calls draw when there is a change in the world state |
| 20:17 | Cr8 | mapv is map, but returns a vector and isn't lazy. Handy if you want the output to already-be-computed and especially so if you're going to be doing random access to it (or if you want to throw reducers at it later) |
| 20:18 | Cr8 | if you're throwing reducers at it in the same place though use reducers/map |
| 20:19 | zachmassia | Cr8: No reduce or anything right now. mapv sounds exactly like what I need |
| 20:19 | zachmassia | Thanks for the help guys :) |
| 20:30 | goldfeld | oohh i like that big-bang library link |
| 20:31 | xeqi | seangrove: do you have a good way to do server side rendering? |
| 20:31 | seangrove | xeqi: For React code? |
| 20:31 | xeqi | yep |
| 20:32 | seangrove | Nope. Thinking about it. Thought it would be fun to have a library fire up node and communicate with it to get the output over a socket |
| 20:32 | seangrove | xeqi: The React guys keep telling me not to re-implement the React rendering code in Clojure, sadly. |
| 20:33 | xeqi | seangrove: heh, I'd skip rewriting the rendering too |
| 20:33 | xeqi | I've seen https://github.com/brendanyounger/omkara/blob/master/src/omkara/react.clj#L29, which basically uses rhinko |
| 20:33 | xeqi | *rhino |
| 20:34 | xeqi | could embed something similar for dyn.js if wanted |
| 20:34 | zachmassia | goldfeld: I'm using it for my first cljs (and functional) program with his fork of monet as well. Might not be the best code but it works so far https://gist.github.com/ZachMassia/9dceffdd42b569845c48 |
| 20:35 | xeqi | but leaves that leaves open how to handle ajax calls for initial data vs rendering them already from server side |
| 20:35 | seangrove | xeqi: I think that'd be fine for static pages that can be rendered once at startup, but dnolen_ mentioned that nodyn is something like 300x slower than node, so I might be nervous to use it dynamically |
| 20:35 | xeqi | and how to load the initial app state w/ that data if server side rendered |
| 20:36 | seangrove | xeqi: Yeah. It's messy enough that I wouldn't really recommend any one-way for newcomers yet, certainly. |
| 20:36 | xeqi | oh well, I'll be interested to see if you come up with something |
| 20:38 | seangrove | xeqi: Since we develop everything without a server first anyway, then setup Schema, then introduce the server, giving the frontend code enough data to render is trivial. It always bootstraps itself with some calls to the server post-load |
| 20:38 | seangrove | And the initial state is enough for good SEO |
| 20:38 | seangrove | But it's a pretty specific approach, still thinking about a more general solution |
| 20:48 | goldfeld | zachmassia: cool! i was considering using the monet fork too, will check out your code, thanks |
| 21:00 | dnolen_ | seangrove: Om 0.5.1 out |
| 21:00 | seangrove | dnolen_: Awesome. I meant to send a PR with IDsplayName implemented for Om inputs |
| 21:01 | seangrove | dnolen_: I can send that in a few minutes if you haven't done it already |
| 21:01 | dnolen_ | seangrove: just open a issue for that, I can do it easily enough. |
| 21:02 | dnolen_ | seangrove: will have to wait for next release |
| 21:04 | mlb- | I'm having trouble unarchiving a password protected zip file from clojure. Does anyone have experience with this? |
| 21:11 | benmoss | mlb-: are you using a library? |
| 21:13 | mlb- | benmoss: I've not found a library that supports extracting from password protected zipfiles. Don't want to have to resort to shelling out if I don't have to |
| 21:13 | benmoss | ZipInputStream doesn't support password protected files |
| 21:13 | benmoss | http://www.lingala.net/zip4j/ is probably your best bet, i dunno if anyone has written a wrapper |
| 21:14 | mlb- | Doh. I should've remembered to check maven and friends |
| 21:14 | mlb- | thanks, benmoss |
| 21:14 | benmoss | sure |
| 21:14 | benmoss | here's some example code using it i just found https://github.com/oakes/Nightweb/blob/master/common/clojure/nightweb/zip.clj |
| 21:29 | dsrx | zip is such an overloaded term |
| 21:30 | dsrx | for example, I remember being surprised to hear that PHP's stdlib included 'zip' functions, only to learn they had to do with zip files |
| 21:32 | mlb- | or Haskell's zip? |
| 21:33 | dsrx | well, that's what I was expecting |
| 21:33 | mlb- | ah, I was thinking of zippers |
| 21:33 | dsrx | yeah, and then there's that :P |
| 21:41 | muhoo | it's fun reading all the backscroll between sean and david. reminds me of a few years ago in here where there were guys like chris, chas, zach, phil, and others, continually evolving all kinds of cool stuff |
| 21:42 | chouser_log | who's chris? ;-) |
| 21:42 | muhoo | and chouser_log too :-) |
| 21:43 | muhoo | grainger, and anthony, there was so much going on |
| 21:43 | logic_prog | is there a way to tell lein "lein, update yourself" |
| 21:44 | muhoo | logic_prog: lein updgrade |
| 21:44 | muhoo | upgrade |
| 21:44 | logic_prog | $ lein upgrade Upgrades should be done using apt rather than Leiningen itself. |
| 21:44 | muhoo | wat? |
| 21:45 | chare | what is the difference between lein trampoline and lein run |
| 21:45 | qbg | logic_prog: You installed lein using apt? |
| 21:46 | logic_prog | yeah |
| 21:46 | muhoo | didn't know you could do that. |
| 21:46 | logic_prog | is that a bad thing? |
| 21:46 | logic_prog | as in "sudo apt-get install leiningen" |
| 21:46 | logic_prog | ubuntu 13.10 |
| 21:46 | right1 | try apt-get install --only-upgrade <packagename> |
| 21:46 | qbg | Is that version out of date for you? |
| 21:47 | logic_prog | I just manually installed lein |
| 21:47 | logic_prog | everything works now :-) |
| 21:47 | muhoo | you might want to uninstall the apt package if you're installing it manually |
| 21:47 | right1 | what do you guys like for websockets in clojure? http-kit or adelph? |
| 21:47 | logic_prog | http-kit |
| 21:48 | logic_prog | the author of http-kit is awesome |
| 21:48 | logic_prog | i've filed bug reports on github issues, and he's responsded |
| 21:48 | muhoo | haven't tried http-kit, but done websockets stuff with aleph and it worked. |
| 21:48 | n0n3such | i've been looking for someone who's used http-kit :) |
| 21:48 | logic_prog | I use http-kit. |
| 21:48 | logic_prog | It's awesome. |
| 21:48 | n0n3such | logic_prog: experiences ? |
| 21:49 | logic_prog | Damn it, I'm not sure what else I can do; it sounds like I'm selling http-kit stock. |
| 21:49 | n0n3such | i tried hooking it up with compojure following the http-kit example and it didn't compile |
| 21:49 | n0n3such | but i'm a clojure noob |
| 21:49 | logic_prog | buy http-kit ! |
| 21:50 | logic_prog | sell bitcoin, buy http-kit |
| 21:50 | muhoo | logic_prog: everyone has their programmign fanboi thing |
| 21:50 | ddellacosta | woah, I've never heard that about upgrading lein, in fact only the opposite. |
| 21:50 | muhoo | i annoy people by telling them how awesome clojure, om, and datomic are |
| 21:50 | n0n3such | some kind of namespace problem |
| 21:50 | benmoss | anyone familiar with vim-fireplace, is there much that can be done for a file like this? https://github.com/Datomic/simulant/blob/master/examples/repl/hello_world.clj |
| 21:50 | logic_prog | muhaoo: I like clojure, om, and datomic |
| 21:50 | logic_prog | muhaoo: admittedtly, http-kit is not as awesome as clojure/datomic, but possibly comparable to om |
| 21:52 | mlb- | benmoss: I use fireplace quite a bit. What do you mean "done"? |
| 21:52 | muhoo | i expect that once i get further into core.async i'll be just as fanboi about that. so far i'm impressed. |
| 21:52 | benmoss | mlb-: i can't evaluate any forms in that file |
| 21:52 | benmoss | mlb-: when i 'cpp' the first line: https://gist.github.com/benmoss/9339442 |
| 21:53 | mlb- | I've not worked with dataomic and friends, but as long as fireplace has an nREPL connection, things "just work" for me |
| 21:53 | benmoss | hmm |
| 21:54 | mlb- | huh. that stacktrace is something I've not seen before |
| 21:54 | benmoss | i have found i have problems whenever there's a file like this that has no ns and is just meant to be evaled |
| 21:54 | benmoss | seems like just some vimscript error |
| 21:55 | benmoss | even just 'cqp'-ing (+ 1 1) yields the same stacktrace |
| 21:55 | benmoss | something about it trying to create a new ns |
| 21:56 | technomancy | logic_prog: lein from apt-get is hopelessly out of date ATM; I'd recommend removing and installing by hand |
| 21:56 | logic_prog | technomancy: already did that |
| 21:57 | logic_prog | technomancy: if only the maintainer of len would add a mode, where a system wide lein would (1) check to see if slef is out of date and (2) if so, install a up to date lein in ~/.local-lein, and (3) call ~/.local-lein |
| 21:57 | logic_prog | :-) |
| 21:58 | technomancy | logic_prog: if you want something that's up-to-date, you shouldn't be using apt-get to begin with |
| 21:59 | technomancy | the whole point of apt-get is that it will always work the same as it did when it was first packaged and never break |
| 22:00 | tolitius | technomancy: is that something "lein possible": https://www.refheap.com/51402 ? |
| 22:00 | chare | do you guys use pulsar lightweight threads with clojure? |
| 22:01 | technomancy | tolitius: yeah, lein templates can take arguments |
| 22:01 | technomancy | tolitius: right now the composability story around templates isn't great, but simple flags and such are easy |
| 22:02 | benmoss | mlb-: can you try this repo out? https://github.com/benmoss/fireplace-bug |
| 22:02 | benmoss | just eval the form in the file in examples |
| 22:02 | tolitius | technomancy: great! I could not find the how to on template arguments, is there a place I can dive in for more info? |
| 22:04 | technomancy | tolitius: it should be fairly clear if you do `lein new template mytemplate` |
| 22:04 | technomancy | it spits out a template with a defn in it; just add more args to the defn |
| 22:05 | tolitius | benmoss: fyi: it works for my fireplace setup, e.g. gets evaluated to 2 |
| 22:05 | benmoss | hmm |
| 22:06 | benmoss | tolitius: examples/wtf/bug.clj ? |
| 22:06 | benmoss | lemme try updating and see if that fixes anything |
| 22:07 | tolitius | technomancy: you mean the "entry point fn": e.g. https://github.com/tolitius/cccp/blob/master/src/leiningen/new/cccp.clj#L6 ? it makes sense. it's just clojure.. I get it :) |
| 22:08 | technomancy | it's clojure's motto |
| 22:08 | technomancy | "It's just a function" |
| 22:08 | tolitius | benmoss: no, "examples/wtf/bug.clj " will not work |
| 22:08 | tolitius | since your source-paths are not looking there |
| 22:09 | benmoss | source-paths includes examples, shouldn't it? |
| 22:09 | benmoss | maybe i don't understand source-paths, i admit |
| 22:09 | tolitius | benmoss: why would you keep sources in "src" and in another dir that's not in "src"? |
| 22:10 | benmoss | it's a common example i've seen to have some "example" code in another directory |
| 22:10 | benmoss | ala https://github.com/Datomic/simulant/blob/master/examples/repl/hello_world.clj |
| 22:10 | tolitius | benmoss: oh.. and you have no namespace there |
| 22:11 | benmoss | yeah, it's meant to be just evaluable code, not a ns |
| 22:11 | tolitius | benmoss: that's your problem. add "(ns wtf.bug)" to the beginning of your "examples/wtf/bug.clj", and it will work |
| 22:11 | noprompt_ | gawd. emacs indentation for ruby is awful... |
| 22:12 | tolitius | benmoss: I prefer to have "example" code under "test" if you must, but yes, I've seen this pattern around |
| 22:13 | tolitius | technomancy: yep, makes a lot of sense, it was my first clojure template, and as it goes with "firsts", the fear of uncertainty blinds the fact just how simple it is.. |
| 22:13 | tolitius | technomancy: s/clojure template/lein template |
| 22:14 | benmoss | noprompt_: isn't ruby-mode.el maintained by Matz? |
| 22:14 | muhoo | can you nest {:keys []} inside {:keys ? i.e. {:keys {:keys [foo] :as params}} in a ring req? |
| 22:14 | noprompt_ | benmoss: i dunno, but it's fucking horrible. |
| 22:15 | noprompt_ | benmoss: i'm trying to return a hashmap in a case in a when clause and the map indentation is all hosed. |
| 22:15 | muhoo | i've been doing {{:keys [foo]} :params} but if i want other things i have to stutter them, i.e. {{:keys [foo]} :params bar :bar} |
| 22:15 | tolitius | benmoss: in order for it to be "evaluable code" it needs a namespace |
| 22:15 | noprompt_ | i'll get in a bar fight over it: syntax is a *bad* idea. |
| 22:15 | benmoss | tolitius: i thought fireplace tried to create a user ns if one was not declared or something like that |
| 22:16 | technomancy | benmoss: I don't think ruby-mode is maintained at all |
| 22:17 | benmoss | ok, *created* by? not as though that guarantees any kind of quality, just would have assumed |
| 22:19 | tolitius | benmoss: https://github.com/tpope/vim-fireplace/blob/master/doc/fireplace.txt#L118 yes, then you should remove "examples" from under "source-paths" |
| 22:19 | tolitius | benmoss: and it will work |
| 22:20 | benmoss | ah lemme try that |
| 22:20 | tolitius | benmoss: otherwise you _are_ putting it on the classpath, but don't specify the namespace, which is why it does not like it |
| 22:21 | benmoss | indeed, it does work |
| 22:24 | benmoss | thanks tolitius |
| 22:25 | Nyyx | so no libraries in clojure for bimaps? |
| 22:26 | tolitius | benmoss: sure, glad it helped |
| 22:26 | sea-gull | Nyyx: there's a bimap in guava |
| 22:26 | sea-gull | which is available from clojure too |
| 22:27 | tolitius | Nyyx: will http://clojuredocs.org/clojure_core/clojure.set/map-invert work? |
| 22:27 | Nyyx | I guess, but I'll have two maps |
| 22:28 | Nyyx | and I was hoping to serialize them so idk about guava |
| 22:29 | tolitius | Nyyx: but it is two indices one way or another |
| 22:29 | tolitius | Nyyx: *these are |
| 22:31 | tolitius | Nyyx: e.g. in guava these are also two maps: https://code.google.com/r/baggiogamp-guava/source/browse/guava/src/com/google/common/collect/HashBiMap.java#76 |
| 22:32 | tolitius | Nyyx: so I don't see why a simple map-invert won't work |
| 22:41 | Nyyx | tolitius: okay I was wrong |
| 22:41 | Nyyx | I'll use map-invert |
| 22:59 | Nyyx | if I have a function which uses map-invert in its body on the same map over and over will it always calculate the invert? |
| 23:00 | bbloom | Nyyx: clojure doesn't do any common subexpression elimination optimizations beyond what the java vm will do at jit time (read; very simple ones) |
| 23:01 | bbloom | Nyyx: so yes |
| 23:02 | MattAbbott | what optimizations does clojure do before hitting the jvm? |
| 23:02 | bbloom | MattAbbott: practically none at the source transformation level |
| 23:03 | MattAbbott | I see. Are optimizations just kinda low on the priority list right now? |
| 23:03 | bbloom | MattAbbott: they're simply not necessary in most cases |
| 23:03 | Nyyx | bbloom: what about if I use a let binding? |
| 23:03 | Nyyx | and put the map-invert in there |
| 23:03 | bbloom | Nyyx: every time the let runs, the right side of the bindings will be re-evaluated |
| 23:03 | Nyyx | so I have to put it in a def? |
| 23:04 | bbloom | Nyyx: if you've only got one map & one map invert, then yeah, put it in a def. |
| 23:04 | bbloom | Nyyx: depending on your use case, you could manually memoize in some way |
| 23:05 | Nyyx | the map stores user settings that could change |
| 23:05 | Nyyx | so eventually I was thinking of putting it into an atom? |
| 23:05 | bbloom | Nyyx: may vary at startup? or can change at runtime? |
| 23:05 | Nyyx | runtime |
| 23:06 | bbloom | if you haven't measured and determined that it's too slow, i'd say ignore it |
| 23:06 | Nyyx | so I guess I would stick both maps in a vector of the atom or two atoms for each one but then I'd need a watcher to change an atom when one changes right? |
| 23:07 | bbloom | Nyyx: you can do either a watcher or simply store the input AND the output, then check if the inputs differ, if so, recompute the output |
| 23:08 | bbloom | your choice if you want/need eager or lazy recomputation |
| 23:09 | bbloom | Nyyx: i'd just skip the watcher completely and not bother with the lazy recomputation. instead, just make a function to set the new settings and update two mutable values there |
| 23:09 | Nyyx | bbloom: okay thanks |
| 23:09 | Nyyx | cleared up my confusion |
| 23:17 | wei__ | is there a blocking sleep in javascript? would be nice for using inside a go block |
| 23:18 | tolitius | wei__: take from a timeout channel? |
| 23:18 | tolitius | will block until the timeout is done |
| 23:19 | wei__ | oh yeah, that'll work |
| 23:22 | wei__ | didn't realize there's actually a timeout channel in the api- that's cool |
| 23:25 | bbloom | wei__: if you don't already know, be sure to check out various golang resources for how to utilize multiplexing and timeout channels |
| 23:26 | wei__ | will do thanks bbloom |
| 23:27 | munderwo | Hi all. has anybody played around with HTTP-kit? |
| 23:28 | munderwo | I was wondering. A lot of their examples use the form (with-channel req channel …) but I'm not sure where the channel value comes from? |
| 23:39 | devn | Does anyone use earmuffs still on their dynamic vars? |
| 23:39 | dsrx | munderwo: it's a macro that makes handlers where the symbol channel (in that case) is bound to a channel opened up with a client/server |
| 23:39 | devn | Or is that old school at this point? |
| 23:40 | dsrx | munderwo: the docstring for with-channel might be helpful |
| 23:48 | munderwo | dsrx: so it grabs the web socket channel from the request headers? or from the middleware or something? |
| 23:48 | minikomi | I'm wanting to use a github branch which isn't yet available on clojars .. is git cloning the project & then symlinking it in checkouts the way to go? |
| 23:55 | dsrx | munderwo: yeah, the actual socket is grabbed from the request in the expanded macro |
| 23:55 | munderwo | dsrx: ahh ok. that makes sense. it looked like it was just appearing from no-where which was confusing. but makes sense now |