#clojure log - Jun 04 2014

The Joy of Clojure
Main Clojure site
Google Group
List of all logged dates

0:33 ddellaco_: amalloy, right1, alandipert: I don't understand why folks think SQL is such a problem honestly

1:13 PhallicQ: sputnikus

1:13 What is your opinion on state sanctioned executions?

1:15 hellofunk: PhallicQ are you talking about federal laws for capital punishment? I think you are confusing this room with #closure

1:17 PhallicQ: I don'tknow of any room called #closure

1:17 hellofunk, but yes, I am talking about capital punishment

1:17 what is your opinion on the pracitce?

1:18 hellofunk: PhallicQ http://ejusa.org/learn/victims

1: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

1:20 is anyone familiar with any projects that do something similar and is that approach not completely foolish?

1:21 PhallicQ: hellofunk, let me see.

1:22 hellofunk, ah yeah

1:22 retributive justice.

1:23 A very American concept

1:23 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.

1:23 hellofunk: PhallicQ the closure you're looking for is not the clojure we're offering

1:24 PhallicQ: Like I said, I'm not looking of that

1:24 I know what this channel is about

1:24 New scheme without TCO, some-what better type system, worse macroes etc.

1:25 Well, the type system is weaker.

1:25 Persistent vectors are cool though

1:25 Funky data structure.

1: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?

1:59 amalloy: hellofunk: in the thread processing your web requests, *out* is typically not bound to whatever your repl is reading from

1:59 hellofunk: amalloy ah that probably explains it

2: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

2:00 hellofunk: how do i get the *out* redirected to the repl, if possible?

2:28 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.

3:57 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"})

3:58 pasted a typo. it is: (route/files "/login" {:root "./login.html"})

6:36 yotsov: came across this quite neat performance comparison of atoms, refs and similar: http://clojure.roboloco.net/?p=894

6:38 I am surprised that futures are roughly as expensive as refs. For me that makes them suitable only for very specific situations

6:39 Glenjamin: futures are 1:1 with threads iirc

6:39 so if you create loads, co-ordination overhead will dominate

6:40 yotsov: I see. but no transactional memory involved with futures, right?

6:40 Glenjamin: not as far as i know

6:40 yotsov: thanks

6:51 clgv: yotsov: might be due to the configuration of the threadpool for futures

6:52 yotsov: actually comparing performance of refs and futures is apples vs oranges

6: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

6:53 clgv: yotsov: what's the actual comparison over there you are refering to?

6:55 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"

6: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

6:55 yes I see

6:56 so it is the jvm threads overhead we see there

6:56 that's indeed irrelevant

6:56 clgv: although using criterium these benchmarks seem not well planned

6:59 the promise/deliver roundtrip does not make sense without some decent workload.

6:59 whodidthis: n

7:00 clgv: yotsov: and why is "3 futures" only done with atoms and not with refs as comparisons - that would actually make sense ;)

7: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

7:09 clgv: yotsov: no they dont. they are implemented on top of javas threadpoolexecutors

7:09 yotsov: clgv: yep makes sense now, thanks

7:09 clgv: $source future-call

7:09 lazybot: future-call is http://is.gd/BkUPBd

7:10 visof: hi

7:11 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"

7:11 "clojure_is_nice"

7:12 clgv: visof: split on upper caser letter a join with the wanted delimiter

