2013-10-22
| 00:53 | jared314 | binding gives me a warning about not dynamic |
| 00:54 | technomancy | jared314: you can bind *ns* |
| 00:54 | amalloy | jared314: (eval `(do (in-ns ~'whatever.core) ~@forms)) |
| 00:55 | jared314 | this is the code: https://www.refheap.com/20060 |
| 00:55 | jared314 | perhaps it is the my repl instance |
| 00:58 | jared314 | nm it was my repl instance |
| 01:21 | jared314 | does the reader literal tag only apply to the next valid form? |
| 01:25 | justdit | hi guys! I'm doing tests for my app which uses asynchronous call from Langohr. And I have a problem: lein exits before that asyn call finishes. |
| 01:25 | justdit | Is there a way to solve this problem? |
| 01:29 | coventry | gfredericks: That trick of bashing LispReader/macros is awesome! |
| 01:29 | amalloy | gfredericks: what have you done? |
| 01:30 | coventry | I will only use this power for good. :-) |
| 01:34 | jared314 | coventry: what was this? |
| 01:35 | bitemyapp | seangrove: http://nathanic.org/posts/2013/typed-clojure-tour/ |
| 01:36 | seangrove | Oh, very nice! |
| 01:36 | seangrove | I'll check this out sometime this week or weekend, need to add it to my core.async test |
| 01:36 | coventry | jared314: gfredericks's marginalia link demonstrates a way of implementing reader macros by fiddling with clojure's internal java structures. |
| 01:37 | jared314 | coventry: can you post the link again? just lost my history |
| 01:38 | coventry | Logs are here: http://logs.lazybot.org/irc.freenode.net/%23clojure Link is https://github.com/gdeer81/marginalia/blob/master/src/marginalia/parser.clj#L63 |
| 01:39 | coventry | *poof* |
| 01:39 | jared314 | coventry: neat! |
| 01:58 | arrdem | jkkramer: any interest in structural hashing for Loom? |
| 01:58 | arrdem | jkkramer: I just did graph structural hashing and would be happy to work on a PR if you think it's something Loom could use. |
| 02:28 | ta479 | ,help |
| 02:28 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: help in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 02:51 | akurilin | Is there any way of aliasing compojure routes without much duplication? |
| 02:52 | akurilin | As in, my api routes are foo.bar.com/1/somethings and that doesn't look super nice in the URL bar if you're serving both HTML and json from the same routes |
| 02:54 | xsyn | akurilin: json/1/somethings vs 1/somethings ? |
| 02:55 | akurilin | as in, I'd rather remove the api version from the URL since that's more internal |
| 02:55 | akurilin | and for mobile clients |
| 02:56 | xsyn | ah |
| 02:56 | xsyn | I'm not sure how that would work |
| 03:03 | ta479 | what are the major web frameworks for clojure, like Scala's Lift, play, scalatra, unfiltered, etc.? |
| 03:06 | xsyn | ta479: there's a library you can look at lib-noir, Clojure is more llibrary than framework driven |
| 03:06 | xsyn | look at lib-noir and compojure |
| 03:09 | ta479 | xsyn: are there any examples I can learn from |
| 03:11 | scottj | ta479: also pedestal |
| 03:13 | xsyn | also pedestal |
| 03:14 | xsyn | which, depending on what you want to do may be like tying a rocket to your car ;) |
| 03:14 | xsyn | ta479: I'm trying to find what I got started with |
| 03:14 | xsyn | ta479: My understanding of Pedestal is that it's amazing for single page apps, scottj is that right? |
| 03:15 | scottj | xsyn: that's my understanding. I haven't used it. |
| 03:15 | H4ns | does anyone know whether there is a trick that makes primsmatic's schema.core support recursive definitions? |
| 03:16 | H4ns | i tried just specifying the name of a schema in its own definition, but that ends up with an unbound reference which cannot be validated |
| 03:19 | H4ns | http://cljbin.com/paste/52661e2de4b067e3f51a922b |
| 03:41 | ta479 | what's the difference between == and = |
| 03:44 | xsyn | I'm not sure in Clojure |
| 03:44 | xsyn | but generally = is has same value |
| 03:44 | junk325 | = is type independent |
| 03:44 | xsyn | == is same value and type |
| 03:44 | junk325 | == tests for identical values |
| 03:45 | ta479 | I don't get it |
| 03:47 | jared314 | i thought == was only for numbers |
| 03:48 | jared314 | ,(== 1 1.0) |
| 03:48 | clojurebot | true |
| 03:49 | jared314 | ,(== 1 "1") |
| 03:49 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number> |
| 03:49 | jared314 | ,(= 1 "1") |
| 03:49 | clojurebot | false |
| 03:50 | jared314 | ,(= 1 1.0) |
| 03:50 | clojurebot | false |
| 03:51 | ta479 | ,(== 1.0 1) |
| 03:51 | clojurebot | true |
| 03:52 | ta479 | still confused |
| 03:52 | jared314 | the value of 1 and 1.0 are the same |
| 03:52 | jared314 | but |
| 03:52 | jared314 | the type of 1 and 1.0 is different |
| 03:53 | jared314 | == for numbers compares value |
| 03:53 | ta479 | so xsyn meant = tests for same value and type? |
| 03:53 | junk325 | look at the source |
| 03:53 | ta479 | because he said == does that |
| 03:53 | junk325 | https://github.com/richhickey/clojure/blob/a1eff35124b923ef8539a35e7a292813ba54a0e0/src/clj/clojure/core.clj#L886 |
| 03:54 | xsyn | == tests for value and type |
| 03:54 | xsyn | = test for value |
| 03:54 | jared314 | are you sure? |
| 03:55 | junk325 | no |
| 03:55 | junk325 | it's not based on type, solely |
| 03:56 | junk325 | jared314: for numbers == just checks equivalence |
| 03:57 | junk325 | for other types it tests for identical values |
| 03:57 | jared314 | == doesn't work for other types, just numbers |
| 03:57 | junk325 | == uses `(. clojure.lang.Numbers (equiv ~x ~y)) |
| 03:57 | xsyn | Why would you specifically define an operator just for values? |
| 03:57 | junk325 | = uses (clojure.lang.Util/equiv x y) |
| 03:58 | junk325 | that's the difference between the two |
| 03:58 | jared314 | xsyn: to easily compare double and int |
| 03:58 | junk325 | how are you defining "values"? |
| 03:58 | xsyn | ah |
| 03:58 | jared314 | number values |
| 03:59 | ta479 | ,(== "1") |
| 03:59 | clojurebot | true |
| 03:59 | xsyn | yes, that makes sense |
| 03:59 | junk325 | yeah, what you said jared314 |
| 03:59 | Jarda | ,(== "1" 1) |
| 03:59 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.String cannot be cast to java.lang.Number> |
| 03:59 | junk325 | = will equate nil with other non-nil values |
| 03:59 | Jarda | ,(= nil 2) |
| 03:59 | clojurebot | false |
| 03:59 | junk325 | == will only equate 0 with 0 in any form and not nil |
| 03:59 | Jarda | ,(= nil 0) |
| 03:59 | clojurebot | false |
| 04:00 | junk325 | ,(= nil 0) |
| 04:00 | clojurebot | false |
| 04:00 | junk325 | ,(= nil false) |
| 04:00 | clojurebot | false |
| 04:00 | ta479 | == only works on numbers though, so there are no other types it works with except for the trivial unary case |
| 04:00 | jared314 | ,(== 2 2/1) |
| 04:00 | clojurebot | true |
| 04:01 | junk325 | ta479 is right |
| 04:01 | junk325 | (== nil 0) gives an exception |
| 04:02 | junk325 | the docs should be more explicit about this |
| 04:02 | akurilin | Hey guys, has anybody here dealt with the issue of selmer not being able to find .html templates once the project is uberjarred? |
| 04:02 | jared314 | there should be better docs on the whole |
| 04:03 | akurilin | Getting a FileNotFoundException, but otherwise it works just fine non-jarred |
| 04:03 | junk325 | lol |
| 04:03 | jared314 | but that is a big task |
| 04:03 | junk325 | a lot of the docs are written very obscurely |
| 04:03 | junk325 | some are like mindtrap puzzles |
| 04:03 | jared314 | they assume you have read the source |
| 04:03 | jared314 | which isn't a bad skill to have |
| 04:04 | junk325 | sometimes the source required digging into core clojure java |
| 04:05 | gws | akurilin: what version of selmer |
| 04:05 | ta479 | the doc for == also says returns non-nil which is ambiguous when it really always returns a bool |
| 04:05 | jared314 | akurilin: is the template in the uberjar? |
| 04:05 | akurilin | gws 0 4 6 |
| 04:05 | akurilin | jared314, yes, I unzipped and looked inside |
| 04:05 | gws | akurilin: i ask because of this https://github.com/yogthos/Selmer/commit/33f004e407b626bba0403568d8a6a9dd2bf567f2 |
| 04:05 | gws | try 0.4.8? |
| 04:05 | amalloy | akurilin: you're probably using (file ...) instead of (resource ...) somewhere |
| 04:06 | amalloy | ie, "look here in the filesystem" (which doesn't exist in the deploy environment, rather than "look here on the classpath" (which the uberjar contains a copy of) |
| 04:07 | akurilin | gws, yeah that was it :( |
| 04:07 | akurilin | gws, or :) I mean |
| 04:07 | akurilin | amalloy, I was using render-file taking classpath in consideration, but I know what you mean, probably ran into that issue as well a dozen times. |
| 04:10 | jared314 | there was a project awhile back, that showed up on hacker news, about searchable clojure function examples |
| 04:10 | jared314 | you would search for a function and get example usages from some place |
| 04:10 | jared314 | i wonder what happened to that |
| 04:11 | akurilin | yogthos, thanks for fixing that btw, made my night :) |
| 04:12 | akurilin | bitemyapp, btw, totally did what you mentioned a while ago with the gradual transition off of backbone to server-side rendering. Carving out one route at a time in nginx, chunk of the site is rendered by a completely different app |
| 04:14 | jared314 | what is the preferred way to add new entries to *data-readers*? binding or set! |
| 04:19 | ddellacosta | jared314: I seem to recall it being something different than this, but clojuredocs.org, while out of date, still has plenty of useful clojure function examples |
| 04:20 | jared314 | ddellacosta: i remember it being different too. I think he was using the datomic clojure parser at the time. |
| 04:21 | ddellacosta | jared314: yah, you could feed a "before and after" or something in, and it would give you functions that did what you wanted, right? |
| 04:22 | jared314 | ddellacosta: I don't remember that part, but that would be cool |
| 04:23 | ddellacosta | jared314: ah, maybe I'm thinking of something else then |
| 04:24 | jared314 | ddellacosta: http://getclojure.org/ |
| 04:24 | ddellacosta | oh neat |
| 04:24 | ddellacosta | oh, that's super fun |
| 04:24 | ddellacosta | thanks jared314 |
| 04:26 | ddellacosta | ha, the first few results for juxt are hilarious: http://getclojure.org/search?q=juxt&num=0 |
| 04:26 | jared314 | https://news.ycombinator.com/item?id=5839659 |
| 04:27 | ta479 | ,(not= 1.0 1) |
| 04:27 | clojurebot | true |
| 04:27 | ddellacosta | juxt juxt juxt juxt juxt juxt |
| 04:27 | ta479 | ,(not= 1 1) |
| 04:27 | clojurebot | false |
| 04:27 | ta479 | ,(not= 1 "1") |
| 04:27 | clojurebot | true |
| 04:27 | jared314 | he pulled the examples from the IRC logs |
| 04:27 | jared314 | and clojuredocs |
| 04:28 | ddellacosta | yah, wish they had added project links per that HN comment |
| 04:28 | ddellacosta | and there are definitely some garbage results, but ah well. Still a nifty idea |
| 04:28 | ddellacosta | with some refining thing it could be a great tool |
| 04:28 | ddellacosta | *think |
| 04:29 | jared314 | it might be neat to parse the open source clojure projects and get a graph db of the related functions |
| 04:30 | ddellacosta | jared314: ah, to see what kind of functions are used in conjunction with each other more often, for example? |
| 04:30 | ddellacosta | that would indeed be coo; |
| 04:30 | jared314 | yes |
| 04:30 | ddellacosta | *cool |
| 04:31 | xsyn | woah, juxt is awesome |
| 04:32 | xsyn | the documentation is insane though |
| 04:32 | ta479 | (cf map) is really long |
| 04:33 | jared314 | is anyone board enough to take a look at my code and tell me if i'm doing something stupid |
| 04:34 | jared314 | ? |
| 04:34 | jared314 | bored* |
| 04:34 | jared314 | https://gist.github.com/Jared314/7095415 |
| 04:41 | jared314 | i'll take that as a nope |
| 04:54 | ucb | jared314: I'm not bored but need a distraction :) |
| 04:54 | ucb | looking. |
| 04:54 | jared314 | ucb: thanks |
| 04:55 | ucb | right. Well above my punching weight. Apologies :( |
| 04:55 | jared314 | ucb: np |
| 04:56 | jared314 | ucb: I need to get back on task anyway |
| 04:56 | ucb | jared314: :) |
| 04:56 | nonuby | jared314, perhaps take a look at clojure style guide, above my punching weight too to comment on anything but style |
| 04:58 | jared314 | nonuby: https://github.com/bbatsov/clojure-style-guide ? |
| 04:58 | nonuby | thats the one |
| 05:12 | uruviel | jared314: what are you trying to do exactly? It looks like you want to parse some HTML (guessing from the hiccup) into a custom language? |
| 05:12 | musicalchair | jared314: that's interesting. it looks fun to play with. A bit above my punching weight & I'm not sure exactly where you're going with this (though I can guess). I might've shied away from using eval and written some sort of specific evaluator. I'd probably start with insta/transformer, actually. One thing to note is the implicit 'magic' of your code means you can't have a rule named 'grammar'. I would |
| 05:12 | musicalchair | say that sort of style goes against the grain of clojure community but that's no reason to stop, necessarily |
| 05:13 | jared314 | uruviel: i'm translating hiccup to sexp because instaparse only has hiccup and enlive output formats |
| 05:13 | jared314 | uruviel: and you cannot add more |
| 05:14 | uruviel | jared314: aahh right, now I see. Haven't played with instaparse yet (it's on the todo-list somewhere) |
| 05:14 | jared314 | musicalchair: i wasn't sure where to put the grammar |
| 05:15 | musicalchair | jared314: if you used insta/transformer, you could retain the implicit magic 'ns defines a langauge' by having a grammar var (as you do) and a transformer var that contains the transform map |
| 05:15 | jared314 | musicalchair: i was hoping that the "user" would write the namespace and then use the register function |
| 05:16 | yojimb012345 | hey all, question about decomposition within a fn i.e. double square brackets, I know what this code does but I am having problems visualising in steps what the syntax is saying specifically of the [[h s]] bit: (doseq [line (map (fn [[h s]] (str h " (" s ")")) (partition 2 (hn-headlines-and-points)))] (println line))) |
| 05:16 | uruviel | jared314: so (guessing here) you want to generate a language that generates sexp's? |
| 05:17 | jared314 | uruviel: yes, it would simplify implementing the language functionality |
| 05:17 | jared314 | uruviel: but, it was just an idea |
| 05:18 | uruviel | jared314: hmm interesting approach, any specific DSL (using the term liberally here) in mind? I mean, I assume you'd like a custom language instead of vanilla Clojure because you'd be able to express some abstractions better |
| 05:19 | musicalchair | jared314: if you didn't want to use insta/transformer, you could still have a 'fn-map' var (or something) and in hiccup->sexp, make some gensyms for the fn, use the gensyms instead of the ns syms, and wrap the form in a let that binds the fns to the gensyms. a little complicated... |
| 05:20 | jared314 | musicalchair: hold on, still looking at the instaparse source to see if transformer will work |
| 05:21 | jared314 | yojimb012345: the mapped function takes the partitioned items and splits them back out into to then concat them into a string |
| 05:21 | notofi | Why is this function also "declaring(defn init [] (defn add5 [a] (+ a 5))) |
| 05:21 | notofi | Why is this function "declaring" add5 without me even calling (init) |
| 05:23 | jared314 | yojimb012345: it will take the (1 2) and assign 1 to h and 2 to s |
| 05:24 | uruviel | notofi: because defn simply expands to (def (fn ...)) and defs define vars, which are bound to the namespace (iirc) |
| 05:25 | notofi | uruviel: yes but the "defn add5" is never evaluated |
| 05:25 | notofi | uruviel: it should only be evaluated when I call (init) |
| 05:27 | uruviel | notofi: it shouldn't and it doesn't in my REPL |
| 05:28 | notofi | uruviel: In my repl its like this: user=> (defn init [] (def Z 100)) |
| 05:28 | uruviel | notofi: http://pastebin.com/4Wj5DGPj |
| 05:28 | notofi | #'user/init |
| 05:28 | notofi | user=> Z |
| 05:28 | notofi | #<Unbound Unbound: #'user/Z> |
| 05:28 | TEttinger | yes |
| 05:28 | TEttinger | that means it isn't declared |
| 05:29 | TEttinger | unbound fn |
| 05:29 | TEttinger | or rather unbound unbound |
| 05:29 | TEttinger | it doesn't even know its an fn yet |
| 05:29 | notofi | but the symbol Z should not be able to be resolved |
| 05:29 | TEttinger | it isn't. |
| 05:29 | TEttinger | try calling it |
| 05:30 | TEttinger | heck try calling qwerrtyyyyyy |
| 05:30 | TEttinger | should be the same |
| 05:30 | notofi | its not the same |
| 05:30 | notofi | user=> Y |
| 05:30 | notofi | CompilerException java.lang.RuntimeException: Unable to resolve symbol: Y in this context, compiling:(NO_SOURCE_PATH:0:0) |
| 05:30 | clojurebot | Huh? |
| 05:30 | notofi | user=> Z |
| 05:30 | notofi | #<Unbound Unbound: #'user/Z> |
| 05:30 | TEttinger | oh interesting |
| 05:31 | notofi | it has the same effect as if I would be (declare Z) |
| 05:31 | TEttinger | you can still defn over it |
| 05:32 | TEttinger | you're right, that is odd. it probably has to do with some compile-time stuff with defn |
| 05:33 | uruviel | notofi: hmm that's weird. You might wanna look through the defn source, maybe that explains it |
| 05:34 | jared314 | musicalchair: I was hoping to extend the functions called beyond just transformations. So, you could implement the functionality of a dsl with clojure functions that match the grammar rules. I could generalize the hiccup->sexp to be a parse-tree transform though. |
| 05:44 | jared314 | musicalchair & uruviel thanks for the help |
| 08:35 | jtoy | is there a simple function to check if a type is any numeric value? I am getting back nil or NaN or Infinity sometimes, but i want the value to be any float or integer |
| 08:35 | llasram | Yes, but -- ##(number? Double/NaN) |
| 08:35 | lazybot | ⇒ true |
| 08:40 | jtoy | I will just check for the type being a double or integer than |
| 08:40 | jtoy | i didnt know about number? |
| 08:40 | llasram | ##(float? Double/NaN) |
| 08:40 | lazybot | ⇒ true |
| 08:40 | llasram | ##(instance? Double Double/NaN) |
| 08:40 | lazybot | ⇒ true |
| 08:40 | llasram | But: ##(Double/isNaN Double/NaN) |
| 08:40 | lazybot | ⇒ true |
| 08:41 | llasram | But: ##(Double/isInfinite Double/POSITIVE_INFINITY) |
| 08:41 | lazybot | ⇒ true |
| 08:41 | llasram | So those may be what you really want to check |
| 09:09 | glosoli | I have a map like this {:entry1 "val1" :entry2 "val2" :entry3 "val3"} I am curious if there is some alternative to update-in, that could update given set of keys by executing function on each of the value ? |
| 09:10 | llasram | glosoli: It's not in the standard lib, but a function usually named `map-vals` is a pretty common utility function |
| 09:10 | mdrogalis | glosoli: fmap? |
| 09:10 | mdrogalis | clojure.algo.functors I think |
| 09:10 | glosoli | aaa ok thanks sirs |
| 09:10 | mdrogalis | As llasram said, not in the standard lib. |
| 09:31 | coventry2 | mdrogalis: clojure.algo.generic.functor |
| 09:34 | yedi_ | https://github.com/yedi/chatter/blob/master/src-cljs/chatter/app.cljs ; why is (name :keyword) causing raising an exception here? |
| 09:34 | yedi_ | dnolen bitemyapp, just a ping to see if you guys were able to take a look aat this |
| 09:35 | Morgawr | yedi_: what exception is raised? |
| 09:36 | mdrogalis | coventry2: Thanks :) |
| 09:38 | yedi_ | Morgawr: https://gist.github.com/yedi/9562cebf6bc6e74d0a1a |
| 09:41 | Morgawr | yedi_: weird, I don't really know D: |
| 09:45 | yedi_ | Morgawr: thanks for lookin anyways |
| 09:46 | Morgawr | yedi_: does it happen if you use the full name? cljs.core/name ? |
| 09:46 | Morgawr | because maybe it's getting shadowed/masked by something else |
| 09:47 | yedi_ | ill try it |
| 09:52 | yedi_ | no change |
| 09:53 | Morgawr | yedi_: that's weird then, I know they changed the way keywords are stored in cljs internally, the version I have of cljs is still an old one so I can't test (also on a bad connection) |
| 09:53 | Morgawr | might be a bug |
| 09:53 | Morgawr | does it happen in a cljs rhino repl too? |
| 09:53 | yedi_ | i had one in the 1800s and then someone also suggested i upgrade to the newest when this bug appeared |
| 09:54 | yedi_ | but it didn't fix it |
| 09:54 | yedi_ | i just put up the whole repository so people can try to figure out if im doing something dumb elsewhere |
| 09:55 | yedi_ | and nope |
| 09:55 | yedi_ | it doesn't happen in a rhino repl. which is what makes this so odd |
| 09:56 | Morgawr | yedi_: yeah, definitely weird, I wish I knew more about cljs to help but unfortunately I don't |
| 09:57 | yedi_ | yea np |
| 09:57 | vanitha | ./script/run Error: Could not find or load main class clojure.main |
| 09:57 | vanitha | beginner to clojure. looking for your help. unable to get koans to run |
| 10:07 | xeqi | vanitha: which version of leiningen are you using? |
| 11:05 | dbsr | hey all |
| 11:05 | dbsr | im using euler challenges to learn clojure, i only started just now, and i was wondering about indentation |
| 11:06 | dbsr | or rather newlines |
| 11:06 | dbsr | when to start one |
| 11:06 | dbsr | is this ok for example http://bpaste.net/show/142834/ |
| 11:06 | mdrogalis | dbsr: https://github.com/bbatsov/clojure-style-guide |
| 11:06 | mdrogalis | dbsr: Use =, not == :) |
| 11:07 | dnolen | yedi: your example app is pretty complicate w/ no instructions on how to run it. |
| 11:07 | glosoli | is there some nice pastebin for clojure that runs the code ? |
| 11:07 | dbsr | thanks mdrogalis |
| 11:08 | H4ns | glosoli: cljbin.com |
| 11:08 | dbsr | whats the difference if I may ask? like js == ===? |
| 11:09 | tazjin | Hej guys! If I set repositories in a Leiningen profile it seems like the ^:replace metadata is ignored. Is there a workaround? |
| 11:09 | mdrogalis | dbsr: = for value equality, == is numeric equality I think? |
| 11:09 | mdrogalis | I've actually never seen anyone use == |
| 11:09 | wink | glosoli: http://cljbin.com/ |
| 11:09 | dbsr | heh, got it from here http://java.ociweb.com/mark/clojure/article.html#FP |
| 11:10 | glosoli | thanks sirs |
| 11:22 | dobry-den | I find myself frequently mapping `int` across byte-arrays to do seq things on them (like concat), and then (byte-array (map byte ...)) when i'm done. |
| 11:22 | yedi | dnolen: my b, I added instructions for running it: https://github.com/yedi/chatter/blob/master/README.md |
| 11:23 | dobry-den | I don't remember my question |
| 11:25 | arrdem | clojurebot: ping |
| 11:25 | clojurebot | PONG! |
| 11:25 | `cbp | dobry-den: :P |
| 11:26 | Morgawr | http://nathanic.org/posts/2013/typed-clojure-tour/ really great article found on HN, probably it's been shared before but.. enjoy :) |
| 11:27 | arrdem | Morgawr: the author posed it in #typed-clojure about 24hrs ago. Good read. |
| 11:27 | Morgawr | aw damn, there's a #typed-clojure channel |
| 11:27 | Morgawr | thanks for letting me know :) |
| 11:27 | dobry-den | Here's a question: Would you say it's bad form to (let [x (get mymap :mykey (ex-info "Invalid"))] ...) instead of checking `x` in the body? |
| 11:28 | arrdem | yeah it's kinda dumb... so low traffic that they should really be in here. |
| 11:28 | llasram | dobry-den: Well, `ex-info` just returns an exception, not throws it, so... |
| 11:28 | Morgawr | arrdem: I'll just idle, sniping for interesting conversations hehe |
| 11:28 | llasram | dobry-den: But `get` is just a function, which evaluates all of it's arguments first, so doesn't really support that sort of idiom |
| 11:29 | arrdem | Morgawr: lurkin is the way to do it.. |
| 11:29 | dobry-den | llasram: I meant `or` |
| 11:29 | llasram | I think that one seems perfectly reasonable :-) |
| 11:29 | llasram | Well, unless the value in the map might be `false` or `nil` |
| 11:30 | dobry-den | llasram: I'm pretty newb with exceptions. I've been using ex-info this week for exceptions but never came across a difference between returning them vs throwing them |
| 11:30 | dobry-den | i seem thrown in that any time they are evaluated in my code they show up to the user and halt progress |
| 11:30 | ToBeReplaced | dobry-den: i would do that in a precondition |
| 11:31 | llasram | ##(ex-info "foo" {}) |
| 11:31 | lazybot | ⇒ #<ExceptionInfo clojure.lang.ExceptionInfo: foo {}> |
| 11:31 | llasram | ##(throw (ex-info "foo" {})) |
| 11:31 | lazybot | clojure.lang.ExceptionInfo: foo {} |
| 11:31 | ToBeReplaced | like (defn myfun [m] {:pre [(contains? m :mykey)]} ...) |
| 11:31 | xeqi | dobry-den: are you interested in something like ##(doc if-let) ? |
| 11:31 | lazybot | ⇒ "Macro ([bindings then] [bindings then else & oldform]); bindings => binding-form test If test is true, evaluates then with binding-form bound to the value of test, if not, yields else" |
| 11:31 | llasram | An exception is just an instance of a class which extends Exception (or more generally, Throwable) |
| 11:32 | llasram | It doesn't cause non-local exits until you `throw` it |
| 11:33 | cleos_frey | hey guys, is there anyway to pull out the doc string of a method (eg, (do-magic myfn) => "This is a docstring") |
| 11:33 | dobry-den | llasram: Weird, maybe I just thought I tested it |
| 11:33 | llasram | cleos_frey: ##(-> #'first meta :doc) |
| 11:33 | lazybot | ⇒ "Returns the first item in the collection. Calls seq on its\n argument. If coll is nil, returns nil." |
| 11:34 | dobry-den | ToBeReplaced: that's great, thanks. |
| 11:34 | cleos_frey | llasram: what do the hashes mean? |
| 11:34 | jkkramer | dobry-den: for that use case, there's also safe-get: https://github.com/Prismatic/plumbing/blob/master/src/plumbing/core.clj#L89 |
| 11:34 | llasram | cleos_frey: The ## outside the parens just tells lazybot to evaluate it |
| 11:35 | jkkramer | or prismatic's schema, for describing/enforcing more complex data shapes |
| 11:35 | cleos_frey | oh haha |
| 11:35 | llasram | cleos_frey: The #' means you want the var itself for `first`, not the value of the var `first` |
| 11:35 | llasram | ##[first #'first] |
| 11:35 | lazybot | ⇒ [#<core$first clojure.core$first@d1931f> #'clojure.core/first] |
| 11:36 | dnolen | dbsr: == is only for numbers |
| 11:36 | ToBeReplaced | i'd like to see more clojure libraries use preconditions to sanitize their "options" input -- it's a pet peeve of mine when i pass ":stream" to find out i should be passing ":as-stream" or similar |
| 11:37 | cleos_frey | llasram: perfect, thank you! |
| 11:46 | dbsr | hey, how woould i rewrite this http://java.ociweb.com/mark/clojure/article.html#FP so the iteration / comprehension stops when the sum of the filtered result is > n? |
| 11:46 | dbsr | ow wrong link |
| 11:46 | dbsr | http://bpaste.net/show/142844/ |
| 11:46 | mdrogalis | dbsr: take-while |
| 11:47 | llasram | Hmm, I don't think so |
| 11:47 | llasram | If you're using Clojure 1.5.x, you can write it using `reduce` and `reduced` |
| 11:47 | mdrogalis | llasram: Where do you see the problem? |
| 11:47 | dbsr | lemme see, i only installed it this afternoon |
| 11:47 | dbsr | its 1.5.1 |
| 11:48 | cleos_frey | [I/exit |
| 11:48 | dbsr | imma have a look at the docs, thanks mdrogalis llasram |
| 11:48 | llasram | mdrogalis: take-while applies a predicate to the individual values, not to an aggregation over the values |
| 11:48 | cleos_frey | lets try that again |
| 11:48 | llasram | dbsr: One sec -- when you say "installed," OOC what did you mean? |
| 11:48 | dbsr | heh, through the package manager of arch |
| 11:49 | mdrogalis | llasram: Ah, nice. I was too quick. |
| 11:49 | llasram | dbsr: If that didn't actually install Leiningen, then most people here would suggest doing that before playing around much further: http://leiningen.org/ |
| 11:49 | dbsr | got lein running, thanks :) |
| 11:49 | llasram | Ok, cool :-) |
| 11:49 | dbsr | use lein repl for the vim plugin |
| 11:49 | llasram | Awesome |
| 11:50 | dbsr | yea, looks like reduce should do the trick, thanks again |
| 11:50 | mdrogalis | llasram: Can you show me an example of using reduced ? I haven't see it before. |
| 11:52 | llasram | Sure: ##(reduce (fn [sum x] (let [sum (+ x sum)] (if (pos? sum) (reduced sum) sum))) -123 (range)) |
| 11:52 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: reduced in this context |
| 11:52 | llasram | Hah, lazybot |
| 11:52 | llasram | ,(reduce (fn [sum x] (let [sum (+ x sum)] (if (pos? sum) (reduced sum) sum))) -123 (range)) |
| 11:52 | clojurebot | 13 |
| 11:52 | llasram | &*clojure-version* |
| 11:52 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 11:52 | hyPiRion | whaaat |
| 11:52 | llasram | Get with the times, lazybot! |
| 11:53 | hyPiRion | Raynes: what have you done? :o |
| 11:53 | mdrogalis | llasram: Ah, nice. Thanks :) |
| 12:00 | ticking | has anybody thought about writing a websocket as core.async channel abstraction lib? I'm wondering if ws should retain their unbounded nature or if a protocol should enforce boundedness like with regular channels. |
| 12:03 | xeqi | ticking: https://github.com/lynaghk/jetty7-websockets-async |
| 12:03 | mdrogalis | ticking: Let applications decide IMO. |
| 12:04 | xeqi | it was used in the torus pong clojure cup submission https://github.com/uswitch/torus-pong/ |
| 12:04 | tbaldridge | ticking if you are going to that I'd recommend looking into using dropping buffers as well. The semantics around alts! are a bit interesting. what does this mean? (alts! [[socket1 42] [socket2 42]]). If you want to stick to core.async semantics that should send to either one or the other, not both. |
| 12:04 | ticking | xeqi: yeah kevin simply uses dropping channels iirc, but no guarantee of delivery over a guarantee of delivery medium seems like the worst default to me |
| 12:05 | tbaldridge | ticking: this is a network connection, you can never really guarantee delivery. |
| 12:05 | ticking | tbaldridge: on not delivery the connection closes |
| 12:06 | tbaldridge | What if you put into a channel and them the socket closes, what do you do with the value you took from the channel? |
| 12:06 | tbaldridge | what do you do if the message gets to the remote end, and the remote buffer is full? |
| 12:07 | ticking | yeah, but you know that the last n (depending on the websocket buffer size) messages might got lost |
| 12:07 | ticking | tbaldridge: yeah, thus the protocol on top of ws messages that enforces delivery |
| 12:08 | ticking | well, delivery of channel closing |
| 12:09 | tbaldridge | ticking: so basically make everything use (dropping-buffer n) |
| 12:09 | tbaldridge | ticking: or sliding-buffer, but IMO that's the only way to do networking with core.async correctly. |
| 12:09 | ticking | tbaldridge: dropping buffers put you into a limbo of a semibroken connection |
| 12:10 | tbaldridge | ticking: welcome to networking. The only reliable semantics are "at least once delivery"+ack messages+idempotent messages |
| 12:10 | tbaldridge | ticking: notice how not even Erlang attempts to solve this. In Erlang everything is "best effort delivery" |
| 12:11 | ticking | erlang is the actor model, core async is csp |
| 12:11 | ticking | they have a fundamentally different approach when it comes to message passing |
| 12:11 | tbaldridge | ticking: and networks are not csp. Don't try to turn them into something they are not. Physical machines have locks, transactions etc. |
| 12:12 | ticking | tbaldridge: and still we generally use tcp instead of udp |
| 12:12 | tbaldridge | That's why CSP exists at all, we can guarantee that a CPU core won't suddenly disconnect from the system. We know that if we put memory into memory location X it will get there, (aside from torching the machine). |
| 12:13 | ticking | tbaldridge: just because we can't guarantee delivery absolutely, does not mean we have to give no guarantees |
| 12:14 | seangrove | tbaldridge: If core.async can't guarantee memory updates through a simple machine torching, sounds like a ticket needs to be filed |
| 12:14 | ticking | tbaldridge: with a certain certainty yes |
| 12:14 | tbaldridge | seangrove: ?? |
| 12:14 | lazybot | tbaldridge: Uh, no. Why would you even ask? |
| 12:15 | seangrove | tbaldridge: Sorry, attempt at humor and and apparent miss |
| 12:15 | ticking | tbaldridge: nevertheless we can guarantee certain things for example, we guarantee delivery except for the n last send messages |
| 12:15 | tbaldridge | ticking: that's fine, but that doesn't match the core.async semantics. So now we're in a odd world where a thing looks like a channel, acts like a channel, but has different semantics. |
| 12:16 | tbaldridge | ticking: so that's my point. Either make everything unreliable (and have it fit with core.async semantics), or make it a completely different thing that isn't called a channel. |
| 12:17 | ticking | tbaldridge: no not really, say we have a simple send ack-receive protocol on top of websockets, we should be able to leave unreceived messages in the cannel |
| 12:18 | ticking | which is exactly core.asyc semantics, if its not removed it stays in the channel |
| 12:18 | seangrove | ticking: Isn't that something you could build on top of core.async as a library? |
| 12:18 | ticking | tbaldridge: if the connection breaks down, your application disgards that half filled but now closed channel |
| 12:19 | tbaldridge | ticking: so that's the problem. Core.async uses two-phase commit. And now you hit the messenger problem. You send "recv message", the remote end acks it, you never get the ack (connection dies). Now what? The remote end is processing the message, but it hasn't been removed from the queue. |
| 12:19 | ticking | seangrove: I'm definately not proposing this to be built into core.async |
| 12:20 | ticking | tbaldridge: when your websocket dies you can assume that the client dies as well |
| 12:20 | tbaldridge | ticking: really? Did it process the message? If the remote end was going to launch a missile, was the missile launched or not? |
| 12:21 | tbaldridge | it all comes down to this problem: http://en.wikipedia.org/wiki/Two_Generals'_Problem and it cannot be fixed, that's life. Network connections are unreliable. |
| 12:21 | ticking | tbaldridge: you are assuming that the two sides have the same authority |
| 12:21 | tbaldridge | The only way fix it is via idempotent messages. At that point reliability doesn't matter. |
| 12:21 | ticking | tbaldridge: with websockets they have not |
| 12:22 | tbaldridge | ? |
| 12:22 | ticking | tbaldridge: ther client is basically a slave, once the connection breaks down, it dies as well |
| 12:23 | tbaldridge | ticking: that's not exactly true. I worked on a system that used websockets. They auto-reconnect. I would often restart the server and never restart the client. The WS would reconnect and continue to operate as expected. |
| 12:24 | ticking | tbaldridge: that is a border case I'm happy to ignore |
| 12:25 | ticking | tbaldridge: in 99% of all web applications the server is assumed to be reliable while the client is not |
| 12:26 | ticking | tbaldridge: but even in your scenario the client basically becomes the classical server and vice versa |
| 12:27 | tbaldridge | I suppose, if you ignore certain physical constraints, it becomes easier to write code that works in the "normal" case. |
| 12:28 | tbaldridge | I would prefer to write systems that continue to work even if things aren't "normal". |
| 12:28 | ticking | tbaldridge: why do you treat websockets like udp, they are not |
| 12:29 | seangrove | ticking: With websockets, is there no possible way a message ACK can be lost? |
| 12:29 | seangrove | Is it guaranteed to be delivered even if it's dropped several times? |
| 12:29 | tbaldridge | ticking: It's just that the most common intersection of core.async and ws looks something like UDP. Stop trying to make things look like channels that aren't channels, and I don't have a problem. |
| 12:30 | ticking | seangrove: with every use case proposed so far, when the ack gets lost, the side which send the ack is dead |
| 12:30 | ticking | seangrove: so you never get a split brain situation |
| 12:31 | seangrove | Well, it's all over my head. But I suppose if you can get it to work, it would be interesting to see. |
| 12:32 | ticking | tbaldridge: udp looses messages between messages, websockets don't do that, so they are basically an unbounded chan which looses its messages when closed |
| 12:33 | ticking | tbaldridge: so an unbounded single consumer multiple producer channel |
| 12:33 | tbaldridge | ticking: unbounded chan that looses messages is nothing like CSP |
| 12:33 | tbaldridge | or looses on close that is. |
| 12:34 | ticking | tbaldridge: with buffersize 0 it is |
| 12:34 | tbaldridge | ticking: with buffersize of 0 you can't even enqueue unless a remote side will accept the message and then it always delivers the message (even if the channel is closed). |
| 12:37 | ticking | tbaldridge: 1 yes wheres the problem, 2 that sounds like a bug to me |
| 12:37 | tbaldridge | ticking: all I'm saying here, is that a lot of people have but thought into this, and there's a reason Kevin's system uses dropping-buffers. |
| 12:38 | tbaldridge | And with idempotent messages one can always add reliable messaging to something like Kevin's code. |
| 12:39 | ticking | tbaldridge: yeah but idempotency is a whole unnessecary can of worms |
| 12:40 | ticking | tbaldridge: look I agree 100% percent with you, when it comes to networking in general, just not for websockets^^ |
| 12:41 | dobry-den | (.toByteArray (biginteger x)) -> No method .toByteArray for clojure.lang.BigInt. (.toByteArray (.toBigInteger (biginteger x)) -> No method .toBigInteger for java.math.BigInteger. |
| 12:43 | tbaldridge | Websockets are not magic, they are network protocols. I don't see how it is any different |
| 12:47 | ticking | tbaldridge: in the way one client's existence depends on the existence of the connection |
| 12:51 | tbaldridge | ticking: I suppose you could get by with saying "if the network connection dies you must restart your app". Although for most systems I work on that would be a painful requirement. |
| 12:52 | tbaldridge | ticking: switch off the VPN, reload your app. Switch from Wifi to hardline, restart your app. Someone steps in front of your flaky wifi connection, restart the app. |
| 12:53 | ticking | tbaldridge: yes to all but the last one ^^ |
| 12:53 | tbaldridge | Like I said, redefine the parameters of the problem, and I suppose something like this could work. But I'd hate to base an entire app on such assumptions. |
| 12:55 | tbaldridge | A better idea, imo is to use unreliable semantics, then use core.async to layer reliable semantics on top when you need them. Mix in a bit of idempotent-ency where needed and that sounds like a much better solution, imo. |
| 13:02 | seangrove | bitemyapp: You remember at the prismatic meetup they talked about marquee they would insert in code in different sections? I was wondering if there's actually a term for that |
| 13:02 | technomancy | page breaks or gtfo |
| 13:02 | seangrove | technomancy: in source code? |
| 13:03 | technomancy | seangrove: hells yea |
| 13:04 | technomancy | they're just whitespace |
| 13:13 | arrdem | technomancy: what exacly does that generate in an editor? |
| 13:13 | arrdem | * how does it render |
| 13:13 | technomancy | arrdem: emacs renders it as ^L |
| 13:15 | technomancy | supposedly there are tricks to get it to render like an <hr> |
| 13:15 | technomancy | hmm; I should set that up |
| 13:16 | seangrove | technomancy: Please share if you find it |
| 13:16 | arrdem | ; C-79 RET - |
| 13:16 | arrdem | :P |
| 13:17 | coventry | http://www.emacswiki.org/emacs/PageBreaks |
| 13:17 | arrdem | (inc coventry) |
| 13:17 | lazybot | ⇒ 3 |
| 13:17 | technomancy | emacs also has bindings for jumping forward and backward by pages |
| 13:18 | arrdem | technomancy: I know Emacs can navigate by pages, I was curious if emacs did whitespace padding to fit _only_ one page-break deliminated hunk on the screen |
| 13:19 | technomancy | arrdem: nah |
| 13:20 | ticking | tbaldridge: btw, you convinced me to go with reconnect-ability and unreliability, but I still 90% of all code will ignore the latter |
| 13:20 | ticking | *think |
| 13:23 | technomancy | I can confirm that M-x package-install page-break-lines works |
| 13:23 | coventry | I'm wondering whether it would be a good idea for the compile/eval functions in Compiler.java to wrap any exceptions from calls to macroexpand* in CompilerExceptions. Would make it easier to find errors by providing source location info. Anyone seen prior discussion of ideas like this? |
| 13:35 | coventry | I guess the try/catch in AnalyzeSeq gets most of these cases already, actually. |
| 14:49 | metactus | is there a way to recur with a different arity if the function is overloaded? |
| 14:50 | amalloy | metactus: not tail-recursively (ie, with recur), but you can just call the function again, by name |
| 14:51 | jared314 | what about trampoline? |
| 14:51 | amalloy | completely irrelevant |
| 14:52 | jared314 | amalloy: ouch, just trying to learn here |
| 14:52 | metactus | amalloy: that worked, thanks |
| 14:52 | mdrogalis | That was a bit uncalled for. :/ |
| 14:52 | AimHere | If you call the function again, that will eat up the stack though, won't it? |
| 14:53 | coventry | trampoline actually seems like a sensible solution, if the different-arity calls turn out to overflow the stack. |
| 14:56 | amalloy | coventry: (defn foo ([x] x) ([x y] (trampoline #(foo x)))) doesn't use up any less stack space; you have to rewrite other related functions in order to get a net benefit from the trampoline |
| 14:59 | mikerod | Would AOT compilation be to blame (or a suspect) for slower start up times of an uber-jar that has the clojure jar along with a small program written in clj? |
| 14:59 | mikerod | With verbose output on java jar, it seems that a lot of classes are being loaded upfront, is this expected? |
| 15:00 | technomancy | mikerod: I've never heard of AOT being anything but a help for startup time |
| 15:01 | mikerod | technomancy: that's what I was thinking |
| 15:02 | coventry | amalloy: Yes, it's pointless to transfer through a trampoline call. It might make sense in the context of a trampoline for foo to return something like #(if pred (foo x) (foo x y)), though. |
| 15:03 | bitemyapp | seangrove: the marquee thing, was this one of the lightning talks or a Prismatic thing? |
| 15:03 | coventry | s/transfer/recur/ |
| 15:07 | dnolen | yedi: not sure when I'll have time to look at your app, IMO you should try to recreate the problem with a simpler app with no deps besides CLJ and CLJS. |
| 15:29 | dobry-den | In Java, if you pass `array1` into (fn [array] array[0] = "foo"), does that mutate array1 or just a copy of it? |
| 15:30 | ndp | As with most things in Java, array parameters are pass-by-reference so that will mutate array1 in place. |
| 15:31 | dobry-den | ndp: thanks |
| 15:31 | dobry-den | that's really confusing |
| 15:33 | ndp | What's really annoying coming from Clojure is how the Guava Collections libraries handle sorting - they generally sort in place. It really messes with my Zen thing. |
| 15:33 | cmajor7 | need an opinion: need to walk a sequence until something is found. "map/reduce/filter" walk the sequence in full. "loop" is "somewhat too imperative" :), maybe "while".. but also feels very similar to loop. what do you guys think? |
| 15:33 | coventry | cmajor7: check out (reduced) for stopping a reduce loop. |
| 15:34 | hyPiRion | map and filter doesn't walk a sequence in full. |
| 15:34 | ndp | filter returns a lazy seq so you can stop iteration when you find the element |
| 15:34 | dobry-den | cmajor7: (first (filter pred coll)) stops at first match becuase filter is lazy |
| 15:35 | llasram | mod chunking |
| 15:35 | Morgawr | cmajor7: maybe take-while? depends on what you need |
| 15:35 | amalloy | also (some is-this-the-thing? coll) |
| 15:36 | amalloy | well, i guess that returns a boolean, so is only what you want if you just want to know whether something is there, rather than what is there |
| 15:36 | cmajor7 | coventry: I think that is exactly what was missing.. reduced was added in 1.5, missed it. |
| 15:36 | dobry-den | llasram: are 32 realized at a time |
| 15:36 | Raynes | gf3: You're unoriginal and that's bad and you should feel bad. |
| 15:37 | llasram | dobry-den: That's how the current implementation works, yeah |
| 15:37 | hyPiRion | &*clojure-version* |
| 15:37 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 15:37 | dobry-den | ndp: ive had my clojure blinders on for so long that the ruby version would also mutate in place. i remember now that it was what inspired me to try clojure after working on a large codebase. |
| 15:37 | cmajor7 | amalloy: some is good too, I am doing ternary tree breadth first search.. (until I find something) so on each level I do (3^level) things.. hence wanted to stop somewhere.. |
| 15:38 | gf3 | Raynes: I used to think I was too hip to be unoriginal |
| 15:38 | llasram | Raynes: Yeah, what's up with lazybot? Poor, sad, old lazybot |
| 15:38 | gf3 | Raynes: Now I just have too many pairs of tight pants |
| 15:38 | Raynes | lazybot: kill |
| 15:38 | lazybot | KILL IT WITH FIRE! |
| 15:38 | Raynes | gf3: You should use snapchat. |
| 15:38 | gf3 | Raynes: I am a snapchat machine |
| 15:38 | gf3 | Raynes: Add me: LOLgianni |
| 15:39 | bitemyapp | gf3: if I add you, do you promise to send pictures of the puppy? |
| 15:40 | gf3 | bitemyapp: Sadly I'm on the other side of Canada now :( |
| 15:40 | gf3 | bitemyapp: But I can send you cute-as-fuck cat snaps |
| 15:40 | bitemyapp | gf3: deal. |
| 15:40 | gf3 | bitemyapp: Also shitty dance moves and really horrible selfies |
| 15:41 | gf3 | Raynes: Also FWIW I agree with you, re: beard |
| 15:41 | cmajor7 | dobry-den (and others): yep, (first (filter pred..)) will also "do it" since map/reduce/filter are in fact lazy (although by 32). cool, now I have plenty to choose from, although "reduced" sounds great to try, since it is all new and shiny :) |
| 15:41 | llasram | cmajor7: `reduce` is not lazy |
| 15:41 | llasram | FYI |
| 15:41 | Raynes | gf3: Fight the power! |
| 15:42 | Raynes | bitemyapp, gf3: Funfact: I walked past the snapchat headquarters on the Venice boardwalk about two weeks ago. Didn't even realize it was there until I saw the big ol' snapchat icon. |
| 15:42 | hyPiRion | huh what beard |
| 15:42 | gf3 | Raynes: And then it disappeared after 10s |
| 15:42 | pandeiro | should async's go blocks work as expected when used from the browser REPL? or only in pre-compiled code? |
| 15:43 | bitemyapp | Raynes: I saw when I visited you in LA |
| 15:43 | bitemyapp | saw it* |
| 15:43 | cmajor7 | llasram: but "reduced" will stop it whenever "I want" e.g. "found" |
| 15:43 | cmajor7 | ,(doc reduced) |
| 15:43 | bitemyapp | their beachhouse is the best use of VC money I've ever seen |
| 15:43 | clojurebot | "([x]); Wraps x in a way such that a reduce will terminate with the value x" |
| 15:43 | Raynes | gf3: lol |
| 15:43 | llasram | cmajor7: Yes. Doesn't make it lazy though :-) |
| 15:43 | cemerick | dnolen: On cljs master, (rseq []) => (); Clojure returns nil for the same. Do you want a ticket for that? |
| 15:44 | cmajor7 | llasram: oh, you are referring to my statement of it being lazy. yes, it is not. thx |
| 15:45 | bitemyapp | hrm. Creepy. My landlord has a snapchat account that starts with "PicChic" |
| 15:45 | dnolen | cemerick: sure, preferable that the patch follow any performance related optimizations present in Clojure |
| 15:45 | dnolen | cemerick: not saying there are any (haven't looked myself) |
| 15:46 | cemerick | dnolen: Sure; I'm personally more interested in correctness/compat at the moment, but I'll take a look. |
| 15:49 | dnolen | cemerick: ok I took at peek, I want a fast patch for that just like Clojure + tests |
| 15:49 | dnolen | cemerick: implementers of IReversible need to do the right thing. |
| 15:49 | cemerick | dnolen: sorted-map is correct, which is something |
| 15:54 | dnolen | cemerick: as long you're there note you can type-hint the return value of rseq as ^seq, and type-hint coll as ^not-native in this case. |
| 15:58 | cemerick | dnolen: OK, "fast patch"? The fix is to simply drop the else branch from -rseq @ 3315, no? (and 707 for that matter) |
| 15:59 | dnolen | cemerick: sounds good to me, I just didn't want a seq or empty? call in rseq |
| 15:59 | cemerick | oh, sure |
| 15:59 | cemerick | I'm going to have to read the compiler a bit to really know what the ^seq and ^not-native hints are for. Will take a closer look at that later. |
| 16:00 | cemerick | I mean, I can guess, but that's probably not a good idea. :-) |
| 16:00 | dnolen | cemerick: ^seq is just to propagate information so we don't have truth calls around conventions like |
| 16:00 | dnolen | (if (seq foo) ...) |
| 16:00 | dnolen | or |
| 16:00 | dnolen | (let [s (seq foo)] (if s ...)) |
| 16:00 | dnolen | ^not-native is to remove protocol indirection |
| 16:00 | cemerick | dnolen: so ^seq guarantees not-empty? |
| 16:00 | dnolen | and get direct dispatch |
| 16:01 | dnolen | cemerick: no in this case ^seq just means it's a ^seq value, nil or a seq |
| 16:01 | cemerick | ok |
| 16:01 | cemerick | dnolen: *realized*, then? |
| 16:02 | dnolen | cemerick: nope, it's like the ^boolean type hint |
| 16:02 | dnolen | it's really just for (if x ...) |
| 16:02 | cemerick | dnolen: then how does it help you avoid (seq x)? |
| 16:02 | cemerick | i.e. if it's a lazy, empty seq |
| 16:02 | dnolen | cemerick: sorry I think you're getting confused what it's for |
| 16:03 | cemerick | heh |
| 16:03 | cemerick | almost surely |
| 16:03 | dnolen | (defn ^seq rseq [coll] ...) |
| 16:03 | cemerick | Need to read some internals :-) |
| 16:03 | dnolen | this communicates to the compiler that the result can be tested with (if x ...) |
| 16:03 | dnolen | w/o needed to check for stupid JS false-y values |
| 16:03 | dnolen | needing |
| 16:04 | dnolen | i.e 0 and the blank string |
| 16:04 | cemerick | dnolen: ok, so it's more of a host mask than actually statically guaranteeing anything about (seq x) |
| 16:04 | tos9 | /qui |
| 16:05 | dnolen | cemerick: yep, only about performance same as ^boolean |
| 16:05 | clojurebot | Excuse me? |
| 16:06 | cemerick | dnolen: and will ^not-native on rseq's `coll` arg emit a warning on e.g. `(rseq (js/Array.))`? |
| 16:06 | dnolen | cemerick: no, runtime exception just like Clojure |
| 16:07 | dnolen | cemerick: none these type hints are about verification - only optimizations hints to the compiler |
| 16:08 | dnolen | cemerick: though later down the line when we have more inference in the compiler - I would like to start emitting warnings |
| 16:11 | pandeiro | dnolen: should go blocks work from the browser repl or just in pre-compiled code? |
| 16:12 | dnolen | pandeiro: I don't see why it would make a difference, though doing go block at the REPL might get hairy with running event loops |
| 16:12 | dnolen | er go loops |
| 16:12 | pandeiro | dnolen: yeah i am just trying to recreate your examples (the simplest ones) from your blog |
| 16:13 | pandeiro | and what i notice is that (<! ...) doesn't seem to work |
| 16:13 | pandeiro | stuff gets put! on channels fine and the go block itself returns some kind of object with dirty puts et al |
| 16:14 | dnolen | pandeiro: I haven't tried core.async w/ brepl so I can't say definitively but I'd be very surprised. |
| 16:14 | pandeiro | but the special <! take operation doesn't do anything |
| 16:14 | dnolen | pandeiro: <! only works in a go block |
| 16:14 | pandeiro | right i am evaling the whole form |
| 16:14 | pandeiro | (go (let ... (while true ... (<! ...)))) |
| 16:15 | dnolen | pandeiro: but what channel are you reading from and is someone else *already* reading from it |
| 16:15 | dnolen | pandeiro: which is what I alluded to above, running go loops and REPL interaction is going to be very tricky |
| 16:15 | pandeiro | okay... |
| 16:16 | pandeiro | i defined a listen exactly like yours, with no callback but returning a channel |
| 16:16 | pandeiro | then i do (let [c (chan)] (go ...)) and use that very chan |
| 16:16 | pandeiro | even that first use would have issues? |
| 16:17 | pandeiro | sorry (let [c (listen ...) ] above |
| 16:19 | dnolen | pandeiro: if you evaluate the entire let block should be OK |
| 16:19 | pandeiro | dnolen: i am using a pre-compiled cljs, that wouldn't be an issue though i imagine |
| 16:19 | pandeiro | ( cljs i am using is this: https://gist.github.com/pandeiro/6628294/raw/clojurescript.plus.js ) |
| 16:20 | dnolen | pandeiro: I would not expect that to work at all |
| 16:20 | noncom | i know i can destuct maps in function arguments. but can i destruct nested maps? |
| 16:20 | dnolen | pandeiro: core.async now needs 1934 |
| 16:20 | pandeiro | dnolen: i have a more recent build locally |
| 16:21 | pandeiro | dnolen: as for not working, every other lib seems to |
| 16:21 | pandeiro | it lets me start up a browser repl server and have cljs anywhere i inject a bookmarklet, which is fun |
| 16:21 | dnolen | pandeiro: because you're getting lucky |
| 16:21 | dnolen | pandeiro: in general you cannot rely on this behavior |
| 16:21 | dnolen | pandeiro: core.async is perf sensitive and relies on 1934 |
| 16:22 | dnolen | changes in 1934, I mean |
| 16:22 | pandeiro | dnolen: ah yeah no the build i am using i 1934 |
| 16:22 | pandeiro | the github one is old |
| 16:22 | pandeiro | i have another local version |
| 16:22 | pandeiro | but you meant 'getting lucky' about the pre-built cljs in general? |
| 16:22 | dnolen | pandeiro: yes |
| 16:22 | pandeiro | working with the browser repl / bookmarklet? |
| 16:22 | dnolen | pandeiro: you must build everything together |
| 16:22 | pandeiro | why is that lucky? |
| 16:22 | ianeslick | @cemerick Do you have a second to chat about immutant logging? |
| 16:22 | dnolen | pandeiro: because the compiler could change |
| 16:22 | pandeiro | ah |
| 16:22 | dnolen | calling conventions and who knows what else |
| 16:23 | ianeslick | @cemerick There is an interesting issue regarding making dynamic logging changes 'sticky' |
| 16:23 | pandeiro | but *if it built* |
| 16:23 | cemerick | ianeslick: oh? |
| 16:23 | dnolen | pandeiro: yes if everything is built with the same version of the compiler - this approach could work - though I don't see the point. |
| 16:24 | ianeslick | @cemerick If I call .setLevelName on the result of a .getLogger call it doesn't stick. But if the Logger from getLogger is printed to the repl, then I call .setLevelName, it works. Feels like something somewhere is lazy |
| 16:24 | dnolen | bbiab |
| 16:24 | ianeslick | @cemerick I can't figure out what the repl is doing that causes the logger (a new logger) to be persisted. |
| 16:25 | ta479 | Can anyone explain this complicated type signature to me: http://pastebin.com/HfKvqQLg |
| 16:26 | cemerick | ianeslick: well, j.u.l.Loggers don't have much smarts to them, so I'd doubt there's laziness around |
| 16:26 | ta479 | it seems unnecessarily complicated compared to haskell's fmap :: (a -> b) -> f a -> f b |
| 16:26 | cemerick | ianeslick: are you doing something similar to my gist? |
| 16:26 | ianeslick | Yes |
| 16:27 | ianeslick | Yes, I didn't see anything walking through the code |
| 16:27 | brehaut | ta479: if clojure's map and haskell's fmap did the same thing, then saying map's type is unnecessarily complex would be sensible. but they dont |
| 16:27 | cemerick | ianeslick: I'm still on immutant 1.0.1 I think, if that matters *shrug* |
| 16:27 | ianeslick | Probably not, I don't think the log manager was updated. |
| 16:28 | ta479 | brehaut: the only difference I see is variadic parameters |
| 16:28 | brehaut | ta479: clojure's map is only fmap over sequences, not arbitrary structures, but it is also also zip due to varargs |
| 16:28 | ianeslick | I can log against the logger, but the log level doesn't stick until I allow the logger to be printed by the REPL. Very odd! |
| 16:29 | brehaut | ta479: also, typed clojures type system is different to haskells. it can encode some things that are difficult in haskell, eg non-empty sequences |
| 16:29 | cemerick | ianeslick: There's absolutely either a race condition or a module init order issue that forces the application of that namespace at the *end* of my immutant.init. Are you doing that? Even if you are, it may be that we're forcing the loading of modules in different orders, at different times, etc. |
| 16:30 | ianeslick | @cemerick This phenomenon happens after load time; I use XML to set a default state, then am writing some REPL tools to change settings during development. e.g. this works: (switchboard.utils.sys/set-logger-level (str *ns*) :debug) |
| 16:30 | ianeslick | But this has no effect: (do (switchboard.utils.sys/set-logger-level (str *ns*) :debug) nil) |
| 16:31 | ianeslick | (defn set-logger-level |
| 16:31 | ianeslick | "Sets the log level for a namespace" |
| 16:31 | ianeslick | [namespace level] |
| 16:31 | ianeslick | (let [level (.toUpperCase (name level))] |
| 16:31 | ianeslick | (doto (get-logger namespace) |
| 16:31 | ianeslick | (.setLevelName level) |
| 16:31 | ianeslick | (.log (Level/parse level) |
| 16:31 | ianeslick | (str "Enabling logging of " *ns* " at " level)) |
| 16:31 | ianeslick | (.getLogContext)))) |
| 16:31 | ianeslick | Sorry, should have been a gist, but it's small |
| 16:31 | brehaut | ta479: keep in mind, haskell's library is developed in sync with its type system. clojure's library develops in isolation and the type system must then provide types for those idioms. it does result in more complex types for core functions due to their flexibility. |
| 16:31 | ianeslick | In both of those cases, the enable logging statement is issued but only in the 'printed at the repl' case does it persist. |
| 16:33 | cemerick | ianeslick: how are you starting your REPL? |
| 16:33 | ianeslick | It's an nrepl attached to immutant. |
| 16:33 | cemerick | ianeslick: right, but: are you letting immutant start it, or are you controlling it? |
| 16:34 | ta479 | brehaut: so is it possible to make a much slimmer type signature for a custom map and lose some flexibility? |
| 16:34 | brehaut | ta479: yes |
| 16:34 | brehaut | ta479: but why would you |
| 16:34 | ianeslick | Letting immutant start the repl server. |
| 16:35 | ianeslick | Then connect from emacs |
| 16:35 | ianeslick | Same effect occurs if I use nrepl-inspect instead of just printing it. |
| 16:37 | noncom | can i do a nested destructuring of a nested map? |
| 16:37 | cemerick | ianeslick: so, I don't have any theories re: the effect of the REPL on the 'stickiness'. I'm willing to bet it's a misattribution, and you're just getting the "correct" logger sometimes, sometimes not (due to classloader wonkiness). Does your logging config work properly when applied at the end of your immutant.init? |
| 16:38 | amalloy | noncom: certainly, why not? |
| 16:38 | noncom | amalloy: could you show how it looks like? i just can't guess.. |
| 16:39 | amalloy | noncom: do you know how to destructure a map? it's just applying further destructuring to the "names" of the locals you bind |
| 16:39 | noncom | (defn f [& {:keys [a b c]}] ...) |
| 16:40 | noncom | but how i destructure a, b or c? in a separate let? |
| 16:40 | amalloy | noncom: that is shorthand for a more general destructuring |
| 16:40 | amalloy | &(let [{{:keys [first]} :name} {:name {:first "john" :last "smith"}}] first) |
| 16:40 | lazybot | ⇒ "john" |
| 16:41 | noncom | aha.. i see... is it possible to take it to arguments destructuring or do i have to use this full form? |
| 16:42 | hyPiRion | That doesn't make sense |
| 16:42 | noncom | what do you mean? |
| 16:43 | hyPiRion | If you have {:keys [{...}]}, then what does {...} refer to? |
| 16:43 | hyPiRion | (If I read you correctly, I am not sure I am) |
| 16:43 | hyPiRion | You can use the :as directive inside a map to keep it though. |
| 16:44 | noncom | yeah, and that is the same kind of problem that i originnaly stepped into. thought maybe there is a way. also didn't know about what amalloy showed - looks cool |
| 16:44 | noncom | yeah, so an :as or further lets are the way |
| 16:45 | hyPiRion | ,(let [{{:keys [first] :as person} :name} {:first "john" :age 21}] [first person]) |
| 16:45 | clojurebot | [nil nil] |
| 16:45 | amalloy | noncom: you should practice destructuring maps without using :keys |
| 16:45 | hyPiRion | well obviously I forgot something there |
| 16:45 | hyPiRion | ,(let [{{:keys [first] :as person} :person} {:person {:first "john" :age 21}}] [first person]) |
| 16:45 | clojurebot | ["john" {:age 21, :first "john"}] |
| 16:45 | amalloy | the convenient shortcut :keys seems to be causing you to not understand the more-general things being pointed out to you |
| 16:46 | noncom | amalloy: how do i do destructuring without :keys? the "let" examples above use :keys |
| 16:46 | hyPiRion | ,(let [{{first :first :as person} :person} {:person {:first "john" :age 21}}] [first person]) |
| 16:46 | clojurebot | ["john" {:age 21, :first "john"}] |
| 16:46 | amalloy | $google clojure destructure map |
| 16:46 | lazybot | [Jay Fields' Thoughts: Clojure: Destructuring] http://blog.jayfields.com/2010/07/clojure-destructuring.html |
| 16:47 | noncom | ah right.. |
| 16:47 | noncom | thanks guys, you made good examples! |
| 16:47 | noncom | so no way to destructure a nested map right inside function params declaration? |
| 16:48 | noncom | oh sorry |
| 16:48 | noncom | found it in the jayfields examples |
| 16:48 | noncom | ok, i'll go practive |
| 16:48 | noncom | *practice |
| 16:52 | ta479 | brehaut: because a lot of the higher order function types are something I can't imagine myself writing in my own code |
| 16:53 | ta479 | HOD types for clojure.core functions |
| 16:53 | ta479 | just doesn't seem practical |
| 16:53 | brehaut | ta479: why would you be writing types for core? |
| 16:54 | ta479 | no, types for my own HOD functions |
| 16:54 | ta479 | HOF* |
| 16:55 | brehaut | ta479: thats entirely different to writing types for functions in core |
| 16:55 | brehaut | ta479: in particular, you probably arent supporting a wide range of interfaces |
| 16:56 | ianeslick | @cemerick I can try that, but I'm applying it interactively so I'm unclear how within the same repl session the class loader environment would change. I'm only evaluating the loggers for actively loaded classes, the repl is in the loaded class's namespace, and I'm making those two calls one of which enables the logger and one of which doesn't. |
| 16:56 | ianeslick | @cemerick The misattribution is likely, but I can't figure out what else I might attribute the difference to |
| 16:57 | technomancy | ianeslick: this isn't twitter; easy with the derefs |
| 16:57 | ianeslick | @oops |
| 16:57 | technomancy | you'll cause his transactions to retry |
| 16:57 | ianeslick | #oops? |
| 16:57 | ianeslick | IRC #noob |
| 16:57 | ianeslick | I always forget the conventions... |
| 16:57 | mtp | this isn't twitter |
| 16:58 | ianeslick | mtp: I'm being facetious |
| 16:58 | mtp | hard to tell :) |
| 16:58 | ianeslick | Although I did forget the '@name' vs. name: to call out someone specifically. |
| 17:00 | cemerick | ianeslick: Yeah, it doesn't make sense on the face of it. I just have a hard time believing that REPL printing can affect the state of a Logger. |
| 17:01 | ianeslick | cemerick: I hear you and agree. I'll noodle on it some more. |
| 17:11 | sveri | hi, do you know a place where people can code together online? |
| 17:12 | TimMc | Like a multiplayer web IDE? |
| 17:12 | sveri | exactly |
| 17:12 | technomancy | there is https://syme.herokuapp.com that I made |
| 17:12 | sveri | i often thought that it would be more fun to solve puzzles together or work on a project |
| 17:13 | sveri | technomancy: ah, i see, thats a nice start |
| 17:13 | sveri | but somehow the community is missing |
| 17:14 | technomancy | sveri: right, you need to arrange beforehand with whoever you're collaborating with |
| 17:14 | technomancy | I find IRC to be a great medium for that =) |
| 17:14 | sveri | yea thats right, partially |
| 17:14 | sveri | but imagine something like a chat server |
| 17:14 | sveri | you can scroll coding rooms |
| 17:15 | sveri | and people sit and talk about something, everybody can join |
| 17:15 | sveri | for instance if you dont wanna hack on something but like to watch somebody hack |
| 17:16 | technomancy | that'd be cool |
| 17:16 | technomancy | could just use a freenode channel though |
| 17:17 | sveri | yea, but i know a lot of coders that dont use irc and watch me like a maniac when i tell them i ask questions in the irc from time to time |
| 17:17 | technomancy | invite them in; we won't bite |
| 17:17 | technomancy | well except for bitemyapp |
| 17:17 | sveri | :D |
| 17:17 | sveri | i know |
| 17:18 | sveri | but its almost always like: "IRC? does it still exist?" :D |
| 17:18 | TimMc | Man, if I didn't have IRC, I'd be like "What is computer? How does Clojure?" |
| 17:18 | grncdr | sveri: there's also https://friendco.de/ that might interest you |
| 17:18 | TimMc | ...although StackOverflow is becoming a pretty amazing resource. |
| 17:19 | sveri | grncdr: thats almost what i am looking for, but again not open enough |
| 17:20 | sveri | hm, dismissing the fact that the try it now button isnt working :D |
| 17:21 | grncdr | sveri: yeah I have no affiliation with it |
| 17:22 | grncdr | played around a bit when it was announced and moved on |
| 17:22 | sveri | grncdr: yea, was no offense, good to know that something like that exists |
| 17:30 | musicalchair | sveri: I like your idea; I've been thinking in a similar vein or two recently |
| 17:30 | TimMc | Hmm, someone was talking about a collaborative editing thing recently... |
| 17:35 | bhenry | what does it mean when a namespace compiles fine in the repl, but when trying to run `lein ring server` that same namespace won't compile because it can't resolve a particular symbol from another namespace? |
| 17:37 | technomancy | bhenry: you deleted a var or created something in the repl that doesn't exist on disk |
| 17:38 | bhenry | technomancy: it's a brand new nrepl session in emacs and all i do is C-c-k within the namespace in question. it compiles fine. |
| 17:38 | technomancy | oh, no idea then. check to see if it works from lein run? |
| 17:38 | technomancy | I don't use lein-ring |
| 17:41 | technomancy | IMO sticking with lein run and lein repl is a lot simpler |
| 17:42 | bitemyapp | bhenry: what symbol, anyway? |
| 17:42 | bitemyapp | bhenry: lein ring is mostly handling auto-reloads which is basically just some middleware and #' of the app var. |
| 17:43 | bitemyapp | it does some other things like designate takedown/init functions but I think realistically you don't want to rely on the magic and instead just understand what's going on. |
| 17:45 | bhenry | bitemyapp: it's a symbol in my own namespace. but it compiles from the repl, and not from the lein ring server command. it breaks in the lein ring server command after i switch from clojure 1.4 to clojure 1.5, but in the repl, it compiles with either dependency |
| 17:45 | hiredman | bhenry: have you cleared out target/classes/? |
| 17:46 | bhenry | not if lein clean doesn't do that. |
| 17:46 | bhenry | hiredman: ^^ |
| 17:47 | hiredman | I dunno, if the directy exists delete it |
| 17:47 | bhenry | hiredman: target/classes is empty |
| 17:47 | hiredman | bhenry: what symbol is it? |
| 17:48 | hiredman | bhenry: how are you loading code in the repl? |
| 17:48 | hiredman | bhenry: do you have a pastebin of the stacktrace? |
| 17:49 | bitemyapp | bhenry: run lein clean, refheap the code, include the stacktrace. |
| 17:54 | bhenry | bitemyapp: here is the code: https://gist.github.com/bhenry/b0b77e4fab6b862b728f here is the stack: https://www.refheap.com/e0dc2bb00296b669e454871db |
| 17:55 | bhenry | if i C-c-k (nrepl in emacs) inside of either of those files, they compile fine with either version of clojure. but that stacktrace happens in the terminal with 1.5.1 but works fine with 1.4.0 |
| 17:56 | bitemyapp | bhenry: show me a project.clj |
| 17:56 | bitemyapp | I need version numbers. |
| 17:56 | bitemyapp | and lein ring config. |
| 17:57 | hiredman | ah, you shouldn't do that |
| 17:58 | hiredman | but why it is doing that, I'm not sure, I bet lein ring is swallowing the exception loading *.config |
| 17:58 | hiredman | you should use clojure.java.io/resource |
| 17:58 | bhenry | bitemyapp: https://gist.github.com/bhenry/b0b77e4fab6b862b728f same link, but with new stuff. |
| 17:59 | bitemyapp | bhenry: that's not how you should do a config. |
| 17:59 | bitemyapp | bhenry: use this: https://github.com/weavejester/environ/ |
| 17:59 | bitemyapp | bhenry: make it a plain clojure file, use whatever is in the environment, fallback to defaults. |
| 18:00 | bitemyapp | and hiredman is right, use cji/resource when you do need to load files, but you're doing configuration in general wrong anyway. |
| 18:00 | technomancy | https://twitter.com/mikerubits/status/392748169735323648 |
| 18:01 | bitemyapp | technomancy: <3 |
| 18:02 | bhenry | it's fair to have your opinion about something. i didn't write that, so i will not change it. something tells me that it's not the cause of my problem, though. |
| 18:03 | bhenry | if i did anything that expectedly only works in 1.4.0 and not 1.5.1 please let me know what it is (our other project on 1.5.1 has its configs set up the same way, and it works fine) |
| 18:05 | hiredman | bhenry: my guess is both your calls to slurp are throwing exceptions because the working directory of lein ring server isn't what you expect it to be, and lein ring server is somehow masking those exceptions |
| 18:05 | bitemyapp | bhenry: if something fails to compile and load, then the symbol referred from it will fail to exist. |
| 18:05 | bitemyapp | and what hiredman just said. |
| 18:05 | bitemyapp | un-jankifying your config solves this problem too. |
| 18:06 | hiredman | put in some printlns to verify the exception, then switch to io/resource |
| 18:07 | satshaba2 | ok I want to use typed clojure |
| 18:08 | bitemyapp | satshaba2: cool! |
| 18:08 | satshaba2 | but when I try to only type 1 function |
| 18:08 | bitemyapp | satshaba2: http://nathanic.org/posts/2013/typed-clojure-tour/?utm_source=dlvr.it&utm_medium=twitter |
| 18:08 | satshaba2 | it complains when it checks the rest |
| 18:08 | bitemyapp | satshaba2: you generally have to be explicit about typing everything in core.typed |
| 18:08 | satshaba2 | haha, yes I've been reading it |
| 18:08 | satshaba2 | huh ok. So it's all or nothing? |
| 18:08 | satshaba2 | at what granularity? |
| 18:08 | satshaba2 | name space? |
| 18:09 | dnolen | satshaba2: yes |
| 18:09 | bitemyapp | satshaba2: technically namespace, but you'll have to ^:no-check a bunch of stuff for it not to spread outside that namespace. |
| 18:10 | satshaba2 | OK cool! thanks! |
| 18:12 | coventry | That blog post makes typed clojure look like a lot of work. The type for map is longer than a naive implementation of the function, for instance. Is it paying off for people. |
| 18:12 | coventry | ? |
| 18:13 | bitemyapp | coventry: it's tedious compared to what I'm used to, but I'm still interesting in using it more. |
| 18:13 | bitemyapp | coventry: def-alias goes a long way too. |
| 18:13 | bhenry | bitemyapp: it correctly prints the result of the slurp statement right in the terminal from which i run `lein ring server` |
| 18:15 | bhenry | bitemyapp: i updated the gist with how i printed it. i can't see an explanation why it is running that just fine, but not finding it from crypto. |
| 18:19 | bitemyapp | bhenry: you shouldn't really be def'ing file operations like that either, should be a function or memoized fn. |
| 18:19 | mikerod | maven-shade-plugin changed all the timestamps in my uber jar. This caused all AOT clojure files to be re-compiled at startup. Made start up very slow. boo |
| 18:20 | mikerod | This took me a while to discover what the problem was. |
| 18:20 | bhenry | i've got guys that do this. all i'm trying to do is update dependencies. and don't know how to track down why this doesn't work in 1.5.1 but it works in 1.4.0 without issue. |
| 18:20 | bitemyapp | mikerod: nasty. |
| 18:22 | mikerod | bitemyapp: Yeah, I ended up using lein uberjar and didn't have the same issue. |
| 18:22 | mikerod | Then I noticed the timestamps. |
| 18:25 | TEttinger | bhenry, you saw that analytics.engine uses clojure 1.5.1 as a dep right? |
| 18:26 | bhenry | YES! that's why i need to get the project working with 1.5.1. we are beginning the move to make this standalone project a part of analytics-engine. |
| 18:26 | bhenry | TEttinger: ^ |
| 18:26 | TEttinger | ah ok |
| 18:27 | bhenry | when I uncomment the 1.4.0 line in the project.clj everything goes back to working just fine. |
| 18:28 | TEttinger | did you link the full stacktrace yet? |
| 18:55 | glosoli | nrepl was so awesome until some retard started renaming :) |
| 18:56 | bitemyapp | glosoli: as much as I dislike the unnecessary rename, said retard is also maintaining your tools for you :) |
| 18:57 | glosoli | Just to make clear, and not to sound disrespectful, but is it maintenance when all he does now is fixing after shit made up by renaming ? |
| 18:58 | mgaare | if you liked nrepl 0.2, you can get it from marmalade and keep using that |
| 18:59 | glosoli | mgaare: Kinda looking forward to Cursive... :) |
| 18:59 | technomancy | nrepl.el is the new slime! |
| 19:00 | mgaare | glosoli: what is that? |
| 19:00 | TimMc | sveri: http://www.pairprogramwith.me/ has a big ol' list of pairing tools and services. |
| 19:00 | technomancy | which is to say, the new thing that will confuse newcomers as they try to navigate outdated documentation |
| 19:00 | glosoli | mgaare: IDE for Clojure :) based on Intellij :) |
| 19:00 | glosoli | technomancy: But you know what's cool now? at least Newcomers won't confuse the meaning of nrepl-emacs and nrepl lol |
| 19:01 | glosoli | sure they willl... |
| 19:01 | mgaare | ah, ok |
| 19:01 | technomancy | glosoli: I'm just glad I'm not stuck maintaining it |
| 19:02 | glosoli | technomancy: Yeah :) |
| 19:02 | mgaare | I don't mind the new name |
| 19:04 | bitemyapp | I'm ambivalent but think it's silly. |
| 19:04 | bitemyapp | it'll be nice once the dust clears just on account of being less ambiguous as to which component of nrepl one is referring to. |
| 19:04 | bitemyapp | the server or the client on Emacs. |
| 19:05 | bitemyapp | technomancy: I've had some people ask that I move faster on grom because they find grench too annoying to install btw. |
| 19:05 | technomancy | grom is your haskell one? |
| 19:05 | bitemyapp | technomancy: aye |
| 19:06 | technomancy | bitemyapp: is it the libffi or libreadline dependency that's annoying? or are people compiling the whole thing? |
| 19:06 | bitemyapp | technomancy: compiling the whole thing with opam, I think they find having to install all that obnoxious. |
| 19:06 | technomancy | why not use the bins? |
| 19:06 | bitemyapp | I don't care since I like having a working ocaml compiler + libs ready to go. |
| 19:06 | technomancy | yeah, opam takes ages |
| 19:06 | bitemyapp | technomancy: they aren't advertised obviously enough, apparently. |
| 19:06 | technomancy | huh |
| 19:06 | technomancy | thanks for telling me |
| 19:07 | bitemyapp | technomancy: no problem. |
| 19:07 | bitemyapp | technomancy: I look forward to doing a comparison between the two. |
| 19:07 | bitemyapp | I've used OCaml and Haskell but I've never had the chance to directly compare them. |
| 19:08 | Raynes | bitemyapp: Time is Money by You Me At Six |
| 19:09 | bitemyapp | Raynes: I'm listening to Black Boned Angel. this better be good. |
| 19:12 | technomancy | bitemyapp: these friends are macosecksists? |
| 19:12 | bitemyapp | technomancy: pretty sure. |
| 19:13 | technomancy | k, someone submitted a brew recipe fwiw |
| 19:13 | bitemyapp | if that compiles from scratch he'll still be pissed, but I'll let him know. |
| 19:13 | technomancy | heh; no idea but it wouldn't surprise me |
| 19:13 | technomancy | lolhomebrew |
| 19:21 | bitemyapp | technomancy: homebrew is pretty terrible. |
| 19:21 | bitemyapp | Raynes: okay that was good. Back to my black metal though. |
| 19:32 | satshaba2 | any style tips on https://www.refheap.com/20083? |
| 19:33 | satshaba2 | I've solved the problem, but did I do it in an idiomatic way |
| 19:34 | satshaba2 | ? |
| 19:38 | TEttinger | satshaba2, I'm not sure about using the same name for different symbols. like which "words" is it? |
| 19:41 | satshaba2 | TEttinger: good point. Mostly I'm wondering if letfn is the right approach |
| 19:41 | satshaba2 | I wish I had Haskell's `where` |
| 19:42 | satshaba2 | could I make a macro for that ? |
| 19:42 | bitemyapp | satshaba2: please don't. |
| 19:42 | metactus | macro pariahs D: |
| 19:42 | metactus | /wrist |
| 19:42 | bitemyapp | satshaba2: your code is briefer than the math.combinatorics version, but I'm trying to figure out why yours is producing slightly different data. |
| 19:43 | satshaba2 | hahaha |
| 19:43 | bitemyapp | it seems roughly equivalent to (combinations (set (mapcat concat words)) 3) |
| 19:43 | satshaba2 | is it something in combinatorics? I was just trying to solve a short problem |
| 19:44 | brehaut | satshaba2: are you referring to where being after the body rather than let which is before, or the recursive definitions allowed by where? |
| 19:44 | satshaba2 | yes |
| 19:44 | brehaut | (and letfn) |
| 19:44 | satshaba2 | sorry, the former |
| 19:44 | satshaba2 | the where being after the body |
| 19:44 | satshaba2 | for me that's a cleaner read |
| 19:44 | brehaut | in haskell i agree |
| 19:44 | bitemyapp | in Clojure, not so much. |
| 19:45 | brehaut | clojure is mostly strict, so theres a certain clarity to let having the definitions before the body because that is when they are evaluated |
| 19:45 | satshaba2 | ah I see |
| 19:46 | brehaut | haskell, where is semantically fine due to the pervasive non-strictness |
| 19:46 | satshaba2 | interesting |
| 19:46 | satshaba2 | so would that code be considered idiomatic? |
| 19:46 | satshaba2 | and readable? |
| 19:47 | brehaut | satshaba2: sure. seems clean. |
| 19:47 | brehaut | satshaba2: some people might opt for a let rather than letfn |
| 19:47 | satshaba2 | let with an fn? |
| 19:47 | brehaut | yeah |
| 19:47 | satshaba2 | neat |
| 19:47 | brehaut | or let with a #( ) |
| 19:47 | brehaut | letfn is a special case of let + fn because it allows the functions to be mutually recursive |
| 19:48 | satshaba2 | really? I thought i was just a way of naming your fn so you could recur on it within that fn |
| 19:48 | brehaut | you can do that with fn |
| 19:48 | satshaba2 | oh oh i see |
| 19:48 | brehaut | fn accepts a name |
| 19:48 | satshaba2 | ah, cool! |
| 19:48 | brehaut | but (letfn [a … b …] …) a and b can recursive into each other |
| 19:49 | satshaba2 | awesome. thanks a bunch! |
| 19:49 | brehaut | np |
| 20:07 | TEttinger | satshaba2, I'm a bit confused, is it supposed to have duplicates? |
| 20:07 | TEttinger | (for [a (words 0) b (words 1) c (words 2)] [a b c]) seems to work without producing duplicates |
| 20:13 | hyPiRion | (apply clojure.math.combinatorics/cartesian-product words) should also work fine. |
| 20:25 | dbsr | hey all, im having some trouble with using reduce / reduction correctly |
| 20:26 | dbsr | for this code: http://bpaste.net/show/142987/ |
| 20:27 | dbsr | i would like to stop the iteration when the sum of the filter is > n, since n wouldnt be a perfect number at this point |
| 20:28 | dbsr | I dont understand how I can use reduction here, since if I put reduction at the start the function would no longer return the result of the n == sum condtion |
| 20:28 | TEttinger | sounds like a use for loop/recur, with a conditional |
| 20:28 | hyPiRion | sounds like take-while or something |
| 20:29 | TEttinger | or that |
| 20:29 | dbsr | TEttinger: ill have a look at the docs, I was asking because I understood 'one' shouldnt use for loops in clojure |
| 20:31 | TEttinger | not a for loop, loop/recur |
| 20:31 | TEttinger | but take-while is better I think |
| 20:33 | Morgawr | how would you do that with take-while? |
| 20:33 | Morgawr | you'd have to accumulate the sum |
| 20:33 | Morgawr | wouldn't you? |
| 20:33 | hyPiRion | shh on you |
| 20:33 | Morgawr | :( |
| 20:33 | hyPiRion | :p |
| 20:33 | Morgawr | w-w-was I wrong? |
| 20:34 | hyPiRion | no |
| 20:34 | rasmusto | you'd change the fn to have an accumulator, yea? |
| 20:34 | Morgawr | rasmusto: well yeah but it kind of defeats the point then |
| 20:34 | hyPiRion | well, you could probably use reductions, but that's be messy |
| 20:34 | rasmusto | Morgawr: what point is that? |
| 20:35 | Morgawr | rasmusto: being elegant and non-hacky |
| 20:36 | rasmusto | an inner loop/recur w/ an accumulator is a non-elegant hack? |
| 20:36 | Morgawr | more elegant than engineering an accumulator with take-while... or at least that's what I'd say |
| 20:36 | Morgawr | but not sure how you'd use an accumulator with take-while actually so I'm probably wrong |
| 20:38 | hyPiRion | dbsr: https://www.refheap.com/20085 is how I would've done it. |
| 20:39 | dbsr | how can I add to the total sum of proper divisors in a take while loop? |
| 20:39 | dbsr | ow, thanks hyPiRion ill have a look |
| 20:40 | dbsr | later, i like puzzling this out |
| 20:40 | dbsr | for now :d |
| 20:40 | hyPiRion | a take-while is probably a horrible fit in hindsight |
| 20:41 | dbsr | heh ok, what doc should i be reading instead? |
| 20:41 | hyPiRion | actually, there's probably a bug there. replace < with <= and you'll be fine. |
| 20:43 | dbsr | didnt know about ? in fn definitions heh |
| 20:43 | hyPiRion | it's a common idiom for functions returning true/false |
| 20:43 | dbsr | those are for truth conditions? |
| 20:43 | rasmusto | it's just a notation thing |
| 20:44 | hyPiRion | yeah, those you usually call isCondition and stuff in other languages |
| 20:44 | dbsr | cool heh |
| 20:44 | hyPiRion | and yeah, it's just notation |
| 20:44 | dbsr | and zero? is shorthand for (= 0 foo) |
| 20:45 | hyPiRion | yeah |
| 20:45 | hyPiRion | "shorthand", because it's actually longer |
| 20:47 | dbsr | anyhows, i think i get reduce now, thanks a lot hyPiRion |
| 20:48 | hyPiRion | np |
| 20:50 | rasmusto | hyPiRion: good example, I like that reduce + reduced can be like a take-while w/ some sort of state |
| 20:50 | hyPiRion | hmm, you made me think there |
| 20:52 | rasmusto | I have this weird example of doing something similar. I had think I had an impl using reduce before https://www.refheap.com/20086 |
| 20:52 | rasmusto | by similar I mean not at all the same |
| 20:53 | rasmusto | and by impl I mean horrible code |
| 20:55 | Morgawr | (fn [n] (loop [ s (range 1 n) sum 0] (cond (> sum n) false (and (= sum n) (empty? s)) true (empty? s) false (zero? (mod n (first s))) (recur (rest s) (+ sum (first s))) :else (recur (rest s) sum)))) |
| 20:55 | Morgawr | this is my solution :D |
| 20:55 | Morgawr | and it's terribly ugly haha |
| 20:55 | Morgawr | (re: perfect number) |
| 20:58 | hyPiRion | https://www.refheap.com/20087 |
| 20:59 | Morgawr | hyPiRion: I'd love to actually pair that with filter as well |
| 20:59 | Morgawr | so you like.. walk the list, filter and reduce at the same time |
| 20:59 | Morgawr | and exit on false condition |
| 21:00 | hyPiRion | sounds like a kitchen sink |
| 21:00 | Morgawr | I don't think it's something that unusual |
| 21:00 | Morgawr | I mean, if you filter you already have to realize the whole list, right? |
| 21:00 | hyPiRion | no |
| 21:00 | hyPiRion | filter is lazy |
| 21:00 | rasmusto | reduce would, but you can "reduced" it |
| 21:01 | Morgawr | filter is not lazy... |
| 21:01 | Morgawr | or is it? |
| 21:01 | hyPiRion | ,(filter even? (range)) |
| 21:01 | clojurebot | (0 2 4 6 8 ...) |
| 21:01 | Morgawr | mmm |
| 21:02 | Morgawr | ,(take 6 (filter even? (range))) |
| 21:02 | clojurebot | (0 2 4 6 8 ...) |
| 21:02 | jmonetta | hi guys |
| 21:02 | Morgawr | ,(take 6 (filter even? (repeat 5)) |
| 21:02 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 21:02 | Morgawr | ^ ? |
| 21:02 | Morgawr | oh wait |
| 21:02 | Morgawr | derp |
| 21:02 | Morgawr | that never returns any value |
| 21:02 | Morgawr | sorry hyPiRion you're right, I'm just tired |
| 21:02 | Morgawr | I guess I'll head to bed, night |
| 21:02 | jmonetta | talking about laziness, can someone tell me why this takes 5 seconds instead of 2? (take 2 (map (fn [x] (Thread/sleep 1000) (* x 2)) (range 5))) |
| 21:03 | hyPiRion | $google fogus chunked lazy seq |
| 21:03 | lazybot | [fogus: De-chunkifying Sequences in Clojure] http://blog.fogus.me/2010/01/22/de-chunkifying-sequences-in-clojure/ |
| 21:03 | hyPiRion | jmonetta: ^ |
| 21:03 | jmonetta | thx! |
| 21:05 | rasmusto | ,(time (doall (take 33 (map (fn [x] (Thread/sleep 10) (* x 2)) (range))))) |
| 21:05 | clojurebot | "Elapsed time: 654.421377 msecs"\n(0 2 4 6 8 ...) |
| 21:18 | timvisher | ,(apply < [[1 1 1] [1 1 2] [1 1 3] [1 1 4] [1 1 5] [1 1 6] [1 1 7] [1 1 8] [1 1 9]]) |
| 21:18 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 21:18 | hyPiRion | sort perhaps? |
| 21:18 | timvisher | hmm. interesting. clojurescript says that's true |
| 21:18 | timvisher | but then says (apply < [[1 1 1] [1 1 2] [1 1 3] [1 1 4] [1 1 5] [1 1 6] [1 1 7] [1 1 8] [1 1 9] [1 1 10]]) is false |
| 21:19 | timvisher | but i guess that's undefined behavior |
| 21:19 | hyPiRion | oh, I'd guess that's lexicographically comparisons |
| 21:19 | timvisher | hyPiRion: I'm actually trying to assert that a set of maps ascend. |
| 21:19 | timvisher | using juxt |
| 21:19 | timvisher | but vectors don't seem to compare, unless you're sorting |
| 21:19 | timvisher | which is strange |
| 21:20 | timvisher | however, compare works fine |
| 21:20 | hyPiRion | could you use compare? |
| 21:20 | hyPiRion | as in |
| 21:20 | hyPiRion | ah |
| 21:20 | timvisher | but it's just strange that compare works but none of the other operators do |
| 21:20 | timvisher | but that's what i'll have to do. :\ |
| 21:22 | timvisher | it's also a shame that compare isn't variable arity :( |
| 21:28 | timvisher | hyPiRion: that's annoying. :) https://gist.github.com/timvisher/7110708 |
| 21:28 | timvisher | looks like it's working though. thanks for the help! |
| 21:28 | hyPiRion | Oooh, I see. Yeah, that would be annoying |
| 21:29 | hyPiRion | not sure what I helped you with, but you're welcome I guess :p |
| 21:29 | timvisher | meh. call it moral support. ;) |
| 21:29 | timvisher | going to the conj? |
| 21:29 | hyPiRion | yeah |
| 21:30 | timvisher | or is that morale support? |
| 21:30 | timvisher | is that even a phrase? |
| 21:30 | timvisher | i'm tired. :\ |
| 21:30 | timvisher | nice! it's my first year. |
| 21:30 | timvisher | pretty excited. :) |
| 21:30 | hyPiRion | I think it's "moral support", but I'd guess the actual American/English people here would know better |
| 21:31 | timvisher | interesting. that's indeed right. i'll have to look up the etymology of that. |
| 21:31 | timvisher | has anyone heard of someone working on cljs-time (or some other name)? |
| 21:32 | hyPiRion | It's my first year too. Hopefully I'll be able to go on a yearly basis, but it's expensive to travel over the atlantic ocean =/ |
| 21:33 | timvisher | lol. have you been to euroclojure? |
| 21:33 | hyPiRion | no, couldn't afford it because I wasted all my money on tickets to the US. heh |
| 21:33 | timvisher | meta |
| 21:34 | hyPiRion | There's a reason I don't study economics |
| 21:39 | gfredericks | I used to live in south carolina, and instead of driving a few hours to clojure/conj I flew across the country to clojure/west |
| 21:40 | brehaut | gfredericks: you must be a lisp programmer: value, over cost |
| 21:40 | hyPiRion | Aren't we all. |
| 21:41 | hyPiRion | I wonder when the schedule turns up. |
| 21:41 | brehaut | (apologies to perlis) |
| 21:41 | gfredericks | this is like my third year in a row missing clojure/conj? |
| 21:42 | brehaut | gfredericks: think of the positives; we can hang out on #clojure and amalloy wont be here to correct us |
| 21:43 | hyPiRion | brehaut: Oh, he will if you summon him |
| 21:43 | gfredericks | amalloy is going too? |
| 21:43 | brehaut | i have no idea |
| 21:43 | gfredericks | he never goes to conferences |
| 21:43 | brehaut | gfredericks: i think you are thinking of me |
| 21:43 | gfredericks | brehaut: no you never go to conferences but it doesn't surprise anybody |
| 21:43 | brehaut | this is true |
| 21:54 | xeqi | hyPiRion: the conj schedule? or just the talk list? |
| 21:54 | hyPiRion | xeqi: the talks, but they come out at the same time, don't they? |
| 21:55 | xeqi | hyPiRion: http://lanyrd.com/2013/clojureconj/schedule/ |
| 21:55 | hyPiRion | :o |
| 21:56 | hyPiRion | I see Rich have his "To Better Do" app once again |
| 21:56 | hyPiRion | (inc xeqi) |
| 21:56 | lazybot | ⇒ 10 |
| 22:01 | amalloy | what? brehaut, let me correct you: i won't be at the conj |
| 22:02 | bitemyapp | he doesn't need to be at the conj to correct you. |
| 22:03 | bitemyapp | he's a part of the space time continuum. A fundamental particle. |
| 22:03 | bitemyapp | if you deref a real-life atom, one of the values will be amalloy, telling you you're doing it wrong. |
| 22:03 | gfredericks | ~amalloy |
| 22:03 | clojurebot | amalloy is <amalloy> just use juxt, it'll be great |
| 22:04 | marcopolo2 | rkneufeld: yt? |
| 22:04 | llasram | When you write a function which accepts a function and returns a function which returns a function, the result of calling that function is amalloy |
| 22:04 | bitemyapp | llasram: so most Haskell code is just a doppelganger for amalloy? |
| 22:05 | amalloy | i should /part now and forever, and let the myth keep growing |
| 22:05 | bitemyapp | The fire rises! |
| 22:05 | gfredericks | in ten years we'll have bitter factions just based on how to pronounce the first syllable in his nick |
| 22:06 | amalloy | and the faction who thinks being bitter is a form of worship |
| 22:06 | bitemyapp | wars between the ay-ists and ah-ists will bleed into the non-programming world. World War 3 will be a resource war fought in Africa to feed the opposing factions from those split over how to pronounce the first 'a' in amalloy. |
| 22:07 | bitemyapp | and with that, I'm off to Clojure Dojo. hope I see some of you there :) |
| 22:10 | cespare | How do I refer to the objects, bytes, etc (that I use inside a normal function for type hinting like ^objects, ^bytes) inside a macro? I'm basically doing this: http://stackoverflow.com/a/11920022 |
| 22:10 | cespare | in that code he's using `BufferedImage -- how do I refer to objects instead? |
| 22:12 | gfredericks | ,`objects |
| 22:12 | clojurebot | sandbox/objects |
| 22:12 | gfredericks | hm |
| 22:12 | gfredericks | ,'objects maybe |
| 22:12 | clojurebot | objects |
| 22:13 | gfredericks | ((fn [^objects a] (aget a 0)) (into-array Object [7])) |
| 22:13 | gfredericks | '((fn [^objects a] (aget a 0)) (into-array Object [7])) |
| 22:13 | gfredericks | aaaah |
| 22:13 | gfredericks | ,((fn [^objects a] (aget a 0)) (into-array Object [7])) |
| 22:13 | clojurebot | 7 |
| 22:13 | gfredericks | ,((fn [^objects a] (aget a 0)) (into-array Long [7])) |
| 22:13 | clojurebot | 7 |
| 22:13 | gfredericks | ,((fn [^objects a] (aget a 0)) (into-array Long/TYPE [7])) |
| 22:13 | clojurebot | #<ClassCastException java.lang.ClassCastException: [J cannot be cast to [Ljava.lang.Object;> |
| 22:13 | gfredericks | phew it worked |
| 22:15 | marcopolo2 | rkneufeld: ping |
| 22:15 | rkneufeld | Hey |
| 22:15 | cespare | gfredericks: erm, what's the conclusion? |
| 22:15 | marcopolo2 | rkneufeld: Cool, I don't wanna use a lot of your time |
| 22:16 | marcopolo2 | rkneufeld: I'm glad you wanna make sure we does this right, I respect that |
| 22:16 | marcopolo2 | rkneufeld: I'm still new to pedestal so I don't quite understand all of it yet |
| 22:16 | cespare | gfredericks: Whether I do `objects or 'objects, I get a classcastexception evaluating the macro |
| 22:16 | marcopolo2 | rkneufeld: can you briefly explain what [:build :triggers] does? |
| 22:20 | gfredericks | cespare: what's your code look like? |
| 22:20 | gfredericks | 'objects is what it should be |
| 22:26 | cespare | gfredericks: well, i ended up doing something different with the code anyway. I don't have something handy to show you atm |
| 22:26 | cespare | I don't really understand the SO answer from amalloy, though. |
| 22:27 | cespare | Does the type hint get evaluated when the macro is evaluated, even if it's in a syntax quite? |
| 22:27 | cespare | *quote |
| 22:29 | cespare | oh, i see. ^ is a reader macro. |
| 22:30 | gfredericks | yeah; you need the metadata to make its way through the macroexpansion into the compilation phase |
| 22:30 | gfredericks | using ^ just gets metadata attached to the symbols in the macro definition, while you need it to be on the symbols _passed to_ the macro and returned from it |
| 22:30 | gfredericks | ...crazy subtle distinction |
| 22:55 | bhenry | bitemyapp: hiredman: i switched to clojure.java.io/resource. here is the repl working, and the lein-ring which i believe just runs the app, throwing the error in the stacktrace and pointing at config.clj https://gist.github.com/bhenry/f42daf5ef4ec6b448228 |
| 22:55 | bhenry | uuuh, i said that wrong |
| 23:13 | `cbp | bitemyapp: ping |
| 23:24 | `cbp | :-( |