2014-06-04
| 00:33 | ddellaco_ | amalloy, right1, alandipert: I don't understand why folks think SQL is such a problem honestly |
| 01:13 | PhallicQ | sputnikus |
| 01:13 | PhallicQ | What is your opinion on state sanctioned executions? |
| 01:15 | hellofunk | PhallicQ are you talking about federal laws for capital punishment? I think you are confusing this room with #closure |
| 01:17 | PhallicQ | I don'tknow of any room called #closure |
| 01:17 | PhallicQ | hellofunk, but yes, I am talking about capital punishment |
| 01:17 | PhallicQ | what is your opinion on the pracitce? |
| 01:18 | hellofunk | PhallicQ http://ejusa.org/learn/victims |
| 01:20 | xy86 | hi, im toying with using clojure as a compilation target. its bascially an ast and is expression based so very easy to do it to |
| 01:20 | xy86 | is anyone familiar with any projects that do something similar and is that approach not completely foolish? |
| 01:21 | PhallicQ | hellofunk, let me see. |
| 01:22 | PhallicQ | hellofunk, ah yeah |
| 01:22 | PhallicQ | retributive justice. |
| 01:23 | PhallicQ | A very American concept |
| 01:23 | PhallicQ | In my little scandinavian socialist state, we believe prisons should serve as a means to stop crime from happening, not as a vehicle for vengeance, and it's working fine because hey, there's less crime here. |
| 01:23 | hellofunk | PhallicQ the closure you're looking for is not the clojure we're offering |
| 01:24 | PhallicQ | Like I said, I'm not looking of that |
| 01:24 | PhallicQ | I know what this channel is about |
| 01:24 | PhallicQ | New scheme without TCO, some-what better type system, worse macroes etc. |
| 01:25 | PhallicQ | Well, the type system is weaker. |
| 01:25 | PhallicQ | Persistent vectors are cool though |
| 01:25 | PhallicQ | Funky data structure. |
| 01:33 | hellofunk | If I'm running a localhost webserver and I have a println in a function that is running on that server, shouldn't I see the output of that println in the REPL? |
| 01:59 | amalloy | hellofunk: in the thread processing your web requests, *out* is typically not bound to whatever your repl is reading from |
| 01:59 | hellofunk | amalloy ah that probably explains it |
| 02:00 | amalloy | it usually defaults to java's stdout, which will go to a terminal somewhere, or to nowhere at all if some other process started java and then you connected to the repl via another port |
| 02:00 | hellofunk | how do i get the *out* redirected to the repl, if possible? |
| 02:28 | hellofunk | ddellacosta it took a bit of naive hacking but i've got your oauth2 for friend returning the user's email address now, and it works nicely with other friend workflows that also return email address. thanks for all the pointers last couple of days. |
| 03:57 | hellofunk | I'm trying to make a ring route of /login serve a static html file. This doesn't seem to be doing it: (route/files "/login." {:root "./login.html"}) |
| 03:58 | hellofunk | pasted a typo. it is: (route/files "/login" {:root "./login.html"}) |
| 06:36 | yotsov | came across this quite neat performance comparison of atoms, refs and similar: http://clojure.roboloco.net/?p=894 |
| 06:38 | yotsov | I am surprised that futures are roughly as expensive as refs. For me that makes them suitable only for very specific situations |
| 06:39 | Glenjamin | futures are 1:1 with threads iirc |
| 06:39 | Glenjamin | so if you create loads, co-ordination overhead will dominate |
| 06:40 | yotsov | I see. but no transactional memory involved with futures, right? |
| 06:40 | Glenjamin | not as far as i know |
| 06:40 | yotsov | thanks |
| 06:51 | clgv | yotsov: might be due to the configuration of the threadpool for futures |
| 06:52 | clgv | yotsov: actually comparing performance of refs and futures is apples vs oranges |
| 06:53 | yotsov | clgv: I see what you mean. My first reaction was to think futures involve transactional memory in some strange way I wasn't aware of. But of course jvm thread management can lead to such performance if not done correctly too |
| 06:53 | clgv | yotsov: what's the actual comparison over there you are refering to? |
| 06:55 | clgv | yotsov: single futures for very short calculations do have more scheduling effort than benefit. when parallelizing you always need to select the right size of the "work packages" |
| 06:55 | yotsov | Promise/deliver + future creation + destruction 7949 is of the order of what refs do and like 100 times slower than what atoms do |
| 06:55 | yotsov | yes I see |
| 06:56 | yotsov | so it is the jvm threads overhead we see there |
| 06:56 | yotsov | that's indeed irrelevant |
| 06:56 | clgv | although using criterium these benchmarks seem not well planned |
| 06:59 | clgv | the promise/deliver roundtrip does not make sense without some decent workload. |
| 06:59 | whodidthis | n |
| 07:00 | clgv | yotsov: and why is "3 futures" only done with atoms and not with refs as comparisons - that would actually make sense ;) |
| 07:08 | yotsov | clgv: right... well "general" benchmarking not corresponding to a particular scenario, tends to give not so much insight... this article just got me worried that futures might involve transactional memory in a way I am not aware of |
| 07:09 | clgv | yotsov: no they dont. they are implemented on top of javas threadpoolexecutors |
| 07:09 | yotsov | clgv: yep makes sense now, thanks |
| 07:09 | clgv | $source future-call |
| 07:09 | lazybot | future-call is http://is.gd/BkUPBd |
| 07:10 | visof | hi |
| 07:11 | visof | is there a good technique to conver "HelloWorld" to "hello_world" , and the same pattern which the word Start with capital letter so "ClojureIsNice" converted to "clojure_is_nic" |
| 07:11 | visof | "clojure_is_nice" |
| 07:12 | clgv | visof: split on upper caser letter a join with the wanted delimiter |
| 07:12 | visof | ,(clojure.string/split "HelloWorld" #"[A-Z]") |
| 07:13 | clojurebot | eval service is offline |
| 07:13 | visof | clgv: that's will drop H and W |
| 07:14 | clgv | visof: yeah just noticed that |
| 07:16 | clgv | ,(require '[clojure.string :as str]) |
| 07:16 | clgv | ,(str/join "-" (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNice")) |
| 07:16 | clojurebot | eval service is offline |
| 07:16 | clgv | clojurebot: why? |
| 07:16 | clojurebot | eval service is offline |
| 07:16 | clgv | :/ |
| 07:16 | clgv | &(require '[clojure.string :as str]) |
| 07:16 | lazybot | ⇒ nil |
| 07:17 | clgv | &(str/join "-" (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNice")) |
| 07:17 | lazybot | ⇒ "Clojure-Is-Nice" |
| 07:18 | clgv | visof: like that ^^ you just need to lowercase the words to fullfil your full spe |
| 07:18 | clgv | &(str/join "-" (map str/lower-case (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNice"))) |
| 07:18 | lazybot | ⇒ "clojure-is-nice" |
| 07:19 | visof | &(str/join "-" (map str/lower-case (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNiceClgvIsGreat"))) |
| 07:19 | lazybot | ⇒ "clojure-is-nice-clgv-is-great" |
| 07:19 | clgv | thx :P |
| 08:02 | ambrosebs | can I connect my REPL to a lazybot? |
| 08:05 | ambrosebs | nvm just learnt about reloading. |
| 08:07 | visof | clgv: ping |
| 08:07 | visof | &(str/join "-" (map str/lower-case (re-seq #"\p{Upper}\p{Lower}*" "clojureIsNice"))) |
| 08:07 | lazybot | ⇒ "is-nice" |
| 08:08 | clgv | visof: is that an error with repsect to your requirements? |
| 08:08 | visof | i need to get clojure too |
| 08:10 | clgv | &(str/join "-" (map str/lower-case (re-seq #"\p{Alpha}\p{Lower}*" "clojureIsNice"))) |
| 08:10 | lazybot | ⇒ "clojure-is-nice" |
| 08:10 | clgv | visof: http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html |
| 08:16 | ambrosebs | ,*clojure-version* |
| 08:17 | ambrosebs | &*clojure-version* |
| 08:17 | lazybot | ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} |
| 08:17 | clojurebot | eval service is offline |
| 08:17 | ambrosebs | hmm I'll assume lazybot is stuck at 1.4.0 :( |
| 08:24 | clgv | ambrosebs: hit raynes ;) |
| 08:24 | clgv | until he changes it ^^ |
| 08:25 | ambrosebs | Raynes: trying to get core.typed on lazybot again. Is it feasible to upgrade to clojure 1.5.1? |
| 08:31 | ambrosebs | oh cool, wasn't as hard as I thought. |
| 08:31 | ambrosebs | there was a tools.reader conflict with core.typed that I misinterpreted as a clojure.core version thing |
| 08:32 | clgv | ambrosebs: on to 1.6.0 then? ;) |
| 08:32 | ambrosebs | doesn't exist for me yet ;) |
| 08:32 | ambrosebs | waiting for CLJS |
| 08:32 | clgv | what has that to do with cljs? |
| 08:33 | ambrosebs | my clojure world is core.typed which depends on cljs |
| 08:33 | ambrosebs | I'm also the only person who tried to AOT compile cljs |
| 08:33 | ambrosebs | *tries |
| 08:33 | ambrosebs | and that doesn't work with 1.6.0 |
| 08:34 | clgv | ambrosebs: because of the tools.analyzer your world depends on cljs |
| 08:34 | clgv | ? |
| 08:34 | ambrosebs | no core.typed checks cljs code too |
| 08:35 | ambrosebs | not very well yet, but the dependency is there. |
| 08:42 | rurumate | ,(into #{} nil) |
| 08:43 | clojurebot | eval service is offline |
| 08:43 | rurumate | oh noes |
| 08:43 | rurumate | I wanted to point out that, at least in clojure 1.5.1, (into #{} nil) = #{} |
| 08:43 | rurumate | and (into #{} nil nil) = exception |
| 08:44 | rurumate | whereas #{nil} != #{} |
| 08:44 | llasram | &(into #{} [] []) |
| 08:44 | lazybot | clojure.lang.ArityException: Wrong number of args (3) passed to: core$into |
| 08:44 | llasram | rurumate: Thus isn't that expected? |
| 08:44 | llasram | both of `into`s arguments are collections |
| 08:44 | llasram | and it takes only two |
| 08:45 | rurumate | oh, |
| 08:45 | rurumate | right, into takes collection |
| 08:46 | rurumate | I meant (into #{} [nil]) |
| 08:46 | rurumate | anyway |
| 08:47 | rurumate | it's a hot day, brainrot sets in |
| 08:47 | Glenjamin | &(into #{} [nil]) |
| 08:47 | lazybot | ⇒ #{nil} |
| 08:47 | Glenjamin | &(into #{} nil) |
| 08:48 | lazybot | ⇒ #{} |
| 08:48 | Glenjamin | seems right |
| 08:48 | rurumate | so lazybot took clojurebots job away? |
| 08:48 | Glenjamin | oh, someone already did that |
| 08:48 | Glenjamin | they're usually both up |
| 08:48 | clgv | ,(println "back again") |
| 08:48 | clgv | hm no, seems not like it |
| 08:48 | clojurebot | eval service is offline |
| 08:48 | rurumate | stuck in a loop, clojurebot? |
| 08:49 | clgv | rurumate: he got timeouts for that ;) |
| 08:50 | rurumate | &(into {} [nil [1 2] nil] |
| 08:50 | lazybot | java.lang.RuntimeException: EOF while reading, starting at line 1 |
| 08:50 | rurumate | (into {} [nil [1 2] nil]) |
| 08:50 | rurumate | &(into {} [nil [1 2] nil]) |
| 08:50 | lazybot | ⇒ {1 2} |
| 08:51 | rurumate | maps are special |
| 08:51 | clgv | rurumate: well what should be done with nil? |
| 08:51 | clgv | &(into {} [[nil nil] [1 2]]) |
| 08:51 | lazybot | ⇒ {nil nil, 1 2} |
| 08:51 | rurumate | it's understood, map conj takes 2-vec or nil |
| 08:52 | clgv | you need at least key value pairs |
| 08:52 | rurumate | it just takes a bit of getting used to |
| 08:52 | rurumate | &(conj {} nil) |
| 08:52 | lazybot | ⇒ {} |
| 08:52 | clgv | &(into {} [{:a 1 :b 2} {:a 42 :c 3}]) |
| 08:52 | lazybot | ⇒ {:a 42, :b 2, :c 3} |
| 08:53 | rurumate | &(into {} (remove nil? [nil [1 2] nil [3 4]])) |
| 08:53 | lazybot | ⇒ {1 2, 3 4} |
| 08:54 | rurumate | the remove is not needed, is what I used to do |
| 08:56 | Glenjamin | &(conj {} nil) |
| 08:56 | lazybot | ⇒ {} |
| 08:56 | Glenjamin | that's what into does under the hood |
| 09:35 | martin_ | I'm looking for something similar to https://github.com/Leonidas-from-XIV/node-xml2js, but for Clojure. I want a more "natural" (for lack of a better word) data structure than the one clojure.xml/parse provides |
| 09:35 | clgv | rurumate: concerning that "remove" you mentioned - it is likely that the sequence resulted from a "map" and you could just switch to "keep" to throw away all nil values |
| 09:40 | rurumate | oh, thanks clgv I had not known about keep |
| 09:41 | martinklepsch | martin_, looked into enlive? |
| 09:41 | martinklepsch | martin_, what do you want to achieve? |
| 09:44 | martin_ | martinklepsch: to transform a xml datastructure (e.g. merge attributes) into something that can be rendered as json |
| 09:45 | martinklepsch | manually selecting the elements from the XML or in general for various different xml snippets? |
| 09:54 | martin_ | martinklepsch: I'm thinking there's a general solution for it, but maybe there isn't. Example: https://gist.github.com/martinp/8a3bfc85d6f98bd55551 |
| 09:55 | martinklepsch | martin_ I've been working with XML a lot recently and that zipper structure is pretty clever actualyl |
| 09:56 | martinklepsch | martin_, in your example, where does the potential content of a tag go? |
| 10:00 | martin_ | martinklepsch: ideally, they would be merged with :attrs as values of the associated tag name (:bar in the example), but then need to figure what do with duplicate keys and multiple values (when :content has more than one child) |
| 10:01 | martin_ | so maybe the only solution is to do something more explicit with the zipper structure |
| 10:02 | martinklepsch | martin_ Whats your end goal here? do you want to obtain specifc data or rather convert a complete structure? |
| 10:03 | martinklepsch | merged with attrs means: {:more-test "abc" :test "xyz" :content "ovw"} ? |
| 10:03 | martinklepsch | I tried doing something similar and most of the time I just noticed that I was missing a case in how XML can be structured that then broke my attempt |
| 10:03 | martin_ | martinklepsch: yes |
| 10:05 | arrdem | oh good clojure.core/when-let is a thing |
| 10:13 | lvh | how do I add things to a leiningen project that don't have formally released versions? |
| 10:13 | clgv | &(:since (meta #'when-let)) |
| 10:13 | lazybot | ⇒ nil |
| 10:13 | clgv | &(meta #'when-let) |
| 10:13 | lazybot | ⇒ {:macro true, :ns #<Namespace clojure.core>, :name when-let, :arglists ([bindings & body]), :added "1.0", :doc "bindings => binding-form test\n\n When test is true, evaluates body with binding-form bound to the value of test", :line 1687, :file "clojure/core.clj"} |
| 10:13 | clgv | arrdem: since 1.0 ;) |
| 10:13 | arrdem | clgv: all these nice little pseudo-pattern matching constructs :P |
| 10:13 | clgv | lvh: you dont - since no one once to shoot himself in the foot |
| 10:14 | clgv | s/once/wants/ |
| 10:14 | lvh | well, I'd like to do some network simulation |
| 10:14 | lvh | https://github.com/aphyr/timelike seems like it's a pretty decent start |
| 10:14 | clgv | lvh: usually I upload them under a version into a repository |
| 10:14 | lvh | so I run a repository of my own? |
| 10:15 | clgv | lvh: if the artifact is allowed to be public you upload it to clojars.org with a private group name |
| 10:15 | clgv | +can |
| 10:16 | lvh | clgv: I have no idea how that works but I guess I'm about to find out :) |
| 10:17 | cemerick | gfredericks: you pinged? |
| 10:18 | clgv | lvh: easiest way in this case. checkout the git repo change the project name to org.clojars.lvh/timelike maybe choose a different number. use "lein install" and then scp the pomx.xml and the jar to clojars@clojars.org |
| 10:19 | clgv | "version number" |
| 10:19 | lvh | clgv: awesome, thanks! |
| 10:19 | clgv | lvh: you need an account on clojars though and register you public ssh key overthere |
| 10:20 | clgv | lvh: alternatively use "lein deploy" instead of the scp approach but make sure you read its documentation |
| 10:20 | lvh | oh hay, there's actually a timeline clojar already |
| 10:20 | lvh | https://clojars.org/timelike |
| 10:20 | clgv | lvh: even better :D |
| 10:20 | lvh | unfortunately it's [timelike "0.1.0-SNAPSHOT"] |
| 10:21 | lvh | so I have no idea what version that actually is |
| 10:21 | clgv | lvh: that's the version that is on github |
| 10:21 | lvh | clgv: yeah, but isn't that also the default that you get when you lein new? |
| 10:21 | lvh | clgv: I'm suggesting there's lots of commits that have that version in project.clj |
| 10:22 | lvh | so I don't actually know that the thing on clojars is the thing that's currently git master, right? |
| 10:22 | lvh | (I'm really sure they've diverged because there's more recent commits on github, but only by a few days) |
| 10:22 | clgv | lvh: yes thats correct. usually you should make a 0.1.0 release when you think you covered most basic functionality... |
| 10:22 | lvh | I probably don't care too much though :) |
| 10:22 | lvh | clgv: Thanks a lot, that was super helpful! |
| 10:23 | clgv | lvh: if you need the most recent you'll have to build and upload it yourself or contact aphyr to do that ;) |
| 10:38 | dabbelingCLj | any LT users here? |
| 10:38 | arrdem | there are a few here, and more in #lighttable :P |
| 10:39 | stompyj | I used to, but I’ve gone away from it recently |
| 10:39 | dabbelingCLj | stompyj: what do you use instead? |
| 10:39 | stompyj | sublime text 3 |
| 10:40 | dabbelingCLj | thats mac only right? |
| 10:40 | stompyj | although, my goal is to give IDEA + Cursive a good run |
| 10:40 | scripor | it's for windows, too |
| 10:40 | stompyj | no, it’s for all three platforms, win, mac & linux |
| 10:40 | scripor | how is clojure support on ST3? |
| 10:40 | dabbelingCLj | how do you setup developement? |
| 10:41 | stompyj | mmmmm. the nrepl stuff isn’t great, tbh |
| 10:41 | rurumate | what's a good string templating library for clojure? something ala stringtemplate, but easy? |
| 10:41 | stompyj | dabbelingCLj: but I have a weird dev setup atm. I do most of my coding in ST3 and just refresh the page to see whats happening |
| 10:41 | stompyj | I also have tests setup to run after every save |
| 10:42 | stompyj | and I do just keep a REPL open for prototyping functions |
| 10:42 | rurumate | Are there any reasons to not just use emacs? |
| 10:42 | cbp | Uh I can't tell what stringtemplate is like from its page but I always use selmer for templating |
| 10:42 | stompyj | rurumate: I think if you haven’t invested 18 years in VI like I have, then no |
| 10:42 | stompyj | but for me, its probably nto worth the cost |
| 10:43 | stompyj | I run ST3 in VIM mode |
| 10:43 | rurumate | stompyj: it's definitel worth a try |
| 10:43 | stompyj | and all my external boxes have vi on them |
| 10:43 | rurumate | emacs and lisp go pretty well together |
| 10:43 | stompyj | rurumate: I’ve used emacs quite a bit in college |
| 10:43 | cfleming | rurumate: Yeah, but the learning curve is steep |
| 10:44 | cfleming | rurumate: And I think other options are good now too |
| 10:44 | stompyj | rurumate: our infrastructure is clojure, java, javascript, and ruby, it wouldn’t be prudent to optimize for clojure, when it’s 3% of my codebase |
| 10:44 | rurumate | there's another catch about emacs: it's even steeper when you have a non american keyboard layout |
| 10:44 | cfleming | (full disclosure: I develop Cursive, so I'm biased) |
| 10:44 | stompyj | and as I said, I’ve been using vi for close to two decades |
| 10:45 | stompyj | cfleming: awesome. Thats where I want to be in hte next year or so, I love what you’ve done so far |
| 10:45 | rurumate | ok, I see the editor subject is a bit loaded |
| 10:45 | cfleming | stompyj: Yeah, those keyboard shortcuts really get down into the reptilian hindbrain after that long |
| 10:45 | cfleming | stompyj: Thanks! Lots of cool things coming too. |
| 10:46 | cfleming | stompyj: IntelliJ is probably a good fit for that language mix, too. |
| 10:46 | stompyj | Thats my goal |
| 10:46 | stompyj | Getting back to a “Real IDE" |
| 10:46 | stompyj | and IntelliJ seems pretty great |
| 10:47 | cfleming | Unfortunately IdeaVim has some rough edges with Cursive (and other language consoles) |
| 10:47 | cfleming | Yeah, IntelliJ is amazing. |
| 10:47 | cfleming | It's one of my favourite pieces of software ever. |
| 10:47 | stompyj | rurumate: I appreciate the sales pitch, didn’t mean to come off as harsh, just that this decision has been carefully considered :) |
| 10:47 | stompyj | What IdeaVim? |
| 10:48 | cfleming | The Vim bindings for IntelliJ |
| 10:48 | stompyj | Ahhh ok |
| 10:48 | stompyj | thats actually not so bad, For years I split my brain between “Hardcore IDE” for either .NET or Java developement and VI for everythign else |
| 10:48 | stompyj | so when I see a blank editor my mind goes vi |
| 10:48 | cfleming | I'm working with the developer to try to improve the Vim support in consoles. |
| 10:48 | stompyj | and if I see GUI, I think IDE |
| 10:49 | mercwithamouth | i change every 3-4 months |
| 10:49 | cfleming | Hehe |
| 10:49 | stompyj | dabbelingCLj: LT is pretty great tho, you should check it out |
| 10:49 | stompyj | mercwithamouth: lol |
| 10:49 | arrdem | mercwithamouth: someone doesn't use editor level keybindings :P |
| 10:50 | cfleming | Yeah, for getting started easily LT is really nice, especially for cljs |
| 10:50 | tsmarsh | I’ve been writing more and more clojure recently, but I’m a Java developer, so I fear I might be using protocols as a crutch. Is there a good resources on when to use protocols vs how? |
| 10:50 | stompyj | mercwithamouth: you’re killing me. Deadpool is one of my favorite comic book chars |
| 10:50 | stompyj | and now I wonder what he’s been up to :/ |
| 10:51 | cfleming | tsmarsh: Check out the Clojure Programming book - the chapter on protocols/records etc is nice. |
| 10:51 | pandapool | aw crap someone already registered this :P |
| 10:51 | cfleming | Talks in particular about when to choose records over maps etc. |
| 10:51 | dabbelingCLj | stompyj: I just tried and got weird issues :/ thats not helping when learning a new language |
| 10:51 | stompyj | dabbelingCLj: ahhh. got it :/ sorry to hear that |
| 10:52 | irctc | Which concurrency primitive should I use if I want to limit a function concurrent execution of pmap? I want to use pmap on a function say downloadfile but I only want a max of 4 concurrent execution at any one time. Any suggestions? Thank you! |
| 10:52 | stompyj | I’ve yet to use protocols/records. I think my clojure code is probably remedial |
| 10:52 | arrdem | irctc: use a real ratelimiter rather than complecting your parallel function call operation with rate limiting |
| 10:52 | stompyj | heh |
| 10:53 | irctc | What is a real ratelimiter? Are there any implementations? |
| 10:53 | arrdem | $google clojure rate limiting github |
| 10:53 | lazybot | [jkk/rate-gate · GitHub] https://github.com/jkk/rate-gate |
| 10:53 | irctc | Thanks! |
| 10:54 | hhenkel | Hi all, I'm trying to read multiple yaml files and the want them to merge in a "single tree". Anyone aware how to do that? |
| 10:54 | tsmarsh | thanks. |
| 10:55 | hhenkel | I'm using clj-yaml |
| 10:55 | arrdem | hhenkel: custom recursive tree merge? |
| 10:55 | tsmarsh | Protocols just don’t feel very functional, they’re awesome, but somehow it feels like cheating. I think I’m using them correctly according to the examples. Thanks again |
| 10:56 | hhenkel | arrdem: Pardon? :) |
| 10:56 | arrdem | tsmarsh: how are they cheating... as long as your protocol is pure, the protocol methods themselves are first class and life's good. |
| 10:56 | arrdem | tsmarsh: if your protocol isn't pure, then you're just being silly |
| 10:56 | arrdem | (doc merge) |
| 10:56 | clojurebot | "([& maps]); Returns a map that consists of the rest of the maps conj-ed onto the first. If a key occurs in more than one map, the mapping from the latter (left-to-right) will be the mapping in the result." |
| 10:57 | tsmarsh | because the look up isn’t the same as everything else. You look up the function on the first argument, rather than in the namespace. |
| 10:58 | arrdem | hhenkel: (-> (text ← yaml) (λ yaml → map) (λ map → map) (λ map → yaml) (λ yaml → string)) |
| 10:58 | llasram | tsmarsh: The protocol function still exists in the namespace. It just performs implementation dispatch based on that first argument... |
| 10:58 | tsmarsh | ahhhhhh, thats the bit I was missing. That makes so much sense. Thank you |
| 10:58 | hhenkel | arrdem: okay, that sounds reasonable. Only problem I see is that I use hooks in yaml so I guess I need to load all files first, then parse them with clj-yaml (snakeyaml). |
| 10:58 | arrdem | tsmarsh: that's not inherently imperative at all, you're just dispatching differently than a normal function. |
| 10:59 | llasram | arrdem: That said, if you're writing lots of protocols then `deftype`s which implement those protocols, then there probably is a better way :-) |
| 11:00 | tsmarsh | arrdem, it wasn’t imperative that worried about so much as OO. |
| 11:00 | martin_ | given [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}}], what would be good way to transform it into {:a [{:c 2 :b 1} {:c 3 :b 4}]}? |
| 11:00 | arrdem | llasram: yeah. my first compiler abused the crap out of deftype and protocols T_T |
| 11:00 | arrdem | tsmarsh: oo isn't somehow not functional so long as it's pure and the methods can be taken as values... |
| 11:01 | arrdem | tsmarsh: then it's just record oriented programming :P |
| 11:02 | tsmarsh | arrdem, agreed, more that I’m trying to learn to be a better functional programmer, but I fall back in to what I’d concider to be OO. My OO strives to be as pure and immutable as possible, so I guess I shouldn’t be too suprised at the similarities between my Java and my Clojure |
| 11:03 | llasram | tsmarsh: Do you have any code you can share for specific patterns you're concern about? |
| 11:05 | tsmarsh | llasram, not yet. I was about to go in and extend a small project I was working on, and protocols seemed like a good fit. I just wanted to get a sense of “am I writing Java in Clojure”. I’ll share when I’ve checked it in |
| 11:05 | justin_smith | ,(apply merge-with vector [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}}]) martin: |
| 11:05 | clojurebot | {:a [{:c 2, :b 1} {:c 3, :b 4}]} |
| 11:06 | justin_smith | martin_: that is ^ |
| 11:07 | martin_ | justin_smith: beautiful, thank you |
| 12:03 | rurumate | quick, what are '[#_foo] and '#_foo |
| 12:04 | rurumate | or (quote #_foo) |
| 12:05 | philandstuff | well #_ is a reader macro that discards the next form |
| 12:05 | philandstuff | so (quote #_foo) reads as (quote) |
| 12:05 | bbloom | ... why does it need to be so quick? |
| 12:05 | rurumate | yes, that's correct! |
| 12:05 | rurumate | so you don't cheat and try it in the repl |
| 12:06 | philandstuff | that's not cheating? |
| 12:08 | llasram | I didn't realize we were being quizzed on how well our collective mental model of Clojure matched the implementation(s) |
| 12:08 | llasram | Are there prizes and/or punishments? |
| 12:12 | martin_ | justin_smith: any way to do it for a vector with more than two elements? |
| 12:13 | stompyj | (inc llasram) |
| 12:13 | lazybot | ⇒ 25 |
| 12:13 | arrdem | llasram: why would we need rewards when we have internet points! |
| 12:13 | arrdem | (inc llasram) |
| 12:13 | lazybot | ⇒ 26 |
| 12:13 | arrdem | (dec so) |
| 12:13 | lazybot | ⇒ -26 |
| 12:17 | PigDude | aliasing something from antoher namespace .. now i have (def ^{:doc "Docs.."} foo some-ns/kazoo), is that right? |
| 12:17 | PigDude | it works of course |
| 12:17 | llasram | PigDude: Why do you need to do that? |
| 12:17 | PigDude | llasram: i want all API in core |
| 12:18 | PigDude | llasram: it's a python idiom i think but i think it applies here? dunno |
| 12:18 | llasram | ztellman wrote https://github.com/ztellman/potemkin to help with that, but |
| 12:19 | llasram | I think the general consensus is that it's better to just keep the implementation and interface namespace divisions the same |
| 12:19 | justin_smith | martin_: merge-with is varargs, so any number of maps in the vec will work |
| 12:20 | kschrader | anybody know an easy way to print out all of the compojure routes defined in an app? |
| 12:21 | justin_smith | ,(apply merge-with vector [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}} {:a {:c 4}}]) martin_ |
| 12:21 | clojurebot | {:a [[{:c 2, :b 1} {:c 3, :b 4}] {:c 4}]} |
| 12:22 | justin_smith | oh wait, that is structured oddly isn't it |
| 12:24 | cbp | PigDude: nitpick, you can do (def foo "Docs.." ..) |
| 12:28 | justin_smith | ,,(apply merge-with (fn [a b] (if (vector? a) (conj a b) (vector a b))) [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}} {:a {:c 4}}]) martin_: there may be a cleaner way to do this, but this works |
| 12:28 | clojurebot | {:a [{:c 2, :b 1} {:c 3, :b 4} {:c 4}]} |
| 12:29 | justin_smith | but that does end up failing if any of your initial vals are vectors... |
| 12:30 | PigDude | cbp: oh cool, didn't know that |
| 12:31 | dbasch | ,(apply merge-with (fn [& args] (into [] args)) [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}} {:a {:c 4}}]) |
| 12:31 | clojurebot | {:a [[{:c 2, :b 1} {:c 3, :b 4}] {:c 4}]} |
| 12:31 | dbasch | same problem |
| 12:35 | justin_smith | dbasch: I think the right way is to wrap all vals of the first arg in vectors, and then merge-with conj, wrapping any new keys in vectors - which makes me think merge-with is not the right way to do this |
| 12:35 | justin_smith | *any vals of new keys |
| 12:38 | llasram | ,(->> [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}} {:a {:c 4}}] (apply concat) (reduce (fn [m [k v]] (update-in m [k] (fnil conj []) v)) {})) |
| 12:38 | clojurebot | {:a [{:c 2, :b 1} {:c 3, :b 4} {:c 4}]} |
| 12:39 | ambrosebs | Bronsa: can you attach the evaluated result to the AST in analyze+eval ? |
| 12:39 | arrdem | justin_smith: no that's still fine, it just becomes (fn [[x & more]] (reduce (partial merge-with conj) (map-vals vec x) more)) |
| 12:40 | dbasch | ,(apply merge (vals (group-by keys [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}} {:a {:c 4}}]))) |
| 12:40 | clojurebot | [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}} {:a {:c 4}}] |
| 12:40 | dbasch | I don’t know what the original request was |
| 12:40 | arrdem | ambrosebs: I don't think t.e.jvm has that out of the box, but I may be wrong. |
| 12:40 | ambrosebs | arrdem: that's a feature request :) |
| 12:41 | arrdem | ambrosebs: :P |
| 12:41 | arrdem | (doseq [maintainer lurking-maintainers] (inc maintainer)) |
| 12:41 | ambrosebs | oh I forgot to say please! |
| 12:42 | Bronsa | ambrosebs: sure, any idea for the field name? :eval-ret? |
| 12:42 | arrdem | Bronsa: :result |
| 12:42 | Bronsa | arrdem: that's better, yeah |
| 12:43 | dbasch | it looks like the bot that logs this channel is not running http://clojure-log.n01se.net/ |
| 12:45 | arrdem | as long as we're bugging Bronsa... |
| 12:45 | Bronsa | ambrosebs: https://github.com/clojure/tools.analyzer.jvm/commit/37679c74039507042050f88bb25eac362d595d00 |
| 12:46 | Bronsa | arrdem: :) |
| 12:46 | arrdem | Bronsa: I don't know if preserving the raw input from macroexpand through eval is something you'd consider a feature, but I hacked it in for Oxcart. https://github.com/arrdem/oxcart/commit/ad55c112547712367890456e578d671636d5447e |
| 12:46 | arrdem | s/eval/analyze/g |
| 12:47 | Bronsa | ambrosebs: I'm probably gonna cut a 0.2.0 later today with the new env stuff |
| 12:47 | ambrosebs | looks good |
| 12:47 | ambrosebs | you mean with t.a.js? |
| 12:48 | ambrosebs | unaware of env stuff in t.a.jvm |
| 12:48 | Bronsa | ambrosebs: no, t.a.js is not ready for a release yet |
| 12:49 | Bronsa | ambrosebs: the next releases of t.a and t.a.j will include a breaking change, I moved :namespaces from :env to a global env/*env* |
| 12:49 | ambrosebs | oh very nice |
| 12:49 | martin_ | ,(apply merge-with (comp flatten vector) [{:a {:c 2, :b 1}} {:a {:c 3, :b 4}} {:a {:c 4}}]) |
| 12:49 | clojurebot | {:a ({:c 2, :b 1} {:c 3, :b 4} {:c 4})} |
| 12:49 | Bronsa | ambrosebs: that's for the sake of unifying behaviour between t.a.jvm and t.a.js |
| 12:49 | martin_ | justin_smith: ended up with that one ^ |
| 12:50 | justin_smith | oh, cool - except flatten sucks |
| 12:50 | justin_smith | ~flatten |
| 12:50 | clojurebot | flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with. |
| 12:50 | Bronsa | ambrosebs: also it makes more sense to have the namespaces map in an env that can be shared between different analyze calls |
| 12:51 | martin_ | justin_smith: I see :) |
| 12:51 | ambrosebs | ah true. |
| 12:51 | justin_smith | martin_: same problem as the (if (vector? a) ...) version - it loses structure |
| 12:51 | Bronsa | arrdem: re: :raw-form, sure, I'd take a patch for that |
| 12:52 | arrdem | Bronsa: the issue is that it sits weirdly in the macroexpand/analyze pipeline because it needs to jump over macroexpand and I don't think you expose a macorexpand+analyze fn. |
| 12:53 | arrdem | Bronsa: you're welcome to it, I just don't think of where it would fit offhand. |
| 12:57 | PigDude | (RT.java:505) |
| 12:57 | PigDude | of course! |
| 12:59 | PigDude | hangs the tests too |
| 13:00 | PigDude | my test suite has stopped reportnig errors |
| 13:00 | PigDude | it reports the line location but not the sort of error, and hangs |
| 13:03 | justin_smith | https://www.refheap.com/86275 martin_: finally a version that preserves all incoming structure, just couldn't figure out how to do it as a one liner |
| 13:04 | Bronsa | arrdem: http://sprunge.us/BWIE what do you think? |
| 13:04 | justin_smith | it's probably more verbose and simultaneously more obtuse than it needs to be, but it is the first version that is actually correct if any v in the incoming maps is already a vector |
| 13:04 | justin_smith | also it is bad because it walks all the keys of all the maps twice |
| 13:09 | arrdem | Bronsa: works for me |
| 13:09 | arrdem | Bronsa: thanks! |
| 13:09 | Uruk | Q: lein seems to ignore my $http_proxy and $https_proxy. Running netstat/wireshark while running lein deps shows it's trying to direct connect. Anything else to check? How do you get lein to respect $http_proxy? |
| 13:09 | arrdem | Uruk: ask in #leiningen probably... |
| 13:10 | Uruk | arrdem: will do, thanks |
| 13:10 | arrdem | dunno if tech is lurking yet but he's more likely to give support over ther.e |
| 13:10 | PigDude | so, this is a problem i could use some help with |
| 13:10 | PigDude | why my test suite is not showing errors, and hangs instead? |
| 13:11 | Bronsa | arrdem: np https://github.com/clojure/tools.analyzer/commit/6042cd3b25ad7e6a597e7fcf3bd0ddb8c6159a54 |
| 13:11 | technomancy | Uruk: all the proxy stuff has been contributed; I don't think anyone on the maintainer team is familiar with it |
| 13:11 | arrdem | Bronsa: wait, what on earth is your :raw-forms doing? O |
| 13:11 | PigDude | i am invoking tests with `lein test` and cleaned my project to make sure there was nothing untoward |
| 13:11 | arrdem | Bronsa: oh it's a seq of every step of macroexpand-1. |
| 13:11 | Bronsa | yeah |
| 13:11 | arrdem | Bronsa: solid! |
| 13:11 | MagBo[MURT] | hi. I can't figure out if *symbol* has any special meanong |
| 13:12 | MagBo[MURT] | meaning*. I mean those asterisks |
| 13:12 | PigDude | this is making it extremely difficult to fix bugs found by these tests, because i only get a file and line number |
| 13:12 | PigDude | in certain cases i get a RT.java line number instead |
| 13:15 | justin_smith | martin_: updated to only walk the input once https://www.refheap.com/86275 |
| 13:16 | PigDude | i have a hunch there is an infinite loop in a test here, and that clojure test runner does not report (see?) the exceptions until some later point in the test execution |
| 13:16 | PigDude | what do you do about this? |
| 13:18 | MagBo[MURT] | the more docs I read the more I thknk that a symbol in asterisks denotes something semantically but isnt enforced by reader. |
| 13:18 | justin_smith | PigDude: maybe spawn a thread alongside the test that throws an exception after some timeout, and manually stop that thread when the individual test completes |
| 13:19 | justin_smith | PigDude: that way the exception can tell you which test spawned the thread that timed out and threw an exception |
| 13:19 | justin_smith | PigDude: I bet core.async would make this very easy to do |
| 13:19 | PigDude | but this is a bug right? |
| 13:20 | justin_smith | PigDude: sounds like a bug in your test |
| 13:20 | justin_smith | how should the test runner no a-priori how long a test has to run? |
| 13:20 | justin_smith | *know |
| 13:20 | PigDude | oh because i feel like a test runner that emits ERROR in (test-events-out-of-order) (MultiFn.java:160) Uncaught exception, not in assertion. expected: nil |
| 13:20 | PigDude | and then hangs while not showing a known exception |
| 13:20 | PigDude | is buggy |
| 13:21 | justin_smith | ,(def *x* 'should-be-special) MagBo[MURT] |
| 13:21 | clojurebot | #<CompilerException java.lang.SecurityException: denied, compiling:(NO_SOURCE_PATH:0:0)> |
| 13:21 | justin_smith | MagBo[MURT]: anyway, if you run that above in your local repl, you will see the warning: "Warning: *x* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *x* or change the name. (NO_SOURCE_PATH:1)" |
| 13:22 | MagBo[MURT] | justin_smith: got it, had a hunch that it denotes some warning-level semantics. |
| 13:23 | justin_smith | MagBo[MURT]: right, and you would see that warning if any lib you used made a *foo* that was not ^:dynamic |
| 13:23 | MagBo[MURT] | got it, thanks. |
| 13:24 | MagBo[MURT] | i wonder if it's reflected in the docs. |
| 13:25 | justin_smith | ,(meta #'*1) |
| 13:25 | clojurebot | {:ns #<Namespace clojure.core>, :name *1, :added "1.0", :file "clojure/core.clj", :column 1, ...} |
| 13:25 | justin_smith | ,(:dynamic (meta #'*1)) |
| 13:25 | clojurebot | true |
| 13:25 | MagBo[MURT] | really difficult to search for all these arcane modifyers and while #, ^ and so on are really well documented, i didnt see anything about **. |
| 13:26 | justin_smith | MagBo[MURT]: we call them earmuffs http://dev.clojure.org/display/community/Library+Coding+Standards |
| 13:27 | ambrosebs | Bronsa: just happened to have some calls to update-ns-map! in core.typed. |
| 13:27 | MagBo[MURT] | justin_smith: <3 thanks for the link |
| 13:28 | Bronsa | ambrosebs: remove the env argument and it will work as before |
| 13:29 | ambrosebs | ok |
| 13:30 | Bronsa | I could have left the argument as a no-op to avoid breaking compatibility now that I think about it |
| 13:32 | Bronsa | MagBo[MURT]: note that ** are not modifiers, *foo* is just a regular symbol |
| 13:33 | ambrosebs | I guess. |
| 13:43 | Glenjamin | http://yobriefca.se/blog/2014/05/19/the-weird-and-wonderful-characters-of-clojure/ |
| 13:44 | jcromartie1 | I have a lot of issues with the terminology of that article |
| 13:45 | Glenjamin | the bit at the top about not having a good reference point for hard-to-google symbols is valid though |
| 13:45 | jcromartie1 | yes |
| 13:45 | jcromartie1 | except http://clojure.org/reader |
| 13:46 | Glenjamin | mm, but not everything ungooglable is part of the reader |
| 13:49 | ambrosebs | Bronsa: could t.a.jvm make this a little easier to write? Just a macroexpand-1 that provides a map of macro overrides https://github.com/clojure/core.typed/blob/master/src/main/clojure/clojure/core/typed/analyze_clj.clj#L82 |
| 13:49 | justin_smith | is there a version of pcalls which reorders the results based on which one returns first? |
| 13:49 | ambrosebs | unsure if it's common enough to support. |
| 13:50 | justin_smith | ie. so that (first (race-pcalls ...)) would always give the result of the fastest calculation |
| 13:52 | Glenjamin | i'm not sure how you'd implement that |
| 13:52 | Glenjamin | would need another thread checking results of the worker threads? |
| 13:53 | Glenjamin | or some sort of channel |
| 13:53 | justin_smith | Glenjamin: I am working on a version with a promise and futures racing to fill the promise right now |
| 13:53 | justin_smith | just figured it might already exist |
| 13:53 | Glenjamin | how do you know which promise is ready? |
| 13:53 | justin_smith | both futures want to deliver the same promise |
| 13:53 | justin_smith | first one wins |
| 13:53 | Glenjamin | oh, i see |
| 13:53 | justin_smith | the other gets cancelled |
| 13:54 | Glenjamin | if the future completes and the promise is already taken, it tries the next one? |
| 13:54 | pjstadig | have the pcalls conj into an atom containing a vector |
| 13:54 | justin_smith | ahh, not directly using the result |
| 13:54 | justin_smith | but I like the idea of cancelling the calls that are not done yet |
| 13:55 | cbp | justin_smith: that sounds like alts!! with the cancelling |
| 13:55 | justin_smith | cbp: yeah, but I was hoping I could do something simple that did not require pulling in all of core.async |
| 13:55 | justin_smith | which may be folly, finding out now |
| 13:56 | faustroll | I'm fiddling with logging |
| 13:57 | faustroll | I like the thinking behind clj-logging-config |
| 13:57 | faustroll | but it seems not to have caught on and not been introduced into clojure.tools.logging |
| 13:58 | Bronsa | ambrosebs: I guess you could do something like http://sprunge.us/WjjJ |
| 13:58 | faustroll | It looks as if when folks are using logback they are fiddling with xml? |
| 14:00 | faustroll | any thoughts on logging in a clojure way? |
| 14:00 | justin_smith | faustroll: I had really bad luck trying to make any of the clojure wrappers for java logging stuff behave in a nice clojurey way (ie. runtime config that did not depend on global settings and did not require mucking with xml) |
| 14:00 | justin_smith | faustroll: this could have just been a sign of my impatience or ignorance though |
| 14:02 | faustroll | justin_smith: I hear you. I'm feeling the pain right now |
| 14:02 | faustroll | justin_smith: clj-logging-config looks like a noble attempt |
| 14:03 | justin_smith | if you can stomach a single global config, timbre is the least yucky https://github.com/ptaoussanis/timbre |
| 14:03 | faustroll | justin_smith: but it seems not to have been updated for slf4j |
| 14:04 | justin_smith | or maybe I mean most-clojurey, which to me is least-yucky |
| 14:04 | llasram | If all you want out of logging is to get lines tagged with the log level to go out via STDERR, clojure.tools.logging is fine |
| 14:04 | llasram | (and since IMHO that's what you usually really want from logging...) |
| 14:04 | arrdem | tools logging is fine, but timbre is a little nicer for leightweight use. |
| 14:05 | arrdem | definitely not a lightweight lib tho. |
| 14:05 | llasram | "Hey, there sure are a lot of JVM logging libraries. I know how to solve this -- I'll write another one!" |
| 14:05 | arrdem | (inc llasram) ;; the lisper's curse strikes again. |
| 14:05 | lazybot | ⇒ 27 |
| 14:05 | faustroll | thanks so much for all the responses |
| 14:05 | llasram | tools.logging at least is just a facade which works over whatever Java library logging facility you are probably already using |
| 14:05 | arrdem | llasram: but xml is nasty and evil... |
| 14:06 | arrdem | ambrosebs: lol @ swift static types |
| 14:06 | llasram | I use it with slf4j+log4j and a ~5 line property file |
| 14:06 | llasram | No XML in site |
| 14:06 | llasram | er, sight |
| 14:06 | faustroll | arrdem: i'd love to avoid xml |
| 14:06 | llasram | We do have *some* XML at our site :-) |
| 14:07 | faustroll | llasram: as long as no human has to read it |
| 14:07 | llasram | Of course |
| 14:07 | llasram | log4j's property file configuration is pretty human-friendly IMHO |
| 14:08 | faustroll | llasram: the libraries I am using are already using logback |
| 14:08 | llasram | Are they directly using logback, or are they using that as the default via slf4j? |
| 14:08 | cbp | java config files are pretty tame compared to RPC things |
| 14:09 | faustroll | llasram: I'd like a clojurey way of programmatically setting log levels in different contexts |
| 14:09 | llasram | Er. Why? |
| 14:10 | faustroll | llasram: very noob here. but I want to quiet logs during testing |
| 14:10 | llasram | Then you don't want programmatic setting of the log level -- you want test configuration which sets the log level :-) |
| 14:11 | faustroll | llasram: lol! yes. I want to quiet the logs while testing in Storm |
| 14:12 | arrdem | so just load a different log config as part of testing... |
| 14:12 | llasram | faustroll: Do you mean you want to change the log level of a Storm cluster while doing some sort of integration testing, or just change the log level while running local tests? |
| 14:12 | faustroll | llasram: local tests |
| 14:13 | faustroll | llasram: I modified a with-quiet-logs function |
| 14:13 | llasram | I see |
| 14:13 | faustroll | llasram: and it worked with log4j |
| 14:14 | eraserhd | OK, so if I 'lein install' and it puts a jar in ~/.m2/repository, I'm supposed to be able to use it from another project, right? |
| 14:14 | llasram | What I'd do instead is add a `test-resources` directory and Leiningen :test profile :resource-paths entry, then include a separate logging config |
| 14:14 | justin_smith | eraserhd: if you require the right group / artifact |
| 14:14 | llasram | It will only apply when running `lein test` (vs running tests in your REPL), but that's usually what I personally want anyway |
| 14:14 | faustroll | llasram: thanks for the suggestion |
| 14:15 | eraserhd | justin_smith: Well, I'm definitely doing that, I just bumped the version in the requiring project. |
| 14:15 | jcromartie1 | I'm really liking Cursive. |
| 14:15 | justin_smith | eraserhd: that is to say, if you add the right group / artifact in your deps (sorry for the sloppiness) |
| 14:15 | eraserhd | Oh, doh. No I don't. Weird internal version messiness. |
| 14:15 | faustroll | llasram: Storm moved on from log4j to slf4j and my previous function is no longer useful |
| 14:16 | justin_smith | eraserhd: yeah, lein install is pretty simple, so any problems are usually just not getting the group / artifact right |
| 14:16 | faustroll | I looked at the way pallet implemented logging and I liked it |
| 14:17 | dgleeson | I have a question about ring middleware. So I'm still pretty new to clojure, so this might sound like a dumb question. In all the examples of middleware I see that the first thing that happens is an anonymous function that takes a request. I'm not sure I understand where the request is coming from. |
| 14:18 | gtrak | dgleeson: check out the jetty servlet adapter. |
| 14:19 | gtrak | https://github.com/rmarianski/ring-jetty-servlet-adapter/blob/master/src/ring/adapter/jetty_servlet.clj#L14 |
| 14:19 | eraserhd | dgleeson: middleware returns an anonymous function which accepts a request. |
| 14:20 | dgleeson | eraserhd: Ah, ok, that makes sense!! thanks |
| 14:20 | gtrak | dgleeson: and that calls this to build the request map: https://github.com/mmcgrana/ring/blob/master/ring-servlet/src/ring/util/servlet.clj#L149 |
| 14:20 | eraserhd | So it's like (defn wrap-x [x] (fn [req] (x req))) |
| 14:20 | dgleeson | gtrak: also, thanks for the backgroudn! |
| 14:20 | gtrak | np! |
| 14:21 | eraserhd | So what happens when project x requires version A of z, project y requires version B of z, and project x requires project y (in leiningen)? |
| 14:22 | gtrak | you get to learn about lein exclusions |
| 14:23 | eraserhd | Is it an error? Or is the result "undefined"? |
| 14:23 | doritostains | I'm loading a schema in a datomic mem db, ~900 lines, and I get a "Method code too large" error. Is there a limit to how large a transaction can be or would there be something I should look in to? |
| 14:24 | technomancy | eraserhd: depth in the dependency tree determines it; if there's a tie then the first one wins |
| 14:26 | faustroll | llasram: I'm looking a logback docs now |
| 14:26 | faustroll | llasram: I see that logback first looks for a logback-text.xml |
| 14:27 | llasram | faustroll: If they're using slf4j, you *can* use log4j instead of logback if you prefer it. You just need to add exclusions for the logback and slf4j logback bindings and include the log4j ones |
| 14:27 | jcromartie1 | how many people here use Emacs in OS X from the terminal vs Emacs.app |
| 14:28 | eraserhd | technomancy: Oh, cool. |
| 14:28 | eraserhd | technomancy: Thanks. |
| 14:29 | PigDude | is there a shorthand for (fn [& [first-arg]] (f first-arg))? i.e. (single-arg-fn first-arg) .. |
| 14:29 | faustroll | llasram: thanks. I'm okay with logback. I'm building this with forward compatibility in mind |
| 14:29 | PigDude | i find i define functions like that for multimethods |
| 14:30 | llasram | ,((partial count) [1] :whatever :else) |
| 14:30 | clojurebot | #<ArityException clojure.lang.ArityException: Wrong number of args (3) passed to: core/count> |
| 14:30 | justin_smith | PigDude: why not (fn [arg & _] (frob arg)) |
| 14:30 | llasram | Ha, what was I thinking |
| 14:30 | faustroll | llasram: If Storm is moving on to logback, then logback it is for this project |
| 14:31 | justin_smith | PigDude: or is the intention that with no args first-arg would be passed on as nil? |
| 14:31 | PigDude | justin_smith: well, it's for instance if i had a multimethod that dispatched by identity in some cases, identity only accepts one arg |
| 14:32 | PigDude | justin_smith: but method implementations should be able to work with however many args |
| 14:32 | justin_smith | I think (fn [arg & _]) is more explicit about taking multiple args and only using the first |
| 14:32 | justin_smith | to me the fact that zero args becomes an error is a bonus |
| 14:33 | PigDude | hm that's a good point |
| 14:33 | PigDude | being same length, i used theone without the dummy binding _, but they do behave differently |
| 14:34 | justin_smith | PigDude: https://www.refheap.com/86280 a simple error-if-it-took-too-long function |
| 14:35 | justin_smith | (timed 10 #(reduce *' (range 1 10000N))) => AssertionError Assert failed: completed in a timely manner: 10ms G__1837 user/timed (NO_SOURCE_FILE:7) |
| 14:36 | justin_smith | could be trivially updated to pass in a string to include in the assert message |
| 14:40 | devn | There has to be a better way to do this: https://gist.github.com/devn/09f17059c55c01f85922 |
| 14:41 | amalloy | devn: java.lang.String is just String |
| 14:41 | devn | amalloy: sure, just qualifying it along with java.io.File |
| 14:42 | dbasch | my name is String. java.lang.String. |
| 14:42 | llasram | devn: If you really want to use some `*client*` dynamic, make the multimethod e.g. `as-page!*` and dispatch only on the non-WebClient argument. Then you can have `as-page!` be a function which accepts either arity and delegates to `as-page!*` |
| 14:43 | devn | llasram: yeah, i was heading that direction, but i wondered if there was a simpler option i was missing. that seems like the right thing to do though |
| 14:44 | devn | llasram: much obliged for the input |
| 14:44 | llasram | Well, ditching the default dynamic var argument would make it even simpler :-) |
| 14:46 | devn | llasram: yeah, but i don't wannnnnaaa :D |
| 14:48 | ticking | I really wonder what would be possible if all clojure code was just EDN instead of a superset. |
| 14:49 | ticking | You could manage the code in a database and send it of to different compilers that run as services on different platforms |
| 14:49 | dbasch | ticking: the same but less concise |
| 14:50 | ticking | dbasch: well you could tell your IDE to manage syntactic sugar for you |
| 14:51 | amalloy | i'd be sad to lose #(% x) |
| 14:51 | amalloy | ugh, and having to write (quote x) instead of 'x |
| 14:52 | amalloy | and syntax-quote |
| 14:52 | ticking | amalloy: why not have a rule in your editor that automatically displays short fn s as #(, same goes for ' |
| 14:53 | arrdem | ticking: because nesting #() isn't legal and therefore rewriting fns to #() isn't generally sane,. |
| 14:53 | ticking | amalloy: syntax quote is the only thing that would really suck because it is all done by the reader and there is no symbolic equivalent |
| 14:53 | ticking | arrdem: yeah, but I have never seen a #( contain a fn |
| 14:54 | amalloy | ticking: what |
| 14:54 | amalloy | that happens all the time |
| 14:54 | amalloy | i mean, not all the time, but certainly not never |
| 14:54 | arrdem | ticking: sure, but I have, and I've also written fns containing fns. that said I did just write a lambda lifting engine so... moot point any way you want to get the AST into the compiler. |
| 14:55 | arrdem | it'll all express the same control flow once compiled and that's all that matters |
| 14:56 | ticking | arrdem: yeah fn conainting fn or #( seems sensible to me but having short hand notation contain enough code to include a fn seems weird to me |
| 14:57 | arrdem | ticking: is it stylistically weird? sure... point is that the parser permits it. |
| 14:57 | arrdem | s/parser/reader & macroexpander/g |
| 14:58 | patrickod | I'm working on a small clojure project with ring and the ring server-headless command has suddenly stopped working due to an SSL issue with the clj_http dependency https://gist.github.com/patrickod/25671c703311eb8157a3 |
| 14:58 | patrickod | specifically java.lang.ClassNotFoundException: org.apache.http.conn.ssl.SSLContexts |
| 14:59 | ticking | arrdem: it just feels to me that clojure has the largest "data all the things" movement of all lisps, yet the language itself is the least homoiconic of them all |
| 14:59 | patrickod | I'm unsure what could have changed no my machine to cause this. has anyone experienced this before? |
| 14:59 | arrdem | ticking: how so? |
| 14:59 | arrdem | ticking: reader macros are still just as first class as lists and much nicer to use. |
| 15:00 | ticking | arrdem: the code has the most syntactic sugar |
| 15:00 | ticking | arrdem: yeah and I'd argue that reader macros break homoiconicy |
| 15:00 | arrdem | ticking: lolk |
| 15:00 | ticking | arrdem: at least when there is not a simple transformation between them as in ' and quote |
| 15:00 | hiredman | patrickod: do a 'lein deps :tree' it is likely that you have conflicting dependencies on different versions of the apache http client stuff |
| 15:01 | arrdem | ticking: okay, and why does this matter in terms of homoiconicy? |
| 15:02 | patrickod | hiredman: yah that seems to be the case. there's dependencies using both 4.3.x and 4.2.x |
| 15:02 | hiredman | patrickod: well pick one |
| 15:03 | patrickod | these are subdependencies. I'll see if their parent packages have updates that I've not used |
| 15:03 | arrdem | ticking: code's still data, data's still code, macroexpand happens to make some things easier to write. |
| 15:03 | amalloy | ticking: homoiconicity doesn't care at all about the textual representation of your code, only that the forms produced by the reader and manipulated by the compiler are the same data structures as you use to store "normal data" |
| 15:04 | arrdem | (inc amalloy) |
| 15:04 | lazybot | ⇒ 116 |
| 15:04 | ticking | arrdem amalloy: according to that definition any self hosting language is homoiconic |
| 15:04 | amalloy | uh, no? |
| 15:05 | amalloy | like, try python. how do you manipulate python code from within python? do you use arrays, lists, tuples, and dictionaries? no, you have to use strings or some byzantine AST object |
| 15:05 | ticking | amalloy: let's assume I take python, rewrite all the code blocks into python lists, maps and strings, during parsing, then pass it on to the compiler |
| 15:05 | dbasch | ticking: that’s no longer python |
| 15:05 | amalloy | if you did that, it would be homoiconic |
| 15:06 | amalloy | but that's not at all what python is now |
| 15:06 | amalloy | and that's a gargantuan project |
| 15:06 | ticking | amalloy: the tl;dr of wikipedias definition of homoiconicity is " the AST and the syntax are isomorphic" |
| 15:06 | hiredman | amalloy: wikipedia's homoiconicity entry would seem to disagree with ou |
| 15:07 | ticking | how is the ast of a sytax quote isomorphic to what it expands to? |
| 15:07 | dbasch | “In a homoiconic language the primary representation of programs is also a data structure in a primitive type of the language itself” |
| 15:08 | ticking | dbasch: yes, but as clojure has no quasiquote type, I don't see how this holds |
| 15:10 | justin_smith | homoiconicity is not identity of source code as ascii and program structure, that the internal form is a native clojure structure suffices |
| 15:10 | justin_smith | reader macros are a convenience, but they don't affect the meaning of the thing stored |
| 15:11 | ticking | justin_smith: but how is that any different from any self hosting system |
| 15:11 | ticking | arrdem: no seriously, show me the difference |
| 15:11 | dbasch | a python program is not a primitive python data structure, unless you call strings data structures |
| 15:11 | ticking | currently the best way to work with clojure seems to be tools.analyzer |
| 15:11 | amalloy | heh. C is homoiconic because its code is represented as pointers to bytes, which are a native type |
| 15:11 | arrdem | because the read of "for(int i = 0; i < 3; i++){println(i);}" has no syntactic meaning in another language. |
| 15:11 | arrdem | here java |
| 15:12 | justin_smith | ticking: you can walk the internal representation, and it looks like normal data structures, and you can use normal data structure manipulating code on it |
| 15:12 | ticking | which produces the exact byzantine ast "objects" amalloy feared |
| 15:12 | dbasch | machine language is homoiconic :P |
| 15:12 | arrdem | (inc dbasch) |
| 15:12 | lazybot | ⇒ 4 |
| 15:12 | amalloy | ticking: no, the easiest way to work with clojure is to write clojure, and use macros to manipulate the source |
| 15:13 | amalloy | you use tools.analyzer if you need a deep knowledge of what small vm-level instructions your code will turn into |
| 15:14 | ticking | amalloy: but that is exactly the point, you can't manipulate the source, only an intermediary, because of reader macros |
| 15:14 | ticking | otherwise writing a structural editor would be a bazillion times easier |
| 15:15 | justin_smith | but the intermediary has the same structure as the source, it is just more explicit / verbose - and when you are doing programmatic transformation this is a big win |
| 15:15 | Glenjamin | but you *can* manipuate the AST |
| 15:15 | justin_smith | because that is simpler to work with in macros etc. |
| 15:15 | dbasch | ticking: you can manipulate the source to a large extent, depending on what you want to do, without expanding reader macros |
| 15:15 | ticking | justin_smith: I agree for most reader macros, but not for example for quasiquote |
| 15:16 | justin_smith | ticking: you would rather manually do what quasiquote does yourself, rather than use the expanded and resolved version of the form? |
| 15:16 | PigDude | justin_smith: thanks, i was working on a macro but couldn't quite get it to work, i'll have to paste it when i do later :) |
| 15:17 | justin_smith | PigDude: np, I was considering a macro a last resort, what I have there could easily be wrapped in a convenience macro to avoid creating a thunk manually though |
| 15:17 | ticking | justin_smith: no, I rather had ` turn to (quasiquote |
| 15:18 | llasram | ticking: Maybe orthogonal to what you're saying, but have you seen https://github.com/brandonbloom/backtick ? |
| 15:18 | ticking | llasram: not yet thanks, this seems very interesting |
| 15:19 | ticking | justin_smith: I'm not against all the syntactic niceties and shorthands, I just think they should be a more direct representation of the read intermiary |
| 15:20 | ticking | s/intermiary/intermediary |
| 15:21 | ticking | There are things like indentation, I would rather leave to the editor completely |
| 15:21 | justin_smith | ticking: so you want more granularity in where one can intervene? |
| 15:21 | l3dx | https://gist.github.com/tskardal/e189daf48e971e2a3197 - how can I solve this in a better way? the result of this is a seq of JPanels |
| 15:22 | l3dx | or should I perhaps just ignore the return value. it's mutated after all |
| 15:22 | dbasch | l3dx: you shouldn’t be using for, you should have a loop |
| 15:22 | ticking | justin_smith: basically, I want a more straightforward and simpler intermediary representation that retains more properties of the written code |
| 15:22 | dbasch | l3dx: for is for creating sequences, you want side effects |
| 15:23 | ticking | justin_smith: the worst in this regard is the meta reader I think ^, it outputs datastructures with metadata directly |
| 15:25 | amalloy | dbasch: well, doseq |
| 15:26 | amalloy | ticking: so you want sjacket or something? wanting something that understands clojure's textual layout is nice, but if that's all you want i don't understand the railing against homoiconicity |
| 15:26 | dbasch | amalloy: or dotimes, in this case |
| 15:26 | amalloy | dbasch: he'll probably want to use x and y in the real code |
| 15:27 | l3dx | dbasch: ok, so how would I achieve the same x-y-loop? |
| 15:28 | dbasch | l3dx: (doseq [x (range (:witdh game) …. |
| 15:28 | justin_smith | l3dx: do what amalloy suggests and switch out for for dotimes, dotimes has the same syntax but it is done for side effects and returns nil and isn't lazy |
| 15:28 | clojurebot | In Ordnung |
| 15:28 | l3dx | aah, so not the actual loop function |
| 15:28 | justin_smith | err, I meant doseq, unless you need the numbers |
| 15:28 | l3dx | as in loop/recur |
| 15:29 | llasram | clojurebot: dotimes has the same syntax but it? |
| 15:29 | clojurebot | Gabh mo leithscéal? |
| 15:29 | llasram | Ok, so the whole thing then |
| 15:29 | l3dx | thanks |
| 15:29 | dbasch | l3dx: yes, I meant a loop in the generic sense |
| 15:30 | ticking | amalloy: what I'm saying is that the smarter the reader macros get, the more removed the source code will be from the read datastructure will be. And this means less homoiconicity as wikipedia defines it "is a property ... in which the program structure is similar to its syntax, and ... internal representation can be inferred by reading the text..." |
| 15:30 | ticking | s/will be/ |
| 15:30 | arrdem | ticking: so really this is a long argument against context sensitive macros, which are a bad idea anyway. |
| 15:31 | AWizzArd | Anyone here who was using naive bayes on mnist? |
| 15:32 | amalloy | aw man. it turns out that you can use emacs to browse a jar inside of a tgz, but if you try to read any files inside the jar, unzip breaks |
| 15:32 | justin_smith | sounds like an emacs bug |
| 15:35 | ticking | arrdem: theres nothing wrong with context sensitivity as long as it is expressed in the read datastructure to be executed by regular macros and not as a reader macro to be executed before it is data |
| 15:36 | ticking | arrdem: you should be able to read a code file, serialize it again and not go "WTF", that is my metric here |
| 15:40 | Glenjamin | what actually happens if you read-string with a syntax quote? |
| 15:40 | amalloy | ~tias |
| 15:40 | clojurebot | Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance. |
| 15:41 | Glenjamin | ,(read-string "`(~@a)") |
| 15:41 | clojurebot | (clojure.core/seq (clojure.core/concat a)) |
| 15:41 | amalloy | &`(foo ~@bar ~baz) ;; a shortcut |
| 15:41 | lazybot | java.lang.RuntimeException: Unable to resolve symbol: bar in this context |
| 15:41 | amalloy | &'`(foo ~@bar ~baz) |
| 15:41 | lazybot | ⇒ (clojure.core/seq (clojure.core/concat (clojure.core/list (quote clojure.core/foo)) bar (clojure.core/list baz))) |
| 15:41 | justin_smith | ,,(read-string "`+") |
| 15:41 | clojurebot | (quote clojure.core/+) |
| 15:41 | amalloy | guys why are you using read-string |
| 15:41 | amalloy | just use quote. that's what it's for |
| 15:41 | Glenjamin | because of the homoiconicity discussion |
| 15:41 | justin_smith | he asked a question about read-string |
| 15:42 | amalloy | (read-string "foo") is the same as 'foo, for all foo |
| 15:42 | cbp | (inc amalloy) |
| 15:42 | lazybot | ⇒ 117 |
| 15:43 | ticking | even worse |
| 15:43 | ticking | '(defn ^Integer len [^String x] (.length x)) |
| 15:43 | Glenjamin | ,'(defn ^Integer len [^String x] (.length x)) |
| 15:43 | clojurebot | (defn len [x] (.length x)) |
| 15:44 | ticking | ah sorry I'm a bit distracted yeah thanks ^^ |
| 15:44 | ticking | so where did the meta go? |
| 15:44 | Glenjamin | ,(binding [*with-meta* true] '(defn ^Integer len [^String x] (.length x))) |
| 15:44 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve var: *with-meta* in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 15:44 | ticking | ,(meta (second '(defn ^Integer len [^String x] (.length x)))) |
| 15:44 | clojurebot | {:tag Integer} |
| 15:44 | ticking | ah there it is |
| 15:44 | Bronsa | ,(binding [*print-meta* true] (pr '(defn ^Integer len [^String x] (.length x)))) |
| 15:44 | clojurebot | (defn ^Integer len [^String x] (.length x)) |
| 15:44 | Glenjamin | ^^ thats the one |
| 15:45 | ticking | yeah but that means that no database that we currently use in clojure can hold our code |
| 15:46 | Bronsa | :| |
| 15:46 | ticking | we either have metas in syntax, which it won't be able to read, or we have metas attached to the symbols, which it will probably disgard, because they are not part of the value |
| 15:47 | arrdem | or we could just have a more honest print that displays metas so that round tripping code is honest... |
| 15:47 | arrdem | s/honest/an identity operation/g |
| 15:47 | amalloy | arrdem: you won't like all the :line metadata that gets printed |
| 15:47 | arrdem | amalloy: I'm well aware of all the metadata that'd get spewed. |
| 15:48 | Bronsa | and if you use tools.reader you get :line, :column, :end-line, :end-column, :file and maybe even :source ! |
| 15:48 | arrdem | Bronsa: yeah... source containing source.... this'll end well |
| 15:49 | Bronsa | arrdem: https://github.com/clojure/tools.reader/blob/master/src/main/clojure/clojure/tools/reader/reader_types.clj#L294 |
| 15:50 | arrdem | Bronsa: what are you doing to that poor var... |
| 15:50 | Bronsa | arrdem: to my defense I didn't write that code |
| 15:51 | devn | technomancy: do you know how many hits clojars.org gets/day? |
| 15:51 | Bronsa | arrdem: it's a way to get an anonymous Var |
| 15:51 | technomancy | devn: I have numbers that are a year and a half old; want 'em? |
| 15:52 | devn | yeah that'd be cool |
| 15:52 | arrdem | Bronsa: hum.... |
| 15:52 | technomancy | https://www.refheap.com/6193 |
| 15:52 | amalloy | Bronsa: what about with-local-vars? ##(with-local-vars [x 1] x) |
| 15:52 | lazybot | java.lang.SecurityException: You tripped the alarm! class clojure.lang.Var is bad! |
| 15:53 | technomancy | devn: wait, do you mean the web app or the repository? |
| 15:53 | amalloy | ,(with-local-vars [x 1] x) |
| 15:53 | clojurebot | #<Var: --unnamed--> |
| 15:54 | Bronsa | amalloy: uh it didn't occur to me that vars created with with-local-vars could escape the with-local-vars scope |
| 15:54 | technomancy | hm; that might not be all that useful |
| 15:54 | amalloy | i don't actually know if it works, but it probably does |
| 15:54 | Bronsa | yeah looking at the source now, it's just Var/create + bindings around the body |
| 15:54 | amalloy | ,(let [v (with-local-vars [x 1] x)] (with-bindings [v 2] @v)) |
| 15:54 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.Var cannot be cast to clojure.lang.IMapEntry> |
| 15:55 | amalloy | ,(let [v (with-local-vars [x 1] x)] (with-bindings {v 2} @v)) |
| 15:55 | clojurebot | 2 |
| 15:55 | amalloy | magic! |
| 15:55 | ticking | arrdem Bronsa: so yeah, I'm not saying all is lost, a more honest print might be a good idea, but I think being able to put code into databases and query it would be really awesome, and putting nodes a la {:type :vector :contents foo} really seems like too much |
| 15:55 | Bronsa | yeah well, I still prefer (Var/create 1) to (with-local-vars [x 1] x) :) |
| 15:55 | amalloy | wimp |
| 15:55 | amalloy | interop is the easy way out |
| 15:55 | Glenjamin | isn't that what codex does? |
| 15:56 | Glenjamin | maybe not codex |
| 15:56 | arrdem | amalloy: does it matter? it reaches in to the same var class anyway, just through a clojure core fn instead... |
| 15:56 | Glenjamin | what was that git history clojure datomic thing called? |
| 15:56 | llasram | codeq |
| 15:56 | ticking | yeah |
| 15:57 | Bronsa | I wish (var x) was (the-var x) so var could be Var/create |
| 15:57 | amalloy | arrdem: it doesn't matter |
| 15:57 | bbloom | Bronsa: isn't Var/create == intenr ? |
| 15:57 | amalloy | i would use Var/create instead of with-local-vars |
| 15:57 | bbloom | intern* |
| 15:57 | amalloy | bbloom: no, that needs a name |
| 15:57 | amalloy | puts it into a namespace, etc etc |
| 15:57 | bbloom | (doc intern) |
| 15:57 | Bronsa | bbloom: no, Var/create returns an anonymous Var instance |
| 15:57 | clojurebot | "([ns name] [ns name val]); Finds or creates a var named by the symbol name in the namespace ns (which can be a symbol or a namespace), setting its root binding to val if supplied. The namespace must exist. The var will adopt any metadata from the name symbol. Returns the var." |
| 15:58 | bbloom | (doc the-var) |
| 15:58 | clojurebot | Huh? |
| 15:58 | bbloom | yeah, ok, "or creates" |
| 15:59 | ticking | Glenjamin: but I think they are only code aware and don't dump it all in the database, the orgmode readme contains a lot of questionmarks on ast vs strings |
| 15:59 | gfredericks | cemerick: I pung; I was pondering NREPL-53 and was wondering if it's valid to say that nrepl middleware ordering boils down to a basic topological sort; once the op-vs-var thing is normalized |
| 15:59 | bbloom | Bronsa: Var/create doesn't need to be primitive or anything, does it? i don't understand your wish :-P |
| 15:59 | Bronsa | bbloom: what I meant is, I wish the `var` special form was called `the-var` so that we could have a `var` function that created an anonymous Var, just like we have `atom`, `ref` etc |
| 15:59 | Bronsa | bbloom: I'd rather write (var 1) than (clojure.lang.Var/create 1) :P |
| 15:59 | gtrak | gfredericks: I think I'm running into issues there |
| 15:59 | bbloom | Bronsa: ah, i see. you mean for un-named thread locals |
| 15:59 | bbloom | gotcha |
| 16:00 | Bronsa | yep |
| 16:00 | gtrak | apparently nrepl middleware and gary don't mix |
| 16:00 | bbloom | sorry, came to the conversation a step late :-) |
| 16:01 | gtrak | gfredericks: https://groups.google.com/d/msg/clojure/nUBBbYZHuTE/ScLBH-A2HkoJ |
| 16:01 | bbloom | yeah, vars are a bit... dare i say... complected |
| 16:02 | bbloom | namespace + state management combined |
| 16:06 | amalloy | i propose that instead of using reflection to resolve unhinted interop, clojure just assumes you meant String |
| 16:06 | amalloy | that seems like the #1 cause of reflection warnings |
| 16:08 | dbasch | amalloy: it would be interesting to run a test on all the artifacts on clojars and see if that’s indeed the case |
| 16:09 | amalloy | dbasch: i think String would constitute about 50% of all interop |
| 16:09 | amalloy | but you can't really test it in an automated way |
| 16:10 | bbloom | amalloy: you probably could with eclj |
| 16:10 | bbloom | amalloy: but not realistically yet, b/c all clojure.core usage is considered interop lol |
| 16:15 | arrdem | Bronsa: thinking about the AOT stuff, my gut is that class compilation should just emit a seq of [classname bytecode] pairs and that subsequent classloading or lack thereof should be its own thing as opposed to the implicit classloading that t.e.jvm does now. thoughts? |
| 16:17 | Bronsa | arrdem: that's not going to work as tej works right now, control doesn't return to t.e.j/eval for all fns unfortunately. |
| 16:19 | gfredericks | gtrak: hooray it's not just me |
| 16:19 | gtrak | was planning to spend a couple days on it sometime in the next few weeks |
| 16:19 | gtrak | it's really holding back cider. |
| 16:19 | gtrak | or at least, my lack of understanding it is holding back cider. |
| 16:19 | Bronsa | arrdem: an option could be to make the class-loading mechanism configurable using an option on the emit frame, so maybe (e/emit (a/analyze ..) {:loader-fn (fn [loader class-name bytecode] (.defineClass loader class-name bytecode))} ..) |
| 16:20 | gfredericks | gtrak: it weirds me out that this doesn't blow up for normal people |
| 16:20 | gtrak | I think that normal people don't futz with middlewares yet. |
| 16:20 | Bronsa | arrdem: that way you could roll your own loader-fn and put the [class-name bytecode] tuples in an atom maybe |
| 16:20 | gtrak | except to you know, like just add one. |
| 16:20 | arrdem | Bronsa: that'd probably work. I'm gonna break for food and I'll play with it once I'm back. |
| 16:21 | Bronsa | arrdem: ok |
| 16:21 | gfredericks | gtrak: right, but why doesn't this issue apply to existing sets of middlewares? |
| 16:21 | gtrak | gfredericks: my workaround was to collect all the expects and requires from a bunch of middlewares and generate a single middleware. |
| 16:21 | gfredericks | gtrak: i.e., reimplement the ordering yourself? :D |
| 16:21 | gtrak | heh yes. |
| 16:21 | gtrak | but that's a big change for me not understanding the implications. |
| 16:22 | Bronsa | arrdem: are you a clojure contrib member? if so you can go ahead and make the changes you need to t.e.j in a branch if you want |
| 16:24 | arrdem | Bronsa: I've had my CA in for a while, don't think I have contrib access tho. I asked tb++ about it a while back and it sounded like something that wasn't gonna happen for whatever reason. |
| 16:24 | arrdem | so... shrug |
| 16:25 | arrdem | probably something I should bug Alex M. about. |
| 16:25 | gfredericks | gtrak: we should flip a coin to see who has to fix it |
| 16:26 | gtrak | gfredericks: I'll end up fixing it in a few weeks unless you beat me to it. been really busy. |
| 16:26 | gtrak | but first I have to make some test-cases. |
| 16:26 | gfredericks | gtrak: you saw my code on the ticket? |
| 16:26 | gtrak | yea |
| 16:27 | gtrak | i did something similar. |
| 16:27 | gtrak | i don't even remember. |
| 16:27 | gtrak | :-) it's a mess. |
| 16:27 | gfredericks | did you observe nondeterminism or just incorrectness? |
| 16:27 | Bronsa | arrdem: yeah, I don't really know how any of this stuff should work but try asking Alex, I wouldn't have a problem letting you push your changes in a separate branch |
| 16:27 | gtrak | incorrectness. |
| 16:27 | gtrak | I didn't try multiple JVMs |
| 16:28 | gtrak | gfredericks: I would expect a behavior that throws an error if constraints can't be met, at least a warning. |
| 16:28 | gtrak | with the conflicting constraints. |
| 16:28 | gfredericks | gtrak: I didn't think my constraints were even conflicting |
| 16:28 | gtrak | mine either. |
| 16:28 | gtrak | it made no sense. |
| 16:29 | gtrak | but the result was totally wrong. |
| 16:29 | gtrak | or at least it didn't match my understanding |
| 16:29 | gtrak | _something_ was wrong. |
| 16:30 | gfredericks | fo sho |
| 16:30 | gfredericks | I wasn't able to wrap my head around the code so far |
| 16:30 | gfredericks | I was hoping that given two middlewares the info would boil down to a partial order |
| 16:31 | gfredericks | can't tell looking at the code if that's the case |
| 16:31 | gtrak | me neither, I might try reimplementing it. |
| 16:31 | gtrak | like I said, on the order of a couple days' work. |
| 16:31 | gtrak | hopefully before we have to push a cider release. |
| 16:33 | gtrak | it seems like these tooling projects have lots of good ideas that are half-finished :-) |
| 16:33 | gtrak | for instance the elisp bencode impl couldn't handle nesting before I got to it. |
| 16:33 | gfredericks | that must be less dire than it sounds |
| 16:34 | gtrak | well, nesting's a nice thing to want to have. |
| 16:34 | gtrak | which is why I had to realize that pain for myself. |
| 16:34 | gtrak | and this is why we can't have nice things. |
| 16:36 | {blake} | Hey, all: I have a question about some code I've written. (ref: https://www.refheap.com/86286) In particular, I feel like it's cheap to have to call "flatten" and especially "remove nil?". Any thoughts? |
| 16:37 | joegallo | {blake}: i believe you could collapse your let and if up into the for itself (as :let and :when) |
| 16:37 | {blake} | I know I could get the "remove nil?" out if I tested the return but I can't see a non-clunky way to do that. |
| 16:37 | gtrak | gfredericks: I've even started thinking about what it would take to implement these things in CLJS or possibly CLR :-) |
| 16:37 | gtrak | which is a whole can of worms. |
| 16:37 | {blake} | joegallo, thanks, lemme try that out... |
| 16:37 | joegallo | then you wouldn't have to remove the nils from the result, because they wouldn't have been generated by the for |
| 16:38 | {blake} | Well, but...hmmm. |
| 16:39 | llasram | {blake}: It looks to me like this may be one of the circumstances where you want a manual `lazy-seq` |
| 16:40 | {blake} | llasram: A manual lazy-seq...like calling "lazy-seq" directly? |
| 16:40 | llasram | Yes |
| 16:41 | llasram | Oh, except... the recursion is essentially depth-first? |
| 16:41 | {blake} | llasram: OK, I'll check that out, too. |
| 16:41 | zoldar | {blake}: you could also make use of destructuring in let bindings |
| 16:41 | {blake} | zoldar, ok *makes list* |
| 16:42 | gfredericks | gtrak: so many cans |
| 16:43 | zoldar | {blake}: that's partly a matter of personal preference but I would rather use full names rather than abberviations, even when the scope is small |
| 16:43 | {blake} | zoldar, not sure I follow...you mean full names instead of "t", "c" and "tt"? |
| 16:44 | zoldar | {blake}: yes |
| 16:45 | {blake} | zoldar, I get that. I'm not sure where I come down on it yet. If I use full names, I find myself wondering if I'm thinking too concretely. |
| 16:46 | amalloy | {blake}: the flatten is particularly outrageous, as you suspected. i'd write something like https://www.refheap.com/61d3a3c7f691c1f26c8084770, although i agree about the names t, c, tt; i added x only because i don't know what the right name is in your context |
| 16:47 | zoldar | {blake}: overall, you could move the code working with a single element of collection (the one in for form) to a separate function - and instead of using flatten and for you could use a form like (into {} (map ... pz-xml)) |
| 16:47 | {blake} | amalloy: You agree with zoldar about using full names? |
| 16:48 | {blake} | Ah, yes, I see that you've fleshed them out. =P |
| 16:51 | cemerick | gfredericks: generally and IIRC. There's a set of reasonably complex nREPL issues that were started a week or two ago I haven't looked at in detail, that's one of them. |
| 16:52 | {blake} | amalloy, I don't think I get "for [{:keys [tag content]} pz-xml..." You're iterating over pz-xml and pulling out the keys, is that right? Then destructuring tag and content from them? |
| 16:52 | zoldar | {blake}: erm, of course the second part of my last advice is wrong, ignore it |
| 16:53 | {blake} | zoldar, OK. It usually takes me a while to go through the advice queue and quasi-understand it. Heh. |
| 16:53 | amalloy | are you asking about :keys destructuring in general, or about what it's doing inside a for, or...? |
| 16:56 | amalloy | actually, i'm off to lunch. but the basic point is: anytime you give something a name, you can destructure it instead. [{:keys [x y z]} foo] is a destructuring form that says "look up (:x foo), (:y foo), and (:z foo), and create locals named x, y, and z for them" |
| 16:56 | {blake} | amalloy: thanks...I think that answers it |
| 17:05 | zoldar | {blake}: in case you haven't heard about it yet, 4clojure.com is pretty fun way to learn idioms of the language. It's pretty useful to follow a couple of top participants to see what they have come up with after solving a given problem yourself. I remember that amalloy's solutions in particular were pretty damn nice. |
| 17:07 | mdeboard | The map destructuring bind syntax is particularly hard to remember IMO |
| 17:08 | mordocai | zoldar: Thanks for that! I'm just lurking in this channel and going through The Joy of Clojure. Looks like 4clojure.com will be very helpful to "master" clojure. |
| 17:08 | mdeboard | [{:keys [x y z]} foo] ... lots of syntax |
| 17:08 | arrdem | mdeboard: :keys, :as and :or aren't too bad, IMO |
| 17:09 | arrdem | it's just a mapping datastructure from keys to local symbols |
| 17:09 | zoldar | mordocai: my pleasure |
| 17:09 | mdeboard | Well, it's just remembering whether to use parens, braces, brackets, "Is 'keys' a keyword? I forgot" |
| 17:09 | zoldar | mordocai: however thanks should go to the authors |
| 17:09 | mordocai | zoldar: Of course, but thanks for letting me know about it :P |
| 17:10 | mdeboard | The function parameter syntax in general is tough forme to remember |
| 17:10 | mdeboard | When you get into optional arguments, destructuring, etc. |
| 17:11 | noonian | [{:keys [x y z]} foo] could also be written [{x :x, y :y, z :z} foo] btw, :keys :as and :or is nice sugar to keep it concise(ish) |
| 17:13 | zoldar | mordocai: another option is clojure track on exercism.io however I'm not sure how active it is now |
| 17:14 | mordocai | zoldar: You said you liked amalloy's solutions on 4clojure, do you remember what username they are under? Don't see amalloy or related username that I can tell. (I would ask amalloy but looks like they are AFK) |
| 17:14 | {blake} | zoldar, I've done about 60-70 of the 4Clojure exercises. I didn't find it all that useful. I might now, though, knowing more about Clojure. |
| 17:15 | zoldar | {blake}: heh, I've just logged in and don't see him either... |
| 17:16 | {blake} | mordocai, I think he's under amalloy, at least as far as submitting problems. |
| 17:16 | dbasch | {blake}: there’s a point at which 4clojure becomes more about programming puzzles than the language, probably 60-70 is about right before you’re better off with a real project |
| 17:17 | zoldar | {blake}: ah, you have to switch to show all |
| 17:17 | dbasch | {blake}: imo, the most useful ones are the ones that make you reimplement features of the language (e.g. comp, juxt) |
| 17:17 | {blake} | dbasch, Exactly. There's also a point =before= where you're just throwing stuff together to see if you can make something come out, which has limited use. (At least, that's what =I= ended up doing. =P) |
| 17:17 | {blake} | dbasch, true, and those are the hardest, IMO. |
| 17:18 | zoldar | dbasch: yeah, there's even an (optional) code golf contest |
| 17:20 | zoldar | oops just realized that I've mixed up names when messaging, sorry |
| 17:21 | llasram | ~guards |
| 17:21 | clojurebot | SEIZE HIM! |
| 17:21 | arrdem | ~gourds |
| 17:21 | zoldar | :) |
| 17:21 | arrdem | aaaaand bot ignored |
| 17:21 | llasram | Huh |
| 17:21 | arrdem | this is getting old. |
| 17:21 | llasram | Oh, are you on clojurebot's naughty list some how, arrdem ? |
| 17:22 | arrdem | llasram: apparently. |
| 17:22 | llasram | hiredman: ? |
| 17:22 | gtrak | ~gourds |
| 17:22 | clojurebot | SQUEEZE HIM! |
| 17:22 | hiredman | llasram: ? |
| 17:23 | llasram | Just wondering arrdem's status on clojurebot's secret naughty list |
| 17:23 | llasram | Seeeeecrets |
| 17:24 | hiredman | https://github.com/hiredman/clojurebot/blob/master/clojurebot-facts/src/clojurebot/facts.clj#L74 |
| 17:24 | llasram | s,secret,well-publicized, |
| 17:24 | arrdem | well damn. |
| 17:25 | gtrak | up there with bitemyapp, that's harsh. |
| 17:25 | arrdem | yeah... I'm actually offended somewhat. |
| 17:26 | gtrak | what did you do? |
| 17:26 | arrdem | no idea... best guess is that I wrote too many factoids. *shrug* |
| 17:28 | dbasch | arrdem: you should write your own bot, with blackjack and hookers |
| 17:28 | dbasch | arrdem: call it bender |
| 17:28 | arrdem | dbasch: meh... priorities. |
| 17:28 | llasram | Or just submit a polite and apologetic PR to hiredman :-) |
| 17:29 | dbasch | everybody should write an irc bot once, it’s fun |
| 17:29 | arrdem | dbasch: I already did mine. in perl and irssi. never again. |
| 17:29 | dbasch | I did mine in Ruby |
| 17:29 | arrdem | dbasch: the good news is that the pentesters in the channel it lurked never did manage to exploit it :D |
| 17:30 | {blake} | I did one in Delphi. |
| 17:36 | knur | :) |
| 17:40 | pcn | Does anyone know the record uptime for a windows box? |
| 17:44 | amalloy | it can't be an official record unless a beer company verifies it |
| 17:48 | arrdem | well you can write a Θ bound for it, based on the first sale of MS-DOS... |
| 17:57 | dbasch | arrdem: you can do better than that, the development of Windows started in 1982 |
| 18:08 | justin_smith | I'm picturing that Owl from the tootsie roll commercial, starting up a windows box, getting a blue screen after two minutes: "two. two minutes" |
| 18:09 | dbasch | asking about the machine with the most windows uptime is a bit like wondering who’s the tallest midget to ever live |
| 18:10 | amalloy | dbasch: http://en.wikipedia.org/wiki/Adam_Rainer |
| 18:10 | justin_smith | http://raamdev.com/2007/another-best-personal-windows-uptime/ here is a guy bragging about 131 days |
| 18:11 | TimMc | hahaha |
| 18:11 | gtrak | mine runs fine except it freaking reboots itself. |
| 18:11 | gtrak | when updates are pushed. |
| 18:11 | dbasch | amalloy: actually I remember that guy from the first edition of the Guinness book of records I got when I was a kid |
| 18:11 | dbasch | along with Robert Wadlow |
| 18:11 | mordocai | Meh, my linux uptime isn't that great because I am an update-aholoic so I reboot for kernel/libc updates regularly. Better than being forced to reboot though. |
| 18:14 | TimMc | Yeah, critical patches ruin uptime whether you're forced to reboot or do it voluntarily. :-/ |
| 18:15 | dbasch | “The earliest application of the Game Oriented Assembly Lisp (GOAL) programming tool, was the original Jak and Daxter game.” <— Guinness record |
| 18:16 | kenrestivo | btw, it's not just windows. a friend with a macbook air, had problems with network connectivity, and was told by the "genius" at the apple store to reboot his macbook every few days to solve that |
| 18:17 | teslanick | What does #' indicate? e.g. #'app ? |
| 18:18 | amalloy | ,'#'app |
| 18:18 | clojurebot | (var app) |
| 18:18 | amalloy | if there's some reader syntax that confuses you, you can just put a quote in front of it and see what it expands to |
| 18:19 | teslanick | I didn't know that, thans! |
| 18:20 | dbasch | teslanick: #’ is a reader macro called var-quote |
| 18:21 | dbasch | teslanick: those are hard to google, you can find them here: http://clojure.org/reader#The%20Reader--Macro%20characters |
| 18:21 | teslanick | That's precisely why I asked -- it would be impossible to google for it. ;) |
| 18:23 | kenrestivo | ,'#inst "2014-05-01" |
| 18:23 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 18:23 | cbp | hmm why is that denied |
| 18:24 | whodidthis | mysteries of the universe, why is (compojure.core/defroutes them-routes ...) given to ring-handler as #'them-routes |
| 18:25 | cbp | whodidthis: so you can modify them at runtime |
| 18:26 | amalloy | cbp: maybe clojurebot knows that j.u.Date is garbage, and he's trying to protect you |
| 18:29 | cbp | you might take my j.u.Date from me clojurebot but you will never take my freedom |
| 18:29 | sdegutis | TIL that (future (doall (repeatedly some-fn-that-throws-exception))) silently stops unless you put in a try/catch. |
| 18:35 | cbp | sdegutis: it might be that its just not done yet |
| 18:35 | cbp | sdegutis: can only make sure its done by dereferencing it |
| 18:35 | sdegutis | cbp: It doesn't take this many hours for an EC2 server to download a 1.5 GB file. |
| 18:36 | amalloy | well, it can never be done, since he asked for an infinite amount of work |
| 18:36 | sdegutis | amalloy: semantics |
| 18:36 | cbp | amalloy: but it throws so it will be done at the first step |
| 18:36 | PigDude | is this normal multimethod usage when other namespaces are defining methods? the :require [tex-mex] feels weird: https://www.refheap.com/83d9d77c079836d461c129c84 |
| 18:38 | amalloy | that's basically what you have to do, PigDude. you can include a comment explaining that it's for loading method definitions |
| 18:38 | cbp | sdegutis: i guess i mean *started* rather than done |
| 18:39 | cbp | so it's not failing silently just not doing much at all |
| 18:39 | amalloy | also, namespaces with no . in them are bad juju. so like, you'd want awesome.cookbook and recipes.tex-mex or something |
| 18:39 | PigDude | amalloy: and it's that way for protocols as well? |
| 18:39 | dbasch | sdegutis: that’s a very strange way to keep calling a function until it fails btw |
| 18:39 | sdegutis | dbasch: it should never fail. |
| 18:39 | PigDude | amalloy: yea i was justhammering out this example for you all |
| 18:39 | amalloy | dbasch: but it's nice because it guarantees that it will fail! |
| 18:39 | dbasch | sdegutis: then how does it end? |
| 18:39 | amalloy | because he's saving its results in a doall, and he'll eventually run out of ram for them |
| 18:40 | cbp | :-P |
| 18:40 | sdegutis | dbasch: it's how we run infinite background-processes in the website until I can get this infrastructure tool working for EC2 and spin up a new server for that |
| 18:40 | sdegutis | amalloy: the results are nil afaik, but yeah, good point, I shouldn't use a doall |
| 18:40 | dbasch | infinite background processes? Wow, you must have a high aws bill :P |
| 18:41 | amalloy | sdegutis: infinitely many nils still take up infinite space |
| 18:41 | dbasch | my iinstances are limited to 10^100 processes |
| 18:41 | sdegutis | Hmm. |
| 18:41 | sdegutis | No no no, not a unix process, just a task. |
| 18:41 | sdegutis | To run in a new Java thread. |
| 18:42 | dbasch | sdegutis: that’s better, I can do 10^300 threads |
| 18:42 | amalloy | 10^100 processes, huh? that's the kind of number only like google could handle |
| 18:42 | cbp | 10^100 processes? that's not even enough to compile haskell! |
| 18:42 | dbasch | I need them, I’m trying to list all bitcoin keys |
| 18:42 | arrdem | dbasch: y u build rainbow tbls n brk blockchain. y u do dis. |
| 18:43 | amalloy | c'mon guys, play along. 10^100? google? googol? i'm dying here |
| 18:43 | dbasch | amalloy: that’s the kind of joke they’d love at the 10^(10^100) |
| 18:43 | amalloy | *rimshot* |
| 18:44 | arrdem | amalloy: no it's ~rimshot |
| 18:44 | amalloy | i don't let clojurebot steal my glory |
| 18:44 | cbp | too bad arrdem can't do it |
| 18:44 | arrdem | cbp: I'll build my own bot with blackjack and hookers... |
| 18:45 | PigDude | anyhow thanks amalloy :) |
| 18:48 | PigDude | i researched this other quesiton i had a lot and couldn't find an answer either: how do you bind something in a macro that is private to the macro? |
| 18:49 | PigDude | i can output values with ~() but i can't share them with other ~() expansions |
| 18:50 | amalloy | PigDude: i don't really understand the question. are you looking for something more sophisticated than auto-gensyms? |
| 18:50 | PigDude | more specifically, to define a function (as a curiosity) that accepted some gensym-named arguments and then uses them somewhere in its body |
| 18:50 | PigDude | amalloy: well v# works fine when you know ahead of time how many you have |
| 18:51 | PigDude | amalloy: but if i generate this list of symbols, then i want to do (map gensym (somthing)) |
| 18:51 | PigDude | and use it around the function |
| 18:52 | PigDude | i thought it was a stupid question but i couldn't figure out how to define some data in the macro and use it twice, basically: (defmacro m [x] (let [x* (inc x)] ...)) <- no trace of x/x* should be in the macro-expanded form |
| 18:52 | amalloy | you can certainly do that. just (let [names (repeatedly n gensym)] `(fn [~@names] (+ ~@names))) or whatever |
| 18:52 | amalloy | PigDude: what you've just written is the answer to your question |
| 18:52 | PigDude | (defmacro m [] (let [names (repeatedly n gensym)] `(fn [~@names] (+ ~@names))) |
| 18:52 | PigDude | , (defmacro m [] (let [names (repeatedly n gensym)] `(fn [~@names] (+ ~@names)))) (m [1 2 3]) |
| 18:52 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: n in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 18:52 | amalloy | x and x* only live in the macro's scope, they don't get emitted |
| 18:52 | PigDude | , (defmacro m [n] (let [names (repeatedly n gensym)] `(fn [~@names] (+ ~@names)))) (m [1 2 3]) |
| 18:52 | clojurebot | #'sandbox/m |
| 18:53 | PigDude | ah right only one at a time |
| 18:53 | PigDude | ,(macroexpand-1 '(m [1 2 3])) |
| 18:53 | clojurebot | #<ClassCastException java.lang.ClassCastException: clojure.lang.PersistentVector cannot be cast to java.lang.Number> |
| 18:53 | amalloy | ,((m 5) 1 2 3 4 5) |
| 18:53 | clojurebot | 15 |
| 18:53 | PigDude | amalloy: oh ok so i was only seeing them because i was using macroexpand-1? |
| 18:53 | PigDude | amalloy: of course! |
| 18:54 | amalloy | PigDude: no, if you saw them in macroexpand, they were in the emitted source |
| 18:54 | amalloy | presumably because you let them inside of the syntax-quote, instead of outside it |
| 18:54 | amalloy | ,(macroexpand-1 '(m 5)) |
| 18:54 | clojurebot | (clojure.core/fn [G__131 G__132 G__133 G__134 G__135] (clojure.core/+ G__131 G__132 G__133 G__134 ...)) |
| 18:55 | amalloy | note that `names` doesn't exist in there anywhere |
| 18:57 | PigDude | right |
| 18:59 | PigDude | amalloy: i was writing this macro earlier and having a tough time for some reason, i think it's because i was expanding with the wrong function |
| 19:00 | PigDude | ,(defmacro fnn [f n] (let [syms (repeatedly n gensym)] `(fn [~@syms] (~f ~@syms)))) |
| 19:00 | clojurebot | #'sandbox/fnn |
| 19:01 | PigDude | ,(defmacro fnn [f n] (let [syms (repeatedly n gensym)] `(fn [~@syms & _#] (~f ~@syms)))) |
| 19:01 | clojurebot | #'sandbox/fnn |
| 19:01 | PigDude | ,((fnn identity 1) 1 2 3) |
| 19:01 | clojurebot | 1 |
| 19:17 | amalloy | gross. (merge) and (merge-with f) return nil instead of {} |
| 19:20 | technomancy | amalloy: same thing |
| 19:20 | gfredericks | yeah name six circumstances where nil doesn't act like {} |
| 19:20 | gfredericks | you can't do it. |
| 19:20 | gfredericks | case closed. |
| 19:20 | amalloy | gfredericks: well, i took over a codebase where someone loved to write (m k) instead of (k m) |
| 19:20 | gfredericks | delete the codebase |
| 19:21 | amalloy | working on it |
| 19:21 | gfredericks | w00t clojure legacy code |
| 19:22 | amalloy | also, using map! (map some-map [:x :y :z]) |
| 19:22 | technomancy | ~gourds |
| 19:22 | clojurebot | SQUEEZE HIM! |
| 19:22 | gfredericks | amalloy: I think that's the same root cause |
| 19:22 | gfredericks | so you're still short five |
| 19:23 | amalloy | gfredericks: well, obviously. the main root cause is "calling it as a function" |
| 19:23 | gfredericks | yes |
| 19:23 | amalloy | but while (m k) is more or less indefensible, passing it as a function to something else is reasonable |
| 19:23 | gfredericks | ah ha okay |
| 19:23 | amalloy | but, okay, challenge accepted: (instance? Map nil) |
| 19:23 | gfredericks | I think (m k) is defensible actually |
| 19:23 | amalloy | gfredericks: not when k is a literal keyword |
| 19:24 | gfredericks | true dat |
| 19:24 | gfredericks | I think there are two primary map usages -- record-like and map-like |
| 19:24 | gfredericks | for record-like, use the keyword as a function; for map-like, use the map as a function, at least if you know it's a PHM; otherwise use get |
| 19:24 | gfredericks | anyhow you're up to 2 |
| 19:25 | amalloy | i usually use get anyway. you never know when some madman like technomancy or gfredericks will say "psh nil is just like a map" |
| 19:25 | gfredericks | you can't just find more superclasses of PHM either |
| 19:25 | gfredericks | nil is just like an empty string |
| 19:25 | amalloy | okay. passing it to java code |
| 19:25 | gfredericks | nil; it's just like <html></html> |
| 19:26 | gfredericks | clojurebot: nil is just like an empty picnic basket |
| 19:26 | clojurebot | c'est bon! |
| 19:26 | amalloy | and uh, (when opts (use-opts)), where opts is a map or nil |
| 19:26 | technomancy | amalloy: in general I hate sloppiness around nil semantics, but you can usually get away with it when it's a conflation between nil and a collection |
| 19:26 | technomancy | nillable scalar values are a bucket of hurt though |
| 19:27 | gfredericks | technomancy: that is an interesting distinction |
| 19:27 | amalloy | gfredericks: comparing for equality, hashing, using as a key in a map: those three just count as one, but they count |
| 19:27 | technomancy | gfredericks: well most collection stuff just calls get or seq on the arg anyway |
| 19:27 | amalloy | so i think i'm at 5 |
| 19:27 | technomancy | *the moral equivalent of get |
| 19:27 | gfredericks | guys I use C-t all the time |
| 19:27 | amalloy | oh, and calling conj/into |
| 19:28 | amalloy | gfredericks: i rebound C-t to transpose-sexps, because i'm a typing wizard who never transposes characters |
| 19:28 | gfredericks | only whole sexps |
| 19:28 | amalloy | well, i change my mind a lot |
| 19:28 | gfredericks | clojurebot: amalloy is a typing who wizard only sexps transposes |
| 19:28 | clojurebot | Ik begrijp |
| 19:29 | amalloy | clojurebot: gfredericks is a sexp wizard who only types transpositions |
| 19:29 | clojurebot | Ik begrijp |
| 19:29 | technomancy | I used to have C-t as my screen prefix |
| 19:30 | technomancy | so I was blind to the usefulness of character transpositions |
| 19:30 | technomancy | (dec so) |
| 19:30 | lazybot | ⇒ -27 |
| 19:32 | amalloy | i'm surprised there's anything with a score of -27 in lazybot's karma db |
| 19:32 | technomancy | decing so is a time-honored #clojure tradition |
| 19:33 | cbp | $karma bitemyapp |
| 19:33 | lazybot | bitemyapp has karma 16. |
| 19:33 | cbp | $karma callen |
| 19:33 | lazybot | callen has karma 15. |
| 19:35 | amalloy | so has the lowest karma score of anything |
| 19:35 | amalloy | java is in 4th with -4 |
| 19:36 | amalloy | actually, let's limit this to #clojure. java is *second* with a score of -4. javascript hot on its heels with -3 |
| 19:36 | technomancy | (dec javascript) |
| 19:36 | lazybot | ⇒ -4 |
| 19:37 | nullptr | $karma IE |
| 19:37 | lazybot | IE has karma 0. |
| 19:37 | amalloy | after that they start getting silly, with things like "n", "%2", and "also" |
| 19:37 | technomancy | lazybot: that's how you know this isn't a web-centric channel |
| 19:37 | amalloy | but i see clojuredocs has -1 |
| 19:37 | technomancy | err |
| 19:37 | technomancy | ^ nullptr |
| 19:38 | amalloy | lazybot: look at technomancy when he's speaking to you |
| 19:38 | nullptr | technomancy: true enough ... in our company's general dev chat IE has -162 ... still falls short of outlook's -430 (notice a theme?) |
| 19:38 | technomancy | abject despair? |
| 19:38 | amalloy | you guys like negative numbers? |
| 19:38 | nullptr | (inc technomancy) |
| 19:38 | lazybot | ⇒ 110 |
| 19:39 | xy86 | has anyone here used instaparse? |
| 19:39 | nullptr | as in all channels, negative karma is for technologies, positive karma is for people |
| 19:39 | cbp | also was a nick on this channel |
| 19:39 | cbp | like so |
| 19:39 | technomancy | maybe so is short for "also" |
| 19:40 | amalloy | ~anyone |
| 19:40 | clojurebot | Just a heads up, you're more likely to get some help if you ask the question you really want the answer to, instead of "does anyone ..." |
| 19:40 | gfredericks | xy86: we're using it at work |
| 19:41 | xy86 | gfredericks: i dont see anyhwere in the docs how to get line the line number from a node as the result of a parse |
| 19:42 | gfredericks | xy86: I actually don't know anything about it I just wanted everybody to know I was a hipster |
| 19:42 | gfredericks | the other guy on my team wrote the code :) |
| 19:48 | kwertii | I have a project where “lein uberjar” fails with “Compilation failed: Subprocess failed”. (“lein compile” seems to work fine.) Is there any way to make “lein uberjar” print more information on what exactly is failing? |
| 19:52 | technomancy | kwertii: try `lein with-profile uberjar compile` |
| 19:53 | kwertii | technomancy: “Warning: profile :uberjar not found.” |
| 19:54 | kwertii | other than that, no errors |
| 19:56 | technomancy | huh... try applying profile isolation; see the end of the faq |
| 20:04 | kwertii | OK, trying |
| 20:19 | AWizzArd | I am experiencing a strange error message. Perhaps someone saw it before. I have a (defrecord MNIST [label digit]). When I have a (def x (MNIST. 10 20)) I can do (.label ^MNIST x). Works fine. |
| 20:20 | AWizzArd | However, I have a vector data, and when I (doseq [element data] (.label ^MNIST element)) I get an error: test.MNIST cannot be cast to test.MNIST |
| 20:21 | Bronsa | AWizzArd: that probably means that you evaluated twice the defrecord |
| 20:21 | Bronsa | and you created the vector with those instances before re-evaluating the defrecord |
| 20:22 | AWizzArd | Bronsa: okay, that sounds good. I will restart my jvm, perhaps I indeed played with it. |
| 20:26 | AWizzArd | Bronsa: Yes, works. Thx! |
| 20:27 | AWizzArd | Bronsa: cause when I reloaded the file (in emacs, C-c C-k) it found again my defrecord. |
| 20:28 | AWizzArd | Is there some “defoncerecord”? |
| 20:28 | AWizzArd | I constantly reload my test file but did a defonce on my data file, as the import takes nearly 30 seconds. |
| 20:31 | AWizzArd | (when-not (ns-resolve *ns* 'MNIST) (defrecord MNIST [label digit])) |
| 20:33 | AWizzArd | Maybe the Clojure compiler could check when it sees a defrecord if such a record already exists. In such a case it won’t have to be replaced. |
| 20:33 | AWizzArd | If the fields didn’t change there would be no need to over-define the existing one. |
| 20:34 | AWizzArd | My when-not doesn’t work, it replaces the defrecord anyway. |
| 20:35 | johncash | records are object oriented poison |
| 20:36 | AWizzArd | Well, I was the guy who originally suggested them, in early 2009. |
| 20:36 | AWizzArd | They are a very nice addition and allow for good efficiency. |
| 20:37 | AWizzArd | I used defstruct but found that it was much slower compared to plain Java classes. |
| 20:37 | AWizzArd | Back then Rich hung out here every day and I asked if we could get a defclass. |
| 20:38 | AWizzArd | At first he didn’t like that, but a few months later he came up with a very cool idea: adding defrecord to Clojure. I thought that I heard about this idea before ;) |
| 20:39 | technomancy | imma join johncash in the corner |
| 20:40 | cbp` | u guys just dont like SPEEED |
| 20:40 | johncash | shooting yourself in the foot happens very fast |
| 20:40 | p_l | (optimize (debug 0) (speed 3) (safety 0) (size 0)) ; eh? |
| 20:40 | AWizzArd | p_l: did that too ;) |
| 20:41 | gfredericks | ,(defstruct foo bar) |
| 20:41 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: bar in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:41 | gfredericks | ,(defstruct foo [bar]) |
| 20:41 | clojurebot | #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: bar in this context, compiling:(NO_SOURCE_PATH:0:0)> |
| 20:41 | gfredericks | man it's been so long since I did a defstruct |
| 20:41 | AWizzArd | Indeed. |
| 20:42 | AWizzArd | Though I don’t see how defrecords have anything to do with oop. |
| 20:42 | amalloy | i happen to know that it's (defstruct foo :bar) |
| 20:42 | kwertii | technomancy: I tried profile isolation as described in the FAQ; “lein compile” now gives the same “Compilation failed: Subprocess failed” error as “lein uberjar”. Other than that, no change |
| 20:42 | AWizzArd | Hah, the long forgotten syntax :) |
| 20:43 | amalloy | because the code i'm working on, written in the distant past of 2013, has a defstruct |
| 20:43 | technomancy | kwertii: cool, you fixed your build =) |
| 20:43 | gfredericks | depends on what you think OOP is about |
| 20:43 | gfredericks | I was explaining defrecord to a teammate just two days ago and his reaction was "just like OOP!" |
| 20:44 | cbp | every currently recommended clojure book was written for 1.3 anyway |
| 20:44 | cbp | everyone knows defstruct when they first start |
| 20:44 | johncash | #<INSTANCEOFPERSON name: "foo" age: 42> vs {name: "foo", :age 42} |
| 20:44 | amalloy | cbp: huh? records were added, and structs deprecated, in 1.2 |
| 20:44 | cbp | oh |
| 20:45 | johncash | i think people closely associate polymorphism with OOP |
| 20:45 | cbp | I guess written for 1.2 with the 2nd edition in 1.3 and defstruct not removed :-P |
| 20:45 | gfredericks | I think the worst thing about OOP culture is encapsulated state, and defrecords don't have that |
| 20:47 | AWizzArd | Yes, they are just a data structure like you and me. |
| 20:47 | AWizzArd | Computer science is about using the right data structures and algorithms. |
| 20:47 | gfredericks | um |
| 20:47 | gfredericks | I don't think that's what records are obut |
| 20:47 | gfredericks | aboeutho |
| 20:47 | gfredericks | about |
| 20:47 | AWizzArd | They are a very lightweight data structure. |
| 20:47 | gfredericks | since datastructurewise they are effectively maps |
| 20:48 | AWizzArd | With very much less memory requirements and different lookup times. |
| 20:48 | gfredericks | yeah I guess there's a perf vs api distinction |
| 20:48 | jcromartie | I wish I could hit C-c C-k without an nREPL connection and automatically jack in |
| 20:49 | AWizzArd | What is again the syntax for the #: reader macro? |
| 20:49 | gfredericks | the what |
| 20:49 | kwertii | technomancy: er. I did? |
| 20:49 | amalloy | you just type #: and then the reader explodes |
| 20:49 | AWizzArd | Or what is the reader macro that allows to run code at read time? |
| 20:49 | gfredericks | ,#:kaboom! |
| 20:49 | clojurebot | #<RuntimeException java.lang.RuntimeException: Reader tag must be a symbol> |
| 20:49 | kwertii | jcromartie: C-c M-j does that |
| 20:50 | gfredericks | haha funny error |
| 20:50 | gfredericks | ,#&kaboom! |
| 20:50 | clojurebot | #<RuntimeException java.lang.RuntimeException: EOF while reading> |
| 20:50 | technomancy | kwertii: it was leaking state and giving you a false positive when it should have failed |
| 20:50 | gfredericks | wow that reader literal thing takes up a big swath of the # dispatch space |
| 20:50 | gfredericks | ,#&kaboom! :val |
| 20:50 | clojurebot | #<RuntimeException java.lang.RuntimeException: No reader function for tag &kaboom!> |
| 20:50 | cbp | jcromartie: im sure you can write an elisp function to do that? :-P |
| 20:50 | AWizzArd | Was it #& maybe? |
| 20:51 | gfredericks | #= |
| 20:51 | amalloy | AWizzArd: you're thinking of #=, which is a tool of the devil |
| 20:51 | AWizzArd | Ah yes, that was it. |
| 20:51 | AWizzArd | amalloy: guess who I am? |
| 20:51 | kwertii | technomancy: You mean “lein compile” should have always failed? |
| 20:51 | johncash | I have learned from Om that global application state is the only sane way to do state, however counter intuitive that may sound |
| 20:51 | jcromartie | kwertii: C-c M-j, then C-c C-k |
| 20:51 | kwertii | jcromartie: ah, I see |
| 20:52 | jcromartie | but I think C-c C-k should imply a cider-jack-in when there's no nREPL yet |
| 20:52 | johncash | coming from an era of "global variables the sky is falling" |
| 20:52 | kwertii | jcromartie: yes, that could be. seems straightforward enough to add |
| 20:53 | johncash | AWizzArd: A wizard? |
| 20:54 | cbp | johncash: as long as you're dealing with a single thread |
| 20:56 | johncash | ah good point |
| 20:56 | AWizzArd | johncash: btw, I am aware that wizard has only one ‘z’. |
| 20:56 | johncash | clojurescript is inheritly single threaded |
| 20:57 | johncash | AWizzArd: i was joking, you asked amalloy to guess who you were, and i respond "a wizard" |
| 20:58 | johncash | cbp: whats the best way to manage global app state with multiple threads? |
| 20:59 | cbp | Well |
| 20:59 | cbp | I don't know |
| 21:00 | AWizzArd | johncash: in Clojure one might be using refs for that. |
| 21:01 | cbp | My rethinkdb driver uses an agent as a frontend for a connection and it seems to work pretty well |
| 21:01 | amalloy | delete all the global app state. mischief managed |
| 21:02 | johncash | amalloy: so global app state is only a good idea in a single threaded environment? |
| 21:03 | johncash | AWizzArd: if you only have one ref as your global state, it seems to me there is no advantage of using STM since there is nothing to coordinate |
| 21:03 | AWizzArd | cbp: yes, and internally rethinkdb probably uses its own stm and fully persistant data structures. |
| 21:03 | AWizzArd | johncash: yes |
| 21:03 | amalloy | it's not a great idea then either. but i'm being overzealous on purpose: having some mutable state is acceptable, but if you have so much that you're having trouble managing it, the solution is usually to have less, not to get better management tools |
| 21:04 | AWizzArd | johncash: nope I meant :) |
| 21:04 | AWizzArd | johncash: if you want to read two times from your global ref that is fine. You can’t do this with an atom, as it might have changed between the two reads. |
| 21:04 | cbp | AWizzArd: sure, but as far as I've tested there are no race conditions with the sockets |
| 21:05 | johncash | amalloy: wouldn't it depend on the domain? Some application domains could be inherently very stateful |
| 21:06 | AWizzArd | johncash: let’s say you want to send money from one bank account to another. You first read from an account to see if it has a good balance. Then you withdraw a certain amount. But after reading the current balance and before doing this withdrawel someone else might have withdrawn all money in that account. |
| 21:07 | johncash | AWizzArd: doesn't that example assume two refs? one for each account balance? |
| 21:07 | amalloy | johncash: there's no such thing as inherently stateful |
| 21:08 | cbp | that example assumes a relational database |
| 21:08 | cbp | cus i don't want my money getting garbage collected no sir |
| 21:08 | AWizzArd | johncash: just one ref {:accounts {"amalloy" {:balance 17000000}}} |
| 21:08 | AWizzArd | johncash: but you access it possibly several times within one transaction. |
| 21:08 | johncash | AWizzArd: ah i get you now |
| 21:09 | johncash | amalloy_: is the _ suffix a convention for idleness? |
| 21:10 | dbasch | amalloy: well, real-time aircraft control is ridiculously stateful |
| 21:11 | p_l | more like it's not "functional" in the way people associate with the word these days |
| 21:11 | johncash | (inc dbasch) |
| 21:11 | lazybot | ⇒ 5 |
| 21:14 | amalloy | dbasch: sure, airplanes move around a lot in real life. but that doesn't mean that your program's model of airplanes has to be a big set of mutable Plane objects |
| 21:14 | amalloy | you model reality in a way that makes programming to achieve your goals easiest; statefulness isn't thrust upon you by a problem domain |
| 21:15 | dbasch | amalloy: true, but until now it has been impossible to model certain systems with mostly immutable state because of hardware constraints |
| 21:15 | AWizzArd | I for example work with big mutable arrays. |
| 21:15 | kwertii | technomancy: Is there anything else I can try to make “Compilation failed: Subprocess failed” tell me something useful? |
| 21:16 | AWizzArd | Everything else would be by far too slow. |
| 21:16 | dbasch | amalloy: for example, I used to be part of a team that crawled the web constantly and we could not afford to keep every old state of the web, not even the internet archive can |
| 21:17 | dbasch | we had to reuse storage space, delete old states |
| 21:17 | dbasch | the idea of databases with version control has been around forever but mostly impractical, and at some point people would laugh at anyone who’d consider it for a real-life project |
| 21:18 | dbasch | of course it’s awesome that now we can model things with less state because of better hardware and software |
| 21:20 | johncash | and non-naive immutable datastructures |
| 21:22 | kenrestivo | "databases with version control".... um, datomic? |
| 21:23 | kenrestivo | 1http://docs.datomic.com/clojure/#datomic.api/as-of |
| 21:23 | kenrestivo | ehrm, i meant http://docs.datomic.com/clojure/#datomic.api/as-of |
| 21:28 | arrubin | kenrestivo: Datamoic is not the first temporal database. |
| 21:28 | arrubin | And the technique is not new. |
| 21:28 | arrubin | Datomic rather. |
| 21:30 | arrubin | A common technique is to use a trigger to move the existing data to an archive table. |
| 21:59 | AWizzArd | Is there |
| 21:59 | AWizzArd | Is there (dotimes [i n] |
| 21:59 | AWizzArd | oops |
| 21:59 | AWizzArd | Is there an await for futures? |
| 22:03 | Jachy | AWizzArd: Just dereference the future. |
| 22:04 | AWizzArd | Jachy: ah okay, it still has the blocking behaviour. |
| 22:04 | AWizzArd | I thought this was removed at some point, but good then, thx. |
| 22:42 | sdegutis | Apparently (.delete tmp-file) does not delete the temp file. I found this out the hard way. |
| 22:49 | mgaare | anyone have a favored method of passing stateful dependencies like database connections to ring handlers? |
| 22:52 | dbasch | sdegutis: did it return true? |
| 22:52 | dbasch | mgaare: the easiest way is to use an atom |
| 22:56 | sdegutis | dbasch: never checked :) |
| 22:58 | dbasch | ,(.delete (java.io.File. "blah")) |
| 22:58 | clojurebot | #<SecurityException java.lang.SecurityException: denied> |
| 22:58 | dbasch | meh |
| 23:03 | mgaare | dbasch: yeah, I've tried that before, and some middlewares before |
| 23:04 | kwertii | technomancy: Found it. If a top-level form in clj being compiled throws an exception, ‘lein compile’ eats the exception and fails silently. |
| 23:09 | kwertii | technomancy: at least, that’s what happens in my real project. While trying to make a minimal example test case project, it *does* print the compile error. :/ |
| 23:26 | j0ni | anyone seen this error trying to require clojure.core.async? CompilerException java.lang.Exception: namespace 'clojure.core.async.impl.channels' not found, compiling:(clojure/core/async.clj:9:1) |
| 23:26 | j0ni | everything works fine in a toy project... |
| 23:34 | TimMc | I thought there was a lein task you could run that would give you a sort of lein task repl where you could enter things like "test foo.core" instead of running lein test foo.core |
| 23:35 | dbasch | j0ni: what do your deps look like? |
| 23:38 | j0ni | dbasch: clojure.set, com.stuartsierra.component, taoensso.timbre and 2 of my own namespaces |
| 23:38 | j0ni | eval-ing the ns form in cider gets me that error |
| 23:39 | dbasch | j0ni: I mean, is this a lein project and if so what does the :dependencies mapping look like |
| 23:40 | j0ni | oh |
| 23:40 | j0ni | https://gist.github.com/j0ni/b173f407fc30e41f05d3 |
| 23:40 | j0ni | dbasch: ^^ |
| 23:42 | j0ni | sorry, was private, just made it public |
| 23:56 | j0ni | hmm, it appears to be due to capacitor |
| 23:58 | dbasch | j0ni: yes, it has its own core.async |