#clojure log - Mar 26 2014

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

1:23 startling: It seems like rebindings of dynamic variables don't persist past protocol method calls, is that true? why? can it be avoided?

1:27 oh, no, I'm wrong. I see why, though.

1:29 I pass a function that uses a dynamic variable to 'map'; when this function gets called, it sees the original value of the bound variable. Can this be avoided?

1:32 example: https://gist.github.com/startling/9777360

1:34 I suspect the answer is "make a pull request that judiciously eliminates all use of dynamic variables".

1:37 arrdem: startling: yep, dynamic vars tend to be a major code smell

1:39 ddellacosta: startling: as arrdem says...I have rarely found a situation where a dynamic var was the right choice. More to the point, using pure functions as much as possible helps being able to reason about your code, tremendously.

1:39 startling: ddellacosta: I agree 100%

1:39 alas, I'm using other peoples' code.

1:39 ddellacosta: startling: ah, gotcha

1:39 arrdem: startling: yeah PR that shit when you get time to fix it

1:40 startling: that's one thing I've been bad about lately, use a lib, don't like its design, spend the first two days rewriting it and then do a "fixed yo shitz" pr

1:42 ddellacosta: arrdem: that's kind of problematic though, 'cause I hate spending time on a pull request before I've had a chance to hash it out with the lib author. If they don't accept your fix for any reason it may be a waste...

1:42 arrdem: I mean, still a good thing to do generally speaking

1:42 arrdem: ddellacosta: sure.

1:42 ddellacosta: if I ever do finish cloutjure one thing I wanted to get to was library clout

1:42 startling: well, this is a pretty clear-cut bug, so I'm not that worried about it.

1:43 I *am* worried about the author being MIA, considering the last commit is 2 years old.

1:43 arrdem: startling: which lib?

1:43 startling: https://github.com/lancepantz/clj-yaml

1:43 lancepantz: hey

2:11 lancepantz, I PR'ed a fix to clj-yaml; if you don't want to deal with it I'd be happy to take over maintenance.

2:24 TEttinger: SnakeYAML wasn't exactly a high-performance library last I heard. someone mentioned taking 10 seconds to parse config files (he was using scala with no wrapper around SnakeYAML IIRC), but he had a fairly old computer

2:24 (we're talking under 1 MB config I think)

2:25 startling: TEttinger: do you have a recommendation?

2:26 TEttinger: unfortunately no, other than use EDN...

2:27 startling: TEttinger: that's not an option for us, unfortunately.

2:27 TEttinger: I helped the guy I'm talking about look for a replacement and couldn't find anything

2:27 YAML's grammar isn't exactly simple is it...

2:27 socksy: so in clojure, what's the idiomatic way for doing something like mean squared error? In an imperative language I would have a mutable variable and keep adding to it. This feels like bad practice in clojure

2:28 startling: TEttinger: heh

2:28 arrdem: socksy: map and reduce are gonna be your friends

2:28 gfredericks: ,(def square #(* % %))

2:28 clojurebot: #'sandbox/square

2:29 gfredericks: ,(->> (map - [1 2 3] [4 5 6]) (map square) (reduce +))

2:29 clojurebot: 27

2:29 arrdem: gfredericks: you're missing a (/ (count))

2:29 gfredericks: yep

2:31 socksy: there's a confounding problem, in that this is being passed as a function to a map. So effectively I already have a function acting as map, called "read-and-do", which is a convenience function around with-open, which takes a function to do to each line

2:32 arrdem: socksy: there's your problem

2:32 socksy: indeed

2:32 arrdem: socksy: you want to read _all_ your input and build one datastructure

2:32 socksy: then you take _all_ that data and transform it

2:32 socksy: iterate until you've got the result you want

2:32 socksy: that's nice and all, but my data is generally bigger than my RAM

2:33 though I suppose I could load it up on to a large AWS instance

2:33 arrdem: then you need to leverage lazy evaluation to achieve streaming computation.

2:33 which in many cases you'll just get magically if you write idiomatic code.

2:34 gfredericks: well

2:34 resource management isn't magical

2:34 socksy: i don't see how idiomatic code gets around the fact that "slurp" puts everything into a string?

2:34 gfredericks: right

2:34 you don't use slurp

2:35 you use line-seq

2:35 or something

2:35 you just have to be sure that you've consumed the whole thing before your with-open finishes

2:36 socksy: my read-and-do is a very basic wrapper around line-seq because i found myself typing that code out repeatedly :)

2:36 gfredericks: sure

2:37 is there something still unclear about this? I've lost track of the question

2:38 arrdem: gfredericks: resource management to not blow ram

2:38 gfredericks: (with-open [r ...] (->> (line-seq r) (map parse-somehow) (map ...) (reduce ...)))

2:38 socksy: well, more just an idiomatic way to make this into a map function

2:39 gfredericks: I wrote most of MSE as map/reduce above

2:40 socksy: indeed, thanks! But what does your code mean when you say "map parse"? line-seq is lazy, and map is doing it lazily, and then you map that into a different map?

2:40 wait, scrap the last bit

2:42 gfredericks: the mapping is lazy, the reduce forces the whole thing; but neither the whole original seq nor the intermediates are ever in memory at once

2:42 which is of course exactly what laziness is buying you

2:42 socksy: aha, so it's still a lazy construct by the time of the second map

2:43 and hopefully the reduce will cause it to execute before closing the file

2:43 right, I'll play around with that, thanks for the help!

2:50 startling: lancepantz, another PR; this one's a security issue.

2:53 bob2: <3 clojuring

2:58 nwolfe: Anybody working with Omchaya or is there a more appropriate place to ask this?

2:59 Ha I bet the clojurescript channel would be the better place.... :D

3:00 amalloy: startling: i don't think lancepantz really reads IRC much. he'll just notice the github notification probably

3:00 gfredericks: you're on irc at clojure/west? or went home already? (that's what i did)

3:01 startling: amalloy, there are a number of other open PRs, I mentioned it here on the off chance he was around.

3:03 gfredericks: amalloy: I'm did not go home already

3:35 Frozenlock: I think the cljs advanced compilation is screwing up something here... https://www.refheap.com/65821

3:35 Any advice?

3:39 amalloy: Frozenlock: if you don't have externs defined for the jquery plugin or whatever you're using, the closure compiler will rename all dot-interop methods to save characters. but since it's not actually rewriting the jquery code itself, the chosen name doesn't exist there

3:39 Frozenlock: Ah right.... that's the aget/aset thing, correct?

3:39 amalloy: so i think you either need externs, or to use something like (.apply (aget foo "modal") foo "show")

3:40 i don't recall the details, since i don't use cljs, but i presume that's enough to make sense to you

3:40 Frozenlock: It does, thank you very much.

3:51 luxbock: I'd like to define a couple of helper functions in my profiles.clj and then inject them into clojure.core with vinyasa. does anyone know if there's a way for me to do this without having to define the functions in their own separate namespace/library of their own

3:53 at first I tried defining them as normal in :injections, and then using vinyasa.inject/inject to inject those functions from the user namespace but that didn't work

4:10 beamso: i didn't realise there was a lein survey out

4:14 zachmassia: I'm working on converting some js code over to cljs, and wondering if there is a better / cleaner way to write this: https://gist.github.com/ZachMassia/0cc4675b1ce7bbe6746c

4:20 beamso: maybe inc and dec instead of + and -?

4:22 zachmassia: beamso: Good call, that will clean it up a bit. Apart from that it's fine though? Fairly new to clojure and functional programming

4:24 beamso: looks okay to me

4:24 from a weird perspective i hate the change from > to < and back again

4:25 but i also hate the .js file leaving off curly brackets for the if cases so :/

4:27 Frozenlock: What's the difference between using an atom and transcient/persistent?

4:27 zachmassia: Heh, didn't write the js :P, but now that you mention it I think I might move that last when up with the first one to keep it symmetrical

4:28 beamso: zachmassia: it's more that it jumps back and forth between less and more

4:28 not the ordering of the tests

4:29 Frozenlock: http://stackoverflow.com/a/15722398

4:29 Frozenlock: Thanks

4:34 zachmassia: Would this be a case where a transient is appropriate? I didn't really use it for the performance gains here

