#clojure log - Mar 26 2015

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

1:46 wefwef: attempting to run lein repl results in the following: Could not transfer artifact org.clojure:tools.nrepl:pom:0.2.6 from/to central (https://repo1.maven.org/maven2/): java.lang.RuntimeException: Unexpect

1:46 ed error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty

1:47 on OpenJDK Runtime Environment (build 1.8.0_31-b13)


1:49 not currently behind proxy, any jvm type settings to check?

2:19 Kneiva: wefwef: http://stackoverflow.com/questions/4764611/java-security-invalidalgorithmparameterexception-the-trustanchors-parameter-mus ?

2:21 wefwef: here's one with openJDK http://architecturalatrocities.com/post/19073788679/fixing-the-trustanchors-problem-when-running

3:24 hamid: hello there :) Would anyone help me solve this one? :P http://clojurescriptkoans.com/#destructuring/7

3:26 kungi: hamid: yes I would. I always have a look at this tutorial when I'm not sure about destructuring: http://blog.jayfields.com/2010/07/clojure-destructuring.html

3:27 hamid: ka2u, awesome thanks.

4:55 sveri: "Working on siwf in clojure and clojurescript" just went live!, check it out here: http://www.twitch.tv/sveri80

6:03 ane: wtf watching people code is now a thing?

6:03 the_frey: it is?

6:04 justin_smith: evidently, but hey if people want to watch, why not

6:11 clgv: half-pair-programming? :P

6:12 ane: did you spot plenty of videos being uploaded?

6:18 justin_smith: clgv: sveri just posted a link

6:23 clgv: justin_smith: too early for me ;)

6:29 elvis4526: Where are static files served when running lein run with http-kit ?

6:30 justin_smith: elvis4526: whereever you tell ring to look for them (via wrap-static)

6:30 elvis4526: though generally wrap-resources is better, because it allows serving files from inside an unexploded jar

6:30 elvis4526: I use compojure

6:31 justin_smith: that doesn't change things

6:31 compojure uses ring

6:31 ring uses the wrap-static or wrap-resources middleware

6:31 elvis4526: sorry i didn't finish what I wanted to say lol

6:31 I did (files "/public") in my routes

6:31 this is relative to where when running lein run ?

6:32 justin_smith: I've never used that "files" thing, I've always used wrap-resources or wrap-static, and those are relative to the classpath

6:33 elvis4526: classpath = where you're clj file are ?

6:33 when deploying into a jar, /public really refer at the root of the jar

6:33 (if this is any help)

6:33 justin_smith: really? that seems like a terrible idea

6:34 classpath is the set of places where the jvm looks for resources at runtime

6:34 elvis4526: where does static file should live ?

6:34 justin_smith: the primary job for lein is to set up your classpath

6:35 they can be whereever is convenient, but I typically put them is resources/ and then use wrap-resources to point to the folder they are in

6:35 eg if I put them in resources/public/ then I use (wrap-resources "public")

6:35 elvis4526: so there are available at localhost/public/blabla.js ?

6:35 justin_smith: right

6:35 elvis4526: that's what I did

6:55 justin_smith: elvis4526: actually, I take that back - if you do (wrap-resources "public") and had the file resources/public/bla.js, you would access it as "localhost/bla.js"

6:59 sveri: ane clgv justin_smith I tried that a few times now and, the funny thing is, it really helps me concentrate and not get distracted (coding for private things always suffer my procrastination wishes), it's an interesting concept and, at the same time, you can get people attracted to clojure :-)

7:12 justin_smith: heh, it was interesting to see intellij in action

7:13 sveri: I was never able ti get productive with emacs, tried it three times for severl hours, but...

7:23 laurio: justin_smith: wow, didn't know that

7:25 i started to use cond instead in order to avoid hard coding values more than once

7:26 elvis45261: Is there a way to speed up lein run ?

7:26 it's crazy slow.

7:27 justin_smith: elvis45261: https://github.com/technomancy/leiningen/wiki/Faster


7:28 elvis45261: that's what I was about to ask

7:28 it seems the only "okay" solution

7:28 justin_smith: another trick is to not use lein at all

7:29 lein cp > "class_path.txt"; java -cp $(cat class_path.txt) clojure.main -m your.ns

7:30 but that's only going to be marginally faster than LEIN_FAST_TRAMPOLINE - remember that that only works when you do "lein trampoline run" - "lein run" is not affected by the LEIN_FAST_TRAMPOLINE setting at all

7:39 agarman: I tried nailgun before, but it becomes convoluted as soon as you have multiple projects or change dependencies or etc.

7:40 borkdude: ordnungswidrig I'm unsure how to combine existing? and put! or post! I want to enfore that someone can only put! or post! when :exists? is true. but when I set put-to-existing? to true, a normal get responds with a 201..

7:51 zoldar: borkdude: you hardcode put-to-existing? to true?

7:53 borkdude: never mind, it seems to be a glitch because of code reloading in the repl

7:54 zoldar: borkdude: ok

7:54 borkdude: I suppose that you are aware of this: http://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg

7:54 borkdude: zoldar yes

7:55 zoldar: just making sure

9:09 borkdude: ordnungswidrig I'm still not sure how I must do this with liberator: someone puts!, but if the thing doesn't exist? it should return a 404

9:10 ordnungswidrig I have implemented :exists? and set :can-put-to-missing? to false, but that doesn't work

9:10 justin_smith: borkdude: I thought the idea with PUT is that it creates a resource where there wasn't one previously

9:10 borkdude: justin_smith I thought that was post

9:11 justin_smith maybe I'm wrong

9:11 justin_smith: borkdude: the relevant rfc http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

9:12 "The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line."

9:12 "The PUT method requests that the enclosed entity be stored under the supplied Request-URI."

9:17 borkdude: so maybe you don't want PUT requests at all, and actually want only POST to be allowed?

9:18 borkdude: justin_smith in plain english: I want to store an attribute/column in an existing record. which should I use then?

9:18 justin_smith: post

9:18 put is for making new records

9:18 post is for adding details to something that is already there

9:19 borkdude: ok

9:20 justin_smith: like, if this were eg. reddit, "put" would be for creating a new link, and "post" would be for adding a comment to that link

9:20 borkdude: justin_smith so put for a new "top level" thing

9:20 justin_smith: yeah

9:21 sveri: borkdude: idempotent is the word you are looking for here, if your operation adds something and is idempotent, make it a PUT. Otherwise make it a POST

9:21 justin_smith: sveri: it's not just that though. He wants a 404 for a non-existing URL, which is something POST would do, but not PUT

9:22 PUT would just create the new thing

9:22 (if PUT is accepted at the route targeted, of course)

9:22 sveri: justin_smith: ok, sry, I joined to late I guess and misunderstood the question

9:24 borkdude: for sake of understanding, it's this resource I'm talking about: https://www.refheap.com/98907

9:24 I would expect a POST to listen to existing?, but that's not what's happening

9:26 sveri: borkdude: "listen to existing?" what do you mean exactly?

9:28 borkdude: ehm, I mean: it will return a 404 when exists? is nil or false

9:29 sveri: hm, just shooting blindly here, what does (if-let return? maybe try an if statement instead of if-let?

9:29 justin_smith: sveri: if-let returns the same as if would

9:29 borkdude: (if-let [a nil] a) is nil

9:29 sveri: kk

9:29 justin_smith: it just adds a convenient let binding

9:30 borkdude: and I assume you have verified that answers/read-by-invitation isn't returning ()

9:30 since () is truthy of course

9:30 borkdude: ah, I should set can-post-to-missing? to false

9:31 https://www.dropbox.com/s/0inkfr1wwsqqpm2/Screenshot%202015-03-26%2014.30.00.png?dl=0

9:31 justin_smith: that sounds applicable. I've been meaning to try liberator.

9:31 borkdude: thanks for thinking along guys

9:32 justin_smith: so that fixed it?

9:32 sveri: yea, that looks nice

9:32 borkdude: do you handle authentication / authorization with liberator?

9:32 borkdude: sveri authentication no, authorization yes

9:33 sveri: is your code publicy available? I'd like to have a look at it

9:33 borkdude: sveri I'm using lib-noir for authentication

9:34 sveri but I wouldn't go there anymore, since it's deprecated by luminus

9:34 sveri: hm, I see

9:34 borkdude: sveri just look at the luminus website how to do authentication and then use :authorized? (fn [ctx] .... (-> ctx :request :session ...)) etc to authorize whatever you like

9:35 sveri: Ok, so no fancy wrapper / abstraction stuff like friend

9:35 borkdude: sveri no. I tried friend, but I never got the hang of it

9:36 sveri: I dropped friend in favor of buddy, which seems pointless after I finally grasped friend :D

9:36 borkdude: sveri buddy is also used in luminus

9:36 sveri I kind of fall back on luminus for standard web stuff, so my colleagues can look at that if they have to work on my project in the future. nice references

9:37 sveri: Yea, he really put a lot of effort into the documentation. I used it as a reference for my own template

9:53 dxlr8r: hello. small question. how do I join/concat regex patterns?

9:53 clgv: dxlr8r: you dont.

9:53 dxlr8r: I have a usecase where I need it to not repeat myself

9:53 clgv: dxlr8r: you can concat strings to a single string and convert that to a regex

9:54 dxlr8r: hmmm

9:54 dstockton: use re-pattern and combine the patterns as strings

9:54 justin_smith: dxlr8r: ##(re-seq (re-pattern (str #"a" #".")) "bananananana")

9:54 lazybot: ⇒ ("an" "an" "an" "an" "an")

9:54 clgv: maybe you can get the string representation back from the regex

9:54 justin_smith: clgv: yup

9:54 and then create a new regex from that

9:55 dxlr8r: justin_smith: thx :)

9:55 will use re-pattern. how could I overlook that? :)

9:57 catern: dear #clojure

9:57 is there a way I can easily get my incanter data into my LaTeX document?

9:58 like, for R there is something (I think) where you can just put R variables or something into your LaTeX, and they will get filled in at pdflatex time

9:58 is there anything clever I could do to get that for Incanter...?

9:59 dxlr8r: justin_smith: I get "unsupported escape character" when I try to store my regex

9:59 \d that is

9:59 need to use \\ :/ stupid :P

10:00 justin_smith: dxlr8r: or you can do what I did above (str #"\d" #"whatever")

10:00 #"" requires less escaping

10:00 dxlr8r: hmmm

10:02 nice :) thanks for having patient with a total clojure idiot... come to think of it, not that good on programming in general :)

10:08 clgv: catern: sure 3-4 lines of clojure get that done

10:08 catern: clgv: er, how?

10:08 clgv: catern: just write out the columns then iterate over the rows

10:08 catern: what

10:09 think you're answering someone else's question :)

10:09 clgv: (str/join " & " column-values) will do the table stuff for altex

10:09 catern: nope yours

10:09 catern: I don't want to do table stuff

10:09 I have no tables, just single values

10:10 clgv: catern: what is "incanter data"? just values?

10:10 catern: yes

10:10 I mean

10:10 clgv: well just copy them over then

10:10 catern: I have table data as well

10:10 clgv: :/

10:10 uh

10:10 no?

10:10 clojurebot: no is tufflax: there was a question somewhere in there, the answer

10:11 justin_smith: clojurebot: you're weird.

10:11 clojurebot: excusez-moi

10:11 catern: clgv: i'd rather not?

10:11 clgv: catern: I guess I dont understand what your problem is.

10:11 catern: nevermind

10:11 clgv: have you ever used R and LaTeX together?

10:12 clgv: you found out that your p-value is 0.031 and want to have that in latex - then just copy the 0.031 over there.

10:12 ticking: lol

10:12 catern: clgv: I want that value to update when I re-run the analysis

10:12 which you can do with R and LaTeX, http://en.wikipedia.org/wiki/Sweave

