#clojure log - Jan 14 2016

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

2:17 lokien_: Hello noncom|2

2:17 * lokien_ waves

2:20 noncom|2: lokien_: hi:D

2:21 just woke up, dressing up to go to job

2:21 and you?

2:22 lokien_: me has no job :^) so just shower

2:23 and I'll read about all these hexagons and cljs and reagent and stuff

2:24 noncom|2: oh right!

2:24 lokien_: I wonder, why not brutha?

2:25 noncom|2: what is brutha?

2:26 lokien_: "A simple and functional ClojureScript interface to React."

2:26 noncom|2: oh

2:26 lokien_: "Unlike Om and Reagent, Brutha is unopinionated on how you handle your application state. It doesn't include cursors or specialized atoms, instead relying on you to call a mount function with new state data. This is useful when you want to manage your application state yourself"

2:26 it's interesting

2:28 noncom|2: well, actually what you choose, depends on how you want it to be... i was working with reagent.. afaik it does not care about the state too.. this description could fit it too. not sure what's different

2:28 lokien_: hmm, so I'll try reagent, cause it's more popular here

2:28 noncom|2: but i am not well-experienced on all the cljs-react interfaces

2:28 lokien_: brb, have fun at your job!

2:29 noncom|2: yeah, ok, thank! :)

2:29 also, there's #clojurescript

2:29 but sometimes there's just not many people and talking here can be more productive.

2:30 but #clojurescript is nice, there are good cljs-specific discussions

2:33 ah, just re-read the description you posted - yes, reagent uses special atoms which replace usual atoms

2:33 changing them triggers the redraw

2:33 be careful not to get in a dead loop then

2:35 i use reagent and mostly like the experience. but also i will try the other things some time

2:41 lokien_: noncom|2: this family is fine for me :^)

2:42 noncom|2: eww, dead loops. I knew there was a hook

4:10 noncom: lokien_: but if you follow the React guideline that state should not be modified from the rendering code, you won't get into that trouble. the trouble is that my code was heavily relying on lazy initialization of some render-specific structures. so i had to separate things more preceisely, ok. but originally i got into some loops. they're easy to debug though

4:23 django_: #lesswrong

5:26 lokien_: noncom: are cljs' errors better than clj's? I heard they are

5:27 jonathanj: i was reading <http://stuartsierra.com/2016/01/09/how-to-name-clojure-functions> and the author mentions "Don't repeat the name of the namespace"

5:28 which is something i currently have a problem with, i have a namespace ns.pdf.crush and i have some functions related to crushing (compressing) the document, notably `crush-document` which means if addressing it by an ns alias it's `crush/crush-document`

5:29 MJB47: he also mentions something about verb-functions iirc

5:29 so i wouldnt worry about it :)

5:29 jonathanj: unfortunately `document` is a bad name, so the only other option i can think of is moving it to ns.pdf

5:29 MJB47: not to mention those are just guidelines

5:30 they arent hard rules

5:30 jonathanj: sure, but it was something that was bugging me before i read the article

5:30 what's the stance on putting an implementation in src/x/pdf/crush.clj but using the ns x.pdf?

5:30 is that confusing or bad etiquette?

5:31 MJB47: the compiler might moan at you

5:31 iirc proj.something.yeah

5:31 actually expects a file to be at /proj/something/yeah

5:33 jonathanj: mmm, parts of clojure.core are actually structured this same way

5:33 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_deftype.clj

5:33 MJB47: i might be wrong

5:34 i just recall having an issue with doing that when i first started using clojure

5:34 oh

5:34 that file doesnt have its own namespace

5:34 jonathanj: but it's kind of weird, you have to call (load) from the "parent" file and stuff

5:34 MJB47: it just adds itself to clojure.core (using in-ns)

5:34 jonathanj: http://stackoverflow.com/questions/4690758/splitting-a-clojure-namespace-over-multiple-files

5:46 seems a bit weird

5:50 kungi: How can I build a checkbox set with reagent forms? Im trying to use multi-select with checkboxes but keep failing at it.

5:53 powered: kungi, can you build it with html?

5:53 reagent just uses hiccup style dsl to generate html

5:54 kungi: powered: yes I could but then I have to build the data binding myself. I really would like to use reagent-forms for this

5:55 powered: that's my point, just use reagent to build similar html