4:38 Frozenlock: ,(let [[i j] [4 5] size 5] (for [x [-1 1] y [-1 1] :let [new-x (+ i x) new-y (+ j y)] :when (every? #(< % size) [new-x new-y])] [new-x new-y]))

4:38 clojurebot: ([3 4])

4:38 Frozenlock: https://www.refheap.com/65834

4:39 (or something like that...)

4:43 zachmassia: Hmm, initially that seems harder to read

4:44 Frozenlock: Really? o_O

4:46 zachmassia: lol, I'm still getting used to the lisp way of doing things

4:48 I'm attempting to port http://cjlarose.com/2014/01/09/react-board-game-tutorial.html over to om

4:49 Frozenlock: zachmassia: You might want to give reagent a try (especially if you are beginning with clojure) http://holmsand.github.io/reagent/

4:53 mpenet: zachmassia: atoms vs transients: one is a mutable ref the other is just an optimisation for performance (that you should never bash in place, which is what you were probably thinking of doing)

4:53 http://clojure.org/transients

4:55 zachmassia: Frozenlock: I came across Reagent last week I believe. Any reason you suggest it over om?

4:56 mpenet: Ya, I think I'm probably focusing too much on directly porting the logic from the js code instead of the overall result

5:02 locks: zachmassia: https://github.com/levand/quiescent#rationale

5:09 zachmassia: locks: Interesting read, thanks for the link :) I'll make sure to bookmark that one

5:10 locks: yeah, it’s a nice overview of the three libraries

5:14 zachmassia: Frozenlock: Your snippet is giving me different results than the original fn: https://gist.github.com/ZachMassia/0cc4675b1ce7bbe6746c

5:20 vmarcinko: hello, noob question, i guess around data readers

5:20 i try to read datomic scehma.edn from my file

5:20 (read-string (slurp (io/resource "datomic/schema.edn"))) works OK

5:20 but when Iuse EDN reader

5:20 via

5:21 (edn/read-string (slurp (io/resource "datomic/schema.edn")))

5:21 i get error: No reader function for tag db/id

5:22 i thought reader functions are same for both clojrue reader and edn reader, no? and datomic jar has these readers registered for both, no?

5:23 reader function i meant for datomic jar

5:24 trap_exit: is there a way, in clojure, to forward declare variables _across_ namespaces ?

5:24 i.e. foo/cat and bar/dog mutualy call each other

5:24 is there a way to make this work?

5:24 (foo + bar are namespaces, cat +dog are functions)

5:25 noidi: if they're so closely intertwined, they probably belong to the same namespace

5:30 Pate_: what's the minimum code I need to "run" a fn in a .clj file?

5:30 do I have to have a -main fn?

5:30 xsyn: nope

5:30 you can execute from top down without lein boilerplating

5:33 Pate_: so (defn foo ...) (foo) in my-file.clj?

5:37 what's the shortest way to run a clojure file from the command line without using lein?

5:40 is there any help on installing cake on Windows?

5:40 clgv: Pate_: why not lein, the defacto standard build tool for clojure?

5:40 Pate_: does lein have a persistent jvm in the bg?

5:40 clgv: no. does cake?

5:41 Pate_: do I remember correctly that you are the one that wants to use clojure CLR in the powershell for devops?

5:42 dissipate: how do you get lein to load dependencies from outside a project folder?

5:42 mengu: would it make sense to have a clojurescript talk in a frontend conference?

5:42 Pate_: nope, not me. but that sounds like a cool idea!

5:43 apparently cake tries to keep a jvm around: https://github.com/ninjudd/cake/wiki/Persistent-JVM

5:43 clgv: dissipate: you usually need to specify everything as dependencies in the project.clj so that leiningen automatically adds the jars to the classpath. but there might be an option to specify classpath additions

5:43 Pate_: mengu, absolutely, esp. if you show Om.

5:44 dissipate: clgv, then what is the point of the ~/.m2 directory?

5:44 Pate_: I also found Drip, which supposedly works with lein to keep a JVM around for faster startup: https://github.com/flatland/drip

5:44 clgv: dissipate: ah thats the maven cache. anything in there is found when you add its maven coordinates to the dependencies declaration in yourproject.clj

5:45 Pate_: yeah and technomancy had some project for that as well. but I did not try any of them, so I can't recommend any ;)

5:46 dissipate: Pate_, have you tried POM?

5:46 Pate_: not familiar with pom

5:46 (clojure noob)

5:46 dissipate: Pate_, sorry, i meant Pomegranate. https://github.com/cemerick/pomegranate

5:47 clgv: pomegranate is just for adding dependencies on the fly to a running repl

5:47 dissipate: supposedly it allows you to load depedencies on the REPL so you don't have to reload the REPL

5:47 Pate_: that's cool

5:47 clgv: and is used in leiningen afaik

5:48 Pate_: but mind the warning in the readme "Please note that there are a number of scenarios in which add-dependencies will not work, or will not work as you'd expect."

5:48 Pate_: ok. so how do I get a persistent jvm running on windows for faster clj startup?

5:48 dissipate: clgv, so lein acts as a 'virtual environment' for a project as well?

5:49 clgv: dissipate: I am not entirely sure what you mean with 'virtual environment'

5:49 dissipate: i guess i'm a bit confused because in the python world 'pip' and 'virtualenv' are two different tools

5:50 AeroNotix: dissipate: dependencies are much better in the JVM world than they are in Python

5:50 Pate_: does Drip work on Windows? https://github.com/flatland/drip

5:50 AeroNotix: dissipate: maven allows you to have a myriad of the same library in your "site-packages"

5:50 when lein runs, it creates the JVM's version of PYTHONPATH each time

5:50 Pate_: drip keeps a fresh jvm around, instead of using a persistent jvm around, which can cause problems over time.

5:50 clgv: well a project should depend on a concrete version of the library it uses and leiningen pulls them in for you

5:50 AeroNotix: thus giving your library a "virtualenv"

5:51 dissipate: it works properly, unlike the hacks venv has to do to work.

5:51 dissipate: AeroNotix, i see. i'm starting to understand that lein is what are separate tools in other language ecosystems. :O

5:51 clgv: it is funny how you get the urge to run away screaming when someone explains you how dependencies and libraries work in GNU R

5:52 AeroNotix: dissipate: there's no downside to them being the same tool, in fact it works better

5:52 clgv: dissipate: well as AeroNotix pointed out the dependency approach is different

5:52 Pate_: (canonical Drip repo: https://github.com/ninjudd/drip)

5:52 dissipate: AeroNotix, yeah, it's pretty nifty. can't wait to publish my first project to clojars. :P

5:53 clgv: Pate_: drip seems very *nix-only from its readme

5:53 Pate_: :(

5:53 dissipate: i'm working on a RNG library that uses different sources of entropy and will have a better 'shuffle' function

5:54 Pate_: there's not a lot of C code, so could probably be ported to Windows.

5:54 or made cross-platform.

5:55 dissipate: my god, someone is porting AIXI to clojure!

6:01 Pate_: how do I write to stdout when I'm in a REPL?

6:01 (prn "test") ?

6:02 clgv: print/println

6:02 ,(println "Hello!")

6:02 clojurebot: Hello!\n

6:02 clgv: ,(prn "Hello!")

6:02 clojurebot: "Hello!"\n

6:02 clgv: prn/pr is for serialization to text

6:04 Pate_: how do I tell lein where to load Clojure from, after I downloaded and unzipped Clojure 1.6?

6:04 or do I just add it as a dependency to any project.clj and run?

6:04 Morgawr: Pate_: Lein uses its own Clojure, you don't need to download/unzip clojure yourself

6:05 just list clojure as a dependency of a project and it will be downloaded automatically

6:05 aka :dependencies [[org.clojure/clojure "1.6.0"]] in theproject.clj

6:05 the project*

6:07 BalkyDwarf: completely off topic(s) but I just came across this blog post and found it very well done and nicely simple: http://www.clojured.com/2013/04/writing-clojureclojurescript-web.html

6:08 Pate_: BalkyDwarf, nice post.

6:14 BalkyDwarf: Pate_: yeah it makes me feel like pedestal is not really needed... pedestal is too rails-like and springfuse-like for me...

6:14 Pate_: Pedestal is too big. It expounds on its simplicity, but it is too complex.

6:15 I suspect that Om combined with sente/http-kit will win the common Clojure real-time story.

6:17 BalkyDwarf: Pate_: oh ok, never heard of those... do they allow to make clojure + clojurescript webapps ?

6:18 Pate_: yes. Om is a ClojureScript integration on top of React. It blows away anything MV*: swannodette.github.io/2013/12/17/the-future-of-javascript-mvcs/

6:19 the immutable Cljs memory model makes React's virtual DOM diffs near O(1), as far as I can tell.

6:20 so you always re-render the whole "scene" or page, but the actual DOM changes are heavily batched and optimized. This lets you forget about state in the DOM.

6:20 BalkyDwarf: Pate_: thanks, sounds interesting. Does it provide some tools for client/server communication via ajax/websocket?

6:20 Pate_: no, that's where sente comes in

6:20 Morgawr: I personally prefer quiescent over Om, it's simpler and for my use cases (aka very simple web apps) it feels much easier to reason about, check it out if you don't know it :)

6:20 Pate_: sente lets you do realtime over core.async channels

6:20 Morgawr, had not heard of Quiescent.

6:21 Morgawr: https://github.com/levand/quiescent

6:21 BalkyDwarf: thank you guys

6:21 Morgawr: it's similar to Om in some ways but very different in others

6:21 Pate_: BalkyDwarf, and with an additional 13 lines, swannodette added undo to the "todo" example: http://swannodette.github.io/todomvc/labs/architecture-examples/om-undo/index.html

6:23 Morgawr, Quiescent looks really interesting. Also hadn't heard of reagent: http://holmsand.github.io/reagent/

6:34 deobalds: We're attempting to use clojure.java.jdbc without any libs on top of it. We're writing some tests which hit the db (just using clojure.test). We've written a fixture which wraps the test in a transaction so we roll back our changes to the test db, but clojure.test/use-fixtures doesn't seem to run if we run a test individually (M-c M-, in our case). Does anyone have any advice in this area?

6:37 BalkyDwarf: Morgawr: what do you use, if anything, alongside quiescent, for ajax / websockets? sense or core.async or something else?

6:39 Morgawr: BalkyDwarf: heh, I'm not much of a webdev, I just played around with quiescent (still a WIP to remake my site but exams have been slowing me down)

6:39 I know quiescent is pretty much made to work with core.async for channels

6:39 and that's what I'm going to use to propagate events

6:39 but that's it, really

6:40 BalkyDwarf: Morgawr: thanks!

6:55 random ranting: from devops perspective, I wonder which is a lesser evil - something extremely young like http-kit, or a dinosaur like tomcat. I guess ring+jetty is a good middle ground, but that feels too organically grown for some reason...

7:33 noidi: deobalds, I've just run (my-fixture my-test) in the REPL

7:34 I'm sure you can write a bit of elisp to do that for you. personally I wouldn't bother, given that recalling the previous entry in the REPL takes only a couple of keystrokes.

7:37 xyproto: When building clojure from source, with the intent of packaging it for a linux distro, is it better to use ./antsetup.sh + ant or mvn package?

7:38 readme.txt on github mentions both methods, but I don't know which method would be preferrable

7:38 *preferable

7:38 beamso: for a silly comparison, homebrew on mac os x distributes leiningen instead of clojure

7:39 xyproto: And is the topic correct, is it not 1.6.0 that is the latest release version?

7:39 beamso: it is 1.6.0 but i haven't seen anyone with ops

7:40 xyproto: beamso: all programming languages wants to use their own language-specific package manager. This looks like the best solution from the point of view from the respective languages. From the perspective of packaging packages for a distro, they should be all be packaged in a somewhat similar way. (Until someone does something sensible, like making a package manager where the language-related package managers

7:40 are included as plugins).

7:41 beamso: that's why I just can't package leiningen and call it a day, for now :/

7:43 beamso: yes and no

7:44 xyproto: how does one run maven in order to only perform the tests, after having built clojure?

7:45 beamso: mvn clean package should run the tests

7:45 xyproto: beamso: yes, but I only wish to run the tests

7:45 beamso: mvn test

7:45 xyproto: beamso: first build, then test

7:45 beamso: ok, thanks!

7:45 beamso: (in two separate functions in the package description)

7:46 beamso: in mvn, package depends on test

7:46 compile doesn't depend on test

7:46 xyproto: beamso: great!

7:46 beamso: testing it now

7:47 beamso: it looks like mvn calls out to ant anyway

7:48 xyproto: beamso: when run with "mvn test" it tries to compile clojure even though it has already been compiled with "mvn package -Dmaven.test.skip=true"

7:49 beamso: if the timestamps aren't being checked i can see that happening

7:49 xyproto: ok, but your answer didn't work

7:50 beamso: a) i've never compiled clojure before

7:50 b) i believe you're asking me why maven isn't working as you'd expect

7:51 xyproto: beamso: a) then why are you answering like you know the answer and b) it's not only maven, but the build system + configuration chosen by clojure

7:51 AeroNotix: Guys, chill

7:51 xyproto: AeroNotix: am chill :)

7:51 beamso: i'm simply using my knowledge of maven and looking at what i see in the github repo

7:52 xyproto: I blame myself for asking before researching. Thanks for the help.

7:54 beamso: TIL clojure is distributed compiled in debian

7:56 reQunix: Should someone update the topic since 1.6.0 has been released?

7:58 hyPiRion: reQunix: yeah

7:58 technomancy: you know what you have to do

8:11 mskoud: Topic need change :-)

8:16 clgv: does someone fill out a tally sheet of how often the topic remark occurs? :P

8:18 Averell: only 6 times since yesterday.

8:19 reQunix: It'll stop once the topic is updated... Consider it added motivation. : )

8:33 sm0ke: ,(java.util.Date. Long/MAX_VALUE)

8:33 clojurebot: #inst "292278994-08-17T07:12:55.807-00:00"

8:33 sm0ke: wish some one lives to face the end of timestamp problem

8:34 hyPiRion: That is not the timestamp problem

8:35 sm0ke: http://www.youtube.com/watch?v=-5wpm-gesOY is the "timestamp" problem

8:39 beamso: i thought the time problem was in 2037.

8:39 sm0ke: ,(java.util.Date. Integer/MAX_VALUE)

8:39 clojurebot: #inst "1970-01-25T20:31:23.647-00:00"

8:40 sm0ke: ,(java.util.Date. 0)

8:40 clojurebot: #inst "1970-01-01T00:00:00.000-00:00"

8:40 beamso: something like that one

8:41 sm0ke: ,(java.util.Date. -1000000000000)

8:41 clojurebot: #inst "1938-04-24T22:13:20.000-00:00"

8:41 beamso: oops. 2038.

8:41 http://en.wikipedia.org/wiki/Year_2038_problem

8:41 sm0ke: ,(java.util.Date. Long/MIN_VALUE)

8:41 clojurebot: #inst "292269055-12-02T16:47:04.192-00:00"

8:41 sm0ke: hmm look weird

8:43 ned-: does anyone know why this exception is being thrown ? http://pastie.org/8970117

8:50 beamso: for the earlier one, should it be (use 'clojure.contrib.duck-streams)

8:51 ?

8:52 and for the second, (:require [clojure.contrib.duck-streams :refer spit])

8:52 ?

8:52 clgv: yay apparently I build a dead lock when on my first attempt to build a thread-safe "require"

8:53 beamso: actually, (:require [clojure.contrib.duck-streams :refer [spit]])

8:55 hyPiRion: beamso: spit was integrated into Clojure core in 1.3.0 I believe

8:55 clgv: ,(meta #'spit)

8:55 clojurebot: {:ns #<Namespace clojure.core>, :name spit, :arglists ([f content & options]), :column 1, :added "1.2", ...}

8:55 hyPiRion: oh, even earlier

8:55 clgv: pretty close ;)

8:55 hyPiRion: I just remember that clojure.contrib was abandoned in 1.3

8:56 AimHere: I dread any language that doesn't just let me spit and slurp files as and when needed now

8:56 ned-: welp that explains it

8:56 beamso: oh. maybe that answer's ned-'s questions better.

8:56 ned-: wheres duck-streams now

8:56 hyPiRion: ned-: you can just use `spit` without requiring anything these days :)

8:56 ned-: hyPiRion: ooh thank you sir.

8:56 hyPiRion: I believe everything in duck-streams is in clojure.core

8:56 or in clojure.java.io

8:57 at least spit and slurp is in clojure core

8:58 clgv: I have an immediate mental image of "duck-streams", anyone else?

8:59 hyPiRion: clgv: http://i.imgur.com/FsxIVgT.jpg

8:59 clgv: hyPiRion: almost ,)

8:59 I'd imagine several ducks on the water^^

9:00 atyz: clgv: This? http://image.shutterstock.com/display_pic_with_logo/410935/410935,1278271292,5/stock-photo-a-pair-of-ducks-in-a-gushing-stream-56501821.jpg

9:01 clgv: atyz: :D

9:54 lnostdal: what's the difference between fn and fn* ?

9:54 CookedGryphon: fn* is an internal implementation detail, don't use it unless you're tweaking the language

9:55 lnostdal: yeah, i'm curious about what it does internally compared to fn

9:55 hyPiRion: lnostdal: ##(macroexpand-1 '(fn [[a b]] (+ a b)))

9:55 lazybot: ⇒ (fn* ([p__17884] (clojure.core/let [[a b] p__17884] (+ a b))))

9:55 lnostdal: i'm not using it directly; code like #(if % :x :y) will generate it

9:55 CookedGryphon: well for a start, I think it's defined in java

9:55 hyPiRion: one of the details

9:58 clgv: do we have a specialized string compare in clojure that compares strings starting with a number by that number?

9:58 I'd guess someone wanted that behavior already ;)

9:59 otherwise I'd hack it together via regex and parseLong

10:00 hyPiRion: clgv: what would happen if the string doesn't start with a number?

10:01 ,*clojure-version*

10:01 clojurebot: {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}

10:02 clgv: hyPiRion: that's definition, either lesser or greater than then ones with a number

10:02 hyPiRion: alright

10:03 clgv: hyPiRion: somehow similar to when I use (sort-by :id data-coll) and there might be no :id in some items

10:07 hyPiRion: ,(sort-by #(some-> (re-find #"^-?\d+" %) Long/parseLong) ["100 ten" "void" "103 foo" "-40 40"])

10:07 clojurebot: ("void" "-40 40" "100 ten" "103 foo")

10:07 hyPiRion: clgv: ^?

10:09 clgv: hyPiRion: looks good :D - guess it is to specialized for clojure.core.* namespaces ;)

10:09 CookedGryphon: is there a looping construct like this: https://www.refheap.com/66001

10:10 TimMc: clgv: As opposed to version number comparison?

10:10 CookedGryphon: i find myself writing loop, when-let, recur so often in this basic format with core async

10:10 clgv: TimMc: pardon?

10:10 hyPiRion: clgv: yeah, seems probably a bit too specialised. It's not hard to make yourself though :)

10:10 clgv: CookedGryphon: write yourself a "while" macro

10:10 TimMc: Well, numerical sorting in a file listing shares some properties with version number sorting, but it's not the same.

10:11 clgv: ,(doc while)

10:11 clojurebot: "([test & body]); Repeatedly executes body while test expression is true. Presumes some side-effect will cause test to become false/nil. Returns nil"

10:11 TimMc: and I was wondering which you wanted

10:11 hyPiRion: I just pad stuff with zeroes and use ISO 8601, then sort alphanumerically