10:12 clgv: catern: well then you maybe want some kind of templating

10:12 ticking: catern: an you want it in what context?

10:12 catern: clgv: yes, agreed

10:15 clgv: catern: the sweave approach looks frightening

10:15 ticking: catern: sorry I mist most of the discussion what is the tool you want to use? gorilla repl, clojure ipython? plain html?

10:15 clgv: how do you plan to submit latex sources to a journal?

10:15 catern: clgv: I plan to make a PDF?

10:15 clgv: catern: I guess having a latex file with place holders for the computed values, is probably the best approahc

10:16 catern: clgv: are you telling me to copy them in again?

10:16 clgv: catern: journals almost always want your latex ;)

10:16 catern: again, would rather not copy this stuff in manually

10:16 clgv: catern: no. your program can readin the latex file and fill in the values automatically

10:16 catern: so templating

10:16 yes

10:16 clgv: so you use the latex file as template

10:16 catern: suggestions?

10:17 clgv: catern: we have used selmer for html templating

10:17 should work with latex as well

10:17 ticking: http://www.tetrisrockstar.com/dynamic-latex-documents-with-clojure-and-fleet/

10:18 catern: ticking: thank you but I have already googled and seen that

10:18 ticking: catern: k

10:18 clgv: ticking: interesting

10:19 catern: looking at fleet, I'd stick with selmer for your requirements

10:34 irctc__: Can someone point me in the right direction? I'd like to idiomatically turn a sequence of hash-maps with keys :a :b :c to a new sequence of hash-maps with only keys :a and :c

10:34 so ({:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}) becomes ({:a 1 :c 3}{:a 4 :c 6})

10:35 tatut: (map #(dissoc % :b) coll)

10:35 justin_smith: &(map (partial select-keys [:a :c]) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}])

10:35 lazybot: ⇒ ({} {})

10:35 Bronsa: ,(map (partial dissoc :b) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}])

10:35 clojurebot: #<ClassCastException java.lang.ClassCastException: clojure.lang.Keyword cannot be cast to clojure.lang.IPersistentMap>

10:35 irctc__: ahh dissoc

10:35 Bronsa: ,(map #(dissoc % :b) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}])

10:35 clojurebot: ({:a 1, :c 3} {:a 4, :c 6})

10:35 justin_smith: &(map #(select-keys % [:a :c]) [{:a 1 :b 2 :c 3}{:a 4 :b 5 :c 6}])

10:35 lazybot: ⇒ ({:c 3, :a 1} {:c 6, :a 4})

10:35 irctc__: without looking it up, can it handle multiple keys to dissoc at the same time?

10:35 Glenjamin: (doc select keys)

10:35 clojurebot: #error{:cause "Wrong number of args (2) passed to: core/eval54/fn--55/my-doc--56", :via [{:type clojure.lang.ArityException, :message "Wrong number of args (2) passed to: core/eval54/fn--55/my-doc--56", :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 6628]}], :trace [[clojure.lang.Compiler macroexpand1 "Compiler.java" 6628] [clojure.lang.Compiler macroexpand "Compiler.java" 6694] [clojure.lang.Compiler eval "Compiler.java" 676

10:35 clgv: irctc__: or select-keys depending on the exact use case ;)

10:35 irctc__: aah

10:36 Bronsa: irctc__ yes

10:36 justin_smith: irctc__: dissoc is varargs, but select-keys is closer to what you want I think

10:36 irctc__: thanks all! select-keys/dissoc

10:36 Glenjamin: hrm, no response to my doc request :(

10:36 justin_smith: Glenjamin: you had a typo

10:36 Glenjamin: oh

10:36 haha

10:36 that stack trace makes sense now

10:47 clgv: oh clojurebot changed to string-serializable exceptions?

10:47 stuartsierra: No, Clojure did!

10:47 dysfun: why can't i (defn [f & fs :as all-fs] all-fs) ?

10:47 clgv: ,(clojure-version)

10:47 clojurebot: "1.7.0-master-SNAPSHOT"

10:47 clgv: stuartsierra: for real? is there some blog post or similar about that?

10:48 stuartsierra: is it just a printmethod impementation?

10:48 patrickgombert: clgv: https://github.com/clojure/clojure/commit/692645c73c86d12c93a97c858dc6e8b0f4280a0b

10:48 stuartsierra: dysfun: Because function arity is not the same thing as destructuring, although they share the same syntax.

10:49 clgv: patrickgombert: thanks

10:49 dysfun: okay. is there something cleaner than do what i've done and just use a let underneath and a precondition to assert length is pos?

10:50 patrickgombert: clgv: it’s a nice change, really useful for quickly scanning

10:51 clgv: hopefully nil-safe ;)

10:52 uhh there is a (set! *warn-on-reflection* true) i it... :P

10:53 justin_smith: dysfun: how about (defn [& [f & fs :as all-fs]] all-fs)

10:53 dysfun: ewww :)

10:54 justin_smith: it does what you want though

10:54 dysfun: yeah, not denying it :)

10:54 still need the precondition

10:55 obviously i could write a macro,

10:56 clgv: a (set! *warn-on-reflection* true) in core_print.clj is going to be fun ;)

10:59 catern: hmmm

10:59 clgv: Actually I asked in #latex and have a somewhat better idea

10:59 you can generate them in the form \def\foo{val} from within the clojure (or whatever else you use) script and then \input{|"script"}

11:00 (where "script" is something that outputs \def\foo{val} on stdout)

11:00 and \input includes that into the document

11:00 clgv: catern: yeah, pretty similar approach but limiting the document generation to the external file

11:01 catern: clgv: to the external file?

11:01 it seems like a really good approach - at first I was hesistant because I'd need to define all my variables that I wanted to include in advance

11:01 clgv: you do not include an external file ?

11:02 catern: clgv: oh, no no, \input{|"script"} executes script and includes its stdout into the document

11:02 clgv: you want to actually run a clojure program from the \input statement?

11:02 catern: very unixy :)

11:02 clgv: definitely!

11:02 some lein task, probably

11:03 clgv: haha, your editing will suck due to the much longer latex compilation duration ;)

11:03 catern: clojure startup times :(

11:03 the worst thing about clojure

11:04 clgv: better use \include{constants.tex} and generate that file via a manual call to your clojure program

11:04 justin_smith: catern: what about if "script" was "curl localhost/clojure-server/get-data"

11:04 then you don't have to wait for startup

11:04 clgv: justin_smith: woah, complexity is exploding! :P

11:04 catern: justin_smith: hey, that's smart and also a TERRIBLE HACK

11:04 but I like it

11:04 justin_smith: hehe

11:05 grench is similar

11:05 but maybe less hackish

11:05 you just have one clojure process running, and use grench to get a result from it

11:05 clgv: catern: whats wrong with generating the "constants.tex" - it's like the suggested apporach from #latex but without the high costs of running the clojure program on every latex compilation

11:06 catern: clgv: that's good too I suppose

11:06 I actually like justin_smith's suggestion

11:06 clgv: tikz has a similar approach by using "externalization" as they call it

11:06 catern: I mean all of these are small layers around the central functionality of generating some LaTeX

11:06 maybe I will write a library to generate LaTeX from Clojure values

11:07 justin_smith: catern: you could call it 'org mode'

11:07 catern: justin_smith: :)

11:07 justin_smith: hey, not really though

11:07 justin_smith: I know

11:07 clgv: catern: with the implementation of (format "\def\%s{%s}" (sanitize name) (value)) ? ;)

11:08 dysfun: clgv: from that paste above, i'm intuiting that in clojure 1.7 they're making the core better behaved. is that something they're trying to do?

11:08 catern: clgv: well, what if you have a seq you want to include, or a seq of seqs? (for some reason..)

11:08 justin_smith: clgv: for scalars, but what about structured types?

11:09 catern: maybe it should just be part of Incanter, because I can't see much use in including a dict in LaTeX

11:09 justin_smith: catern: it's just the kind of thing that org mode does - it can do both (embedding clojure code / results, generating latex)

11:10 catern: justin_smith: org-mode does embedding clojure code?

11:10 then I have no need for this!

11:10 clgv: justin_smith: he definitely needs to specify some strucutre of what is supposed to be rendered to latex ..

11:10 catern: justin_smith: please, tell me more

11:10 justin_smith: catern: http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-clojure.html

11:11 catern: oh

11:11 yes

11:11 clgv: dysfun: not sure to what you refer exactly

11:11 catern: I see that

11:11 pretty nice

11:11 justin_smith: "org-babel-clojure allows Clojure code to be executed directly within embedded code blocks in Org-mode documents. These code blocks and their results can be included in an exported document." -- export options include latex

11:11 dysfun: is there a reliable way to get an empty version of a given collection?

11:11 zerokarmaleft: catern: it's a rabbit hole, but check out https://github.com/thi-ng/geom and other repositories for org-mode+babel+clojure literate craziness

11:11 catern: justin_smith: yeah, I've been writing all this in org-mode anyway :)

11:12 dysfun: clgv: setting warn on reflection is presumably attempting to tighten up the behaviour of the core to be a bit higher quality and eliminate performance defects. is this an intended goal for 1.7?

11:12 * catern gives up his idea of making a Hiccup for LaTeX

11:12 justin_smith: dysfun: ##(map empty ["a" {:a 0} [1 2 3] #{:a}])

