#clojure log - Nov 09 2013

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

0:00 bitemyapp: akurilin: what library is this?

0:00 What is it you're trying to do?

0:00 akurilin: bitemyapp, https://github.com/korma/Korma/blob/master/src/korma/core.clj#L512

0:01 bitemyapp: akurilin: yeah that's pretty minor.

0:01 akurilin: AOP that bitch.

0:01 akurilin: bitemyapp, what's that?

0:01 Google time? :)

0:01 bitemyapp: http://en.wikipedia.org/wiki/Aspect-oriented_programming https://github.com/michaeldrogalis/dire/ http://en.wikipedia.org/wiki/Metaobject#Metaobject_protocol

0:02 akurilin: Alright thanks, I'll investigate.

0:03 Btw I almost switched from having a DAL for my "models" and then I realized mocking pure korma calls would have been not trivial. Guess I just add a level of indirection :)

0:04 Can't win every fight.

0:04 bitemyapp: I think the truism of software is that indirection solves every problem except indirection.

0:07 bbloom: bitemyapp: is indirection a problem? or is slowdown (both for the computer's execution and the programmer reasoning) caused by excessive indirection the problem?

0:07 justin_smith: isn't indirection inherently some multiplier of computation time?

0:09 bitemyapp: bbloom: I only care about the practical consequences.

0:10 bbloom: what languages do you hack in that aren't Clojure and CLJS?

0:10 seangrove: Facjure?

0:10 bbloom: seangrove wins: all my other code is in postfix notation. also, i only use traditional chinese characters

0:10 seangrove: factjor :P

0:11 bbloom: bitemyapp: but no seriously.... i'm working for Code.org right now

0:11 if you're bilingual, help us translate! http://crowdin.net/project/codeorg

0:11 anyway, that's javascript & ruby

0:11 plus i tend to be the dude who writes a buttload of bash, sed, awk, make, etc

0:11 seangrove: 我明明用简体字

0:11 bbloom: i'm monolingual :-P

0:12 seangrove: Ah, well, all the more impressive for using traditional Chinese characters then

0:12 bbloom: Looking at this now, could possibly handle a few languages

0:12 Not sure what it is though

0:13 Heading out for a few hours, but would be curious to check out later

0:14 bbloom: seangrove: http://code.org/hourofcode & http://code.org/translate

0:14 ddellacosta: seangrove: いってらっしゃい

0:15 what am I doing wrong that I can get stefon to run (specifically the clj-v8 component) when running via lein ring, but not within an uberjar on same environment?

0:15 seangrove: ddellacosta: いってきますます

0:15 ddellacosta: seangrove: haha

0:16 bbloom: guys. it's not polite to speak in other languages in the presence of monolingual folks

0:16 we get paranoid

0:17 ddellacosta: bbloom: sorry, I just said "see ya later," and he replied "be back," in a kind of funny way

0:17 bbloom: ddellacosta: i google translated it :-P

0:17 thanks tho

0:17 ddellacosta: bbloom: ah. The impressive thing about seangrove is, however, that the first comment he made was Chinese, and the other ones were Japanese.

0:17 and I think his Korean is pretty kickass too.

0:18 bitemyapp: ddellacosta: not the only languages he knows...

0:18 ddellacosta: no no, the list keeps going.

0:18 ddellacosta: I'm sure...

0:20 now, about that stefon issue...why would an uberjar give me this? https://www.refheap.com/20622

0:21 I suspect I need to pass something to the java -jar args to tell it not to look for that lib in the system, but rather in a lib, but I am a java idiot so I'm not sure what is up.

0:22 * ddellacosta really needs to read that java book recommended on the clojure list this week

0:32 TEttinger: I wonder if clojure on linux with openjdk (ARM) has the same performance issues clojure has/had on android (ARM). I'll be installing PicUntu on my roughly-$60 ARM mini-PC, and it would be nice if I could use clojure and run it on there. does anyone else have an MK802 or similar TV stick?

0:32 beppu: noob question: `lein new help` says that 3rd party templates can be found at https://clojars.org/search?q=lein-template but that list seems incomplete.

0:32 Is there a better way to find 3rd party `lein new` templates?

0:32 TEttinger: beppu, that's a good question

0:33 beppu: TEttinger: wasn't the android performance issue due to the Dalvik VM (...and less to do w/ the ARM processor's characteristics)?

0:34 TEttinger: beppu, I hope so. this thing is a quadcore ARM computer the size of a big usb drive

0:34 I am absolutely amazed by how cheap computers have gotten

0:42 uvtc: TEttinger, do you mean pico-ITX?

0:43 TEttinger: never heard of it, PicUntu is an ubuntu distro for these stick PCs

0:45 uvtc: Ah. I thought maybe those tiny PC's you mentioned were of one of the ITX form-factors. Unfamiliar with stick PC's.

0:47 TEttinger: http://liliputing.com/2013/04/tronsmart-mk908-quad-core-android-tv-stick-performance-video.html

0:48 there are tons of them now, and they have gotten a lot better in the last year or two

0:48 I own an MK802 first gen, which is a tiny overheat machine

0:49 since then there have been 3 or 4 versions that add new features to that, among them not overheating as much

0:49 uvtc: Silly question: can you run a desktop OS on one of those?

0:49 TEttinger: yes, if by desktop OS you mean linux

0:49 uvtc: Right.

0:49 Wow.

0:50 TEttinger: PicUntu is XFCE Ubuntu

0:50 you can even use stock android with a keyboard and mouse, and I have

0:50 uvtc: This is one of the reasons I'd love to see a Clojure implementation in C (or Rust?). JVM-based Clojure seems like it'd be too resource-hungry for one of these.

0:50 justin_smith: ubuntu had a kickstarter for a phone that would work as a desktop once you connect a display / keyboard / mouse via USB

0:50 same concept

0:50 TEttinger: eh, it has 2GB RAM

0:52 justin_smith: I would use emacs on an n900 ages ago - I set up one of the keys on the keypad to be meta as a prefix key

0:52 and I actually succeeded in running a ring app on it

0:52 (very slowly)

0:52 TEttinger: ha! I remember those nokia MIDs

0:52 uvtc: 2GB. Wow. That's what my *current* desktop has. :)

0:58 TEttinger: uvtc, the one I got came with a wireless keyboard, which was the big problem I had with the MK802 -- I was carrying around a keyboard that was probably 50x larger than the computer. something like http://www.aliexpress.com/item/MK908-RK3188-quad-core-android-4-1-google-tv-stick-xbmc-box-2G-8G-bluetooth-mini/893264177.html

1:10 ddellacosta: soo...anyone know why jna.library.path is not set up properly when using clj-v8 in an uberjar?

1:11 TEttinger: ddellacosta, can you set it as a JVM opt?

1:15 ddellacosta: TEttinger: I guess so...the problem is, I'm not sure what it should be. When I run the project via lein ring/repl, it is set to be the target dir

1:15 I think that is the default. What I'm confused about is how it works when it is an uberjar

1:18 argh, anyways, gotta go.

1:21 tutysara: was reading web development in clojure, had a look at the middleware - wrap-noir-session, question is what is a stateful session and how it is different from the normal ring session

1:35 bitemyapp: tutysara: depends on what's intended by "session"

1:35 tutysara: session can mean a user session, which is typically stored as an identifier, or in whole as data in the user's cookies

1:36 tutysara: but when it comes to Ring, what's usually meant is basically state that comes with the processing of the request.

1:40 tutysara: okie, I wanted to know how is the ring session different from noir session (in lib noir) and what advantage i get by wrapping the handler in wrap-noir-session

1:42 Raynes: tutysara: Ring's session middleware puts the session in the request map and expects that if you have updated the value that you return it inside of the response map.

1:43 This tends to be unwieldily sometimes, so wrap-noir-session exists to provide a stateful layer on top of it.

1:48 tutysara: Raynes: ok, so this means noir takes care of sending the session data in response if we set in using sessions/put anywhere while processing the request

1:48 Raynes: tutysara: Yes.

2:19 dobry-den: nother stateful session lib: https://github.com/brentonashworth/sandbar