6:02 noncom: lokien_: i don't think so. all in all i find clj errors pretty awesome, since they are java errors to me, and i come from java. and java has one of the best (if not the best) error-reporting mechanism that i have known

6:03 lokien_: cljs errors OTOH are often riddled with JS errors, which are sometimes very hard to make sense of or even locate. on top of there there are cljs-specific errors, like a keyword cannot start with a digit, which is kinda present in clojure spec, but not popular, and clojure supports them anyway and many things silently rely on them..

6:04 lokien_: or there are some issues with shadowing, since variable concept of JS is totally different from java.. it's possible to shadoe or even maybe redefine an imported namespace locally in a function

6:05 kungi: the more you rely on frameworks the more frmeworks rely on you

6:08 lokien_: so with keywords like :42de98f987a7ccc77b i was getting totally uninformative messages and spent like 2 days analyzing the dump of my database to find what made the cljs edn reader choke

6:09 and this type of keywords is a hex id from a mongo db, which is perfectly working fine within clojure itself

6:54 gfdhjf: bad uncle is inserting his penis into 10 year old girl's vagina causing her to moan in agony because they both are niggers

7:01 burn all jews in oven

7:08 lokien_: noncom: oh my god

7:09 jsabeaudry: When given the choice between apply and reduce, which is better? (i.e. (apply max coll) vs (reduce max coll) )

7:10 powered: apply

7:11 gfdhjf: innocent children deserve to be beaten to death

7:11 TMA: ,(apply max (range 1 1000000))

7:11 clojurebot: 999999

7:12 noncom: jsabeaudry: i wonder for the criterion on "better" though

7:13 gfdhjf: sieg heil

7:13 powered: (time (apply str (repeat 10000 "aaaaaa")))

7:13 noncom: i can only think of speed, so probably you can (time ...) your test and see what timings you get on 10th run or so (when the JVM warms up)

7:13 powered: try the same with reduce str and it will go orders of magnitude slower

7:13 TMA: jsabeaudry: other languages have a limit on maximum number of arguments to a function which apply hits but reduce doesn't

7:14 gfdhjf: child rape is fun

7:14 noncom: lokien_: yeah, basically most of the bad that comes out of cljs in the underlying bad of js itself

7:14 i don't really like js for that sake. it can be a hell to debug

7:14 cljs makes it a LOT better

7:15 but be prepared for the js-specific fun

7:15 and css fun

7:16 jsabeaudry: interesting, so in general apply is preferrable but there might be cases where only reduce would be possible

7:17 the_nonameguy: hey, how would I go about defining a prismatic schema that says that a map should optionally contain keywords or strings, mapped to strings?

7:17 as I see there is no or function

7:17 (s/defschema X {(s/optional-key s/Str) s/Str (s/optional-key s/Keyword) s/Str})

7:18 noncom: jsabeaudry: yeah, things like "or" and "and" cannot be applied, them are maceos

7:18 the_nonameguy: this didn't work either

7:18 noncom: *macros

7:20 the_nonameguy: maybe you can make 2 schemes, catch their exceptions and OR on them... a bit hacky but should work

7:21 wonder if there's a way to do this in terms of the DSL

7:21 the_nonameguy: at that point it's cleaner to do a predicate fn

7:21 noncom: the_nonameguy: if you wont find an answer, maybe you could post an issue on github with the question

7:23 gfdhjf: burn all jews in oven

7:23 burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven burn

7:23 all jews in oven burn all jews in oven burn all jews in oven burn all jews in oven

7:27 the_nonameguy: noncom: solution: (s/defschema Headers {(s/cond-pre s/Str s/Keyword) s/Str})

7:27 noncom: the_nonameguy: wow, elegant!

7:28 the_nonameguy: thx

7:28 noncom: i want to employ schema in my projects too. currently i have very limited experience with it..

7:30 the_nonameguy: it's not bad, but take care not to overuse it

7:30 it's best at the edges of your system

7:39 kungi: noncom: yes you are right

7:48 yunfan: hi, which function just return the argument it accept?

7:48 powered: identity

7:49 yunfan: powered: thanks

7:52 lokien_: noncom: "fun" D:

7:53 yunfan: are there any functions which could control how many depths we want while flatting collections?

7:53 for eg, i only want it to flat only 1 depth

7:53 noncom: yunfan: maybe in some libs, not in the core

7:54 yunfan: you can though do (apply concat []) to imitate this

7:54 for 1 level

7:55 yunfan: noncom: i think i need a common ways