11:12 lazybot: ⇒ (nil {} [] #{})

11:12 clojurebot: Titim gan éirí ort.

11:12 dysfun: justin_smith: oh brilliant, thanks!

11:12 clgv: dysfun: I guess it ended up there by accident

11:12 justin_smith: dysfun: as you see, it might not do what you want for strings, (which aren't really collections I guess)

11:13 clgv: dysfun: enforcing reflections warnings is not a good idea in general - that has generated a lot of noise already with some libraries where it ended up in a release by accident

11:15 justin_smith: catern: haha, nice, looking at clojure-babel in more detail, they actually include an example of using incanter inside clojure inside org-mode to generate latex

11:15 ~emacs

11:15 clojurebot: emacs is finicky to configure and often broken

11:15 catern: justin_smith: yeah, I saw that, which is great

11:16 clojurebot: hey! :(

11:16 clojurebot: No entiendo

11:16 clgv: ,(print "catern: :P")

11:16 clojurebot: catern: :P

11:26 catern: such emacs bashing

11:27 you'll drive people to worse things

11:27 they'll think you're being serious!

11:27 keep emacs bashing to #emacs

11:28 J_Arcane: :( I am bombing the extra credit in the UofH Clojure course. :P

11:28 BinaryResult: A reminder: Disco Melee is currently hiring clojure devs https://docs.google.com/document/d/1GvnrSCUbYgbY9XdFs_DUx-0QZG2bIYT8Mbr0zdpTeew/edit?usp=sharing

11:29 bacon1989: they have a clojure course?

11:29 that would be awesome

11:30 J_Arcane: http://iloveponies.github.io/120-hour-epic-sax-marathon/index.html

11:36 borkdude: in liberator, when someone uploads a file I consider too big, what should I respond with?

11:37 jonathanj: all my dependency versions are hardcoded in project.clj, which is great because nothing magically updates them underneath me breaking all my code. but is there a way to find out if any of my project deps have a newer version?

11:37 borkdude: jonathanj lein ancient

11:37 justin_smith: jonathanj: lein ancient

11:37 jonathanj: guess that's a lein plugin i need to depend on

11:37 ordnungswidrig: borkdude: valid-entity-length? => false

11:39 borkdude: ordnungswidrig ok. I was thinking of returning a 413. I'll try valid-entity-lenght? and see what happens

11:40 ordnungswidrig: borkdude: liberator will return a 413 if valid-entity-length? returns false

11:40 borkdude: ordnungswidrig cool. I didn't see it in the decision graph, so I wondered

11:40 clgv: ~emacs

11:40 clojurebot: emacs is finicky to configure and often broken

11:41 ordnungswidrig: borkdude: it comes after `known-content-type`

11:41 borkdude: ordnungswidrig you're right. I see it now. A bit blind I guess :)

11:42 justin_smith: borkdude: I think Control-f works in svg

11:42 ordnungswidrig: borkdude: well, there's always the list of decisions which is search-able. But you need to know what to search for

11:42 sritchie: hey all - I’m looking at shadow build and seeing something about lein run I hadn’t known

11:42 borkdude: justin_smith yes, I done that, but I could not find 413. It seems in the decision graph the arrow goes to 415

11:42 clgv: borkdude: that monster graph might need an interactive search ;)

11:42 sritchie: if you provide a keyword like :project/cljs to lein run, does that fetch that entry in the project map?

11:43 justin_smith: borkdude: oh, OK

11:43 borkdude: ordnungswidrig the arrow at false goes to 415. https://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg

11:43 ordnungswidrig I searched for 413, that's why I could't find it :)

11:43 justin_smith: borkdude: I just found it under 413

11:44 https://clojure-liberator.github.io/liberator/assets/img/decision-graph.svg

11:44 on the left side, right under 503

11:44 ordnungswidrig: justin_smith: oh, I guess that is outdated *grr*

11:44 justin_smith: ordnungswidrig: oh, the one I linked to is outdated?

11:44 ordnungswidrig: oh no, that's the right one but there' a 413 left of 422 for me?!

11:45 borkdude: ah dude, I'm really blind today :)

11:45 ordnungswidrig justin_smith you're right, sorry

11:45 justin_smith: yes, and under 503, or se of it :)

11:45 ordnungswidrig: hahaa

11:45 justin_smith: ordnungswidrig: perhaps I miscommunicated

11:46 ordnungswidrig: borkdude: so we're fine?

11:46 borkdude: ordnungswidrig absolutely.

11:46 sritchie: anyone know about passing :project/key args in lein?

11:46 to lein run

11:47 ordnungswidrig: ,anyone

11:47 stuartsierra: When did org-clojure get CIDER support?

11:47 clojurebot: #error{:cause "Unable to resolve symbol: anyone in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: anyone in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: anyone in this context", :at [...

11:47 ordnungswidrig: stuartsierra: CIDER support?!

11:47 stuartsierra: http://orgmode.org/worg/org-contrib/babel/languages/ob-doc-clojure.html

11:47 justin_smith: sritchie: args to lein run will be the args passed to -main, and all be strings, right?

11:47 sritchie: except for this cryptic comment: https://github.com/technomancy/leiningen/blob/master/src/leiningen/run.clj#L146

11:48 justin_smith: and the examples in shadow-build have you passing :project/cljs

11:48 ordnungswidrig: stuartsierra: sweeeeet

11:48 sritchie: which I think grabs that entry out of project.clj

11:48 stuartsierra: Haven't tried it yet; I rolled my own org-clojure a while ago.

11:48 sritchie: justin_smith: trying to find the piece of code that handles that though

11:48 justin_smith: sritchie: wow, that's a weird feature

11:48 sritchie: yup, undocumented as far as I ca tell

11:53 borkdude: I just noticed that a method call also works in thread-first: (-> ctx :tempfile .length)

11:54 justin_smith: borkdude: also works with doto

11:54 ordnungswidrig: borkdude, justin_smith: did that change recently? I'm pretty sure that there was a time where that would not work

11:54 clgv: justin_smith: but borkdude is probably interested in that value of .length ;)

11:55 justin_smith: clgv: yes, related fact

11:55 clgv: ordnungswidrig: no always worked since 1.2.1

11:55 Bronsa: ordnungswidrig: always worked afaik

11:55 justin_smith: ordnungswidrig: I don't ever remember it not working

11:55 clgv: ordnungswidrig: you might get problems with typehints depending on the concrete form

11:55 * justin_smith showed up for the tail end of 1.3

11:59 _kardan: Anyone familiar with Bidi? I'm trying to use redirects but can't get it to work https://gist.github.com/kardan/8758aa14ca8c90970bcc what am I doing wrong?

12:00 sritchie: justin_smith: boom: https://github.com/technomancy/leiningen/blob/master/leiningen-core/src/leiningen/core/main.clj#L251

12:00 ordnungswidrig: _kardan: I think you must not wrap the #".*" in brackets.

12:01 justin_smith: sritchie: there it is. Still think it's a weird feature :)

12:01 sritchie: yeah, definitely

12:01 especially because you can’t nest -

12:02 I was looking into this because I wanted to provide shadow with a config for each of two profiles

12:02 the fact that you can only pull top level keys is odd

12:02 justin_smith: sritchie: and because ideally lein shouldn't even be present at production run time

12:03 sritchie: yeah, the “prod” build would be more for building the production version of clojurescript

12:08 _kardan: ordnungwidrig true, but didn't fix my issue. Thanks anyway

12:08 borkdude: is is possible to get the reponse's status with Google Closure iframeIo?

12:09 nullptr: borkdude: you can know it failed but i don't think you can get the specific response code/status

12:10 borkdude: nullptr ok

12:10 nullptr: actually -- that's just from the event

12:10 looks like it has getLastErrorCode and getLastError

12:13 borkdude: nullptr in the case of a 413 response, the success is still true. but I can just use the innerHTML to see if the file was too big

12:14 nullptr: borkdude: it looks like there's a setErrorChecker hook there so you could probably inject your check there to influence isSuccess

12:15 borkdude: nullptr it does not even reach the error state

12:15 nullptr oh wait, sorry, my bad

12:15 nullptr I'll try it

12:16 anti-freeze: Hey everyone. Does anyone know how I add a custom if statement in selmer? I want to add an if-authenticated block

12:18 Maybe just a function or something to check if the user is authenticated?

12:19 clgv: anti-freeze: cant't you just use an authenticated property?

12:19 anti-freeze: clgv: You mean passing it as a parameter after every render?

12:19 before*

12:19 so (render-file "auth.html" {:authenticated false})

12:20 clgv: yeah, just include that property to your property map

12:22 anti-freeze: clgv: I would, but this is needed for every single render, as its in the base template. I found something in the selmer source, maybe it could help. https://github.com/yogthos/Selmer/blob/master/src/selmer/tags.clj

12:24 borkdude: nullptr thanks for that suggestion. works great :)

12:25 clgv: anti-freeze: so? there might be other properties you also need in the base template sooner or later

12:26 anti-freeze: clgv: I do, but passing the same thing around to every template seems a little annoying, considering I can just check that value against the session :identity key

12:26 clgv: anti-freeze: ah, right, I'd have a central function for rendering which takes care of such properties

12:26 anti-freeze: humm, a tag could be possible solution, not entirely sure

12:30 noncom: how do i set charset for a post request in clj-http?

12:30 (for a multipart post request)

12:30 anti-freeze: clgv: I'll give it a shot and report back

12:45 clgv: Still no luck. I get compiler errors

12:46 clgv: https://www.refheap.com/98909

12:48 clgv: anti-freeze: I did not implement a tag myself so far...

12:49 anti-freeze: clgv: This is beginning to annoy me. See, I need it for base.html which is where all other templates extend from. It would be horrible if I had to pass it as a parameter with every request

12:50 clgv: anti-freeze: can't you implement the single render function (render-template url, prop-map) that adds the auth property to prop-map before rendering with selmer?

12:50 anti-freeze: pretty easy fix ;)

12:51 anti-freeze: clgv: Maybe. I'll give selmer another go and then I'll just do that. Not the best fix however

12:51 clgv: anti-freeze: why?

12:51 anti-freeze: clgv: I don't know. I used selmer because of its "extensibility"

12:52 clgv: anti-freeze: ah ok. well, read up on the docs - maybe you overlooked some info on custom tags

12:56 supersym: you know what I love about Clojure? Every time I think "Hey, let's try and see if this or that works....", it actually does.

12:57 contrary to my recent php experiences which were the exact opposite ... lol

12:57 clgv: haha :D

13:01 borkdude: just checking, but would processable? be the correct decision point to check wether an upload is an image?

13:02 in liberator that is

13:02 supersym: erh depends I guess? sometimes client side but you mention upload, as in its on the server already?

13:02 ah

13:04 borkdude: supersym yes, I don't trust my clients ;)

13:19 sritchie: anyone here using shadow-build, or its live reload feature?

13:21 borkdude: cool library: pantomime. (-> picture :tempfile mime-type-of image?)

13:28 timvisher: poll: Clojure version of 'pythonic'?

13:28 i tend to say 'clojurey' but that both looks and sounds a little dumb to me (^_^)

13:28 'clojury'?

13:28 :\

13:29 justin_smith: I tend to just call it "OK" as in "that code's OK" or "that isn't actually OK"

13:29 but perhaps there should be a clojure flavored version of that

13:29 :clojure/acceptable?

13:31 Glenjamin: "simple"

13:31 justin_smith: (inc Glenjamin)

13:31 lazybot: ⇒ 17

13:31 clgv: O_o

13:32 Glenjamin: although knowing to use (next) over (rest), (seq) over (empty?) etc

13:32 i guess that's more what we're talking about

13:42 sritchie: tomjack: hey, are you https://github.com/tomjakubowski by any chance?

13:43 bendlas: timvisher: I'd have to say 'idiomatic'

13:43 even though that can be used in other languages as well, it's particularly idiomatic to call something 'idiomatic' in clojure

13:44 dnolen: sritchie: tjakubow is who you're looking for

13:44 sritchie: dnolen: you might be interested in this “bug” I found, as it might come up -

13:44 dnolen: shadow-build implements live-reloading with goog.isProvided_

13:44 https://github.com/thheller/shadow-build/blob/fe129c26d68572991ef1ccdbd1da8e4dfbdb6277/src/cljs/shadow/cljs/live_reload.cljs#L26

13:44 dnolen: sritchie: I don't use shadow-build

13:45 sritchie: and I'm becoming less interested in what other tools are doing, it's too hard to follow now

13:45 sritchie: dnolen: for sure. just wanted to thank you, since I think your patch here fixed that issue https://github.com/tomjakubowski/weasel/pull/54/files

13:45 dnolen: sritchie: that logic also incorrect

13:46 sritchie: see cljs.browser.repl/bootstrap

13:46 anything else is not going to work

13:46 sritchie: thanks, I’ll get a patch up

13:46 dnolen: sritchie: just load that ns and call it, it's meant to be reused

13:47 sritchie: dnolen: you mean in weasel

13:47 dnolen: sritchie: that's right, there's already a PR for this, or comment about it

13:48 hrm or I thought there was ...

13:49 sritchie: https://github.com/tomjakubowski/weasel/blob/master/src/cljs/weasel/repl.cljs

13:49 dnolen: looks like you handled it already

13:49 5 days after that other commit I sent

13:50 dnolen: sritchie: heh

13:50 sritchie: yeah cemerick has been fixing up piggieback pretty good, it should just work if you're willing to go bleeding edge

13:50 timvisher: all of these suggestions are generic though

13:51 sritchie: dnolen: anyway, this “only reload required things” is a busted optimization, since you might want to redefine multimethods that never get explicitly required

13:51 dnolen: otherwise, wait till he announces this stuff, we're releasing a version of ClojureScript just for nREPL users

13:51 timvisher: as in they'd be just as applicable in any community

13:51 i would always want my code to be 'simple', 'idiomatic' etc.

13:51 dnolen: sritchie: I don't follow

13:52 timvisher: but it sounds like no one has a phrase that does that :)

13:52 how can i reload a defrecord that implements a protocol at the repl?

13:52 sritchie: dnolen: was referencing two things - 1 is that I’ve got a multimethod based system for defining client side and server side page state data. Some of the client side multimethod definitions are in cljx files that aren’t required by cljs,