3:35 luxbock: I'm trying to join two matrices together like this (extend [[1 2][3 4]] [[5 6][7 8]]) -> [[1 2 5 6][3 4 7 8]] using core.matrix but I can't think of how to do this (there's no extend command) other than to transpose both of the matrices and then add the second one as rows to the first one

3:35 does anynoe know if there's a better way to do this?

3:44 amalloy: if you just wanted vectors instead of matrices, i think ##(map into [[1 2][3 4]] [[5 6][7 8]]) is fine?

3:44 lazybot: ⇒ ([1 2 5 6] [3 4 7 8])

3:46 luxbock: yeah I was hoping to find a way that would work with all implementations of core.matrix

3:49 I'm trying create a magic-matrix function and for the case of a singly even matrix I have to divide a bigger matrix into four sub-matrices and do a few transformations with those and then add them together again

4:10 TEttinger: luxbock, I'm curious what this matrix stuff is for

4:11 luxbock: not for anything particular, just practice

4:11 I noticed Octave has a function for creating magic-matrices and so I thought it would be a good excercise to write it in Clojure

4:12 TEttinger: ah cool

4:12 luxbock: http://blogs.mathworks.com/cleve/2012/11/05/magic-squares-part-2-algorithms/

4:13 just following this

4:19 poppingtonic: luxbock: I'm sure there's a really elegant way of writing a magic-square algorithm. Cool.

4:24 john2x: is there a way to simplify this: (-> "foobarbaz" (str/replace #"foo" "fizz") (str/replace #"bar" "quuz") (str/replace #"baz" "buzz"))

4:25 Apage43: see clojure.string/escape if you don't need the searched part to actually be a regex

4:26 ,(clojure.string/escape "foo - bar - baz" {"foo" "fizz" "bar" "quuz" "baz" "buzz})

4:26 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading string>

4:26 Apage43: ,(clojure.string/escape "foo - bar - baz" {"foo" "fizz" "bar" "quuz" "baz" "buzz"})

4:26 clojurebot: "foo - bar - baz"

4:26 Apage43: huh

4:26 oh feh

4:26 escape works on characters, not arbitrary search strings

4:27 TEttinger: (doc (clojure.string/escape)

4:27 clojurebot: #<RuntimeException java.lang.RuntimeException: EOF while reading>

4:27 TEttinger: (doc clojure.string/escape)

4:27 clojurebot: "([s cmap]); Return a new string, using cmap to escape each character ch from s as follows: If (cmap ch) is nil, append ch to the new string. If (cmap ch) is non-nil, append (str (cmap ch)) instead."

4:27 addisaden: learned *g+

4:27 Apage43: forget what i said :)

4:28 addisaden: is there a bot evaluating clojure? :D

4:28 ,(+ 1 2)

4:28 clojurebot: 3

4:28 addisaden: haha nice ^^

4:32 TEttinger: ,(reduce #(clojure.string/replace %1 (first %2) (second %2)) "foobarbaz" {#"foo" "fizz" #"bar" "quuz" #"baz" "buzz"})

4:32 clojurebot: "fizzquuzbuzz"

4:32 TEttinger: it's always reduce.

4:33 john2x: cool, thanks!

4:34 TEttinger: no prob

5:23 cYmen: phew

5:23 Just watched "are we there yet"...

5:23 not sure if rich is a genious or crazy

6:18 poushkar: Hello there. I am newbie in Clojure, reading about functions at the moment. Can't figure out why this code: (((fn [] +)) 4 5) results in 9. Could someone explain it to me, please?

6:21 john2x: (fn [] +) defines an anonymous function that just returns the function `+`. ((fn [] +)) calls that function, so now you have (+ 4 5)

6:24 poushkar: john2x: oh, that's easy. I've got confused with parentheses. Thank you

7:19 cYmen: alright, on to learning some "ring"

7:27 Question: When I try to (use 'hello-world.core) from the repl and I have an error in that file. How can I recover and reload after fixing that error?

7:27 h_smith: core.async question. if I have two threads listening on the same channel on the go block, how can send an event to both threads? looks like my event is getting consumed by only one listener

9:56 zeebrah: I was expecting (let [+ *] `(1 2 3 (+ 1 1))) to evaluate to (1 2 3 (clojure.core/* 1 1))) but it's not. What's up with that?

9:58 justin_smith: zeebrah: bindings in a let block are not evaluated if quoted

9:59 ,(let [a +] `a)

9:59 clojurebot: sandbox/a

9:59 justin_smith: ,(let [a +] 'a)

9:59 clojurebot: a

10:01 ddellacosta: soo, I'm trying to get my uberjar to work the same way as my project run via lein ring, with regards to a library (clj-v8) that gets loaded via jna. The relevant code is here: https://github.com/circleci/clj-v8/blob/master/clj-v8/src/v8/core.clj

10:02 it seems like it finds the library for the external .so just fine (the one packaged with the clj-v8 lib itself) when loaded via lein ring/repl, but in the uberjar it tries looking for the lib in the system's libs

10:03 I've tried setting -Djna.library.path in jvm-opts in lein project as well as when running the jar, but no dice.

10:04 justin_smith: wait, so you create an uberjar, then run it with lein?

10:04 ddellacosta: justin_smith: no, java -jar

10:04 justin_smith: then -Djna.library.path should be in the java command line, right?

10:04 ddellacosta: sorry, that was confusing: trying to get the uberjar to work the same way as running via lein ring/repl does

10:05 justin_smith: right; but that doesn't work either.

10:05 justin_smith: weird

10:05 I have had many problems with jna loading as well

10:05 wish I knew what the problem was

10:06 ddellacosta: well, if you check this bit out, it seems like the lib itself is doing some magic: https://github.com/circleci/clj-v8/blob/master/clj-v8/src/v8/core.clj#L4

10:07 justin_smith: so what invoked __SET_JNA_PATH__?

10:07 ddellacosta: justin_smith: yeah, I guess I have to learn more about how jna works...pretty confused by what is going on there. I don't even know what the proper setting should be...is the lib packaged in the uberjar, and so should the path be relative to that? dunno

10:07 justin_smith: you can open an uberjar with zip

10:07 *unzip

10:08 ddellacosta: __SET_JNA_PATH__ is set when loading that lib, I assume...if you're asking what uses it, it is stefon in my app

10:08 justin_smith: so that can help with that question, at least

10:08 ddellacosta: yeah, good point, I knew that but didn't think to see if it was in there...will check right now

10:08 justin_smith: oh wait, the defonce is using the return value

10:08 so that is a total hack

10:09 it is just being done that way so you can reload the namespace without running the top level code again

10:09 I misread it at first

10:13 ddellacosta: huh, gotta go read up on jar file execution. I was hoping to avoid learning this much about Java...haha

10:13 thanks for taking a look justin_smith

10:14 justin_smith: I wish I understood this stuff better, there are some native libs I would like to be able to use

10:15 ddellacosta: justin_smith: yeah, I wish I understood it better too...I'll ping you if I figure anything out. For now I have some reading to do. :-/

10:26 jared314: has anyone built a library that uses core.async as an abstraction for jdbc? Google has failed me

10:36 justin_smith: jared314: well you don't need a specific library to do your queries inside a go block so that they are async with other code

10:37 but you would need to adapt that heavily to your own db usage (knowing what can be done in parallel while waiting for the db to return your data)

10:39 jared314: justin_smith: well, then I will put that idea on the back burner then

10:41 swarthy: jared314: Writing some actual Golang code might help it make more sense. Typically in Go you would structure your code such that N readers would pull from something on the 'read' channel. Then you would send from those N readers to a single writer on the 'write' channel.

10:41 jared314: Thus doing a bunch of stuff, but programming in a synchronous feeling way.

10:43 ddellacosta: justin_smith: dunno if your problems were like mine in that they are problems with uberjars, but this post was quite helpful in understanding the issue: https://groups.google.com/forum/#!topic/leiningen/2OZQPMi3cks

10:44 justin_smith: this suggests that nothing you can do via jvm_opts or args to java will have any effect

10:44 justin_smith: er, sorry, that's incorrect--will not have any effect with regards to specifying the path inside the jar to use those libs by default

10:45 justin_smith: right, so you have to put native libs onto disk somehow

10:45 before you can load them

10:45 you would think there would be a standard turnkey way of doing this

10:46 but I guess not

10:46 ddellacosta: justin_smith: yeah, seriously...seems like a relatively common issue

10:47 weeelll, may be time to write a wee library perhaps

10:47 justin_smith: I have a four day weekend maybe I can make something...

10:47 yeah

10:48 throw in some puns about blanket access to native libs and you can tie it into the american thanksgiving story

10:48 sorry, that was probably in bad taste

10:50 ddellacosta: justin_smith: hahaha

10:50 as an American, I forgive you

10:50 dobry-den: native american?

10:50 ddellacosta: nope, not in the sense of being one of the folks who the Europeans displaced/killed en masse

10:52 justin_smith: I'll see what my tech lead thinks of the joke (he is Native American)

10:52 ddellacosta: well, I could continue the joke but I will stop...but it gave me a chuckle. I like dark humor, however

10:52 ah, there ya go.

10:53 anyways, on that note, you folks have a good night. Gonna hit the hay.

10:54 * ddellacosta waves his handkerchief and sniffles

10:54 uvtc: o/

11:01 francis_wolke: Has anyone run into an issue with the clojurescript browser repl where it freezes indefinitely? If so, what is your fix?

11:01 dobry-den: at this point in my life, i tend to restart repls til they work

11:02 foo already refers to bar.foo? restarting

11:02 spotify frozen?

11:03 francis_wolke: dobry-den: I usually do that, however it's freezing on startup. I rolled back my git changes to ensure it's not something in my code.

11:04 clojurebot: Huh?

11:04 justin_smith: francis_wolke: another voodoo option is to lein clean

11:04 can't hurt

11:05 francis_wolke: justin_smith: Thanks. Totally forgot about that.

11:06 seangrove: francis_wolke: C-c C-b

11:06 And then reconnected... although that's only for nrepl.el

11:09 zilti: ilitary

11:16 francis_wolke: 3 restarts, and for some reason __this__ time it works. Strange.

11:16 justin_smith: I am sure that Papa Legba was appeased by your sacrificial lein clean

11:17 francis_wolke: justin_smith: 3 restarts after `lein clean`

11:17 justin_smith: sacrifices take a while to get to their ethereal destination, duh

11:18 jared314: francis_wolke: it's like a car. If you keep trying to start it, it gets better.

11:19 dobry-den: ^

11:19 justin_smith: perhaps we could implement a new plugin for percussive maintinance

11:20 lein jostle

11:20 dobry-den: the entropy in your computer gradually aligns to adapt to the state it needs to be in for the jvm to work

11:20 justin_smith: with the more powerful line slam option

11:20 dobry-den: sorta like a car's computer

11:20 repl to work*

11:25 benmoss: do people usually gitignore the output directory for cljs?

11:25 justin_smith: benmoss: yeah

11:27 dobry-den: for sure

11:28 justin_smith: output generated by code in the repo running in an automatic way should not be stored in the repo

11:28 that goes for sass, m4, whatever

11:28 dobry-den: nothing worse than when you gitadd some js output and your clojure code coverage on github is reported below 100%

11:28 or when your project becomes a CSS project because you included twitter bootstrap

11:28 justin_smith: hah

11:28 benmoss: so the target directory too?

11:29 dobry-den: yeah

11:29 benmoss: ah github has '/targets/' in their leiningen gitignore, but mine is producing target

11:30 dobry-den: yeah it should be target

11:33 muhoo: i've seen projects (not clj) where people include jars in git. horrifying.

11:34 benmoss: is there any way to use a local leiningen template?

11:34 justin_smith: I've worked on projects where people put all our assets (images, pdfs, zip downloads) into git

11:34 muhoo: benmoss: pivate repo?

11:35 justin_smith: benmoss: I guess you could lein install it?

11:35 benmoss: muhoo: just for testing it

11:35 dobry-den: is it really that bad, though? it's like a layman's local-dependency deploy.

11:36 justin_smith: benmoss: yeah, I usually lein install and then check from another project if I can use it before deploying, reduces the number of deploys I need to do

11:36 muhoo: benmoss: IIRC there is a way to test templates from a dir. don't remember where it's documented tho

11:36 dobry-den: just look up the template literature

11:37 muhoo: same way as dev/testing plugins tho

11:37 justin_smith: it would be nice if we had a version of lein install which tracked what had been manually installed for easy removal, so you can local install to check that things work nicely, then remove so you don't get a warped view of what your lib versions act like

11:38 of course we can do this manually, but I like the idea of doing it conveniently

11:38 dobry-den: the things we put up with

11:39 justin_smith: I'm not complaining, just daydreaming of possible features. I may even try to make that thing some day.

11:40 dobry-den: yeah, i didnt mean it like that

11:42 when i first came to clojure, i hated looking up dependency versions. (i still do if it's on maven) i started writing a plugin that lets me `lein dep-install compojure`. but i never polished it because i became too lazy

11:43 jared314: dobry-den: doesn't lein have a search task now?

11:43 justin_smith: so it would be a tool that would get the latest stable version of each dep I assume?

11:43 dobry-den: yeah, and mutate the project.clj map

11:44 benmoss: after i've `lein install`ed the local repo, how can i uninstall it so it doesn't shadow the real repo?

11:44 justin_smith: like slamhound for your project.clj https://github.com/technomancy/slamhound

11:45 dobry-den: of course, by the time the jvm boots just to tell you it couldn't find "commnos-io" wwhen you mean "commons-io", you couldve just added it yourself

11:45 justin_smith: benmoss: remove the director, it will bee under ~/.m2/

11:45 *directory

11:45 benmoss: thanks

11:46 dobry-den: speaking of, does anyone do any clojure develoment on a weak computer?

11:46 justin_smith: I ran a ring app on an n900 once, just to see if I could

11:46 it worked, but slowly

11:46 dobry-den: i was a rails developer on a 2009 atom netbook and that was painful

11:46 haha

11:47 justin_smith: I used to use an underpowered 2008 Acer (with debian installed), but I got tired of having to shut down one lein project in order to have enough ram for another to run

11:48 benmoss: I'm still working on a 2008 macbook

11:48 justin_smith: so I went totally over the top and got a system76 bonobo

11:48 dobry-den: hell yeah. 2 years on my netbook and i'd even have to do things like shutdown every other tab to watch a youtube video

11:48 justin_smith: which is awesome, but not as portable as a notebook should be

11:49 but hey, 32 gigs of ram, as long as I don't try to use rythmbox that is enough

11:49 lol

11:49 dobry-den: i had a 17" laptop for half of uni. definitely a tank

11:49 comical to open that fatboy up in class

11:49 TimMc: Upgrading from 8 to 16 GB of RAM at work. Too many Java services.

11:50 dobry-den: yeah, i'm at 8gm ram and it's not enough. especially now that i'm getting into datomic

11:50 justin_smith: https://www.system76.com/laptops/model/bonx7 17.3" bonobo extreme, weights 9 pounds, the power supply is another 4 pounds or so

11:50 TimMc: oh jeez

11:51 justin_smith: that acer was 2 gigs of ram - somehow I managed to develop clojure on it anyway

11:51 dobry-den: ever take that tank to a public space? it probably imposes itself upon the world around you

11:51 justin_smith: definitely

11:52 dobry-den: even the dude that brings his imac to starbucks feels uneasy next to you

11:52 justin_smith: I always tell people I only use a computer that big in order to make me look smaller in comparison

12:48 lynaghk`: dnolen: ping

12:49 dnolen: it's me and Zach Allaun coming to you straight from EC2. We're doing the node knockout and have run into "property backtrack undefined" issues with core.async + core.match. Using latest cljs, async, and match on node.js. Have you run into this before?

12:52 jtoy: i noticed for each java process I start with "lein run -m ns.core" it starts to java processes, is this normal and can I hve it run with one java process instead to reduce resource usage?

12:55 jared314: jtoy: have you tried lein trampoline?

12:56 jtoy: I have not, jared314 , i see this solves it http://www.flyingmachinestudios.com/programming/lein-trampoline/

12:57 jared314: jtoy: that is the one

13:00 jtoy: jared314: what exactly is a task name, I couldnt just change "lein run -m ns.core" to lein trampoline ns.core

13:02 jared314: jtoy: did "lein trampoline run -m ns.core" not work?

13:03 jtoy: jared314: yes, that does work, thank you

13:17 brainproxy: on the latest cljs and cljsbuild

13:17 trying to itegrate repl into my dev/test build

13:18 getting complaints about stuff missing seemingly related to goog base

13:18 so i guess it's not enough to require cljs.browser.repl in order to pull that stuff into the build

13:19 now, i see some references to "out/goog/base.js" in the wiki and other places

13:19 however, in the out dir, i only have cljs and clojure subdirs

13:20 also, before today, I've never had an `out` dir, but have been doing `lein cljsbuild auto/once...` stuff for awhile, so maybe the upgrade of cljs and the lein plugin have brought that into play

13:20 clarification: the "complaints" mentioned above relate to browser-side exceptions from the the compiled js

13:22 jtoy: interesting read, just came across this http://scottlocklin.wordpress.com/2011/11/30/only-fast-languages-are-interesting/

13:25 jared314: jtoy: I like how people invent micro benchmarks then judge things, without discussing it with anyone

13:26 jtoy: it's even better when they act stubborn and justify it with the "it shouldn't require effort" line

13:30 justin_smith: "Then again, the nice thing about the internets is people telling you when, and exactly how you’re being stupid."

13:31 jared314: justin_smith: reminds me of cat videos on reddit. "Hey look at my cat being crazy!" "Your cat is having a seizure, take it to the vet immediately!"

13:31 brainproxy: okay, after fiddling a bit it seems to come down to this exception:

13:31 "Uncaught TypeError: Object #<Object> has no method 'setTimeout' "

13:31 where the object in question is "goog.Timer.defaultTimerObject"

13:32 which is the same object as "goog.global"

13:34 dobry-den: jtoy: is it that interesting? that person has code like (def rands (repeatedly rand)) and (def tmp (take 3000000 rand)) which realizes both collections of 3mill numbers in two different vars

13:36 then includes the realization of them both in the benchmarks

13:37 indigo: "Only smart programmers are interesting" ;P

13:38 francis_wolke: Clojurescript people: Earlier today I asked for a solution to a frozen browser repl. The issue happened again (repl freezes, restarting the repl does not help, detatching repl does not help), but this time aound I opened up the page I'm working on in a new tab - which fixes the issue.

13:38 dobry-den: if i blow the stack trying to add numbers in a language im admittedly new to, my first thought is actually that i'm a doing it wrong

13:38 francis_wolke: Thoughts?

13:38 indigo: dobry-den: Funny, that was my thought too ;P

13:39 dobry-den: of course, mike anderson, clojure hero, is fucking everywhere

13:39 jared314: dobry-den: na, it shouldn't require thought. It should "just work". Like everything else in life

13:40 dobry-den: he's like darkwing duck

13:40 oh look, a stackoverflow clojure question i can answer. Nope. mikera already answered it.

13:41 (he points out the blogger's issue in a comment on that post)

13:45 majyk: maybe mikera is the Jon Skeet of Clojure

13:51 brainproxy: dnolen: I have a cljs project that uses a wrapper similar to the one I cooked up for mori several months ago

13:51 https://github.com/swannodette/mori/blob/master/support/wrapper.js

13:52 i discovered just now that the `..cal({})` part can be problematic inasmuch as in the compiled output there is a line `goog.global = this`

13:52 and there are other parts that depend on `goog.global` having on it all the expected things from the global environment, e.g. setTimeout

13:53 it's possible to replace `..call({})` in the wrapper with `..call(this)` but that kind of defeats the purpose

13:54 so... I was wondering if you had any thoughts on the matter; I had not run into a problem until just now when I was trying to make use of `clojure.browser.repl`, but I'm not sure whether that was the reason it came up or whether it's related to my bumping to the latest clojurescript release

14:34 logic_prog: is there an idiomatic way to run read-string over an entire file after slurp-ing it ?

14:35 justin_smith: why not load-file?

14:35 or do you need the text too

14:35 oh, you don't want to execute, just read

14:36 francis_wolke: logic_prog: java.io.PushbackReader

14:36 logic_prog: I want to just read it all in as a sexp

14:37 justin_smith: do you want it as text too?

14:37 francis_wolke: logic_prog: Yes, but if it has multiples sexps?

14:37 justin_smith: (I mean as a string too)

14:37 logic_prog: I want a list of sexp's

14:39 francis_wolke: logic_prog: You want Pushbackreader.

14:39 It'll allow you to read a file out as sexps

14:43 logic_prog: (let [reader (java.io.PushbackReader. (clojure.java.io/reader "lsearch.xyz"))] (clojure.edn/read reader))

14:43 how do I call map on this to read until eof?

14:44 justin_smith: you probably want a loop rather than map

14:44 since you don't have a sequence of the length of the input sequence

14:44 to map over

14:46 logic_prog: (let [reader (java.io.PushbackReader. (clojure.java.io/reader "lsearch.tkx"))] (loop [ans '()] (let [x (clojure.edn/read reader)] (recur (cons x ans)))))

14:46 how do I handle the exception?

14:47 hyPiRion: (let [sym (gensym) val (clojure.edn/read {:eof sym} reader)] (if-not (= val sym) (recur ...) return-val))

14:47 Or something in that regard

14:47 coventry: logic_prog: https://www.refheap.com/20629

14:48 logic_prog: will look into it, thanks

14:48 coventry: But it's not reliable to read a whole file without evaluating it form by form.

14:49 justin_smith: coventry: thats nice, I assume it is from an existing codebase?

14:49 coventry: Yes.

14:49 justin_smith: Some earlier mucking around. Nothing solid. https://www.refheap.com/20630

14:58 bitemyapp: arrdem: boo

15:07 dnolen: lynaghk: ping

15:22 lynaghk: you need to include the runtime core.match stuff

15:28 sritchie: bitemyapp: liberator Q, if you have a second

15:36 benkay: ,ping

15:36 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: ping in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:39 bitemyapp: sritchie: I'm far from an expert, but I'll google what I can ^_^

15:41 benkay: why do you keep doing that?

15:42 benkay: because i don't have a robust erc setup yet

15:42 and i'm in argentina, and occasionally the connection dies, and i know that if i

15:42 ,anything

15:42 clojurebot: #<CompilerException java.lang.RuntimeException: Unable to resolve symbol: anything in this context, compiling:(NO_SOURCE_PATH:0:0)>

15:43 benkay: clojurebot will respond

15:43 :)

15:43 ¿sabes?

15:43 ¿entiendes?

15:44 biggbear: yo sabía que los args decían ¿entendés?

15:45 benkay: your spanish is better than mine ;)

15:45 adios!

15:45 sritchie: bitemyapp: try to use enlive with liberator,

15:46 amalloy: benkay: if it's just for private use, please /msg clojurebot instead of talking to him publicly - he responds just the same

15:46 sritchie: and I find that when I return my basic response from handle-not-found, (response/response enlive-snippet),

15:46 NPEs abound :)

15:46 bitemyapp: so the Q is, I guess, how to redirect?

15:46 inside of a liberator response?

15:47 benkay: thanks amalloy

15:52 sritchie: No method in multimethod 'render-map-generic' for dispatch value: text/javascript

15:52 this is the crux

16:00 logic_prog_: does clojurescript have a prepend? http://docs.closure-library.googlecode.com/git/closure_goog_dom_dom.js.html shows append, but I want to insert an element as a the _first_ child rather than _last_ child of a node

16:02 bitemyapp: sritchie: eek @ enlive. Hrm. redirect.

16:04 hrm. this is why I just use Ring, haha.

16:04 sritchie: http://clojure-liberator.github.io/liberator/doc/handlers.html

16:04 sritchie: https://github.com/clojure-liberator/liberator/blob/master/examples/clj/examples/collection.clj#L52

16:14 bbloom: logic_prog_: there is insertChildAt and insertSiblingBefore

16:14 logic_prog: insertChildAt seems to _replace_

16:14 either that, or I'm doing something wrong

16:15 bbloom: logic_prog: i dunno. i don't really use any of the goog.dom stuff

16:17 bitemyapp: `cbp: how's your weekend going?

16:36 cjfrisz: I've finally got enough of my own fns/macros that I use in every project to want them in a library that gets included by default. Is there a best practice for automating this?

16:38 amalloy: cjfrisz: automatically including your library in other projects of yours? if you do this it will only bring tears

16:38 dnolen: cljsfrisz: just make a lein template that includes your lib

16:39 amalloy: unless you just mean you want it added to your project.clj everytime you create a project

16:39 cjfrisz: Moreso than copy/pasting the same few macros into every project?

16:39 amalloy: That

16:39 amalloy: sure. then do what dnolen says

16:39 cjfrisz: dnolen amalloy: thanks!

16:39 bbloom: cjfrisz: i think that copy paste is the right level of reuse for a many utilities

16:39 technomancy: cjfrisz: scottj suggested making the default template look in the user profile for extra thingies to add, which would be neat

16:40 or really, if all the templates did that

16:41 cjfrisz: bbloom: Agreed, but I think the 4th time I copy my defrecord+ macro is when I should consider making it easier to access :-p

16:41 bbloom: what's defrecord+ do?

16:42 cjfrisz: Right now it defines a get/set interface for the record a la R6RS define-record-type

16:42 bbloom: .... why?

16:43 hiredman: because cjfrisz is a schemer

16:43 cjfrisz: ^^^^

16:43 bbloom: dude. just stop making so many damn record types

16:43 technomancy: (inc bbloom)

16:43 lazybot: ⇒ 18

16:43 bbloom: i have like 3 record types in dozens of small projects & i only created them after profiling :-P

16:43 technomancy: hypothesis: adding :reload/:reload-all/:verbose to a :require clause is a thing you do temporarily to your ns form, not something you intentionally leave in.

16:44 [Y/n]

16:44 Raynes: technomancy: Y

16:44 * technomancy has zero record types; never profiles

16:44 cjfrisz: bbloom: I'm not claiming that everyone should do it; it's just the way my brain works thanks to Scheme

16:45 technomancy: Raynes: thanks. looking over a big slamhound improvement that only works with that assumption, but I think it's OK.

16:45 bbloom: cjfrisz: fight the urge. you're a smart guy. force yourself to think a different way and soon enough you'll gain some insight that frees your brain from one approach and offers you a vantage point from which you can select the appropriate approach

16:45 technomancy: Y, but even more than that: i never add them. i rely on hotkeys in my editor

16:46 technomancy: bbloom: even better

16:46 Raynes: technomancy: I've only used reload for two reasons. The first is to reload a namespace in the REPL, and the second is to reload plugins in lazybot (but that is a function that calls the 'require' function, not an (ns ..) addition).

16:46 I've never seen anyone else use it for anything more interesting than that either.

16:46 cjfrisz: bbloom: Is the alternative to just use hash-maps instead?

16:47 bbloom: cjfrisz: the most common of several alternatives, yes

16:47 technomancy: cjfrisz: they're just maps; ignore the concrete type

16:48 why did github screw up my comment by hiding the bulk of it here? https://github.com/technomancy/slamhound/pull/53#issuecomment-28137768

16:48 bbloom: cjfrisz: you need to decouple your mental concept of "type" from the "type tag" from "some tag i put on this data to discriminate by"

16:49 technomancy: did you email it in?

16:49 technomancy: bbloom: yeah, do they use a different parser or something?

16:49 bbloom: technomancy: what mail client do you use? at my last company i did *lots* of email parsing & quoted text removal and shit like that. it's a nightmare

16:50 technomancy: bbloom: mu4e; just sending boring old plaintext email.

16:50 bbloom: technomancy: odd.... you didn't type two hyphens between your paragraphs by chance? :-P

16:50 technomancy: or intent them 2 lines or whatever?

16:51 technomancy: nope: http://p.hagelb.org/raw-github-comment.html

16:51 bbloom: surely a regex run amuck

16:52 *shrug*

16:52 technomancy: I specifically didn't wrap it because I know github doesn't like that

16:52 one more reason to prefer non-http ways of accessing github I guess?

16:53 bbloom: cjfrisz: i can only assume that right now you're staring at some outputted data structure w/o a record type prefix and you feel like somebody has unclipped your seatbelt

16:53 technomancy: https://github.com/technomancy/slamhound/commit/6bf39a849c9f913e37c9eca10b9e28566850c502 \m/

16:54 bitemyapp: cjfrisz: stop fucking around and just make maps.

16:55 cjfrisz: bbloom bitemyapp: I don't get the record type fear

16:55 It's not the performance, and it's not the record type tag

16:55 bbloom: cjfrisz: it's not fear

16:56 cjfrisz: It just evokes memories of sloppy undergrad code where they use association lists instead of define-record-type

16:56 technomancy: alists are a crappy workaround for not having a good associative data structure

16:56 bbloom: cjfrisz: by choosing to use a record, you're added a type tag to your public interface, declaring a minimum set of fields for initalization, weakening data interop between systems, introducing versioning problems, etc

16:57 technomancy: see that over and over in elisp and it is really terrible

16:58 bbloom: cjfrisz: if you don't need type dispatch or a fixed set of fields for perf reasons, then you shouldn't opt in to the other things that come along with records

16:58 bitemyapp: cjfrisz: write Clojure, not Scheme in Clojure.

16:58 cjfrisz: bbloom: So you'd quit your bitching if I changed defrecord+ to create a map instead of record type?

16:58 bitemyapp: cjfrisz: don't be rude, we're trying to reduce your pain level arising from writing poor Clojure code.

16:59 bbloom: cjfrisz: no, then i'd bitch even more. accessor functions are a nightmare

16:59 bitemyapp: you're being rude. cjfrisz is willing to learn

16:59 bitemyapp: cjfrisz and i have met in person & are on terms where he can say "quit your bitching" to me

16:59 bitemyapp: bbloom: this is your daily reminder that I am not omniscient.

17:00 if somebody is rude in IRC when receiving help, I'm going to snip their wings.

17:00 bbloom: if you can dump your facebook relationship graph to XML I can use that as a reference in future.

17:00 bbloom: bitemyapp: i know you're not omniscient, which is why i informed you of the situtaiton

17:00 moving on.

17:01 technomancy: records also act weirdly when reloaded

17:01 bbloom: cjfrisz: what benefit does accessor functions give you?

17:01 technomancy: you can have two visually identical objects be not-equal

17:01 bitemyapp: technomancy: well specifically, stale instances can float around.

17:01 then something derived from an older version of the record type won't equal an otherwise identical record.

17:01 bbloom: technomancy: that's b/c defining a type has the side effect of pulling an entry from a unique source: new-ing up a type object

17:02 bitemyapp: annoying and pointless.

17:02 technomancy: occasionally a necessary evil

17:02 bitemyapp: technomancy: this is why I prefer teaching Python people to use Clojure. "Just use maps" comes naturally.

17:02 technomancy: but not something you'd just inflict upon yourself for no reason

17:03 bbloom: bitemyapp: that's not been my experience. the python community is very fractured between OOPnauts and "just use a function function and a map"-people

17:03 cjfrisz: let's leave gut out of this for a moment: what do records or unique accessors buy *you*?

17:07 cjfrisz: bbloom: Maybe nothing more than comfort of a familiar idiom a la define-record-type

17:07 bbloom: I'll have to think on that one more

17:07 bbloom: cjfrisz: getters & setters are one of the worst ideas to ever happen in programming :-)

17:07 cjfrisz: another issue i have: auto-generation of predicates

17:08 er type predicates

17:08 (define-record-type foo ...) also gives you foo? too right?

17:10 there's no need for that either, b/c we already have generalized `instance? and `satisfies? for concrete types and abstractions respectively. beyond that, it's up to the programmer to define predicates which should have the docstring "Checks if x is a logical foo" rather than "Checks if x is an instance of type Foo", which is unnecessary early coupling

17:10 case in point:

17:10 (doc fn?)

17:10 clojurebot: "([x]); Returns true if x implements Fn, i.e. is an object created via fn."

17:10 bbloom: meanwhile:

17:10 (doc ifn?)

17:10 clojurebot: "([x]); Returns true if x implements IFn. Note that many data structures (e.g. sets and maps) implement IFn"

17:10 bbloom: *sigh* causes so much confusion!

17:11 `cbp_: bitemyapp: hi, just trying to learn some haskell cus every cs paper seems to be using it :(

17:11 bbloom: fn? should be ifn? and what was fn? should be (partial instance? clojure.langFn)

17:11 cjfrisz: see what i'm getting at?

17:11 s/langFn/lang.Fn/

17:12 cjfrisz: bbloom: So what about the fact that not having a functional interface to your data type leads to more silent failures if you try to access the data structure incorrectly?

17:13 `cbp_: ghc 900 mb....

17:13 bbloom: cjfrisz: who cares? everything is printable and immutable. add a pprint statement somewhere in your program, eyeball it, and resolve your "type error"

17:14 bitemyapp: `cbp_: that's a fantastic idea. I really enjoy Haskell. Keep me posted :)

17:15 `cbp: bitemyapp: how you doing?

17:15 bitemyapp: `cbp: I'm going to start poking at reproducible error cases and see what I can do to pass the error to the client.

17:15 `cbp: ok

17:16 bitemyapp: I'm pretty good, I haven't started coding, but I've been noodling over the error passing behavior all morning. I've got somebody coming by to buy a monitor off me, then I'll get to work.

17:16 `cbp: bitemyapp: did bja ever contact you again?

17:17 cjfrisz: bbloom: I still think a functional interface is going to prevent enough debugging time to be worth it

17:17 bitemyapp: `cbp: no, that's why I'm proceeding.

17:17 `cbp: he can improve upon whateve I do if he likes, but I want error handling in ASAP.

17:17 well, not even "handling", just graceful notification of agent breakage to the client.

17:19 bbloom: cjfrisz: you have a functional interface. keywords are functions and assoc is a function too. what you want is earlier error detection via type checks

17:21 cjfrisz: bbloom: keywords and assoc don't fail in those cases as I'd want them to

17:21 bbloom: cjfrisz: sure, but they are functions :-P

17:21 cjfrisz: bbloom: I might need medical attention for the amount that my eyes are rolling

17:22 bitemyapp: cjfrisz: if you want early error detection, why not use core.typed?

17:22 cjfrisz: I can't stop it!

17:22 amalloy: bitemyapp: if you like haskell, have you looked at elm? it's pretty neat, although i don't know if i'm excited enough to actually get good at it

17:23 bitemyapp: amalloy: I have, but I favor things like Fay for that. I think it's cool that they're bringing FRP to the masses though.

17:23 amalloy: Fay being the CLJS of Haskell, so to speak.

17:23 cjfrisz: bitemyapp bbloom: core.typed is a very cool thing that I like a lot, but the class of machinery you have to set up for that is way different and way heavier than if all I want is early error detection on improper record type accesses

17:26 bbloom: cjfrisz: so there is a cost/benefit trade off to be made between formally specifying static requirements and early detection of errors

17:26 cjfrisz: i'm a big believer that things should fail loudly if they are gonna fail at all

17:27 cjfrisz: and i'm also a believer that they should fail *early*

17:27 cjfrisz: however, i don't buy the argument that early == compile time, since me working at my repl is as early as most people run their compilers, but i'll assume, as a schemer, you agree with that

17:27 cjfrisz: bbloom: indeed

17:28 amalloy: bitemyapp: neat. fay might be easier to pick up; fewer new concepts

17:28 bbloom: so by throwing an exception when there is a type error, i do get a *bit* earlier, like half way through execution, rather than after exectution w/ just a wrong value

17:28 cjfrisz: however, i generally write & test small enough bits of purely functional code, that it's almost always trivial to pin point the source of the mistake

17:28 cjfrisz: that said....

17:29 cjfrisz: some programs really do have a lot of different concepts that exist in scope at the same time, all of which can be representeded by associative data structures

17:29 cjfrisz: and i can imagine, it might get confusing when that does occur & type errors make slip through and not be detected early

17:29 cjfrisz: *however*

17:30 cjfrisz: i find it's more frequent that i'll invalidate an invariant, than add an extra key that has no impact

17:30 cjfrisz: and i also find it's more frequent that i made a DESIGN error

17:31 cjfrisz: and beyond those, my experience has shown that judicious print statements, validation functions, and carefully considered assertions, pays greater dividends

17:31 cjfrisz: by relying on early detection of a small class of errors, my experience has been that i subconsiously adjust my design and process to nudge errors to fall in to that small class

17:32 cjfrisz: and later, when i say "shit, i really need a validator function and some logging" i wish i started on it earlier!

17:34 bitemyapp: amalloy: Fay is just vanilla Haskell + DOM interface for the most part.

17:34 bbloom: cjfrisz: i'm not saying it's not useful to have ready-built sanity checks. i'm saying that there are hidden costs and so you should only pay them when you need them & look for ways to avoid needing to pay them or to buy something different & get more bang for buck

17:34 bitemyapp: amalloy: and uses the existing GHC tooling (thank god)

17:34 amalloy: bitemyapp: minus typeclasses, apparently, which seems like a big deal

17:34 or did i misread somehow?

17:35 cjfrisz: bbloom: That sounds like we're suspiciously close to being on the same page :-p

17:36 bbloom: even if we enact it in different ways

17:36 bbloom: cjfrisz: as is always the case with smart people who arrive at the same place form wildly different directions & then ultimately talk past each other

17:36 cjfrisz: i've been down the auto-generated attr_accessor path quite a bit in ruby land. i much prefer clojure's approach. all i'm saying: give it a try :-P

17:37 cjfrisz: bbloom: I didn't realize that there was quite that much baggage on Clojure's record types, so that's useful to know

17:38 As much shit as people give R6RS define-record-type, myself and the other prolific and intelligent Schemers of the world seem to get a lot of mileage out of the metaphor

17:38 So I still buy into that metaphor, but I'm flexible on the underlying representation for it

17:38 noonian: i thought records were optimized compared to regular maps because there is only one instance of each key required for every instance?

17:38 bbloom: noonian: that's not why the are optimized

17:38 noonian: oh?

17:38 bbloom: noonian: they have a fixed memory layout for their required fields

17:39 noonian: the compiler can convert (:foo record) to a field lookup

17:39 bitemyapp: amalloy: sadly, yeah. When cabal 1.18 and haskell-suite become standard and more common, that might change.

17:40 noonian: ah, thanks for dropping that info

17:40 what is the 'baggage' you guys were talking about? i came in late

17:40 bitemyapp: value types on the JVM would be kinda cool.

17:43 bbloom: noonian: issues w/ namespace reloading regarding dispatch, equality, etc. asymmetry between assoc/dissoc and type preservation, problems for serialization & versioning, etc

17:44 cjfrisz: Letting different versions of data structures play nice together is such a double-edged sword...

17:45 noonian: ah, I see

17:46 cjfrisz: I've had big Scheme systems where there were instances of "oh, it's a good thing that version wouldn't play nice because it was stale" and "man, I wish it didn't treat this version as stale" for the exact same record type

17:46 bbloom: cjfrisz: versioning is hard.

17:47 cjfrisz: The way the generative/nongenerative clause works in define-record-type, you can have it either way, but smarter programmers than I have taught to default to nongenerative

17:48 technomancy: are opaque structs a common thing across schemes?

17:48 bbloom: cjfrisz: i can't find any real details on gen/nongen.

17:48 technomancy: those are incredibly annoying

17:48 bbloom: cjfrisz: docs?

17:49 oh i found something here http://www.scheme.com/tspl4/records.html

17:49 cjfrisz: bbloom: was about to send that link

17:49 bbloom: right, def vs defonce

17:49 both suck for different reasons :-P:

17:50 cjfrisz: bbloom: There might be additional details in CSUG: http://scheme.com/csug8/objects.html#./objects:h13

17:50 technomancy: R6RS records aren't *exactly* opaque

17:50 If you're willing to do some gymnastics, you can pull the layout and interface out of a record

17:50 I've never had to do it, so I don't remember how off the top of my head

17:51 bbloom: but in general, this is complexity

17:51 and it's cost you should only pay if you need to

17:51 cjfrisz: bbloom: to what are you referring?

17:51 bbloom: generative vs nongenerative

17:51 defrecord (and deftype, etc) is generative

17:52 maps are effectively nongenerative, since the type is consistent across clojure versions

17:52 cjfrisz: bbloom: right

17:52 cYmen: Good evening.

17:52 bbloom: cjfrisz: nongenerative is problematic with static information tied to a type tag, like required fields

17:54 cYmen: *sigh*

17:55 Since I'm trying to learn clojure I might as well start using emacs again...

17:55 My brain will be so messed up with all the shortcuts...

17:56 noonian: that was too ambitious for me

17:56 well, i've always used emacs but never too a fraction of its potential

17:57 cYmen: Are there any other IDEs?

17:57 noonian: i use Light Table now for Clojure

17:58 cYmen: Oh, is that in a usable state?

17:59 noonian: definitely, but there aren't many docs so you have to know how to use its 'start typing and get shown possibly completions' interface

17:59 mainly for tweaking settings

18:02 * cYmen watches the video again.

18:17 cjfrisz: Something I've not thought about before

18:17 Scheme: (eq? 'a 'a) => #t

18:17 Clojure: (identical? 'a 'a) => false

18:18 That is one really dumb thing Scheme did that was good to ignore in Clojure

18:18 bbloom: cjfrisz: that's b/c symbols can have metadata. keywords test identical?

18:18 cjfrisz: technically, the strings that back the symbols are interned :-P

18:20 cjfrisz: bbloom: the Scheme standard requires that all instances of a symbol be *actually a pointer to the same thing* IIRC

18:20 Which is a really annoying thing to take care of

18:20 bbloom: cjfrisz: yeah, that's true of keywords in clj/jvm (sans the spec part)

18:21 cjfrisz: it makes for super fast equality, which is important when symbols are self-evaluating, but not super important when symbols are ... symbolic ... for their intentional indirection

18:22 cjfrisz: bbloom: right

18:22 Keywords working that way makes more sense than for symbols

18:22 bbloom: cjfrisz: it's also a reason why the vector syntax is so important

18:22 symbols : keywords :: lists : vectors ;; in terms of evaluation strategies

18:23 any time you add a data type to your evaluator that has some kind of special evaluation rule, you should also add a quoting construct or a type with the non-special evaluation rule

18:24 or both :-P

18:30 cYmen: noonian: Now I want to learn how to use lighttable, ring and clojure and clojurescript and feel totally overwhelmed.

18:30 All your fault!

18:30 noonian: haha

18:30 you'll thank me someday

18:30 bbloom: cYmen: just sloooow it down and use the little text editor at http://www.4clojure.com/ and do some puzzles

18:30 you can thank noonian looong after you thank me :-P

18:31 cYmen: bbloom: I've already done a ton of those.

18:31 bbloom: ok, well then add one thing at a time

18:32 rbxbx: cYmen: what were you using for editing before clojure?

18:32 cYmen: most of the major environments have at least halfway decent support for Clojure now

18:33 cYmen: Well, I am used to vim and visual studio these days. But back when I was doing anything with lisp I liked emacs for it

18:33 .

18:34 So far all the clojure I wrote was in vim without any support for anything.

18:34 bbloom: cYmen: try vim-fireplace. i use it heavily

18:34 lots of closeted vim folks in here like it

18:34 cYmen: But I was just looking at ways for not having to reload and restart everything when trying ring examples...

18:35 rbxbx: cYmen bbloom : yup, it's a pretty great environment

18:35 cYmen: foreplay was renamed to fireplace...what does that tell us about tpope? :p

18:35 rbxbx: cYmen: not sure what you mean exactly, but I'd be willing to bet vim-fireplace would help you to accomplish that.

18:36 cYmen: it tells us that some people got uneasy and didn't like an otherwise good plugin due to it's name so it was renamed :p

18:36 cYmen: rbxbx: Problem 1: When I try to (use 'hello-world.core) and I get an error, can I somehow recover without restarting the repl?

18:37 swarthy: I'm a Vim user that has been thoroughly enjoying LightTable for Clojure, what trouble are have with LightTable cYmen?

18:37 rbxbx: cYmen: care to gist the error?

18:38 swarthy: you having*

18:38 cYmen: rbxbx: Uh sure I can produce one but I mean it's not about the error that is usually easily fixed....

18:39 rbxbx: cYmen: the error is putting vim into an unusable state?

18:39 cYmen: that... shouldn't be the case.

18:39 cYmen: rbxbx: No just the repl I started with lein repl.

18:39 In detail:

18:39 start repl with "lein repl"

18:40 run "(use 'ring.adapter.jetty)"

18:40 run "(use 'hello-world.core)"

18:40 now get an error because of e.g. unmatched parens

18:40 fix error...rerun last command doesn't work...

18:41 I'm sorry my process probably doesn't make any sense at all.

18:43 rbxbx: cYmen: yeah, not sure off hand. I actually have to bounce, but if you're unable to resolve things feel free to ping me.

18:43 cYmen: sorry, godspeed!

18:43 cYmen: thanks anyway, bye

18:44 swarthy: No real reason just didn't want to get into it right now because I am working remote through ssh.

18:44 llambda: is there a way to force lein to run each unit test in isolation? i'm seeing some strange results with a particular set of unit tests and if i manually do something like `lein test :only foo.bar/baz` all works as expected, otherwise there appears to be leakage between tests

18:45 amalloy: llambda: there's not really any such thing as "in isolation", unless you want to restart the jvm each time. there's nothing lein can do to "undo" any side effects your code decided to perform

18:46 llambda: hm it's too bad there isn't some kind of setup and tear down infrastructure that lein could call between tests

18:49 coventry: You could probably get pretty close by rewriting run-tests to (require 'actual-namespace :reload) between each test in test-actual-namespace.

18:53 amalloy: llambda: you can use a test fixture to run any code you want before and after each test

18:53 llambda: coventry: that might help. or possibly using something like speclj

18:53 swarthy: cYmen: that makes sense

18:54 technomancy: llambda: yeah, that's a problem with clojure.test unfortunately

18:54 no run-wide fixtures

19:00 cYmen: Oh..I think I want nREPL.

19:02 technomancy: llambda: I think there could be a "run each test in its own JVM" plugin though, that sounds kind of familiar

19:05 llambda: technomancy: that might be helpful

19:18 abaranosky: does core.typed require you to type annotate everything before it is useful?

19:19 bitemyapp: abaranosky: yes, but you can do it a namespace at a time.

19:19 abaranosky: you can ignore the type errors arising from a lack of annotations and focus on only the parts that are type errors for things that are annotated too.

19:19 abaranosky: bitemyapp: if that first ns depends on others, how does core.typed disambiuate?

19:19 I see

19:19 bitemyapp: it doesn't, you add no-check annotations for the outside things you're using.

19:19 arohner: abaranosky: start small

19:20 abaranosky: bitemyapp: do you know a good link to see how to write type annotations for common stuff?

19:20 bitemyapp: the no-check annotations isolate the type checker propagation.

19:20 abaranosky: https://github.com/clojure/core.typed/blob/master/src/main/clojure/clojure/core/typed/base_env.clj

19:20 ~baseenv is https://github.com/clojure/core.typed/blob/master/src/main/clojure/clojure/core/typed/base_env.clj

19:20 clojurebot: Roger.

19:21 abaranosky: bitemyapp: thx, that's perfect

19:22 bitemyapp: abaranosky: no problem at all.

19:23 abaranosky: and I second arohner's advice, start small.

19:26 abaranosky: bitemyapp and arohner: the error messages aren't so obvious. Makes sense to start small.

19:26 bitemyapp: abaranosky: domain is the arguments to the function, range is the results

19:26 that might be obvious to somebody that took undergrad math in college, but I did not, so it took me a moment.

19:27 * arohner took those classes, and barely remembered them

19:28 bitemyapp: arohner: but you knew what it meant immediately when it said domain/range, right?

19:29 arohner: I figured them out from context

19:29 bitemyapp: same as me then.

19:29 abaranosky: do you see anything wrong here? https://gist.github.com/AlexBaranosky/7392037

19:30 bitemyapp: abaranosky: also, you can use check-ns and cf from the REPL, might be faster than lein typed.

19:30 abaranosky: bitemyapp: yeah, cool, thx

19:31 bitemyapp: abaranosky: example project while I try to understand why the nested vec set is failing. https://github.com/typedclojure/core.typed-example

19:31 abaranosky: there's also a typed-clojure IRC channel btw.

19:37 dobry-den: How do yall prevent Java APIs from infesting your code with their bullshit? Sometimes I have a Bouncycastle Point: (.toBigInteger (.getX point)). Sometimes I hava a java.security Point: (.getAffineX point)

19:38 abaranosky: bitemyapp: are you using core.typed for any production code? I'm still on the fence about the added verbosity its going to add

19:38 dobry-den: could you elaborate a little more on the question?

19:39 I'm not familar with those libs, but on thing you can always do is convert to the points to Vectors

19:39 its context-dependent though

19:41 cjfrisz: This sounds like a painfully dumb question, but I've just never run into it before: is there a built-in predicate to ask if something is a boolean?

19:41 I know there's true? and false?

19:41 abaranosky: (some-fn true? false?) ;; :)

19:42 (partial instance? Boolean)

19:42 cjfrisz: abaranosky: The former is what I wrote

19:43 abaranosky: this is probably fastest: (defn boolean? [x] (instance? Boolean x))

19:43 dobry-den: abaranosky: I guess i'm looking for a pattern so that I can carry points around in my code like {:x BigInt, :y BigInt}, or keypairs like {:priv _, :pub _}.

19:44 and then i'd define a function like (defn multiply [point n] ...) that turns them back into whatever Java obj they need to be

19:44 abaranosky: most would robably use [x y]

19:44 jtoy: is it correct to say that if i define a macro that calls other functions, all those other functions must be defined ahead of time? but shouldnt the functions i call only need to be defined when I use the macro?

19:44 bitemyapp: abaranosky: production code? no, but I've experimented with using it on production code.

19:44 abaranosky: production code isn't a good measure here, my current project at work is a bit of a throwaway and is very "HACK NOW NOW NOW NOW" in terms of scheduling.

19:45 if I had some time to fuckin' breathe I'd eat the pain and just it.

19:45 just use it*

19:47 abaranosky: `reduced` is a pretty neat little somewhat recent addition to clojure.core

19:47 enables you to short-circuit a reduce call

19:51 bitemyapp: abaranosky: reduced is important, it brings folding capability in Clojure to parity with loop/recur and Haskell's foldl/foldl'/foldr

19:51 abaranosky: bitemyapp: yeah, it rocks for certain

19:51 bitemyapp: mostly to parity with loop/recur, there are some things recursion can do that a short-circuiting fold might still find a little awkward.

19:51 I can provide an example if you care what that might be.

19:52 abaranosky: bitemyapp: if you want, go for it, but don't go too far out of you way on my behalf :)

19:52 bitemyapp: abaranosky: this is a pattern I ran into that is really awkward with folds, basically where you want to "take 2, merge those items, put them back into the iterable"

19:53 abaranosky: messing with the base iterable in that way is awkward with folds unless you make it part of the "carry" and do something else for the actual foldee.

19:53 which would be really weird and is in effect, mimicking recursion in a fold for no good reason.

19:53 abaranosky: bitemyapp: yeah, I use oo/recur for that

19:53 bitemyapp: so you just use loop/recur (or recursion, if you're in Haskell) for that.

19:54 abaranosky: I meant loop/recur , not oo/recur :)

19:56 dnolen: got sick of using console.log, added enable-console-print! to CLJS, also added support for *print-length* https://github.com/clojure/clojurescript/compare/5827c4cd48...0e427a08c5

19:56 if somebody wants to do *print-depth* that would be cool

19:57 bitemyapp: dnolen: I'm surprised it took you that long to get impatient with it,

19:57 dnolen: bitemyapp: always some other yak I'd rather shave

19:58 bitemyapp: dnolen: I chuckled heartily when cemerick said there were no more yaks left in Clojure-land. Least true thing I'd seen in ages.

20:03 dnolen: heh wow

20:03 clojure.pprint uses defstruct still

20:06 abaranosky: don't fix it, if it ain't broken ;)

20:07 dnolen: abaranosky: truth

20:11 jtoy: what is the proper way to test if a function is defined?

20:14 bitemyapp: jtoy: there's nothing specific to functions for this.

20:14 jtoy: and I can still tell you're writing terrible code.

20:15 jtoy: you should learn Clojure.

20:15 specifically, if you did, you'd know why you don't need anything specific to functions to detect if a var is defined or not.

20:16 jtoy: I recommend this book: http://clojurebook.com/

20:37 jtoy: how is it possible to get an error like: user-find already refers to: #'toy-app.datastore/user-find in namespace: pusher.core if user-find is only defined in toy-app.datastore ?

20:39 bja: jtoy, if you attempt to def user-find in toy-app.datastore or require it twice, I believe you would see tat

20:39 bitemyapp: bja: I'd like to start on the error handling stuff

20:40 bja: have you made any progress? if not, that's okay, I just don't want to trip over you.

20:44 jtoy: bja i cant require it twice? I require it from different namespaces

20:44 i only def it once and I double checked with grep, so it must be the require twice issue, how exactly does that work?

20:44 bja: within the same namespace, you would see that error. you can require it from as many namespaces as you wish

21:07 dobry-den: jtoy: a common way to botch your state is to do something like (:require [... :refer :all]), eval it, delete the line, then 1 hour later (for me, 5 min) without having restarted the repl, you forget you did it

21:07 ambrosebs: abaranosky: did you figure out your core.typed parse errors?

21:07 dobry-den: and now youve got all them phantom functions defined in the current ns

21:07 and nothing to grep

21:08 that's why if one were to piechart how i spend my time every day, it's a pacman labeled "restarting repl"

21:11 in his mouth a sliver labeled "whining on #clojure"

21:19 MattY: hello. there was one macro that lets you pipe a value through a series of functions. anyone knows what I am talking about?

21:19 >> or something

21:20 bitemyapp: ,(-> 1 inc inc inc inc inc inc inc inc inc inc inc inc inc inc inc inc inc inc inc inc inc)

21:20 clojurebot: 22

21:20 MattY: that's it, thanks!

21:29 mtp: bitemyapp‘ wow

21:39 arrdem: bitemyapp: watrudoing

21:39 bitemyapp: I log in and all I see is inc

21:44 Julian_d: arrdem: He was answering a question: "MattY: hello. there was one macro that lets you pipe a value through a series of functions. anyone knows what I am talking about?"

21:45 arrdem: Julian_d: I know just giving him crap

21:45 Julian_d: arrdem: my bad :p Just trying to be helpful. I'm likely to need the karma down the road ;)

21:47 justin_smith: his code can be made more seasonal

21:47 ,(let [❄ inc ☃ 1] (-> ☃ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄ ❄))

21:47 clojurebot: 42

21:48 arrdem: justin_smith: you aren't helping here bud :P

21:51 ddellacosta: justin_smith: I go to bed and when I get up you're still making holiday jokes

21:51 justin_smith: I commend you sir

21:51 dobry-den: I'm new to typed clojure and I'm having trouble in the newbie foothills: How can I annotate a byte array?

21:52 justin_smith: ddellacosta: I was out bicycling most of the day, but back now

21:53 ddellacosta: justin_smith: you're spoiling my fantasy of someone spending all day on IRC making bad holiday jokes. It's like, bad-santa-bot or something

21:53 dobry-den: oh yeah, under the blanket with the native libs

21:54 justin_smith: ddellacosta: hah

21:54 ddellacosta: dobry-den: haha, you remembered...

21:55 arrdem: dobry-den: won't it just be (Seq byte)?

21:55 justin_smith: I am working on a quad tree that is cljs compatible for a packing lib, with bit masks I am getting really amazing performance

21:56 (which I need, because every placement will need a number of quad tree ops)

21:56 ddellacosta: sooo, speaking of native libs, in an uberjar, how do I execute code before my require'd libs get loaded for my main fn?

21:57 justin_smith: that sounds pretty cool, are you going to release it as OSS?

21:57 justin_smith: ddellacosta: yeah

21:57 ddellacosta: neat, would like to check it out when you do

21:57 justin_smith: basically we are thinking "masonry in clj / cljs (but more configurable / customizable)

21:57 "

21:57 arrdem: ddellacosta: you'll have to not use (ns) for requires, execute code first then use inline (require) forms to get the same effect.

21:58 justin_smith: not very far yet, but I have some very smart collaborators so I think it wil lrock

21:58 ddellacosta: arrdem: ah, okay, I was suspecting something along those lines...thanks.

21:58 arrdem: ddellacosta: you're welcome, sorry there isn't a better answer

21:59 justin_smith: arrdem: it would suffice to only do that with the mainspace with -main in it, right?

21:59 ddellacosta: arrdem: nah, I just want to make sure that there isn't...poking around leiningen docs and mailing lists yields about the same kind of answers

21:59 justin_smith: and other namespaces could be normal?

22:02 bitemyapp: ddellacosta: hey, Japanese question

22:19 concur: if I recur from within the locking macro, will I keep the lock?

22:19 or leave the scope of locking?

22:19 bitemyapp: concur: I have a hard time imagining why that would interfere with anything

22:20 concur: more chancy would be doing core.async channel operations which could deadlock.

22:20 amalloy: concur: i sorta doubt you can recur across a locking-boundary

22:21 concur: I just want to get out of the locking scope

22:21 and try again basically

22:21 but some things need to happen before it locks again

22:22 amalloy: &(loop [l (Object.)] (locking l (recur l)))

22:22 lazybot: java.lang.UnsupportedOperationException: Cannot recur across try

22:22 Apage43: CompilerException java.lang.UnsupportedOperationException: Cannot recur across try

22:22 concur: aw

22:22 thanks

22:22 amalloy: concur: instead of trying to use recur to break out, you have to "finish" the locking block normally, and then recur while already outside it

22:22 or recur to a point that's still inside it

22:23 concur: the thing is

22:23 I want to exit the lock on two different conditions

22:23 one recurs

22:23 one actually does something

22:24 hmm

22:24 I think I know how I can pull this off actually

22:24 Apage43: i like the new windows 8.1 installer messages

22:24 concur: I'll have to see what finish does first

22:24 &(doc finish)

22:24 lazybot: java.lang.RuntimeException: Unable to resolve var: finish in this context

22:25 concur: lol

22:25 Apage43: "Setting up a few more things..." "Getting ready..." "Almost ready..." "Let's start"

22:25 concur: I should probably do that in my own terminal anyway

22:26 oh

22:26 lol

22:26 I thought you meant finish was a function

22:26 was wondering what it could do

22:26 you just meant to close the parens off though :P

22:40 dobry-den: Does anyone have a command handy for evaluating some arbitrary clojure with nrepl? For instance, I'd like to bind C-c C-f to (clojure.typed/check-ns)

23:01 justin_smith: concur: instead of using the locking form you can use a java.concurrent.locks.Lock, and lock and unlock it manually http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/locks/Lock.html

23:01 concur: that's true

23:02 I think I'll be able to make due with just locking

23:02 but that's good to keep in mind

23:03 justin_smith: but then it is of course up to you to ensure that the Lock object gets released

23:03 which is nicer with locking, you just need to be sure the form exits and you are good

23:05 concur: right

23:06 I'm trying to minimize my java interop anyway

23:06 I already have way too much of it

23:08 I think I've found a very nice way to utilize locking in my program :)

23:08 no need for Lock

23:18 I just ran my code for the first time

23:18 got one small error that I fixed right away

23:18 and on the second run it works

23:18 what in the name of fuck?

23:18 this can't be

23:19 justin_smith: the code demons are messing with your head

23:20 concur: it still has the same exact issue that the other function I wrote had, actually

23:20 which I think is an issue with the interface they share

23:20 but other than that, it works perfect

23:20 I don't believe this

23:21 but I'll take it as an excuse to finally go to that party

23:21 and stop writing code for the night

23:23 muhoo: oontz oontz oontz code party

23:27 bitemyapp: I'm having an issue where a write against SocketOutputStream connected to a broken socket will return nil and not error out

23:27 but a second write will finally throw the exception.

23:27 how do I make the first unsuccessful write throw?

23:32 justin_smith: you could put an assert around the write, then any falsey return throws

23:33 never mind, an assert does not return the value asserted

23:33 if that function existed (and you could make it exist), it may be the simplest way to handle the situation

23:34 bitemyapp: er.

23:34 there are multiple things going on with what you said that aren't matching my mental model of the universe. one moment please.

23:34 justin_smith: ,(doto 1 assert)

23:34 clojurebot: 1

23:34 justin_smith: ,(doto nil assert)

23:34 clojurebot: #<AssertionError java.lang.AssertionError: Assert failed: G__60>

23:34 justin_smith: see, falsey is an exception

23:34 wei: my clojure.tools.logging/spy macro stopped working after switching to logback (but the other macros work, e.g. info). where is the output going for spy?

23:35 justin_smith: concise

23:35 (doto (write-to-socket) assert)

23:35 bitemyapp: justin_smith: for starters, .write always returns nil.

23:35 justin_smith: returns the value of write-to-socket, or throws

23:35 that's what you want, no?

23:35 bitemyapp: justin_smith: I have zero means of detecting whether it failed or not

23:35 justin_smith: oh, sorry

23:35 never mind then

23:35 bitemyapp: because it always returns nil and it's not throwing an exception.

23:36 only if I perform a *second* write will it throw a socket exception.

23:36 justin_smith: check .open after writes?

23:36 bitemyapp: justin_smith: ...on the socket or the outputstream?

23:37 I don't see an open method on the outputstream.

23:37 nor on the socket.

23:38 :connected continues to be true on the socket even after a disconnection occurs.

23:38 justin_smith: is this because the socket is an OS resource, and nothing in the jvm finds out the other end has closed it until it tries to use it?

23:38 bitemyapp: it DID use it!

23:39 I wrote to it while the server on the other side was down!

23:39 amalloy: bitemyapp: i mean, in general that's not possible, right? you can't control how long it takes the networking stack to detect/decide that the other end of the socket is dead

23:39 bitemyapp: the problem is that writes aren't triggering any exceptions or issues of any kind, yet are getting SWALLOWED somehow.

23:39 amalloy: shouldn't a write against a dead connection fail?

23:39 justin_smith: because of how sockets are supposed to work, the OS is supposed to retry after the system call returns

23:39 bitemyapp: I know it won't magically throw when I don't do anything

23:39 but shouldn't it fail when I write to it the first time, as opposed to the second time?

23:40 justin_smith: I don't know if there is a way to wait for the OS timeout or respond to it

23:40 amalloy: sure, if it's known to be dead. but in real life, write() on a working socket just puts something in a networking buffer and schedules some networking activity

23:40 bitemyapp: are you telling me writes are non-blocking and throwing bytes over the fence?

23:40 justin_smith: no, because the way sockets work, it returns before the other end has acked

23:40 amalloy: then, eventually, that write happens, and when the other end doesn't respond in X amount of time, the OS concludes the socket is dead

23:41 bitemyapp: christ

23:41 justin_smith: bitemyapp: to your last question, yes

23:41 amalloy: bitemyapp: the alternative is too horrible to contemplate. your entire app blocks every time you send a byte, for an entire tcp round-trip

23:41 bitemyapp: sure but

23:41 justin_smith: it is not a java problem even, it is how posix and sockets are designed to work

23:41 bitemyapp: how do I know which writes failed and which did not, asynchronously or not?

23:41 if it just gets swallowed and I can't tell the difference?

23:42 amalloy: i'm not sure. it's the sort of thing it's hard for me to decide if it's even possible

23:42 bitemyapp: if I attempt to run a SQL query against a down database, I get an exception or error back

23:42 justin_smith: bitemyapp: http://www.softlab.ntua.gr/facilities/documentation/unix/unix-socket-faq/unix-socket-faq-2.html

23:43 bitemyapp: *how are they doing that?*

23:43 justin_smith: top question in that faq

23:43 bitemyapp: justin_smith: fine fine fine whatever, but there is existing tooling that is returning errors deterministically for failed writes.

23:43 amalloy: bitemyapp: because they're expecting an actual response back; when they don't get one, they throw an exception

23:43 Adeon: they send back acknowledgements

23:44 bitemyapp: okay, so the problem here is that my reads are independent of my writes.

23:44 justin_smith: yeah, you need an ACK that you can check for

23:44 amalloy: if all you're doing is shouting into the ether, you won't find out quite as quickly that nobody is listening

23:44 bitemyapp: it's a non-blocking API

23:44 so it sounds like if my socket dies I need to deliver the exception to all on-deck promises.

23:44 and wrap up the agent

23:49 lpvb: anyone know how to get the intellij repl to recompile java source code so I don't have to relaunch it

23:50 justin_smith: lpvb: maybe import? does import implicitly reload?

23:50 maybe not

23:51 lpvb: no

23:51 I have to do lein javac

23:51 then close the repl

23:52 start it up again and then import reloads the right object file

23:53 bitemyapp: okay, so I'm starting to get this nailed down.

23:54 is failure the only condition under which a read from an InputStream will return nil?

23:54 justin_smith: maybe keep a set of un-acknowledged sent data, and once you get a closed socket, you mark all in the set as unsent?

23:55 bitemyapp: no, I think it can return nil if it isn't ready

23:55 lpvb: it's really slow too because lein javac first launches leiningen and that takes a while

23:55 is there a way to get lein in some kind of continuous mode so I can issue commands to it

23:55 * bitemyapp scowls

23:56 lpvb: without relaunching lein

23:59 algal: Hello, all.

23:59 I'd love some advice on how to use Clojure's concurrency features correctly, to maintain certain invariants in an SQL db.

23:59 I understand the point of an SQL db is usually that they guarantee operations are atomic, but I'd like to build up some operations within clojure functions that are effectively atomic within those functions.

Logging service provided by n01se.net