7:57 noncom: yunfan: well, https://www.google.ru/search?q=clojure+flatten+level&oq=clojure+flatten+level&aqs=chrome..69i57.287j0j9&sourceid=chrome&es_sm=122&amp;ie=UTF-8

8:00 yunfan: noncom: those ways would failed for this: (apply concat '((1 2) 3 (4 5 (6 7))))

8:00 while flatten not

8:01 noncom: yunfan: yeah, well, you cold replace concat with a more sophisticated dunction that ensures that there's a seq

8:01 ,sequence?

8:01 clojurebot: #error {\n :cause "Unable to resolve symbol: sequence? in this context"\n :via\n [{:type clojure.lang.Compiler$CompilerException\n :message "java.lang.RuntimeException: Unable to resolve symbol: sequence? in this context, compiling:(NO_SOURCE_PATH:0:0)"\n :at [clojure.lang.Compiler analyze "Compiler.java" 6688]}\n {:type java.lang.RuntimeException\n :message "Unable to resolve symbol: seque...

8:01 noncom: ,seq?

8:01 clojurebot: #object[clojure.core$seq_QMARK___4355 0x531e966b "clojure.core$seq_QMARK___4355@531e966b"]

8:01 noncom: ,(seq? [1])

8:01 clojurebot: false

8:01 noncom: hmmm

8:02 ,(sequential? [1])

8:02 clojurebot: true

8:02 noncom: ,(sequential? 1)

8:02 clojurebot: false

8:02 noncom: yunfan: here ^

8:04 yunfan: noncom: ok

8:05 noncom: so you can do (fn [e] (if (sequential? e) e [e]))

8:06 prior to concat

8:56 engblom: What has been happening to clojure.org?

8:57 I wanted the cheatsheet, but the whole site seems to be down.

8:58 MJB47: http://jafingerhut.github.io/cheatsheet/clojuredocs/cheatsheet-tiptip-no-cdocs-summary.html

9:09 juanjo_: hi

9:09 how can i run an specific test from clojure sources?

9:10 noncom: juanjo: ummm by loading the project and executing the specific function?

9:10 juanjo_: i was expected some command

9:10 but ok

9:10 thanks

9:12 noncom: juanjo_: but command to waht? the tests are just code, and you can deal with it just like usual...? there's no specific testing framework build-in in clojure core

9:15 engblom: yep, o see it's down...

9:16 engblom: ummm actually the check says it's up..

9:17 hmmmm but can't accesss it through a proxy though :/

9:49 juanjo_: noncom: the answer was here http://dev.clojure.org/display/community/Developing+Patches under Run an individual test

9:51 sohail: what's the right way to set a "production url" vs a test url in a lein project?

9:51 I need to generate links with this url and in testing, I want it to go to my local server but in production I want it to point somewhere else

9:52 jonathanj: there are probably many ways

9:52 one possible way is to use environ, or read the value out of a config file

9:53 reading configuration data out of project.clj is, imho, hard enough that you should probably consider it a mistake

9:53 sohail: I was thinking of environ, actually

9:54 so (env :theThingInMyProject.clj)?

9:55 noncom: sohail: yeah, environ is probably the best option, however, you code example seems a bit strange

9:56 juanjo_: so it's just the same as i said - you load the project and run a particular test from the repl

9:56 juanjo_: i would be surprised if it was different for a lisp

9:56 sohail: noncom why is it strange?

9:58 noncom: sohail: it's camel keyword with a file extension... so you code a clojure source file name into a keyword? not that it's impossible, but um.. strange.. not sure if environ works that way also..

9:58 but it might

9:58 sohail: oh it was just an example

9:58 noncom: yeah :)

9:58 sohail: the real thing would be something like (env :base-url) I guess

9:58 noncom: yeah

10:01 sohail: it's so easy to deploy onto heroku. Not sure how much pain I am in for in the future.

10:02 noncom: sohail: afaik heroky is pain just for its money

10:02 all else is rather fine there

10:02 one of the most expensive hostings i've seen so far

10:03 sohail: hm

10:03 noncom: but they like, very popular and are always on the edge and stuff

10:03 afaik

10:03 sohail: pricing doesn't seem TOO bad

10:04 MJB47: heroku is incredibly easy to set up and use

10:04 i have to commend them for that