13:53 dnolen: but their multimethod implementations are still registered under simple or advanced compilation, since they get jammed into the final loaded file

13:53 cemerick: sritchie: piggieback 0.2.0-SNAPSHOT is looking pretty decent with the latest CLJS; just check the "installation" note in piggieback's readme

13:53 sritchie: dnolen: in :none mode, they get ignored, so I have to explicitly require those namespaces to get the multimethod registrations

13:53 dnolen: 2nd pt was that shadow tries to optimize by only reloading files that have been required by some namespace: https://github.com/thheller/shadow-build/blob/fe129c26d68572991ef1ccdbd1da8e4dfbdb6277/src/cljs/shadow/cljs/live_reload.cljs#L23

13:54 dnolen: which 1) will always fail in :none mode if you’ve got a repl running, and 2) will cause the files containing those multimethods I mentioned above to never reload

13:54 dnolen: sorry, getting into details you just said you wanted to avoid :)

13:54 dnolen: sritchie: right I don't care about this stuff at all :)

13:55 sritchie: to the 1st point, that's just not going to change, :simple and :none just pull everything in the src directory in which is pretty obnoxious

13:55 sritchie: you have to use the classpath to get customized builds which is outrageous in my opinion

13:56 in the future :simple and higher will take :main to control what's in a build

13:56 sritchie: dnolen: yup, that’s what I’m doing, and agreed

13:56 dnolen: psyched for the modules stuff, btw -

13:57 dnolen: btw - racehubhq.com launched, full client side, written in Om

13:57 dnolen: sritchie: yeah, it's pretty awesome if you're building a big app

13:57 sritchie: dnolen: still some rough edges. modules are important for hiding a bunch of the admin-only stuff, like the timing app

13:57 dnolen: sritchie: 502 :(, but awesome!

13:57 sritchie: dnolen: Om baby! nice. so much for the change I just pushed.

14:21 dnolen: fixed https://racehubhq.com/

14:22 dnolen: sritchie: looks real sweet :)

14:23 sritchie: working on writing up the routing stuff I built for this + sente

14:23 thanks again for Om! the transition to client side’s been really fun because of it.

14:24 dnolen: sritchie: np, glad to hear it! Looking forward to getting back to it, got some goodies planned in the near future once the ClojureScript REPL stuff is behind us.

14:27 sritchie: cemerick: did that piggieback issue, or tools.nrepl issue, with resetting to cljs.user every time ever get fixed?

14:28 I upgraded to piggieback 0.1.5 and tools.nrepl 0.2.7, but still no dice

14:29 cemerick: sritchie: not aware of the issue, but you should be using 0.2.0-SNAPSHOT & nREPL 0.2.10 if you're running the newest CLJS stuff

14:29 sritchie: https://github.com/tomjakubowski/weasel/issues/26

14:29 you’ve commented on the issue, I believe

14:29 “latest cider on melpa” is probably the issue

14:30 bendlas: sritchie: I had that issue, but it went away a couple of weeks ago

14:31 cemerick: sritchie: oh, that. I think that was always a cider issue; nothing related changed in piggieback/nREPL

14:32 sritchie: cool

14:32 cemerick: sritchie: in any case, 0.2.0 is basically a rewrite to support the latest CLJS REPL bits

14:32 sritchie: nice

14:32 cemerick: So any issues reported < 4 days ago are obsolete :-P

14:32 sritchie: compatible w/ the latest weasel etc?

14:33 cemerick: sritchie: should be? Works well w/ nashorn, rhino, node, brepl, and ambly. Haven't gotten a weasel report either way yet.

14:33 sritchie: okay, cool

14:33 thanks! I’ll try the upgrade after locking down this shadow-build live reload thing

14:37 dah: dnolen: been thinking an osascript ClojureScript REPL backend could be fun for OS X automation

14:38 .. or even building full blown Cocoa applications i guess

14:39 dnolen: dah: sounds like a reasonable idea to me, mfikes has already done a ton of this work in Ambly/Shrimp

14:41 dah: dnolen: cool, thanks for the pointer

14:44 anti-freeze: dah: Haha, pointers...

15:06 mikerod: are there any good sources out there to explain what `print-dup` is?

15:06 I sort of get it.

15:06 but I just would like to read something more "official"

15:06 I saw some ancient mailing list stuff where Rich briefly discussed it (no link at the moment).

15:07 what does "dup" even stand for?

15:07 duplicate I think

15:07 profil: is there a way to get index when using for? (for [x [1 2 3 4 5]] (prn x "is at index: " x-index))

15:07 patrickgombert: mikerod: my understanding is that it is for serialization

15:08 mikerod: patrickgombert: yes

15:08 it allows more objects to have a reader-friendly print

15:09 ro_st: profil: no, you'll need to use map-indexed

15:09 joegallo: profil: (for [[i x] (map-indexed vector [:a :b :c])] ...)

15:09 not exactly what you wanted, but it works

15:09 ro_st: or do what joegallo says. nice one

15:09 mikerod: by reader-friendly, I mean they can be read back in and eval'ed back to life

15:10 profil: I'm thinking that I could change the for into a map-indexed instead..

15:10 joegallo: ah, that's only if you absolutely *must* use for -- alternatively you could fold your for's body into the fn arg to map-indexed

15:10 profil, yes, exactly :)

15:10 mikerod: I guess it is just a hook to make arbitrary ways to represent data to be serialized and then read back in later - I think it requires read with eval enabled.

15:12 amalloy: mikerod: right. also, it tends to get sorta out of date because nobody uses print-dup

15:12 i know there were some cases in the past where print-dup on some kind of uncommon data structure (maybe treemap?) printed a call to a constructor that doesn't exist anymore

15:13 dyba: I'm reading Let Over Lambda and noticed some interesting difference between Common Lisp and Clojure when defining the nif macro:

15:13 (defmacro nif [expr pos zero neg] `(cond (pos? ~expr) ~pos (zero? ~expr) ~zero :else ~neg))

15:14 Clojure expands it to: (if (clojure.core/pos? 0) "Pos" (clojure.core/cond (clojure.core/zero? 0) "Zero" :else "Neg"))

15:14 But CL expands it to the result "Pos", "Zero" or "Neg"

15:14 amalloy: dyba: no it doesn't. you are using the macroexpander in CL wrong, or defining the macro wrong

15:15 dyba: amalloy: perhaps I did, I used CL's macroexpand function

15:16 Are they different?

15:16 amalloy: no. but perhaps you forgot to quote the expression to expand, for example

15:16 dyba: Hm, good catch. Let me try it again

15:18 amalloy: dyba: also, try using macroexpand-1

15:19 i'm trying it in clisp, and it looks like the macroexpander is smart enough to elide checks that it knows will be true or knows will be false

15:19 so you want to expand only your own macro, not the further macro that it expands to

15:19 [10]> (macroexpand-1 '(nif -1 1 2 3)) ;=> (COND ((< 0 -1) 1) ((EQUALP 0 -1) 2) (T 3))

15:19 where i basically never use CL so i don't remember if equalp is the right predicate to use or what

15:22 dyba: amalloy: yup it works with macroexpand-1

15:22 macroexpand gives me the evaluated result

15:23 And I am using a quote in front of the expression I'm passing to macroexpand

15:25 amalloy: dyba: yeah, i was surprised to discover that = and < have uh...compiler macros, i guess, associated with the functions for them

15:25 so like if you expanded '(nif x 1 2 3), you'd get the full cond tree

15:25 but '(nif 0 1 2 3) it knows how to evaluate at compile time

15:27 dyba: amalloy: Ah, I see what you mean

15:29 amalloy: so what you're saying this behavior in CL suggests that = is likely built with a compiler macro?

15:29 saying is that*

15:29 amalloy: well, = is a built-in function, and appears to have a compiler macro as well

15:30 in theory it could be special-cased by the macroexpander, but probably it is just a compiler macro

15:34 danlentz: if you are interested in CL compiler macros, there is a short presentation given my arthur lemmens floating around out there

15:34 http://www.pentaside.org/paper/compilermacro-lemmens/compiler-macros-for-publication.txt

15:36 amalloy: danlentz: i understand the idea of compiler macros, but i don't know whether = uses one, or how i would confirm my expectation that it does

15:37 danlentz: can’t you call (compiler-macro-function ‘=)

15:38 amalloy: danlentz: apparently not. but i wouldn't have known to try that; i never use CL

15:39 danlentz: compiler-macros are somewhat heady stuff. I worked in CL for a number of years and pretty rarely came into contact with them.

15:40 amalloy: danlentz: rarely noticed coming into contact with them, anyway

15:40 danlentz: yes, you’re right.

15:41 dyba: danlentz: that presentation helped with having a better understanding of the idea of compiler macros

15:41 thanks!

15:41 danlentz: reading through this paper again, the use-case of translating n-ary to binary functions is interesting.

15:42 yeah, im just rereading it and thinking the same thing.

15:42 amalloy: danlentz: clojure has its own version of compiler macros too, mostly for the primitive math stuff

15:42 danlentz: arthur lemmens is really an iconic common-lisper. I spent my first year or so of CL studying his persistent object-store called Rucksack

15:43 dyba: I don't use CL but reading Let Over Lambda requires having some basic understanding of that language

15:43 danlentz: shit yeah it does

15:43 dyba: Which is why I asked the question originally

15:43 danlentz: that is a hard book

15:43 amalloy: eg, see the definition of nil?, which has in its metadata {:inline (fn [x] (list 'clojure.lang.Util/identical x nil))}

15:44 dyba: danlentz: you're telling me! ;) Definitely not an easy read

15:44 danlentz: if you look in my CL-CTRIE project I have a dlambda, plambda

15:44 dyba: I haven't read that chapter yet; I'm currently on ch. 3

15:44 danlentz: https://github.com/danlentz/cl-ctrie/blob/master/ctrie-lambda.lisp

15:44 dyba: The once only macro

15:45 Sweet!

15:45 danlentz: dyba: did you read paul graham first?

15:45 dyba: I'm bookmarking that and coming back to it when I get to that chapter

15:45 danlentz: You mean On Lisp?

15:45 danlentz: y

15:45 dyba: I'm reading that one too

15:45 Just got past the first chapter

15:45 danlentz: its good to read that first — its mostly about macros

15:46 LoL is on the edge of the discovered macro universe. On Lisp covers the stuff that may come in more handy day to day.

15:47 but I love that book, awesome to see clojurians reading it!

15:50 however, I have to warn you, anytime I show a client code with “pandoric-lambda” in it they make a scrunchy face like I just fed them lemons

15:50 dyba: danlentz: I'll keep that in mind. I'm reading LoL first because I have a hard copy of it. On Lisp is out of print last I checked. And it sells for hundreds of dollars on Amazon.

15:50 danlentz: its free

15:50 dyba: I downloaded the free PDF, but I still like to have the book on my hand

15:50 danlentz: oh

15:51 dyba: danlentz: lol

15:51 danlentz: i do understand. I print stuff out and bind it nicely with a stiff paperboard backing (cut from a heavy duty binder) and poly cover

15:51 dyba: (the popular lol) ;)

15:52 I think I will do that with On Lisp, so that I can write on the margins of the pages

15:52 danlentz: dyba: what I love is the pandoric-lambda from LoL though

15:53 and the entire concept of “sub-lexical scope”

15:53 dyba: what chapter are those topics on?

15:54 danlentz: dont remember offhand. the entire first part of the book builds up to pandoric-lambda

15:54 dyba: Ah I found them

15:54 danlentz: then he goes back and does other stuff like a forth interpreter

15:56 I think clojure macros are quite a bit easier to work with than in common-lisp, just because the gensyms are so easy syntactically

15:57 I might be slow, but it took me a couple of years to work though LoL

15:58 because it wasnt continuous. I’d read until I was thoroughly baffled, then put the book down for 6 months and try again.

16:00 dyba: danlentz: "Should you experience headaches or other discomfort through the course of this book, I recommend that you immediately execute a garbage collection cycle (get some sleep), then return with a fresh and open mind"

16:00 danlentz: usually until I saw something in the outside world that I connected with the book and somehow made something “click” — then I’d get 10 pages further until baffled again.

16:27 dyba: if you do cut and paste the code, at line 133 there is a (defun/inline …) form that is just syntactic sugar to define a function and declare it ‘inline’ all with one form.

16:28 dyba: danlentz: I'll keep that in mind

16:28 danlentz: you would need to change that or copy the defun/inline macro: https://github.com/danlentz/cl-ctrie/blob/master/common-macro.lisp#L38

16:30 there are some other useful examples of macros in that file, if you are interested

16:30 like, you were talking about “once only”

16:31 https://github.com/danlentz/cl-ctrie/blob/master/common-macro.lisp#L74 defines a defmacro/once macro

16:35 edbond: how to get matched value from map of regexp => value? (<somefns> { #"a" 42, #"b" 99 } "bbb") ;; 99

16:36 possible direction, what fns to look at?

16:36 gfredericks: some could probably help

16:36 ,(doc some)

16:36 clojurebot: "([pred coll]); Returns the first logical true value of (pred x) for any x in coll, else nil. One common idiom is to use a set as pred, for example this will return :fred if :fred is in the sequence, otherwise nil: (some #{:fred} coll)"

16:36 chouser: or keep, depending on if you want more than one result

16:37 edbond: just first result

16:37 chouser: and of course re-find

16:37 edbond: thanks

16:37 ,(inc gfredericks)

16:37 clojurebot: #error{:cause "Unable to resolve symbol: gfredericks in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: gfredericks in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: gfredericks in this ...

16:37 gfredericks: ,(def gfredericks 41)

16:37 clojurebot: #'sandbox/gfredericks

16:37 edbond: ,(inc gfredericks)

16:37 clojurebot: 42

16:37 edbond: nice

16:38 (inc gfredericks)

16:38 lazybot: ⇒ 129

16:39 danlentz: ,danlentz

16:39 clojurebot: #error{:cause "Unable to resolve symbol: danlentz in this context", :via [{:type clojure.lang.Compiler$CompilerException, :message "java.lang.RuntimeException: Unable to resolve symbol: danlentz in this context, compiling:(NO_SOURCE_PATH:0:0)", :at [clojure.lang.Compiler analyze "Compiler.java" 6535]} {:type java.lang.RuntimeException, :message "Unable to resolve symbol: danlentz in this context",...

16:40 danlentz: ,(def danlentz Math/PI)

16:40 clojurebot: #'sandbox/danlentz

16:40 gfredericks: ,(inc danlentz)

16:40 clojurebot: 4.141592653589793

16:40 gfredericks: $google zip code 41415

16:40 lazybot: [41415 Rayburn Dr, Northville, MI 48168 is Recently Sold | Zillow] http://www.zillow.com/homedetails/41415-Rayburn-Dr-Northville-MI-48168/88392796_zpid/

16:41 danlentz: wow

16:41 $google clj-uuid

16:41 lazybot: [danlentz/clj-uuid · GitHub] https://github.com/danlentz/clj-uuid

16:42 danlentz: cool!

16:46 ben_vulpes: yo so cider is eating print statements in my http-kit webapp :(

16:46 lein repl commits no such crime

16:46 halp wat do

16:46 danlentz: ,(java.util.UUID/randomUUID)

16:46 clojurebot: #uuid "a296e782-0372-4a7b-996d-9ef25a5437d2"

16:48 danlentz: ben_vulpes: check other window

16:48 ?

16:48 ben_vulpes: other...window?

16:48 cider-error?

16:48 nrepl-connection?

16:49 danlentz:

16:50 danlentz: well, there are a limited number of them, check them all

16:51 i mean, what I am asking is if maybe you are doing IO on a background thread and it is directed to the console rather than cider

16:51 but ive never done anything with http-kit so that is just a stab in the dark on general principle

16:52 ben_vulpes: danlentz: the only relevant buffers i have at hand are nrepl-server and cider-repl

16:52 what would be different in execution between cider via emacs and lein repl?

16:52 i'm way out of my depth on this one.

16:52 iirc i've seen this in ring as well

16:52 justin_smith: ben_vulpes: it's an old bug

16:53 ben_vulpes: cider rebinds *out* but that does not propagate to your ringer server's threads

16:53 ben_vulpes: aha that sounds right

16:53 justin_smith: ben_vulpes: so any printing from them go to the initial value of *out*, which is either an *nrepl-server* buffer, or the terminal where you started up from, or whatever

16:55 ben_vulpes: agh fuck

16:55 https://github.com/clojure-emacs/cider/pull/818

16:56 dude

16:56 can i just use slime?

16:56 and mebbe nrepl?

16:56 danlentz: things work like this in CL/slime as well

16:56 * ben_vulpes sighs

16:57 justin_smith: ben_vulpes: the bug doesn't come up in inferior-lisp, if you don't mind doing things caveman style

16:57 danlentz: I never thought of it as a “bug"

16:57 ben_vulpes: you never thought the dropping of print statements on the floor was a bug?

16:57 justin_smith: danlentz: the difference is that with slime, the process buffer (default root *out*) is also the repl buffer

16:57 danlentz: this is not the case in cider

16:58 danlentz: the behaviour of special variables between/among thread I mean

16:59 justin_smith: yeah, that's slightly orthogonal to the UI disaster in cider

16:59 last comment in that thread: "I submit that having the application's standard output, including log output, in a buffer separate from interactive REPL output is desireable. I would go so far as to call it a feature."

17:00 there you have it, cider author has declared that not outputting to the cider repl buffer is a feature

17:01 danlentz: well that is bizarre

17:01 but I agree with the idea of not having *out* bound to the cider-repl in all threads

17:03 justin_smith: I think separating output between buffers, defaulting to a buffer that never pops to the front, should be an opt-in thing

17:04 As a naive new user, I'd rather deal with messy output cluttering a buffer, than output that I expect never being visible

17:05 ben_vulpes: especially since it's such a radical divergence from how the time tested and battle hardened tools elsewhere in the lisp universe behave in my limited experience.

17:05 danlentz: it seems normal to me

17:05 well, the default output from the foreground should go to the repl. background threads all go to the console.

17:06 i’ve been donating $10 a week to the cider project

17:06 justin_smith: I long ago ditched cider for inferior-lisp

17:07 ben_vulpes: justin_smith: i think i'll have to hit you up for a crash course on inferior lisp here shortly

17:07 danlentz: i want it to get better, but it didnt happen overnight with slime either — thats for sure.

17:08 ben_vulpes: what would be the cider-y solution?

17:08 justin_smith: hehe, just to warn you it is seriously feature deprived. But it isn't constantly broken, and is never surprising to me.

17:08 ben_vulpes: i don't need much by way of features

17:08 i've got helm

17:08 justin_smith: ben_vulpes: another option is monroe

17:09 ben_vulpes: "simple installation without any dependencies, except Emacs"

17:09 ahahaha

17:09 i guess theoretically emacs could be just a single dep

17:12 danlentz: i think the reason is that output to the CIDER nrepl buffer is very slow. Even a modest amout of printing is going to “freeze” things up a bit.

17:13 justin_smith: danlentz: do you mean the cider-nrepl (aka console) or cider repl (aka the repl)

17:13 danlentz: the cider repl in my emacs window

17:14 justin_smith: danlentz: the reason I ask is that the hidden console output (not a repl) is actually called *cider-nrepl* or something very close to that

17:14 the buffer that most people never see, and they think prints that end up there never happened

17:15 danlentz: I gave up keeping track of what things were being called a while ago…. :)

17:15 Frozenlock: justin_smith: it's really aggravating when it occurs...

17:15 "Where is my print? I'm sure I added a print somewhere..."

17:15 justin_smith: Frozenlock: yes, I would disagree with the official stance and call it a bug actually.

17:17 danlentz: if you are doing a lot of that, might it make sense to consider a logging package, which in many cases will be much faster than printing to console and light years faster than printing to Cider repl

17:17 buffered output and so forth

17:17 justin_smith: danlentz: the logger will end up printing to the console, unless you set up a log file

17:17 danlentz: right'

17:17 i mean, just a suggestion

17:18 and then tail -f the log file, I mean

17:18 justin_smith: danlentz: M-x auto-revert-tail-mode

17:19 Frozenlock: M-x butterfly

17:21 I used to have plenty of problems with Cider, but I don't anymore. I also don't live on the edge. I found a stable version and I stick with it (for now).

17:21 danlentz: y i pulled back from the edge a few months ago myself

17:21 Frozenlock: The only bad thing I can think of is connecting to a remote repl with a poor connection: the autocomplete is sloooow

17:22 danlentz: the edge is rather pointy these days

17:24 Frozenlock: I wonder if we could find a correlation between the number of issues opened at any point and the expected user experience.

17:25 danlentz: my opinion is that the lack of willingness to cooperate by the SLIME developers hurt the clojure tooling (cider) and it is taking a while to draw even. But I think the result is that also cider may wind up to be the cleaner and more modern tool

17:25 at some point.

17:25 i miss the debugger

17:26 Frozenlock: danlentz: by what I understood, slime was a horrible mess. I would ask technomancy to chip in, but I don't think he's here. :-/

17:27 danlentz: i probably put off working with clojure for at least a couple of years just because it was problematic to use at the same time Slime for Clojure and Slime for CL

17:27 Frozenlock: danlentz: http://technomancy.us/163

17:27 danlentz: interesting

17:29 i think he’s not saying that the SLIME developers were actively belligerent towards the idea

17:29 which, having watched, was my impression

17:30 Frozenlock: About the debugger https://github.com/clojure-emacs/cider/issues/694

17:31 danlentz: there were actually many contributed patches to the SLIME effort that the maintainers simply threw on the floor

17:32 and they made it very difficult, as he said, for any project to fork and extend

17:34 I really feel like the approach they took did more to harm the CL community than slow Clojure down all that much.

17:35 attila lemdvai did some awesome patches that allowed you to use SLIME basically as a text-gui interface for your own app

17:36 all that was required was that a couple of hooks be added into the trunk, and the use-case of SLIME could have really expanded to provide a sorely lacking facility: any sort of common front-end interface among lisps

17:37 p_l: danlentz: back in the day i always felt it had more to do with all yhe clojure patches I've seen being for a version considered outdated (but last tarballed)

17:39 danlentz: that would be a good sugestion for the Cider project: customizable “inspector” that allows you to design arbitrary CRUD layout

17:40 justin_smith: danlentz: hmm, what about something using GUD mode with jdb instead of the usual gdb?

17:40 danlentz: might be gud

17:40 :)

17:41 justin_smith: GUD UI example http://tuhdo.github.io/static/c-ide/gdb-many-windows.gif

17:41 one window with stack frames, another with breakpoints, another showing locals, etc.

17:41 and threads

17:42 jdb provides all of that, I wonder how well elisp could extract sensible clojure info from all of it

18:03 xemdetia: gdb-many-windows the best friend

18:03 Lewix: why is that clojurist don't have an awesome newsletter like gooist

18:03 or rubyist

18:04 amalloy: Lewix: you haven't written one yet

18:04 justin_smith: Lewix: we have one, we just decided not to invite you

18:04 * justin_smith is just kidding.

18:04 om: eval is evil!

18:04 Lewix: amalloy: im not a clojurist yet

18:04 danlentz: what is that lambda-love newsletter

18:04 xemdetia: I mean clojure has a useful irc channel why do you need a newsletter

18:04 om: I have Enlive selector code (with fns) that I load from a config file.

18:04 Frozenlock: Lewix: the #clojure channel is like the official doc and the mailing list. All in one.

18:04 justin_smith: Lewix: we have (def newsletter) and the clojure gazette

18:04 Lewix: xemdetia: well to keep up to date in an efficient way? To promote clojure ?

18:05 om: Selectors are vectors. But at some point the fns (from enlive ns) have to be resolved.

18:05 bja: if I want to a map as a JSON value for HoneySQL, do i have to override the ToSql implementation for IPersistentMap (thus giving up subqueries)?

18:05 Lewix: justin_smith: i see. I'll google that

18:05 justin_smith: Lewix: http://defnewsletter.com/ http://www.clojuregazette.com/

18:05 om: I thought that the eval being done in the processing ns, I could call my function in another ns without requiring enlive there too. But this is where the eval happens indeed.

18:05 so it seems, eval is really evil!

18:06 justin_smith: om: also, eval is also very bad for performance

18:07 om: justin_smith: how would you proceed then, to have the fns is selectors being resolved?

18:08 danlentz: lewix: http://reborg.tumblr.com

18:08 another “clojure weekly”

18:08 justin_smith: om: if possible, a simple mapping (via hash map) from symbols or keywords to the functions that are valid. This also prevents the "run arbitrary code" issue, or at least improves that situation.

18:08 danlentz: I endorse Clojure Weekly because he mentioned me last week :)

18:09 om: to give an idea : https://www.refheap.com/98916

18:09 justin_smith: this is exactly what I do

18:09 Lewix: danlentz: thanks

18:09 om: but I some point they have to be resolved? don't they?

18:10 justin_smith: om: well, if you use a hash map from symbol to function, then you don't need eval

18:10 it's a whitelist

18:10 om: justin_smith: really?

18:11 justin_smith: if I have, say, [[:table (left :table)] :> [:tr (left :tr)]] how do I get it resolve

18:11 danlentz: can you use “resolve” rather than eval?

18:11 om: left or enlive/left

18:12 danlentz: I mean, isnt a ns basically a hash map from symbol to function?

18:12 om: danlentz: I don't think so, I'll try again

18:13 justin_smith: om: (clojure.walk/post-walk #(if (symbol? %) (get {'left enlive/left} %) %) selector)

18:13 where you would selectively add the valid functions to the hash map

18:13 danlentz: oh i see

18:13 om: justin_smith: sure, but this doesn't give me a fn that I can pass to enlive: this is the problem

18:13 justin_smith: it's easier if the structure is more predictable, but post-walk will do the job

18:15 om: if you look to the few lines of code I posted, you will see remove-nodes to which I pass bunches of selectors taken from a vector

18:15 justin_smith: oh right, left is being called with args

18:16 om: the pb being that when remove-nodes is called from another ns, the later should have enlive required

18:17 justin_smith: om: this is the thing I am saying is fixed by inserting the actual functions into the form.

18:17 but I'm unfamiliar with this part of enlive

18:17 and some weird stuff is going on there

18:17 where clearly eval is the easy way to handle it

18:18 pandeiro: what is the idiomatic way to go from record -> plain map?

18:18 justin_smith: pandeiro: (into {} rec)

18:18 amalloy: pandeiro: don't define the record type to begin with is easiest

18:18 om: justin_smith: thanks a lot, maybe I misunderstood what you meant with postwalk here (because I use it a lot too)

18:18 amalloy: i think om is trying to run user-specified code at runtime, not just do some simple lookup to plug into an already-defined function

18:19 bja: can I temporarily extend-protocol something (i.e. in a thread-local way)?

18:19 justin_smith: amalloy: yeah, I think it's some enlive specific idiom going on too

18:19 amalloy: eval seems easier than trying to invent an entire interpreter for enlive selectors

18:19 dnolen: bja: you cannot

18:19 pandeiro: justin_smith: ok that works; amalloy: yeah neocons did it, not me

18:20 amalloy: pandeiro: why do you need it to be a map anyway, if you have a record already?

18:20 pandeiro: amalloy: serializing it to edn

18:20 om: amalloy: but then how do you avoid requiring the ns where the fns are defined (in my case enlive), in the ns calling my function (not sure I am clear)?

18:21 amalloy: I guess you can't

18:21 justin_smith: om: what about a post-walk and resolving all symbols?

18:21 amalloy: you don't. eval happens in a clean environment, usually in clojure.core or something, so if you want more names accessible you need to make them accessible in the code you're evaluating

18:21 justin_smith: and then what? you still need to eval the result

18:21 om: because eval happens at "eval" time, hence my calling it evil

18:21 justin_smith: amalloy: right, but then they are fully qualified

18:21 om: oh, right

18:22 justin_smith: amalloy: wouldn't fully resolving any symbols make sure eval works?

18:22 amalloy: meh. just (eval `(do (require [enlive.whatever :refer :all]) ~the-user-code)))