10:12 clgv: ah ok. just plain numerical sorting. I have items with ids that usually start with numbers that have chronological information

10:31 CookedGryphon: Is there anything falsey in clojure to which I can attach metadata?

10:32 I have a function in my api which currently returns true or false depending on the success or failure of the requested operation

10:33 ambrosebs: CookedGryphon: no

10:33 CookedGryphon: it's nice and clean doing (when (operation ...) ...) but now I want to in some cases query the cause of the false answer, and exceptions completely complicate the flow of the functions using this api

10:34 clgv: CookedGryphon: you can invert the meaning as they do in C/C++ by returning error reasons (e.g. clojure maps) or nil on success

10:34 CookedGryphon: ugh, that's not nice or obvious to look at though...

10:35 perhaps if I had an appropriately named function... but still

10:35 clgv: well you only need a when-success macro

10:36 CookedGryphon: I wish you could attach meta to nils, it feels like you should be able to do some really nice error handling with current nil-punning behaviour, but if anything wants to examine the root cause of the nil being passed down they examine the metadata

10:36 clgv: btw. in the case of when you won't be able to look at the reasons of the error anyway ;)

10:36 CookedGryphon: then you get the stack benefits of exceptions and the ease of use of nil-punning

10:37 clgv: good point, but you could still use when for the trivial case, and then let out the value if you wanted to examine more closely

10:39 clgv: CookedGryphon: in SBCL you could do that with multiple return values. as long as you do not care you get only the first value and you have to do something special to get the other values...

10:41 CookedGryphon: clgv: what I'm talking about would go a little further than that, your caller doesn't need to care about your error directly, as long as it deals with nils nicely and passes on the same nil on a nil input it can't do anything with

10:41 but there's probably some major drawbacks I haven't considered

10:43 clgv: a pity there is no to-boolean protocol method ;)

10:43 you could have your metadata nil with it^^

10:51 ambrosebs: CookedGryphon: I don't think nil-punning is really worth worrying about.

10:51 CookedGryphon: I just make a predicate function and move on

10:51 if your solution works with nil-punning, great.

10:52 but meh

11:09 Morgawr: https://hackworth.be/2014/03/26/clojure-web-security-is-worse-than-you-think/ anybody read this?

11:24 cbp: Morgawr: yea

11:27 arrdem: Morgawr: yea

11:27 jph-: Morgawr, i wrote it

11:27 :P

11:27 Morgawr: jph-: good one :P

11:27 I'm watching the video talk now

11:27 jph-: i was really worried about how it'd be received

11:27 Morgawr: just felt the need to spread it around :P

11:27 jph-: i didnt want it to come across as shitting on clojure

11:28 and it's really just a few of my notes from aarons talk

11:28 Morgawr: when I read the title I was a bit taken aback but both the article and the talk on which the article is based on raise valid and solid points

11:28 jph-: but i figured it needed calling out

11:29 hyPiRion: jph-: Valid criticism is not shitting, it's important

11:30 jph-: if we hit rails-like popularity, we dont want rails-like security issues with it

11:30 Morgawr: or php-like (in)security :P

11:30 jph-: yep

11:31 BalkyDwarf: I wonder if these security concerns apply to pedestal

11:32 jph-: web security issues are fairly well understood

11:32 but if the controls aren't built in to address them

11:32 then by default, they're vulnerable

11:32 Morgawr: yeah

11:32 that's the problem, sane defaults

11:33 jph-: i link to the owasp testing guide and top 10 in the post, ask your web framework developers how the protect against them

11:33 s/the/they/

11:46 sdegutis: What's a good way to create some functions (representing third party services) that you will override with lightweight implementations during testing, and which you have to explicitly set to the real functions in production?

11:47 Bronsa: sdegutis: just use with-redefs when testing

11:48 mikerod: is there anything "easy" available to allow Clojure to .clj source from somethiing like a JarInputStream. :)

11:48 allow Clojure to compile .clj *

11:48 sdegutis: Bronsa: So use dynamic vars to hold all the functions related to this service, and alter-root-var them in production, and with-redefs them in testing?

11:49 Although if they're just going to be alter-root-var'd, I probably don't need them to be ^:dynamic.

11:49 Bronsa: why do you need to alter-var-root them?

11:50 sdegutis: I don't want them to be set to the real or fake services until I explicitly set them so during production.

11:50 This is to avoid accidentally forgetting to override them in tests, and ending up using the real services by accident.

11:50 Bronsa: oh ok

12:03 technomancy: jph-: did aaron's talk mention read-eval?

12:03 rkneufeld_: technomancy: He didn't mention it specifically, but he did touch briefly on injection attacks.

12:03 jph-: technomancy, i don't believe so

12:03 he kinda sped over injection imo

12:04 i almost included a section on what he said re injection

12:04 but in reality, it boiled down to "we have korma, but it isn't abstract enough, but we dont need an ORM"

12:04 so i was left scratching my head

12:04 and it didnt really get to nitty gritty re injection

12:05 technomancy: too bad; IMO the fact that you're just supposed to figure out that the reader isn't safe for user-provided data is trouble just waiting to happen

12:05 jph-: it did make me wonder how a user-input would be processed all the way into korma

12:05 ie if the old yaml issues with ruby applied to maps

12:06 compojure routes into functions into korma

12:07 technomancy: jph-: they do apply to the reader

12:07 older versions of ring used to use the reader for cookie storage

12:07 jph-: i haven't yet done much testing in that space... i'm still getting my head around the higher-level compojure architecture

12:08 technomancy: if people get that wrong even in ring, you can just imagine what actual apps in the wild are like

12:08 jph-: the other thing is that unlike ruby, there isn't really a 'security team' for clojure

12:08 since ownership of libraries is spread far and wide

12:09 TimMc: jph-: The HTML templating thing is my personal rant-in-a-can.

12:09 jph-: TimMc, in what sense?

12:09 too many?

12:09 or the security side?

12:10 TimMc: The security side.

12:10 Most of them are usnafe by default.

12:10 cbp: selmer is good against xss

12:10 xeqi: TimMc: hmm, I thought it was just hiccup

12:10 TimMc: Not just hiccup.

12:10 jph-: this is the kind of discussion i think the clojure community needs more of

12:11 otherwise clojure web apps will end up a ticking time bomb

12:11 ppl blindly assuming someone else has done the right stuff for us

12:11 cbp: But a lot of people like their templates to be vectors :-D

12:11 TimMc: cbp: You can have that and ahve it be secure as well.

12:12 check out the patch clojars uses on Hiccup

12:12 xeqi: TimMc: thats actually not 100% secure, someone found a bug in it :(

12:13 well, an unexpected interaction between nested params and it

12:14 I'd love to find time to take hiccup out of clojars entirely

12:14 and replace it with something safe

12:14 TimMc: xeqi: Oh, I'd like to see the bug and patch!

12:14 xeqi: along with many other things that take time ....

12:15 hyPiRion: xeqi: hey let's implement a Clojure version with fast startup time, port leiningen to it and all its plugins

12:15 xeqi: TimMc: my quick solution for clojars was to remove nested params, since we don't ever use it

12:15 hyPiRion: Takes a weekend tops

12:16 cbp: hyPiRion: arrdem was gonna implement "lean clojure" for GSoC

12:16 xeqi: hyPiRion: haha, are you making fun of satvvik's talk?

12:16 hyPiRion: xeqi: I'm not at west, so no =(

12:17 rasmusto: lean-clojure-nrepl-cider.el

12:17 sdegutis: I've been taking Clojure's vars and destructuring for granted, they're each pretty great.

12:17 felher: Hey folks. Would one sooner use '-' in longer namespace-names or '_'?

12:17 xeqi: hyPiRion: there are people that want to pursue this, rhickey, satvvik, and tbaldridge had a discussion around the gsoc plans for that

12:17 sdegutis: felher: - in the name, _ in the file

12:17 rasmusto: felher: - in the name-space, _ in name_space.clj

12:17 Bronsa: xeqi: hear hear

12:17 sdegutis: i won

12:17 felher: hehe :D

12:18 rasmusto: sdegutis: my answer had both examples

12:18 hyPiRion: xeqi: leaner as in on the jvm?

12:18 sdegutis: rasmusto: touche

12:18 felher: Thanks folks. :)

12:19 xeqi: hyPiRion: yep, think more static compiled for production stuff where you don't need to redef and such

12:19 hyPiRion: Ah, right

12:25 CookedGryphon: I have a proxy-super call in a proxy implementation, and it's eating 70% of my processing time in reflection

12:25 does anyone have a clue how to type hint it? It looks like (proxy-super onTouchEvent event)

12:26 so I have no idea where to hint the implicit this...

12:26 sdegutis: Leiningen handles -h placed after an alias, intercepting it from the function itself.

12:26 This was not expected behavior.

12:27 hyPiRion: sdegutis: yeah, it's a known issue

12:27 I think it's scheduled for 2.4

12:27 sdegutis: Oh.

12:27 technomancy: it's fixed in master

12:27 well

12:27 it still does that by default, but you can opt out

12:27 sdegutis: Ah.

12:28 I liked that feature all the way up until last night when I used an alias to shorten a command line utility I'm writing.

12:34 hyPiRion: technomancy: while you're here, you better do something like `TOPIC=$(echo $TOPIC | sed 's|1.5.1|1.6.0|g')` before people complain about the outdated topic in this channel again

12:34 technomancy: oh yeah

12:35 rasmusto: ,*clojure-version*

12:35 clojurebot: {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}

12:35 clgv: :D

12:35 seangrove: Has anyone else noticed that the topic is outdated?

12:35 rasmusto: ##*clojure-version*

12:35 seangrove: Ahhhh, damn

12:35 clgv: :P

12:35 * seangrove wanted to be the last one to complain before it was changed

12:36 * seangrove pulls out mavis beacon... "Better luck next time"

12:36 clgv: maybe it needs a rewrite as well. since 1.7/2.0 is not that near ;)

12:36 AmandaC: technomancy: I demand balanced news! I want the not-so-top analysis’s opposing opinion on the matter!

12:36 jcromartie: the penultimate analyst?

12:36 rasmusto: ##(prn *clojure-version* 'hmmm)

12:36 lazybot: ⇒ {:major 1, :minor 4, :incremental 0, :qualifier nil} hmmm nil

12:37 technomancy: AmandaC: depends, are you qualified as a not-so-top analyst?

12:38 Averell: the number exploitation must end. I predict versions will run out in the next 30 years.

12:38 justin_smith: ,*clojure-version*

12:38 clojurebot: {:interim true, :major 1, :minor 6, :incremental 0, :qualifier "master"}

12:38 rasmusto: justin_smith: why's lazybot on 1.4 still?

12:38 hyPiRion: clgv: 2.0 is not that near? I'm not sure, but I would've expected some news on that on the clojure-dev mailing list

12:39 Apologies for not understanding jokes

12:39 justin_smith: rasmusto: I think they intentionally leave them on the most recent two versions, but they have been *erherm* lazy in updating one of htem

12:39 rasmusto: justin_smith: was waiting for that :)

12:40 AmandaC: technomancy: nah, I’m a number denier. I refuse to accept numbers even exist.

12:40 AeroNotix: AmandaC: yo

12:40 justin_smith: clgv: hyPiRion: I like Knuth's versioning for TeX, where each release gets it incrementally closer to PI

12:40 AeroNotix: AmandaC: doing Clojure these days?

12:41 AmandaC: AeroNotix: and several other languages, yes

12:41 AeroNotix: AmandaC: cool!

12:42 patchwork: AmandaC: numbers don't exist, but they are useful

12:43 rasmusto: math has no applications outside of SAT testing

12:43 * rasmusto hides

12:47 justin_smith: rasmusto: nonsense! just the other day I proved there was a 1:1 and onto mapping from my monthly budget (idealized as a continuous income stream) and the sum prices of the inventory of the local musical equipment store

12:48 rasmusto: are you saying you bought everything in a music shop?

12:49 justin_smith: rasmusto: I justified doing so in theory, that was good enough :)

12:50 rasmusto: money is just a placeholder anyways, may as well replace it with guitar picks and midi keyboards

12:50 justin_smith: true enough

12:51 they are isomorphic at least

12:52 rasmusto: speaking of investing, am I the only one who isn't freaking out and cancelling my order RE that facebook/oculus thing?

12:53 jcromartie: rasmusto: it is really shocking

12:53 justin_smith: http://weareinstrument.com/labs/open-source/oculus-bridge my company may have played a small part in facebook finding the oculus rift useful :(

12:54 jcromartie: Facebook is just not where promising new technology goes to thrive.

12:54 patchwork: I am becoming increasingly weary of giant companies acquiring awesome things and destroying them

12:55 I heard that right after I heard about the demise of OpenNI

12:55 and primesense

12:55 justin_smith: patchwork: oh, that is sad

12:55 rasmusto: does it help that oculus is hardware+software and is so different from what facebook normally buys?

12:55 patchwork: glad I got my asus xtion when I did, you can't even find one anymore

12:56 jcromartie: rasmusto: it might help mitigate the awfulness

12:56 patchwork: Very curious to see what the result is… any way oculus can come out of this unscathed? I can't imagine it being used for anything awesome at this point

12:58 rasmusto: I went in for a ue4 subscription, I'm still damn excited about the new hardware

12:59 jcromartie: patchwork: well, if it's still a device that people can buy and develop for, with Carmack at the helm, it might be OK

12:59 but if Facebook steers the dev experience AT ALL, then I'd imagine it will pretty much be the beginning of the end of Oculus

12:59 patchwork: jcromartie: I will hold some measure of hope

13:03 S11001001: the Oculus team thanks you for going on this incredible journey with them

13:03 jcromartie: S11001001: stop it you are making me sad

13:03 mdrogalis: lol

13:12 rasmusto: any clojure/west must-see talk videos? I watched (and loved) the instaparse one

13:15 jph-: rasmusto, the security one