10:04 but it is incredibly expensive :(

10:05 noncom: jsonmurphy: well, $7 per 512MB ram and you pay additional costs here and there if you overflow the limits

10:05 MJB47: ive always sort of used them to start something

10:05 and then moved to AWS or a dedi or something if things get bigger

10:05 noncom: maybe $30 a month is not much for someone, but it definitely sensible for me and some other folks

10:06 MJB47: im more talking about when you have a cluster of 10 4gb machines the price begins to get noticable compared to competitors :P

10:06 noncom: dang, why i do i always forget to put in the "to be" verbs lately?

10:06 MJB47: we used to have our production stack on heroku, but we had to move

10:06 noncom: oh, so you're on more than a hobby plan

10:07 MJB47: for that yes

10:07 i have lots of other things on heroku free tier/hobby stuff

10:07 mostly for the simplicity of it

10:07 takes literally 3 minutes to go from nothing to server online

10:07 and thats awesome

10:08 noncom: yes, i totally agree for that

10:08 codefinger: MJB47: i would agree that the simplicity is a part of what you're paying for on Heroku. Its more than just an IaaS like AWS.

10:08 noncom: someone is paying for it to be so :D

10:08 codefinger: (i work at Heroku)

10:08 MJB47: definitely codefinger

10:09 codefinger: most shops that run on Heroku do so because they don't want to pay an ops team to handle routing, back-ups, failover, etc. so heroku does it

10:10 noncom: yeah, that's a good feature actually

10:12 MJB47: and entirely accurate

10:12 noncom: i love the design!

10:12 MJB47: heroku is an awesome service imo

10:12 codefinger: MJB47: <3

10:12 MJB47: (can i has free credit now?)

10:12 :P

10:13 codefinger: i'm not in charge of that part unfortunately :)

10:13 MJB47: dammit

10:13 so close

10:13 jonathanj: codefinger: do you hang around in #clojure because you're a hobby Clojurist or because you use it at Heroku?

10:13 codefinger: i basically just break stuff in the clojure buildpack :P

10:13 jonathanj: ah

10:13 codefinger: jonathanj: both

10:13 so if you've ever deployed to Heroku and it didn't work -- it's probably my fault

10:13 jonathanj: does Heroku use Clojure internally?

10:14 codefinger: jonathanj: yes

10:14 jonathanj: i've never deployed anything to Heroku, i once watched someone deploy some Haskell there though

10:14 codefinger: but still predominately a ruby shop

10:14 jonathanj: codefinger: interesting, what do you guys use Clojure for?

10:15 codefinger: hmm, not sure i can say :/ i has to do with how we deploy, manage and release buildpacks for production

10:16 jonathanj: if you ever feel like trying, here's the fastest way https://twitter.com/codefinger/status/634771452760301568

10:16 sohail: is there a way to deploy from bitbucket? it' skind of annoying manually pushing to heroku

10:16 jonathanj: cool :)

10:17 sohail: #clojure/#heroku-support lol

10:18 codefinger: sohail: we have some very good Github integrations https://devcenter.heroku.com/articles/github-integration but for bitbucket you would probably want to supplement it with something like codeship or a CI to deploy from

10:19 there may be a post-deploy hook thing too?

10:20 sohail: I figured, thanks codefinger

10:54 TimMc: codefinger: Oh, don't feel too bad -- the last time things broke, it's because fetching buildpacks pinned to commit IDs was broken.

10:56 codefinger: TimMc: oh i remember that. it was fixed though right?

11:11 franksn: linuxbbq

11:13 sdegutis: How do you generally prefer to have a main template that you return from most of your routes? Do you make it a function that you call which returns a Ring map?

11:14 SevereOverfl0w: sdegutis: I wrote a little thing I called "cloak" for wrapping up handlers in a template.

11:15 I may have not understood the question.

11:15 TimMc: codefinger: Dunno, I switched to a tag and it's working. It was a bit of rude surprise to resume work on a project and find that my build had broken in the meantime. :-P

11:15 Eh, I shouldn't harp on this too much, deployment is hard. :-)

11:15 SevereOverfl0w: But you could write a protocol, which turns strings into a ring map. But again, I don't think I understand.

11:15 Compojure has a great protocol for it: https://github.com/weavejester/compojure/blob/master/src/compojure/response.clj

11:16 sdegutis: SevereOverfl0w: but that protocol kind of requires you return a new type