18:22 om: I mean I do not eval in my function, but the eval happens when my function is called, right?

18:23 oh, seriously?

18:23 thanks

18:23 amalloy: om: that's what i'm saying. if you want the user code to have a specific environment set up, you just change the user code to set up that environment itself

18:24 om: I see, thanks to both of you

18:24 calhinshaw: I'm not sure this is the right place to ask, so let me know if it's not. I'm new to clojurescript webapps and having trouble getting routing working. I made a new luminus project with the +cljs option and added the goog.history code at http://yogthos.net/posts/2014-08-14-Routing-With-Secretary.html, but I can't get get the back button to work or get the urls i'm dispatching to display in the url bar. Does anyone have any suggest

18:24 ions? Thanks.

18:24 om: pretty neat explanation (I did not get eval was happening in a 'clean' env)

18:27 sobel: so.. i'm having odd probles with floats (Float/parseFloat)

18:27 what type is a 'naked' decimal number? that may be my trouble

18:28 danlentz: that is the special “exhibitionist primitive” type

18:28 sobel: hah. i don't know if unboxed is the right term in clojure.

18:29 i lack words. that makes this (and google) harder.

18:29 danlentz: you have to watch out for contagion :)

18:29 justin_smith: sobel: float and double are unboxed, Float and Double are boxed

18:29 sobel: when the compiler gets the right hints, it can figure out when it doesn't need to box things

18:29 sobel: i have a vector of floats i parsed with Float/parseFloat, and when i try to filter one, it's not found. but when i filter for (Float/parseFloat "0.0943") it'sfound

18:29 danlentz: http://clojure.org/java_interop#Java%20Interop-Type%20Hints

18:30 sobel: aha, that settles it

18:30 justin_smith: thx

18:30 justin_smith: sobel: with clojure 1.7, there is a *warn-on-boxed* value for the unchecked-math setting

18:30 sobel: floating point equality is your problem

18:30 sobel: i suppose i don't really want Float/parseFloat. what's a better way to get numeric out of string?

18:31 justin_smith: ,(= 0.0943 (Float/parseFloat "0.0943"))

18:31 clojurebot: false

18:31 justin_smith: sobel: ^^ that's your issue

18:31 sobel: justin_smith: yes, that was basically my isolated problem

18:31 justin_smith: sobel: read-string

18:31 or Double/parseDouble

18:32 ,(= 0.0943 (Double/parseDouble "0.0943"))

18:32 clojurebot: true

18:32 justin_smith: but floating point equality is always going to be problematic

18:32 sobel: yeah, i'm familiar with the built-in problem on that

18:33 fwiw, 0.0 doesn't suffer the fp inequality issue at hand ;)

18:33 justin_smith: heh, I'd hope not

18:34 sobel: is there a simpler numeric conversion that doesn't involve eval?

18:34 justin_smith: sobel: parseDouble doesn't involve eval

18:34 read-string doesn't either

18:34 sobel: e.g. untrusted sources

18:35 is this doc outdated? Note that read-string can execute code (controlled by *read-eval*),

18:35 justin_smith: parseDouble is your safest bet if you know that will be the expected type

18:35 sobel: and as such should be used only with trusted sources.

18:35 justin_smith: right

18:35 so use parseDouble

18:35 or edn/read-string

18:35 danlentz: ,(= (float 0.0943) (Float/parseFloat "0.0943"))

18:35 clojurebot: true

18:35 sobel: that'll be a boxed Double right?

18:35 justin_smith: sobel: absolutely

18:35 boxing was not your issue here

18:36 danlentz: ,(= 0.0943 (Double/parseDouble "0.0943"))

18:36 clojurebot: true

18:36 danlentz: your issue is the default representation

18:36 sobel: ah ok

18:37 justin_smith: sobel: unboxed doubles can't be stand alone values, they can only be members of a double-array or arguments / return values of methods. Maybe they can be fields of some class too?

18:37 but they aren't objects

18:37 sobel: that's only a slight bit weird. i think i can digest it.

18:38 justin_smith: sobel: unboxed numerics exist so code can be fast

18:38 sobel: objects have overhead, sometimes we really don't want that overhead

18:38 sobel: mostly it's just a foible i hit on at the repl. the code that needs to care is actually ok, it's just obnoxious trying to validate it with tiny tests and hand-picked data.

18:39 yotsov: Hello. Is there a clojurescript equivalent of environ? Any way to pass build env variables to the code?

18:40 sobel: justin_smith: oh yeah, totally understood on boxing vs performance. i think my trouble was just expecting a cut & paste value to let me test my code when it was full of boxed values.

18:40 justin_smith: sobel: boxing was not your issue here

18:41 sobel: your issue was that 0.0943 as a literal, is a double in clojure

18:41 but you were creating floats from strings

18:41 floats and doubles have different resolution

18:41 om: amalloy: interestingly enough, doing a require in the eval raises a class not found exception

18:41 justin_smith: so they compare oddly

18:41 amalloy: om: oh sure, it needs to be quoted better

18:41 justin_smith: om: make sure to get your quoting right

18:41 amalloy: my example wasn't right

18:42 (eval `(do (require ['~'enlive.whatever :refer :all]) ~the-user-code)))

18:42 om: well, syntax quoting should be enough no, why dequote

18:42 catern: yikes

18:42 clojure gets pretty ugly with the quoting

18:43 om: thanks, amalloy, justin_smith

18:43 amalloy: why is the tilde "quoted"?

18:43 catern: thamalloy.

18:44 justin_smith: catern: sadly thjustin_smith just doesn't have the same ring to it

18:44 catern: thustin_smith!

18:45 sobel: justin_smith: i know, and i was looking right at it, thinking eh, should be ok at least to the ten-thoundths place!

18:46 anywho, thanks all

18:47 om: amalloy: got it to work (still did not fully catch the '~')

18:47 (inc amalloy)

18:47 lazybot: ⇒ 243

18:47 amalloy: om: '~' is not a compound thing, it is just a combination of ', then ~, then '

18:47 sobel: this is my first commercial clojure project. being able to conveniently manipulate data is saving me numerous trips to the database. my input design seems to assume that you can't sort or merge data without sql.

18:48 justin_smith: (inc group-by)

18:48 lazybot: ⇒ 1

18:48 om: amalloy: oh, you quote the unquote

18:48 amalloy: you want to emit 'enlive.whatever, with a quote in front of it, so you start with '. then, you want to not namespace-qualify enlive.whatever, so you write ~ to leave the ` context, and ' to enter a normal quoting context

18:49 catern: guys

18:49 I need to write some clojure

18:49 it's amazing

18:49 some more*

18:49 I did some trivial programming with it earlier

18:49 and it was great

18:49 om: amalloy: excellent, thank you

18:49 catern: what trivial project should I do next?

18:49 justin_smith: jeapordy app

18:49 catern: what is clojure good at besides web apps and statistics?

18:49 justin_smith: (wrong kind of trivial)

18:50 sobel: justin_smith: once i can write the clojure-equivalent of sql exprs involving group by, order by, rank over, partition over, and having... there will be no more utility-trips to the db :)

18:50 justin_smith: sobel: well, group-by alreayd works at least, it would be nice to build a lib that has all of them

