2014-11-14
| 02:35 | cosmicexplorer | test |
| 02:35 | TEttinger | mic check, 1, 2 |
| 02:36 | cosmicexplorer | we're good to go |
| 02:36 | TEttinger | welcome to clojure, here's some bots. ##["lazybot"] |
| 02:36 | lazybot | ⇒ ["lazybot"] |
| 02:36 | TEttinger | ,"clojurebot" |
| 02:36 | clojurebot | "clojurebot" |
| 02:56 | godd2 | "redbot, standing by" |
| 03:06 | amalloy | neat, i didn't know that M-q takes a prefix argument to justify the text |
| 04:04 | engblom | Where should I look if I want to make simple clickable 2D graphics with Clojure for Android mobile devices? |
| 04:04 | engblom | A nice sample project to look at would be nice and of course some reference material to check up things. |
| 04:14 | sm0ke | well said justin_smith |
| 04:23 | m00nlight | When I use some clojure code in an java project using storm, it seems conflict of clojure.core/some? with backtype.storm/some?, does anyone have sollutions? |
| 04:24 | Glenjamin | m00nlight: see the example on https://clojuredocs.org/clojure.core/refer-clojure |
| 04:27 | m00nlight | Glenjamin: Thanks, I will have a try right now |
| 04:27 | sm0ke | m00nlight: you will still get that warning |
| 04:27 | sm0ke | unless you are willing to compile and edit storm code |
| 04:29 | TEttinger | engblom: I know libgdx works on android, and play-clj is a wonderful clojure binding to that library, but I don't know how well clojure in general runs on android |
| 04:34 | TEttinger | $google play-clj |
| 04:34 | lazybot | [oakes/play-clj · GitHub] https://github.com/oakes/play-clj |
| 04:34 | TEttinger | ^ engblom |
| 04:35 | m00nlight | sm0ke : but in fact it cause a exception |
| 04:35 | TEttinger | "The mobile support is currently experimental, and may have poor performance or even fail to run on some devices." That mainly refers to iOS, which has been trouble to perform well on even for the main lib in java |
| 04:35 | m00nlight | sm0ke: |
| 04:35 | m00nlight | java.lang.IllegalStateException: Attempting to call unbound fn: #'backtype.storm.util/some? |
| 04:35 | m00nlight | at clojure.lang.Var$Unbound.throwArity(Var.java:43) ~[clojure-1.6.0.jar:na] |
| 04:36 | sm0ke | ,(doc some?) |
| 04:36 | clojurebot | "([x]); Returns true if x is not nil, false otherwise." |
| 04:37 | m00nlight | sm0ke: I already exclude the some? in core |
| 04:37 | m00nlight | (doc some?) |
| 04:37 | clojurebot | "([x]); Returns true if x is not nil, false otherwise." |
| 04:37 | m00nlight | nil |
| 04:38 | TEttinger | did you then include backtype.storm ? |
| 04:38 | TEttinger | I guess the word is require or use |
| 04:38 | sm0ke | ah nice catch TEttinger |
| 04:38 | sm0ke | m00nlight: what are you trying to do? |
| 04:39 | m00nlight | Very simple code implement in clojure for some other Java program to use in storm |
| 04:39 | TEttinger | m00nlight, do you want to call storm's some? or your own some? |
| 04:39 | sm0ke | run storm of clojure 1.6 is not possible unless storm updates it |
| 04:39 | TEttinger | or clojure's some? i mean |
| 04:39 | m00nlight | TEttinger: So I need to use an old version of clojure? |
| 04:40 | TEttinger | 1.5 isn't that old, actually... |
| 04:40 | TEttinger | sm0ke, do you think 1.5 will work? |
| 04:40 | sm0ke | yes |
| 04:41 | sm0ke | storm has updated to 1.5 |
| 04:41 | m00nlight | sm0ke: OK. Thanks, I will try to use clojure 1.5 instead |
| 04:49 | m00nlight | sm0ke: TEttinger: Glenjamin: Thanks very much, problem solved :) |
| 04:49 | TEttinger | woo |
| 04:49 | TEttinger | (inc sm0ke) |
| 04:49 | lazybot | ⇒ 7 |
| 04:51 | sm0ke | storm is notorius with respect to clojure compatibility |
| 04:52 | mnngfltg | Vim users rejoice! I've created an "alternate star": https://www.refheap.com/93358 |
| 04:53 | mnngfltg | So you can move your cursor over a namespace and hit `_` to cycle through all uses of that namespace in your code. |
| 04:53 | sm0ke | and i am not sure where if that code style does any good |
| 04:54 | TEttinger | is that vimscript, mnngfltg? |
| 04:54 | mnngfltg | tettinger yes I think :) |
| 04:55 | TEttinger | that's _ in non-insert mode, right? :) |
| 05:09 | whodidthis_ | how does one eval just a single line or symbol in fireplace |
| 05:11 | mnngfltg | Tettinger, right |
| 05:12 | mnngfltg | whodidthis_, a single form (the one under the cursor): `cpp` |
| 05:13 | whodidthis_ | what if i just want to see what is up in a symbol without writing (println mythingie) |
| 05:15 | engblom | TEttinger: Thanks! |
| 05:15 | whodidthis_ | return contents of mythingie without writing println around it i mean |
| 05:16 | engblom | I thought (or ...) was always taking the arguments in order. |
| 05:26 | engblom | (first vector) will give the first element rather than using (nth 0 vector). Is there a similar thing for changing the first element rather than using (assoc vector 0 value) ? |
| 05:28 | sm0ke | ,(cons 0 (rest [1 2 3])) |
| 05:28 | clojurebot | (0 2 3) |
| 05:29 | engblom | sm0ke: the same long as (assoc [1 2 3] 0 0) |
| 05:29 | engblom | ,(assoc [1 2 3] 0 0) |
| 05:29 | clojurebot | [0 2 3] |
| 05:30 | sm0ke | engblom: thats pretty short imo |
| 05:30 | engblom | Maybe there is not a ready function for changing the first element and this is how it is done normally |
| 05:31 | engblom | ,(nth [1 2 3] 0) |
| 05:31 | clojurebot | 1 |
| 05:31 | engblom | ,(first [1 2 3]) |
| 05:31 | clojurebot | 1 |
| 05:32 | engblom | What I meant is that in the same way as (first ...) is more elegant than (nth ...) for getting the first element, I was wondering if there is more elegant ways for changing the first rather than refering with an index. |
| 05:34 | hyPiRion | engblom: no, but if you use the list/vector as a stack, you can use pop, conj and peek |
| 05:35 | hyPiRion | ,(conj 0 (pop (list 1 2 3))) |
| 05:35 | clojurebot | #<ClassCastException java.lang.ClassCastException: java.lang.Long cannot be cast to clojure.lang.IPersistentCollection> |
| 05:35 | hyPiRion | ,(conj (pop (list 1 2 3)) 0) |
| 05:35 | clojurebot | (0 2 3) |
| 06:25 | dysfun | hrm, is there something in ring.middleware.session i've missed for setting how long the cookie will be valid? i see the cookie options but those don't appear to take functions, in which case how can i provide a DateTime (which it requires for Expires:) when it's a middleware? |
| 06:26 | dysfun | i'm using the cookie store |
| 07:21 | dysfun | is there an idiomatic way to rethrow an exception, adding extra information? |
| 07:22 | dysfun | preferably one that might reasonably be understood by timbre so there's helpful information in the logs |
| 07:24 | clgv | dysfun: only the java way. you can wrap the exception in a new one and throw that one or just throw the current exception |
| 07:24 | hyPiRion | you can bounce with ex-info tricks. Lemme make a macro/function for that |
| 07:25 | dysfun | :) |
| 07:32 | hyPiRion | dysfun: https://www.refheap.com/93366 |
| 07:32 | hyPiRion | Not sure how that works with timbre, but you can add data to the exception like this |
| 07:34 | hyPiRion | actually, this is a bit better: https://www.refheap.com/93367 |
| 07:34 | dysfun | hrm, i'm not guaranteed to be getting an ExceptionInfo though. I'd like to catch Exception more generally and then turn that into an ExceptionInfo |
| 07:34 | hyPiRion | multiple clauses. |
| 07:34 | hyPiRion | Oh. |
| 07:35 | hyPiRion | Well, you can add another catch for Exception afterwards, and let the map be an empty one |
| 07:36 | hyPiRion | There, I updated it to do just that. Same link as latest |
| 07:36 | dysfun | I suppose in those cases, I can just create a new one, putting the original exception in the map of info. It's not ideal, but i can postprocess it |
| 07:37 | dysfun | hrm, the colour scheme on refheap is quite nice on the eyes |
| 07:38 | dysfun | hyPiRion: thanks for the help |
| 07:38 | hyPiRion | dysfun: no problem, hope it's useful for you |
| 07:39 | dysfun | :) |
| 07:48 | dysfun | hyPiRion: also why is it that so often the problem that makes people understand why macros are special involves exceptions? Are they really more tedious in most languages? I've never thought so. |
| 07:48 | dysfun | well, no more than other things |
| 07:52 | hyPiRion | dysfun: Well, most things macros are used for is control flow related. Either through looping (dotimes, doseq) or exceptions. Most other things can just be solved by functions |
| 07:53 | dysfun | yeah. i find the lack of first class anonymous functions and closures to be much more annoying |
| 07:56 | hyPiRion | I feel that persistent data structures and functional programming matters more, but I suppose that's because most of the useful macros are already included in Clojure |
| 07:58 | dysfun | yes, i'm liking them both a lot. i found it very hard to program an imperative language recently after about 6 months of almost full time clojure |
| 07:58 | dysfun | a lot of my imperative code has smelled functional for years though |
| 07:58 | dysfun | (damn you, elisp!) |
| 07:59 | hyPiRion | hah – for me it was a lot harder to transition. Took a lot of time to unlearn mutable data structures. |
| 08:02 | dysfun | yes, i admit i struggled with that at first |
| 08:02 | dysfun | but i've come to prefer it |
| 08:03 | dysfun | but i used to program a lot of perl, which has map and grep built in |
| 08:03 | hyPiRion | me too – much easier to work with after the struggle was over |
| 08:53 | sveri | Hi, anyone here using clara (rule system) and knows how to generate rules on the fly? |
| 09:07 | sveri | Or can I somehow create namespaces on the fly in clj / cljs and add rules and whatever to it to evaluate it in memory then? |
| 09:12 | hyPiRion | sveri: yeah, you can create namespaces on the fly in clj. Not sure how clara works, but I wouldn't be surprised if you could make "anonymous" rules on the fly. |
| 09:15 | sveri | hyPiRion: thanks, something more to read about :-) |
| 09:54 | zand` | Anyone using the debugger in cursive clojure? I can't seem to get it to stop at a breakpoint in a very simple test.. :-/ |
| 10:04 | gfredericks | ,'ping |
| 10:04 | clojurebot | ping |
| 10:17 | justin_smith | $ping |
| 10:17 | lazybot | justin_smith: Ping completed in 0 seconds. |
| 10:25 | gfredericks | ~ping |
| 10:25 | clojurebot | PONG! |
| 10:41 | puredanger | idle Friday question - one change as a side effect of proposed changes in http://dev.clojure.org/jira/browse/CLJ-1546 is that vec would no longer guarantee a new vector instance. If passed a vector, it would simply return it. I imagine that 99.9???% of users would benefit from this change in meaning (by saving 100+ ns every time this is done). |
| 10:42 | puredanger | Does anyone know of a case where a library actually relies on this "new vector instance" behavior? it would have to be something where identity is important (not just equality) |
| 10:42 | justin_smith | puredanger: going on intuition alone, I would have naively assumed vec already did that |
| 10:42 | puredanger | http://crossclj.info/fun/clojure.core/vec.html might jog your memory |
| 10:42 | justin_smith | (inc crossclj) |
| 10:42 | lazybot | ⇒ 3 |
| 10:42 | puredanger | justin_smith: agreed. I'm looking for the odd duck here. |
| 10:42 | puredanger | (inc crossclj) |
| 10:42 | lazybot | ⇒ 4 |
| 10:42 | puredanger | for sure |
| 10:42 | puredanger | I have been regularly using it to answer questions like this |
| 10:44 | verma | is this also the place for clojure-clr? or is there a dedicate channel for it? |
| 10:44 | justin_smith | hmm - I'll add a crossclj lookup plugin to my "lazybot nice to have" list - seems it would be straightforward to do |
| 10:44 | puredanger | verma: questions welcome here, not sure if there is a separate channel |
| 10:44 | EvanR | puredanger: if anyone is relying on something like that, they deserve to get broke by this ;) |
| 10:45 | verma | puredanger, sure thanks :) |
| 10:45 | justin_smith | EvanR: well the docs did explicitly say it would always make a new vec |
| 10:45 | puredanger | EvanR: I somewhat sympathize with this. I think Rich is on board with that too. |
| 10:45 | EvanR | the ideal of referential transparency and all |
| 10:45 | puredanger | justin_smith: the docs will change |
| 10:45 | EvanR | justin_smith: yurg |
| 10:46 | justin_smith | puredanger: right, just my 2¢ regarding "anyone who expected it deserves breakage" |
| 10:46 | puredanger | this is definitely a semantic (potentially breaking) change in behavior, but one that I think is extremely subtle |
| 10:47 | stuartsierra | I would be surprised if it broke anything. |
| 10:48 | puredanger | agreed, just trying to uncover that surprise early :) |
| 10:49 | puredanger | I've looked through many usages found in crossclj and I have a hard time finding anything that relies on this "new" behavior |
| 10:50 | Bronsa | (inc crossclj) |
| 10:50 | lazybot | ⇒ 5 |
| 10:51 | kungi | (inc crossclj) |
| 10:51 | lazybot | ⇒ 6 |
| 10:55 | EvanR | whoever decided that and then decided it needed to be documented as such also deserves breakage |
| 10:55 | EvanR | creative destruction |
| 10:57 | puredanger | one possible use case for old behavior would be to ensure the removal of meta |
| 10:57 | puredanger | ,(meta (vec (with-meta [1 2] {:foo "foo"}))) |
| 10:57 | clojurebot | nil |
| 10:57 | EvanR | what is meta :( |
| 10:58 | TimMc | yuck |
| 10:58 | puredanger | metadata |
| 10:58 | EvanR | very powerful |
| 10:58 | EvanR | is metadata mutable? |
| 10:58 | TimMc | EvanR: with-meta attaches metadata to certain Clojure objects (gives you back a new object); meta retrieves it. |
| 10:59 | puredanger | collections generally retain meta through collection functions |
| 10:59 | puredanger | sequence functions generally do not retain meta |
| 10:59 | puredanger | (since they convert the coll to a seq) |
| 11:00 | TimMc | EvanR: When you see something like ^{:foo :bar}, that's attaching metadata to the next form for the benefit of the compiler. |
| 11:00 | edw | Speaking of crossclj, it's sketchy how it makes it so difficult to click out to wherever code originates from. It's like it doesn't want you to leave the site. |
| 11:00 | edw | A more prominent link would be an important act of good faith. |
| 11:01 | TimMc | You think it's intentional? |
| 11:01 | puredanger | I don't think it's sketchy. just a lot of stuff on those pages :) |
| 11:01 | bbloom | ,123 |
| 11:01 | clojurebot | 123 |
| 11:01 | justin_smith | edw: no matter what you are trying to do, crossclj is a little confusing |
| 11:01 | puredanger | exactly :) |
| 11:01 | justin_smith | edw: they just need a UX overhaul |
| 11:02 | edw | TimMc: I have no idea whether it's intentional. But pretty every other similar resource makes it relativly easy. justin_smith, you're right; I should not ascribe to malice what's more easily explained by UX breakage. |
| 11:03 | justin_smith | edw: if they were serving any ads I may feel differently - but what do they gain from your page view? |
| 11:04 | edw | justin_smith: I hear you; some people (not saying the CrossClj folk(s), see above) are just greedy for people's attention. |
| 11:05 | edw | The (old) Google ethos--get em in and out as quickly as possible--is not shored by most people. |
| 11:05 | edw | s/shored/shared/ |
| 11:06 | puredanger | so, vec could return essentially the same vector sans meta and it would at least be constant time |
| 11:06 | justin_smith | edw: also, gmail is like the opposite of that |
| 11:07 | bbloom | puredanger: that would also produce a new identity |
| 11:07 | puredanger | yes |
| 11:07 | justin_smith | puredanger: that likely solves everything except folks who were exploiting array aliasing - and THEY deserve breakage I think |
| 11:07 | puredanger | justin_smith: I don't care about that |
| 11:08 | justin_smith | good |
| 11:08 | puredanger | I would happily break that :) |
| 11:08 | puredanger | new patches hitting master right now, btw |
| 11:08 | puredanger | including CLJ-1529 which has the Class.forName() improvement in it |
| 11:08 | stuartsierra | Brace yourselves, people. |
| 11:09 | puredanger | https://github.com/clojure/clojure/commits/master |
| 11:12 | clj-learner | hi, i'm learning neo4j with neocons, how do i vizualize a path in my application? |
| 11:15 | TimMc | puredanger: You think vec *should* strip metadata? |
| 11:15 | puredanger | it does now and someone might rely on that |
| 11:16 | TimMc | You think that's a more likely case than relying on identity changing? |
| 11:16 | puredanger | yes |
| 11:16 | bbloom | TimMc: definitely |
| 11:16 | puredanger | but it would also address that case |
| 11:16 | owengalenjones | in cljs, if Im using an external library do I need to *both* declare it in :cljsbuild :compiler :externs AND include it in a <script src = > tag? |
| 11:17 | TimMc | huh |
| 11:17 | dc_ | in multimethod dispatch based on class, how do i specify that |
| 11:17 | edw | justin_smith: The Marissa-Mayer, Google-as-search-engine part of the company's history was dominated by the sort of thinking I described. It's well suited to things like the Grimoire, CrossClj, MELPA. |
| 11:17 | justin_smith | dc_: specify class as the dispatch function |
| 11:18 | dc_ | i want a different method dispatched for a collection of chars vs a collection of integers |
| 11:18 | justin_smith | dc_: or use a protocol - they do that, and have better performance |
| 11:18 | dc_ | justin_smith: sry hit send early |
| 11:18 | dc_ | k, i'm aware of protocols and their power, but haven't used them yet, except in clojure koans |
| 11:19 | stuartsierra | dc_: That's not a class, you would need a dispatch function like (fn [coll] (type (first coll))) |
| 11:19 | justin_smith | ,(map (comp class first) [[] [1] "a"]) ; dc_ |
| 11:19 | clojurebot | (nil java.lang.Long java.lang.Character) |
| 11:19 | Bronsa | wow, t.a.jvm loads noticeably faster with clj master than with clj 1.7.0-alpha3 |
| 11:21 | justin_smith | dc_: yeah, for dispatch based on item type a protocol wouldn't help really, but you could use a dispatch function that checks the type of the first item |
| 11:22 | puredanger | Bronsa: yes, expect more of that :) doesn't help every project, but it does help in many cases, macro-heavy projects in particular. |
| 11:31 | EvanR | can i dynamiclly instantiate a java class that i have in a variable |
| 11:31 | EvanR | can i even have java classes in a variable |
| 11:31 | EvanR | ,(let [x java.lang.Long] x) |
| 11:31 | clojurebot | java.lang.Long |
| 11:32 | EvanR | ,(let [x java.lang.Long] (new x)) |
| 11:32 | clojurebot | #<CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: x, compiling:(NO_SOURCE_PATH:0:0)> |
| 11:32 | Bronsa | EvanR: no, you need reflection to do that |
| 11:33 | Bronsa | EvanR: core.incubator has a function for that |
| 11:33 | Bronsa | new-from-string or something similar |
| 11:33 | EvanR | hmm |
| 11:33 | hyPiRion | you can wrap them in functions as well |
| 11:33 | Bronsa | https://github.com/clojure/core.incubator/blob/master/src/main/clojure/clojure/core/incubator.clj#L76 |
| 11:33 | Bronsa | new by name |
| 11:33 | EvanR | ok |
| 11:43 | donbonifacio | I have autotest running, after some full test runs (about 30), I start to get out of memory exception. Isn't it weirf? |
| 11:43 | donbonifacio | - /s/weirf/weird |
| 11:43 | sdegutis | Seems normal to me. |
| 11:44 | donbonifacio | what about the GC? isn't it working? should I expect this kind of behaviour in prd? |
| 11:44 | sdegutis | Clojure is still young, and most libraries are ad-hoc and written just to get the job done for the author. |
| 11:44 | sdegutis | So expect to see lots of room for improvement all around. |
| 11:45 | justin_smith | donbonifacio: running out of heap, or permgen? |
| 11:46 | justin_smith | if heap, something in your test is holding onto data it does not need, if permgen, use a newer jvm that doesn't segregate permgen, or turn on permgen gc (it is often off by default) |
| 11:46 | donbonifacio | java.lang.OutOfMemoryError: unable to create new native thread |
| 11:46 | Bronsa | sdegutis: that's not true at all |
| 11:46 | technomancy | s/Clojure/the field of computing/ |
| 11:46 | TimMc | *tools |
| 11:46 | justin_smith | donbonifacio: are you creating threads in your tests? |
| 11:46 | sdegutis | Bronsa: Well maybe you and I are using different libraries. |
| 11:47 | sdegutis | But the ones I'm using seem to break all the time. |
| 11:47 | donbonifacio | justin_smith: I'm testing pedestal, and making several requests to test the public rest api |
| 11:47 | justin_smith | donbonifacio: in the test teardown, are you properly shutting down the pedastal instance? |
| 11:47 | donbonifacio | noooo |
| 11:48 | donbonifacio | I'm not doing anything like that |
| 11:48 | donbonifacio | didn't know I had to, I confess |
| 11:48 | justin_smith | donbonifacio: so, to be clear: your test starts up pedastal, runs a few requests against it, and leaves it running? |
| 11:49 | ohpauleez | Or are you using Pedestal's testing `response-for`? |
| 11:49 | donbonifacio | yes, I have autotest running, and it reloads every thime. I don't know if it reloads pedestal |
| 11:49 | Bronsa | sdegutis: I don't see how you can go from "the libraries I use have bugs" to "most clojure libraries are ad-hoc and wrotten just to ghet the job done for the author" |
| 11:49 | sdegutis | Bronsa: Well sure, if that was all there was to it. |
| 11:49 | stuartsierra | Bronsa: I'll go there. |
| 11:50 | donbonifacio | ohpauleez: response-for |
| 11:50 | justin_smith | donbonifacio: does the test code start up pedastal, or does it assume pedastal is already up and running? |
| 11:50 | sdegutis | Bronsa: But experience fills in the missing context. |
| 11:50 | ohpauleez | donbonifacio: Ahh, so there's no running Pedestal. Are you doing a POST in any of the endpoints? |
| 11:50 | donbonifacio | I don't start pedestal, I use response-for |
| 11:50 | donbonifacio | some POSTs and PUTs |
| 11:50 | donbonifacio | a lot actually |
| 11:50 | justin_smith | oh, OK, I misunderstood that part |
| 11:51 | ohpauleez | donbonifacio: Do you store or hold onto the results to compare them across multiple tests? |
| 11:51 | justin_smith | donbonifacio: I would try profiling, to see what is being leaked each time the tests run. the jdk comes with jvisualvm which should suffice for this |
| 11:51 | ohpauleez | I've personally never heard of this happening, just seems like you're creating some data somewhere and never letting it go (you're always keeping a reference to it) |
| 11:52 | donbonifacio | ohpauleez: nop, each test is independent. But sometimes tests perform several requests |
| 11:52 | ohpauleez | it could also be the autotest runner |
| 11:52 | justin_smith | donbonifacio: ohpauleez: either way a profiler should likely catch it |
| 11:52 | ohpauleez | donbonifacio: Yeah, the multiple requests thing should be ok. I do that across a lot of Pedestal projects (and within pedestal itself) |
| 11:53 | ohpauleez | donbonifacio: Yeah, if you just use jvisualvm, or whatever you have on hand, you'll see what's holding on to data |
| 11:53 | donbonifacio | ok, i'll try to use it, and if I find something and get back to you ohpauleez |
| 11:53 | ohpauleez | Also, feel free to bounce into #pedestal if you have any specific questions. Always more than happy to help! |
| 11:53 | ohpauleez | Thanks! I appreciate it |
| 11:54 | justin_smith | donbonifacio: one thing to look for is in the threads panel, if it is creating new threads each time the tests run that maybe don't get disposed of |
| 11:55 | donbonifacio | kay thanks, never used it before, will play with it |
| 11:55 | donbonifacio | btw, anyone using VIM? still can't find a nice workflow |
| 11:56 | engblom | donbonifacio: I am using vim, but I have a bit of the same problem. |
| 11:56 | ohpauleez | donbonifacio: I'm also using vim |
| 11:56 | ohpauleez | I love my workflow |
| 11:56 | ohpauleez | :) |
| 11:56 | donbonifacio | how's your workflow? |
| 11:57 | engblom | ohpauleez: Would you mind making a tar.gz of your setup? Or putting it on github? |
| 11:59 | ohpauleez | I use Pathogen. And then these: Paredit, fireplace, Ack, gundo, classpath, clojure-highlight, clojure-static, dispatch, leiningen, projectionist, surround |
| 11:59 | ohpauleez | In my tmux, I split horizontally, and my lower pane is tiny. It runs a repl |
| 12:00 | ohpauleez | From there I mostly only `cpp` and `cpr` |
| 12:00 | donbonifacio | how do you reload the code on the repl? |
| 12:00 | ohpauleez | I always have a `(comment )` block in the file I work in, to try things out |
| 12:01 | ohpauleez | cpr |
| 12:01 | donbonifacio | reloads all or just the current file? |
| 12:01 | ohpauleez | requires-reloads current file (to my knowledge) and runs any tests present. |
| 12:02 | donbonifacio | one thing I like on my ruby workflow, is that I can run a test, and then go to other files make changes and run that test again. |
| 12:02 | ohpauleez | Why do you need to reload all? You just `cpr` when you make a change |
| 12:02 | donbonifacio | hum |
| 12:02 | donbonifacio | yes, you're right ohpauleez |
| 12:07 | andyf_ | Bronsa: So, I?m finally changing Eastwood?s suspicious-expression linter to use asts rather than source forms, so it is no longer giving incorrect warnings for things like (-> 1 (= 1)) |
| 12:07 | andyf_ | Except for keyword typos, I think it is the last one that doesn?t use asts |
| 12:09 | andyf_ | I?m now hitting what should have been predictable: nested macro calls inside things like defrecord expansions that contain things that issue warnings, and/or with > 1 arg contain in their expansion a 1-arg and/or that warns if I don?t prevent it somehow, same for cond, etc. |
| 12:10 | andyf_ | My current plan is to add in checks for these cases by looking in the ancestor nodes of the ast for context that says "oh, that one is normal and shouldn't warn because it was expanded from foo". If you happen to think of a cleaner way, I'd be interested to know. |
| 12:10 | andyf_ | but I'm content going down this path if we don't think of anything better |
| 12:14 | justin_smith | andyf_: it seems like there would be a lot of constructs that would be a likely error at the top level of code, but be present expansion of a well-made macro |
| 12:16 | andyf_ | Sure, but I can't think of a precise definition of "the top level of code" that doesn't eliminate checking inside macros you write yourself. |
| 12:16 | mdrogalis | tbaldrid_: re mailing-list: I'm not saying I agree/disagree with you about feature expressions being in core, but I find it funny that we sometimes argue that larger things should be in core 'because it would be convenient', and we use the exact opposite argument about adding very small things to clojure.core. |
| 12:16 | tbaldrid_ | how is this a large change/ |
| 12:16 | tbaldrid_ | ? |
| 12:16 | justin_smith | andyf_: yeah, that's tricky |
| 12:17 | mdrogalis | tbaldridge: Feature expressions? |
| 12:17 | andyf_ | justin_smith: Hmm. Perhaps "if the last macro expanded to get here was in clojure.core, then don't warn for it" |
| 12:17 | tbaldridge | if file.endswith(".clj") or file.endswith(".cljp") { load(file)} |
| 12:17 | mdrogalis | tbaldridge: That's really all there is to it? |
| 12:17 | tbaldridge | The approach I advocated isn't really feature expressions at all, it's just a new "portable" file extension. |
| 12:18 | mdrogalis | Yeah, I got'cha. I guess I'm mis-remembering some things from the last time I read the feature-expressions design doc. |
| 12:18 | tbaldridge | you put cross-platform code in the new file type, everything platform specific goes in .clj, cljc, or .cljs |
| 12:18 | tbaldridge | yeah, it's changed alot recently |
| 12:18 | tbaldridge | And some people like cfleming chimed in saying that anything that modifies the guts of the reader is going to be super hard for tools to figure out without evaling the namespace or something. |
| 12:19 | mdrogalis | tbaldridge: Ah, ignore my comment then. |
| 12:19 | tbaldridge | Now I have no say in the final approach Clojure takes here, it's just worth pointing out that not every variant of "feature expressions" is complex |
| 12:20 | mdrogalis | That's a good point. |
| 12:20 | Bronsa | wow. the reduce impl is even more confusing than I though. there are now 3 interfaces + 2 protocols implementing it |
| 12:21 | Bronsa | and some implementations are unreachable, e.g. it looks like reduce will never use the ArraySeq_prim IReduce impl |
| 12:22 | Bronsa | puredanger: ^ that's maybe something that should be addressed before 1.7, it seems that some IReduce/IChunk reduce impls still don't handle reduced |
| 12:22 | puredanger | which? |
| 12:23 | puredanger | tbaldridge was supposed to find and fix all of those, so I'll blame him :) |
| 12:23 | Bronsa | puredanger: ArrayChunk/ArraySeq_[prim]/gvec |
| 12:24 | tbaldridge | Yeah, except, adding "reduced?" support to ArrayChunk breaks a bunch of thigns |
| 12:25 | Bronsa | also reduce on primitive arrays seems slower than it could be |
| 12:25 | tbaldridge | Bronsa: well it does do boxing, or are you thinking of something else? |
| 12:25 | puredanger | oh right, we talked about that didn't we |
| 12:25 | Bronsa | it gets routed from collreduce to internalreduce's Obejct impl rather than to the IReduce impl for their ArraySeq_* |
| 12:26 | puredanger | reduce will have a special case to prefer IReduce over CollReduce |
| 12:26 | Bronsa | puredanger: the thing is that (long-array [1 2 3]) is not IReduce, (seq (long-array [1 2 3])) is |
| 12:26 | puredanger | that's in CLJ-1572 which almost made it in today |
| 12:27 | Bronsa | ah wait, I see I'm wrong |
| 12:27 | Bronsa | or not. uhm. |
| 12:28 | Bronsa | yup, reduce doesn't seem to use the arrayseq path for arrays |
| 12:30 | puredanger | hmm, yeah CollReduce could potentially be extended to arrays |
| 12:30 | Bronsa | ah! there's an impl for arrayseq_* of internalreduce that's not broken |
| 12:31 | puredanger | if there's a gap here, please file a ticket |
| 12:31 | Bronsa | so arrayseq_* IReduce impl is broken, but internalreduce's impl is not broken |
| 12:31 | Bronsa | puredanger: I'll try to figure out what is a bug and what is just dead code and open a ticket |
| 12:32 | Bronsa | ,(.reduce (seq (long-array [1 2 3 4 5])) (fn [_ a] (println a) (reduced 6))) |
| 12:32 | clojurebot | 2\n3\n4\n5\n#<Reduced@d85409: 6> |
| 12:32 | puredanger | certainly, ArraySeq* should check reduced |
| 12:32 | Bronsa | like, this is obviously wrong but this path will never be used by reduce |
| 12:33 | Bronsa | ,(reduce (fn [_ a] (println a) (reduced 9)) (seq (long-array [1 2 3 4 5]))) |
| 12:33 | clojurebot | 2\n9 |
| 12:33 | puredanger | those sound like 2 separate jiras to me |
| 12:35 | Bronsa | puredanger: do you have any idea why IChunk defines a reduce method but doesn't extend IReduce? |
| 12:35 | bodie_ | has anyone tried anything around pair programming in lighttable besides the firepad demo? |
| 12:35 | bodie_ | I'm thinking something like a floobits plugin or something over xmpp |
| 12:37 | puredanger | Bronsa: timbaldridge just looked into some of that stuff recently, but don't know. IChunk.reduce() has slightly different semantics than IReduce.reduce() iirc. |
| 12:37 | puredanger | in particular, around reduced |
| 12:38 | Bronsa | puredanger: ok I'll dig into that code and try to figure it out. |
| 12:38 | puredanger | he was (I think) trying to reconcile them in the patch for http://dev.clojure.org/jira/browse/CLJ-1515 |
| 12:39 | Bronsa | ah, there's also IKVreduce lol. 3interfaces+3protocols then |
| 12:39 | Bronsa | I feel like this could be cleaned out quite a bit |
| 12:40 | puredanger | Bronsa: if designed fresh, surely |
| 12:41 | puredanger | but harder if considering how not to break existing users of CollReduce or IReduce |
| 12:42 | Bronsa | puredanger: meh, IReduce just got a breaking change |
| 12:42 | puredanger | ? |
| 12:42 | Bronsa | IReduce -> IReduce,IReduceInit |
| 12:43 | Bronsa | nevermind, I missed that IReduce extends IReduceInit |
| 12:44 | andyf_ | you are in a maze of twisty little passages, all alike. :) |
| 12:44 | puredanger | I was just eaten by reduced |
| 12:45 | Bronsa | reduced added a ton of complexity in the impl |
| 12:46 | Bronsa | but I have to say, it's really handy |
| 12:49 | puredanger | Bronsa: I'm stepping away to work on some conj stuff but would really like those tickets. if you don't have time, drop me an email and I'll take care of it. |
| 12:50 | Bronsa | puredanger: I'll look into the code a bit more to understand what's a bug and what's just my misunderstanding but will definitely open those tickets later |
| 12:51 | Bronsa | as it stands now I'm pretty sure c.c/reduce is fine, OTOH using IReduce's reduce directly can be broken |
| 13:01 | brucehauman | hey all, Is anyone looking for a Conj ticket? |
| 13:09 | bbloom | if i suspect a `lein repl` instance, and come back, it says "Welcome back!" |
| 13:09 | bbloom | but it doesn't seem toa ctually work |
| 13:11 | justin_smith | bbloom: also, odd behavior if you try to tell it to keep running in the background |
| 13:12 | bbloom | s/suspect/suspend |
| 13:13 | stuartsierra | bbloom: I always suspect lein. |
| 13:13 | bbloom | stuartsierra: my subconscious agrees |
| 13:14 | justin_smith | bbloom: you could compare the behavior of "rlwrap java -cp $(lein cp) clojure.main" |
| 13:16 | cfleming | tbaldridge: I think your proposed solution probably leads to more code duplication, but still gets a big (inc) from me. |
| 13:22 | kanobe | So I have a Go project that uses other Go projects (i.e. has their repos cloned) |
| 13:22 | kanobe | oops wrong chan :P |
| 13:22 | kanobe | Sorry |
| 13:22 | technomancy | ~guards |
| 13:22 | clojurebot | SEIZE HIM! |
| 13:22 | technomancy | =) |
| 13:22 | hfaafb | D: |
| 13:23 | martinklepsch | In James Reeves' `template` what are endpoints useful for? https://github.com/weavejester/duct |
| 13:23 | martinklepsch | Is that for when parts of the application use different components/systems? |
| 13:27 | justin_smith | martinklepsch: I think that's the REST endpoint concept - you can have multiple endpoints that act as entities, each one accepts some subset of request methods (get/post/put/delete etc.) |
| 13:28 | stuartsierra | Isn't there a way to do (map first (partition 2 …)) with a single function? |
| 13:29 | TimMc | stuartsierra: take-nth I think |
| 13:29 | TimMc | ,(take-nth 2 (range 20)) |
| 13:29 | clojurebot | (0 2 4 6 8 ...) |
| 13:30 | stuartsierra | TimMc: That's it, thanks |
| 13:31 | TimMc | $findfn 2 [0 1 2 3 4] [0 2 4] |
| 13:31 | lazybot | [clojure.core/take-nth] |
| 13:31 | TimMc | \o/ |
| 13:31 | TimMc | You're a bot! |
| 13:41 | EvanR | can extend (the protocol thing) be used to implement java interfaces? |
| 13:41 | EvanR | like ILookup |
| 13:42 | stuartsierra | EvanR: no |
| 13:42 | EvanR | alrighty then |
| 13:44 | _2_perez | hi(L) |
| 13:45 | Bronsa | tbaldridge: ok so ArrayChunk's reduce impl is right as it is now |
| 13:46 | csd_ | What are some good books on unit testing, TDD, and debugging? They don't have to necessarily be Clojure specific |
| 13:47 | Bronsa | tbaldridge: basically reduce on a chunked-seq reduces over each chunk via ArrayChunk/reduce, that needs to return a reduced so that the chunked-seq reduce can know it has to unwrap it & return rather then reduce the other chunks |
| 13:47 | tbaldridge | which breaks the .reduce contract |
| 13:47 | Bronsa | tbaldridge: so changing that in your patch for range is wrong |
| 13:47 | Bronsa | tbaldridge: not really, that/s IChunk/reduce not IReduce/reduce |
| 13:47 | Bronsa | that's* |
| 13:48 | tbaldridge | oh, they're different, didn't know that |
| 13:48 | Bronsa | I guess that's why IChunk defines a reduce that's not IReduce's one |
| 13:48 | Bronsa | tbaldridge: it's similar to how kvreduce is implemented for maps -- kvreduce on PHM unwraps, kvreduce on the internal nodes doesn't |
| 13:49 | Bronsa | tbaldridge: yeah all that impl is kinda confusing bcause same signature but different contracts |
| 13:51 | eric_normand | I'm having trouble with tagged literals |
| 13:51 | eric_normand | This is the error message: RuntimeException No reader function for tag subspace/core-async-channe |
| 13:51 | eric_normand | (sorry, has \l at the end) |
| 13:52 | eric_normand | and this is my *data-readers*: {subspace/core-async-channel #'portal.subspace/read-channel} |
| 13:52 | eric_normand | portal.subspace/read-channel exists |
| 13:52 | eric_normand | any clues? |
| 13:52 | stuartsierra | eric_normand: Have you loaded 'portal.subspace'? |
| 13:52 | eric_normand | yes |
| 13:53 | stuartsierra | Then I got nothing. |
| 13:53 | stuartsierra | Except that data readers are rarely necessary. |
| 13:53 | eric_normand | hmm |
| 13:53 | eric_normand | I might try doing without |
| 13:53 | eric_normand | thanks |
| 13:55 | sdegutis | ,zero? |
| 13:55 | clojurebot | #<core$zero_QMARK_ clojure.core$zero_QMARK_@113722b> |
| 13:55 | sdegutis | ,one? |
| 13:55 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: one? in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 13:55 | sdegutis | Why isn't there a (one?) function? |
| 13:57 | sdegutis | ,(let [[foo1 & fooN] [1 2 3]] (if (empty? fooN) foo1 (first fooN))) |
| 13:57 | clojurebot | 2 |
| 13:57 | sdegutis | I wanted to test whether a collection had 1 or more elements. Ultimately I ended up with something like that. |
| 13:58 | dmitrygusev | why returning 2nd element then? |
| 13:59 | eric_normand | (seq coll) tests if there are one or more elements in coll |
| 13:59 | eric_normand | ,(seq []) |
| 13:59 | clojurebot | nil |
| 13:59 | eric_normand | ,(seq [1 2 3]) |
| 13:59 | clojurebot | (1 2 3) |
| 14:00 | technomancy | sdegutis: sounds like you need a pattern match |
| 14:01 | dmitrygusev | btw, quoting https://twitter.com/hlship/status/530395233410764800 : I'm experimenting with a convention that varargs arguments are prefixed with '&' (i.e. (defn foo [x & &xs]) … helps with the calling side |
| 14:01 | eric_normand | sdegutis: what technomancy said |
| 14:01 | sdegutis | See, I'm trying to return either the only one, or one that matches a pattern. |
| 14:01 | sdegutis | technomancy: I don't know what that means in Clojure. |
| 14:02 | eric_normand | sdegutis: I see. |
| 14:02 | eric_normand | what kind of pattern? |
| 14:03 | sdegutis | (str/contains ":" (:title %)) |
| 14:03 | eric_normand | nice |
| 14:03 | eric_normand | what about: |
| 14:03 | sdegutis | I could just look for the pattern first, and (or) it with (first). |
| 14:04 | sdegutis | But that's less, umm, accurate. |
| 14:04 | sdegutis | (or (filter pattern thingies) (first thingies)) |
| 14:04 | eric_normand | ,(let [coll [1 2 3] f (fn [pred coll] (or (first (filter pred coll)) (first coll)))] (f coll)) |
| 14:04 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (1) passed to: sandbox/eval142/f--143> |
| 14:04 | sdegutis | eric_normand: mainly because that fails |
| 14:04 | eric_normand | ,(let [coll [1 2 3] f (fn [pred coll] (or (first (filter pred coll)) (first coll)))] (f even? coll)) |
| 14:04 | clojurebot | 2 |
| 14:04 | sdegutis | Oh. |
| 14:08 | sdegutis | eric_normand: So yeah, we had the same idea. Seems more idiomatic Clojure, but seems much less semantically correct. |
| 14:09 | sdegutis | I admit that I sound like a heretic, but I've fallen out of love with Clojure, and I'm more annoyed with it these days than anything else. |
| 14:11 | nkoza | sdegutis: what are you using instead of clojure? |
| 14:11 | sdegutis | Nothing. |
| 14:11 | sdegutis | I just use Clojure. |
| 14:12 | xeqi | i thought pixie was the new hotness |
| 14:13 | godd2 | I just started learning Clojure, so I haven't had the opportunity to be annoyed with it yet |
| 14:13 | sdegutis | I've had my eye on Swift, but it's Apple only so pretty much useless for my job (web app). |
| 14:13 | technomancy | writing code without pattern matching is super annoying to me too, but at least for application-level stuff you can bring in core.match, right? |
| 14:13 | technomancy | I have a hard time understanding why you wouldn't, anyway |
| 14:13 | sdegutis | I've also had my eye on Rust, but I'm waiting until it's done changing before I seriously look at it. |
| 14:13 | sdegutis | technomancy: I don't know what that's for. |
| 14:14 | sdegutis | technomancy: does Clojure have pattern matching? |
| 14:14 | technomancy | sdegutis: there is a clojure lib that implements it as a macro, yeah |
| 14:14 | eric_normand | sdegutis: it's really nice |
| 14:14 | sdegutis | technomancy: core.match? |
| 14:14 | sdegutis | eric_normand: it looks nice |
| 14:14 | technomancy | yup |
| 14:14 | sdegutis | eric_normand: did you write it? |
| 14:14 | eric_normand | no |
| 14:14 | eric_normand | david nolen |
| 14:14 | sdegutis | Oh. |
| 14:15 | sdegutis | I guess that makes sense. |
| 14:15 | eric_normand | sdegutis: but I've used it |
| 14:15 | sdegutis | It looks just like a fancy (cond), is that all it does? |
| 14:16 | eric_normand | cond with unification |
| 14:16 | technomancy | that's like saying vars are just fancy variables |
| 14:16 | eric_normand | binds locals, pattern matches, and optimizes the matching |
| 14:16 | sdegutis | eric_normand: sold. |
| 14:17 | technomancy | it's like ... when you try to destructure against something that's not a collection, you get an error or nils or whatever, but pattern matching lets you offer a bunch of patterns and pick the branch that matches |
| 14:19 | sdegutis | Oh so it's also an enhanced destructuring? Nice. |
| 14:20 | sdegutis | What's a decent testing framework? |
| 14:20 | technomancy | lol |
| 14:20 | Bronsa | sdegutis: didn't you set yourself up to writing a better one for clojure last year? or am I confusing you with someone else? |
| 14:21 | sdegutis | Bronsa: That was me, I've since given up on trying to contribute to things. |
| 14:21 | sdegutis | Bronsa: So I'm just looking for a decent, stable one. Has the landscape changed since last year? |
| 14:22 | Bronsa | I've always only used clojure.test and have been happy with it. |
| 14:23 | sdegutis | I imagine clojure.test hasn't changed since last year. |
| 14:23 | Bronsa | right |
| 14:23 | sdegutis | Never mind. Perhaps I'll just fix this bug in the one I'm using. |
| 14:23 | sdegutis | (If only I knew how.) |
| 14:32 | arrdem | is there a core.logic idiom like run-1? |
| 14:33 | arrdem | run-db has an [n]. okay. |
| 14:51 | rads | is there a difference between a reference and an identity when we're talking about state management? |
| 14:51 | rads | I understand that both represent a sequence of values changing over time |
| 14:51 | gfredericks | I think I use those words interchangeable in that context |
| 14:51 | gfredericks | -bly* |
| 14:51 | TimMc | wordsbly |
| 14:52 | gfredericks | Ibly thinkbly Ibly usebly thosebly wordsbly interchangeablebly inbly thatbly contextbly |
| 14:52 | gfredericks | ^FTFM |
| 14:52 | rads | I feel like identity is a more abstract concept, and a reference type is an implementation of an identity in a program |
| 14:53 | rads | does that make sense? |
| 14:53 | gfredericks | that sounds fair |
| 14:53 | rads | that helps with my understanding a bit |
| 14:53 | rads | thanks |
| 15:03 | stuartsierra | rads: Sometimes we use "identity" to mean object identity, as in a Java Object. |
| 15:05 | justin_smith | amalloy_: I figured the eval privmsg thing out: the clojure plugin duplicates all the message dispatch logic that was in registry/try-handle, and I had only updated the latter. So I am going to abstract it out so it can continue to be correct in both places. |
| 15:14 | xyproto | Could someone please test "quine-relay-git" on Arch Linux (from AUR) and see if clojure errs out for you as well? |
| 15:14 | xyproto | Unsure if it is a problem with quine-relay or clojure. |
| 15:15 | justin_smith | I don't use arch, but may be able to help if nobody more qualified is around: what's the error message? |
| 15:16 | justin_smith | xyproto: if the error is the fact that there is no clojure package, you likely want leiningen in its stead (which is a builder / packager / runner tool for clojure, clojure is just a jar file) |
| 15:18 | kenrestivo | "ibly" sounds like something i should register and domain-squat until some startup wants to use it as their company nam |
| 15:19 | justin_smith | kenrestivo: butter jump! |
| 15:19 | justin_smith | *better, lol |
| 15:19 | kenrestivo | butterjump.com is taken |
| 15:20 | justin_smith | http://ibly.com/ also |
| 15:20 | kenrestivo | sorry, ibly is taken, butterjump.com is not |
| 15:20 | justin_smith | butterjump.com is already halfway to being viral just by the name - next you need some unwarranted enthusiasm and absurd juxtapositions of in-jokes |
| 15:21 | justin_smith | maybe some loud noises |
| 15:21 | justin_smith | and BANG you have a hit |
| 15:21 | kenrestivo | ~butterjump is a hit |
| 15:21 | clojurebot | Ok. |
| 15:21 | kenrestivo | i wonder if there's a browsable database somewhere of all the clojurebot factoids. must be some high entertainment in there |
| 15:24 | sdegutis | ~guards |
| 15:24 | clojurebot | SEIZE HIM! |
| 15:24 | puredanger | (inc guards) |
| 15:24 | lazybot | ⇒ 1 |
| 15:24 | justin_smith | ~gourds |
| 15:24 | clojurebot | SQUEEZE HIM! |
| 15:35 | gfredericks | kenrestivo: hiredman gave out a db dump once |
| 15:35 | gfredericks | I think I had it at one point but probably misplaced it |
| 16:33 | LIHOY | #bitcoin: Beware of scams! Scammers are sending users private messages with bitcoin-stealing malware and offers to trade. We are unable to stop them, so you must protect yourself. NEVER download or run programs from strangers! When in doubt, ask the ops. |
| 16:33 | LIHOY | îé |
| 16:33 | LIHOY | I'm from Russia . I thought that Russian server) fuck karoch ) |
| 16:34 | arrdem | technomancy: fingerguns required |
| 16:34 | bbloom | technomancy: ^^ |
| 16:35 | arrdem | (inc technomancy) |
| 16:35 | lazybot | ⇒ 157 |
| 16:35 | technomancy | pew pew pew |
| 16:43 | TimMc | What an odd little spammer. |
| 16:46 | hfaafb | good advice tho |
| 16:46 | akkad | teknemancy? |
| 16:46 | technomancy | hfaafb: except for the last two words, yeah |
| 16:57 | augustl | anyone got some tips for using clojure data structures from another JVM language? I'm gonna use Groovy, with Gradle as the build system. |
| 16:57 | augustl | just depend on clojure, and call something.Something.init()? |
| 17:01 | gfredericks | augustl: you might need to require RT? |
| 17:02 | gfredericks | probably not though |
| 17:02 | gfredericks | so I don't think you have to explicitly init anything |
| 17:02 | arrdem | augustl: as of 1.6 or 1.5 you no longer need to explicitly init core |
| 17:03 | augustl | afaik there's something protocol related in maps that fails without RT |
| 17:03 | augustl | I'll just try 1.6 and see what happens :) |
| 17:06 | scape_ | with string replace, how would I supply a var instead of a raw regex string? ie: #"abc" with (str "ab" "c") |
| 17:07 | scape_ | oh wait |
| 17:07 | scape_ | I can |
| 17:07 | scape_ | hah |
| 17:07 | scape_ | :-\ |
| 17:07 | scape_ | wait no i can't |
| 17:07 | arrdem | vars are an implementation detail and should always be transparent |
| 17:08 | scape_ | https://clojuredocs.org/clojure.string/replace |
| 17:08 | arrdem | which example, scape_? |
| 17:09 | dbasch | scape_: use re-pattern |
| 17:09 | scape_ | (clojure.string/replace "The color is red" #"red" "blue") where #"red" is instead (str "red") or something evaluated |
| 17:09 | scape_ | oh |
| 17:09 | scape_ | I'll see |
| 17:09 | dbasch | &(clojure.string/replace "abcabc" (re-pattern (str "ab" "c")) "def") |
| 17:09 | lazybot | ⇒ "defdef" |
| 17:10 | bbloom | (doc clojure.string/replace) |
| 17:10 | clojurebot | "([s match replacement]); Replaces all instance of match with replacement in s. match/replacement can be: string / string char / char pattern / (string or function of match). See also replace-first. The replacement is literal (i.e. none of its characters are treated specially) for all cases above except pattern / string. For pattern / string, $1, $2, etc. in the replacement string are substituted with the string that |
| 17:10 | scape_ | thanks |
| 17:10 | scape_ | repattern looks like it will work |
| 17:10 | bbloom | ,(clojure.string/replace "abc" "b" "x") |
| 17:10 | clojurebot | "axc" |
| 17:10 | bbloom | scape_: seems to work for me... |
| 17:10 | bbloom | if you use re-pattern, you'll need to escape any metacharacters |
| 17:10 | bbloom | ,(clojure.string/replace "abc" (str "b" "c") "x") |
| 17:10 | clojurebot | "ax" |
| 17:11 | dbasch | of course a string works too for that case |
| 17:11 | scape_ | yea it looks like it is |
| 17:11 | scape_ | hmm |
| 17:11 | scape_ | I get clojure.lang.Compiler$CompilerException: java.lang.IllegalArgumentException: Invalid match arg: , |
| 17:12 | scape_ | gotta look closer I think, thanks |
| 17:14 | bbloom | scape_: i bet you're not passing it what you think you're passing it |
| 17:14 | scape_ | yea I was willy nilly searching a map without checking if key existed |
| 17:15 | scape_ | thx |
| 17:18 | hfaafb | how come rich hickey never says hi to anyone here |
| 17:18 | hfaafb | i just wanna autocomplete rhickey once in my life |
| 17:18 | hfaafb | or rich |
| 17:18 | hfaafb | or whatever |
| 17:21 | bbloom | hfaafb: i think you answered your own question... people want to talk to him just to talk to him, and he wants to accomplish things :-P |
| 17:28 | rads | "rads: Sometimes we use "identity" to mean object identity, as in a Java Object." |
| 17:28 | rads | does that mean the identity of a java object is actually a value? |
| 17:29 | rads | oh darn, stuartsierra is no longer here |
| 17:30 | gfredericks | we should have a ceremonial annual event where rich comes into #clojure and everybody gets to A) suggest using github PRs instead of jira and B) request exactly one function to add to clojure.core |
| 17:30 | puredanger | yeah, that would go over great :) |
| 17:31 | dbasch | rads: no, in java different objects can have the same value |
| 17:32 | dbasch | i.e. two objects can be equal but not identical |
| 17:32 | seancorfield | gfredericks: would that be a bit like the annual event on the mailing list where the CA process is discussed? :) |
| 17:32 | gfredericks | seancorfield: oh right that should be a part of it somehow |
| 17:33 | dbasch | well, there’s always the old cardboard cutouts of rich hickey from the last conj, maybe someone can send one to hfaafb |
| 17:35 | rads | dbasch: do you know how the jvm determines if two objects are identical? does it simply compare the pointers to where the state is stored in memory? |
| 17:35 | gfredericks | maybe also everything gets to paste one stack trace they've encountered and gesture wildy while saying "just look at this thing!" |
| 17:35 | gfredericks | rads: depends on what you ask it to do |
| 17:35 | gfredericks | rads: the jvm can do pointer equality, or it can do custom equality based on Object#equals |
| 17:36 | gfredericks | clojure.core/= does something more complicated |
| 17:36 | dbasch | rads: == means are they the same reference |
| 17:36 | gfredericks | where == is java syntax |
| 17:36 | rads | I'm trying to get a fundamental understanding of these three terms: reference, value, and identity |
| 17:36 | dbasch | .equals means “do they have the same value” (for whatever definition of equals the class has) |
| 17:37 | rads | the "reference" is a location in virtual memory, correct? |
| 17:38 | rads | it's just a pointer? |
| 17:40 | arohner | rads: 'value' typically means an immutable object: "foo", 42, {:a :b} |
| 17:40 | arohner | rads: 'reference' typically means a box that can point to a value. refs, atoms and vars are all reference types |
| 17:41 | arohner | rads: identity typically means a thing that is unique, that can be found by its unique attribute. it can be an immutable value that has e.g. an :id column, or a ref where there's only one of them in the system, etc |
| 17:42 | amalloy | hmmmm. can anyone think of a case where ~''x would produce something different from '~'x? i've seen the latter numerous times, and it just occurred to me that it should be identical to the former but i've never actually seen it |
| 17:42 | rads | arohner: thanks for that succinct explanation |
| 17:43 | rads | here's something I've been wondering: is it fair to say that physical memory slots and CPU registers are the lowest level "references" available to programmers? |
| 17:43 | rads | at the operating system level at least |
| 17:43 | arohner | probably |
| 17:44 | EvanR | registers in memory on devices |
| 17:44 | gfredericks | rads: people are being wishy-washy about this because these words don't have official definitions. you just gotta figure out what are useful meanings for your context and be explicit about that when you need to |
| 17:46 | rads | so technically there's no limit to how far you can "move the reference up" in a functional program, since you could represent your program as a function on the current state of the CPU registers and physical memory |
| 17:46 | rads | does that make sense? |
| 17:46 | EvanR | rads: its useful to consider yourself working on a virtual machine with abstract notions of whatever the programming language is manipulating |
| 17:46 | dbasch | rads: memory and cpu registers are not “references”, any more than a mailbox or the trunk of your car is a reference |
| 17:46 | dbasch | they are storage units |
| 17:46 | dbasch | you can refer to them, of course |
| 17:46 | EvanR | thinking that you are direct accessing anything at any level is either misguided or inappropriate for the current abstraction |
| 17:47 | EvanR | virtual memory, microcode, its all a lie |
| 17:48 | EvanR | the internet protocol is a rich source of abstractions over things no one has ever heard of, or cares about for the purposes of application programming |
| 17:49 | rads | okay, so you make references that point to locations in storage units |
| 17:49 | EvanR | for example |
| 17:49 | rads | the storage unit is abstract |
| 17:49 | rads | could be a CPU register, could be redis |
| 17:49 | rads | the reference is a symbol within the program that provides access to that location within the storage unit? |
| 17:50 | rads | is `int c` a reference in the C programming language since it changes mutable state? |
| 17:50 | justin_smith | rads: no, it is a storage location |
| 17:51 | justin_smith | rads: vars or local bindings provide access via symbols to those locations |
| 17:51 | justin_smith | that is no it is not a symbol |
| 17:51 | EvanR | int c is a declaration for storage |
| 17:52 | dbasch | in C, int c means “make a space for an int in the stack, and when you see c in this scope I’m talking about that space” |
| 17:52 | rads | I'm using C as an example for now because it's simpler than clojure's model |
| 17:52 | EvanR | dbasch: depending on where it appears |
| 17:52 | EvanR | rads: you think? |
| 17:52 | dbasch | EvanR: yeah, I’m assuming a function |
| 17:52 | justin_smith | "int c" tells the c compiler you want to refer to some location in the stack or memory heap by the symbol c |
| 17:53 | justin_smith | "(def c)" tells clojure you want to refer to something, within this namespace, by the symbol c |
| 17:53 | rads | EvanR: not for writing programs on top of, but it's easier for me to understand if I can see the connection of the system itself |
| 17:53 | EvanR | do does (declare c) |
| 17:53 | EvanR | so* |
| 17:53 | oskarkv | amalloy apparently ``'~'x is not the same as ``~''x. I don't know how to think about these cases, ie how to predict what they will produce |
| 17:53 | justin_smith | rads: (let [c 1]) tells clojure that you want to refer to 1 locally as c |
| 17:53 | rads | I see |
| 17:54 | rads | what if you're mutating a struct? is the struct a reference? |
| 17:54 | justin_smith | rads: everything in the jvm that is not a primitive is a reference type |
| 17:54 | EvanR | rads: "the system" is another abstraction, you just more familiar with it, but its not even that simple of an abstraction |
| 17:54 | amalloy | oskarkv: well, ``~''x is identical to `''x |
| 17:54 | amalloy | because `~ is a no-op |
| 17:55 | rads | I'm trying to understand how `c = 1` in C is different than `(reset! c 1)` in clojure |
| 17:56 | rads | the end result is the same for the programmer |
| 17:56 | justin_smith | rads: so, if you are mutating a "struct" that struct will be represented in the jvm as an "Object" - an instance of some "Class", and you can refer to it the same way you would any other value - via local binding, or a namespaced global var |
| 17:56 | rads | in clojure, c is a reference type |
| 17:56 | technomancy | I had a waaaay easier time understanding C pointers after learning clojure's reference model. |
| 17:56 | justin_smith | rads: or of course a value in a slot of some other Object |
| 17:56 | technomancy | not that they're the same thing, but the fact that clojure's model was so explicit helped me keep the concepts straight in C where they can be fuzzier |
| 17:57 | dbasch | rads: for one, c = 1 is not an atomic operation |
| 17:57 | EvanR | the storage units in question have different lifetimes |
| 17:58 | rads | is reset! atomic? |
| 17:58 | EvanR | rads: its not exactly right to call anything in C a reference |
| 17:58 | rads | I thought you only get atomicity with swap! |
| 17:58 | dbasch | rads: what does reset! operate on? |
| 17:59 | rads | you would get the same semantics if you replaced c variables with atoms and only used resets instead of assignment, wouldn't you? |
| 17:59 | rads | C, the language, variables I mean |
| 17:59 | EvanR | C the language doesnt guarantee any atomic operations |
| 18:00 | rads | but I'm saying if you have a bunch of writers using reset! on an atom, those operations are also not atomic |
| 18:00 | rads | even though the reference type is called an atom |
| 18:00 | EvanR | :doc reset! |
| 18:01 | rads | "Sets the value of atom to newval without regard for the |
| 18:01 | rads | current value. Returns newval." |
| 18:01 | rads | if there is no coordination of the previous value, how can there be atomicity? |
| 18:01 | dbasch | rads: there is a subtle difference |
| 18:02 | dbasch | you could execute a clojure program in discrete steps and a c program in discrete steps too |
| 18:02 | dbasch | right after a reset!, the value would be what you put in |
| 18:02 | tuft | atomicity just means it either happens completely or not at all. if two threads try to assign the same variable in C a third may see an inconsistent state / partial update |
| 18:02 | dbasch | in c, the step after an assignment makes no guarantees if there are concurrent assignments |
| 18:02 | technomancy | dbasch: reset! is the same though |
| 18:04 | rads | so when you do `c = 1` in a C program, it is not immediately visible to other threads with access to the same memory location? |
| 18:04 | EvanR | youre not guaranteed to see the value you put it right after putting it in |
| 18:04 | dbasch | technomancy: you’re right, just looked at the code |
| 18:04 | rads | and the different with clojure is that the other threads will see the new value immediately? |
| 18:04 | rads | difference* |
| 18:04 | technomancy | atomicity only matters if the new value is based on the old |
| 18:05 | technomancy | (so, swap! but not reset!) |
| 18:05 | rads | yes, that's what I was confused about |
| 18:05 | EvanR | rads: when you were asking about atomicity issues, i was thinking you were talking about word tearing |
| 18:05 | EvanR | like your variable gets half way committed |
| 18:06 | tuft | yeah that's what i'm talking about |
| 18:06 | tuft | that to me is atomicity too |
| 18:06 | oskarkv | amalloy yeah but I have trouble understanding what happends with ``'~'x |
| 18:06 | oskarkv | happens* |
| 18:06 | rads | my main motivation for this is figuring out what a useful AtomicReference implementation might look like in JavaScript |
| 18:06 | tuft | the other thing is more about serialization |
| 18:06 | amalloy | oskarkv: nothing very good. it's hard to imagine wanting to use taht |
| 18:07 | EvanR | rads: in browser javascript you are in luck, because the threads do not interleave, everything you do is atomic in this sense |
| 18:07 | oskarkv | hehe but i'm curious. amalloy do you understand it? :P |
| 18:07 | amalloy | take a look at even like ##``'x |
| 18:07 | lazybot | ⇒ (clojure.core/seq (clojure.core/concat (clojure.core/list (quote quote)) (clojure.core/list (quote clojure.core/x)))) |
| 18:07 | tuft | rads: doesn't ClojureScript already have an atom? |
| 18:07 | amalloy | `'~'x produces the code necessary to output (quote x) |
| 18:07 | dbasch | rads: javascript is single-threaded (at least in the browser) so atomicity means nothing |
| 18:07 | rads | tuft: yeah I'm talking JS only |
| 18:08 | rads | it becomes important when you're synchronzing data with the server |
| 18:08 | EvanR | javascript over the years has silently saved countless programmers from even knowing that concurrent programming challenges exist |
| 18:08 | amalloy | ``'~'x produces the code necessary to produce the code necessary to output (quote x), which is not very useful |
| 18:08 | tuft | yeah no volatiles in js land |
| 18:08 | tuft | except web workers? |
| 18:08 | dbasch | rads: no, it means nothing |
| 18:08 | EvanR | tuft: new fangled contraptions ;) |
| 18:08 | rads | what if I want to perform an operation on the client concurrently with other clients? |
| 18:08 | oskarkv | amalloy yeah ok gonna think about it some more. Just as an exercise ;) |
| 18:09 | rads | that needs to be an atomic operation |
| 18:09 | oskarkv | thanks |
| 18:09 | dbasch | rads: in that case you care about atomicity on the server side |
| 18:09 | EvanR | rads: are you sure you are using the word correctly yet? |
| 18:10 | rads | maybe this is a better phrasing: I want to make an abstraction in JavaScript that makes performing atomic operations between the client and server easier |
| 18:10 | technomancy | hooo boy |
| 18:10 | dbasch | I give up |
| 18:10 | technomancy | so yeah, a distributed system is completely different |
| 18:11 | tuft | rads: could we have a concrete example please? |
| 18:11 | technomancy | welcome to CAP theorem =) |
| 18:11 | dbasch | the point is that if you run an operation in js, nobody will come and change your state while it’s pending |
| 18:11 | rads | I can't go into a ton of detail |
| 18:12 | rads | basically I want to perform simple synchronization between the client and server in a web app where the writes are not very common, but better than just last write wins |
| 18:12 | tuft | rads: maybe you can obfuscate your $1e6 idea sufficiently? =) |
| 18:12 | dbasch | rads: if you’re competing with other clients, it’s up to the server to synchronize access to whatever |
| 18:13 | rads | I just don't want to risk violating any contracts with my employer, sorry |
| 18:13 | dbasch | e.g. you and someone else are trying to buy the last ticket to a concert |
| 18:13 | tuft | rads: what dbasch said |
| 18:13 | dbasch | either you buy it or the other person does, but there’s nothing the browser can do about it |
| 18:14 | rads | dbasch: no, but the browser can perform the operation optimistically. at that point you have two states to reconcile when you get the next response from the server |
| 18:15 | dbasch | rads: why would you want to do that? |
| 18:15 | rads | why would I want to perform operations optimistically before I get a response from the server? |
| 18:15 | dbasch | not for that example. Are you writing a text editor that claims to save but really hasn’t saved anything? |
| 18:16 | rads | it's more about not making the UI block when the user performs an action |
| 18:17 | rads | otherwise you have to wait for the server response to have a consistent state if you have no plan to reconcile any optimistic opereations |
| 18:18 | rads | technomancy: any recommendations for learning about distributed systems? |
| 18:19 | rads | dbasch, tuft: I appreciate your help so far. this is a tough problem |
| 18:19 | dbasch | rads: look into Om if you want to do this in Clojure |
| 18:20 | dbasch | or any other react-based framework |
| 18:20 | rads | that's what this is for, a react application |
| 18:21 | rads | trying to understand how the different pieces fit together and centralize the state synchronization with the server in one place |
| 18:21 | rads | I followed Om closely when it came out last year, but I'm trying to understand the fundamentals behind Om itself |
| 18:22 | rads | so that maybe I could contribute back to Om one day with a better understanding of these principles |
| 18:41 | myguidingstar | hi all, what is the best way to write a Leiningen template? |
| 18:42 | myguidingstar | is there anyway to make one from a working project? |
| 18:43 | justin_smith | myguidingstar: not that I know of. But there is "lein new template [name]" |
| 18:43 | myguidingstar | well, I know that |
| 18:44 | justin_smith | oh, you knew about the template template? |
| 18:44 | justin_smith | have you checked out the files it makes? |
| 18:46 | myguidingstar | I know how to write lein template from scratch |
| 18:47 | myguidingstar | I'm thinking of a conventional way to convert a 'working temple' into a template with {{placeholders}} |
| 18:47 | myguidingstar | s/working temple/working template/ |
| 18:48 | myguidingstar | oh, I meant 'working project' |
| 18:48 | justin_smith | if that exists, I have not heard of it |
| 18:49 | technomancy | you should write one =) |
| 18:49 | myguidingstar | technomancy, yeah, I'm thinking of it |
| 18:51 | myguidingstar | should be a set of rules: hello-project (real, runnable symbols!!!) to {{placeholders}} |
| 18:53 | myguidingstar | and finally: "lein templatize input-dir output-dir" |
| 18:54 | myguidingstar | technomancy, any suggestions about such rules? |
| 18:54 | technomancy | part of the reason it doesn't exist yet is it's difficult to come up with sufficiently generalizable rules =) |
| 19:04 | andyf | technomancy: "Subprocess failed." Is printed by lein if a plugin does (System/exit 1) and that is by design, yes? Just confirming |
| 19:08 | technomancy | andyf: ideally the plugin could replace that generic message with something more descriptive, but if they don't, then yeah that's what you'd see if a project JVM exited nonzero. |
| 19:09 | andyf | Understood. I'm just documenting it for now since it wasn't already and someone thought it was a bug in Eastwood |
| 19:14 | gfredericks | andyf: is issue #21 still unworked-on, and is it work-onable? |
| 19:16 | andyf | gfredericks: I think I have both time and interest to get a start on it this weekend, but it depends how much time it takes me to finish #93 first |
| 19:17 | andyf | But if you want to go for it, I don't mind |
| 19:17 | gfredericks | okay I will give you a heads up if I do |
| 19:19 | andyf | I keep getting reminded when creating linters (1) how much easier tools.analyzer makes it, and (2) how much I don't know about corner cases that exist when I start |
| 19:20 | technomancy | andyf: I'd recommend doing eval-in-project in a try/catch and watching for :exit-code on an ExceptionInfo |
| 19:21 | technomancy | also... why ExceptionInfo and not InfoException? |
| 19:21 | gfredericks | well it's not an exception due to Info |
| 19:22 | andyf | On the exception name, Bronsa named it |
| 19:23 | technomancy | it's less verbose at least than DataConevyingException |
| 19:23 | Bronsa | andyf: I believe technomancy is talking about c.l.ExceptionInfo, not about t.a.j.ExceptionThrown |
| 19:23 | andyf | Or is there an existing InfoException you are asking why we are not using it instead? |
| 19:23 | gfredericks | clojure.lang.ClojureProblem |
| 19:23 | Bronsa | but I haven't read the scrollback so I might not have all the context |
| 19:25 | technomancy | total bikeshed, forget I said anything |
| 19:25 | andyf | Bronsa: You did not choose name of ExceptionInfo in tools.reader? |
| 19:26 | Bronsa | ah |
| 19:26 | andyf | Wait, what were we talking about again? :-) |
| 19:26 | Bronsa | andyf: not really, that's just to implement c.l.ExceptionInfo in clj 1.3 or whatever the version |
| 19:27 | Bronsa | puredanger: ah by the way, importing by default ExceptionInfo would be super for writing cross language code. |
| 19:27 | andyf | Bronsa: I currently aot that class only in Eastwood and I recall adding that because things broke without doing so |
| 19:27 | eric_normand | clojure.edn/read does not use *data-readers* |
| 19:28 | eric_normand | is that a bug? |
| 19:28 | Bronsa | eric_normand: no, a design choice |
| 19:28 | eric_normand | Bronsa: why? |
| 19:28 | Bronsa | eric_normand: c.edn/read has a different signature than c.c/read |
| 19:28 | Bronsa | eric_normand: it uses a map arg rather than dynamic vars |
| 19:28 | andyf | eric_normand: it lets you specify them in arg I think? |
| 19:28 | eric_normand | I see |
| 19:29 | andyf | More explicit that way |
| 19:29 | eric_normand | yes |
| 19:29 | Bronsa | andyf: dunno, I don't recall how compilation works there. but tools.reader's ExceptionInfo is only used by clj <=1.3 |
| 19:33 | andyf | Bronsa: Namespace c.t.reader.impl.utils requires it unconditionally, doesn't it ? |
| 19:34 | Bronsa | andyf: ah yeah. right so it has to be AOT compiled or the type hint will fail |
| 19:35 | Bronsa | andyf: now I remember, loading the namespace conditionally would mess with maven or something like that |
| 19:35 | andyf | No big deal for me. Just making sure I wasn't missing something |
| 19:37 | andyf | Bronsa: Some years down the road I hope that (= 3 (:minor *clojure-version*)) requires updating :-) |
| 19:37 | Bronsa | heh |
| 19:38 | Bronsa | andyf: I'm just counting on the fact that when (if) the time comesclojure 2.x will break so much existing code that changing that will be the last of my problems |
| 19:38 | andyf | Probably so |
| 19:38 | technomancy | MAH EYEZ https://github.com/ztellman/cambrian-collections/blob/master/project.clj#L10-L15 |
| 19:39 | technomancy | why, github, why? |
| 19:39 | technomancy | is this revenge for something untoward rich said about pull requests? |
| 19:39 | Bronsa | lol |
| 19:39 | Bronsa | technomancy: syntax highlighting for clojure has been broken for over 20 days :( |
| 19:39 | andyf | Github has seen the rising tide of Clojure popularity and is trying to quell it |
| 19:40 | justin_smith | technomancy: what really got me was the bright red highlighting of some square brackets in racket code |
| 19:40 | justin_smith | but yeah, that is pretty wtf too |
| 19:40 | technomancy | http://p.hagelb.org/chair.gif |
| 19:42 | andyf | But how do you feel, really? |
| 19:42 | technomancy | actually it's a shame the gif cuts off where it does |
| 19:42 | technomancy | because the next few frames reflect it perfectly |
| 19:43 | justin_smith | that movie was surprisingly good |
| 19:43 | andyf | Youtube source? |
| 19:43 | technomancy | (inc lego-movie) |
| 19:43 | lazybot | ⇒ 1 |
| 19:44 | technomancy | andyf: http://www.youtube.com/watch?v=YkCeUjvgXRk |
| 19:45 | Jaood | to bad that patch didn't made it to 1.7 |
| 19:46 | amalloy | justin_smith: currently in https://github.com/flatland/useful/blob/develop/src/flatland/useful/seq.clj, some of the commas are highlighted bright red and some are not |
| 19:46 | Bronsa | Jaood: which patch? |
| 19:46 | amalloy | i think it's the case that commas preceded by punctuation are bright red; if there's a letter before it, it's not |
| 19:46 | Jaood | Bronsa: ztellman's |
| 19:47 | justin_smith | amalloy: woah, that sucks |
| 19:51 | andyf | Time to make an overlay site for github with better highlighting choices? |
| 19:51 | technomancy | andyf: yeah, a userstyles.org thing would be great |
| 19:51 | justin_smith | maybe a petition of payed members (I pay for membership there, and I would sign) |
| 19:52 | martinklepsch | whats a good project to look at to understand the component system? I looked at duct but it seems to be different to most (https://github.com/weavejester/duct) |
| 19:52 | justin_smith | s/membership/account I guess |
| 19:52 | technomancy | maybe it's a sign that github's pseudomonopoly needs to come to an end |
| 19:53 | technomancy | I really wish I could recommend gitlab. so close, but still frustrating. |
| 19:54 | hyPiRion | Let's make something ourselves, how hard could it be |
| 19:54 | andyf | Pushes, pulls, issues, free hosting of public files and static web pages. All still good |
| 19:57 | technomancy | a fork of gitlab that actually uses the project readme as the splash page. boom. |
| 19:58 | justin_smith | maybe the new highlighting is a passive-agressive way to encourage us to do less code-browsing on site |
| 19:58 | justin_smith | (original definition of passive-agressive, not the new one) |
| 19:59 | hyPiRion | the new one? |
| 19:59 | justin_smith | hyPiRion: where people call being friendly while making a criticism, or leaving a note, or being indirect "passive agressive" |
| 19:59 | justin_smith | the old definition was pretty specific: undermining a project without overt hostility |
| 20:00 | Jaood | technomancy: but gitlab is for self-hosting so you can really compare them? |
| 20:00 | Jaood | s/can/can't/ |
| 20:00 | technomancy | Jaood: gitlab is both |
| 20:01 | technomancy | but they make some decisions that only make sense in the context of private repos |
| 20:01 | technomancy | like refusing to use readmes as splash pages |
| 20:01 | technomancy | they have hosted gitlab both for OSS and private stuff |
| 20:04 | Jaood | technomancy: oh true, was not obvious from their landing page |
| 20:06 | Jaood | technomancy: you don't like bitbucket? |
| 20:07 | technomancy | Jaood: I remember being very unimpressed with the issues system |
| 20:07 | technomancy | but GH's isn't great either |
| 20:08 | technomancy | maybe it just reminded me too much of jira |
| 20:10 | michaniskin_ | what's the best way to read in a clojure file that contains forms like ::foo/bar? |
| 20:10 | michaniskin_ | i don't want to evaluate it, i just want to read the forms |
| 20:11 | Bronsa | michaniskin_: it's not possible without at least evaluating the namespace form |
| 20:11 | michaniskin_ | wonderful |
| 20:11 | michaniskin_ | thanks Bronsa |
| 20:12 | Bronsa | michaniskin_: well that's not entirely true I guess, you *can* read it without evaluating it, all you need is the alias setup |
| 20:12 | michaniskin_ | yeah i have that already |
| 20:12 | michaniskin_ | i was just checking that i wasn't insane |
| 20:13 | michaniskin_ | i was hesitant to assume that reading and evaluation were complected |
| 20:14 | Bronsa | michaniskin_: also you can use tools.reader to do that without messing with the namespace system if you already know the aliases |
| 20:14 | Bronsa | michaniskin_: https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader.clj#L303-L313 |
| 20:14 | michaniskin_ | i don't want an AST, i want to read forms |
| 20:14 | Bronsa | michaniskin_: tools.reader is not tools.analyzer :) |
| 20:14 | michaniskin_ | ah ok |
| 20:15 | michaniskin_ | yes i have some filthy code that sniffs ns decls |
| 20:15 | michaniskin_ | but i don't feel good about myself when i think of it |
| 20:16 | michaniskin_ | it makes me sad how clojure seems to get more complicated every release |
| 20:16 | michaniskin_ | instead of more elegant |
| 20:16 | Bronsa | really? why do you say that? |
| 20:16 | andyf | You are in good company, if it is anything like tools.namespace ns form detection |
| 20:17 | michaniskin_ | well i make a lot of build tooling, and it just requires more and more filthy hacks every release |
| 20:17 | michaniskin_ | i have a ghetto compiler basically to emulate the evaluation that's mixed up in the reader |
| 20:18 | Bronsa | michaniskin_: I'm just curious, examples of features added in recent releases that complicate it? |
| 20:18 | michaniskin_ | ::foo/bar is a big one |
| 20:18 | Bronsa | that's been there since 1.0 |
| 20:18 | michaniskin_ | also the stuff that supports that kind of thing in the destructuring forms |
| 20:18 | michaniskin_ | tagged literals in source files |
| 20:19 | andyf | michaniskin_: How do those features affect a build tool? |
| 20:19 | michaniskin_ | because you can't manipulate source files without evaluating them in some way |
| 20:19 | andyf | Maybe you do want tools.analyzer :-) |
| 20:19 | michaniskin_ | instead of being able to read lists like normal, you need a context in which to evaluate a minilanguage |
| 20:19 | Bronsa | michaniskin_: the only valid complaint I'll give you is the one about tagged literals, but that's been there for 2 years now |
| 20:20 | michaniskin_ | if you do a lot of metaprogramming stuff these affordances really weigh on you |
| 20:21 | michaniskin_ | anyway i know it's a minority opinion |
| 20:21 | Bronsa | michaniskin_: don't get me wrong, I can agree with you if you said that some things in clojure could be easier, I just don't agree on you when you say that it's getting more complex with every new release |
| 20:22 | michaniskin_ | i don't want it to be easier, i want it to be simpler :) |
| 20:22 | andyf | I don't know exactly the goals your tool have, but I wonder whether there is a different approach that works better with Clojure, rather than at odds with it |
| 20:22 | Bronsa | forgive my loose usage of language, that was not my point though |
| 20:22 | michaniskin_ | haha i know, i'm just pulling your chain :) |
| 20:23 | michaniskin_ | but seriously this is how it seems to me, things getting easier but less simple |
| 20:23 | Bronsa | andyf: I guess the biggest source of "complexity" for tool writers for clojure is that clojure's evaluation model is form-at-a-time and that the namespace system is mutable |
| 20:24 | michaniskin_ | Bronsa: yes, that, too. that's exactly right |
| 20:24 | Bronsa | andyf: it's much better for cljs `ns` is a special form and there's no way to intern something at runtime |
| 20:25 | michaniskin_ | we're currently experimenting with that with boot |
| 20:25 | michaniskin_ | using fresh clojure runtimes for each expression and so forth |
| 20:26 | michaniskin_ | maybe what i need is a language that compiles to clojure |
| 20:33 | andyf | Bronsa: I tried timing whole Eastwood crucible run with 1.7 alpha3 vs alpha4 and it went from 36.3 mins to 33.3 mins. Nice, but not huge. |
| 20:34 | andyf | I think of code speedups as opportunity to add more projects in :-) |
| 20:41 | justin_smith | amalloy: pr that fixes the privmsg triggers on lazybot submitted |
| 20:41 | justin_smith | also, it is a clean history |
| 20:42 | amalloy | *chuckle* |
| 20:42 | amalloy | justin_smith: you tested it? |
| 20:42 | justin_smith | yes indeed |
| 20:42 | justin_smith | but feel free to double check my work, of course |
| 20:43 | Bronsa | andyf: yeah alpha4 has only load time enhancements, alpha3 had a big impact on runtime for t.a.jvm because of better caching in multimethods |
| 20:46 | arrdem | justin_smith: r u havin a giggle there with lossy karma m8 |
| 20:46 | justin_smith | heh |
| 20:47 | justin_smith | arrdem: note that that hasn't been submitted officially as a pr (yet?) |
| 20:47 | amalloy | justin_smith: i think he is now not responding to PMs which are commands *or* inline hook things |
| 20:47 | justin_smith | err... |
| 20:49 | amalloy | itym Raynes/lazybot#104 |
| 20:49 | lazybot | correct privmsg handling -- https://github.com/Raynes/lazybot/pull/104 is closed |
| 20:49 | arrdem | huh. didn't know about that command. |
| 20:50 | amalloy | arrdem: well, of course it's not actually a command but a hook: if he sees user/repo#issuenum in any message he says that |
| 20:50 | arrdem | justin_smith: yo was this supposed to get comitted? https://github.com/noisesmith/lazybot/commit/a79782382763cef9cc00f08b8b03c621443742f0#diff-f3ec7c8cbebc04166e5e467a96fe641aR30 |
| 20:51 | justin_smith | arrdem: damn, gotta fix that too, thanks |
| 20:51 | arrdem | np |
| 20:52 | justin_smith | this pr was not as ready as I thought it was... |
| 20:53 | justin_smith | amalloy: odd, I am sending anybot clojure commands and he is evaluating them |
| 20:54 | justin_smith | amalloy: he is evaluating regular commands but only when prefix is supplied... |
| 20:55 | justin_smith | and the only diff I see from upstream/master is the removal of that pprint |
| 21:54 | Bronsa | andyf: not sure if this will help you w/ eastwood, but t.a now supports early termination of walking at any point via reduced: http://sprunge.us/UNdd?clj |
| 21:55 | andyf | Nice. Can't think of where I'd use that, but will try to keep it in mind. Tend to just scan all the nodes. |
| 21:55 | Bronsa | the impl suffered a bit in readability but this is a great feature to have when needed |
| 21:56 | Bronsa | andyf: e.g. in the mexpansion-steps function I wrote a while ago for cfleming I used a dyn var to short-circuit walking after the first macroexpansion, this makes it possible to do that without it |
| 21:57 | Bronsa | then: https://gist.github.com/Bronsa/28720fbc280d661f91d7/007717a14f48488bc5e795b5ea45ea5af3322166#file-gistfile1-clj-L46-L47 vs now: https://gist.github.com/Bronsa/28720fbc280d661f91d7#file-gistfile1-clj-L44 |
| 22:00 | andyf | Today I learned that using :raw-forms, your assumptions of what is there can be made wrong if someone uses their own custom macro expander, as tools.macro's with-symbol-macros does |
| 22:01 | gfredericks | dang symbol-macros |
| 22:01 | gfredericks | andyf: do you know if riddley does that too? |
| 22:01 | Bronsa | andyf: your assumption of my assumption? :P |
| 22:02 | andyf | I don't know about riddley. |
| 22:02 | Bronsa | gfredericks: IIRC riddley's macroexpander matches clojure's |
| 22:03 | andyf | My assumption. My approach to writing linters is to look at ast contents of one or a few cases, write some pattern matching conditions, and see what happens. Usually works well |
| 22:03 | Bronsa | ah, gotcha |
| 22:03 | Bronsa | andyf: have you thought about using core.match for eastwood linters btw? could save you some trouble |
| 22:04 | andyf | Fortunately this is "only" a linter, so if I don't catch everything possible, it is par for the course |
| 22:04 | ztellman | riddley matches it, but also does inline expansion |
| 22:05 | Bronsa | ztellman: I believe clojure's does too |
| 22:05 | ztellman | Bronsa: it doesn't |
| 22:05 | Bronsa | ,(macroexpand-1 '(inc 1)) |
| 22:05 | clojurebot | (inc 1) |
| 22:05 | lazybot | ⇒ 9 |
| 22:05 | andyf | Thought about it, but haven't learned core.match yet. |
| 22:05 | Bronsa | ouch. |
| 22:05 | Bronsa | ztellman: weird, I assumed it did |
| 22:05 | ztellman | so did I, until it bit me |
| 22:05 | Bronsa | I guess it does inlining later during analysis |
| 22:06 | ztellman | likewise, (clojure.walk/postwalk macroexpand ...) doesn't do what it should in quoted forms |
| 22:06 | ztellman | and a bunch of other things |
| 22:06 | ztellman | basically clojure.walk/macroexpand-all is badly named |
| 22:07 | Bronsa | macroexpan-all-and-maybe-more? |
| 22:07 | andyf | Sorry, what is it in "riddley matched it "? |
| 22:07 | ztellman | macroexapnd-some-and-maybe-more |
| 22:07 | andyf | A subset of a superset of the right thing? |
| 22:07 | Bronsa | ztellman: I know about the "maybe-more" what about the "some"? :) |
| 22:07 | ztellman | Bronsa: the inlined forms |
| 22:07 | Bronsa | ah ok |
| 22:08 | gfredericks | "A subset of a superset of X" can be basically anything I think |
| 22:08 | gfredericks | that must be the joke |
| 22:08 | ztellman | andyf: I'm not following |
| 22:08 | andyf | That's what I was going for |
| 22:08 | Bronsa | well the subset of the superset of x kinda approximates x |
| 22:08 | gfredericks | joke explanations brought to you by gfredericks |
| 22:08 | Bronsa | kinda sorta until it stops working |
| 22:09 | andyf | ztellman: Earlier you said "riddley matches it ..." and I didn't understand the meaning |
| 22:09 | ztellman | ah! I mean riddly matches the compiler's macroexpansion behavior |
| 22:09 | ztellman | +e |
| 22:10 | ztellman | the clojure.walk version is both less and more than the compiler's macroexpansion |
| 22:11 | Bronsa | riddley could be implemented in a couple of lines using t.a.jvm btw :P |
| 22:12 | ztellman | Bronsa: well, I'm actually using the LOCAL_ENV exposed by the compiler, so I'm more guaranteed to be accurate, but sure |
| 22:12 | Bronsa | ztellman: that's true, yeah |
| 22:13 | ztellman | I don't recall t.a.jvm being available at the time, though |
| 22:13 | ztellman | maybe I wasn't paying attention |
| 22:14 | Bronsa | ztellman: it was still really alpha at the time |
| 22:15 | Bronsa | it's unfortunate that the vals of &env leak compiler classes rather than an info map. luckly because of that almost nobody uses it (except probably ztellman and amalloy) |
| 22:16 | ztellman | Bronsa: the compiler was clearly never designed with extensibility in mind, I'd be overjoyed if that were changed |
| 22:16 | ztellman | but I'm only brave enough to poke at the compiler a bit |
| 22:18 | arrdem | more or less convinced that the existing compiler is ossified by simple virtue of core not being interested in changes to it forget anything else |
| 22:20 | andyf | Other fish for them to fry, most likely |
| 22:21 | andyf | C-in-C seems to be taking shape nicely, though |
| 22:21 | andyf | Thanks to someone whose nick rhymes with kadonsa |
| 22:29 | cfleming | While we're talking macroexpansion, is it true that if I want to accurately expand a subform inside some larger form, I would have to macroexpand all its ancestors from the top-level form down to the form I want, but should not have to macroexpand any of the siblings of those ancestors? |
| 22:29 | arrdem | unless your users are evil people who have non-toplevel defmacros |
| 22:30 | cfleming | Unfortunately I have to assume that all my users are potentially evil |
| 22:30 | cfleming | Or at least misguided |
| 22:30 | andyf | Other possible evilness that is rare: macros with side effects during expansion |
| 22:31 | andyf | E.g. gen-class if I recall correctly |
| 22:31 | Bronsa | midje does interning at macroexpansion for example |
| 22:32 | cfleming | I see - I actually did that myself while trying to write my macroexpand stepper, I used an atom to count when to stop. |
| 22:32 | andyf | gen-class writes to file system |
| 22:32 | cfleming | Bronsa: I'll have to go back and look at your example again. The feedback I got was that naive stepping took too long and was tedious for large forms. |
| 22:33 | cfleming | But it turns out to be quite hard to support accurate expansion of arbitrary subforms. |
| 22:33 | justin_smith | andyf: during macro expansion? |
| 22:34 | Bronsa | cfleming: if you want to try https://gist.github.com/Bronsa/28720fbc280d661f91d7 out, behare that you'll need t.a and t.a.j from master |
| 22:35 | cfleming | Thanks, I'll take a look. I'm a little worried about needing t.a. and t.a.j as a dependency since I'd have to load them into the user's REPL, but I might have to. |
| 22:35 | andyf | justin_smith: Yes. |
| 22:35 | justin_smith | wow |
| 22:35 | cfleming | I wanted to use Riddley, but that was also slightly complicated by the need to load a Java class over a REPL connection. |
| 22:37 | andyf | cfleming: Eastwood uses a copy and rename hack to avoid namespace version conflicts with user projects. Not fun, but effective |
| 22:37 | cfleming | andyf: gen-class just writes the class files, right? Or does it write more than that? |
| 22:37 | cfleming | andyf: Yes, I'd have to do that, for sure. |
| 22:37 | andyf | cfleming: I think only 1 class file |
| 22:37 | TEttinger | I'm wondering if anyone with experience in uberjar internals would be able to make sense of this issue I'm having bundling JREs with Clojure Uberjars, but not Java Runnable Jars. https://github.com/libgdx/packr/issues/33#issuecomment-62863164 |
| 22:38 | TEttinger | that's a jump to the comment that gets to what I think the issue may be |
| 22:41 | cfleming | andyf: I assume proxy probably does as well - deftype/reify have built in forms so they don't have to. |
| 22:42 | andyf | I don't recall the others I found right now - keeping a list for future reference would have been a good idea |
| 22:46 | cfleming | I guess definterface etc as well - pretty much anything pre-protocols which generates a class |
| 22:47 | Bronsa | cfleming: btw if you're interested in that, I think I can think of a way to do out-of-order macroexpansion with t.a.jvm |
| 22:47 | Bronsa | cfleming: you're correct, yes |
| 22:47 | cfleming | Bronsa: I am definitely interested in that. |
| 22:48 | Bronsa | deftype/defprotocol/reify do that at analysis time otoh |
| 22:48 | cfleming | I'm still not sure how the UI should work, but basically the desire is to be able to select a form for expansion, and have that expansion be as accurate as possible. |
| 22:49 | justin_smith | regarding proxy, I just did ##(proxy [Object] [] (toString [] "boo")) and did not see anything show up on disk |
| 22:49 | lazybot | java.lang.ClassCastException: clojure.lang.Var$Unbound cannot be cast to clojure.lang.DynamicClassLoader |
| 22:49 | cfleming | justin_smith: Actually, proxy might just define the class from memory directly. |
| 22:50 | cfleming | justin_smith: gen-class and definterface have to. |
| 22:50 | Bronsa | justin_smith: proxy aots only with *compile-files* true |
| 22:50 | justin_smith | cool |
| 22:50 | cfleming | to write to disk, that is. |
| 22:51 | justin_smith | cfleming: now that I think about it, it makes sense on an intuitive level that the constructs that directly deal with java stuff like classes / interfaces would construct things on disk |
| 22:51 | Bronsa | cfleming: yes I think I understand what you need. I'm going to sleep now but I'll think about it & let you know if it can be done in a reasonable way |
| 22:51 | cfleming | Bronsa: BTW Cursive can now mark vars that are not used anywhere in the project |
| 22:51 | justin_smith | while more abstracted stuff may not |
| 22:51 | cfleming | Bronsa: Ok, thanks. I'm pretty busy right now, this will all be post-conj, so no rush. |
| 22:53 | cfleming | justin_smith: Right, it's just a little odd that it happens in macroexpansion. It makes sense though since there's really no other time to do it without language changes. |
| 22:54 | justin_smith | yeah, a side-effect-free expansion stage would allow interesting tooling though |
| 22:54 | justin_smith | and simpler |
| 22:54 | cfleming | justin_smith: Yeah, this is why I don't want to automatically macroexpand for Cursive's analysis |
| 22:55 | cfleming | Scheme macros would be easier since that's a pattern matching system IIRC, it doesn't allow arbitrary code execution. |
| 23:00 | Bronsa | cfleming: would you be able to add a metadata flag to the sub-form that needs to be macroexpanded? e.g. (foo (bar ^:mexpand-this (baz ..) ..) ..) |
| 23:01 | cfleming | Bronsa: I was planning to, I can't see any other way to keep track of where you need to macroexpand. |
| 23:02 | cfleming | Bronsa: I'm not doing anything with metadata yet, I'd actually like to be able to expand with full metadata, then I can hide it in the UI and selectively show what the user wants to see (full metadata, only type hints, etc). |
| 23:03 | cfleming | Bronsa: But I think to do that I'd have to read from the top of the file for the metadata to be accurate. |
| 23:08 | Bronsa | cfleming: you mean, for source-info metadata? |
| 23:08 | cfleming | Bronsa: Right. |
| 23:09 | cfleming | Bronsa: Plus whatever metadata previous macroexpansions have added, but I don't need to parse from the top of the file for that, just from the top-level form. |
| 23:09 | Bronsa | cfleming: well, you could use tools.reader's IndexingPushbackReader :P you can specify the line/col offset in the ctor |
| 23:10 | cfleming | Bronsa: Oh nice :) |
| 23:11 | cfleming | Bronsa: It might be possible to get away without custom metadata, and just saying "expand the form at line 100, col 23" |
| 23:11 | cfleming | Bronsa: That metadata should be preserved through expansions I think. |
| 23:11 | Bronsa | cfleming: there might be ways to do that with the clojure reader aswell but I'm obviously going to promote my libs :P |
| 23:12 | cfleming | Bronsa: Of course, I expect nothing else :) |
| 23:12 | Bronsa | cfleming: yeah that should be possible aswell |
| 23:12 | cfleming | Bronsa: Anyway, you should go to bed, this isn't urgent for me. |
| 23:12 | Bronsa | right. |
| 23:22 | sm0ke | play-clj is great, but it still feels very low level, i wish there was a higher level of abstraction for making games |
| 23:22 | sm0ke | something like elm in clojure |
| 23:28 | bbloom | sm0ke: https://twitter.com/ClojureNYC/status/533435896939700224 |
| 23:29 | sm0ke | $google github clojure reagi |
| 23:29 | lazybot | [weavejester/reagi · GitHub] https://github.com/weavejester/reagi |
| 23:29 | sm0ke | btw reagi is awesome, but the main problem lies in tying frp with game entities |
| 23:31 | sm0ke | anyhow the paper on elm could be an intersting read |
| 23:31 | sm0ke | thanks bbloom |