11:16 codefinger: TimMc: :( feel free to ping me if you have anymore issues

11:16 sdegutis: SevereOverfl0w: since for all the basic types you could use, it already has implementations

11:17 SevereOverfl0w: Now I'm confused as to what you're asking sdegutis

11:18 sdegutis: Welp.

11:19 SevereOverfl0w: sdegutis: Could you try again please? :D

11:20 sdegutis: Nah.

11:29 WorldsEndless: I'm looking for a deep sort function for nested maps, so each level is sorted by a particular key

11:29 (presumably returning a sorted map)

11:39 I guess some recursive form of sorted-map-by is the answer, but I haven't quite figured out how to put the pieces together

11:45 justin_smith: WorldsEndless: something like (clojure.walk/postwalk (fn [e] (if (map? e) (sorted-map-by some-key e) e)) m)

11:48 oh, that would be (into (sorted-map-by some-key) e)

11:49 domgetter: How do you stop the execution of a form in lein repl without exiting the repl?

11:49 justin_smith: never mind, sorted-map-by takes a comparator, and only compares keys, not values, which is likely not what you wanted

11:49 domgetter: I'm on Windows on Leiningen 2.5.4

11:49 justin_smith: domgetter: with lein repl, Control-C will do that

11:49 WorldsEndless: justin_smith: Well, I've already inserted an :index key to each thing, so I can sort by key

11:49 domgetter: Control-C doesn't do anything

11:50 justin_smith: WorldsEndless: into the key of each thing? it doesn't sort by the maps, just by the keys

11:51 WorldsEndless: justin_smith: So I have {:index "1" :submap1 {:index "1A"} }

11:51 domgetter: justin_smith: You think it might be a Windows issue?

11:51 WorldsEndless: Err, add to that :submap2 {:index "1B"} etc

11:51 justin_smith: WorldsEndless: it would sort :index and :submap, and ignore the values

11:51 WorldsEndless: I see

11:52 justin_smith: domgetter: I'm really not sure how things work with windows - if there is a usual "interrupt" keystroke for the windows terminal you could try that

11:52 sohail: so is it possible to connect via cider to a repl running over http?

11:52 domgetter: justin_smith: what keystroke is that?

11:52 Control-D ?

11:52 justin_smith: domgetter: sorry, I don't know windows

11:53 domgetter: ah okay, fair enough. Thanks

11:53 justin_smith: on *nix Control-D is EOF, not interrupt

11:53 WorldsEndless: I think Windows is Alt-. as per http://wiki.squeak.org/squeak/899

11:53 justin_smith: domgetter: google found this, but I have no windows machine to test any of this on http://stackoverflow.com/questions/800521/linuxlike-ctrl-c-keyboardinterrupt-for-the-windows-cmd-line

11:53 WorldsEndless: (interupt key)

11:54 justin_smith: domgetter: it suggests control-break also

11:55 domgetter: also, very few leiningen devs use windows, so windows is a little less polished as a lein platform, I am sure they would accept fixes or bug reports though

12:00 domgetter: justin_smith: control break does a thread dump

12:01 unless it's doing control-pause and I don't know how to tell it to use the break part of my pause/break key

12:04 justin_smith: people who use ssh (probably all of us here): cho 'UseRoaming no' >> /etc/ssh_config

12:05 they are not going to reveal the issue until they have a fix, but that closes the vuln.

12:05 s/cho/echo of course

12:06 it might be /etc/ssh/ssh_config on your box

12:35 TimMc: justin_smith: A malicious/compromised remote server or a MITM can use roaming support to reveal chunks of client memory, possibly including key material.

12:36 Isn't it exciting when security-sensitive applications are written in a non-memory-safe language?

12:37 MJB47: yes

12:37 lets rewrite the security ecosystem in clojure :)

12:37 wut could go wrong?

12:38 wink: sshd would take longer to start than the server

12:38 TimMc: Even better, use swearjure. Not only is it memory-safe, you avoid all floating-point bugs! (Because it doesn't support floats...)

12:38 MJB47: I was thinking maybe ocaml. :-)

12:41 (Correction: No MITM exploits for this bug, only compromised servers.)

12:42 MJB47: you arent allowed to think about ocaml

12:42 this is clojure chat

12:46 * TimMc guiltily slides grenchman out of sight

12:46 TimMc: Actually, I still need to give that a shot.

15:29 justin_smith: any pl.danieljanus.tagsoup users? or anyone who might be able to explain why every time I get a lazy-parse-xml result from tagsoup it's creating a thread that never exits?