18:50 amalloy: justin_smith: pls, pronounce it like "gee-pordy" next time someone is talking about jeopardy

18:50 justin_smith: amalloy: uh, OK

18:51 my spelling is shit

18:51 amalloy: (the misspelling leads to a funny-sounding pronunciation)

18:51 justin_smith: yes

18:51 amalloy: although i guess the right spelling should be pronounced pretty funny too, if english made any sense

18:51 sobel: justin_smith: i'm new at this, but i'd hope all the basics (order by, group by, having) are available

18:51 justin_smith: sort-by, group-by, filter

18:51 sobel: i mean.. i used sort-by earlier today

18:52 i'd just need to figure out how to replace rank over and partition

18:52 catern: what's a good clojure library for simple geometry and drawing? Say I wanted to draw one of these: http://en.wikipedia.org/wiki/Voronoi_diagram

18:53 justin_smith: catern: I'd check out analemma if svg output is acceptable

18:53 catern: what about quil?

18:54 justin_smith: quil is kind of weird, but sure

18:54 catern: weird?

18:54 justin_smith: quil has its own main loop thing, and does a few things in ways that are not conventional

18:54 sobel: Swing is always quick & dirty

18:54 justin_smith: it wants to be like the clojure processing

18:55 jaen: Just trying some macro shenanigans and I can't figure out a way to refer to a some-gensym# that's outside a ~(expr) from inside it. Any way to do that? (I need to conditionally emit code in macro that uses this gensym)

18:55 amalloy: jaen: you can't

18:56 jaen: Damn, I suspected that : X

18:56 amalloy: you need to generate your own gensym by hand, if you want to use it in multiple contexts

18:56 jaen: amalloy: you mean like (gensym "name")?