13:15 rasmusto: jph-: with-security? I'll queue it up

13:15 jph-: rasmusto, yep, that one

13:16 rasmusto: cool, thanks

13:24 pyr: hi clojure ! just dropping by because i'm really happy to release http://pithos.io today, an S3 compatible object store server written in clojure

13:27 cbp: (inc pyr)

13:27 lazybot: ⇒ 2

13:28 Raynes: (inc pyr)

13:28 lazybot: ⇒ 3

13:34 pyr: (btw if anyone deems it interesting, i'd love a few upvotes here: https://news.ycombinator.com/item?id=7474817

13:35 Jahkeup: very nice pyr!

13:35 (inc pyr)

13:35 lazybot: ⇒ 4

13:36 nickmbailey: cool stuff

13:37 pyr: what version of cassandra?

13:37 pyr: 2.0+

13:37 jcromartie: Neat

13:38 nickmbailey: pyr: which clojure client did you use?

13:38 pyr: alia, from mpenet

13:48 r1chard: http://www.youtube.com/watch?v=CBL59w7fXw4 <-- have you seen this "clojure.web/with-security"

13:48 I feel like there's some BS in that talk.

13:48 Not just feel, know.

14:00 jph-: good, call them out

14:00 i kinda think the speaker rushed through most of it, didnt really go into specifics for several areas

14:02 but i didn't spot anything obviously wrong, i just think some parts were glossed over

14:03 r1chard: Well first, you don't selectively escape or "strip" HTML tags in user input. That's a recipe for disaster.

14:03 Either you escape HTML entities, or you don't.

14:03 If you need selective support for, say, bold and italic, you need to go through a string DSL allowing only that.

14:04 HTML is full of edge cases, if you try to parse it, attackers will abuse the edge cases.

14:04 jph-: yep

14:04 like... what is it, there's 90+ ways of representing <

14:04 encoding

14:04 r1chard: Second, he's complaining that pass hashing libraries don't offer HMAC.

14:05 HMAC is for message origin codes, not for password hashes. Vastly different attacks. Vastly different approaches.

14:05 TimMc: ++

14:05 r1chard: Tacking on HMAC for password hashes feels like he has no idea why HMAC is used.

14:06 jph-: yes, i would have liked him to elaborate more on that point

14:06 r1chard: Third: "there are too many template engines and db vendors you guys. Let's just stop. Let's just stop." Uhmm okay? You go make people just "stop" their projects, what kind of a solutions is this?

14:06 technomancy: sounds like ryah

14:06 jph-: my recollection is he was complaining about multiple template libraries within projects

14:07 r1chard: jph-, I don't know. It's very arbitrary to just put a limit on a project what it'll use. Any bigger project is done in separate components, and one has to pick the right tools for the job.

14:07 technomancy: http://shitryandahlsays.tumblr.com/post/33834861831/but-who-decides

14:07 jph-: r1chard, well, the speaker is entitled to his opinion, as are you :)

14:07 shep-home: I've got this one hash, and it has a lot of data in it. When I print it to the REPL, it's big and slows down emacs. What are some options to customize the printing of that hash alone?

14:08 r1chard: jph- :D

14:08 jph-: r1chard, btw, i wrote the writeup of that vid that hit hn

14:08 :P

14:08 r1chard: jph- :D

14:09 Also the fact he's promoting ORM as better for DB security is making my heart bleed.

14:09 jph-: to me it sounded like a former ruby guy wanting better security in his new favourite language

14:09 well

14:09 the injection section was rushed as well

14:09 r1chard: ORM may speed up development, but that's hardly the only way to fix DB security.

14:09 jph-: "korma is ok, but it isnt enough but we dont need ORM but we need more abstraction"

14:09 hence why i left it out of my post

14:09 r1chard: :)

14:09 jph-: i didnt really have any takeaways

14:09 technomancy: aren't most of the rails DB issues stemming from the fact that people don't bother to learn SQL precisely because of ORMs?

14:10 * jph- yawns

14:10 jph-: well its 2am here, i shall bid you all adieu

14:10 technomancy: "learn how your database works" is better advice, not that people will follow it

14:10 jcromartie: technomancy++

14:10 oh sorry

14:10 (inc technomancy)

14:10 lazybot: ⇒ 101

14:11 tuft: 5 minutes into the talk and he hasn't said anything yet...

14:12 Bronsa: shep-home: *print-lenght* and *print-level*

14:16 shep-home: Bronsa: thanks! won't that truncate my output at some arbitrary position though?

14:16 Bronsa: yes it will

14:17 gfredericks: Bronsa: me and a few guys are at the clojurewest hackfest thinking about extending codeq to have usage analysis stuff (similar to the code I sent earlier)

14:17 and the major hitch compared to my earlier approach is that it might not be reasonable to actually eval the code

14:17 my guess is that this more or less precludes using tools.analyzer in a serious way -- can you confirm that's the case

14:18 Bronsa: gfredericks: there's no way to evaluate a whole file/namespace without evaluating each form as you go

14:18 how would you be able to macroexpand?

14:18 gfredericks: right but I'm thinking it's not possible to eval _at all_

14:19 at least if you want the analysis to go over the whole history of the project, because then you have lots of changing dependency sets

14:19 Bronsa: yeah I see where the problem lies

14:20 TimMc: shep-home: So, you can do things like (keys foo) and then select-keys

14:20 gfredericks: Bronsa: so should I give up trying to do something general and maybe have it start a separate jvm for each commit we want to analyze?

14:20 hiredman: gfredericks: it seems like that would be better built as a service a long side/on top of codeq

14:21 Bronsa: gfredericks: I honestly don't see why you would need tools.analyzer at all for this

14:21 gfredericks: hiredman: the first thought was to write a library that just interacts with the codeq db, adding usage info

14:21 hiredman: is that what you're thinking of?

14:21 hiredman: codeq indexes the codebase, then you can pick shas to feed in to this other service that checks out the sha and enrichs the data codeq has

14:21 yeah

14:22 gfredericks: Bronsa: the main thing we need is, given pieces of code, figuring out what vars it uses

14:23 Bronsa: gfredericks: I see. whichever way you want to do it, I don't think you're going to be able to go anywhere without evaluating the forms for macroexpansion

14:23 gfredericks: Bronsa: okay, that's what I was imagining

14:23 Bronsa: (defmacro x [a] (if (do-something-with a) `some-var `some-other-var))

14:24 there's no way to know statically if you're going to be using some-var, some-other-var or both

14:24 gfredericks: sure

14:24 shep-home: TimMc: To use those, I would need to know that /this/ is the big hash, right? And I have a big vector too, not just a hash :-)

14:24 gfredericks: hiredman: okay, so one commit at a time sounds reasonable to you too?

14:25 shep-home: I'd love to be able to "override to toString" for a single hash when I create it

14:25 Bronsa: gfredericks: btw I don't know if you were logging yesterday but I added analyze+eval to t.a.j which doesn't require you to do any eval manually && doesn't require you to generate a new env everytime

14:26 gfredericks: Bronsa: yeah, I saw that; thanks

14:30 hiredman: gfredericks: I think it would have to be

14:32 Bronsa: gfredericks: also, if you decide to use t.a, this seems like a good place to use datomic's datalog to query the ASTs, example https://github.com/clojure/tools.analyzer/blob/master/src/test/clojure/clojure/tools/analyzer/query_test.clj#L17

14:33 wei__: is there such thing as reduce-while?

14:33 rasmusto: (doc reduced)

14:33 clojurebot: "([x]); Wraps x in a way such that a reduce will terminate with the value x"

14:34 wei__: e.g. taking from a collection until the sum is a certain amount

14:34 rasmusto: wei__: ^^

14:34 TimMc: shep-home: Yeah. So you should bug gfredericks to write his giant datastructure visualizer. :-P

14:34 wei__: rasmusto: nice. does that also work with core.reducers?

14:35 rasmusto: wei__: I believe so? Though it may be a 1.6 patch that allows that

14:36 amalloy: reduced was added in 1.5

14:36 along with reducers

14:37 wei__: although really you don't need reduced for use cases like reduce-while - you can use reductions and take-while

14:37 wei__: rasmusto: mind pointing me to an an example usage?

14:37 oh yeah, reductions is lazy too right

14:37 andrzejsliwa: Hi guys, anyone using smartparens on emacs for clojure development? any sane defaults (to be more like paredit)

14:37 ?

14:38 rasmusto: wei__: ah, nvm about the 1.6 thing. This is what I was remembering http://dev.clojure.org/jira/browse/CLJ-1160

14:38 reductions + take-while is probably a better answer

14:38 amalloy: huh. what's better about smartparens than paredit, andrzejsliwa?

14:39 andrzejsliwa: I have it as default in my Emacs Prelude bundle

14:39 gfredericks: TimMc: do you solicit buggings on this issue every month or so?

14:40 amalloy: andrzejsliwa: well, reading over the docs, i'd suggest at least turning on smartparens-strict-mode

14:41 andrzejsliwa: and then use it with paredit?

14:41 amalloy: well, i think you're supposed to use one or the other

14:41 andrzejsliwa: some people mixing them... but I want to avoid it

14:42 amalloy: i'd just install paredit, because it's well known and has worked for decades(?). but if you're using smartparens, strict-mode will get you a behavior that i've found useful in paredit

14:45 rasmusto: wei__: some examples