15:33 I found the issue - this line creates a future that won't exit if you stop reading results https://github.com/nathell/clj-tagsoup/blob/master/src/pl/danieljanus/tagsoup.clj#L219

15:33 * justin_smith is off to make a PR

16:18 rhg135: is there a way to atomically set a per thread binding?

16:22 justin_smith: rhg135: isn't binding sufficiently atomic, given it can't affect or be affected by other threads?

16:23 rhg135: ah, that's true, I forgot about that

16:23 thx

16:26 blake__: Is there a doc on how to add clojurescript to your clojure app? I thought there was but now can't find anything.

16:34 arrdem: blake__: figwheel is likely going to be your starting point.

16:35 blake__: arrdem: Yeah, I just created a new figwheel app and was looking at what I needed to add. Unless there's a lein modify-template-to-include command. =P

16:35 justin_smith: also there is a clojurescript quick-start, where first you can just compile cljs from your regular repl, then migrate that to a lein task, and finally that can be migrated to figwheel

16:35 blake__: justin_smith: Not a fan. Was trying to avoid that.

16:35 justin_smith: it was very enlightening to see how simple cljs was with zero tooling.

16:35 blake__: its' simpler than you think.

16:36 blake__: justin_smith: Perhaps it's changed since the last time I looked at it. It was pretty ugly...a year ago?

16:36 justin_smith: blake__: (cljs.build.api/build "src" {:output-to "out/main.js"})

16:36 that's literally it

16:37 that's all the tools are doing for you (except the config map gets bigger and uglier to put inline of course)

16:37 https://github.com/clojure/clojurescript/wiki/Quick-Start

16:38 any hints on how to make a future exit? for whatever reason future-cancel is not doing the trick, and this thread leak is terrible

16:41 arrdem: justin_smith: thread/exit?

16:41 justin_smith: or do you need to kill it remotely?

16:42 Gonna be spending the afternoon on Grimoire and the Cheatsheet if there are particular pain points in those directions.

16:42 justin_smith: arrdem: an xml processor creates the future to process its input so it can deliver the result as a lazy-seq. I tried modifying it so it returned the future so I could cancel it, but this is not doing the trick. code outside scope has to be able to decide when enough data is read.

16:43 if I keep reading until input runs out, the thread exits as expected

16:44 but if I just read until I find an item I want, it leaves a thread hanging until the vm dies, seemingly impervious to future-cancel calls

16:44 amalloy: future-cancel just calls .interrupt probably, which can only stop a threat that's blocking on a method that can throw InterruptedException

16:44 future-cancel has never been reliable

16:45 justin_smith: amalloy: so maybe I don't want this lazy-seq abstraction, and I should just do the event processing in thread

16:45 amalloy: yes

16:45 justin_smith: but it was someone else's code and doing it in terms of lazy-seqs seemed so nice

16:45 OK

16:46 amalloy: or just fully read the stream, if you know it won't be so big that's a problem

16:46 justin_smith: amalloy: stream is random junk from the intarwebs

16:46 amalloy: start up another future to consume that other future. hot future-on-future action

16:46 justin_smith: so I feel much better just closing it up and being done

16:46 hahaa

16:46 amalloy: well, you're already reading arbitrarily far into a stream that's random junk from the internet

16:47 stopping early is an improvement, but not really a guarantee of anything in particular

16:47 justin_smith: that's true

16:48 someone is going to start tweeting links to /dev/random connected to an http port, just to fuck with me

16:48 arrdem: dibs

16:48 amalloy: arguably you would be getting what you deserve

16:48 (also, someone is probably already doing this)

16:49 justin_smith: what about just truncating the input stream before you feed it to the xml parser?

16:50 (process (take 1000000 input)) or whatever

16:50 and then you can fully read without wory