18:57 amalloy: (let [x (gensym "x")] `(let [~x 1] ~(if whatever `(+ 1 ~x) `(- ~x 1))))

18:57 jaen: Ok, thanks : )

18:57 justin_smith: (inc `~'amalloy)

18:57 lazybot: ⇒ 1

18:58 amalloy: ,`~`~`~`~1

18:58 clojurebot: 1

18:59 amalloy: tip: to make your code more confusing, just sprinkle some `~ into it at random

18:59 it's like a 2-character identity function

18:59 sobel: soaking up excess readability

19:00 this language has everything, i swear

19:00 (pony)

19:00 justin_smith: ,(`~`~get `~`~`~`~get `~`~`~`~`~`~`~get `~`~`~`~`~`~`~`~`~`~`~get)

19:00 clojurebot: #object[clojure.core$get "clojure.core$get@40007a3a"]

19:00 amalloy: *chuckle*

19:02 sobel: and today, my big milestone was making intuitive sense out of the idiom (apply map vector [[ ... ]])

19:02 justin_smith: that's much more useful

19:03 sobel: starting to get some opinions on how this should be learned

19:22 irctc_: Would like to convert [{:year "2015" :grp "foo" :name "A"} {:year "2015" :grp "foo" :name "B"} {:year "2014" :grp "bar" :name "C"} {:year "2014" :grp "bar" :name "D"}] to..

19:22 {"2015" {"foo" [{:year "2015" :grp "foo" :name "A"} {:year "2015" :grp "foo" :name "B"}]} "2014" {"bar" [{:year "2014" :grp "bar" :name "C"} {:year "2014" :grp "bar" :name "D"}]}}

19:24 oddcully: group-by?

19:24 irctc_: trying to use successive calls to group-by with a function signature like: (group-by-nest coll [:year :grp])

19:25 justin_smith: wait, where does the :grp part come in? they aren't grouped by it

19:26 amalloy: irctc_: http://stackoverflow.com/q/25480674/625403 looks like your question

19:26 justin_smith: maybe you just want to sort by it?

19:26 irctc_: oh, now I see, never mind

19:26 chouser: (into {} (for [[year v2] (group-by :year v)] [year (group-by :grp v2)]))

19:27 justin_smith: (inc chouser)

19:27 lazybot: ⇒ 19

19:27 amalloy: chouser: works, but i like cgrand's version on stackoverflow better. avoids traversing the whole input multiple times

19:27 irctc_: amalloy: that looks like the one.. thanks.

19:28 * chouser nods

19:28 chouser: though you rebuild the root map once for every element instead.

19:29 irctc_: chouser: thank you. will check that out too!

19:29 chouser: neither is cleanly parameterized on the set of keys to be extracted. bit of a shame.

19:30 hiredman: with some work you can turn cgrand's approach in to a transformation of a reducing function, and etc etc

19:30 http://aphyr.github.io/tesser/tesser.core.html#var-group-by

19:30 amalloy: chouser: it's pretty easy to do that for cgrand's, though. yours isn't obviously possible to do that with

19:31 chouser: well, yes, generally if you have a solution from cgrand I'd go with that.

19:31 amalloy: wow how has cgrand's answer been there for so many years and the parens don't even balance

19:32 oh i guess it's only last year

19:34 danlentz: should I just always use (defn foo ^Thing [] …) instead of (defn ^Thing foo [] …) ?

19:34 hiredman: no

19:34 danlentz: only primitives?

19:35 hiredman: you shouldn't do either until you've yelled at someone who can get patches in for a while

19:35 danlentz: in reading lein-eastwood I found out that all of my (defn ^long foo [] …) were not correct

19:35 hiredman: yeah

19:35 for primitives that is correct

19:35 danlentz: so that is a pisser

19:35 amalloy: https://www.refheap.com/4d7acc00d8cbdf6e67afe77c2 - cgrand's answer, parameterized for the keys to index on

19:36 hiredman: ,(doc clojure.set/index)

19:36 clojurebot: Huh?

19:36 hiredman: clojurebot: jerk

19:36 clojurebot: you cut me deep, man.

19:36 justin_smith: ,(require 'clojure.set)

19:36 clojurebot: nil

19:37 justin_smith: (doc clojure.set/index)

19:37 clojurebot: "([xrel ks]); Returns a map of the distinct values of ks in the xrel mapped to a set of the maps in xrel with the corresponding values of ks."

19:37 danlentz: but (defn foo ^x.y.Thing [] ….) is correct, according to the eastwood page on :wrong-tag

19:37 hiredman: :/

19:37 danlentz: so wouldnt it be best to always just use type hints in that position and to just fully qualify them if needed?

19:37 for consistency?

19:38 hiredman: danlentz: I am looking at the page for wrong tag, it says (defn foo ^x.y.Thing [] ….) is incorrect

19:39 is that what you meant?

19:39 danlentz: hilariously it was an attempt to bring consistency that left us in this state

19:40 danlentz: i’m kind of more bothered by this than most other rought edges ive run into

19:40 i mean, this seems actually crazy

19:41 amalloy: danlentz: a lot of totally crazy things are explained by "historically x was true, so this crazy thing y made sense at the time"

19:41 danlentz: ;; no warning for this since it is fully qualified

19:41 (defn linklist3 ^java.util.LinkedList [coll] (java.util.LinkedList. coll))

19:42 which one came first? putting the return type on the var?

19:42 amalloy: yes

19:42 danlentz: is the history of this written up somewhere?

19:42 hiredman: danlentz: I think you are confusing two different warnings about tags there

19:43 danlentz: well, two warnings but i dont think i have them confused

19:43 hiredman: danlentz: eastwood may warn about them in the same linter, but the full qualified classname is an entirely distinct issue from where the tag goes

19:43 danlentz: no not exactly

19:43 amalloy: hiredman: is it?

19:43 danlentz: because if the fully qualified classname is not supplied

19:44 for meta on argument vecotr, then it will cause an error when used in another namespace

19:44 amalloy: my understanding is that if you put a fully-qualified classname on the arglist, it works "as intended", but an unqualified classname throws exceptions or something later

19:44 irctc_: amalloy: many thanks for the rewritten function on refheap!

19:44 hiredman: Oh of course, and that is the mess left by the attempt to unify them

19:44 danlentz: using fully qualified classname as tag on the argument vector resolves the issue

19:44 amalloy: right

19:45 danlentz: it is something that at very least would be really helpful to do a better job pointing out n the official clojure docs

19:45 warn you that something unexpected is lurking

19:45 justin_smith: this reminds me of the repo I made to try to disambiguate this stuff

19:46 I should work on that again soon

19:46 danlentz: i kind of like the dunaj syntax approach myself

19:48 so, type hints on the argument vector — are they

19:49 so when I type hint an argument vector to indicate return value — is that “first class” metadata? If it is not associated with a var, would it be possible to introspect back out the return value type hint of a function?

19:49 i can’t get at it with (meta var) obviously

19:55 qqq: !hello

19:55 !list

19:58 oskarkv: Hey! I just pushed this https://github.com/oskarkv/map-regexps Feel free to critique and comment about anything, it's my frist public lib

20:00 dnolen: inf-clojure can be made to work w/ ClojureScript, https://github.com/clojure/clojurescript/wiki/Emacs-%26-Inferior-Clojure-Interaction-Mode

20:01 TEttinger: that looks handy, oskarkv

20:01 dnolen: with a couple of tweaks to ClojureScript and couple of tweaks to inf-clojure could probably be made to work great

20:01 oskarkv: TEttinger I'm glad you think so :)

20:01 danlentz: oskarkv: this is interesting, nice work!

20:01 oskarkv: thanks

20:01 TEttinger: one odd quirk: {} has a meaning in textual regexps that could be useful to have an analogue to

20:02 ,(re-find #"a{3}" "aardvark? aaaaaagh!")

20:02 clojurebot: "aaa"

20:02 oskarkv: Yeah

20:02 danlentz: what school are you doing clojure at, if you dont mind me asking

20:02 TEttinger: yeah, I'm also curious

20:02 gfredericks: TIL inf-clojrue

20:03 oskarkv: Royal institute of technology, sweden

20:03 bendlas: oskarkv: does it nest? like, can keys and values be regexp?

20:03 TEttinger: that's a good question, bendlas, since regular text regexps don't have a concept of nested strings

20:04 oskarkv: bendlas No, but maybe one could make it so

20:05 bendlas: oskarkv, TEttinger, yeah, I think it's kind of curious to have a grammar of concatenative (regexp) over context-free (maps)

20:05 TEttinger: oskarkv, yeah I think if this handled more than just sequences of maps, it could be more generally useful, but already it's a fairly novel technique to what previously was an annoyance in clojure code

20:05 *to solve what

20:06 bendlas: oskarkv: I like that you expose run-single-step. too many parsers overlook the need for incremental parsing

20:06 oskarkv: Right now keys are compared with =, but it would be easy to check if the key is a fn, it could instead apply that fn as a predicate

20:06 danlentz: so, I could use this to specify a path grammar over a graph?

20:07 oskarkv: danlentz I'm afraid I'm not sure what you mean

20:08 TEttinger: it could be useful to support just plain ol sequences of non-collection values.

20:08 oskarkv: TEttinger yes, that would probably be farily easy to do

20:09 But for [] and {}, maybe we need new metacharacters if they are clojure literals instaed

20:10 bendlas: oskarkv: a non-string based DSL might also be an option, since in clojure you already have powerful data literals

20:10 TEttinger: true

20:10 bendlas: IIRC, cgrand has done a regexp parsing dsl in clojure

20:12 danlentz: i dont purport to fully grok why, but I seem to recall reading on clojars that the org.clojars.oskarkv group recommended for private forks?

20:12 oskarkv: Hm, non-string based DSL, what kind?

20:12 danlentz oh, maybe

20:13 amalloy: org.clojars.yourname is for you; use it however you want

20:13 bendlas: oskarkv: https://github.com/cgrand/regex

20:14 danlentz: “Personal groups are designed to hold things like throwaway alpha versions and forks of other projects. They’re long and ugly on purpose to encourage official releases to use canonical groups.”

20:15 https://github.com/ato/clojars-web/wiki/Groups

20:17 bendlas: oskarkv: you can do that kind of dsl pretty easily in any functional language, based on applicative/monadic parsing, but I'm not entirely sure how that ties in to the notion of a vm-based model of regexps

20:18 oskarkv: bendlas If I understand correctly, with cgrand's lib I can make REs out of data, but then use them on text as with regular regexps?

20:19 bendlas: oskarkv: yes

20:19 amalloy: bendlas: what does all this have to do with virtual machines? (which i think is what you mean by vm)

20:19 oskarkv: Anyway I imagined that my lib would be used to search for patterns in logs, etc

20:20 danlentz: state machine

20:20 ?

20:20 oskarkv: amalloy I based my implementation on this http://swtch.com/~rsc/regexp/regexp2.html

20:21 bendlas: that's what I'm not sure about, but my I guess so

20:22 you mentioned the Russ Cox paper "the virtual machine approach" and my intuition was, that this must be the alternative to doing a monadic parser

20:22 danlentz: related, have you looked at clj-rpe?

20:22 bendlas: erm, amalloy, oskarkv mentioned it on the gh readme

20:23 oskarkv: Hm, I'm not sure what a monadic parser is. But the parsing step is already done by the time that VM stuff comes along

20:23 ...in my lib

20:23 danlentz: vm = state machine, though.

20:24 oskarkv: Yes, more or less

20:24 bendlas: in a monadic parser, you define a parser monad which holds you parser state, like read ahead, and then your parsers are monadic values. monadic bind usually means concatenation

20:24 danlentz: this is a good article, thanks for pointing it out

20:25 bendlas: then you build up your grammar with combinators

20:26 oskarkv: what's the vm stuff that comes along in your parser?

20:26 danlentz: bendlas: your explaination reminds me of: “Wadler tries to appease critics by explaining that "a monad is a monoid in the category of endofunctors, what's the problem?"

20:27 http://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html

20:27 oskarkv: bendlas the parser just parses the RE into an AST. But after that you need to make some machinery to actually use it on the input string to match stuff

20:27 bendlas: danlentz: not every functional language, though ;-)

20:29 danlentz: I see your point, I guess the beauty of it is, how a really generic operation like m-bind can mean parser concatenation

20:29 oskarkv: bendlas so the VM stuff is like a NFA that you read about in automata theory

20:29 bendlas: kind of like how matrix multiplication can mean translation/rotation/scaling/shearing in one

20:32 creese: Can someone comment on the advantages of macros over code generation?

20:33 bendlas: oskarkv: I see, so I guess in a (m-word) parser, the AST is already given by the source language but I really have to read up on some theory, to get a grasp on how an NFA maps over

20:33 justin_smith: creese: macros can use the higher level facilities of the language for operating on collections, while code generation is typically limited to string munging

20:34 creese: for example, we don't need to make any special effort to prevent adjacent symbols in a macro combining to form an erroneous third symbol

20:35 oskarkv: bendlas I'm not sure about monadic parsers, but I always thought that a parser parses the input text (source code, regexp, etc) into an AST, according to a given grammar. But, just as in compilers, you are not done after parsing. You have code generation left.

20:36 amalloy: oskarkv: a parser doesn't have to use characters as its input type. bendlas is talking about a "parser" whose input type is the maps you're trying to match

20:36 creese: justin_smith: makes sense

20:37 bendlas: oskarkv: do you mean in this case, parsing the definition of the parser and then generating code to actually parse the input language?

20:37 creese: justin_smith are macros in clojure evaluated at run-time or compiled?

20:37 justin_smith: creese: compiled only

20:37 bendlas: amalloy: that. characters are just the sole input type for a subset of parsers

20:38 justin_smith: creese: though in jvm clojure the compiler is always present at runtime, if that's really needed

20:39 creese: I'm wondering how I can have a macro fed by params from a config file and not pay any penalty for that at run-time

20:40 does it recompile when I change the config parameter and reload?

20:40 justin_smith: creese: if the config file is available at compile time, it should just work

20:40 creese: it isn't

20:40 it's read at run-time

20:40 when the app starts

20:40 justin_smith: creese: no, there is no automatic recompilation in clojure

20:40 amalloy: creese: you can't. how could a macro run at compile time modify your source code based on the information available in config files at runtime?

20:40 justin_smith: creese: app start is compile time, if you haven't loaded all your namespaces yet

20:41 but yeah

20:41 bendlas: oskarkv: so in a monadic parser, you basically try to reuse as much of you host language as possible. meaning you define the parser syntax in terms of the host syntax and then try to get the host compiler doing the parser generation for you. Then the input language can consist of a stream of characters, or whatever it is you are trying to parse.

20:41 oskarkv: bendlas Well in my case, I have a grammar for the REs. And I use a parser generator (once) to generate a parser for the REs. Then from the AST of a particular RE, I construct a VM that does the matching. The input map sequence does not need a parser, because they are not arranged in any special way.

20:42 justin_smith: creese: also, there's nothing a macro can do that a function can't, except for syntax (including "not evaluating some arguments" as syntax here)

20:44 catern: argh

20:44 argh argh

20:44 argh

20:44 argh

20:44 okay, so, if I want to do something that is really comfortable in Clojure

20:44 and I don't want to write a web app

20:44 oskarkv: bendlas ok, I see.

20:44 catern: what should I do?

20:44 raspasov_: justin_smith: yea I was always wondering, how is passing a fn1 to a fn2 for fn1 to be executed later different from a macro? (except for the syntactic nicety about it) ?

20:44 justin_smith: raspasov_: exactly

20:44 catern: (i.e. what is something else really comfortable in Clojure)

20:45 (inb4 nothing)

20:45 bendlas: catern: logfile processing

20:45 catern: bendlas: is that a joke?

20:45 justin_smith: catern: graph / data analysis.

20:45 raspasov_: justin_smith: I mean, yea there might be some perf overhead, but that would be the passing of a fn pointer to a fn

20:45 catern: justin_smith: as in, graph algorithms?

20:45 raspasov_: which probably nears zero

20:46 catern: I could do more incanter stuff I guess

20:46 justin_smith: catern: as in working on a bunch of data in a graph.

20:46 catern: justin_smith: ok

20:46 justin_smith: so yeah, partially graph algorithms, sure

20:46 catern: er

20:46 ok

20:47 justin_smith: anything server oriented with a long uptime

20:47 raspasov_: justin_smith: not being a macro expect myself, I have been preferring passing a fn to a fn instead of writing a macro, I feel it makes the code easier for me to understand, and for people later on I hope

20:47 bendlas: oskarkv: ok and how do you tie in the once-generated RE parser into a particular VM?

20:47 raspasov_: justin_smith: and more composable

20:47 bendlas: (inc raspasov_)

20:47 lazybot: ⇒ 1

20:47 justin_smith: raspasov_: yes, this is all true

20:48 (inc raspasov)

20:48 lazybot: ⇒ 2

20:48 justin_smith: bendlas: lazybot doesn't know that raspasov_ and raspasov are the same person

20:48 bendlas: justin_smith: yeah, that's the problem with pointer based equality ;-)

20:49 justin_smith: bendlas: it's string based actually, mongodb

20:49 raspasov_: justing_smith: thanks, I'm glad I got something right :)

20:49 bendlas: justin_smith: well, all pointers are strings in memory

20:49 oskarkv: bendlas The parser (a function in my case) returns the AST. Then I have a function `compile-re` that takes it and returns a set of instructions for the VM. But the VM is pretty simple (just a few functions) that take those instructions and run them on the input map seq.

20:50 raspasov: corrected nickname :)

20:51 bendlas: (inc raspasov)

20:51 lazybot: ⇒ 3

20:51 bendlas: there you go

20:52 raspasov: bendlas: thanks, I didn't do much :)

20:52 bendlas: yay for (fn [a] (fn [b] ))

20:52 that's exactly the point. I hate it, when programmers do too much to solve a simple problem

20:53 raspasov: bendlas: haha, that's very true

20:54 all that being said, macros definitely have their place, I mean a lot of Clojure is written in it, it's just that I think you really need to be sure that the macro that you're writing has value beyond your own few namespaces, otherwise it would just be there to confuse people I feel like

20:54 creese: justin_smith: thankx

20:54 raspasov: written in them*

20:54 bendlas: oskarkv: cool, I'll have a look at the instruction set of your VM and will definitely read the paper.. interesting stuff

20:58 raspasov: sure, some of my best friends use macros ;-)

20:59 joking aside, the latest case where I needed them was, when the alternative was writing a hundred little wrapper functions, by hand, based on some documentation, where I could just generate them with a macro based on reflection

20:59 raspasov: bendlas: haha

21:00 bendlas: yea that's a good example

21:00 bendlas: and boy was I glad to have them then

21:29 oskarkv: bendlas_mobile https://www.refheap.com/98920

21:47 bendlas: oskarkv: ok, that instruction sequence looks like a code generator could optimize the living hell out of it. OTOH, from just glancing, I find it kind of hard to get a grip on the various magic numbers

21:47 but I guess that's the way of things with low-level representations

21:55 oskarkv: bendlas optimize how? The numbers are just indices into the sequence of instructions itself

21:56 except for the save ones :P

21:57 justin_smith: oskarkv: it's like the difference between an interpreter and a compiler - the same info that you use in the form of numeric indexes, could be converted to remove a level of indirection and get put directly on the execution stack

21:59 oskarkv: justin_smith yeah

22:02 bendlas: justin_smith: well put

22:03 oskarkv: I'm not sure how I would do that. Do you know something I could read?

22:05 bendlas: not sure, maybe documentation of your target byte code: x86? llvm?

22:05 justin_smith: oskarkv: hmm... not sure what the best resource for that would be. Probably not the asm.java docs (though this is the tool clojure uses to accomplish that task)

22:05 oskarkv: Or, maybe I just don't understand exactly what you mean. Converted how exactly?

22:05 bendlas: or yeah, jvm

22:06 oskarkv: Ok

22:06 justin_smith: oskarkv: it's the concept of compilation, instead of writing code that looks up the next step, then executes it, you generate bytecode representing the series of steps, and the program just executes them one after another

22:06 you could also convert the state machine into a function, and let clojure do the compilation part

22:07 by lifting out the variables to be args, and then putting the steps in sequence

22:07 bendlas: partial evaluation might also be a worthwile avenue

22:08 oskarkv: Ah, I see

22:08 Will have to think about it

22:22 bendlas: oskarkv: also, if you implemented nesting (regexes as keys/values), I suspect there were some deep insights to be had from how { and } would correspond to push and pop on the execution stack

22:24 oskarkv: bendlas perhaps ;)

22:25 But right now I'm looking for some problems that people even just might solve with my lib, so that I can claim it's useful. I really need it to get this school thing done :P

22:26 Opimizing by compiling more seems fun though

22:28 amalloy: if you want to optimize by compiling, in a lisp it's a lot easier than generating bytecode directly with asm. you can just generate the sexprs for a function body, and then eval the function

22:28 oskarkv: Yeah

22:29 justin_smith: yeah, that's what I meant by letting clojure do the compilation part

22:29 bendlas: yup, IMO that's the real use case for eval

22:30 (apart from repl)

22:36 justin_smith: bendlas: speak for yourself, I find the rpl perfectly useful

22:36 (aka "cat")

22:38 bendlas: yeah, nothing like going from lazy-seq to transducer and back ;-)

22:39 justin_smith: maybe we should call it ripl: read-identity-print-loop

22:43 just as long as nobody starts going full circle and call it a 'disruptor'

22:44 justin_smith: mace of disruption, most powerful weapon against undead

22:44 bendlas: :-)

22:45 ring of fire, baby

23:58 chr15m: hello, this is probably a stupid question, but does anyone know how, in vim, to gather any loose closing parentheses in a block onto the end of the last line?

Logging service provided by n01se.net