14:45 ,(last (take-while #(<= % 10) (reductions + (range 30))))

14:45 clojurebot: 10

14:45 rasmusto: ,(reduce (fn [a b] (if (>= a 10) (reduced a) (+ a b))) (range))

14:45 clojurebot: 10

14:46 andrzejsliwa: thx for advice amalloy

14:46 wei__: so that's how you use reduced, thank

14:48 TimMc: gfredericks: Something like that yeah. *I* want that tool! :-P

14:49 $mail xeqi nested params appears to be a ring thing -- how was it causing a problem with hiccup?

14:49 lazybot: Message saved.

14:51 arohner: I'm having trouble googling for the alan dipert gherkin video mentioned in the mal video. Any suggestions?

14:51 gtrak: arohner: it's in the lightning talks

14:52 http://www.youtube.com/watch?v=bmHTFo2Rf2w

14:52 arohner: ty

14:56 aaelony: anyone using Kovasb's session (https://github.com/kovasb/session/tree/master/src/cljs/session) ? It looks beautiful, but shift-enter isn't evaluating expressions for me...

14:57 sorry, better link was : https://github.com/kovasb/session

15:06 gfredericks: TimMc: I've mitigated a small amount of the pain via my bg macro in my repl-utils

15:08 futile: Anyone here have experience embedding REPLy into a Clojure app?

15:12 TimMc: gfredericks: OWow does that help?

15:16 *How

15:17 DaReaper_: Is there any working plugin for clojure development on NetBeans?

15:18 or at least an editor?

15:20 hfaafb: there's counterclockwise for eclipse

15:20 nightcode

15:20 emacs

15:20 a few sublime text plugins

15:20 lighttable

15:22 yogthos: also cursive with intellij works pretty well

15:23 Anderkent: futile: kind of. What's your issue?

15:23 futile: I'm trying to figure out how to change the namespace when you call reply.main/launch-nrepl directly from within Clojure.

15:23 So far I have this, but it fails: (launch-nrepl {:skip-default-init true :custom-init (in-ns 'billow.core)})

15:24 amalloy: futile: you probably want to quote that custom-init form

15:24 futile: amalloy: I'll try that, although it looks like REPLy is pretty macro-heavy code. See https://github.com/trptcolin/reply/blob/master/src/clj/reply/conversions.clj

15:25 amalloy: Yes, that worked perfectly.

15:25 Thank you both.

15:26 Anderkent: no prob, next time I recommend just asking your question immediately, amalloy could have probably helped you even before I got here :P

15:26 futile: Yes, yes, very good ideas all around.

15:27 Next time I will ask my question directly. Also I will try suggestions before doubting them.

15:27 aaelony: quick update: shift-enter works for me in Chrome but not in Firefox...

15:29 DaReaper_: hfaafb: any for netbeans?>

15:35 futile: It appears that if you use REPLy with another namespace like that, you no longer have access to (doc). How would you get access back?

15:35 tpope: clojure.repl/doc

15:35 (use 'clojure.repl)

15:36 futile: Ah yes, thank you.

15:46 technomancy: amalloy: afaict smartparens' main advantage is that it can work with multi-char delimiter sets

15:46 which is neat for html, but pointless for clojure

15:47 dakrone: technomancy: well, useful for strings and maps in clojure

15:47 amalloy: technomancy: might be useful if it supports #{...} and #(...), i guess

15:47 technomancy: dakrone: hm; how so?

15:48 dakrone: technomancy: ah nevermind, I forgot clojure-mode adds paredit support for "" and {}

15:48 amalloy: dakrone: that's all in paredit, i'm pretty sure, not clojure mode

15:48 dakrone: in-sexp highlighting is a nice feature smartparens has that paredit doesn't

15:48 technomancy: strings work for any lisp already

15:48 amalloy: in-sexp highlighting?

15:50 dakrone: amalloy: background highlighting the body of an expression the first time it's typed, it's difficult to explain :)

15:50 amalloy: mmmm. so that's instead of bouncing the cursor/point?

15:50 Blkt: what's the best way to handle configuration (files) in a Clojure webapp?

15:51 technomancy: so like show-paren-mode except for the body instead of just the delimiters?

15:51 seems weird to tie that to smartparens instead of creating something orthogonal

15:51 hyPiRion: I'm fine with highlight-parentheses really.

15:51 dakrone: amalloy: technomancy: yes, except it's more "while-you-type-the-expression" than after the fact

15:51 it is useful when typing JSON

15:52 amalloy: technomancy: show-paren-mode will show the body if you ask

15:52 technomancy: oh, cool

15:52 futile: Ah there is a clojure.test emacs plugin isn't there..

15:52 technomancy: ooh, mixed. I like the sound of that

15:52 futile: yeah but it's kinda lame

15:59 futile: Would it be better to just get the clojure.test autorunner?

16:00 technomancy: it should be replaced with nrepl-discover

16:00 futile: Ah.

16:01 gtrak: technomancy: I thought it was funny/odd that bbatsov wanted to wait for nrepl-discover to mature..

16:01 since there's few emacs-related nrepl projects besides cider.

16:01 technomancy: gtrak: yeah, I don't really understand his project management style

16:01 gtrak: like.. not gonna mature unless we use it, dude.

16:05 futile: All programming seems to be just finding new ways to call functions with arguments...

16:05 technomancy: futile: except forth

16:06 gtrak: I just tried to explain my understanding of monads to a haskeller like that

16:06 fancy parameter-passing

16:06 futile: technomancy: I call shenanigans.

16:06 technomancy: gtrak: http://p.hagelb.org/mrfp.gif

16:06 futile: it's true

16:11 eraserhd: I'm having a weird bug that I can reproduce, but having trouble isolating small code that does it.

16:11 tgoossens: When I have a class with methods. If I change the representation of the object, my compiler tells me what methods don't work anymore. In clojure if i create function to work with a certain data structure and I change it, I don't automaticlly find what functions that must be changed.

16:11 eraserhd: It seems to be about making a lazy list a key in a meta map in a macro, then accessing it at run time.

16:11 Does this ring any bells?

16:13 Oh, value. not key.

16:19 devn: whoa. clojure/west talks are up already: http://www.youtube.com/watch?v=wVXjExRiFy0

16:20 zerokarmaleft: yea, somebody's cracking the whip in SF

16:20 technomancy: devn: there was an incredible amount of whining around this last year

16:20 futile: What are the great new ways to enhance our clojure.test experiences?

16:20 klang: .. there goes sleep tonight ..

16:21 devn: technomancy: oh i remember! :)

16:27 gtrak: last year it was all Alex, now it's cognitect and friends

16:37 jcromartie: yeesh now I feel like my app is insecure?

16:37 I thought I had a pretty good handle on it :|

16:41 amalloy: eraserhd: metadata probably gets evaluated

16:50 jcromartie: how often do you end up writing code that checks argument or return types?

16:51 like, :pre and :post maps, or asserts, or code that throws IllegalArgumentException?

16:51 gtrak: jcromartie: schema's been really nice for this

16:54 tuft: tgoossens: true, but the flip side is that they can continue doing what they did before, as they aren't coupled to the type you changed.

16:55 amalloy: jcromartie: super rarely. i occasionally throw IAE; never use pre/post; and very rarely use assert

16:55 tuft: tgoossens: .. and your tests should be able to provide the same checklist.

16:55 hiredman: assertions and pre/post are great

16:56 I have only ever regretted not having them

16:56 (not to say I use them a lot, I just regret not having them in places a lot)

16:56 akurilin: So if I want to share a bunch of business logic pure functions across multiple projects, what should determine if the :source-paths approach is good enough or if I should go the separate .jar route?

16:57 tuft: anyone using schema in their project?

16:57 futile: I have been using preconditions for this utility I'm writing.

16:57 hiredman: not having a custom message :pre/:post is a pain though

16:57 AeroNotix: tuft: schema?

16:58 rasmusto: AeroNotix: prismatic's thing for runtime type checking

16:58 tuft: AeroNotix: yes that ^^ =)

16:59 seems useful for when things get really nested

16:59 AeroNotix: oh ok

16:59 tuft: .. or when accepting input to the system from outside.

17:00 futile: What's a good way of pulling in data from a non-compile-time-loaded file?

17:00 hiredman: the cloud is a vast roiling sea where devops are prone to mad acts of maintaince and chatops, best not to assume anything

17:00 jcromartie: futile: EDN/Clojure data?

17:00 AeroNotix: hiredman: chatops?

17:00 rasmusto: futile: slurp it from resources?

17:00 futile: My users pass "my.config.namespace" which contains defs which may execute some code.

17:00 And I need to access their defs.. and there's a lot of ways.

17:01 jcromartie: futile: I'd say the right way to get at the vars in a namespace is ns-publics

17:01 futile: I could have them hook into a function of mine which redefs some defs I can access. Or I can have them (in-ns) into my namespace and do their defs, and I just access them at runtime.

17:01 hiredman: (for example changing the character encoding on a database in a way that some how twiddles the bits in your gzipped blobs)

17:01 futile: jcromartie: ah so the second one?

17:01 jcromartie: futile: this sounds… weird

17:01 :-/

17:01 futile: Alternatively I could just make this file return a map that I def right into a def in my own namespace, and just use known keys.

17:02 I'm going to great lengths to avoid the trouble of writing a leiningen plugin.

17:03 I've used the map solution before to good effect.. very little runtime magic needed except (load the-file).

17:04 (def my-map (load their-file)) ... (do-something-with (:some-key my-map))

17:04 That's simplest, I'll just do that.

17:08 jcromartie: futile: why can't they just pass you data?

17:09 instead of giving you something you'll turn around and load?

17:09 I don't know what you're building

17:10 shep-home: Does Mark Engelberg hang around here? Or anyone associated with instaparse?

17:11 futile: jcromartie: I'm building a lib that you install and then do `lein run -m mylib.main your-config-namespace`

17:11 jcromartie: I control the entry-point of the lib, since it's a command-line util.

17:11 jcromartie: Of course, that whole invocation will be hidden away in a lein-alias for good measure.

17:13 akurilin: shep-home: I don't remember seeing him on here but I had a really easy time getting hold of him on Instaparse's google groups

17:14 guy's extremely reponsive and helpful

17:14 shep-home: akurilin: thank you. I wanted to give that team a big thank you. They made this (https://github.com/shepmaster/clojure-ruby) fun to write

17:15 futile: Wow.

17:18 rasmusto: shep-home: did you watch the clojure/west talk on instaparse?

17:19 shep-home: rasmusto: nope - is it worth watching?

17:20 rasmusto: Yep: http://www.youtube.com/watch?v=b2AUW6psVcE

17:20 you'll learn a bit more about the "team" :D

17:21 shep-home: rasmusto: excellent, thank you. I think I can find 40 minutes to watch this during funployment :-)

17:21 rasmusto: I found his mini-dive into the implementation to be really cool

17:21 it's all async + pseudo pubsub

17:22 Anderkent: it was nice, but I wish there was more info about why the algorithm is correct, it's not obvious (at least to me)

17:23 rasmusto: Anderkent: yeah, hence "mini-dive"

17:23 I don't mind the aabababa examples though, I'd get confused otherwise

17:23 Anderkent: yeah that was nice

17:28 verma: anyone here uses lien-npm? can't get it to generate a package.json

17:30 os is it not persistent? in the sense that it would be removed when the task is done executing?

17:30 oh, it does remove it https://github.com/bodil/lein-npm/blob/master/src/leiningen/npm.clj#L74

17:35 lein run seems to run my script, but its not generating package.json when running the file, I need it for node-webkit

17:46 TravisD: Is there a way to query how much memory is available in the JVM?

17:48 justin_smith: (.freeMemory (Runtime/getRuntime))

17:48 znurgl: How can you convince your boss about using Clojure in one sentence? (theoretical question)

17:49 nightfly: It's new and cool

17:49 justin_smith: TravisD: depending what you mean by "how much memory is available" other methods may have better answers

17:49 gtrak: znurgl: 'it's a concurrency library'

17:50 technomancy: znurgl: "if I have to write any more java I'll quit."

17:50 justin_smith: TravisD: but you probably want the info returned by some method of (Runtime/getRuntime) http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html

17:50 TravisD: justin_smith: Ah, I really just wanted to know how much space was reserved for the heap or something. I was running out of space and I was curious how much there is

17:50 justin_smith: maxMemory is likely what you want

17:51 TravisD: ah, yes, just saw it in the docs

17:51 Averell: "this will be more cost-effective than our current cobol code"

17:51 justin_smith: (.maxMemory (Runtime/getRuntime))

17:51 TravisD: ,(.maxMemory (Runtime/getRuntime))

17:51 clojurebot: #<CompilerException java.lang.SecurityException: Reference To Runtime is not allowed, compiling:(NO_SOURCE_PATH:0:0)>

17:51 justin_smith: also, you may want to compare that to the amount of mem currently allocated

17:51 gtrak: znurgl: 'we can't do feature x in a timely manner without it'

17:52 sdegutis: gtrak: boom got em

17:52 TravisD: justin_smith: cool, thank s:)

17:55 sdegutis: did I do that right?

17:56 justin_smith: sdegutis: http://www.urbandictionary.com/define.php?term=Got%20Em&defid=1716329

17:56 znurgl: I have another strange question. I've never used (def variable-name value) in Clojure. And I checked some project on GitHub and I can't find def, so is it a common thing in Clojure not using variables just dealing with data flow?

17:57 gtrak: def's usually for constants

17:57 or things that aren't functions, generally it's bad to hold state in a var

17:57 justin_smith: znurgl: well, technically defn is just a wrapper on def

17:57 def + fn = defn

17:57 znurgl: justin_smith: sure, I know

17:58 gtrak: znurgl: you shouldn't call def within a function unless you know what you're doing

17:58 znurgl: but I did't use it for defining a variable

17:58 cbp: def for global constants and also closures as i think a def inside a let is a little ugly :-P

17:58 a defn inside a let}

17:58 *

17:59 bja: there's a letfn for that

17:59 znurgl: so the good practice is stay away from def a variable as much as I can, isn't it?

18:00 gtrak: znurgl: def is to create a var, vars have their own semantics.

18:00 cbp: znurgl: no, you just wont use them much naturally

18:00 gtrak: http://clojure.org/vars

18:00 sdegutis: I am using vars like crazy today.

18:00 cbp: bja: but i want a closure in a var

18:00 sdegutis: So many vars.

18:00 cbp: also for holding stuff like atoms/refs/etc..

18:01 gtrak: not just a 'variable', to be precise it's a Var.

18:01 sdegutis: I even def a def within a def https://github.com/sdegutis/Billow/blob/master/src/billow/config.clj#L5-L7

18:01 technomancy: znurgl: clojure doesn't have variables

18:01 gtrak: clojure doesn't have local variables either, those are usually called bindings

18:01 sdegutis: To be fair, there's like so little distinction.

18:02 cbp: sdegutis: i usually do that kind of thing with alter-var-root

18:02 sdegutis: I've found using Clojure to be nearly identical to using Ruby, except for the super-powers Clojure gives you.

18:02 gtrak: it's important to not use a term that means something in other languages :-)

18:02 znurgl: thanks guys, I should check it again :-)

18:02 sdegutis: cbp: I wonder, what's the difference between the two approaches?

18:02 (def ...) vs (alter-var-root ...)

18:03 technomancy: sdegutis: alter-var-root requires it to already exist

18:03 gtrak: cbp: well, for one, the var gets created at compile-time, alter-var-root won't do that.

18:03 when your defn is eval'd the var gets created.

18:03 cbp: sdegutis: the namespace

18:03 All sorts of scary business

18:03 gtrak: It would probably cause concurrency problems to use def.

18:04 potentially.

18:04 sdegutis: I am doing so programming right now.

18:04 technomancy: so programming. much def. very excite.

18:04 bja: sdegutis, is that a doge thing?

18:05 technomancy beat me to it

18:05 sdegutis: Hmm, I didn't realize the connection but yeah, basically the style I was going for.

18:05 Except a little less formal to the meme.

18:05 So I have this really weird library/utility design..

18:05 gtrak: ,(do (defn a [] (def b)) b)

18:05 clojurebot: #<Unbound Unbound: #'sandbox/b>

18:05 gtrak: see the problem?

18:06 sdegutis: You put the ugly stuff into an alias, then run `lein billow`, and it shoves you into a REPL, and gives you access to a few commands like (list-servers), (create-server ...) etc

18:06 gtrak: ,b

18:06 clojurebot: #<Unbound Unbound: #'sandbox/b>

18:06 gtrak: ,c

18:06 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: c in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:06 pyrtsa: gtrak: It will probably cause concurrency problems to use alter-var-root as well.

18:06 sdegutis: It's not conventional, but it gives you a little more flexibility and avoids lein-reloads when you wanna do multiple things in a row.

18:06 pyrtsa: Just a different kind of such.

18:07 gtrak: pyrtsa: I would imagine it wouldn't kill current bindings on the var, and the def would.

18:07 cbp: you also cant require that function

18:07 gtrak: maybe..

18:07 cbp: or you can do it with weird consequences..

18:07 gtrak: just don't do it :-)

18:08 altervarRoot calls a method on the var, def might wholly replace it.

18:08 not sure exactly when.

18:09 alter-var-root notifies watches..