7:12 visof: ,(clojure.string/split "HelloWorld" #"[A-Z]")

7:13 clojurebot: eval service is offline

7:13 visof: clgv: that's will drop H and W

7:14 clgv: visof: yeah just noticed that

7:16 ,(require '[clojure.string :as str])

7:16 ,(str/join "-" (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNice"))

7:16 clojurebot: eval service is offline

7:16 clgv: clojurebot: why?

7:16 clojurebot: eval service is offline

7:16 clgv: :/

7:16 &(require '[clojure.string :as str])

7:16 lazybot: ⇒ nil

7:17 clgv: &(str/join "-" (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNice"))

7:17 lazybot: ⇒ "Clojure-Is-Nice"

7:18 clgv: visof: like that ^^ you just need to lowercase the words to fullfil your full spe

7:18 &(str/join "-" (map str/lower-case (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNice")))

7:18 lazybot: ⇒ "clojure-is-nice"

7:19 visof: &(str/join "-" (map str/lower-case (re-seq #"\p{Upper}\p{Lower}*" "ClojureIsNiceClgvIsGreat")))

7:19 lazybot: ⇒ "clojure-is-nice-clgv-is-great"

7:19 clgv: thx :P

8:02 ambrosebs: can I connect my REPL to a lazybot?

8:05 nvm just learnt about reloading.

8:07 visof: clgv: ping

8:07 &(str/join "-" (map str/lower-case (re-seq #"\p{Upper}\p{Lower}*" "clojureIsNice")))

8:07 lazybot: ⇒ "is-nice"

8:08 clgv: visof: is that an error with repsect to your requirements?

8:08 visof: i need to get clojure too

8:10 clgv: &(str/join "-" (map str/lower-case (re-seq #"\p{Alpha}\p{Lower}*" "clojureIsNice")))

8:10 lazybot: ⇒ "clojure-is-nice"

8:10 clgv: visof: http://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

8:16 ambrosebs: ,*clojure-version*

8:17 &*clojure-version*

8:17 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil}

8:17 clojurebot: eval service is offline

8:17 ambrosebs: hmm I'll assume lazybot is stuck at 1.4.0 :(

8:24 clgv: ambrosebs: hit raynes ;)

8:24 until he changes it ^^

8:25 ambrosebs: Raynes: trying to get core.typed on lazybot again. Is it feasible to upgrade to clojure 1.5.1?

8:31 oh cool, wasn't as hard as I thought.

8:31 there was a tools.reader conflict with core.typed that I misinterpreted as a clojure.core version thing

8:32 clgv: ambrosebs: on to 1.6.0 then? ;)

8:32 ambrosebs: doesn't exist for me yet ;)

8:32 waiting for CLJS

8:32 clgv: what has that to do with cljs?

8:33 ambrosebs: my clojure world is core.typed which depends on cljs

8:33 I'm also the only person who tried to AOT compile cljs

8:33 *tries

8:33 and that doesn't work with 1.6.0

8:34 clgv: ambrosebs: because of the tools.analyzer your world depends on cljs

8:34 ?

8:34 ambrosebs: no core.typed checks cljs code too

8:35 not very well yet, but the dependency is there.

8:42 rurumate: ,(into #{} nil)

8:43 clojurebot: eval service is offline

8:43 rurumate: oh noes

8:43 I wanted to point out that, at least in clojure 1.5.1, (into #{} nil) = #{}

8:43 and (into #{} nil nil) = exception

8:44 whereas #{nil} != #{}

8:44 llasram: &(into #{} [] [])

8:44 lazybot: clojure.lang.ArityException: Wrong number of args (3) passed to: core$into

8:44 llasram: rurumate: Thus isn't that expected?

8:44 both of `into`s arguments are collections

8:44 and it takes only two

8:45 rurumate: oh,

8:45 right, into takes collection

8:46 I meant (into #{} [nil])

8:46 anyway

8:47 it's a hot day, brainrot sets in

8:47 Glenjamin: &(into #{} [nil])

8:47 lazybot: ⇒ #{nil}

8:47 Glenjamin: &(into #{} nil)

8:48 lazybot: ⇒ #{}

8:48 Glenjamin: seems right

8:48 rurumate: so lazybot took clojurebots job away?

8:48 Glenjamin: oh, someone already did that

8:48 they're usually both up

8:48 clgv: ,(println "back again")

8:48 hm no, seems not like it

8:48 clojurebot: eval service is offline

8:48 rurumate: stuck in a loop, clojurebot?

8:49 clgv: rurumate: he got timeouts for that ;)

8:50 rurumate: &(into {} [nil [1 2] nil]

8:50 lazybot: java.lang.RuntimeException: EOF while reading, starting at line 1

8:50 rurumate: (into {} [nil [1 2] nil])

8:50 &(into {} [nil [1 2] nil])

8:50 lazybot: ⇒ {1 2}

8:51 rurumate: maps are special

8:51 clgv: rurumate: well what should be done with nil?

8:51 &(into {} [[nil nil] [1 2]])

8:51 lazybot: ⇒ {nil nil, 1 2}

8:51 rurumate: it's understood, map conj takes 2-vec or nil

8:52 clgv: you need at least key value pairs

8:52 rurumate: it just takes a bit of getting used to

8:52 &(conj {} nil)

8:52 lazybot: ⇒ {}

8:52 clgv: &(into {} [{:a 1 :b 2} {:a 42 :c 3}])

8:52 lazybot: ⇒ {:a 42, :b 2, :c 3}

8:53 rurumate: &(into {} (remove nil? [nil [1 2] nil [3 4]]))

8:53 lazybot: ⇒ {1 2, 3 4}

8:54 rurumate: the remove is not needed, is what I used to do

8:56 Glenjamin: &(conj {} nil)

8:56 lazybot: ⇒ {}

8:56 Glenjamin: that's what into does under the hood

9: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

9: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

9:40 rurumate: oh, thanks clgv I had not known about keep

9:41 martinklepsch: martin_, looked into enlive?

9:41 martin_, what do you want to achieve?

9:44 martin_: martinklepsch: to transform a xml datastructure (e.g. merge attributes) into something that can be rendered as json

9:45 martinklepsch: manually selecting the elements from the XML or in general for various different xml snippets?

9: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

9:55 martinklepsch: martin_ I've been working with XML a lot recently and that zipper structure is pretty clever actualyl

9:56 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 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 merged with attrs means: {:more-test "abc" :test "xyz" :content "ovw"} ?

10:03 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 s/once/wants/

10:14 lvh: well, I'd like to do some network simulation

10:14 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 +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 "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 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 https://clojars.org/timelike

10:20 clgv: lvh: even better :D

10:20 lvh: unfortunately it's [timelike "0.1.0-SNAPSHOT"]

10:21 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 clgv: I'm suggesting there's lots of commits that have that version in project.clj

10:22 so I don't actually know that the thing on clojars is the thing that's currently git master, right?

10:22 (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 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 I also have tests setup to run after every save

10:42 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 but for me, its probably nto worth the cost

10:43 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 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 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 stompyj: Thanks! Lots of cool things coming too.

10:46 stompyj: IntelliJ is probably a good fit for that language mix, too.

10:46 stompyj: Thats my goal

10:46 Getting back to a “Real IDE"

10:46 and IntelliJ seems pretty great

10:47 cfleming: Unfortunately IdeaVim has some rough edges with Cursive (and other language consoles)

10:47 Yeah, IntelliJ is amazing.

10:47 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 What IdeaVim?

10:48 cfleming: The Vim bindings for IntelliJ

10:48 stompyj: Ahhh ok

10:48 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 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 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 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 tsmarsh: if your protocol isn't pure, then you're just being silly

10:56 (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 tsmarsh: oo isn't somehow not functional so long as it's pure and the methods can be taken as values...

11:01 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 or (quote #_foo)

12:05 philandstuff: well #_ is a reader macro that discards the next form

12:05 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 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 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 (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 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 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 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 *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 (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 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 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 you mean with t.a.js?

12:48 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 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 ~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 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 of course!

12:59 hangs the tests too

13:00 my test suite has stopped reportnig errors

13:00 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 also it is bad because it walks all the keys of all the maps twice

13:09 arrdem: Bronsa: works for me

13:09 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 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 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 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 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 PigDude: that way the exception can tell you which test spawned the thread that timed out and threw an exception

13:19 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 how should the test runner no a-priori how long a test has to run?

13:20 *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 and then hangs while not showing a known exception

13:20 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 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 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 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 would need another thread checking results of the worker threads?

13:53 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 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 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 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 which may be folly, finding out now

13:56 faustroll: I'm fiddling with logging

13:57 I like the thinking behind clj-logging-config

13:57 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 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 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 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 (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 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 ambrosebs: lol @ swift static types

14:06 llasram: I use it with slf4j+log4j and a ~5 line property file

14:06 No XML in site

14:06 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 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 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 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 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 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 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 to me the fact that zero args becomes an error is a bonus

14:33 PigDude: hm that's a good point

14:33 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 (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 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 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 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 ugh, and having to write (quote x) instead of 'x

14:52 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 arrdem: yeah, but I have never seen a #( contain a fn

14:54 amalloy: ticking: what

14:54 that happens all the time

14:54 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 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 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 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 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 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 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 but that's not at all what python is now

15:06 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 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 * arrdem rolls his eyes

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 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 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 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 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 s/intermiary/intermediary

15:21 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 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 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 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 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 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 '(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 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 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 * arrdem digs out clojure.lang.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 interop is the easy way out

15:55 Glenjamin: isn't that what codex does?

15:56 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 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 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 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 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 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 but you can't really test it in an automated way

16:10 bbloom: amalloy: you probably could with eclj

16:10 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 it's really holding back cider.

16:19 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 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 so... shrug

16:25 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 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 i did something similar.

16:27 i don't even remember.

16:27 :-) 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 I didn't try multiple JVMs

16:28 gfredericks: I would expect a behavior that throws an error if constraints can't be met, at least a warning.

16:28 with the conflicting constraints.

16:28 gfredericks: gtrak: I didn't think my constraints were even conflicting

16:28 gtrak: mine either.

16:28 it made no sense.

16:29 but the result was totally wrong.

16:29 or at least it didn't match my understanding

16:29 _something_ was wrong.

16:30 gfredericks: fo sho

16:30 I wasn't able to wrap my head around the code so far

16:30 I was hoping that given two middlewares the info would boil down to a partial order

16:31 can't tell looking at the code if that's the case

16:31 gtrak: me neither, I might try reimplementing it.

16:31 like I said, on the order of a couple days' work.

16:31 hopefully before we have to push a cider release.

16:33 it seems like these tooling projects have lots of good ideas that are half-finished :-)

16:33 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 which is why I had to realize that pain for myself.

16:34 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 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 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 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 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 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 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 dbasch, true, and those are the hardest, IMO.

17:18 zoldar: dbasch: yeah, there's even an (optional) code golf contest

17:20 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 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 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 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 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 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 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 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 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 No no no, not a unix process, just a task.

18:41 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 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 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 amalloy: well v# works fine when you know ahead of time how many you have

18:51 amalloy: but if i generate this list of symbols, then i want to do (map gensym (somthing))

18:51 and use it around the function

18:52 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 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 , (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 ,(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 amalloy: of course!

18:54 amalloy: PigDude: no, if you saw them in macroexpand, they were in the emitted source

18:54 presumably because you let them inside of the syntax-quote, instead of outside it

18:54 ,(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 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 ,(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 you can't do it.

19:20 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 * tcrayford_ is currently deep in Compiler.java

19:22 technomancy: ~gourds

19:22 clojurebot: SQUEEZE HIM!

19:22 gfredericks: amalloy: I think that's the same root cause

19:22 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 I think there are two primary map usages -- record-like and map-like

19:24 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 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 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 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 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 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 so I was blind to the usefulness of character transpositions

19:30 (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 java is in 4th with -4

19:36 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 ^ 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 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 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 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 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 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 Bronsa: Yes, works. Thx!

20:27 Bronsa: cause when I reloaded the file (in emacs, C-c C-k) it found again my defrecord.

20:28 Is there some “defoncerecord”?

20:28 I constantly reload my test file but did a defonce on my data file, as the import takes nearly 30 seconds.

20:31 (when-not (ns-resolve *ns* 'MNIST) (defrecord MNIST [label digit]))

20:33 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 If the fields didn’t change there would be no need to over-define the existing one.

20:34 My when-not doesn’t work, it replaces the defrecord anyway.

20:35 johncash: records are object oriented poison

20:35 * johncash goes back to his corner

20:36 AWizzArd: Well, I was the guy who originally suggested them, in early 2009.

20:36 They are a very nice addition and allow for good efficiency.

20:37 I used defstruct but found that it was much slower compared to plain Java classes.

20:37 Back then Rich hung out here every day and I asked if we could get a defclass.

20:38 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:40 * p_l had some memorable bugs with assignments to literals

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 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 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 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 Computer science is about using the right data structures and algorithms.

20:47 gfredericks: um

20:47 I don't think that's what records are obut

20:47 aboeutho

20:47 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 ,#&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 ,#&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 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 AWizzArd: i was joking, you asked amalloy to guess who you were, and i respond "a wizard"

20:58 cbp: whats the best way to manage global app state with multiple threads?

20:59 cbp: Well

20:59 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 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 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 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 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 johncash: but you access it possibly several times within one transaction.

21:08 johncash: AWizzArd: ah i get you now

21:09 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 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 we had to reuse storage space, delete old states

21:17 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 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 1http://docs.datomic.com/clojure/#datomic.api/as-of

21:23 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 And the technique is not new.

21:28 Datomic rather.

21:30 A common technique is to use a trigger to move the existing data to an archive table.

21:59 AWizzArd: Is there

21:59 Is there (dotimes [i n]

21:59 oops

21:59 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 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 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 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 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 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 https://gist.github.com/j0ni/b173f407fc30e41f05d3

23:40 dbasch: ^^

23:42 sorry, was private, just made it public

23:56 hmm, it appears to be due to capacitor

23:58 dbasch: j0ni: yes, it has its own core.async

Logging service provided by n01se.net