16:51 justin_smith: amalloy: that would work except our cutoff is content based - we are searching for a specific tag (we don't care where or how it is nested so streaming works nicely, but we are looking for a specific tag)

16:51 amalloy: right, but you don't want to get stuck on /dev/random

16:51 justin_smith: though I guess I could combine the truncation with the tag search

16:51 amalloy: right

16:56 * TimMc sends justin_smith (concat \< (repeat \a))

16:56 TimMc: err

16:57 (concat "<" (repeat \a))

16:57 You'll never stop parsing the first tag!

16:57 arrdem: ehehehe

16:57 evil input is evil

16:57 justin_smith: yup, yup

16:58 TimMc: I wonder if this SAX impl is smart enough to be like "OK no tag is bigger than 40k" and just throw it away

16:58 I guess I could test it

16:58 arrdem: I mean... really it should be a bound on the tag name, and then a seperate bound on the k/v pairs etc.

16:59 but that's hard and I've never met a parser that does that

16:59 justin_smith: TimMc: in the tests that led to using tagsoup, I found out that you can crash hiccup's html generation just by nesting elements deeply enough

16:59 and "deeply enough" is well less than 100

16:59 I thought it would be elegant to auto-generate the deeply nested html, to ensure I could consume things that deep

17:00 instead I used emacs macros to generate the input

17:11 lokien_: noncom: apparently, I'll have to do this project by myself

17:13 TimMc: justin_smith: 128k should be enough for anyone

17:13 justin_smith: TimMc: for tag names? yeah one would hope

17:13 "but I want each tag to be an animated gif"

17:15 TimMc: sounds reasonable

17:24 neoncontrails: Does uberjar do static analysis? Is there a performance advantage to compiling your query patterns in advance vs. populating the database dynamically in the REPL?

17:28 justin_smith: neoncontrails: clojure really doesn't do any optimizations automatically, it relies of hotspot mostly

17:29 neoncontrails: justin_smith: I see. So is uberjar strictly a convenience?

17:30 justin_smith: uberjar is for putting all your deps in one jar. There is a related action (that uberjar typically does) of aot compiling

17:31 you give it a namespace to compile, and it aot-compiles that namespace and all its deps recursively

17:31 clojurebot: Gabh mo leithscéal?

17:35 neoncontrails: That sounds advantageous. The reason I ask is uberjar finds my class file too large. To run postgresql, I had to remove the methods for populating the database – which isn't a huge deal because I could just do it in the REPL

17:38 But it would seem to me like if you're inserting a bunch of large, static tables into a database, that's precisely the kind of operation static analysis would be helpful for

17:39 justin_smith: neoncontrails: the best way to deal with class files being too large is to move more things into smaller functions

17:39 amalloy: no, it's to not embed large static files into your program as source code

17:39 read them from disk as data files

17:39 justin_smith: well that would help too, sure!

17:41 domgetter: no, no, no, if they're too big, make them bigger until you have integer overflow. problem solved

17:44 neoncontrails: Sorry, this is my first database app and I'm trying to get a feel for best practices. amalloy When you say "read them from disk," you mean dump the tables to a CSV or similar and just read from that?

17:51 justin_smith: or just edn formatted file

17:52 and you can load them from inside your own jar with io/resource also

17:56 neoncontrails: I didn't know about edn. This is great

17:59 blake__: So, I've done the QuickStart and gotten cljs code to compile. All the examples specifically point to the local cljs.jar you download first thing.

18:00 Yet none of the pre-built stuff (like figwheel) does. I don't even have a cljs.jar on my system, except for the one I Just downloaded.

18:03 neoncontrails: blake__: that's the magic of Leiningen. No need to download the cljs.jar, your project.clj will grab it for you in the background

18:04 blake__: neoncontrails: And does what with it? I'd think it'd be on my hard-drive somewhere. Different name, maybe?

18:06 justin_smith: blake__: all lein deps are under ~/.m2/

18:06 neoncontrails: blake__: it is. Not the jar, but the files themselves

18:07 justin_smith: neoncontrails: cljs.jar will be in there somewhere, maybe with a different name

18:08 blake__: clojurescript-build-0.1.9

18:08 neoncontrails: interesting. oh right, Leiningen transfers jar files only

18:10 blake__: depending on what IDE you use, you should be able to quickly reference those files should you ever need to. Cursive loads them alongside my project under 'external dependencies'

18:11 blake__: neoncontrails: I'm using Cursive (registered, cfleming!).

18:13 I haven't been using it for builds, though. Been doing that on the command-line.

18:13 neoncontrails: In your project view on the left hand side, you'll see an icon at the bottom minimized by default. You'll find cljs there once you successfully import it

18:14 blake__: Oh, "External Libraries"?

18:14 neoncontrails: That's the one

18:15 blake__: Yeah, it's not a matter of including it--Cursive really is great with that stuff--but the building thereof.

18:15 I've now got a workflow where I expect to go from the backend compojure app and the frontend clojurescript.

18:18 justin_smith: blake__: the same sort of config that works in the quickstart can be used in the lein cljsbuild or figwheel cljsbuild settings

18:18 and then lein cljsbuild / lein figwheel can do the building for you at that point

18:34 blake__: justin_smith: There doesn't seem to be much on the actual config. (Though this is way better than it was.)

18:34 justin_smith: even better

18:35 or do you mean the config is undocumented?

18:37 blake__: justin_smith: Yeah, unless I missed something.

18:38 justin_smith: :cljsbuild {:builds [{:id "default" :foreign-libs ... :source-paths ... :compiler {...}}]}

18:38 and under builds is a vector of each defined build

18:40 blake__: Ah, right, that stuff is in its own project.

18:41 justin_smith: and under :compiler is the same options you would provide to cljs.jar

18:41 blake__: I think what confuses me is how compojure and my server-side code plays with (say) figwheel and my client-side code.

18:42 justin_smith: compojure and figwheel have no interaction at all

18:42 your cljs has one websocket connection to figwheel, and then whatever connection you set up (ajax, front-loading, websocket) to your compojure app

18:43 figwheel is only there to push code updates and evaluate cljs in a repl, no app logic should depend on it and it should be absent on production

18:45 blake__: justin_smith: Right. That makes sense. Just loading up the compiled Javascript should do what's needed in production.

18:45 justin_smith: exactly, and that's why figwheel and compojure shouldn't rely on each other or even interact really

19:04 devn: hello all

19:06 amalloy: how do i generate something like a compojure GET at runtime? like i have a list of urls, and i want to create a GET for each of them

19:07 but GET is a macro, and expects the path to be a literal string

19:07 justin_smith: amalloy: so you want to make a router at runtime

19:07 amalloy: yes, after reading in a config file that says what routes to serve

19:08 justin_smith: amalloy: I think bidi would do this nicely. My own projects stopped using compojure once we needed to derive routes from data outside the code itself.

19:08 and of course there is the alternative of using eval in an init function

19:09 but bidi is actually meant for that kind of flexibility (or polaris, which I helped make)

19:09 amalloy: actually i think compojure's GET just already does this. it looks like the macro is willing to accept a non-literal. i'll try that

19:09 justin_smith: oh, interesting

19:40 domgetter: How do I use Hiccup with Luminus? http://www.luminusweb.net/docs/html_templating.md

19:40 It doesn't say how to add Hiccup into the namespace you're in

19:42 arrdem: domgetter: (require '[hiccup.core :refer :all])

19:42 see https://github.com/weavejester/hiccup

19:42 also http://weavejester.github.io/hiccup/

19:42 domgetter: okay awesome

19:42 thanks, arrdem

19:42 arrdem: sure

19:48 rhg135: is placing a channel in a persistent collection a good idea

19:48 specifically one in an atom

19:49 arrdem: Why wouldn't that be a good idea.

19:51 amalloy: well, in general mutable things in collections are fine, as long as you realize that means that the collection itself will act a bit like a mutable thing

21:10 rhg135: Retries, arrdem

21:11 arrdem: ??

21:12 rhg135: That's why it could be bad

21:13 I ended up just using a persistent queue of pending puts to do outside the swap

21:23 noncom|2: i have a {} where each value takes long to compute, i want to make it compute in another thread, what is the best approach?

21:23 maybe {:key @(future (compute-value)) ... } ?

21:23 or not?

21:24 arrdem: noncom|2: so {:key @(future ...)} will force the value at map creation time. Not what you want.

21:24 rhg135: I would just use the future with no @ and update the client code. Less magic

21:24 arrdem: noncom|2: someone... gfredericks or hyPiRion has a "lazy maps" library that does this.

21:24 values are delayed and deref'd on get

21:24 rhg135: That too

21:25 noncom|2: well, i want them to compute on parallel because them are requests to a db and just the moment all of them are computed, they will be sent over network

21:25 this is a bit specific scenario

21:26 long requests. i feel doing them in parallel can be faster

21:26 since they're only reads

22:47 irctc: If you use ack, and would like see better support for clojure filetypes please drop a note in this thread: https://groups.google.com/forum/#!topic/ack-users/gMFdNsmjY6I

22:48 I've submitted a PR, but the maintainer would like to confirm with the clojure community that .edn .cljs and .cljc are common clojure filetypes

22:48 as he's unfamiliar with the language

Logging service provided by n01se.net