18:09 cbp: ,(do (ns a) (defn f [] (def x 1)) (ns b) (require 'a) a/x)

18:09 clojurebot: #<Unbound Unbound: #'a/x>

18:09 gtrak: and takes a validator

18:09 so that's one difference

18:09 cbp: er i got a different result..

18:10 oh well

18:10 pyrtsa: gtrak: If you alter-var-root a var while another thread is using it, its value will just suddenly be different, during the computation.

18:10 amalloy: sdegutis: https://github.com/sdegutis/Billow/blob/master/src/billow/config.clj#L5-L7 shouldn't work at all

18:10 gtrak: pyrtsa: I don't believe it

18:10 that's only the case if that thread is using the root binding

18:11 technomancy: ~tias

18:11 clojurebot: Try it and see! You'll get results faster than asking someone in #clojure to evaluate it for you, and you'll get that warm, fuzzy feeling of self-reliance.

18:11 amalloy: alter-var-root doesn't take a value, it takes a function and applies it to the old value

18:11 gtrak: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Var.java#L188

18:11 pyrtsa: gtrak: Easy to test: create two threads, one calling alter-var-root after a timeout, the other using that var repeatedly, sleeping in between.

18:11 gtrak: pyrtsa: bindings

18:11 technomancy: amalloy: the question is whether the root is replaced with a CAS or just a set

18:11 gtrak: know what I mean?

18:11 technomancy: I don't think it's CAS

18:12 gtrak: technomancy: i'm looking at it, it's a volatile

18:12 amalloy: technomancy: that's the conversation y'all are having; i'm making a different point which is that sdegutis's use of alter-var-root is bogus regardless of your discussion

18:12 technomancy: oh, gotcha

18:12 sdegutis: amalloy: how so?

18:12 amalloy: and it's not CAS

18:13 (03:08:22 PM) amalloy: alter-var-root doesn't take a value, it takes a function and applies it to the old value

18:13 sdegutis: Oops.

18:13 pyrtsa: gtrak: Sorry, I think I'm missing the point. Can you educate me? (In private if considered noise here.)

18:13 cbp: Oh he updated it

18:13 sdegutis: Fixed.

18:13 cbp: the speed rivals dnolen's

18:14 sdegutis: https://github.com/sdegutis/Billow/blob/master/src/billow/config.clj#L5-L7

18:14 gtrak: ah, sure. your example is correct, but that's not the point. vars support a thread-local stack of bindings. if there's something bound, then the change to root wouldn't matter on that thread.

18:14 pyrtsa: ^

18:14 cbp: I got confused for a second (he's not using alter-var-root at all!)

18:14 pyrtsa: gtrak: Okay, cool. Now we agree.

18:15 sdegutis: Thanks amalloy :)

18:15 amalloy: here's a pie to show my gratitute: \_/

18:15 amalloy: hah

18:15 sdegutis: No wait sorry that's an upside-down lampshade.

18:16 Here's the pie: ___

18:17 stcredzero: sdegutis: \_/ looks like a standard grey alien glaring at you. Or the victory gesture guy beheaded \o/

18:18 sdegutis: quite

18:19 stcredzero: Actually, they are one and the same. (Now go off and read all of Grant Morrison's Doom Patrol)

18:21 sdegutis: ~guards

18:21 clojurebot: SEIZE HIM!

18:21 stcredzero: Who me?

18:23 sdegutis: Hey clojurebot said it not me

18:24 I am not good at designing APIs and I get really tired out easily from it which wears down my concentration and I end up in here saying ~guards...

18:24 stcredzero: Why would you sic the guards on me?

18:24 shalicke: ~gourds

18:24 clojurebot: SQUEEZE HIM!

18:24 * shalicke takes a bow.

18:24 stcredzero: ~gads

18:24 clojurebot: Pardon?

18:24 sdegutis: shalicke: one of the few times I can literally say LOL

18:24 stcredzero: ~girds

18:24 clojurebot: excusez-moi

18:24 stcredzero: ~gauds

18:24 clojurebot: Titim gan éirí ort.

18:25 technomancy: ~praetorian guards

18:25 clojurebot: CAESE HIM!!!

18:25 amalloy: niiiice

18:25 shalicke: (inc technomancy)

18:25 lazybot: ⇒ 102

18:25 sdegutis: (dec technomancy)

18:25 lazybot: ⇒ 101

18:25 technomancy: can't take the credit; stole it from #emacs

18:25 sdegutis: Just tryin to balance things out

18:25 * shalicke feels like gourds came from there too

18:25 stcredzero: So this is the Lispy version of Hogwarts?

18:25 sdegutis: (inc sdegutis)

18:25 lazybot: You can't adjust your own karma.

18:25 sdegutis: :(

18:25 AeroNotix: (inc sdegutis)

18:25 lazybot: ⇒ 6

18:25 AeroNotix: spread the love

18:25 sdegutis: (inc shalicke)

18:25 lazybot: ⇒ 1

18:26 sdegutis: (inc stcredzero)

18:26 lazybot: ⇒ 1

18:26 technomancy: (dec slytherin)

18:26 lazybot: ⇒ -1

18:26 AeroNotix: ,(prn AeroNotix)

18:26 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: AeroNotix in this context, compiling:(NO_SOURCE_PATH:0:0)>

18:26 sdegutis: ok $karma has got to go

18:26 technomancy: stcredzero: basically, yeah

18:26 stcredzero: stcredzero gets love? What did y'all do with the *real* clojure community?

18:26 sdegutis: Nobody wants #clojure to turn into a popularity contest, and also I have a way low $karma.

18:26 rasmusto: ~clojure

18:26 clojurebot: clojure is the king of the Sinatra-esque all-in-one-file webapp.

18:27 stcredzero: Lies!

18:27 ~Lies!

18:27 clojurebot: Pardon?

18:27 stcredzero: Clojurebot has the makings of a politician!

18:28 wink: I disagree with clojurebot's penultimate statement though

18:28 stcredzero: (pr-src stcredzero)

18:28 wink: because, just today, I wrote a sinatra app

18:28 and because of a certain gem it would have taken me ages (probably) in clojure

18:29 stcredzero: wink: a good and big community counts for a lot

18:29 wink: plus I don't even want to think about inline templates in my clojure code :P

18:29 sdegutis: wink: what gem, you?

18:30 wink: sdegutis: github-flavored markdown :P

18:30 sdegutis: wink: re: templates, looked at hiccup?

18:30 wink: sdegutis: yeah, used it for a while, but that's not really like sinatra inline templates. not worse, but definitely different

18:31 sdegutis: Right, Clojure definitely needs to be used differently than Sinatra.

18:31 Hmm yeah, we're missing a GFM lib..

18:31 I've been using github.com/yogthos/markdown-clj

18:31 wink: I would have never thought I'd "defend" ruby against clojure. ever

18:31 but in this case, as github is a ruby shop, anything else makes less sense

18:32 sdegutis: wink: Great, because in this channel, we admit and confess that Clojure is the best language.

18:32 stcredzero: wink: wish to accept the truth

18:32 wink: as I am *exactly* rendering github wiki links

18:32 s,links,pages,

18:32 sdegutis: wink: In #haskell though we know for a *fact* that Haskell is better than Clojure.

18:32 wink: Granted, in #ruby-lang we know that Ruby is actually the best.

18:32 stcredzero: sdegutis: In this channel, I hope that we also realize: best language != best environment

18:32 brehaut: you are all wrong. idris is the future

18:32 technomancy: gfm from jruby. boom.

18:32 wink: sdegutis: see, in the php channels I am no one even claims it's the best language. we just get shit done :P

18:32 sdegutis: stcredzero: chruby + bundler ftw

18:33 technomancy: wink: same with elisp =)

18:33 brehaut: wink: emphasis on the shit ;)

18:33 stcredzero: chruby? I would be disturbed by programmers telling me they have a chruby for me

18:33 sdegutis: wink: that's because PHP is the best language, no need to tout it.

18:33 technomancy: yeah, elisp is so simple..

18:34 technomancy: ...yet powerful

18:34 sdegutis: (dinc technomancy)

18:34 aww not a real thing

18:34 stcredzero: "double income no closures"

18:34 brehaut: double income no cat?

18:34 wink: I'm allergic to income

18:34 no, wait

18:34 stcredzero: ~scheme

18:34 wink: I'm allergic to cats

18:34 clojurebot: scheme is Scheme is like a ball of snow. You can add any amount of snow to it and it still looks like snow. Moreover, snow is cleaner than mud.

18:35 stcredzero: ~Haskell

18:35 clojurebot: It's greek to me.

18:35 stcredzero: ~Lua

18:35 clojurebot: Pardon?

18:35 wink: ~curry

18:35 clojurebot: Excuse me?

18:35 stcredzero: ~coc

18:35 clojurebot: I don't understand.

18:35 wink: clojurebot: Lua is awesome

18:35 clojurebot: Ok.

18:35 stcredzero: ~coq

18:35 clojurebot: Cool story bro.

18:36 sdegutis: stcredzero: boom got em

18:36 ~Lua

18:36 clojurebot: Lua is awesome

18:36 stcredzero: sdegutis: boom?

18:36 brehaut: gfredericks has some work to do apparently

18:36 wink: I was literally bursing out laughing when someone recently mentioned a problem with coq and the solution was "you forgot Qed. in the end"

18:36 sdegutis: stcredzero: yes.

18:36 stcredzero: sdegutis: yes?

18:36 sdegutis: right

18:37 stcredzero: ~greek

18:37 clojurebot: greek is it to me

18:37 stcredzero: ~me

18:37 clojurebot: It's greek to me.

18:37 wink: stop breaking it

18:37 its feeble mind has suffered enough

18:37 stcredzero: ~Smalltalk

18:37 clojurebot: It's greek to me.

18:38 sdegutis: I cannot take it.

18:38 hiredman: I really should put a throttle in the bot so it automatically will ignore people when they excessively do this kind of thing

18:38 hons: ~scala

18:38 clojurebot: Scala often gets in the way when trying to write neat code -- seen in #scala

18:38 stcredzero: hiredman: sorry, I just got curious

18:39 hons: ~java

18:39 clojurebot:

18:39 hons: ;)

18:39 wink: that entry should've been more verbose

18:40 stcredzero: True story: Smalltalker is told by boss he should change to Java. So he changes all the app icons to coffee cups and gets to code in Smalltalk for an additional 6 months. Later, he came to work for the Smalltalk vendor. (Where I was working)

18:41 technomancy: stcredzero: I am in awe.

18:41 stcredzero: Vasilly is awesome, actually. I should steal some of his ideas and rewrite them as pure functional versions

18:50 ~monads

18:50 clojurebot: monads are |monads|

18:50 metellus: ~|monads|

18:50 clojurebot: |monads| is endofunctors

18:50 rasmusto: ~burrito

18:50 clojurebot: Excuse me?

18:51 stcredzero: ~lolcode

18:51 clojurebot: No entiendo

18:54 brehaut: stcredzero: i am disappointed that that story does not fit in 140 characters

18:54 well, 137

18:54 stcredzero: brehaut: And I am not bothered at all.

18:57 brehaut: TrueStory: Boss tells Smalltalker: Switch 2 Java. Smalltalker changes icons to coffeecups and codes in Smalltalk for 6 more months.

18:58 brehaut: stcredzero: haha thanks :)

18:59 gfredericks: a burrito is just a burroita in the menu of endofajitas

18:59 justin_smith: "This man's boss wanted him to switch from Smalltalk to Java. What he did next will restore your faith in humanity"

18:59 rasmusto: gfredericks: haha

18:59 brehaut: gfredericks: ftw

18:59 justin_smith: (inc gfredericks)

18:59 lazybot: ⇒ 43

18:59 gfredericks: that's the third time I've used that joke in 24 hours

18:59 rasmusto: (inc gfredericks)

18:59 lazybot: ⇒ 44

18:59 zspencer: (inc justin_smith)

18:59 lazybot: ⇒ 30

19:00 gfredericks: TimMc: it helps for easily putting giant results in vars without accidentally printing them

19:01 Bbarrett: I am trying to move files from one directory into another, should I utilize Java's .move method in this case, or is there a better way to do with a built in Clojure library

19:01 SegFaultAX: (inc gfredericks)

19:01 lazybot: ⇒ 45

19:01 wink: justin_smith: you got a day job at gawker?

19:02 sdegutis: I am about to use lazy-infinite-sequences to solve a problem.

19:03 brehaut: thats lucky, because strict-infinite-sequences are problematic in practise

19:03 stcredzero: Incidentally: The Smalltalker's name is Vasilly Bykov, IIRC

19:03 amalloy: Bbarrett: if a java method does what you want, use it

19:03 TEttinger: Bbarrett: I'd personally avoid additional dependencies and just use the .move , it's always available

19:03 amalloy: brehaut: it's fine as long as you have infinite time

19:03 wink: sdegutis: "I'll procrastinate the problem away" is what you meant?

19:03 Bbarrett: thanks

19:03 amalloy: and space

19:03 brehaut: amalloy: problematic, not impossible

19:03 Bbarrett: I kind of thought that might be the best path to take

19:03 wink: amalloy: if space is the final frontier, how can it be infinite?

19:03 cbp: Bbarrett: it's likely that the clojure library calls that method anyway

19:03 justin_smith: wink: we use clojure to make optimized lazy headlines (no, I don't work at gawker, but those link bait headlines are too easy to mock)

19:03 hiredman: TEttinger: it is in fact only always available since 1.7

19:03 wink: justin_smith: :P

19:04 TEttinger: hiredman: agh

19:04 Bbarrett: thanks for the input!

19:04 hope everyone is having a kiler day or evening

19:04 stcredzero: As far as we know, all of us reappear an infinite number of times in the cold, empty void past the heat-death of the universe as Boltzmann brains

19:05 SegFaultAX: This channel just got a lot more meta.

19:05 TEttinger: stcredzero: it's great being a brain in space. free IRC

19:06 SegFaultAX: TEttinger: For some reason your movie reminded me of the soul-crushing sadness of Her. Did you see that movie?

19:06 sdegutis: I just did it!! https://github.com/sdegutis/Billow/blob/master/src/billow/service.clj#L14-L19

19:06 gfredericks: all of us reappear an infinite number of times in universes that are entirely identical to ours except that the moon landing was a hoax

19:06 TEttinger: I had a movie?

19:06 SegFaultAX: TEttinger: Wow, I accidentally some words there.

19:06 sdegutis: I used lazy infinite sequences to come up with a uniquely numbered name!

19:06 SegFaultAX: TEttinger: Your comment reminded me*

19:07 stcredzero: This sentence no verb!

19:07 TEttinger: I was confused for a bit. no I have not seen Her

19:07 brehaut: gfredericks: in some of those existances cabbage trees are true

19:07 socksy: ugh i'm getting java.lang.OutOfMemoryError, but i have no idea which part of my code is producing it. Any tips for debugging?

19:07 AeroNotix: uh, with (time) is there something which'll give me the time as a value *and* the value of the expression I am evaluating?

19:07 rasmusto: socksy: jvisualvm?

19:08 AeroNotix: socksy: visualvn

19:08 visualvm

19:08 hiredman: see where your code is allocating lots of memory and stop doing that

19:08 gfredericks: AeroNotix: I have this bg macro that is awesome for that

19:08 AeroNotix: oh wait no

19:08 I did not read that carefully

19:08 I've needed that a lot too and keep re-writing it

19:08 AeroNotix: gfredericks: I want to make a "r u there db" call and time it, as a statistics healthpoint

19:08 wink: reading the last 15minutes makes me wonder if I am drunk or some of you are.

19:09 AeroNotix: wink: I am

19:09 always.

19:09 rasmusto: some-> people are

19:09 hiredman: a profile is great, but just a read through the code should give you a good idea at what is using all the memory

19:09 cbp: I am just dum

19:09 hiredman: profiler

19:09 gfredericks: (defmacro t [& body] `(let [b# (System/currentTimeMillis) ret# (do ~@body)] [ret# (- (System/currentTimeMillis) b#)]))

19:09 amalloy: AeroNotix: i remember seeing something called with-timing, but i forget where

19:09 TEttinger: socksy: I've gotten that in interesting places before, that error.

19:09 gfredericks: AeroNotix: ^there I wrote it again

19:10 AeroNotix: gfredericks: cool, ok. So I'll need to write something for this. No worries. I thought there might be something in the standard library for it

19:10 socksy: going to check out visualvm, cheers

19:10 AeroNotix: gfredericks: or maybe there's a secret cheat mode for (time) where it binds some variable or w/e

19:10 stcredzero: socksy: you going to run that on OS X?

19:10 amalloy: in one of ztellman's libraries, i think

19:10 socksy: the annoying thing about it is that it's an array that reaches the VM limit, but I'm not explictly creating any arrays

19:10 hiredman: the thing with oomes is they occur when you don't have enough memory to satisfy some request, which doesn't tell you about where all the memory is being used

19:11 socksy: stcredzero: arch linux

19:11 stcredzero: socksy: this is fortunate

19:11 TEttinger: socksy, I'm currently struggling with an odd issue with OpenJDK on windows giving that (or maybe something similar) on startup if more than half the RAM on the system is used

19:11 socksy: interesting

19:12 TEttinger: but mine's on startup of the JDK

19:12 socksy: (I've increased the heap size, so it's not a heap memory issue, rather, an issue with array sizes, given they're indexed by ints)

19:12 wink: TEttinger: there is openjdk for windows? oh, wow.

19:13 hiredman: socksy: just because you get an oome while doing something with an array, that doesn't mean the memory is all being consumed there, it just means that is where the vm noticed it didn't have enough

19:13 TEttinger: wink, yeah it's the only full JVM that you're legally allowed to resdistribute modified versions of.

19:13 hiredman: are you holding on to the head of large sequences

19:14 socksy: hiredman: agreed, but it's specifically an out of memory error regarding the array size limit

19:14 wink: TEttinger: interesting. the thought never crossed my mind actually, as I always had Sun/Oracle JDK on windows anyway.

19:15 hiredman: socksy: seems unlike that would be an oome, do you have a gist of the stacktrace?

19:15 TEttinger: wink, yeah especially starting with JDK 8 there's a hefty advantage to modifying it. the JRE is something like 100 MB unaltered.

19:15 wink: TEttinger: you mean the download? I've never had to distribute it

19:16 TEttinger: actually JDK 8 is even larger, but the part you would distribute is (IIRC) 118 MB

19:16 I've been looking into distributing full JREs as a way of avoiding java installation/update hassles

19:17 socksy: hiredman: gimme a few minutes to rerun and run out of memory, but it's just the one liner "java.lang.OutOfMemoryError: Requested array size exceeds VM limit", from calling a function in the repl (no stacktrace :\)

19:17 red00: how can i interact with clojurebot?

19:17 hiredman: socksy: (require 'clojure.stacktrace) (print-stack-trace *e)

19:17 justin_smith: ,:red00

19:17 clojurebot: :red00

19:17 red00: thanks

19:18 justin_smith: np

19:18 rasmusto: red00: you can /msg clojurebot too

19:18 socksy: hiredman: fantastic

19:18 hiredman: socksy: assuming you are using nrepl/cider for whatever annoying reason they decided to default to not displaying stacktraces

19:18 socksy: there is something setting you can toggle to get it to pop up the stracktrace, but I forget what it is

19:19 justin_smith: also there is also clojure.repl/pst

19:19 Averell: toggle-debug-on-error

19:19 justin_smith: Averell: that is for emacs errors

19:19 not jvm ones

19:19 Averell: oh. i didn't read close enough

19:19 hiredman: terrible defaults everywhere

19:20 people thing the stacktraces are ugly, so lets hide them, so now you can't figure out what broke

19:23 socksy: ugh, obviously too sleep deprived because I knew about the stacktrace issue before and forgot to enable it this time. Running the program again...

19:26 aha, it's a stringbuilder

19:28 arohner: hiredman: that's why I don't upgrade emacs libraries :-)

19:28 that, and I never remember how

19:29 socksy: https://gist.github.com/socksy/9796104

19:29 brehaut: arohner: step one, find a goat…

19:29 rasmusto: M-x package-destroy-sanity

19:29 murphy_: haha

19:29 justin_smith: (inc rasmusto)

19:29 lazybot: ⇒ 4

19:29 rasmusto: I just upgrade to cider, seems okay so far :p

19:29 justin_smith: you'd think emacs people could make a better package management thing

19:30 from nrepl? did you just purge nrepl first?

19:30 AeroNotix: when will people learn to put their emacs config into vcs

19:30 rasmusto: I think I deleted ~/.emacs.d/elpa and changed around init.el to have cider in it

19:30 murphy_: probably never would be my guess ??

19:30 lazybot: murphy_: Uh, no. Why would you even ask?

19:30 rasmusto: then re-ran everything

19:30 amalloy: arohner, hiredman: slime/swank for life? are we in that club?

19:31 hiredman: no, I am using cider :/

19:31 rasmusto: I'm a big fan of pathogen + git-submodule

19:31 (sorry emacs ppl)

19:31 justin_smith: AeroNotix: how would I track my package state? is there a single file for that? Would I need to check in all my elc files?

19:31 hiredman: rasmusto: git subtree is way better

19:31 submodule is terrible

19:31 socksy: now this is during a function which is updating an agent map, which admittedly has strings in it, but each string should only be a few characters. I am wondering if it's actually having the error from the repl trying to print out the map

19:31 arohner: amalloy: I'm on some version of nrepl, but I was definitely the last person in my company to switch from slime

19:32 rasmusto: hiredman: does it actually let you look at the contents of the "modules/trees"?

19:32 instead of just dumping a sha into /.git

19:32 hiredman: socksy: yes, it is just the repl printing

19:32 amalloy: ; SLIME 20100404

19:32 <3

19:32 socksy: so this time when I've been thinking it's been running out of memory, it hasn't really

19:33 hiredman: rasmusto: http://makingsoftware.wordpress.com/2013/02/16/using-git-subtrees-for-repository-separation/

19:33 amalloy: socksy: you are trying to print something which is the size of a small country

19:33 hiredman: rasmusto: you never have to submodule init or anything

19:34 when you do a git checkout, it is all there

19:35 rasmusto: so are the master sha1s derived from all of the content of local files and the subtrees?

19:35 hiredman: rasmusto: I believe so

19:35 rasmusto: hiredman: can I do a git subtree fetch --prefix blah/foo ?

19:36 hiredman: I have no idea

19:36 rasmusto: hiredman: I'll have to try it out, submodules fit the need of dotfiles, but subtrees sound better overall

19:36 sdegutis: Ah, my test almost passed, but then I realized I need a really dynamic fake-service that stubs some remote calls and mocks others.

19:37 stcredzero: Am I correct in thinking that cons is O(1)?

19:37 hiredman: I still have a few emacs packages in my emacs as submodules but I have been converting to subtree

19:37 sdegutis: stcredzero: looks like it to me

19:37 hiredman: I have been just vendoring them from elpa, seems to work great so far

19:37 rasmusto: hiredman: can you do a git subtree foreach git pull? (not that it's safe)

19:37 AeroNotix: justin_smith: I just check in .emacs and .emacs.d/

19:37 sdegutis: hiredman: see https://github.com/sdegutis/dotfiles/tree/master/home/.emacs.d/elpa

19:38 package.el takes care of all the grunt work for me

19:38 AeroNotix: justin_smith: and yeah, there's a file which tracks what's installed.

19:39 hiredman: no

19:39 but the whole reason I stick emacs packages in git is I found something I like and I don't want to change it

19:42 sdegutis: technomancy: honestly it's not elisp that's frustrating, it's the emacs api

19:42 technomancy: it's probably just inherent in the problem space.. you've got so many different parts that need to work together, and they're mostly codependent

19:42 justin_smith: wait, elisp is somehow distinct from the emacs api?

19:42 sdegutis: I think defcustom vs defvar vs defadvice vs vs setq vs setq-default etc etc is a good example

19:44 socksy: ok, going to call it a night. Thanks for all the help, everyone

19:44 sdegutis: justin_smith: yessir

19:44 socksy: any time

19:48 It fricken worked.

19:50 * sdegutis dances

19:54 sdegutis: Also I really don't like these tests.. but I don't know a better way: https://github.com/sdegutis/Billow/blob/master/test/billow/service_test.clj

19:54 Any suggestions?

19:54 They're just so.. crappy overall.

19:55 justin_smith: responses and testing-configs could easily go in a separate file / namespace

19:55 amalloy: sdegutis: what is spec buying you over like clojure.test there?

19:55 you just have a bunch of assertions

19:55 sdegutis: amalloy: I couldn't find a test-autorunner for clojure.test

19:57 technomancy: sdegutis: defadvice has nothing to do with the others

19:57 I agree that defcustom is silly though

19:57 defvar is just defonce; that's kind of important

19:57 amalloy: technomancy: whaaaaat. defcustom is great

19:57 sdegutis: technomancy: right, it's for hooks, and rms says non-users shouldn't even use them

19:58 technomancy: amalloy: the customize UI is pretty cringeworthy though

19:58 justin_smith: technomancy: defcustom is kind of like "view level" - it's telling emacs how to make a friendly interactive config wizard for your lib

19:58 technomancy: it seems like a lame attempt to make it so people can use emacs without writing elisp

19:58 like the toolbar

19:58 amalloy: technomancy: i mean, it's not great, but getting a color-chooser widget is so much nicer than having to guess what all available colors are named

19:58 or a font-style widget, etc

19:59 and feedback like "dude that's not the type that this variable expects" the moment you set it, instead of next time you reload your .emacs

19:59 sdegutis: amalloy: What's the motivation to use defcustom when someone isn't using customize-ui?

19:59 amalloy: sdegutis: there is none

19:59 afaik

19:59 sdegutis: hyPiRion: thx

19:59 amalloy: but i use the customize ui

19:59 technomancy: amalloy: hm; I've never seen it used for either of those things

19:59 sdegutis: amalloy: ah

20:00 justin_smith: I find browsing a customize buffer gets me the option I need faster than reading docs does, and is more likely to be accurate to my version than googling

20:00 technomancy: unless you count M-x customize-face, which doesn't actually use defcustom

20:00 amalloy: okay, maybe i was counting customize-face

20:00 sdegutis: amalloy: I've used customize-themes just because it's the quickest way to try out new themes while disabling old ones, but I'd prefer a UI more like magit and less like windows-95

20:00 amalloy: but eg, you can specify :type int, and then the user can't enter strings

20:00 sdegutis: sorry, windows-3.1

20:01 Magit is just wicked awesome.

20:09 yessss, it works so really.

20:14 hyPiRion: hmm good idea

20:14 amalloy: do you know of a good test-autorunner for clojure.test?

20:15 amalloy: $ watch lein test

20:15 sdegutis: That seems maybe not the best?

20:16 Thought I remembered two ones that started existing.

20:17 amalloy: definitely not best. but i don't really care about autotest, and if i did i'm not sure what a lein plugin would do that's better than just running tests constantly

20:17 bob2: I think midje's auto run thing can run c.t tests?

20:18 technomancy: sdegutis: the in-emacs stuff is fine

20:18 I just think we can do better

20:18 sdegutis: not while network effect is a thing

20:19 technomancy: clojure-test-mode is probably the most widely-used monkeypatch in the whole clojure ecosystem

20:19 well, no, that would be lein test. it's the oldest extant monkeypatch.

20:20 jasonjckn: so happy I went to clojure/west

20:22 I think i'll register with clojure/conj now

20:24 hiredman: the conj tends to come together at the last minute, so you can't register until a few months before hand, and last time I think they sold out before they even announced who was speaking

20:24 sdegutis: Oh hey, clojure-test-mode is nice.

20:25 Okay, so let's say someone wanted to help out and make clojure-test-mode not so monkey-patchy, and has a few spare hours.. what would need to be done?

20:25 technomancy: sdegutis: steal rich's SSH key so clojure.test itself can be fixed

20:25 sdegutis: Can it not be just forked?

20:26 (his ssh key)

20:26 (I mean clojure.test)

20:27 technomancy: nrepl-discover actually does the same monkeypatch https://github.com/technomancy/nrepl-discover/blob/master/src/nrepl/discover/samples.clj#L38

20:27 sdegutis: sorry, being a smartass

20:27 the actual thing that's missing is just more detail about where the failure occurred

20:28 bob2: is it a backwards incompatible change?

20:30 technomancy: I don't think so

20:31 in this case we're storing results on the vars where the failures occured

20:31 seems unlikely that would break anything except code that was already doing that monkeypatch

20:33 sdegutis: Why didn't someone just submit a pull request fixing it for Clojure 1.6?

20:38 How do you assert that nothing is thrown in clojure.test?

20:38 technomancy: deftest

20:38 or just is

20:41 sdegutis: woot thx

20:41 <3

20:48 chare: so what do you guys think of this https://hackworth.be/2014/03/26/clojure-web-security-is-worse-than-you-think/

20:49 brehaut: chare: the article is a bit wacky but the presentation is really good

20:49 chare: so you're saying clojure is broken in security for web?

20:49 brehaut: im not sure where the author got “Building secure Clojure web applications needs to be easier, and requires integrated security frameworks - not standalone libraries!” from

20:50 chare: not at all. but it needs more work

20:50 chare: so does that mean i should stick with ruby on rails?

20:50 brehaut: chare: you need to decide that for yourself

20:50 chare: brehaut i'm going to assume you're a security expert so i need advice

20:51 brehaut: chare: assuming random people on the internet are security experts is probably a poor starting position ;)

20:51 chare: brehaut you admitting you don't know anything?

20:51 brehaut: no

20:53 btbngr: cider-repl gives me nice argument hints in the minibuffer within the repl, but is just not doing anything so nice inside my .clj files, is there a way to improve that?

20:53 cider* not cider-repl.

20:54 scottj: btbngr: maybe eldoc-mode? (I haven't used cider, not sure if it uses eldoc-mode for that)

20:55 btbngr: nope, not as is anyway. hey ho. thanks anyhow.

20:56 scottj: just confirmed nrepl.el uses eldoc-mode for that, so you might want to doublecheck

20:58 btbngr: hmm, okay, sounds like i need to investigate my configuration. ta.

20:58 akhudek: chare: there is no "inherent" problem with clojure prevent one from building a secure app. If you really care about security, you should not be relying on your framework to keep you safe anyways. That's not an argument against secure defaults of course, but rather one that suggests that every web developer should learn about security vulnerabilities anyways.

20:59 rhg135: I'm trying to convert https://www.refheap.com/66390 to tail-recursion or a loop but i'm completely lost. any ideas?

21:01 amalloy: rhg135: you can't recurse multiple times in constant space. you have to either use up some stack, or manage a stack/queue yourself as data

21:02 rhg135: amalloy, i only see 1 recursion there though

21:02 amalloy: rhg135: you're mapping

21:02 that's "the same as" [(f x) (f y) (f z)]

21:02 rhg135: i see

21:02 hmm

21:03 btbngr: scottj: aha, found (cider-turn-on-eldoc-mode) in cider-eldoc.el, thanks, that was the clue I needed.

21:03 rhg135: then cps conversion?

21:03 amalloy: *shrug* sure, if you want, although loop/recur with a local "todo" stack will probably be easier

21:04 rhg135: oh duh

21:04 amalloy: and clojure doesn't optimize tail calls anyway, so you'd have to transform the cps into a trampoline

21:04 * rhg135 facepalms

21:04 amalloy: otoh, if this blows your stack, you're building a *really* deep map

21:04 which might later blow your stack anyway, when you try to work with it, even if you avoid doing so while building it

21:06 chare: why does lein run take like 5 seconds to run a hello world program?

21:16 pjstadig: JVM

21:16 jcromartie: no, Clojure

21:17 amalloy: yeah, it's clojure for sure, not jvm

21:18 jcromartie: https://gist.github.com/anonymous/e3566f573eb7f7fd6bb5

21:19 JVM is fast now. Welcome to 2009.

21:19 verma: what is the general strategy for testing a lein plugin?

21:23 ok, found this: https://github.com/technomancy/leiningen/blob/master/doc/PLUGINS.md

21:23 jcromartie: you can test your core plugin function like any other

21:24 brehaut: python is slower than the jvm on my machine which is pretty funny

21:24 hyPiRion: verma: I generally just think really hard before I deploy it. And I usually do it when I'm not tired.

21:24 It's not your standard unit testing technique, but it's a supplement I guess

21:25 =)

21:32 stcredzero: what's the fastest way to flatten sequences, if you don't give a __ about ordering?

21:34 hyPiRion: ~flatten

21:34 clojurebot: flatten is rarely the right answer. Suppose you need to use a list as your "base type", for example. Usually you only want to flatten a single level, and in that case you're better off with concat. Or, better still, use mapcat to produce a sequence that's shaped right to begin with.

21:35 hyPiRion: afaik, removing the ordering wouldn't help at all

21:35 stcredzero: I'm using sequences aggregate a sequence of collections from pmap, and I really do want something completely flat.

21:36 hyPiRion: stcredzero: so essentially a list of lists? Then (apply concat (pmap ...)) should be sufficient

21:37 stcredzero: To put it another way, what's the fastest way to collect stuff coming out of functions sent to pmap as one collection?

21:37 hyPiRion: Or, if you want to be fancy, you can use an atom, set up your own threadpool, and make each process do (swap! atm concat my-results)

21:38 arrdem: manually managed threadpools ++

21:38 stcredzero: I'm actually not using pmap. I wrote my own pmap like thing using futures that blocks until everyone is finished. I think I'd rather not manage threadpools.

21:39 jcromartie: stcredzero: how about a set?

21:40 stcredzero: Will just mapping futures mess things up? What thread pool are those coming out of? How big?

21:40 hyPiRion: jcromartie: will remove duplicates, which is not exactly the same as unordered?

21:40 jcromartie: don't forget about laziness

21:40 hyPiRion: depends on what he wants

21:40 stcredzero: jcromartie: set might work. I'm tempted to use swap! and cons. I'm using mapv and doall to get rid of laziness in this case

21:41 jcromartie: OK so, pmap produces a seq of seqs?

21:41 and you want a single collection of the values of that inner seq?

21:41 stcredzero: jcromartie: yes, it would produce a seq of seqs if I just pumped it through pmap

21:42 jcromartie: and yes, I just want what would be the flattened seq

21:43 jcromartie: what about… (reduce into #{} (pmap whatever coll))

21:43 hyPiRion: stcredzero: (let [atm (atom [])] (mapv deref (mapv #(future (swap! atm into (list-of-elements))) unprocessed-data)) @atm) sounds sorta what you'd like

21:43 but I'm not sure it's very nice wrt. threading

21:44 stcredzero: not nice wrt threading is bad.

21:45 jcromartie: define "nice"

21:45 nice as in: well-behaved? or nice as in: using as many cores as fully as possible?

21:45 hyPiRion: stcredzero: I mean, pmap is already bad. Perhaps https://github.com/TheClimateCorporation/claypoole would help you here

21:45 stcredzero: hyPiRion: yes, so I've heard, so I'm not using pmap.

21:46 hyPiRion: stcredzero: so well, the solution I presented delegates all its work to the future threadpool. It's hard to control, but perhaps that's suitable for your type of work

21:47 *harder

21:47 jcromartie: pmap uses futures

21:48 stcredzero: hyPiRion: how big is the future threadpool? (+ (count cores) 2)?

21:48 arrdem: stcredzero: I think it's bigger than that...

21:49 jcromartie: look

21:49 on my 4-core machine, (reduce into #{} (pmap f coll)) is 4X faster than with map

21:49 I think that's what you want

21:50 (for a long running op where threading overhead is negligible)

21:50 stcredzero: jcromartie: however, this is for cpu bound things which are still short. (Will be firing off many times per second.)

21:51 jcromartie: just test it

21:51 stcredzero: claypoole looks very interesting

21:52 hyPiRion: stcredzero: to answer your question, the future threadpool uses the same threadpool as the agent threadpool. That one grows without any bound, but will reuse threads which are done with their work.

21:54 stcredzero: hyPiRion: so I think this means that I should keep claypoole in mind, but just use my mapv-futures-thing until I see an issue.

21:54 arrdem: unbounded threadpools are suckage.

21:54 jcromartie: are you positive that your mapv-futures-thing is any better than pmap?

21:55 hyPiRion: jcromartie: pmap is horrible if you have some large spikes in working time here and there. Try to check out how fast (pmap #(Thread/sleep %) (concat [1000] (repeat 0 (+ 2 (.. Runtime getRuntime availableProcessors))) [1000])) is

21:55 stcredzero: jcromartie: in that I don't want lazy evaluation for this part, yes.

21:55 hyPiRion: whoops, flip order of the arguments in repeat

21:56 jcromartie: reduce forces the evaluation

21:56 but I'm just saying, if you're using futures

21:56 pmap uses futures

21:58 stcredzero: claypoole looks very attractive. I'm using this for a parallelized game loop, so lazy evaluation is actually dangerous. Also, I can just keep the thread pool sized (+ cores 2) and keep it around for the game loop to use.

22:00 hyPiRion: jcromartie: The issue is that a slow task will block calls later in the list. E.g. if I have a dual core processor, then the 4th task after any task sent off will not be executed before that task is completed

22:02 arrdem: stcredzero: for that application probably what you'll wind up doing is just spinning off N threads and using atoms to implement message queues. Unless your drawing engine is single threaded and you need to coalate all the drawing results rather than splatting them directly "out".

22:02 jcromartie: ,(time (doall (pmap #(Thread/sleep %) [1000 0 0 0 0 0 0 0 0 0 0 0 0 0 1000 0])))

22:02 clojurebot: #<SecurityException java.lang.SecurityException: no threads please>

22:02 jcromartie: well anyway, for me, it was 1s

22:03 stcredzero: arrdem: it's a multiplayer game. It doesn't "draw" so much as send maps over websockets

22:04 hyPiRion: &(Thread/sleep 1000)

22:04 lazybot: ⇒ nil

22:05 hyPiRion: (time (doall (pmap #(Thread/sleep %) (concat [1000] (repeat (+ 2 (.. Runtime getRuntime availableProcessors)) 0) [1000]))))

22:05 &(time (doall (pmap #(Thread/sleep %) (concat [1000] (repeat (+ 2 (.. Runtime getRuntime availableProcessors)) 0) [1000]))))

22:05 lazybot: java.lang.SecurityException: You tripped the alarm! pmap is bad!

22:05 hyPiRion: oh, but Thread/sleep is fine? lazybot, I don't get you.

22:06 jcromartie: hyPiRion: I see, it's when it falls on the particular placement in the sequence?

22:08 stcredzero: arrdem: also, it's a game that needs a discrete grid and I'd also like to have discrete time steps. agent-y/actor-y nondeterminacy is bad

22:08 hyPiRion: jcromartie: right, when there's one really heavy function call, the list won't proceed beyond some element behind it because pmap is lazy

22:08 semilazy, rather

22:11 turbofail: sounds like a job for claypoole

22:23 rhg135: amalloy, am I incorrect in thinking that `map` since it's lazy wouldn't cause a stack explosion

22:24 amalloy: rhg135: that's too general a question to really have an answer

22:24 you can absolutely blow the stack with map, via like ##((fn f [xs] (map f xs)) '(1))

22:24 lazybot: java.lang.IllegalArgumentException: Don't know how to create ISeq from: java.lang.Long

22:25 amalloy: &((fn f [xs] (map f [xs])) '(1))

22:25 lazybot: java.lang.StackOverflowError

22:25 rhg135: oh i see now, amalloy

22:25 back to the drawing board :(

22:25 can't figure out what to put in the queue

22:28 zenoli: How does one go about reading a file into a Buffy buffer? I've been beating my head against this for an hour.

22:38 amalloy: rhg135: why are you trying to make this tail-recursive? it seems really unlikely that that will lead to a program that's better in any interesting way

22:39 rhg135: amalloy, it's for a build tool if this (dependency graph generator) blows the stack large project would be no-ops

22:42 Frozenlock: If I put a CSS file in the resources of a library, will it be available for a project using this library?

22:43 amalloy: hmmm. do you have to build a big nested map? it seems like a one-level map of "all the things X depends on" should be useable (not sure if it needs to be transitive dependencies or direct)

22:45 rhg135: amalloy, yeah you know f*** it this is a POC and i'll try that

22:47 TravisD: Now that's a TLA that you don't see every day

22:49 lemonodor: zenoli: i don’t know, and i haven’t tried buffy, but i liked using https://github.com/ztellman/gloss pretty well,

22:50 zenoli: lemonodor: Thanks...does it deal well with dynamic frames?

22:52 lemonodor: i didn’t try. i was using it to parse AR.Drone telemetry data, which uses a tagged format, but i used my own logic to delimit tagged frames

22:53 zenoli: I just managed to finally get it to accept a file object...the version in Clojars is -beta1, which seems to not like wrapped buffers at all.

22:57 lemonodor: https://github.com/wiseman/turboshrimp/blob/master/src/com/lemondronor/turboshrimp/navdata.clj if you want to see an example

22:59 bob2: TravisD, depends where you work!

22:59 zenoli: Woo, just managed to successfully extract a string!

23:01 lemonodor: Thanks...that's really helpful. I'll poke at gloss as well, since I'm not deeply committed at this point.

23:06 lemonodor: btw, one reason i did the tagged frame logic myself was to do lazy decoding, so i didn’t go to the overhead of parsing every frame if it wasn’t being used.

23:07 go to the overhead? i meant go to the trouble.

23:10 zenoli: I'm trying out a modfile parser for overtone...my first attempt is morbidly inefficient, just sucking in the entire file.

23:11 Java I/O is a terrible twisty maze of classes, all alike.

23:11 brehaut: the dwarf throws his axe.

23:11 it misses

23:12 zenoli: plugh

23:21 malyn: lijnen___: I think it's here: https://github.com/swannodette/swannodette.github.com/blob/master/code/blog/src/blog/instrument/core.cljs

23:22 zenoli: Hmm...can you specify endianness of the representation in gloss? I'm not see anything along those lines in the docs for either it or buffy.

23:23 lemonodor: yes, there are -be and -le versions of each type. you might be able to set the endian-ness of the bytebuffer you give it, i’m not sure

23:23 stcredzero: so, if anyone wants to hop onto my online grid/map engine for my Clojure MMO, I'm running a stress test at http://raidsphere.com

23:24 It's not yet a game.

23:24 zenoli: lemonodor: Ah, hadn't thought to check the classes I was passing in.

23:28 Yep, that does it. Excellent.

Logging service provided by n01se.net